From e5a70744c0653c56bb432e6325f2de629e3f3b56 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 13 Jan 2021 09:47:44 +0000 Subject: update changelog (cherry picked from commit 299c4bda1b306ddc5e0e15bb2a3aed9d24fe3a76) --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index c551dfc7a..19cc7fd43 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Hubzilla 5.2 (2021-xx-xx) +Hubzilla 5.2 (2021-01-13) - Use libzotdir for directory - Streamline usage of channel url for keyId - Basic work on PHP8 compatibility -- cgit v1.2.3 From 83f0c3d1ddcedc2324021f5f0d7a7e0b319da0d3 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 14 Jan 2021 14:28:35 +0000 Subject: some work to fix r_preview in list mode --- Zotlabs/Lib/ThreadItem.php | 48 ++++----- Zotlabs/Module/Channel.php | 54 +++++----- Zotlabs/Module/Display.php | 84 ++++++++-------- Zotlabs/Module/Like.php | 63 +++++++----- Zotlabs/Module/Network.php | 245 +++++++++++++++++++++++---------------------- include/conversation.php | 110 ++++++++++---------- view/js/main.js | 5 +- view/tpl/build_query.tpl | 6 +- 8 files changed, 316 insertions(+), 299 deletions(-) diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 024502d2a..b7eecbd94 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -35,7 +35,7 @@ class ThreadItem { public function __construct($data) { - + $this->data = $data; $this->toplevel = ($this->get_id() == $this->get_data_value('parent')); $this->threaded = get_config('system','thread_allow'); @@ -98,7 +98,7 @@ class ThreadItem { $conv = $this->get_conversation(); $observer = $conv->get_observer(); - $lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) + $lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) ? t('Private Message') : false); @@ -151,9 +151,9 @@ class ThreadItem { if($observer && $observer['xchan_hash'] - && ($observer['xchan_hash'] == $this->get_data_value('author_xchan') - || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') - || $observer['xchan_hash'] == $this->get_data_value('source_xchan') + && ($observer['xchan_hash'] == $this->get_data_value('author_xchan') + || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') + || $observer['xchan_hash'] == $this->get_data_value('source_xchan') || $this->get_data_value('uid') == local_channel())) $dropping = true; @@ -169,15 +169,15 @@ class ThreadItem { 'dropping' => $dropping, 'delete' => t('Delete'), ); - } + } elseif(is_site_admin()) { $drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ]; } // FIXME - if($observer_is_pageowner) { + if($observer_is_pageowner) { $multidrop = array( - 'select' => t('Select'), + 'select' => t('Select'), ); } @@ -223,7 +223,7 @@ class ThreadItem { if(! feature_enabled($conv->get_profile_owner(),'dislike')) unset($conv_responses['dislike']); - + $responses = get_responses($conv_responses,$response_verbs,$this,$item); $my_responses = []; @@ -254,7 +254,7 @@ class ThreadItem { } $showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : ''); - $showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike')) + $showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike')) ? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : ''); /* @@ -264,7 +264,7 @@ class ThreadItem { */ $this->check_wall_to_wall(); - + if($this->is_toplevel()) { // FIXME check this permission if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) { @@ -275,7 +275,7 @@ class ThreadItem { ); } - } + } else { $is_comment = true; } @@ -349,7 +349,7 @@ class ThreadItem { // $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link // since we can't depend on llink or plink pointing to the right local location. - + $owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@')); $viewthread = $item['llink']; if($conv->get_mode() === 'channel') @@ -357,7 +357,7 @@ class ThreadItem { $comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children ); $list_unseen_txt = (($unseen_comments) ? sprintf( t('%d unseen'),$unseen_comments) : ''); - + $children = $this->get_children(); $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); @@ -386,7 +386,7 @@ class ThreadItem { $tmp_item = array( 'template' => $this->get_template(), 'mode' => $mode, - 'item_type' => intval($item['item_type']), + 'item_type' => intval($item['item_type']), //'type' => implode("",array_slice(explode("/",$item['verb']),-1)), 'body' => $body['html'], 'tags' => $body['tags'], @@ -518,8 +518,8 @@ class ThreadItem { // needed for scroll to comment from notification but needs more work // as we do not want to open all comments unless there is actually an #item_xx anchor -// and the url fragment is not sent to the server. -// if(in_array(\App::$module,['display','update_display'])) +// and the url fragment is not sent to the server. +// if(in_array(\App::$module,['display','update_display'])) // $visible_comments = 99999; if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) { @@ -539,7 +539,7 @@ class ThreadItem { } } } - + $result['private'] = $item['item_private']; $result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : ''); @@ -554,7 +554,7 @@ class ThreadItem { return $result; } - + public function get_id() { return $this->get_data_value('id'); } @@ -609,7 +609,7 @@ class ThreadItem { if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) { return false; } - + $item->set_parent($this); $this->children[] = $item; return end($this->children); @@ -683,7 +683,7 @@ class ThreadItem { */ public function set_conversation($conv) { $previous_mode = ($this->conversation ? $this->conversation->get_mode() : ''); - + $this->conversation = $conv; // Set it on our children too @@ -792,7 +792,7 @@ class ThreadItem { if(!$this->is_toplevel() && !get_config('system','thread_allow')) { return ''; } - + $comment_box = ''; $conv = $this->get_conversation(); @@ -808,7 +808,7 @@ class ThreadItem { $arr = array('comment_buttons' => '','id' => $this->get_id()); call_hooks('comment_buttons',$arr); $comment_buttons = $arr['comment_buttons']; - + $comment_box = replace_macros($template,array( '$return_path' => '', '$threaded' => $this->is_threaded(), @@ -865,7 +865,7 @@ class ThreadItem { if($conv->get_mode() === 'channel') return; - + if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) { $this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']); $this->owner_photo = $this->data['owner']['xchan_photo_m']; diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 7ff394750..fe7341e52 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -25,7 +25,7 @@ class Channel extends Controller { function init() { - if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?'])) + if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?'])) goaway('search' . '?f=&search=' . $_GET['search']); $which = null; @@ -56,10 +56,10 @@ class Channel extends Controller { http_status_exit(404, 'Not found'); } - // handle zot6 channel discovery + // handle zot6 channel discovery if(Libzot::is_zot_request()) { - + $sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6'); if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) { @@ -76,8 +76,8 @@ class Channel extends Controller { $data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'] ])); } - $headers = [ - 'Content-Type' => 'application/x-zot+json', + $headers = [ + 'Content-Type' => 'application/x-zot+json', 'Digest' => HTTPSig::generate_digest_header($data), '(request-target)' => strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'] ]; @@ -93,15 +93,15 @@ class Channel extends Controller { $profile = argv(1); } - head_add_link( [ - 'rel' => 'alternate', + head_add_link( [ + 'rel' => 'alternate', 'type' => 'application/atom+xml', 'title' => t('Posts and comments'), 'href' => z_root() . '/feed/' . $which ]); - head_add_link( [ - 'rel' => 'alternate', + head_add_link( [ + 'rel' => 'alternate', 'type' => 'application/atom+xml', 'title' => t('Only posts'), 'href' => z_root() . '/feed/' . $which . '?f=&top=1' @@ -111,18 +111,18 @@ class Channel extends Controller { // Run profile_load() here to make sure the theme is set before // we start loading content profile_load($which,$profile); - + // Add Opengraph markup $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); if(strpos($mid,'b64.') === 0) $mid = @base64url_decode(substr($mid,4)); - + if($mid) $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1", dbesc($mid), intval($channel['channel_id']) ); - + opengraph_add_meta($r ? $r[0] : [], $channel); } @@ -233,7 +233,7 @@ class Channel extends Controller { /** * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups */ - + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 "; @@ -266,7 +266,7 @@ class Channel extends Controller { } } - head_add_link([ + head_add_link([ 'rel' => 'alternate', 'type' => 'application/json+oembed', 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string), @@ -333,12 +333,12 @@ class Channel extends Controller { } } else { - $r = q("SELECT DISTINCT item.parent AS item_id, $ordering FROM item + $r = q("SELECT DISTINCT item.parent AS item_id, $ordering FROM item left join abook on ( item.author_xchan = abook.abook_xchan $abook_uids ) WHERE true and item.uid = %d $item_normal AND (abook.abook_blocked = 0 or abook.abook_flags is null) AND item.item_wall = 1 AND item.item_thread_top = 1 - $sql_extra $sql_extra2 + $sql_extra $sql_extra2 ORDER BY $ordering DESC, item_id $pager_sql ", intval(App::$profile['profile_uid']) ); @@ -375,6 +375,15 @@ class Channel extends Controller { $items = array(); } + // Add pinned content + if(! x($_REQUEST,'mid') && ! $search) { + $pinned = new \Zotlabs\Widget\Pinned; + $r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]); + $o .= $r['html']; + } + + $mode = (($search) ? 'search' : 'channel'); + if((! $update) && (! $load)) { if($decoded) @@ -421,20 +430,11 @@ class Channel extends Controller { '$net' => '', '$dend' => $datequery, '$dbegin' => $datequery2, - '$conv_mode' => 'channel' + '$conv_mode' => 'channel', + '$page_mode' => $page_mode )); - } - // Add pinned content - if(! x($_REQUEST,'mid') && ! $search) { - $pinned = new \Zotlabs\Widget\Pinned; - $r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]); - $o .= $r['html']; - } - - $mode = (($search) ? 'search' : 'channel'); - if($update) { $o .= conversation($items,$mode,$update,$page_mode); } diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 81ac0f7b8..04aeb6d5c 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -19,21 +19,21 @@ class Display extends \Zotlabs\Web\Controller { if(argc() > 1) { $module_format = substr(argv(1),strrpos(argv(1),'.') + 1); if(! in_array($module_format,['atom','zot','json'])) - $module_format = 'html'; + $module_format = 'html'; } if(observer_prohibited()) { notice( t('Public access denied.') . EOL); return; } - + if(argc() > 1) { $item_hash = argv(1); if($module_format !== 'html') { $item_hash = substr($item_hash,0,strrpos($item_hash,'.')); } } - + if($_REQUEST['mid']) $item_hash = $_REQUEST['mid']; @@ -42,19 +42,19 @@ class Display extends \Zotlabs\Web\Controller { notice( t('Item not found.') . EOL); return; } - + $observer_is_owner = false; if(local_channel() && (! $update)) { - + $channel = \App::get_channel(); $channel_acl = array( - 'allow_cid' => $channel['channel_allow_cid'], - 'allow_gid' => $channel['channel_allow_gid'], - 'deny_cid' => $channel['channel_deny_cid'], + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], 'deny_gid' => $channel['channel_deny_gid'] - ); + ); $x = array( 'is_owner' => true, @@ -62,7 +62,7 @@ class Display extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), + 'acl' => populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'), 'permissions' => $channel_acl, 'bang' => '', 'visitor' => true, @@ -75,21 +75,21 @@ class Display extends \Zotlabs\Web\Controller { 'jotnets' => true, 'reset' => t('Reset form') ); - + $o = '
'; $o .= status_editor($a,$x,false,'Display'); $o .= '
'; } - + // This page can be viewed by anybody so the query could be complicated // First we'll see if there is a copy of the item which is owned by us - if we're logged in locally. - // If that fails (or we aren't logged in locally), + // If that fails (or we aren't logged in locally), // query an item in which the observer (if logged in remotely) has cid or gid rights - // and if that fails, look for a copy of the post that has no privacy restrictions. + // and if that fails, look for a copy of the post that has no privacy restrictions. // If we find the post, but we don't find a copy that we're allowed to look at, this fact needs to be reported. - + // find a copy of the item somewhere - + $target_item = null; if(strpos($item_hash,'b64.') === 0) @@ -100,7 +100,7 @@ class Display extends \Zotlabs\Web\Controller { $r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1", dbesc($item_hash . '%') ); - + if($r) { $target_item = $r[0]; } @@ -117,14 +117,14 @@ class Display extends \Zotlabs\Web\Controller { if($target_item['item_blocked'] == ITEM_MODERATED) { goaway(z_root() . '/moderate/' . $target_item['id']); } - + $r = null; - + if($target_item['item_type'] == ITEM_TYPE_WEBPAGE) { $x = q("select * from channel where channel_id = %d limit 1", intval($target_item['uid']) ); - $y = q("select * from iconfig left join item on iconfig.iid = item.id + $y = q("select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['parent']) @@ -141,7 +141,7 @@ class Display extends \Zotlabs\Web\Controller { $x = q("select * from channel where channel_id = %d limit 1", intval($target_item['uid']) ); - $y = q("select * from iconfig left join item on iconfig.iid = item.id + $y = q("select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['parent']) @@ -160,7 +160,7 @@ class Display extends \Zotlabs\Web\Controller { intval($target_item['uid']) ); - $y = q("select * from iconfig left join item on iconfig.iid = item.id + $y = q("select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'CARD' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['parent']) @@ -179,7 +179,7 @@ class Display extends \Zotlabs\Web\Controller { notice( t('Page not found.') . EOL); return ''; } - + $simple_update = ''; if($update && $_SESSION['loadtime']) $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) "; @@ -191,14 +191,14 @@ class Display extends \Zotlabs\Web\Controller { //$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']); $mid = $target_item['mid']; - // if we got a decoded hash we must encode it again before handing to javascript + // if we got a decoded hash we must encode it again before handing to javascript if($decoded) $mid = 'b64.' . base64url_encode($mid); $o .= '
' . "\r\n"; $o .= "\r\n"; - + \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( '$baseurl' => z_root(), '$pgtype' => 'display', @@ -230,7 +230,7 @@ class Display extends \Zotlabs\Web\Controller { '$mid' => (($mid) ? urlencode($mid) : '') )); - head_add_link([ + head_add_link([ 'rel' => 'alternate', 'type' => 'application/json+oembed', 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string), @@ -270,8 +270,8 @@ class Display extends \Zotlabs\Web\Controller { $r = q("SELECT item.id as item_id from item WHERE mid = '%s' - AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' - AND item.deny_gid = '' AND item_private = 0 ) + AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' + AND item.deny_gid = '' AND item_private = 0 ) and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) OR uid = %d ) $sql_extra ) @@ -282,7 +282,7 @@ class Display extends \Zotlabs\Web\Controller { ); } } - + elseif($update && !$load) { $r = null; @@ -307,8 +307,8 @@ class Display extends \Zotlabs\Web\Controller { $sysid = 0; $r = q("SELECT item.parent AS item_id from item WHERE parent_mid = '%s' - AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' - AND item.deny_gid = '' AND item_private = 0 ) + AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' + AND item.deny_gid = '' AND item_private = 0 ) and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) OR uid = %d ) $sql_extra ) @@ -320,7 +320,7 @@ class Display extends \Zotlabs\Web\Controller { ); } } - + else { $r = array(); } @@ -328,7 +328,7 @@ class Display extends \Zotlabs\Web\Controller { if($r) { $parents_str = ids_to_querystr($r,'item_id'); if($parents_str) { - $items = q("SELECT item.*, item.id AS item_id + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE parent in ( %s ) $item_normal ", dbesc($parents_str) @@ -341,10 +341,10 @@ class Display extends \Zotlabs\Web\Controller { else { $items = array(); } - + switch($module_format) { - + case 'html': if ($update) { @@ -363,7 +363,7 @@ class Display extends \Zotlabs\Web\Controller { \App::$page['title'] = (($items[0]['title']) ? $items[0]['title'] . " - " . \App::$page['title'] : \App::$page['title']); $o .= conversation($items, 'display', $update, 'client'); - } + } break; @@ -380,7 +380,7 @@ class Display extends \Zotlabs\Web\Controller { '$owner' => '', '$profile_page' => xmlify(z_root() . '/display/' . $target_item['mid']), )); - + $x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ]; call_hooks('atom_feed_top',$x); @@ -406,13 +406,13 @@ class Display extends \Zotlabs\Web\Controller { header('Content-type: application/atom+xml'); echo $atom; killme(); - + } $o .= '
'; if((($update && $load) || $noscript_content) && (! $items)) { - + $r = q("SELECT id, item_deleted FROM item WHERE mid = '%s' LIMIT 1", dbesc($item_hash) ); @@ -421,14 +421,14 @@ class Display extends \Zotlabs\Web\Controller { if(intval($r[0]['item_deleted'])) { notice( t('Item has been removed.') . EOL ); } - else { - notice( t('Permission denied.') . EOL ); + else { + notice( t('Permission denied.') . EOL ); } } else { notice( t('Item not found.') . EOL ); } - + } $_SESSION['loadtime'] = datetime_convert(); diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 358611b1b..f5f3515c0 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -41,41 +41,52 @@ class Like extends \Zotlabs\Web\Controller { private function like_response($arr) { - if($arr['conv_mode'] === 'channel') { + $page_mode = (($arr['item']['item_thread_top'] && $_REQUEST['page_mode']) ? $_REQUEST['page_mode'] : 'r_preview'); + $conv_mode = (($_REQUEST['conv_mode']) ? $_REQUEST['conv_mode'] : 'network'); + + if($conv_mode === 'channel') { $parts = explode('@', $arr['owner_xchan']['xchan_addr']); profile_load($parts[0]); } - $item_normal = item_normal(); - $activities = q("SELECT item.*, item.id AS item_id FROM item - WHERE uid = %d $item_normal - AND thr_parent = '%s' - AND verb IN ('%s', '%s', '%s', '%s', '%s')", - intval($arr['item']['uid']), - dbesc($arr['item']['mid']), - dbesc(ACTIVITY_LIKE), - dbesc(ACTIVITY_DISLIKE), - dbesc(ACTIVITY_ATTEND), - dbesc(ACTIVITY_ATTENDNO), - dbesc(ACTIVITY_ATTENDMAYBE) - ); - - xchan_query($activities,true); - - $convitems[] = $arr['item']; - $convitems = array_merge($convitems, $activities); + if($page_mode === 'list') { + $items = q("SELECT item.*, item.id AS item_id FROM item + WHERE uid = %d $item_normal + AND parent = %d", + intval($arr['item']['uid']), + intval($arr['item']['parent']) + ); + xchan_query($items,true); + $items = fetch_post_tags($items, true); + $items = conv_sort($items, 'commented'); + } + else { + $activities = q("SELECT item.*, item.id AS item_id FROM item + WHERE uid = %d $item_normal + AND thr_parent = '%s' + AND verb IN ('%s', '%s', '%s', '%s', '%s')", + intval($arr['item']['uid']), + dbesc($arr['item']['mid']), + dbesc(ACTIVITY_LIKE), + dbesc(ACTIVITY_DISLIKE), + dbesc(ACTIVITY_ATTEND), + dbesc(ACTIVITY_ATTENDNO), + dbesc(ACTIVITY_ATTENDMAYBE) + ); + xchan_query($activities,true); + $items = array_merge([$arr['item']], $activities); + $items = fetch_post_tags($items, true); + } - $convitems = fetch_post_tags($convitems,true); $ret = [ 'success' => 1, 'orig_id' => $arr['orig_item_id'], //this is required for pubstream items where $item_id != $item['id'] 'id' => $arr['item']['id'], - 'html' => conversation($convitems, $arr['conv_mode'], true, 'r_preview'), + 'html' => conversation($items, $conv_mode, true, $page_mode), ]; - return $ret; } @@ -102,7 +113,7 @@ class Like extends \Zotlabs\Web\Controller { } $verb = notags(trim($_GET['verb'])); - $mode = (($_GET['conv_mode'] === 'channel') ? 'channel' : 'network'); + $mode = (($_GET['conv_mode']) ? $_GET['conv_mode'] : ''); if(! $verb) $verb = 'like'; @@ -407,8 +418,7 @@ class Like extends \Zotlabs\Web\Controller { $ret = self::like_response([ 'item' => $item, 'orig_item_id' => $item_id, - 'owner_xchan' => $thread_owner, - 'conv_mode' => $mode + 'owner_xchan' => $thread_owner ]); json_return_and_die($ret); } @@ -597,8 +607,7 @@ class Like extends \Zotlabs\Web\Controller { $ret = self::like_response([ 'item' => $item, 'orig_item_id' => $item_id, - 'owner_xchan' => $thread_owner, - 'conv_mode' => $mode + 'owner_xchan' => $thread_owner ]); json_return_and_die($ret); diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 4a1692d64..e9edd8de3 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -22,42 +22,42 @@ class Network extends \Zotlabs\Web\Controller { if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?'])) goaway('search' . '?f=&search=' . $_GET['search']); - + if(count($_GET) < 2) { $network_options = get_pconfig(local_channel(),'system','network_page_default'); if($network_options) goaway('network' . '?f=&' . $network_options); } - + $channel = App::get_channel(); App::$profile_uid = local_channel(); head_set_icon($channel['xchan_photo_s']); - + } - + function get($update = 0, $load = false) { - + if(! local_channel()) { $_SESSION['return_url'] = App::$query_string; return login(false); } - + $o = ''; $arr = array('query' => App::$query_string); - + call_hooks('network_content_init', $arr); - + $channel = App::get_channel(); $item_normal = item_normal(); $item_normal_update = item_normal_update(); - + $datequery = $datequery2 = ''; - + $group = 0; - + $nouveau = false; - + $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : ''); $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : ''); $gid = ((x($_GET,'gid')) ? intval($_GET['gid']) : 0); @@ -87,13 +87,13 @@ class Network extends \Zotlabs\Web\Controller { $search = ''; } } - + if($datequery) $order = 'post'; - - + + // filter by collection (e.g. group) - + if($gid) { $r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1", intval($gid), @@ -106,12 +106,12 @@ class Network extends \Zotlabs\Web\Controller { goaway(z_root() . '/network'); // NOTREACHED } - + $group = $gid; $group_hash = $r[0]['hash']; $def_acl = array('allow_gid' => '<' . $r[0]['hash'] . '>'); } - + $default_cmin = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmin',0) : (-1)); $default_cmax = ((Apps::system_app_installed(local_channel(),'Affinity Tool')) ? get_pconfig(local_channel(),'affinity','cmax',99) : (-1)); @@ -127,7 +127,7 @@ class Network extends \Zotlabs\Web\Controller { $net = ((x($_GET,'net')) ? $_GET['net'] : ''); $pf = ((x($_GET,'pf')) ? $_GET['pf'] : ''); $unseen = ((x($_GET,'unseen')) ? $_GET['unseen'] : ''); - + if (Apps::system_app_installed(local_channel(),'Affinity Tool')) { $affinity_locked = intval(get_pconfig(local_channel(),'affinity','lock',1)); if ($affinity_locked) { @@ -155,16 +155,16 @@ class Network extends \Zotlabs\Web\Controller { } $def_acl = [ 'allow_cid' => '<' . $cid_r[0]['abook_xchan'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ]; } - + if(! $update) { - + // search terms header if($search || $hashtags) { $o .= replace_macros(get_markup_template("section_title.tpl"),array( '$title' => t('Search Results For:') . ' ' . (($search) ? htmlspecialchars($search, ENT_COMPAT,'UTF-8') : '#' . htmlspecialchars($hashtags, ENT_COMPAT,'UTF-8')) )); } - + nav_set_selected('Network'); $bang = '!'; @@ -179,14 +179,14 @@ class Network extends \Zotlabs\Web\Controller { } $channel_acl = array( - 'allow_cid' => $channel['channel_allow_cid'], - 'allow_gid' => $channel['channel_allow_gid'], - 'deny_cid' => $channel['channel_deny_cid'], + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], 'deny_gid' => $channel['channel_deny_gid'] ); $private_editing = (($group || $cid) ? true : false); - + $x = array( 'is_owner' => true, 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''), @@ -204,28 +204,28 @@ class Network extends \Zotlabs\Web\Controller { 'jotnets' => true, 'reset' => t('Reset form') ); - + $status_editor = status_editor($a,$x,false,'Network'); $o .= $status_editor; } - - + + // We don't have to deal with ACL's on this page. You're looking at everything // that belongs to you, hence you can see all of it. We will filter by group if // desired. - - + + $sql_options = (($star) ? " and item_starred = 1 " : ''); - + $sql_nets = ''; $item_thread_top = ' AND item_thread_top = 1 '; - + $sql_extra = ''; - + if($group) { $contact_str = ''; @@ -241,18 +241,18 @@ class Network extends \Zotlabs\Web\Controller { } $item_thread_top = ''; $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like '" . protect_sprintf('%<' . dbesc($group_hash) . '>%') . "' ) and id = parent $item_normal ) "; - + $x = group_rec_byhash(local_channel(), $group_hash); - + if($x) { $title = replace_macros(get_markup_template("section_title.tpl"),array( '$title' => t('Privacy group: ') . $x['gname'] )); } - + $o = $title; $o .= $status_editor; - + } elseif($cid_r) { $item_thread_top = ''; @@ -324,75 +324,26 @@ class Network extends \Zotlabs\Web\Controller { } } - + if(x($category)) { $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY)); } if(x($hashtags)) { $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); } - - if(! $update) { - // The special div is needed for liveUpdate to kick in for this page. - // We only launch liveUpdate if you aren't filtering in some incompatible - // way and also you aren't writing a comment (discovered in javascript). - $maxheight = get_pconfig(local_channel(),'system','network_divmore_height'); - if(! $maxheight) - $maxheight = 400; - - - $o .= '
' . "\r\n"; - $o .= "\r\n"; - - App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( - '$baseurl' => z_root(), - '$pgtype' => 'network', - '$uid' => ((local_channel()) ? local_channel() : '0'), - '$gid' => (($gid) ? $gid : '0'), - '$cid' => (($cid) ? $cid : '0'), - '$cmin' => (($cmin) ? $cmin : '(-1)'), - '$cmax' => (($cmax) ? $cmax : '(-1)'), - '$star' => (($star) ? $star : '0'), - '$liked' => (($liked) ? $liked : '0'), - '$conv' => (($conv) ? $conv : '0'), - '$spam' => (($spam) ? $spam : '0'), - '$fh' => '0', - '$dm' => (($dm) ? $dm : '0'), - '$nouveau' => (($nouveau) ? $nouveau : '0'), - '$wall' => '0', - '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), - '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1), - '$search' => (($search) ? urlencode($search) : ''), - '$xchan' => (($xchan) ? urlencode($xchan) : ''), - '$order' => $order, - '$file' => (($file) ? urlencode($file) : ''), - '$cats' => (($category) ? urlencode($category) : ''), - '$tags' => (($hashtags) ? urlencode($hashtags) : ''), - '$dend' => $datequery, - '$mid' => '', - '$verb' => (($verb) ? urlencode($verb) : ''), - '$net' => (($net) ? urlencode($net) : ''), - '$dbegin' => $datequery2, - '$pf' => (($pf) ? intval($pf) : 0), - '$unseen' => (($unseen) ? urlencode($unseen) : '') - )); - } - $sql_extra3 = ''; - + if($datequery) { $sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery)))); } if($datequery2) { $sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); } - + $sql_extra2 = (($nouveau) ? '' : " AND item.parent = item.id "); $sql_extra3 = (($nouveau) ? '' : $sql_extra3); - + if(x($_GET,'search')) { $search = escape_tags($_GET['search']); if(strpos($search,'#') === 0) { @@ -405,7 +356,7 @@ class Network extends \Zotlabs\Web\Controller { ); } } - + if ($verb) { // the presence of a leading dot in the verb determines @@ -425,7 +376,7 @@ class Network extends \Zotlabs\Web\Controller { ); } } - + if(strlen($file)) { $sql_extra .= term_query('item',$file,TERM_FILE); } @@ -433,52 +384,52 @@ class Network extends \Zotlabs\Web\Controller { if ($dm) { $sql_extra .= " AND item_private = 2 "; } - + if($conv) { $item_thread_top = ''; $sql_extra .= " AND ( author_xchan = '" . dbesc($channel['channel_hash']) . "' OR item_mentionsme = 1 ) "; } - + if($update && ! $load) { - + // only setup pagination on initial page view $pager_sql = ''; - + } else { $itemspage = get_pconfig(local_channel(),'system','itemspage'); App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10)); $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); } - + // cmin and cmax are both -1 when the affinity tool is disabled if(($cmin != (-1)) || ($cmax != (-1))) { - + // Not everybody who shows up in the network stream will be in your address book. // By default those that aren't are assumed to have closeness = 99; but this isn't // recorded anywhere. So if cmax is 99, we'll open the search up to anybody in // the stream with a NULL address book entry. - + $sql_nets .= " AND "; - + if($cmax == 99) $sql_nets .= " ( "; - + $sql_nets .= "( abook.abook_closeness >= " . intval($cmin) . " "; $sql_nets .= " AND abook.abook_closeness <= " . intval($cmax) . " ) "; - + if($cmax == 99) $sql_nets .= " OR abook.abook_closeness IS NULL ) "; - + } - $net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : ''); + $net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : ''); $net_query2 = (($net) ? " and xchan_network = '" . protect_sprintf(dbesc($net)) . "' " : ''); $abook_uids = " and abook.abook_channel = " . local_channel() . " "; $uids = " and item.uid = " . local_channel() . " "; - + if(feature_enabled(local_channel(), 'network_list_mode')) $page_mode = 'list'; else @@ -504,7 +455,7 @@ class Network extends \Zotlabs\Web\Controller { if($nouveau && $load) { // "New Item View" - show all items unthreaded in reverse created date order - $items = q("SELECT item.*, item.id AS item_id, created FROM item + $items = q("SELECT item.*, item.id AS item_id, created FROM item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) $net_query WHERE true $uids $item_normal @@ -517,23 +468,23 @@ class Network extends \Zotlabs\Web\Controller { $parents_str = ids_to_querystr($items,'item_id'); require_once('include/items.php'); - + xchan_query($items); - + $items = fetch_post_tags($items,true); } elseif($update) { - + // Normal conversation view - + if($order === 'post') $ordering = "created"; else $ordering = "commented"; - + if($load) { // Fetch a page full of parent items for this page - $r = q("SELECT item.parent AS item_id FROM item + $r = q("SELECT item.parent AS item_id FROM item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) $net_query WHERE true $uids $item_thread_top $item_normal @@ -557,18 +508,18 @@ class Network extends \Zotlabs\Web\Controller { } // Then fetch all the children of the parents that are on this page - + if($r) { - + $parents_str = ids_to_querystr($r,'item_id'); - + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE true $uids $item_normal AND item.parent IN ( %s ) $sql_extra ", dbesc($parents_str) ); - + xchan_query($items,true); $items = fetch_post_tags($items,true); $items = conv_sort($items,$ordering); @@ -578,20 +529,70 @@ class Network extends \Zotlabs\Web\Controller { } } - + $mode = (($nouveau) ? 'network-new' : 'network'); if($search) $mode = 'search'; - + + if(! $update) { + // The special div is needed for liveUpdate to kick in for this page. + // We only launch liveUpdate if you aren't filtering in some incompatible + // way and also you aren't writing a comment (discovered in javascript). + + $maxheight = get_pconfig(local_channel(),'system','network_divmore_height'); + if(! $maxheight) + $maxheight = 400; + + + $o .= '
' . "\r\n"; + $o .= "\r\n"; + + App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + '$baseurl' => z_root(), + '$pgtype' => 'network', + '$uid' => ((local_channel()) ? local_channel() : '0'), + '$gid' => (($gid) ? $gid : '0'), + '$cid' => (($cid) ? $cid : '0'), + '$cmin' => (($cmin) ? $cmin : '(-1)'), + '$cmax' => (($cmax) ? $cmax : '(-1)'), + '$star' => (($star) ? $star : '0'), + '$liked' => (($liked) ? $liked : '0'), + '$conv' => (($conv) ? $conv : '0'), + '$spam' => (($spam) ? $spam : '0'), + '$fh' => '0', + '$dm' => (($dm) ? $dm : '0'), + '$nouveau' => (($nouveau) ? $nouveau : '0'), + '$wall' => '0', + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), + '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1), + '$search' => (($search) ? urlencode($search) : ''), + '$xchan' => (($xchan) ? urlencode($xchan) : ''), + '$order' => $order, + '$file' => (($file) ? urlencode($file) : ''), + '$cats' => (($category) ? urlencode($category) : ''), + '$tags' => (($hashtags) ? urlencode($hashtags) : ''), + '$dend' => $datequery, + '$mid' => '', + '$verb' => (($verb) ? urlencode($verb) : ''), + '$net' => (($net) ? urlencode($net) : ''), + '$dbegin' => $datequery2, + '$pf' => (($pf) ? intval($pf) : 0), + '$unseen' => (($unseen) ? urlencode($unseen) : ''), + '$page_mode' => $page_mode + )); + } + $o .= conversation($items,$mode,$update,$page_mode); - + if(($items) && (! $update)) $o .= alt_pager(count($items)); $_SESSION['loadtime'] = datetime_convert(); - + return $o; } - + } diff --git a/include/conversation.php b/include/conversation.php index 6615b04c3..087e8c135 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -90,18 +90,18 @@ function item_redir_and_replace_images($body, $images, $cid) { function localize_item(&$item){ if (activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE)){ - + if(! $item['obj']) return; if(intval($item['item_thread_top'])) - return; + return; $obj = json_decode($item['obj'],true); if((! $obj) && ($item['obj'])) { logger('localize_item: failed to decode object: ' . print_r($item['obj'],true)); } - + if(is_array($obj['author']) && $obj['author']['link']) $author_link = get_rel_link($obj['author']['link'],'alternate'); elseif(is_array($obj['actor']) && $obj['actor']['url']) @@ -167,7 +167,7 @@ function localize_item(&$item){ if($author_link && $author_name && $item_url) { $author = '[zrl=' . chanlink_url($item['author']['xchan_url']) . ']' . $item['author']['xchan_name'] . '[/zrl]'; $objauthor = '[zrl=' . chanlink_url($author_link) . ']' . $author_name . '[/zrl]'; - + $plink = '[zrl=' . zid($item_url) . ']' . $post_type . '[/zrl]'; if(activity_match($item['verb'],ACTIVITY_LIKE)) { @@ -189,7 +189,7 @@ function localize_item(&$item){ $item['shortlocalize'] = sprintf($shortbodyverb, '[bdi]' . $author_name . '[/bdi]', $post_type); $item['body'] = $item['localize'] = sprintf($bodyverb, '[bdi]' . $author . '[/bdi]', '[bdi]' . $objauthor . '[/bdi]', $plink); - if($Bphoto != "") + if($Bphoto != "") $item['body'] .= "\n\n\n" . '[zrl=' . chanlink_url($author_link) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]'; } @@ -201,7 +201,7 @@ function localize_item(&$item){ if (activity_match($item['verb'],ACTIVITY_FRIEND)) { - if ($item['obj_type'] == "" || $item['obj_type'] !== ACTIVITY_OBJ_PERSON) + if ($item['obj_type'] == "" || $item['obj_type'] !== ACTIVITY_OBJ_PERSON) return; $Aname = $item['author']['xchan_name']; @@ -209,7 +209,7 @@ function localize_item(&$item){ $obj= json_decode($item['obj'],true); - + $Blink = $Bphoto = ''; if($obj['link']) { @@ -282,7 +282,7 @@ function localize_item(&$item){ $Alink = $item['author']['xchan_url']; $A = '[zrl=' . chanlink_url($Alink) . '][bdi]' . $Aname . '[/bdi][/zrl]'; - + $txt = t('%1$s is %2$s','mood'); $item['body'] = sprintf($txt, $A, t($verb)); @@ -295,15 +295,15 @@ function localize_item(&$item){ // (and update to json storage) if (activity_match($item['verb'],ACTIVITY_TAG)) { - $r = q("SELECT * from item,contact WHERE + $r = q("SELECT * from item,contact WHERE item.contact-id=contact.id AND item.mid='%s';", dbesc($item['parent_mid'])); if(count($r)==0) return; $obj=$r[0]; - + $author = '[zrl=' . zid($item['author-link']) . ']' . $item['author-name'] . '[/zrl]'; $objauthor = '[zrl=' . zid($obj['author-link']) . ']' . $obj['author-name'] . '[/zrl]'; - + switch($obj['verb']){ case ACTIVITY_POST: switch ($obj['obj_type']){ @@ -416,7 +416,7 @@ function count_descendants($item) { * likes (etc.) can apply to other things besides posts. Check if they are post * children, in which case we handle them specially. Activities which are unrecognised * as having special meaning and hidden will be treated as posts or comments and visible - * in the stream. + * in the stream. * * @param array $item * @return boolean @@ -438,14 +438,14 @@ function visible_activity($item) { } // We only need edit activities for other federated protocols - // which do not support edits natively. While this does federate + // which do not support edits natively. While this does federate // edits, it presents a number of issues locally - such as #757 and #758. // The SQL check for an edit activity would not perform that well so to fix these issues - // requires an additional item flag (perhaps 'item_edit_activity') that we can add to the + // requires an additional item flag (perhaps 'item_edit_activity') that we can add to the // query for searches and notifications. - // For now we'll just forget about trying to make edits work on network protocols that - // don't support them. + // For now we'll just forget about trying to make edits work on network protocols that + // don't support them. // if(is_edit_activity($item)) // return false; @@ -455,7 +455,7 @@ function visible_activity($item) { /** * @brief Check if a given activity is an edit activity - * + * * * @param array $item * @return boolean @@ -463,11 +463,11 @@ function visible_activity($item) { function is_edit_activity($item) { - $post_types = [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, basename(ACTIVITY_OBJ_NOTE), basename(ACTIVITY_OBJ_COMMENT)]; + $post_types = [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, basename(ACTIVITY_OBJ_NOTE), basename(ACTIVITY_OBJ_COMMENT)]; - // In order to share edits with networks which have no concept of editing, we'll create + // In order to share edits with networks which have no concept of editing, we'll create // separate activities to indicate the edit. Our network will not require them, since our - // edits are automatically applied and the activity indicated. + // edits are automatically applied and the activity indicated. if(($item['verb'] === ACTIVITY_UPDATE) && (in_array($item['obj_type'],$post_types))) return true; @@ -678,12 +678,12 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa foreach($items as $item) { - $x = [ - 'mode' => $mode, - 'item' => $item + $x = [ + 'mode' => $mode, + 'item' => $item ]; call_hooks('stream_item',$x); - + if($x['item']['blocked']) continue; @@ -699,7 +699,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $is_new = false; if($mode === 'search' || $mode === 'community') { - if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE))) + if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE))) && ($item['id'] != $item['parent'])) continue; } @@ -726,7 +726,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $drop = array( 'pagedropping' => $page_dropping, 'dropping' => $dropping, - 'select' => t('Select'), + 'select' => t('Select'), 'delete' => t('Delete'), ); @@ -769,7 +769,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $tmp_item = array( 'template' => $tpl, 'toplevel' => 'toplevel_item', - 'item_type' => intval($item['item_type']), + 'item_type' => intval($item['item_type']), 'mode' => $mode, 'approve' => t('Approve'), 'delete' => t('Delete'), @@ -844,7 +844,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $conv = new Zotlabs\Lib\ThreadStream($mode, $preview, $uploading, $prepared_item); - // In the display mode we don't have a profile owner. + // In the display mode we don't have a profile owner. if($mode === 'display' && $items) $conv->set_profile_owner($items[0]['uid']); @@ -861,7 +861,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $x = [ 'mode' => $mode, 'item' => $item ]; call_hooks('stream_item',$x); - + if($x['item']['blocked']) continue; @@ -970,9 +970,9 @@ function best_link_url($item) { function thread_action_menu($item,$mode = '') { $menu = []; - + if((local_channel()) && local_channel() == $item['uid']) { - $menu[] = [ + $menu[] = [ 'menu' => 'view_source', 'title' => t('View Source'), 'icon' => 'code', @@ -982,7 +982,7 @@ function thread_action_menu($item,$mode = '') { if(! in_array($mode, [ 'network-new', 'search', 'community'])) { if($item['parent'] == $item['id'] && (get_observer_hash() != $item['author_xchan'])) { - $menu[] = [ + $menu[] = [ 'menu' => 'follow_thread', 'title' => t('Follow Thread'), 'icon' => 'plus', @@ -991,7 +991,7 @@ function thread_action_menu($item,$mode = '') { ]; } - $menu[] = [ + $menu[] = [ 'menu' => 'unfollow_thread', 'title' => t('Unfollow Thread'), 'icon' => 'minus', @@ -1018,7 +1018,7 @@ function author_is_pmable($xchan, $abook) { call_hooks('author_is_pmable',$x); if($x['result'] !== 'unset') return $x['result']; - + if($xchan['xchan_network'] === 'zot' && get_observer_hash()) return true; return false; @@ -1063,7 +1063,7 @@ function thread_author_menu($item, $mode = '') { if($contact) { $poke_link = ((Apps::system_app_installed($local_channel, 'Poke')) ? z_root() . '/poke/?f=&c=' . $contact['abook_id'] : ''); - if (! intval($contact['abook_self'])) + if (! intval($contact['abook_self'])) $contact_url = z_root() . '/connedit/' . $contact['abook_id']; $posts_link = z_root() . '/network/?cid=' . $contact['abook_id']; @@ -1075,7 +1075,7 @@ function thread_author_menu($item, $mode = '') { $ratings_url = (($rating_enabled) ? z_root() . '/ratings/' . urlencode($item['author_xchan']) : ''); if($profile_link) { - $menu[] = [ + $menu[] = [ 'menu' => 'view_profile', 'title' => t('View Profile'), 'icon' => 'fw', @@ -1085,7 +1085,7 @@ function thread_author_menu($item, $mode = '') { } if($posts_link) { - $menu[] = [ + $menu[] = [ 'menu' => 'view_posts', 'title' => t('Recent Activity'), 'icon' => 'fw', @@ -1095,7 +1095,7 @@ function thread_author_menu($item, $mode = '') { } if($follow_url) { - $menu[] = [ + $menu[] = [ 'menu' => 'follow', 'title' => t('Connect'), 'icon' => 'fw', @@ -1105,7 +1105,7 @@ function thread_author_menu($item, $mode = '') { } if($contact_url) { - $menu[] = [ + $menu[] = [ 'menu' => 'connedit', 'title' => t('Edit Connection'), 'icon' => 'fw', @@ -1115,7 +1115,7 @@ function thread_author_menu($item, $mode = '') { } if($pm_url) { - $menu[] = [ + $menu[] = [ 'menu' => 'prv_message', 'title' => t('Message'), 'icon' => 'fw', @@ -1125,7 +1125,7 @@ function thread_author_menu($item, $mode = '') { } if($ratings_url) { - $menu[] = [ + $menu[] = [ 'menu' => 'ratings', 'title' => t('Ratings'), 'icon' => 'fw', @@ -1135,7 +1135,7 @@ function thread_author_menu($item, $mode = '') { } if($poke_link) { - $menu[] = [ + $menu[] = [ 'menu' => 'poke', 'title' => t('Poke'), 'icon' => 'fw', @@ -1209,8 +1209,8 @@ function builtin_activity_puller($item, &$conv_responses) { if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) { $name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown')); - $url = (($item['author_xchan'] && $item['author']['xchan_photo_s']) - ? '' . '' . urlencode($name) . ' ' . $name . '' + $url = (($item['author_xchan'] && $item['author']['xchan_photo_s']) + ? '' . '' . urlencode($name) . ' ' . $name . '' : '' . $name . '' ); @@ -1222,7 +1222,7 @@ function builtin_activity_puller($item, &$conv_responses) { if($item['obj_type'] === 'Answer') continue; - if(! ((isset($conv_responses[$mode][$item['thr_parent'] . '-l'])) + if(! ((isset($conv_responses[$mode][$item['thr_parent'] . '-l'])) && (is_array($conv_responses[$mode][$item['thr_parent'] . '-l'])))) $conv_responses[$mode][$item['thr_parent'] . '-l'] = array(); @@ -1297,9 +1297,9 @@ function status_editor($a, $x, $popup = false, $module='') { } /** - * This is our general purpose content editor. + * This is our general purpose content editor. * It was once nicknamed "jot" and you may see references to "jot" littered throughout the code. - * They are referring to the content editor or components thereof. + * They are referring to the content editor or components thereof. */ function hz_status_editor($a, $x, $popup = false) { @@ -1341,7 +1341,7 @@ function hz_status_editor($a, $x, $popup = false) { $weblink = (($mimetype === 'text/bbcode') ? t('Insert web link') : false); if(x($x, 'hide_weblink')) $weblink = false; - + $embedPhotos = t('Embed (existing) photo from your photo albums'); $writefiles = (($mimetype === 'text/bbcode') ? perm_is_allowed($x['profile_uid'], get_observer_hash(), 'write_storage') : false); @@ -1366,9 +1366,9 @@ function hz_status_editor($a, $x, $popup = false) { $webpage = ((x($x,'webpage')) ? $x['webpage'] : ''); $reset = ((x($x,'reset')) ? $x['reset'] : ''); - + $feature_auto_save_draft = ((feature_enabled($x['profile_uid'], 'auto_save_draft')) ? "true" : "false"); - + $tpl = get_markup_template('jot-header.tpl'); $tplmacros = [ @@ -1394,7 +1394,7 @@ function hz_status_editor($a, $x, $popup = false) { '$reset' => $reset ]; - call_hooks('jot_header_tpl_filter',$tplmacros); + call_hooks('jot_header_tpl_filter',$tplmacros); App::$page['htmlhead'] .= replace_macros($tpl, $tplmacros); $tpl = get_markup_template('jot.tpl'); @@ -1421,7 +1421,7 @@ function hz_status_editor($a, $x, $popup = false) { $catsenabled = ((feature_enabled($x['profile_uid'], 'categories') && (! $webpage)) ? 'categories' : ''); // avoid illegal offset errors - if(! array_key_exists('permissions',$x)) + if(! array_key_exists('permissions',$x)) $x['permissions'] = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ]; $jotplugins = ''; @@ -1539,7 +1539,7 @@ function get_item_children($arr, $parent) { $thr_parent = $item['thr_parent']; if($thr_parent == '') $thr_parent = $item['parent_mid']; - + if($thr_parent == $parent['mid']) { $item['children'] = get_item_children($arr, $item); $children[] = $item; @@ -1698,9 +1698,9 @@ function prepare_page($item) { return replace_macros(get_markup_template($tpl), array( '$body' => $body['html'] )); - + } - + $tpl = get_pconfig($item['uid'], 'system', 'pagetemplate'); if (! $tpl) $tpl = 'page_display.tpl'; diff --git a/view/js/main.js b/view/js/main.js index 3e3fd057c..cd95a8a0b 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -1152,7 +1152,10 @@ function dolike(ident, verb) { if(typeof conv_mode == typeof undefined) conv_mode = ''; - $.get('like/' + ident.toString() + '?verb=' + verb + '&conv_mode=' + conv_mode, function (data) { + if(typeof page_mode == typeof undefined) + page_mode = ''; + + $.get('like/' + ident.toString() + '?verb=' + verb + '&conv_mode=' + conv_mode + '&page_mode=' + page_mode, function (data) { if(data.success) { // this is a bit tricky since the top level thread wrapper wraps the whole thread if($('#thread-wrapper-' + data.orig_id).hasClass('toplevel_item')) { diff --git a/view/tpl/build_query.tpl b/view/tpl/build_query.tpl index 83e756367..af70a9595 100755 --- a/view/tpl/build_query.tpl +++ b/view/tpl/build_query.tpl @@ -1,4 +1,4 @@ -" ; @@ -159,10 +157,10 @@ class Cal extends Controller { 'timezone' => $tz, 'start'=> $start, 'end' => $end, - 'drop' => $drop, + 'drop' => false, 'allDay' => (($rr['adjust']) ? 0 : 1), 'title' => html_entity_decode($rr['summary'], ENT_COMPAT, 'UTF-8'), - 'editable' => $edit ? true : false, + 'editable' => false, 'item' => $rr, 'plink' => [$rr['plink'], t('Link to source')], 'description' => html_entity_decode($rr['description'], ENT_COMPAT, 'UTF-8'), @@ -205,9 +203,9 @@ class Cal extends Controller { '$prev' => t('Previous'), '$next' => t('Next'), '$today' => t('Today'), - '$title' => $title, - '$dtstart' => $dtstart, - '$dtend' => $dtend, + '$title' => '', + '$dtstart' => '', + '$dtend' => '', '$nick' => $nick ]); -- cgit v1.2.3 From aa27f93a9c4f78ddb468a9c6ed00218f61cb25a0 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:00:47 +0000 Subject: cleanup unused/undefined variables --- Zotlabs/Module/Channel_calendar.php | 144 ++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/Zotlabs/Module/Channel_calendar.php b/Zotlabs/Module/Channel_calendar.php index ae4afb2f3..1fa9a45df 100644 --- a/Zotlabs/Module/Channel_calendar.php +++ b/Zotlabs/Module/Channel_calendar.php @@ -1,7 +1,11 @@ set($x[0]); - + $created = $x[0]['created']; $edited = datetime_convert(); } @@ -96,9 +98,9 @@ class Channel_calendar extends \Zotlabs\Web\Controller { $created = $edited = datetime_convert(); $acl->set_from_array($_POST); } - + $post_tags = array(); - $channel = \App::get_channel(); + $channel = App::get_channel(); $ac = $acl->get(); $str_contact_allow = $ac['allow_cid']; @@ -109,22 +111,22 @@ class Channel_calendar extends \Zotlabs\Web\Controller { $private = $acl->is_private(); require_once('include/text.php'); - $results = linkify_tags($desc, local_channel()); + $results = linkify_tags($desc, $uid); if($results) { // Set permissions based on tag replacements - set_linkified_perms($results, $str_contact_allow, $str_group_allow, local_channel(), false, $private); + set_linkified_perms($results, $str_contact_allow, $str_group_allow, $uid, false, $private); foreach($results as $result) { $success = $result['success']; if($success['replaced']) { $post_tags[] = array( - 'uid' => local_channel(), + 'uid' => $uid, 'ttype' => $success['termtype'], 'otype' => TERM_OBJ_POST, 'term' => $success['term'], 'url' => $success['url'] - ); + ); } } } @@ -133,7 +135,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { $cats = explode(',',$categories); foreach($cats as $cat) { $post_tags[] = array( - 'uid' => local_channel(), + 'uid' => $uid, 'ttype' => TERM_CATEGORY, 'otype' => TERM_OBJ_POST, 'term' => trim($cat), @@ -141,7 +143,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { ); } } - + $datarray = array(); $datarray['dtstart'] = $start; $datarray['dtend'] = $finish; @@ -151,7 +153,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { $datarray['etype'] = $type; $datarray['adjust'] = $adjust; $datarray['nofinish'] = 0; - $datarray['uid'] = local_channel(); + $datarray['uid'] = $uid; $datarray['account'] = get_account_id(); $datarray['event_xchan'] = $channel['channel_hash']; $datarray['allow_cid'] = $str_contact_allow; @@ -164,20 +166,20 @@ class Channel_calendar extends \Zotlabs\Web\Controller { $datarray['edited'] = $edited; $datarray['timezone'] = $tz; - + if(intval($_REQUEST['preview'])) { $html = format_event_html($datarray); echo $html; killme(); } - + $event = event_store_event($datarray); - - if($post_tags) + + if($post_tags) $datarray['term'] = $post_tags; - + $item_id = event_store_item($datarray,$event); - + if($item_id) { $r = q("select * from item where id = %d", intval($item_id) @@ -194,27 +196,27 @@ class Channel_calendar extends \Zotlabs\Web\Controller { } } } - - \Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id)); + + Master::Summon(array('Notifier','event',$item_id)); killme(); - + } - - - + + + function get() { - + if(argc() > 2 && argv(1) == 'ical') { $event_id = argv(2); - + require_once('include/security.php'); $sql_extra = permissions_sql(local_channel()); - + $r = q("select * from event where event_hash = '%s' $sql_extra limit 1", dbesc($event_id) ); - if($r) { + if($r) { header('Content-type: text/calendar'); header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"' ); echo ical_wrapper($r); @@ -225,28 +227,26 @@ class Channel_calendar extends \Zotlabs\Web\Controller { return; } } - + if(! local_channel()) { notice( t('Permission denied.') . EOL); return; } if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { - $r = q("update event set dismissed = 1 where id = %d and uid = %d", + q("update event set dismissed = 1 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); } - + if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { - $r = q("update event set dismissed = 0 where id = %d and uid = %d", + q("update event set dismissed = 0 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); } - $channel = \App::get_channel(); - $mode = 'view'; $export = false; $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : ''); @@ -271,31 +271,29 @@ class Channel_calendar extends \Zotlabs\Web\Controller { $event_id = argv(1); } } - + if($mode === 'add') { event_addtocal($item_id,local_channel()); killme(); } - + if($mode == 'view') { - + /* edit/create form */ if($event_id) { - $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) ); - if(count($r)) - $orig_event = $r[0]; } - - $channel = \App::get_channel(); + + $channel = App::get_channel(); if (argv(1) === 'json'){ if (x($_GET,'start')) $start = $_GET['start']; if (x($_GET,'end')) $finish = $_GET['end']; } - + $start = datetime_convert('UTC','UTC',$start); $finish = datetime_convert('UTC','UTC',$finish); $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); @@ -335,7 +333,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { dbesc($adjust_finish) ); } - + if($r && ! $export) { xchan_query($r); $r = fetch_post_tags($r,true); @@ -345,7 +343,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { $events = []; if($r) { - + foreach($r as $rr) { $start = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c')); @@ -369,9 +367,9 @@ class Channel_calendar extends \Zotlabs\Web\Controller { } $edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root().'/events/'.$rr['event_hash'].'?expandform=1',t('Edit event'),'','') : false); - + $drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'',''); - + $tz = get_iconfig($rr, 'event', 'timezone'); if(! $tz) @@ -401,7 +399,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { ); } } - + if($export) { header('Content-type: text/calendar'); header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"' ); @@ -409,20 +407,20 @@ class Channel_calendar extends \Zotlabs\Web\Controller { killme(); } - if (\App::$argv[1] === 'json'){ + if (App::$argv[1] === 'json'){ json_return_and_die($events); } } - + if($mode === 'drop' && $event_id) { $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) ); - + $sync_event = $r[0]; - + if($r) { $r = q("delete from event where event_hash = '%s' and uid = %d", dbesc($event_id), @@ -464,7 +462,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { // if this is a different page type or it's just a local delete // but not by the item author or owner, do a simple deletion - $complex = false; + $complex = false; if(intval($i[0]['item_type']) || ($local_delete && (! $can_delete))) { drop_item($i[0]['id']); @@ -495,7 +493,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller { killme(); } } - + } - + } -- cgit v1.2.3 From 597d7bd532c35327c28a1012add9b81e5e0157b5 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:02:03 +0000 Subject: formatting --- Zotlabs/Module/Channel_calendar.php | 297 ++++++++++++++++++------------------ 1 file changed, 149 insertions(+), 148 deletions(-) diff --git a/Zotlabs/Module/Channel_calendar.php b/Zotlabs/Module/Channel_calendar.php index 1fa9a45df..ac1545644 100644 --- a/Zotlabs/Module/Channel_calendar.php +++ b/Zotlabs/Module/Channel_calendar.php @@ -1,4 +1,5 @@ set($x[0]); $created = $x[0]['created']; - $edited = datetime_convert(); + $edited = datetime_convert(); } else { $created = $edited = datetime_convert(); @@ -100,26 +101,26 @@ class Channel_calendar extends Controller { } $post_tags = array(); - $channel = App::get_channel(); - $ac = $acl->get(); + $channel = App::get_channel(); + $ac = $acl->get(); $str_contact_allow = $ac['allow_cid']; $str_group_allow = $ac['allow_gid']; - $str_contact_deny = $ac['deny_cid']; - $str_group_deny = $ac['deny_gid']; + $str_contact_deny = $ac['deny_cid']; + $str_group_deny = $ac['deny_gid']; $private = $acl->is_private(); require_once('include/text.php'); $results = linkify_tags($desc, $uid); - if($results) { + if ($results) { // Set permissions based on tag replacements set_linkified_perms($results, $str_contact_allow, $str_group_allow, $uid, false, $private); - foreach($results as $result) { + foreach ($results as $result) { $success = $result['success']; - if($success['replaced']) { + if ($success['replaced']) { $post_tags[] = array( 'uid' => $uid, 'ttype' => $success['termtype'], @@ -131,9 +132,9 @@ class Channel_calendar extends Controller { } } - if(strlen($categories)) { - $cats = explode(',',$categories); - foreach($cats as $cat) { + if (strlen($categories)) { + $cats = explode(',', $categories); + foreach ($cats as $cat) { $post_tags[] = array( 'uid' => $uid, 'ttype' => TERM_CATEGORY, @@ -144,30 +145,30 @@ class Channel_calendar extends Controller { } } - $datarray = array(); - $datarray['dtstart'] = $start; - $datarray['dtend'] = $finish; - $datarray['summary'] = $summary; + $datarray = array(); + $datarray['dtstart'] = $start; + $datarray['dtend'] = $finish; + $datarray['summary'] = $summary; $datarray['description'] = $desc; - $datarray['location'] = $location; - $datarray['etype'] = $type; - $datarray['adjust'] = $adjust; - $datarray['nofinish'] = 0; - $datarray['uid'] = $uid; - $datarray['account'] = get_account_id(); + $datarray['location'] = $location; + $datarray['etype'] = $type; + $datarray['adjust'] = $adjust; + $datarray['nofinish'] = 0; + $datarray['uid'] = $uid; + $datarray['account'] = get_account_id(); $datarray['event_xchan'] = $channel['channel_hash']; - $datarray['allow_cid'] = $str_contact_allow; - $datarray['allow_gid'] = $str_group_allow; - $datarray['deny_cid'] = $str_contact_deny; - $datarray['deny_gid'] = $str_group_deny; - $datarray['private'] = intval($private); - $datarray['id'] = $event_id; - $datarray['created'] = $created; - $datarray['edited'] = $edited; - $datarray['timezone'] = $tz; - - - if(intval($_REQUEST['preview'])) { + $datarray['allow_cid'] = $str_contact_allow; + $datarray['allow_gid'] = $str_group_allow; + $datarray['deny_cid'] = $str_contact_deny; + $datarray['deny_gid'] = $str_group_deny; + $datarray['private'] = intval($private); + $datarray['id'] = $event_id; + $datarray['created'] = $created; + $datarray['edited'] = $edited; + $datarray['timezone'] = $tz; + + + if (intval($_REQUEST['preview'])) { $html = format_event_html($datarray); echo $html; killme(); @@ -175,39 +176,38 @@ class Channel_calendar extends Controller { $event = event_store_event($datarray); - if($post_tags) + if ($post_tags) $datarray['term'] = $post_tags; - $item_id = event_store_item($datarray,$event); + $item_id = event_store_item($datarray, $event); - if($item_id) { + if ($item_id) { $r = q("select * from item where id = %d", intval($item_id) ); - if($r) { + if ($r) { xchan_query($r); $sync_item = fetch_post_tags($r); - $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", + $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", dbesc($r[0]['resource_id']), intval($channel['channel_id']) ); - if($z) { - Libsync::build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z)); + if ($z) { + Libsync::build_sync_packet($channel['channel_id'], array('event_item' => array(encode_item($sync_item[0], true)), 'event' => $z)); } } } - Master::Summon(array('Notifier','event',$item_id)); + Master::Summon(array('Notifier', 'event', $item_id)); killme(); } - function get() { - if(argc() > 2 && argv(1) == 'ical') { + if (argc() > 2 && argv(1) == 'ical') { $event_id = argv(2); require_once('include/security.php'); @@ -216,71 +216,71 @@ class Channel_calendar extends Controller { $r = q("select * from event where event_hash = '%s' $sql_extra limit 1", dbesc($event_id) ); - if($r) { + if ($r) { header('Content-type: text/calendar'); - header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"' ); + header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"'); echo ical_wrapper($r); killme(); } else { - notice( t('Event not found.') . EOL ); + notice(t('Event not found.') . EOL); return; } } - if(! local_channel()) { - notice( t('Permission denied.') . EOL); + if (!local_channel()) { + notice(t('Permission denied.') . EOL); return; } - if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { + if ((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { q("update event set dismissed = 1 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); } - if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { + if ((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { q("update event set dismissed = 0 where id = %d and uid = %d", intval(argv(2)), intval(local_channel()) ); } - $mode = 'view'; - $export = false; - $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : ''); + $mode = 'view'; + $export = false; + $ignored = ((x($_REQUEST, 'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : ''); - if(argc() > 1) { - if(argc() > 2 && argv(1) === 'add') { - $mode = 'add'; + if (argc() > 1) { + if (argc() > 2 && argv(1) === 'add') { + $mode = 'add'; $item_id = intval(argv(2)); } - if(argc() > 2 && argv(1) === 'drop') { - $mode = 'drop'; + if (argc() > 2 && argv(1) === 'drop') { + $mode = 'drop'; $event_id = argv(2); } - if(argc() <= 2 && argv(1) === 'export') { + if (argc() <= 2 && argv(1) === 'export') { $export = true; } - if(argc() > 2 && intval(argv(1)) && intval(argv(2))) { + if (argc() > 2 && intval(argv(1)) && intval(argv(2))) { $mode = 'view'; } - if(argc() <= 2) { - $mode = 'view'; + if (argc() <= 2) { + $mode = 'view'; $event_id = argv(1); } } - if($mode === 'add') { - event_addtocal($item_id,local_channel()); + if ($mode === 'add') { + event_addtocal($item_id, local_channel()); killme(); } - if($mode == 'view') { + if ($mode == 'view') { /* edit/create form */ - if($event_id) { + if ($event_id) { q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) @@ -289,25 +289,25 @@ class Channel_calendar extends Controller { $channel = App::get_channel(); - if (argv(1) === 'json'){ - if (x($_GET,'start')) $start = $_GET['start']; - if (x($_GET,'end')) $finish = $_GET['end']; + if (argv(1) === 'json') { + if (x($_GET, 'start')) $start = $_GET['start']; + if (x($_GET, 'end')) $finish = $_GET['end']; } - $start = datetime_convert('UTC','UTC',$start); - $finish = datetime_convert('UTC','UTC',$finish); - $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); + $start = datetime_convert('UTC', 'UTC', $start); + $finish = datetime_convert('UTC', 'UTC', $finish); + $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); - if (x($_GET,'id')){ - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id + if (x($_GET, 'id')) { + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id from event left join item on item.resource_id = event.event_hash where item.resource_type = 'event' and event.uid = %d and event.id = %d limit 1", intval(local_channel()), intval($_GET['id']) ); } - elseif($export) { + elseif ($export) { $r = q("SELECT event.*, item.id as item_id from event left join item on item.resource_id = event.event_hash where event.uid = %d and event.dtstart > '%s' and event.dtend > event.dtstart", @@ -334,86 +334,87 @@ class Channel_calendar extends Controller { ); } - if($r && ! $export) { + if ($r && !$export) { xchan_query($r); - $r = fetch_post_tags($r,true); + $r = fetch_post_tags($r, true); $r = sort_by_date($r); } $events = []; - if($r) { + if ($r) { - foreach($r as $rr) { + foreach ($r as $rr) { $start = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c')); - if ($rr['nofinish']){ + if ($rr['nofinish']) { $end = null; - } else { + } + else { $end = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c')); } - $catsenabled = feature_enabled(local_channel(),'categories'); - $categories = ''; - if($catsenabled){ - if($rr['term']) { + $catsenabled = feature_enabled(local_channel(), 'categories'); + $categories = ''; + if ($catsenabled) { + if ($rr['term']) { $cats = get_terms_oftype($rr['term'], TERM_CATEGORY); foreach ($cats as $cat) { - if(strlen($categories)) + if (strlen($categories)) $categories .= ', '; $categories .= $cat['term']; } } } - $edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root().'/events/'.$rr['event_hash'].'?expandform=1',t('Edit event'),'','') : false); + $edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root() . '/events/' . $rr['event_hash'] . '?expandform=1', t('Edit event'), '', '') : false); - $drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'',''); + $drop = array(z_root() . '/events/drop/' . $rr['event_hash'], t('Delete event'), '', ''); $tz = get_iconfig($rr, 'event', 'timezone'); - if(! $tz) + if (!$tz) $tz = 'UTC'; $events[] = array( 'calendar_id' => 'channel_calendar', - 'rw' => true, - 'id'=>$rr['id'], - 'uri' => $rr['event_hash'], - 'timezone' => $tz, - 'start'=> $start, - 'end' => $end, - 'drop' => $drop, - 'allDay' => (($rr['adjust']) ? 0 : 1), - 'title' => html_entity_decode($rr['summary'], ENT_COMPAT, 'UTF-8'), - 'editable' => $edit ? true : false, - 'item' => $rr, - 'plink' => [$rr['plink'], t('Link to source')], + 'rw' => true, + 'id' => $rr['id'], + 'uri' => $rr['event_hash'], + 'timezone' => $tz, + 'start' => $start, + 'end' => $end, + 'drop' => $drop, + 'allDay' => (($rr['adjust']) ? 0 : 1), + 'title' => html_entity_decode($rr['summary'], ENT_COMPAT, 'UTF-8'), + 'editable' => $edit ? true : false, + 'item' => $rr, + 'plink' => [$rr['plink'], t('Link to source')], 'description' => html_entity_decode($rr['description'], ENT_COMPAT, 'UTF-8'), - 'location' => html_entity_decode($rr['location'], ENT_COMPAT, 'UTF-8'), - 'allow_cid' => expand_acl($rr['allow_cid']), - 'allow_gid' => expand_acl($rr['allow_gid']), - 'deny_cid' => expand_acl($rr['deny_cid']), - 'deny_gid' => expand_acl($rr['deny_gid']), - 'categories' => $categories + 'location' => html_entity_decode($rr['location'], ENT_COMPAT, 'UTF-8'), + 'allow_cid' => expand_acl($rr['allow_cid']), + 'allow_gid' => expand_acl($rr['allow_gid']), + 'deny_cid' => expand_acl($rr['deny_cid']), + 'deny_gid' => expand_acl($rr['deny_gid']), + 'categories' => $categories ); } } - if($export) { + if ($export) { header('Content-type: text/calendar'); - header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"' ); + header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"'); echo ical_wrapper($r); killme(); } - if (App::$argv[1] === 'json'){ + if (App::$argv[1] === 'json') { json_return_and_die($events); } } - if($mode === 'drop' && $event_id) { + if ($mode === 'drop' && $event_id) { $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($event_id), intval(local_channel()) @@ -421,16 +422,16 @@ class Channel_calendar extends Controller { $sync_event = $r[0]; - if($r) { + if ($r) { $r = q("delete from event where event_hash = '%s' and uid = %d", dbesc($event_id), intval(local_channel()) ); - if($r) { + if ($r) { $sync_event['event_deleted'] = 1; - Libsync::build_sync_packet(0,array('event' => array($sync_event))); + Libsync::build_sync_packet(0, array('event' => array($sync_event))); $i = q("select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d", dbesc($event_id), @@ -439,11 +440,11 @@ class Channel_calendar extends Controller { if ($i) { - $can_delete = false; + $can_delete = false; $local_delete = true; $ob_hash = get_observer_hash(); - if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) { + if ($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) { $can_delete = true; } @@ -451,45 +452,45 @@ class Channel_calendar extends Controller { // If the item originated on this site+channel the deletion will propagate downstream. // Otherwise just the local copy is removed. - if(is_site_admin()) { + if (is_site_admin()) { $local_delete = true; - if(intval($i[0]['item_origin'])) + if (intval($i[0]['item_origin'])) $can_delete = true; } - if($can_delete || $local_delete) { + if ($can_delete || $local_delete) { // if this is a different page type or it's just a local delete // but not by the item author or owner, do a simple deletion $complex = false; - if(intval($i[0]['item_type']) || ($local_delete && (! $can_delete))) { + if (intval($i[0]['item_type']) || ($local_delete && (!$can_delete))) { drop_item($i[0]['id']); } else { // complex deletion that needs to propagate and be performed in phases - drop_item($i[0]['id'],true,DROPITEM_PHASE1); + drop_item($i[0]['id'], true, DROPITEM_PHASE1); $complex = true; } $ii = q("select * from item where id = %d", intval($i[0]['id']) ); - if($ii) { + if ($ii) { xchan_query($ii); $sync_item = fetch_post_tags($ii); - Libsync::build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true)))); + Libsync::build_sync_packet($i[0]['uid'], array('item' => array(encode_item($sync_item[0], true)))); } - if($complex) { - tag_deliver($i[0]['uid'],$i[0]['id']); + if ($complex) { + tag_deliver($i[0]['uid'], $i[0]['id']); } } } killme(); } - notice( t('Failed to remove event' ) . EOL); + notice(t('Failed to remove event') . EOL); killme(); } } -- cgit v1.2.3 From dde0f3a4032d2a24f1afa6941452c7c4e933cda7 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:03:49 +0000 Subject: formatting --- Zotlabs/Module/Attach.php | 67 ++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/Zotlabs/Module/Attach.php b/Zotlabs/Module/Attach.php index 172f6a4bc..5f5779b51 100644 --- a/Zotlabs/Module/Attach.php +++ b/Zotlabs/Module/Attach.php @@ -1,4 +1,5 @@ $zip_filename, - 'zip_path' => $zip_path + 'zip_path' => $zip_path ]; Verify::create('zip_token', 0, $token, json_encode($meta)); json_return_and_die([ 'success' => true, - 'token' => $token + 'token' => $token ]); } @@ -63,28 +64,28 @@ class Attach extends Controller { function get() { - if(argc() < 2) { - notice( t('Item not available.') . EOL); + if (argc() < 2) { + notice(t('Item not available.') . EOL); return; } $token = ((x($_REQUEST, 'token')) ? $_REQUEST['token'] : ''); - if(argv(1) === 'download') { + if (argv(1) === 'download') { $meta = Verify::get_meta('zip_token', 0, $token); - if(! $meta) + if (!$meta) killme(); $meta = json_decode($meta, true); header('Content-Type: application/zip'); - header('Content-Disposition: attachment; filename="'. $meta['zip_filename'] . '"'); + header('Content-Disposition: attachment; filename="' . $meta['zip_filename'] . '"'); header('Content-Length: ' . filesize($meta['zip_path'])); $istream = fopen($meta['zip_path'], 'rb'); $ostream = fopen('php://output', 'wb'); - if($istream && $ostream) { + if ($istream && $ostream) { pipe_streams($istream, $ostream); fclose($istream); fclose($ostream); @@ -94,10 +95,10 @@ class Attach extends Controller { killme(); } - $r = attach_by_hash(argv(1),get_observer_hash(),((argc() > 2) ? intval(argv(2)) : 0)); + $r = attach_by_hash(argv(1), get_observer_hash(), ((argc() > 2) ? intval(argv(2)) : 0)); - if(! $r['success']) { - notice( $r['message'] . EOL); + if (!$r['success']) { + notice($r['message'] . EOL); return; } @@ -105,27 +106,27 @@ class Attach extends Controller { intval($r['data']['uid']) ); - if(! $c) + if (!$c) return; - $unsafe_types = array('text/html','text/css','application/javascript'); + $unsafe_types = array('text/html', 'text/css', 'application/javascript'); - if(in_array($r['data']['filetype'],$unsafe_types) && (! channel_codeallowed($r['data']['uid']))) { - header('Content-Type: text/plain'); + if (in_array($r['data']['filetype'], $unsafe_types) && (!channel_codeallowed($r['data']['uid']))) { + header('Content-Type: text/plain'); } else { header('Content-Type: ' . $r['data']['filetype']); } header('Content-Disposition: attachment; filename="' . $r['data']['filename'] . '"'); - if(intval($r['data']['os_storage'])) { + if (intval($r['data']['os_storage'])) { $fname = $r['data']['content']; - if(strpos($fname,'store') !== false) - $istream = fopen($fname,'rb'); + if (strpos($fname, 'store') !== false) + $istream = fopen($fname, 'rb'); else - $istream = fopen('store/' . $c[0]['channel_address'] . '/' . $fname,'rb'); - $ostream = fopen('php://output','wb'); - if($istream && $ostream) { + $istream = fopen('store/' . $c[0]['channel_address'] . '/' . $fname, 'rb'); + $ostream = fopen('php://output', 'wb'); + if ($istream && $ostream) { pipe_streams($istream, $ostream); fclose($istream); fclose($ostream); @@ -140,14 +141,14 @@ class Attach extends Controller { public function zip_archive_handler($zip, $attach_ids, $attach_path, $pass = 1) { $observer_hash = get_observer_hash(); - $single = ((count($attach_ids) == 1) ? true : false); + $single = ((count($attach_ids) == 1) ? true : false); $download_name = 'download.zip'; - foreach($attach_ids as $attach_id) { + foreach ($attach_ids as $attach_id) { $r = attach_by_id($attach_id, $observer_hash); - if (! $r['success']) { + if (!$r['success']) { continue; } @@ -158,8 +159,8 @@ class Attach extends Controller { if ($attach_path) { $strip_str = $attach_path . '/'; - $count = strlen($strip_str); - $zip_path = substr($r['data']['display_path'], $count); + $count = strlen($strip_str); + $zip_path = substr($r['data']['display_path'], $count); } if ($r['data']['is_dir']) { -- cgit v1.2.3 From 50fb658776e82bd343faf2f5aeb81402abd499c5 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:10:44 +0000 Subject: fix undefined variable --- Zotlabs/Module/Chanview.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Chanview.php b/Zotlabs/Module/Chanview.php index 12e1891d4..8ae4841b4 100644 --- a/Zotlabs/Module/Chanview.php +++ b/Zotlabs/Module/Chanview.php @@ -70,7 +70,7 @@ class Chanview extends \Zotlabs\Web\Controller { $zf = Zotfinger::exec($_REQUEST['url'], null); if(array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $_REQUEST['url'] && intval($zf['signature']['header_valid'])) { - Libzot::import_xchan($j); + Libzot::import_xchan($zf['data']); $r = q("select * from xchan where xchan_url = '%s'", dbesc($_REQUEST['url']) ); -- cgit v1.2.3 From 1e474c968947314eff38fe6238c17134cb521dc0 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:14:48 +0000 Subject: unused variable and missing break statement --- Zotlabs/Module/Connections.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php index 7dc301623..5025f4e22 100644 --- a/Zotlabs/Module/Connections.php +++ b/Zotlabs/Module/Connections.php @@ -109,6 +109,7 @@ class Connections extends \Zotlabs\Web\Controller { case 'all': $head = t('All'); + break; default: $search_flags = " and abook_blocked = 0 and abook_ignored = 0 and abook_hidden = 0 and abook_archived = 0 and abook_not_here = 0 "; $active = true; @@ -238,7 +239,7 @@ class Connections extends \Zotlabs\Web\Controller { } $r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash - where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ", + where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ", intval(local_channel()) ); if($r) { @@ -247,7 +248,7 @@ class Connections extends \Zotlabs\Web\Controller { } $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash - WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra $sql_extra2 ORDER BY $sql_order LIMIT %d OFFSET %d ", + WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ORDER BY $sql_order LIMIT %d OFFSET %d ", intval(local_channel()), intval(App::$pager['itemspage']), intval(App::$pager['start']) -- cgit v1.2.3 From f7222d43c9890600ef83712c21105e7d99618c5e Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:26:22 +0000 Subject: only vars can be passed by reference --- Zotlabs/Module/Embedphotos.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Zotlabs/Module/Embedphotos.php b/Zotlabs/Module/Embedphotos.php index 9b0884197..ed5b24724 100644 --- a/Zotlabs/Module/Embedphotos.php +++ b/Zotlabs/Module/Embedphotos.php @@ -40,7 +40,8 @@ class Embedphotos extends \Zotlabs\Web\Controller { if (!$href) { json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false)); } - $resource_id = array_pop(explode('/', $href)); + $arr = explode('/', $href); + $resource_id = array_pop($arr); $x = self::photolink($resource_id); if($x) json_return_and_die(array('status' => true, 'photolink' => $x, 'resource_id' => $resource_id)); -- cgit v1.2.3 From 889581e35be793859963375aeb5a6d7ff2884a60 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:36:48 +0000 Subject: wrong variable name --- Zotlabs/Module/Notifications.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Module/Notifications.php b/Zotlabs/Module/Notifications.php index 1762ad5f6..55268e0a2 100644 --- a/Zotlabs/Module/Notifications.php +++ b/Zotlabs/Module/Notifications.php @@ -19,7 +19,7 @@ class Notifications extends \Zotlabs\Web\Controller { $r = q("select count(*) as total from notify where uid = %d and seen = 0", intval(local_channel()) ); - if($r && intval($t[0]['total']) > 49) { + if($r && intval($r[0]['total']) > 49) { $r = q("select * from notify where uid = %d and seen = 0 order by created desc limit 50", intval(local_channel()) @@ -32,7 +32,7 @@ class Notifications extends \Zotlabs\Web\Controller { $r2 = q("select * from notify where uid = %d and seen = 1 order by created desc limit %d", intval(local_channel()), - intval(50 - intval($t[0]['total'])) + intval(50 - intval($r[0]['total'])) ); $r = array_merge($r1,$r2); } @@ -41,7 +41,7 @@ class Notifications extends \Zotlabs\Web\Controller { $notifications_available = 1; foreach ($r as $rr) { $x = strip_tags(bbcode($rr['msg'])); - $notif_content .= replace_macros(get_markup_template('notify.tpl'),array( + $notif_content = replace_macros(get_markup_template('notify.tpl'),array( '$item_link' => z_root().'/notify/view/'. $rr['id'], '$item_image' => $rr['photo'], '$item_text' => $x, @@ -52,7 +52,7 @@ class Notifications extends \Zotlabs\Web\Controller { } } else { - $notif_content .= t('No more system notifications.'); + $notif_content = t('No more system notifications.'); } $o .= replace_macros(get_markup_template('notifications.tpl'),array( -- cgit v1.2.3 From e55ea8b126f3da4c119513b018ea8d939fcd3a9f Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:52:18 +0000 Subject: undefined variable $filename --- Zotlabs/Module/Photo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 814705a85..041bdf5a2 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -147,7 +147,7 @@ class Photo extends \Zotlabs\Web\Controller { ); if($r) { $allowed = (-1); - + $filename = $r[0]['filename']; $u = intval($r[0]['photo_usage']); if($u) { $allowed = 1; -- cgit v1.2.3 From 60b76c53fc9d4261527f4759e16b06a0b82b3d9f Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 20:58:31 +0000 Subject: fix undefined var --- Zotlabs/Module/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php index 4235f0b97..0373630a9 100644 --- a/Zotlabs/Module/Profile.php +++ b/Zotlabs/Module/Profile.php @@ -90,7 +90,7 @@ class Profile extends \Zotlabs\Web\Controller { if(argc() > 2 && argv(2) === 'vcard') { header('Content-type: text/vcard'); - header('content-disposition: attachment; filename="' . t('vcard') . '-' . $profile['channel_address'] . '.vcf"' ); + header('content-disposition: attachment; filename="' . t('vcard') . '-' . \App::$profile['channel_address'] . '.vcf"' ); echo \App::$profile['profile_vcard']; killme(); } -- cgit v1.2.3 From 5f5b3f3d4c616a0240eb500adcfb7f3f8907567e Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 21:02:13 +0000 Subject: remove unused global var --- Zotlabs/Module/Regver.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/Zotlabs/Module/Regver.php b/Zotlabs/Module/Regver.php index 82b162f56..c45723063 100644 --- a/Zotlabs/Module/Regver.php +++ b/Zotlabs/Module/Regver.php @@ -6,8 +6,6 @@ class Regver extends \Zotlabs\Web\Controller { function get() { - global $lang; - $_SESSION['return_url'] = \App::$cmd; if(argc() != 3) -- cgit v1.2.3 From a2776ade8168b22e67219aaa11137efda5797afc Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 21:19:07 +0000 Subject: exec is marked deprecated --- Zotlabs/Module/Cdav.php | 2 +- Zotlabs/Module/Cloud.php | 2 +- Zotlabs/Module/Dav.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php index f5c5f4384..fe697a526 100644 --- a/Zotlabs/Module/Cdav.php +++ b/Zotlabs/Module/Cdav.php @@ -284,7 +284,7 @@ class Cdav extends Controller { $server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin()); // And off we go! - $server->exec(); + $server->start(); killme(); diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 39ae0f92f..3d1b97980 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -105,7 +105,7 @@ class Cloud extends Controller { // All we need to do now, is to fire up the server - $server->exec(); + $server->start(); if($browser->build_page) construct_page(); diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 82d773139..96fe2c898 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -124,7 +124,7 @@ class Dav extends \Zotlabs\Web\Controller { // $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth)); // All we need to do now, is to fire up the server - $server->exec(); + $server->start(); killme(); } -- cgit v1.2.3 From 4d63c37c38429b9d98bb612cc55956f9650bdb56 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 15 Jan 2021 21:23:14 +0000 Subject: HTTPSig::get_zotfinger_key() only takes the id arg --- Zotlabs/Web/HTTPSig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Web/HTTPSig.php b/Zotlabs/Web/HTTPSig.php index 1f6979191..0b3e2bf2e 100644 --- a/Zotlabs/Web/HTTPSig.php +++ b/Zotlabs/Web/HTTPSig.php @@ -225,7 +225,7 @@ class HTTPSig { } if($keytype === 'zot6') { - $key = self::get_zotfinger_key($id,$force); + $key = self::get_zotfinger_key($id); if($key) { return $key; } -- cgit v1.2.3 From 395b42778779b657749f96c83286f493fd0ccba2 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 16 Jan 2021 09:09:54 +0000 Subject: cleanup mod like --- Zotlabs/Module/Like.php | 376 +++++++++++++++++++++++------------------------- 1 file changed, 180 insertions(+), 196 deletions(-) diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index f5f3515c0..e3fe4a954 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -1,37 +1,42 @@ ACTIVITY_LIKE , - 'dislike' => ACTIVITY_DISLIKE , - 'agree' => ACTIVITY_AGREE , - 'disagree' => ACTIVITY_DISAGREE , - 'abstain' => ACTIVITY_ABSTAIN , - 'attendyes' => ACTIVITY_ATTEND , - 'attendno' => ACTIVITY_ATTENDNO , + 'like' => ACTIVITY_LIKE, + 'dislike' => ACTIVITY_DISLIKE, + 'agree' => ACTIVITY_AGREE, + 'disagree' => ACTIVITY_DISAGREE, + 'abstain' => ACTIVITY_ABSTAIN, + 'attendyes' => ACTIVITY_ATTEND, + 'attendno' => ACTIVITY_ATTENDNO, 'attendmaybe' => ACTIVITY_ATTENDMAYBE ]; // unlike (etc.) reactions are an undo of positive reactions, rather than a negative action. // The activity is the same in undo actions and will have the same activity mapping - if(substr($reaction,0,2) === 'un') { - $reaction = substr($reaction,2); + if (substr($reaction, 0, 2) === 'un') { + $reaction = substr($reaction, 2); } - if(array_key_exists($reaction,$acts)) { + if (array_key_exists($reaction, $acts)) { return $acts[$reaction]; } @@ -44,21 +49,21 @@ class Like extends \Zotlabs\Web\Controller { $page_mode = (($arr['item']['item_thread_top'] && $_REQUEST['page_mode']) ? $_REQUEST['page_mode'] : 'r_preview'); $conv_mode = (($_REQUEST['conv_mode']) ? $_REQUEST['conv_mode'] : 'network'); - if($conv_mode === 'channel') { + if ($conv_mode === 'channel') { $parts = explode('@', $arr['owner_xchan']['xchan_addr']); profile_load($parts[0]); } $item_normal = item_normal(); - if($page_mode === 'list') { + if ($page_mode === 'list') { $items = q("SELECT item.*, item.id AS item_id FROM item WHERE uid = %d $item_normal AND parent = %d", intval($arr['item']['uid']), intval($arr['item']['parent']) ); - xchan_query($items,true); + xchan_query($items, true); $items = fetch_post_tags($items, true); $items = conv_sort($items, 'commented'); } @@ -75,17 +80,16 @@ class Like extends \Zotlabs\Web\Controller { dbesc(ACTIVITY_ATTENDNO), dbesc(ACTIVITY_ATTENDMAYBE) ); - xchan_query($activities,true); + xchan_query($activities, true); $items = array_merge([$arr['item']], $activities); $items = fetch_post_tags($items, true); } - $ret = [ 'success' => 1, 'orig_id' => $arr['orig_item_id'], //this is required for pubstream items where $item_id != $item['id'] - 'id' => $arr['item']['id'], - 'html' => conversation($items, $conv_mode, true, $page_mode), + 'id' => $arr['item']['id'], + 'html' => conversation($items, $conv_mode, true, $page_mode), ]; return $ret; @@ -93,19 +97,18 @@ class Like extends \Zotlabs\Web\Controller { public function get() { - $o = EMPTY_STR; - + $o = EMPTY_STR; $sys_channel = get_sys_channel(); - $sys_channel_id = (($sys_channel) ? $sys_channel['channel_id'] : 0); - - $observer = \App::get_observer(); + $observer = App::get_observer(); $interactive = $_REQUEST['interactive']; - if((! $observer) || ($interactive)) { + + if ((!$observer) || ($interactive)) { $o .= '

' . t('Like/Dislike') . '

'; $o .= EOL . EOL; - if(! $observer) { - $_SESSION['return_url'] = \App::$query_string; + if (!$observer) { + $_SESSION['return_url'] = App::$query_string; + $o .= t('This action is restricted to members.') . EOL; $o .= t('Please login with your $Projectname ID or register as a new $Projectname member to continue.') . EOL; return $o; @@ -113,56 +116,54 @@ class Like extends \Zotlabs\Web\Controller { } $verb = notags(trim($_GET['verb'])); - $mode = (($_GET['conv_mode']) ? $_GET['conv_mode'] : ''); - if(! $verb) + if (!$verb) $verb = 'like'; $activity = $this->reaction_to_activity($verb); - if(! $activity) { + if (!$activity) { return EMPTY_STR; } $is_rsvp = false; - if (in_array($activity, [ ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE ])) { + if (in_array($activity, [ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE])) { $is_rsvp = true; } - $extended_like = false; - $object = $target = null; - $post_type = EMPTY_STR; - $objtype = EMPTY_STR; + $object = $target = null; + $post_type = EMPTY_STR; + $objtype = EMPTY_STR; - if(argc() == 3) { + if (argc() == 3) { - if(! $observer) + if (!$observer) killme(); $extended_like = true; - $obj_type = argv(1); - $obj_id = argv(2); - $public = true; + $obj_type = argv(1); + $obj_id = argv(2); + $public = true; - if($obj_type == 'profile') { + if ($obj_type == 'profile') { $r = q("select * from profile where profile_guid = '%s' limit 1", dbesc(argv(2)) ); - if(! $r) + if (!$r) killme(); $owner_uid = $r[0]['uid']; - if($r[0]['is_default']) + if ($r[0]['is_default']) $public = true; - if(! $public) { + if (!$public) { $d = q("select abook_xchan from abook where abook_profile = '%s' and abook_channel = %d", dbesc($r[0]['profile_guid']), intval($owner_uid) ); - if(! $d) { + if (!$d) { // forgery - illegal - if($interactive) { - notice( t('Invalid request.') . EOL); + if ($interactive) { + notice(t('Invalid request.') . EOL); return $o; } killme(); @@ -170,25 +171,25 @@ class Like extends \Zotlabs\Web\Controller { // $d now contains a list of those who can see this profile - only send the status notification // to them. $allow_cid = $allow_gid = $deny_cid = $deny_gid = ''; - foreach($d as $dd) { + foreach ($d as $dd) { $allow_cid .= '<' . $dd['abook_xchan'] . '>'; } } $post_type = t('channel'); - $objtype = ACTIVITY_OBJ_PROFILE; + $objtype = ACTIVITY_OBJ_PROFILE; $profile = $r[0]; } - elseif($obj_type == 'thing') { + elseif ($obj_type == 'thing') { $r = q("select * from obj where obj_type = %d and obj_obj = '%s' limit 1", - intval(TERM_OBJ_THING), - dbesc(argv(2)) - ); + intval(TERM_OBJ_THING), + dbesc(argv(2)) + ); - if(! $r) { - if($interactive) { - notice( t('Invalid request.') . EOL); + if (!$r) { + if ($interactive) { + notice(t('Invalid request.') . EOL); return $o; } killme(); @@ -198,19 +199,19 @@ class Like extends \Zotlabs\Web\Controller { $allow_cid = $r[0]['allow_cid']; $allow_gid = $r[0]['allow_gid']; - $deny_cid = $r[0]['deny_cid']; - $deny_gid = $r[0]['deny_gid']; - if($allow_cid || $allow_gid || $deny_cid || $deny_gid) + $deny_cid = $r[0]['deny_cid']; + $deny_gid = $r[0]['deny_gid']; + if ($allow_cid || $allow_gid || $deny_cid || $deny_gid) $public = false; $post_type = t('thing'); - $objtype = ACTIVITY_OBJ_PROFILE; - $tgttype = ACTIVITY_OBJ_THING; + $objtype = ACTIVITY_OBJ_PROFILE; + $tgttype = ACTIVITY_OBJ_THING; $links = array(); - $links[] = array('rel' => 'alternate', 'type' => 'text/html', - 'href' => z_root() . '/thing/' . $r[0]['obj_obj']); - if($r[0]['imgurl']) + $links[] = array('rel' => 'alternate', 'type' => 'text/html', + 'href' => z_root() . '/thing/' . $r[0]['obj_obj']); + if ($r[0]['imgurl']) $links[] = array('rel' => 'photo', 'href' => $r[0]['obj_imgurl']); $target = json_encode(array( @@ -224,9 +225,9 @@ class Like extends \Zotlabs\Web\Controller { } - if(! ($owner_uid && $r)) { - if($interactive) { - notice( t('Invalid request.') . EOL); + if (!($owner_uid && $r)) { + if ($interactive) { + notice(t('Invalid request.') . EOL); return $o; } killme(); @@ -234,11 +235,11 @@ class Like extends \Zotlabs\Web\Controller { // The resultant activity is going to be a wall-to-wall post, so make sure this is allowed - $perms = get_all_perms($owner_uid,$observer['xchan_hash']); + $perms = get_all_perms($owner_uid, $observer['xchan_hash']); - if(! ($perms['post_like'] && $perms['view_profile'])) { - if($interactive) { - notice( t('Permission denied.') . EOL); + if (!($perms['post_like'] && $perms['view_profile'])) { + if ($interactive) { + notice(t('Permission denied.') . EOL); return $o; } killme(); @@ -247,18 +248,18 @@ class Like extends \Zotlabs\Web\Controller { $ch = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", intval($owner_uid) ); - if(! $ch) { - if($interactive) { - notice( t('Channel unavailable.') . EOL); + if (!$ch) { + if ($interactive) { + notice(t('Channel unavailable.') . EOL); return $o; } killme(); } - if(! $plink) + if (!$plink) $plink = '[zrl=' . z_root() . '/profile/' . $ch[0]['channel_address'] . ']' . $post_type . '[/zrl]'; - $object = json_encode(Activity::fetch_profile([ 'id' => channel_url($ch[0]) ])); + $object = json_encode(Activity::fetch_profile(['id' => channel_url($ch[0])])); // second like of the same thing is "undo" for the first like @@ -266,26 +267,26 @@ class Like extends \Zotlabs\Web\Controller { intval($ch[0]['channel_id']), dbesc($observer['xchan_hash']), dbesc($activity), - dbesc(($tgttype)?$tgttype:$objtype), + dbesc(($tgttype) ? $tgttype : $objtype), dbesc($obj_id) ); - if($z) { + if ($z) { $z[0]['deleted'] = 1; - Libsync::build_sync_packet($ch[0]['channel_id'],array('likes' => $z)); + Libsync::build_sync_packet($ch[0]['channel_id'], array('likes' => $z)); q("delete from likes where id = %d", intval($z[0]['id']) ); - if($z[0]['i_mid']) { + if ($z[0]['i_mid']) { $r = q("select id from item where mid = '%s' and uid = %d limit 1", dbesc($z[0]['i_mid']), intval($ch[0]['channel_id']) ); - if($r) - drop_item($r[0]['id'],false); - if($interactive) { - notice( t('Previous action reversed.') . EOL); + if ($r) + drop_item($r[0]['id'], false); + if ($interactive) { + notice(t('Previous action reversed.') . EOL); return $o; } } @@ -294,7 +295,7 @@ class Like extends \Zotlabs\Web\Controller { } else { - if(! $observer) + if (!$observer) killme(); // this is used to like an item or comment @@ -315,32 +316,30 @@ class Like extends \Zotlabs\Web\Controller { // create a copy of the parent in your stream. If not the conversation // parent, copy that as well. - if($r) { - if($r[0]['uid'] === $sys_channel['channel_id'] && local_channel()) { - $r = [ copy_of_pubitem(\App::get_channel(), $r[0]['mid']) ]; + if ($r) { + if ($r[0]['uid'] === $sys_channel['channel_id'] && local_channel()) { + $r = [copy_of_pubitem(App::get_channel(), $r[0]['mid'])]; } } - if(! $item_id || (! $r)) { + if (!$item_id || (!$r)) { logger('like: no item ' . $item_id); killme(); } - xchan_query($r,true); - - $item = $r[0]; + xchan_query($r, true); + $item = $r[0]; $owner_uid = $r[0]['uid']; $owner_aid = $r[0]['aid']; - $can_comment = false; - if((array_key_exists('owner',$item)) && intval($item['owner']['abook_self'])) - $can_comment = perm_is_allowed($item['uid'],$observer['xchan_hash'],'post_comments'); - else - $can_comment = can_comment_on_post($observer['xchan_hash'],$item); + if ((array_key_exists('owner', $item)) && intval($item['owner']['abook_self'])) + $can_comment = perm_is_allowed($item['uid'], $observer['xchan_hash'], 'post_comments'); + else + $can_comment = can_comment_on_post($observer['xchan_hash'], $item); - if(! $can_comment) { - notice( t('Permission denied') . EOL); + if (!$can_comment) { + notice(t('Permission denied') . EOL); killme(); } @@ -348,7 +347,7 @@ class Like extends \Zotlabs\Web\Controller { dbesc($item['owner_xchan']) ); - if($r) + if ($r) $thread_owner = $r[0]; else killme(); @@ -356,24 +355,24 @@ class Like extends \Zotlabs\Web\Controller { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($item['author_xchan']) ); - if($r) + if ($r) $item_author = $r[0]; else killme(); - $verbs = " '".dbesc($activity)."' "; + $verbs = " '" . dbesc($activity) . "' "; $multi_undo = false; // event participation and consensus items are essentially radio toggles. If you make a subsequent choice, // we need to eradicate your first choice. - if($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) { - $verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' "; + if ($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) { + $verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' "; $multi_undo = 1; } - if($activity === ACTIVITY_AGREE || $activity === ACTIVITY_DISAGREE || $activity === ACTIVITY_ABSTAIN) { - $verbs = " '" . dbesc(ACTIVITY_AGREE) . "','" . dbesc(ACTIVITY_DISAGREE) . "','" . dbesc(ACTIVITY_ABSTAIN) . "' "; + if ($activity === ACTIVITY_AGREE || $activity === ACTIVITY_DISAGREE || $activity === ACTIVITY_ABSTAIN) { + $verbs = " '" . dbesc(ACTIVITY_AGREE) . "','" . dbesc(ACTIVITY_DISAGREE) . "','" . dbesc(ACTIVITY_ABSTAIN) . "' "; $multi_undo = true; } @@ -386,44 +385,41 @@ class Like extends \Zotlabs\Web\Controller { intval($owner_uid) ); - if($r) { + if ($r) { // already liked it. Drop that item. require_once('include/items.php'); - foreach($r as $rr) { - drop_item($rr['id'],false,DROPITEM_PHASE1); + foreach ($r as $rr) { + drop_item($rr['id'], false, DROPITEM_PHASE1); // set the changed timestamp on the parent so we'll see the update without a page reload - $z = q("update item set changed = '%s' where id = %d and uid = %d", + q("update item set changed = '%s' where id = %d and uid = %d", dbesc(datetime_convert()), intval($rr['parent']), intval($rr['uid']) ); // Prior activity was a duplicate of the one we're submitting, just undo it; // don't fall through and create another - if(activity_match($rr['verb'],$activity)) + if (activity_match($rr['verb'], $activity)) $multi_undo = false; // drop_item was not done interactively, so we need to invoke the notifier // in order to push the changes to connections - \Zotlabs\Daemon\Master::Summon(array('Notifier','drop',$rr['id'])); - + Master::Summon(array('Notifier', 'drop', $rr['id'])); } - if($interactive) + if ($interactive) return; - if(! $multi_undo) { + if (!$multi_undo) { $ret = self::like_response([ - 'item' => $item, + 'item' => $item, 'orig_item_id' => $item_id, - 'owner_xchan' => $thread_owner + 'owner_xchan' => $thread_owner ]); json_return_and_die($ret); } - - } } @@ -431,43 +427,39 @@ class Like extends \Zotlabs\Web\Controller { $arr = array(); - $arr['uuid'] = $uuid; - $arr['mid'] = z_root() . (($is_rsvp) ? '/activity/' : '/item/') . $uuid; + $arr['uuid'] = $uuid; + $arr['mid'] = z_root() . (($is_rsvp) ? '/activity/' : '/item/') . $uuid; - if($extended_like) { + if ($extended_like) { $arr['item_thread_top'] = 1; - $arr['item_origin'] = 1; - $arr['item_wall'] = 1; + $arr['item_origin'] = 1; + $arr['item_wall'] = 1; } else { $post_type = (($item['resource_type'] === 'photo') ? t('photo') : t('status')); - if($item['obj_type'] === ACTIVITY_OBJ_EVENT) + if ($item['obj_type'] === ACTIVITY_OBJ_EVENT) $post_type = t('event'); - $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $item['plink'])); - $objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); + $objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE); - if($objtype === ACTIVITY_OBJ_NOTE && (! intval($item['item_thread_top']))) + if ($objtype === ACTIVITY_OBJ_NOTE && (!intval($item['item_thread_top']))) $objtype = ACTIVITY_OBJ_COMMENT; + $object = json_encode(Activity::fetch_item(['id' => $item['mid']])); - $body = $item['body']; - - $object = json_encode(Activity::fetch_item( [ 'id' => $item['mid'] ])); - - if(! intval($item['item_thread_top'])) + if (!intval($item['item_thread_top'])) $post_type = 'comment'; - $arr['item_origin'] = 1; + $arr['item_origin'] = 1; $arr['item_notshown'] = 1; - $arr['item_type'] = $item['item_type']; + $arr['item_type'] = $item['item_type']; - if(intval($item['item_wall'])) + if (intval($item['item_wall'])) $arr['item_wall'] = 1; // if this was a linked photo and was hidden, unhide it. - if(intval($item['item_hidden'])) { + if (intval($item['item_hidden'])) { $r = q("update item set item_hidden = 0 where id = %d", intval($item['id']) ); @@ -475,103 +467,95 @@ class Like extends \Zotlabs\Web\Controller { } - if($verb === 'like') + if ($verb === 'like') $bodyverb = t('%1$s likes %2$s\'s %3$s'); - if($verb === 'dislike') + if ($verb === 'dislike') $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); - if($verb === 'agree') + if ($verb === 'agree') $bodyverb = t('%1$s agrees with %2$s\'s %3$s'); - if($verb === 'disagree') + if ($verb === 'disagree') $bodyverb = t('%1$s doesn\'t agree with %2$s\'s %3$s'); - if($verb === 'abstain') + if ($verb === 'abstain') $bodyverb = t('%1$s abstains from a decision on %2$s\'s %3$s'); - if($verb === 'attendyes') + if ($verb === 'attendyes') $bodyverb = t('%1$s is attending %2$s\'s %3$s'); - if($verb === 'attendno') + if ($verb === 'attendno') $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); - if($verb === 'attendmaybe') + if ($verb === 'attendmaybe') $bodyverb = t('%1$s may attend %2$s\'s %3$s'); - if(! isset($bodyverb)) - killme(); - - + if (!isset($bodyverb)) + killme(); - if($extended_like) { - $ulink = '[zrl=' . $ch[0]['xchan_url'] . '][bdi]' . $ch[0]['xchan_name'] . '[/bdi][/zrl]'; - $alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]'; + if ($extended_like) { + $ulink = '[zrl=' . $ch[0]['xchan_url'] . '][bdi]' . $ch[0]['xchan_name'] . '[/bdi][/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]'; $private = (($public) ? 0 : 1); } else { - $arr['parent'] = $item['id']; - $arr['thr_parent'] = $item['mid']; - $ulink = '[zrl=' . $item_author['xchan_url'] . '][bdi]' . $item_author['xchan_name'] . '[/bdi][/zrl]'; - $alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]'; - $plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]'; - $allow_cid = $item['allow_cid']; - $allow_gid = $item['allow_gid']; - $deny_cid = $item['deny_cid']; - $deny_gid = $item['deny_gid']; - $private = $item['private']; + $arr['parent'] = $item['id']; + $arr['thr_parent'] = $item['mid']; + $ulink = '[zrl=' . $item_author['xchan_url'] . '][bdi]' . $item_author['xchan_name'] . '[/bdi][/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]'; + $plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]'; + $allow_cid = $item['allow_cid']; + $allow_gid = $item['allow_gid']; + $deny_cid = $item['deny_cid']; + $deny_gid = $item['deny_gid']; + $private = $item['private']; } - $arr['aid'] = (($extended_like) ? $ch[0]['channel_account_id'] : $owner_aid); $arr['uid'] = $owner_uid; - - $arr['item_flags'] = $item['item_flags']; $arr['item_wall'] = $item['item_wall']; $arr['parent_mid'] = (($extended_like) ? $arr['mid'] : $item['mid']); $arr['owner_xchan'] = (($extended_like) ? $ch[0]['xchan_hash'] : $thread_owner['xchan_hash']); $arr['author_xchan'] = $observer['xchan_hash']; + $arr['body'] = sprintf($bodyverb, $alink, $ulink, $plink); - - $arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink ); - if($obj_type === 'thing' && $r[0]['imgurl']) { + if ($obj_type === 'thing' && $r[0]['imgurl']) { $arr['body'] .= "\n\n[zmg=80x80]" . $r[0]['imgurl'] . '[/zmg]'; } - if($obj_type === 'profile') { - if($public) { + if ($obj_type === 'profile') { + if ($public) { $arr['body'] .= "\n\n" . '[embed]' . z_root() . '/profile/' . $ch[0]['channel_address'] . '[/embed]'; } else $arr['body'] .= "\n\n[zmg=80x80]" . $profile['thumb'] . '[/zmg]'; } + $arr['verb'] = $activity; + $arr['obj_type'] = $objtype; + $arr['obj'] = $object; - $arr['verb'] = $activity; - $arr['obj_type'] = $objtype; - $arr['obj'] = $object; - - if($target) { - $arr['tgt_type'] = $tgttype; - $arr['target'] = $target; + if ($target) { + $arr['tgt_type'] = $tgttype; + $arr['target'] = $target; } - $arr['allow_cid'] = $allow_cid; - $arr['allow_gid'] = $allow_gid; - $arr['deny_cid'] = $deny_cid; - $arr['deny_gid'] = $deny_gid; - $arr['item_private'] = $private; + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['item_private'] = $private; - call_hooks('post_local',$arr); + call_hooks('post_local', $arr); - $post = item_store($arr); + $post = item_store($arr); $post_id = $post['item_id']; // save the conversation from expiration - if(local_channel() && array_key_exists('item',$post) && (intval($post['item']['id']) != intval($post['item']['parent']))) + if (local_channel() && array_key_exists('item', $post) && (intval($post['item']['id']) != intval($post['item']['parent']))) retain_item($post['item']['parent']); $arr['id'] = $post_id; call_hooks('post_local_end', $arr); - - if($extended_like) { + if ($extended_like) { $r = q("insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')", intval($ch[0]['channel_id']), dbesc($observer['xchan_hash']), @@ -579,35 +563,35 @@ class Like extends \Zotlabs\Web\Controller { intval($post_id), dbesc($arr['mid']), dbesc($activity), - dbesc(($tgttype)? $tgttype : $objtype), + dbesc(($tgttype) ? $tgttype : $objtype), dbesc($obj_id), - dbesc(($target) ? $target : $object) + dbesc(($target) ? $target : $object) ); $r = q("select * from likes where liker = '%s' and likee = '%s' and i_mid = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' ", dbesc($observer['xchan_hash']), dbesc($ch[0]['channel_hash']), dbesc($arr['mid']), dbesc($activity), - dbesc(($tgttype)? $tgttype : $objtype), + dbesc(($tgttype) ? $tgttype : $objtype), dbesc($obj_id) ); - if($r) - Libsync::build_sync_packet($ch[0]['channel_id'],array('likes' => $r)); + if ($r) + Libsync::build_sync_packet($ch[0]['channel_id'], array('likes' => $r)); } - \Zotlabs\Daemon\Master::Summon(array('Notifier','like',$post_id)); + Master::Summon(array('Notifier', 'like', $post_id)); - if($interactive) { - notice( t('Action completed.') . EOL); + if ($interactive) { + notice(t('Action completed.') . EOL); $o .= t('Thank you.'); return $o; } $ret = self::like_response([ - 'item' => $item, + 'item' => $item, 'orig_item_id' => $item_id, - 'owner_xchan' => $thread_owner + 'owner_xchan' => $thread_owner ]); json_return_and_die($ret); -- cgit v1.2.3 From 0d544e2294149efe5f442fa1191c02f241b85b6a Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 16 Jan 2021 09:17:45 +0000 Subject: wrong logic --- include/items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/items.php b/include/items.php index d89290e2f..610727f30 100755 --- a/include/items.php +++ b/include/items.php @@ -130,7 +130,7 @@ function collect_recipients($item, &$private_envelope,$include_groups = true) { case 'sit': case 'any': case 'con': - if(in_array($rr['xchan_network'], ['zot6', 'zot'])) + if(!in_array($rr['xchan_network'], ['zot6', 'zot'])) break; case 'pub': case '': -- cgit v1.2.3 From 485a232ae68617093f58bed6c15a52f80116cdae Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 16 Jan 2021 09:31:51 +0000 Subject: changelog --- CHANGELOG | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 19cc7fd43..0c54ababf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +Hubzilla 5.2.1 (2021-01-16) + - Fix attach_upgrade() to catch all broken entries in attach + - Fix collect_recipients() public policy filter for zot6 + - Fix leaking of duplicate tasks in queueworker addon_common + + Hubzilla 5.2 (2021-01-13) - Use libzotdir for directory - Streamline usage of channel url for keyId -- cgit v1.2.3 From 38a48de826287cc8360768794824e7d00e8f2ef8 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 17 Jan 2021 13:35:13 +0000 Subject: app_render() check against zot6 --- Zotlabs/Lib/Apps.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php index 7b980b8d3..05b2ba177 100644 --- a/Zotlabs/Lib/Apps.php +++ b/Zotlabs/Lib/Apps.php @@ -524,7 +524,7 @@ class Apps { } elseif(remote_channel()) { $observer = \App::get_observer(); - if($observer && $observer['xchan_network'] === 'zot') { + if($observer && in_array($observer['xchan_network'], ['zot6', 'zot'])) { // some folks might have xchan_url redirected offsite, use the connurl $x = parse_url($observer['xchan_connurl']); if($x) { -- cgit v1.2.3 From 46aefd88832461d762a218fa08e8dfd02d19931a Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 17 Jan 2021 13:41:27 +0000 Subject: fix fetch vcard menu entry for zot6 connections --- Zotlabs/Module/Connedit.php | 290 ++++++++++++++++++++++---------------------- 1 file changed, 145 insertions(+), 145 deletions(-) diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index becf8460d..582563451 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -32,10 +32,10 @@ class Connedit extends Controller { */ function init() { - + if(! local_channel()) return; - + if((argc() >= 2) && intval(argv(1))) { $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash @@ -47,54 +47,54 @@ class Connedit extends Controller { App::$poi = array_shift($r); } } - + $channel = App::get_channel(); if($channel) head_set_icon($channel['xchan_photo_s']); - + } - + /* @brief Evaluate posted values and set changes * */ - + function post() { - + if(! local_channel()) return; - + $contact_id = intval(argv(1)); if(! $contact_id) return; - + $channel = App::get_channel(); - + // TODO if configured for hassle-free permissions, we'll post the form with ajax as soon as the // connection enable is toggled to a special autopost url and set permissions immediately, leaving // the other form elements alone pending a manual submit of the form. The downside is that there // will be a window of opportunity when the permissions have been set but before you've had a chance // to review and possibly restrict them. The upside is we won't have to warn you that your connection // can't do anything until you save the bloody form. - + $autopost = (((argc() > 2) && (argv(2) === 'auto')) ? true : false); - + $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($contact_id), intval(local_channel()) ); - + if(! $orig_record) { notice( t('Could not access contact record.') . EOL); goaway(z_root() . '/connections'); return; // NOTREACHED } - + call_hooks('contact_edit_post', $_POST); - + $vc = get_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard'); - $vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); + $vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); $serialised_vcard = update_vcard($_REQUEST,$vcard); if($serialised_vcard) set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$serialised_vcard); @@ -107,8 +107,8 @@ class Connedit extends Controller { $autoperms = null; $is_self = false; } - - + + $profile_id = ((array_key_exists('profile_assign',$_POST)) ? $_POST['profile_assign'] : $orig_record[0]['abook_profile']); if($profile_id) { @@ -121,17 +121,17 @@ class Connedit extends Controller { return; } } - + $abook_incl = ((array_key_exists('abook_incl',$_POST)) ? escape_tags($_POST['abook_incl']) : $orig_record[0]['abook_incl']); $abook_excl = ((array_key_exists('abook_excl',$_POST)) ? escape_tags($_POST['abook_excl']) : $orig_record[0]['abook_excl']); $hidden = intval($_POST['hidden']); - + $priority = intval($_POST['poll']); if($priority > 5 || $priority < 0) $priority = 0; - + if(! array_key_exists('closeness',$_POST)) { $_POST['closeness'] = 80; } @@ -139,15 +139,15 @@ class Connedit extends Controller { if($closeness < 0 || $closeness > 99) { $closeness = 80; } - + $rating = intval($_POST['rating']); if($rating < (-10)) $rating = (-10); if($rating > 10) $rating = 10; - + $rating_text = trim(escape_tags($_REQUEST['rating_text'])); - + $all_perms = Permissions::Perms(); if($all_perms) { @@ -168,27 +168,27 @@ class Connedit extends Controller { } } - if(! is_null($autoperms)) + if(! is_null($autoperms)) set_pconfig($channel['channel_id'],'system','autoperms',$autoperms); - + $new_friend = false; - + // only store a record and notify the directory if the rating changed if(! $is_self) { - + $signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text; $sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey'])); $rated = ((intval($rating) || strlen($rating_text)) ? true : false); - + $record = 0; - + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan']) ); - + if($z) { if(($z[0]['xlink_rating'] != $rating) || ($z[0]['xlink_rating_text'] != $rating_text)) { $record = $z[0]['xlink_id']; @@ -223,18 +223,18 @@ class Connedit extends Controller { Master::Summon(array('Ratenotif','rating',$record)); } } - + if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) { $new_friend = true; - + // @fixme it won't be common, but when you accept a new connection request // the permissions will now be that of your permissions role and ignore // any you may have set manually on the form. We'll probably see a bug if somebody // tries to set the permissions *and* approve the connection in the same // request. The workaround is to approve the connection, then go back and // adjust permissions as desired. - + $p = Permissions::connect_perms(local_channel()); $my_perms = $p['perms']; if($my_perms) { @@ -247,7 +247,7 @@ class Connedit extends Controller { $abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']); - + $r = q("UPDATE abook SET abook_profile = '%s', abook_closeness = %d, abook_pending = %d, abook_incl = '%s', abook_excl = '%s' where abook_id = %d AND abook_channel = %d", @@ -259,7 +259,7 @@ class Connedit extends Controller { intval($contact_id), intval(local_channel()) ); - + if($r) info( t('Connection updated.') . EOL); else @@ -267,16 +267,16 @@ class Connedit extends Controller { if(! intval(App::$poi['abook_self'])) { if($new_friend) { - Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] ); + Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] ); } - Master::Summon( [ - 'Notifier', - (($new_friend) ? 'permission_create' : 'permission_update'), - $contact_id + Master::Summon( [ + 'Notifier', + (($new_friend) ? 'permission_create' : 'permission_update'), + $contact_id ]); } - + if($new_friend) { $default_group = $channel['channel_default_group']; if($default_group) { @@ -285,11 +285,11 @@ class Connedit extends Controller { if($g) group_add_member(local_channel(),'',App::$poi['abook_xchan'],$g['id']); } - + // Check if settings permit ("post new friend activity" is allowed, and // friends in general or this friend in particular aren't hidden) // and send out a new friend activity - + $pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0", intval($channel['channel_id']) ); @@ -305,23 +305,23 @@ class Connedit extends Controller { $xarr['deny_cid'] = $channel['channel_deny_cid']; $xarr['deny_gid'] = $channel['channel_deny_gid']; $xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0); - + $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . App::$poi['xchan_url'] . ']' . App::$poi['xchan_name'] . '[/zrl]'; - + $xarr['body'] .= "\n\n\n" . '[zrl=' . App::$poi['xchan_url'] . '][zmg=80x80]' . App::$poi['xchan_photo_m'] . '[/zmg][/zrl]'; - + post_activity_item($xarr); - + } - - + + // pull in a bit of content if there is any to pull in Master::Summon(array('Onepoll',$contact_id)); - + } - + // Refresh the structure in memory with the new data - + $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and abook_id = %d LIMIT 1", @@ -331,34 +331,34 @@ class Connedit extends Controller { if($r) { App::$poi = $r[0]; } - + if($new_friend) { $arr = array('channel_id' => local_channel(), 'abook' => App::$poi); call_hooks('accept_follow', $arr); } - + $this->connedit_clone($a); - + if(($_REQUEST['pending']) && (!$_REQUEST['done'])) goaway(z_root() . '/connections/ifpending'); - + return; - + } - + /* @brief Clone connection * * */ - + function connedit_clone(&$a) { - + if(! App::$poi) return; - - + + $channel = App::get_channel(); - + $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and abook_id = %d LIMIT 1", @@ -368,40 +368,40 @@ class Connedit extends Controller { if($r) { App::$poi = array_shift($r); } - + $clone = App::$poi; - + unset($clone['abook_id']); unset($clone['abook_account']); unset($clone['abook_channel']); - + $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); if($abconfig) $clone['abconfig'] = $abconfig; - + Libsync::build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone))); } - + /* @brief Generate content of connection edit page * * */ - + function get() { - + $sort_type = 0; $o = ''; - + if(! local_channel()) { notice( t('Permission denied.') . EOL); return login(); } - + $section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : ''); $channel = App::get_channel(); - + $yes_no = array(t('No'),t('Yes')); - + $connect_perms = Permissions::connect_perms(local_channel()); $o .= "\n"; - + if(argc() == 3) { - + $contact_id = intval(argv(1)); if(! $contact_id) return; - + $cmd = argv(2); $orig_record = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash @@ -429,17 +429,17 @@ class Connedit extends Controller { intval($contact_id), intval(local_channel()) ); - + if(! count($orig_record)) { notice( t('Could not access address book record.') . EOL); goaway(z_root() . '/connections'); } - + if($cmd === 'update') { // pull feed and consume it, which should subscribe to the hub. Master::Summon(array('Poller',$contact_id)); goaway(z_root() . '/connedit/' . $contact_id); - + } if($cmd === 'fetchvc') { @@ -474,7 +474,7 @@ class Connedit extends Controller { dbesc($orig_record[0]['xchan_hash']) ); $cmd = 'refresh'; - } + } if($cmd === 'refresh') { if($orig_record[0]['xchan_network'] === 'zot') { @@ -486,13 +486,13 @@ class Connedit extends Controller { notice( t('Refresh failed - channel is currently unavailable.') ); } else { - + // if you are on a different network we'll force a refresh of the connection basic info Master::Summon(array('Notifier','permission_update',$contact_id)); } goaway(z_root() . '/connedit/' . $contact_id); } - + if($cmd === 'block') { if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_BLOCKED)) { $this->connedit_clone($a); @@ -501,7 +501,7 @@ class Connedit extends Controller { notice(t('Unable to set address book parameters.') . EOL); goaway(z_root() . '/connedit/' . $contact_id); } - + if($cmd === 'ignore') { if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_IGNORED)) { $this->connedit_clone($a); @@ -510,7 +510,7 @@ class Connedit extends Controller { notice(t('Unable to set address book parameters.') . EOL); goaway(z_root() . '/connedit/' . $contact_id); } - + if($cmd === 'archive') { if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_ARCHIVED)) { $this->connedit_clone($a); @@ -519,7 +519,7 @@ class Connedit extends Controller { notice(t('Unable to set address book parameters.') . EOL); goaway(z_root() . '/connedit/' . $contact_id); } - + if($cmd === 'hide') { if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_HIDDEN)) { $this->connedit_clone($a); @@ -528,10 +528,10 @@ class Connedit extends Controller { notice(t('Unable to set address book parameters.') . EOL); goaway(z_root() . '/connedit/' . $contact_id); } - + // We'll prevent somebody from unapproving an already approved contact. // Though maybe somebody will want this eventually (??) - + if($cmd === 'approve') { if(intval($orig_record[0]['abook_pending'])) { if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_PENDING)) { @@ -542,10 +542,10 @@ class Connedit extends Controller { } goaway(z_root() . '/connedit/' . $contact_id); } - - + + if($cmd === 'drop') { - + contact_remove(local_channel(), $orig_record[0]['abook_id']); Master::Summon( [ 'Notifier', 'purge', local_channel(), $orig_record[0]['xchan_hash'] ] ); @@ -556,17 +556,17 @@ class Connedit extends Controller { 'entry_deleted' => true)) ) ); - + info( t('Connection has been removed.') . EOL ); if(x($_SESSION,'return_url')) goaway(z_root() . '/' . $_SESSION['return_url']); goaway(z_root() . '/contacts'); - + } } - + if(App::$poi) { - + $abook_prev = 0; $abook_next = 0; @@ -595,14 +595,14 @@ class Connedit extends Controller { } $tools = array( - + 'view' => array( 'label' => t('View Profile'), 'url' => chanlink_cid($contact['abook_id']), 'sel' => '', 'title' => sprintf( t('View %s\'s profile'), $contact['xchan_name']), ), - + 'refresh' => array( 'label' => t('Refresh Permissions'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/refresh', @@ -616,14 +616,14 @@ class Connedit extends Controller { 'sel' => '', 'title' => t('Fetch updated photo'), ), - + 'recent' => array( 'label' => t('Recent Activity'), 'url' => z_root() . '/network/?f=&cid=' . $contact['abook_id'], 'sel' => '', 'title' => t('View recent posts and comments'), ), - + 'block' => array( 'label' => (intval($contact['abook_blocked']) ? t('Unblock') : t('Block')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/block', @@ -631,7 +631,7 @@ class Connedit extends Controller { 'title' => t('Block (or Unblock) all communications with this connection'), 'info' => (intval($contact['abook_blocked']) ? t('This connection is blocked!') : ''), ), - + 'ignore' => array( 'label' => (intval($contact['abook_ignored']) ? t('Unignore') : t('Ignore')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/ignore', @@ -639,7 +639,7 @@ class Connedit extends Controller { 'title' => t('Ignore (or Unignore) all inbound communications from this connection'), 'info' => (intval($contact['abook_ignored']) ? t('This connection is ignored!') : ''), ), - + 'archive' => array( 'label' => (intval($contact['abook_archived']) ? t('Unarchive') : t('Archive')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/archive', @@ -647,7 +647,7 @@ class Connedit extends Controller { 'title' => t('Archive (or Unarchive) this connection - mark channel dead but keep content'), 'info' => (intval($contact['abook_archived']) ? t('This connection is archived!') : ''), ), - + 'hide' => array( 'label' => (intval($contact['abook_hidden']) ? t('Unhide') : t('Hide')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/hide', @@ -655,18 +655,18 @@ class Connedit extends Controller { 'title' => t('Hide or Unhide this connection from your other connections'), 'info' => (intval($contact['abook_hidden']) ? t('This connection is hidden!') : ''), ), - + 'delete' => array( 'label' => t('Delete'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/drop', 'sel' => '', 'title' => t('Delete this connection'), ), - + ); - if($contact['xchan_network'] === 'zot') { + if(in_array($contact['xchan_network'], ['zot6', 'zot'])) { $tools['fetchvc'] = [ 'label' => t('Fetch Vcard'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/fetchvc', @@ -684,24 +684,24 @@ class Connedit extends Controller { 'sel' => '', 'title' => t('Open Individual Permissions section by default'), ]; - + $self = false; - + if(intval($contact['abook_self'])) { $self = true; $abook_prev = $abook_next = 0; } - + $vc = get_abconfig(local_channel(),$contact['abook_xchan'],'system','vcard'); - $vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); + $vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); $vcard = (($vctmp) ? get_vcard_array($vctmp,$contact['abook_id']) : [] ); if(! $vcard) $vcard['fn'] = $contact['xchan_name']; $tpl = get_markup_template("abook_edit.tpl"); - + if(Apps::system_app_installed(local_channel(),'Affinity Tool')) { $sections['affinity'] = [ @@ -710,7 +710,7 @@ class Connedit extends Controller { 'sel' => '', 'title' => t('Open Set Affinity section by default'), ]; - + $labels = [ t('Me'), t('Family'), @@ -720,7 +720,7 @@ class Connedit extends Controller { ]; call_hooks('affinity_labels',$labels); $label_str = ''; - + if($labels) { foreach($labels as $l) { if($label_str) { @@ -731,11 +731,11 @@ class Connedit extends Controller { $label_str .= "'" . $l . "'"; } } - + $slider_tpl = get_markup_template('contact_slider.tpl'); - + $slideval = intval($contact['abook_closeness']); - + $slide = replace_macros($slider_tpl,array( '$min' => 1, '$val' => $slideval, @@ -751,22 +751,22 @@ class Connedit extends Controller { 'title' => t('Open Custom Filter section by default'), ]; } - + $rating_val = 0; $rating_text = ''; - + $xl = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", dbesc($channel['channel_hash']), dbesc($contact['xchan_hash']) ); - + if($xl) { $rating_val = intval($xl[0]['xlink_rating']); $rating_text = $xl[0]['xlink_rating_text']; } - + $rating_enabled = get_config('system','rating_enabled'); - + if($rating_enabled) { $rating = replace_macros(get_markup_template('rating_slider.tpl'),array( '$min' => -10, @@ -776,28 +776,28 @@ class Connedit extends Controller { else { $rating = false; } - - + + $perms = array(); $channel = App::get_channel(); - + $global_perms = Permissions::Perms(); $existing = get_all_perms(local_channel(),$contact['abook_xchan'],false); - + $unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication'), array(t('No'),('Yes'))); - + $multiprofs = ((feature_enabled(local_channel(),'multi_profiles')) ? true : false); - + if($slide && !$multiprofs) $affinity = t('Set Affinity'); - + if(!$slide && $multiprofs) $affinity = t('Set Profile'); - + if($slide && $multiprofs) $affinity = t('Set Affinity & Profile'); - + $theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'", intval(local_channel()), dbesc($contact['abook_xchan']) @@ -812,20 +812,20 @@ class Connedit extends Controller { foreach($global_perms as $k => $v) { $thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k); //fixme - + $checkinherited = PermissionLimits::Get(local_channel(),$k); - + // For auto permissions (when $self is true) we don't want to look at existing // permissions because they are enabled for the channel owner if((! $self) && ($existing[$k])) $thisperm = "1"; - - + + $perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited); } - + $pcat = new Permcat(local_channel()); $pcatlist = $pcat->listing(); $permcats = []; @@ -838,23 +838,23 @@ class Connedit extends Controller { $locstr = locations_by_netid($contact['xchan_hash']); if(! $locstr) $locstr = unpunify($contact['xchan_url']); - + $clone_warn = ''; $clonable = (in_array($contact['xchan_network'],['zot', 'zot6', 'rss']) ? true : false); if(! $clonable) { $clone_warn = ''; - $clone_warn .= ((intval($contact['abook_not_here'])) + $clone_warn .= ((intval($contact['abook_not_here'])) ? t('This connection is unreachable from this location.') : t('This connection may be unreachable from other channel locations.') ); $clone_warn .= '
' . t('Location independence is not supported by their network.'); } - + if(intval($contact['abook_not_here']) && $unclonable) $not_here = t('This connection is unreachable from this location. Location independence is not supported by their network.'); - + $o .= replace_macros($tpl, [ '$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])), '$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no), @@ -910,7 +910,7 @@ class Connedit extends Controller { '$name' => $contact['xchan_name'], '$abook_prev' => $abook_prev, '$abook_next' => $abook_next, - '$vcard_label' => t('Details'), + '$vcard_label' => t('Details'), '$displayname' => $displayname, '$name_label' => t('Name'), '$org_label' => t('Organisation'), @@ -939,13 +939,13 @@ class Connedit extends Controller { '$zip_code' => t('ZIP Code'), '$country' => t('Country') ]); - + $arr = array('contact' => $contact,'output' => $o); - + call_hooks('contact_edit', $arr); - + return $arr['output']; - - } + + } } } -- cgit v1.2.3 From a925b08e80bc740ea9d23b1dfb7adbf94491ed09 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 17 Jan 2021 13:52:55 +0000 Subject: get_bookmark_link() check against zot6 --- include/bookmarks.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/bookmarks.php b/include/bookmarks.php index 21456c871..145119347 100644 --- a/include/bookmarks.php +++ b/include/bookmarks.php @@ -18,7 +18,7 @@ function bookmark_add($channel,$sender,$taxonomy,$private,$opts = null) { $channel_id = $channel['channel_id']; if($private) - $iarr['contact_allow'] = array($channel['channel_hash']); + $iarr['contact_allow'] = array($channel['channel_hash']); $iarr['mitem_link'] = $taxonomy['url']; $iarr['mitem_desc'] = $taxonomy['term']; $iarr['mitem_flags'] = (($ischat) ? MENU_ITEM_CHATROOM : 0); @@ -41,34 +41,34 @@ function bookmark_add($channel,$sender,$taxonomy,$private,$opts = null) { if(! $menu_id) { $x = menu_list($arr['menu_channel_id'],$arr['menu_name'],$arr['menu_flags']); - if($x) + if($x) $menu_id = $x[0]['menu_id']; - else + else $menu_id = menu_create($arr); } if(! $menu_id) { logger('bookmark_add: unable to create menu ' . $arr['menu_name']); - return; + return; } logger('add_bookmark: menu_id ' . $menu_id); $r = q("select * from menu_item where mitem_link = '%s' and mitem_menu_id = %d and mitem_channel_id = %d limit 1", dbesc($iarr['mitem_link']), intval($menu_id), - intval($channel_id) + intval($channel_id) ); if($r) logger('add_bookmark: duplicate menu entry', LOGGER_DEBUG); if(! $r) { $r = menu_add_item($menu_id,$channel_id,$iarr); - menu_sync_packet($channel_id,get_observer_hash(),$menu_id); + menu_sync_packet($channel_id,get_observer_hash(),$menu_id); } return $r; } function get_bookmark_link($observer) { - if((! $observer) || ($observer['xchan_network'] !== 'zot')) + if((! $observer) || !in_array($observer['xchan_network'], ['zot6', 'zot'])) return ''; $h = @parse_url($observer['xchan_url']); -- cgit v1.2.3 From 8d37a4239ae867b3a6b586558c753f8ca147e4e2 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 17 Jan 2021 13:56:23 +0000 Subject: mark_orphan_hubsxchans() check against zot6 --- include/connections.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/connections.php b/include/connections.php index 99a4cc71e..87db7faa9 100644 --- a/include/connections.php +++ b/include/connections.php @@ -211,8 +211,8 @@ function mark_orphan_hubsxchans() { if($dirmode == DIRECTORY_MODE_NORMAL) return; - $r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0 - and hubloc_network = 'zot' and hubloc_connected < %s - interval %s", + $r = q("UPDATE hubloc SET hubloc_error = 1 WHERE hubloc_error = 0 + AND hubloc_network IN ('zot6', 'zot') AND hubloc_connected < %s - INTERVAL %s", db_utcnow(), db_quoteinterval('36 day') ); -- cgit v1.2.3 From 06b5f7107518c4f1db6579a21c0065f420ccef08 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 17 Jan 2021 14:06:35 +0000 Subject: port util/connect to Lib/Connect --- util/connect | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/connect b/util/connect index 7ceda300f..44128d580 100755 --- a/util/connect +++ b/util/connect @@ -2,6 +2,7 @@ Date: Sun, 17 Jan 2021 14:13:31 +0000 Subject: get_item_elements() check against zot6 --- include/items.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/items.php b/include/items.php index 610727f30..9633ee9bd 100755 --- a/include/items.php +++ b/include/items.php @@ -790,8 +790,8 @@ function get_item_elements($x,$allow_code = false) { dbesc($arr['author_xchan']) ); if($r) { - if($r[0]['xchan_pubkey'] && $r[0]['xchan_network'] === 'zot') { - if(rsa_verify($x['body'],base64url_decode($arr['sig']),$r[0]['xchan_pubkey'])) { + if($r[0]['xchan_pubkey'] && $r[0]['xchan_network'] === 'zot6') { + if(Libzot::verify($x['body'], $arr['sig'], $r[0]['xchan_pubkey'])) { $arr['item_verified'] = 1; } else { -- cgit v1.2.3 From 37f1b774b7a71d59e41cfcc5215575a5309eac94 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 17 Jan 2021 15:19:00 +0000 Subject: missing import --- include/items.php | 1 + 1 file changed, 1 insertion(+) diff --git a/include/items.php b/include/items.php index 9633ee9bd..571359167 100755 --- a/include/items.php +++ b/include/items.php @@ -11,6 +11,7 @@ use Zotlabs\Lib\ThreadListener; use Zotlabs\Lib\IConfig; use Zotlabs\Lib\Activity; use Zotlabs\Lib\Libsync; +use Zotlabs\Lib\Libzot; use Zotlabs\Access\PermissionLimits; use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\AccessList; -- cgit v1.2.3 From cd59c67c678f2ac1cc8457c05e5420d38df152cc Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 08:43:08 +0000 Subject: fix undefined variable --- include/items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/items.php b/include/items.php index 571359167..69c056f7e 100755 --- a/include/items.php +++ b/include/items.php @@ -4478,7 +4478,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE $item_uids and item_thread_top = 1 $sql_options $item_normal ) "; if($arr['since_id']) - $sql_extra .= " and item.id > " . $since_id . " "; + $sql_extra .= " and item.id > " . intval($arr['since_id']) . " "; if($arr['cat']) $sql_extra .= protect_sprintf(term_query('item', $arr['cat'], TERM_CATEGORY)); -- cgit v1.2.3 From 917c6caa14e8b72a3e981b3940a8f56e9814647d Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 08:46:37 +0000 Subject: force arg is not used anymore in drop_item_lolevel() --- include/items.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/items.php b/include/items.php index 69c056f7e..bfca354d1 100755 --- a/include/items.php +++ b/include/items.php @@ -3970,10 +3970,10 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { ); if($items) { foreach($items as $i) - delete_item_lowlevel($i,$stage,$force); + delete_item_lowlevel($i, $stage); } else - delete_item_lowlevel($item,$stage,$force); + delete_item_lowlevel($item, $stage); if(! $interactive) return 1; @@ -4007,7 +4007,6 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { * * @param array $item * @param int $stage - * @param boolean $force * @return boolean */ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL) { -- cgit v1.2.3 From faaa2d447292e554f0498327a81016d215184abd Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 11:21:37 +0000 Subject: $match should be array --- include/bbcode.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/bbcode.php b/include/bbcode.php index d79429719..e1a5c7e47 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -966,7 +966,7 @@ function bbtopoll($s) { $pl['poll_id'] = $match[1]; $pl['poll_question'] = $match[2]; - $match = ''; + $match = []; if(preg_match_all("/\[poll\-answer=(.*?)\](.*?)\[\/poll\-answer\]/is",$s,$match,PREG_SET_ORDER)) { $pl['answer'] = []; foreach($match as $m) { @@ -1349,7 +1349,7 @@ function bbcode($Text, $options = []) { // Check for table of content with params while(strpos($Text,'[toc') !== false) { $toc_id = 'toc-' . random_string(10); - $Text = preg_replace("/\[toc([^\]]+?)\]/ism", '
    ', $Text, 1); + $Text = preg_replace("/\[toc([^\]]+?)\]/ism", '
      ', $Text, 1); } // Check for centered text if (strpos($Text,'[/center]') !== false) { -- cgit v1.2.3 From bee84e9b008bdbc9613912eec9258b962811dab9 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 12:56:07 +0000 Subject: whitespace --- Zotlabs/Access/AccessList.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Zotlabs/Access/AccessList.php b/Zotlabs/Access/AccessList.php index 7cf7b5587..af6c4b7a6 100644 --- a/Zotlabs/Access/AccessList.php +++ b/Zotlabs/Access/AccessList.php @@ -54,7 +54,7 @@ class AccessList { * * \e string \b channel_deny_gid => string of denied gids */ function __construct($channel) { - if($channel) { + if ($channel) { $this->allow_cid = $channel['channel_allow_cid']; $this->allow_gid = $channel['channel_allow_gid']; $this->deny_cid = $channel['channel_deny_cid']; @@ -99,7 +99,6 @@ class AccessList { $this->allow_gid = $arr['allow_gid']; $this->deny_cid = $arr['deny_cid']; $this->deny_gid = $arr['deny_gid']; - $this->explicit = $explicit; } -- cgit v1.2.3 From 4f74d1d877f2ece3829978ddc78c81c83868504b Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:00:39 +0000 Subject: cleanup --- Zotlabs/Access/PermissionLimits.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Zotlabs/Access/PermissionLimits.php b/Zotlabs/Access/PermissionLimits.php index c11dc95e6..fb5fe6133 100644 --- a/Zotlabs/Access/PermissionLimits.php +++ b/Zotlabs/Access/PermissionLimits.php @@ -2,6 +2,7 @@ namespace Zotlabs\Access; +use App; use Zotlabs\Lib\PConfig; /** @@ -39,10 +40,10 @@ class PermissionLimits { */ static public function Std_Limits() { $limits = []; - $perms = Permissions::Perms(); + $perms = Permissions::Perms(); - foreach($perms as $k => $v) { - if(strstr($k, 'view')) + foreach ($perms as $k => $v) { + if (strstr($k, 'view')) $limits[$k] = PERMS_PUBLIC; else $limits[$k] = PERMS_SPECIFIC; @@ -77,14 +78,14 @@ class PermissionLimits { * * \b array with all permission limits, if $perm is not set */ static public function Get($channel_id, $perm = '') { - if($perm) { + if ($perm) { return intval(PConfig::Get($channel_id, 'perm_limits', $perm)); } PConfig::Load($channel_id); - if(array_key_exists($channel_id, \App::$config) - && array_key_exists('perm_limits', \App::$config[$channel_id])) - return \App::$config[$channel_id]['perm_limits']; + if (array_key_exists($channel_id, App::$config) + && array_key_exists('perm_limits', App::$config[$channel_id])) + return App::$config[$channel_id]['perm_limits']; return false; } -- cgit v1.2.3 From 6695225492955bf7ebf68d7326c87216a19508cd Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:08:13 +0000 Subject: cleanup --- Zotlabs/Access/PermissionRoles.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Access/PermissionRoles.php b/Zotlabs/Access/PermissionRoles.php index 82df0c34b..2bcce4eb4 100644 --- a/Zotlabs/Access/PermissionRoles.php +++ b/Zotlabs/Access/PermissionRoles.php @@ -218,13 +218,13 @@ class PermissionRoles { // set permissionlimits for this permission here, for example: // if($perm === 'mynewperm') - // \Zotlabs\Access\PermissionLimits::Set($uid,$perm,1); + // PermissionLimits::Set($uid,$perm,1); if($perm === 'view_wiki') - \Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_PUBLIC); + PermissionLimits::Set($uid, $perm, PERMS_PUBLIC); if($perm === 'write_wiki') - \Zotlabs\Access\PermissionLimits::Set($uid, $perm, PERMS_SPECIFIC); + PermissionLimits::Set($uid, $perm, PERMS_SPECIFIC); // set autoperms here if applicable @@ -262,11 +262,11 @@ class PermissionRoles { case 'view_wiki': set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm, intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','view_pages'))); - + break; case 'write_wiki': set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm, intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','write_pages'))); - + break; default: break; } -- cgit v1.2.3 From f4b71fbec19c6b98fe8b51d7fc31812c75ecb445 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:21:13 +0000 Subject: cleanup --- Zotlabs/Access/Permissions.php | 89 +++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/Zotlabs/Access/Permissions.php b/Zotlabs/Access/Permissions.php index 35016ed57..df5472cc3 100644 --- a/Zotlabs/Access/Permissions.php +++ b/Zotlabs/Access/Permissions.php @@ -75,7 +75,7 @@ class Permissions { $x = [ 'permissions' => $perms, - 'filter' => $filter + 'filter' => $filter ]; /** * @hooks permissions_list @@ -84,7 +84,7 @@ class Permissions { */ call_hooks('permissions_list', $x); - return($x['permissions']); + return ($x['permissions']); } /** @@ -96,10 +96,10 @@ class Permissions { */ static public function BlockedAnonPerms() { - $res = []; + $res = []; $perms = PermissionLimits::Std_limits(); - foreach($perms as $perm => $limit) { - if($limit != PERMS_PUBLIC) { + foreach ($perms as $perm => $limit) { + if ($limit != PERMS_PUBLIC) { $res[] = $perm; } } @@ -111,7 +111,7 @@ class Permissions { */ call_hooks('write_perms', $x); - return($x['permissions']); + return ($x['permissions']); } /** @@ -120,20 +120,20 @@ class Permissions { * Converts [ 0 => 'view_stream', ... ] * to [ 'view_stream' => 1 ] for any permissions in $arr; * Undeclared permissions which exist in Perms() are added and set to 0. - * + * * @param array $arr * @return array */ static public function FilledPerms($arr) { - if(is_null($arr)) { + if (is_null($arr)) { btlogger('FilledPerms: null'); $arr = []; } $everything = self::Perms(); - $ret = []; - foreach($everything as $k => $v) { - if(in_array($k, $arr)) + $ret = []; + foreach ($everything as $k => $v) { + if (in_array($k, $arr)) $ret[$k] = 1; else $ret[$k] = 0; @@ -155,9 +155,9 @@ class Permissions { */ static public function OPerms($arr) { $ret = []; - if($arr) { - foreach($arr as $k => $v) { - $ret[] = [ 'name' => $k, 'value' => $v ]; + if ($arr) { + foreach ($arr as $k => $v) { + $ret[] = ['name' => $k, 'value' => $v]; } } return $ret; @@ -170,15 +170,16 @@ class Permissions { * @return boolean|array */ static public function FilledAutoperms($channel_id) { - if(! intval(get_pconfig($channel_id,'system','autoperms'))) + if (!intval(get_pconfig($channel_id, 'system', 'autoperms'))) return false; $arr = []; + $r = q("select * from pconfig where uid = %d and cat = 'autoperms'", intval($channel_id) ); - if($r) { - foreach($r as $rr) { + if ($r) { + foreach ($r as $rr) { $arr[$rr['k']] = intval($rr['v']); } } @@ -193,11 +194,11 @@ class Permissions { * @return boolean true if all perms from $p1 exist also in $p2 */ static public function PermsCompare($p1, $p2) { - foreach($p1 as $k => $v) { - if(! array_key_exists($k, $p2)) + foreach ($p1 as $k => $v) { + if (!array_key_exists($k, $p2)) return false; - if($p1[$k] != $p2[$k]) + if ($p1[$k] != $p2[$k]) return false; } @@ -214,18 +215,18 @@ class Permissions { */ static public function connect_perms($channel_id) { - $my_perms = []; - $permcat = null; + $my_perms = []; + $permcat = null; $automatic = 0; // If a default permcat exists, use that - $pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default'); - if(! in_array($pc, [ '','default' ])) { - $pcp = new Zlib\Permcat($channel_id); + $pc = ((feature_enabled($channel_id, 'permcats')) ? get_pconfig($channel_id, 'system', 'default_permcat') : 'default'); + if (!in_array($pc, ['', 'default'])) { + $pcp = new Zlib\Permcat($channel_id); $permcat = $pcp->fetch($pc); - if($permcat && $permcat['perms']) { - foreach($permcat['perms'] as $p) { + if ($permcat && $permcat['perms']) { + foreach ($permcat['perms'] as $p) { $my_perms[$p['name']] = $p['value']; } } @@ -235,15 +236,15 @@ class Permissions { // and if there was no permcat or a default permcat, set the perms // from the role - $role = get_pconfig($channel_id,'system','permissions_role'); - if($role) { + $role = get_pconfig($channel_id, 'system', 'permissions_role'); + if ($role) { $xx = PermissionRoles::role_perms($role); - if($xx['perms_auto']) + if ($xx['perms_auto']) $automatic = 1; - if((! $my_perms) && ($xx['perms_connect'])) { + if ((!$my_perms) && ($xx['perms_connect'])) { $default_perms = $xx['perms_connect']; - $my_perms = Permissions::FilledPerms($default_perms); + $my_perms = Permissions::FilledPerms($default_perms); } } @@ -251,11 +252,11 @@ class Permissions { // it is likely a custom permissions role. First see if there are any // automatic permissions. - if(! $my_perms) { + if (!$my_perms) { $m = Permissions::FilledAutoperms($channel_id); - if($m) { + if ($m) { $automatic = 1; - $my_perms = $m; + $my_perms = $m; } } @@ -263,35 +264,35 @@ class Permissions { // custom perms but they are not automatic. They will be stored in abconfig with // the channel's channel_hash (the 'self' connection). - if(! $my_perms) { + if (!$my_perms) { $r = q("select channel_hash from channel where channel_id = %d", intval($channel_id) ); - if($r) { + if ($r) { $x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'", intval($channel_id), dbesc($r[0]['channel_hash']) ); - if($x) { - foreach($x as $xv) { + if ($x) { + foreach ($x as $xv) { $my_perms[$xv['k']] = intval($xv['v']); } } } } - return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] ); + return (['perms' => $my_perms, 'automatic' => $automatic]); } static public function serialise($p) { $n = []; - if($p) { - foreach($p as $k => $v) { - if(intval($v)) { + if ($p) { + foreach ($p as $k => $v) { + if (intval($v)) { $n[] = $k; } } } - return implode(',',$n); + return implode(',', $n); } } -- cgit v1.2.3 From 2729f466d5450576c620b5b7844b57aca434ce45 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:23:29 +0000 Subject: cleanup --- Zotlabs/Daemon/Addon.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Daemon/Addon.php b/Zotlabs/Daemon/Addon.php index c2889e596..c6778750d 100644 --- a/Zotlabs/Daemon/Addon.php +++ b/Zotlabs/Daemon/Addon.php @@ -2,13 +2,12 @@ namespace Zotlabs\Daemon; -require_once('include/zot.php'); - class Addon { - static public function run($argc,$argv) { + static public function run($argc, $argv) { - call_hooks('daemon_addon',$argv); + call_hooks('daemon_addon', $argv); } + } -- cgit v1.2.3 From 2c8e12200821dfbb052ad738880ac9d1575b9c45 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:29:48 +0000 Subject: cleanup daemon/checksites --- Zotlabs/Daemon/Cache_embeds.php | 1 - Zotlabs/Daemon/Checksites.php | 23 ++++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Zotlabs/Daemon/Cache_embeds.php b/Zotlabs/Daemon/Cache_embeds.php index 08088abd6..9e5b8d2bb 100644 --- a/Zotlabs/Daemon/Cache_embeds.php +++ b/Zotlabs/Daemon/Cache_embeds.php @@ -2,7 +2,6 @@ namespace Zotlabs\Daemon; - class Cache_embeds { static public function run($argc,$argv) { diff --git a/Zotlabs/Daemon/Checksites.php b/Zotlabs/Daemon/Checksites.php index 3bcfdd7cf..7227e96e4 100644 --- a/Zotlabs/Daemon/Checksites.php +++ b/Zotlabs/Daemon/Checksites.php @@ -6,34 +6,35 @@ require_once('include/hubloc.php'); class Checksites { - static public function run($argc,$argv) { + static public function run($argc, $argv) { logger('checksites: start'); - - if(($argc > 1) && ($argv[1])) + + if (($argc > 1) && ($argv[1])) $site_id = $argv[1]; - if($site_id) + if ($site_id) $sql_options = " and site_url = '" . dbesc($argv[1]) . "' "; - $days = intval(get_config('system','sitecheckdays')); - if($days < 1) + $days = intval(get_config('system', 'sitecheckdays')); + if ($days < 1) $days = 30; $r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ", - db_utcnow(), db_quoteinterval($days . ' DAY'), + db_utcnow(), + db_quoteinterval($days . ' DAY'), intval(SITE_TYPE_ZOT) ); - if(! $r) + if (!$r) return; - foreach($r as $rr) { - if(! strcasecmp($rr['site_url'],z_root())) + foreach ($r as $rr) { + if (!strcasecmp($rr['site_url'], z_root())) continue; $x = ping_site($rr['site_url']); - if($x['success']) { + if ($x['success']) { logger('checksites: ' . $rr['site_url']); q("update site set site_update = '%s' where site_url = '%s' ", dbesc(datetime_convert()), -- cgit v1.2.3 From e191966e6971fe560d790c5805018e747e94619e Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:36:47 +0000 Subject: only var can be passed by reference, cleanup --- Zotlabs/Daemon/Cron_daily.php | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Zotlabs/Daemon/Cron_daily.php b/Zotlabs/Daemon/Cron_daily.php index a6daad051..1983c68e6 100644 --- a/Zotlabs/Daemon/Cron_daily.php +++ b/Zotlabs/Daemon/Cron_daily.php @@ -6,7 +6,7 @@ use Zotlabs\Lib\Libzotdir; class Cron_daily { - static public function run($argc,$argv) { + static public function run($argc, $argv) { logger('cron_daily: start'); @@ -15,14 +15,12 @@ class Cron_daily { * */ - Libzotdir::check_upstream_directory(); - // Fire off the Cron_weekly process if it's the correct day. - $d3 = intval(datetime_convert('UTC','UTC','now','N')); - if($d3 == 7) { + $d3 = intval(datetime_convert('UTC', 'UTC', 'now', 'N')); + if ($d3 == 7) { Master::Summon(array('Cron_weekly')); } @@ -53,8 +51,8 @@ class Cron_daily { // Clean up emdedded content cache q("DELETE FROM cache WHERE updated < %s - INTERVAL %s", - db_utcnow(), - db_quoteinterval(get_config('system','active_expire_days', '30') . ' DAY') + db_utcnow(), + db_quoteinterval(get_config('system', 'active_expire_days', '30') . ' DAY') ); //update statistics in config @@ -68,8 +66,8 @@ class Cron_daily { // expire old delivery reports - $keep_reports = intval(get_config('system','expire_delivery_reports')); - if($keep_reports === 0) + $keep_reports = intval(get_config('system', 'expire_delivery_reports')); + if ($keep_reports === 0) $keep_reports = 10; q("delete from dreport where dreport_time < %s - INTERVAL %s", @@ -85,13 +83,12 @@ class Cron_daily { // Pull remote changes and push local changes. // potential issue: how do we keep from creating an endless update loop? - $dirmode = get_config('system','directory_mode'); + $dirmode = get_config('system', 'directory_mode'); - if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { + if ($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { Libzotdir::sync_directories($dirmode); } - Master::Summon(array('Expire')); Master::Summon(array('Cli_suggest')); @@ -99,9 +96,10 @@ class Cron_daily { z6_discover(); - call_hooks('cron_daily',datetime_convert()); + $date = datetime_convert(); + call_hooks('cron_daily', $date); - set_config('system','last_expire_day',intval(datetime_convert('UTC','UTC','now','d'))); + set_config('system', 'last_expire_day', intval(datetime_convert('UTC', 'UTC', 'now', 'd'))); /** * End Cron Daily -- cgit v1.2.3 From 3742fe80fc54115683106d2b802b086123ea7bde Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:37:54 +0000 Subject: only var can be passed by reference, cleanup --- Zotlabs/Daemon/Cron_weekly.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Zotlabs/Daemon/Cron_weekly.php b/Zotlabs/Daemon/Cron_weekly.php index d44400767..34d0ed1ee 100644 --- a/Zotlabs/Daemon/Cron_weekly.php +++ b/Zotlabs/Daemon/Cron_weekly.php @@ -4,16 +4,17 @@ namespace Zotlabs\Daemon; class Cron_weekly { - static public function run($argc,$argv) { + static public function run($argc, $argv) { /** * Cron Weekly - * + * * Actions in the following block are executed once per day only on Sunday (once per week). * */ - call_hooks('cron_weekly',datetime_convert()); + $date = datetime_convert(); + call_hooks('cron_weekly', $date); z_check_cert(); @@ -31,8 +32,8 @@ class Cron_weekly { db_utcnow(), db_quoteinterval('21 DAY'), db_utcnow(), db_quoteinterval('10 DAY') ); - if($r) { - foreach($r as $rv) { + if ($r) { + foreach ($r as $rv) { channel_remove_final($rv['channel_id']); } } @@ -43,14 +44,14 @@ class Cron_weekly { db_utcnow(), db_quoteinterval('14 DAY') ); - $dirmode = intval(get_config('system','directory_mode')); - if($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) { - logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())),true)); + $dirmode = intval(get_config('system', 'directory_mode')); + if ($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) { + logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())), true)); } // Check for dead sites Master::Summon(array('Checksites')); - + // update searchable doc indexes Master::Summon(array('Importdoc')); -- cgit v1.2.3 From d0f3d2b2a5736b8d24c4bfc9fa82f5e32bdc2fb2 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:40:01 +0000 Subject: cleanup daemon/curlauth --- Zotlabs/Daemon/Cron_weekly.php | 2 +- Zotlabs/Daemon/CurlAuth.php | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Zotlabs/Daemon/Cron_weekly.php b/Zotlabs/Daemon/Cron_weekly.php index 34d0ed1ee..407aa40ef 100644 --- a/Zotlabs/Daemon/Cron_weekly.php +++ b/Zotlabs/Daemon/Cron_weekly.php @@ -19,7 +19,7 @@ class Cron_weekly { z_check_cert(); prune_hub_reinstalls(); - + mark_orphan_hubsxchans(); // Find channels that were removed in the last three weeks, but diff --git a/Zotlabs/Daemon/CurlAuth.php b/Zotlabs/Daemon/CurlAuth.php index de41382e3..2396da9aa 100644 --- a/Zotlabs/Daemon/CurlAuth.php +++ b/Zotlabs/Daemon/CurlAuth.php @@ -2,6 +2,8 @@ namespace Zotlabs\Daemon; +use App; + // generate a curl compatible cookie file with an authenticated session for the given channel_id. // If this file is then used with curl and the destination url is sent through zid() or manually // manipulated to add a zid, it should allow curl to provide zot magic-auth across domains. @@ -10,15 +12,15 @@ namespace Zotlabs\Daemon; class CurlAuth { - static public function run($argc,$argv) { + static public function run($argc, $argv) { - if($argc != 2) + if ($argc != 2) return; - \App::$session->start(); + App::$session->start(); $_SESSION['authenticated'] = 1; - $_SESSION['uid'] = $argv[1]; + $_SESSION['uid'] = $argv[1]; $x = session_id(); @@ -29,14 +31,14 @@ class CurlAuth { $output = ''; - if($e) { + if ($e) { $lines = file($f); - if($lines) { - foreach($lines as $line) { - if(strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) { + if ($lines) { + foreach ($lines as $line) { + if (strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) { $tokens = explode("\t", $line); $tokens = array_map('trim', $tokens); - if($tokens[4] > time()) { + if ($tokens[4] > time()) { $output .= $line . "\n"; } } @@ -46,9 +48,9 @@ class CurlAuth { } } $t = time() + (24 * 3600); - file_put_contents($f, $output . 'HttpOnly_' . \App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0)); + file_put_contents($f, $output . 'HttpOnly_' . App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0)); - file_put_contents($c,$x); + file_put_contents($c, $x); return; } -- cgit v1.2.3 From 45350179b4ad48b8fc81e23722974d95f39a1fe2 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:41:34 +0000 Subject: cleanup daemon/deliver --- Zotlabs/Daemon/Deliver.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Zotlabs/Daemon/Deliver.php b/Zotlabs/Daemon/Deliver.php index c853af6a8..f8149ee69 100644 --- a/Zotlabs/Daemon/Deliver.php +++ b/Zotlabs/Daemon/Deliver.php @@ -5,25 +5,25 @@ namespace Zotlabs\Daemon; require_once('include/queue_fn.php'); class Deliver { - - static public function run($argc,$argv) { - if($argc < 2) + static public function run($argc, $argv) { + + if ($argc < 2) return; - logger('deliver: invoked: ' . print_r($argv,true), LOGGER_DATA); + logger('deliver: invoked: ' . print_r($argv, true), LOGGER_DATA); - for($x = 1; $x < $argc; $x ++) { + for ($x = 1; $x < $argc; $x++) { - if(! $argv[$x]) + if (!$argv[$x]) continue; $r = q("select * from outq where outq_hash = '%s'", dbesc($argv[$x]) ); - if($r) { - queue_deliver($r[0],true); + if ($r) { + queue_deliver($r[0], true); } } -- cgit v1.2.3 From d5bd09b983f5d3edc44bf383a27ef84a9aa84f5a Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 13:49:58 +0000 Subject: cleanup daemon/deliver_hooks, daemon/directory --- Zotlabs/Daemon/Deliver_hooks.php | 11 ++++------- Zotlabs/Daemon/Directory.php | 40 +++++++++++++++++++--------------------- Zotlabs/Lib/Libzot.php | 2 +- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/Zotlabs/Daemon/Deliver_hooks.php b/Zotlabs/Daemon/Deliver_hooks.php index e8b5acef0..4d3ce4e1d 100644 --- a/Zotlabs/Daemon/Deliver_hooks.php +++ b/Zotlabs/Daemon/Deliver_hooks.php @@ -2,21 +2,18 @@ namespace Zotlabs\Daemon; -require_once('include/zot.php'); - class Deliver_hooks { - static public function run($argc,$argv) { + static public function run($argc, $argv) { - if($argc < 2) + if ($argc < 2) return; - $r = q("select * from item where id = '%d'", intval($argv[1]) ); - if($r) - call_hooks('notifier_normal',$r[0]); + if ($r) + call_hooks('notifier_normal', $r[0]); } } diff --git a/Zotlabs/Daemon/Directory.php b/Zotlabs/Daemon/Directory.php index ab58432de..1f307b273 100644 --- a/Zotlabs/Daemon/Directory.php +++ b/Zotlabs/Daemon/Directory.php @@ -8,40 +8,40 @@ use Zotlabs\Lib\Queue; class Directory { - static public function run($argc,$argv){ + static public function run($argc, $argv) { - if($argc < 2) + if ($argc < 2) return; - $force = false; + $force = false; $pushall = true; - if($argc > 2) { - if($argv[2] === 'force') + if ($argc > 2) { + if ($argv[2] === 'force') $force = true; - if($argv[2] === 'nopush') + if ($argv[2] === 'nopush') $pushall = false; - } + } logger('directory update', LOGGER_DEBUG); - $dirmode = get_config('system','directory_mode'); - if($dirmode === false) + $dirmode = get_config('system', 'directory_mode'); + if ($dirmode === false) $dirmode = DIRECTORY_MODE_NORMAL; $x = q("select * from channel where channel_id = %d limit 1", intval($argv[1]) ); - if(! $x) + if (!$x) return; $channel = $x[0]; - if($dirmode != DIRECTORY_MODE_NORMAL) { + if ($dirmode != DIRECTORY_MODE_NORMAL) { // this is an in-memory update and we don't need to send a network packet. - Libzotdir::local_dir_update($argv[1],$force); + Libzotdir::local_dir_update($argv[1], $force); q("update channel set channel_dirdate = '%s' where channel_id = %d", dbesc(datetime_convert()), @@ -49,8 +49,8 @@ class Directory { ); // Now update all the connections - if($pushall) - Master::Summon(array('Notifier','refresh_all',$channel['channel_id'])); + if ($pushall) + Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id'])); return; } @@ -63,14 +63,12 @@ class Directory { // ensure the upstream directory is updated - - $packet = Libzot::build_packet($channel,(($force) ? 'force_refresh' : 'refresh')); - $z = Libzot::zot($url,$packet,$channel); - + $packet = Libzot::build_packet($channel, (($force) ? 'force_refresh' : 'refresh')); + $z = Libzot::zot($url, $packet, $channel); // re-queue if unsuccessful - if(! $z['success']) { + if (!$z['success']) { /** @FIXME we aren't updating channel_dirdate if we have to queue * the directory packet. That means we'll try again on the next poll run. @@ -95,8 +93,8 @@ class Directory { } // Now update all the connections - if($pushall) - Master::Summon(array('Notifier','refresh_all',$channel['channel_id'])); + if ($pushall) + Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id'])); } } diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 9483759cf..cde4c0145 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -189,7 +189,7 @@ class Libzot { * @see z_post_url() * * @param string $url - * @param array $data + * @param string $data * @param array $channel (required if using zot6 delivery) * @param array $crypto (required if encrypted httpsig, requires hubloc_sitekey and site_crypto elements) * @return array see z_post_url() for returned data format -- cgit v1.2.3 From 9acfc44ac95864007778a837f7833143b271f4d6 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:00:21 +0000 Subject: cleanup daemon/expire --- Zotlabs/Daemon/Expire.php | 30 +++++++++++++++--------------- composer.json | 1 + 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php index a688d6f97..09a87a8f4 100644 --- a/Zotlabs/Daemon/Expire.php +++ b/Zotlabs/Daemon/Expire.php @@ -5,16 +5,16 @@ namespace Zotlabs\Daemon; class Expire { - static public function run($argc,$argv){ + static public function run($argc, $argv) { cli_startup(); - + $pid = get_config('expire', 'procid', false); if ($pid && (function_exists('posix_kill') ? posix_kill($pid, 0) : true)) { - logger('Expire: procedure already run with pid ' . $pid, LOGGER_DEBUG); - return; + logger('Expire: procedure already run with pid ' . $pid, LOGGER_DEBUG); + return; } - + $pid = getmypid(); set_config('expire', 'procid', $pid); @@ -32,19 +32,18 @@ class Expire { // physically remove anything that has been deleted for more than two months /** @FIXME - this is a wretchedly inefficient query */ - $r = q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('36 DAY') + q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s", + db_utcnow(), + db_quoteinterval('36 DAY') ); - /** @FIXME make this optional as it could have a performance impact on large sites */ - if (intval(get_config('system', 'optimize_items'))) q("optimize table item"); logger('expire: start with pid ' . $pid, LOGGER_DEBUG); - $site_expire = intval(get_config('system', 'default_expire_days')); - $commented_days = intval(get_config('system','active_expire_days')); + $site_expire = intval(get_config('system', 'default_expire_days')); + $commented_days = intval(get_config('system', 'active_expire_days')); logger('site_expire: ' . $site_expire); @@ -64,11 +63,12 @@ class Expire { $channel_expire = $service_class_expire; else $channel_expire = $site_expire; - + if (intval($channel_expire) && (intval($channel_expire) < intval($rr['channel_expire_days'])) || intval($rr['channel_expire_days'] == 0)) { $expire_days = $channel_expire; - } else { + } + else { $expire_days = $rr['channel_expire_days']; } @@ -93,13 +93,13 @@ class Expire { } logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG); - + if ($expire_days) item_expire($x['channel_id'], $expire_days, $commented_days); logger('Expire: sys: done', LOGGER_DEBUG); } - + del_config('expire', 'procid'); } } diff --git a/composer.json b/composer.json index ab9d6a371..d138ccc43 100644 --- a/composer.json +++ b/composer.json @@ -31,6 +31,7 @@ "ext-openssl": "*", "ext-json": "*", "ext-zip": "*", + "ext-posix": "*", "sabre/dav": "^4.0", "michelf/php-markdown": "^1.7", "bshaffer/oauth2-server-php": "^1.9", -- cgit v1.2.3 From 441525750f9764f3f42a2ed78ee32a2e6f34c523 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:02:37 +0000 Subject: more cleanup daemon/expire --- Zotlabs/Daemon/Expire.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php index 09a87a8f4..8ca92b6c5 100644 --- a/Zotlabs/Daemon/Expire.php +++ b/Zotlabs/Daemon/Expire.php @@ -21,7 +21,8 @@ class Expire { // perform final cleanup on previously delete items $r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('10 DAY') + db_utcnow(), + db_quoteinterval('10 DAY') ); if ($r) { foreach ($r as $rr) { @@ -47,7 +48,7 @@ class Expire { logger('site_expire: ' . $site_expire); - $r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true"); + $r = dbq("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true"); if ($r) { foreach ($r as $rr) { -- cgit v1.2.3 From 8e5df2dd2282e98d39c6c5e3c7ef51b71f3979b5 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:08:31 +0000 Subject: more cleanup daemon/externals --- Zotlabs/Daemon/Externals.php | 53 ++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/Zotlabs/Daemon/Externals.php b/Zotlabs/Daemon/Externals.php index a9988a509..b657f9de4 100644 --- a/Zotlabs/Daemon/Externals.php +++ b/Zotlabs/Daemon/Externals.php @@ -8,23 +8,22 @@ require_once('include/channel.php'); class Externals { - static public function run($argc,$argv){ + static public function run($argc, $argv) { - $total = 0; + $total = 0; $attempts = 0; logger('externals: startup', LOGGER_DEBUG); // pull in some public posts + while ($total == 0 && $attempts < 3) { + $arr = ['url' => '']; + call_hooks('externals_url_select', $arr); - while($total == 0 && $attempts < 3) { - $arr = array('url' => ''); - call_hooks('externals_url_select',$arr); - - if($arr['url']) { + if ($arr['url']) { $url = $arr['url']; - } + } else { $randfunc = db_getfunc('RAND'); @@ -35,36 +34,36 @@ class Externals { intval(DIRECTORY_MODE_STANDALONE), intval(SITE_TYPE_ZOT) ); - if($r) + if ($r) $url = $r[0]['site_url']; } $blacklisted = false; - if(! check_siteallowed($url)) { + if (!check_siteallowed($url)) { logger('blacklisted site: ' . $url); $blacklisted = true; } - $attempts ++; + $attempts++; // make sure we can eventually break out if somebody blacklists all known sites - if($blacklisted) { - if($attempts > 20) + if ($blacklisted) { + if ($attempts > 20) break; - $attempts --; + $attempts--; continue; } - if($url) { - if($r[0]['site_pull'] > NULL_DATE) - $mindate = urlencode(datetime_convert('','',$r[0]['site_pull'] . ' - 1 day')); + if ($url) { + if ($r[0]['site_pull'] > NULL_DATE) + $mindate = urlencode(datetime_convert('', '', $r[0]['site_pull'] . ' - 1 day')); else { - $days = get_config('externals','since_days'); - if($days === false) + $days = get_config('externals', 'since_days'); + if ($days === false) $days = 15; - $mindate = urlencode(datetime_convert('','','now - ' . intval($days) . ' days')); + $mindate = urlencode(datetime_convert('', '', 'now - ' . intval($days) . ' days')); } $feedurl = $url . '/zotfeed?f=&mindate=' . $mindate; @@ -72,22 +71,22 @@ class Externals { logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG); $x = z_fetch_url($feedurl); - if(($x) && ($x['success'])) { + if (($x) && ($x['success'])) { q("update site set site_pull = '%s' where site_url = '%s'", dbesc(datetime_convert()), dbesc($url) ); - $j = json_decode($x['body'],true); - if($j['success'] && $j['messages']) { + $j = json_decode($x['body'], true); + if ($j['success'] && $j['messages']) { $sys = get_sys_channel(); - foreach($j['messages'] as $message) { + foreach ($j['messages'] as $message) { // on these posts, clear any route info. $message['route'] = ''; - $results = process_delivery(array('hash' => 'undefined'), get_item_elements($message), - array(array('hash' => $sys['xchan_hash'])), false, true); - $total ++; + process_delivery(['hash' => 'undefined'], get_item_elements($message), + [['hash' => $sys['xchan_hash']]], false, true); + $total++; } logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG); } -- cgit v1.2.3 From f1ac5bb667164a93f4969c254aa2010e7c368dd8 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:09:48 +0000 Subject: more cleanup daemon/gprobe --- Zotlabs/Daemon/Gprobe.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Zotlabs/Daemon/Gprobe.php b/Zotlabs/Daemon/Gprobe.php index 9e74eb8b5..29efcf475 100644 --- a/Zotlabs/Daemon/Gprobe.php +++ b/Zotlabs/Daemon/Gprobe.php @@ -9,27 +9,27 @@ use Zotlabs\Lib\Zotfinger; // performs zot_finger on $argv[1], which is a hex_encoded webbie/reddress class Gprobe { - static public function run($argc,$argv) { + static public function run($argc, $argv) { - if($argc != 2) + if ($argc != 2) return; $url = hex2bin($argv[1]); - if(! strpos($url,'@')) + if (!strpos($url, '@')) return; $r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' limit 1", dbesc($url) ); - if(! $r) { + if (!$r) { $href = Webfinger::zot_url(punify($url)); - if($href) { + if ($href) { $zf = Zotfinger::exec($href, null); } - if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) { - $xc = Libzot::import_xchan($zf['data']); + if (is_array($zf) && array_path_exists('signature/signer', $zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) { + Libzot::import_xchan($zf['data']); } } -- cgit v1.2.3 From 8f88543478ecdf80b01757a0f09bb2cbea50c7b8 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:10:38 +0000 Subject: more cleanup daemon/importdoc --- Zotlabs/Daemon/Importdoc.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Zotlabs/Daemon/Importdoc.php b/Zotlabs/Daemon/Importdoc.php index 0ca589e4a..9e818e2b3 100755 --- a/Zotlabs/Daemon/Importdoc.php +++ b/Zotlabs/Daemon/Importdoc.php @@ -5,7 +5,7 @@ namespace Zotlabs\Daemon; class Importdoc { - static public function run($argc,$argv) { + static public function run($argc, $argv) { require_once('include/help.php'); @@ -16,20 +16,20 @@ class Importdoc { static public function update_docs_dir($s) { $f = basename($s); $d = dirname($s); - if($s === 'doc/html') + if ($s === 'doc/html') return; $files = glob("$d/$f"); - if($files) { - foreach($files as $fi) { - if($fi === 'doc/html') { + if ($files) { + foreach ($files as $fi) { + if ($fi === 'doc/html') { continue; } - if(is_dir($fi)) { + if (is_dir($fi)) { self::update_docs_dir("$fi/*"); } else { // don't update media content - if(strpos(z_mime_content_type($fi),'text') === 0) { + if (strpos(z_mime_content_type($fi), 'text') === 0) { store_doc_file($fi); } } -- cgit v1.2.3 From 101005f3d23b2a12c017293ef6df2f8875339949 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:11:29 +0000 Subject: more cleanup daemon/importfile --- Zotlabs/Daemon/Importfile.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Zotlabs/Daemon/Importfile.php b/Zotlabs/Daemon/Importfile.php index 749949679..299fb1ee5 100644 --- a/Zotlabs/Daemon/Importfile.php +++ b/Zotlabs/Daemon/Importfile.php @@ -6,22 +6,21 @@ use Zotlabs\Lib\Libsync; class Importfile { - static public function run($argc,$argv){ + static public function run($argc, $argv) { - logger('Importfile: ' . print_r($argv,true)); + logger('Importfile: ' . print_r($argv, true)); - if($argc < 3) + if ($argc < 3) return; $channel = channelx_by_n($argv[1]); - if(! $channel) + if (!$channel) return; $srcfile = $argv[2]; $folder = (($argc > 3) ? $argv[3] : ''); $dstname = (($argc > 4) ? $argv[4] : ''); - - $hash = random_string(); + $hash = random_string(); $arr = [ 'src' => $srcfile, @@ -35,15 +34,15 @@ class Importfile { 'replace' => true ]; - if($folder) + if ($folder) $arr['folder'] = $folder; - attach_store($channel,$channel['channel_hash'],'import',$arr); + attach_store($channel, $channel['channel_hash'], 'import', $arr); + + $sync = attach_export_data($channel, $hash); + if ($sync) + Libsync::build_sync_packet($channel['channel_id'], ['file' => [$sync]]); - $sync = attach_export_data($channel,$hash); - if($sync) - Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync))); - return; } } -- cgit v1.2.3 From 6e7a2d0d96da54dfbceb5873ed4a5c40adc51d5f Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:13:58 +0000 Subject: more cleanup daemon/master --- Zotlabs/Daemon/Master.php | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/Zotlabs/Daemon/Master.php b/Zotlabs/Daemon/Master.php index 8c3a7e570..6fa656be5 100644 --- a/Zotlabs/Daemon/Master.php +++ b/Zotlabs/Daemon/Master.php @@ -2,58 +2,57 @@ namespace Zotlabs\Daemon; -if(array_search( __file__ , get_included_files()) === 0) { +if (array_search(__file__, get_included_files()) === 0) { require_once('include/cli_startup.php'); array_shift($argv); $argc = count($argv); - if($argc) - Master::Release($argc,$argv); + if ($argc) + Master::Release($argc, $argv); return; } - class Master { static public function Summon($arr) { $hookinfo = [ - 'argv'=>$arr + 'argv' => $arr ]; - call_hooks ('daemon_master_summon',$hookinfo); + call_hooks('daemon_master_summon', $hookinfo); - $arr = $hookinfo['argv']; + $arr = $hookinfo['argv']; $argc = count($arr); - if ((!is_array($arr) || (count($arr) < 1))) { - logger("Summon handled by hook.",LOGGER_DEBUG); + if ((!is_array($arr) || ($argc < 1))) { + logger("Summon handled by hook.", LOGGER_DEBUG); return; } - $phpbin = get_config('system','phpbin','php'); - proc_run($phpbin,'Zotlabs/Daemon/Master.php',$arr); + $phpbin = get_config('system', 'phpbin', 'php'); + proc_run($phpbin, 'Zotlabs/Daemon/Master.php', $arr); } - static public function Release($argc,$argv) { + static public function Release($argc, $argv) { cli_startup(); $hookinfo = [ - 'argv'=>$argv + 'argv' => $argv ]; - call_hooks ('daemon_master_release',$hookinfo); + call_hooks('daemon_master_release', $hookinfo); $argv = $hookinfo['argv']; $argc = count($argv); - if ((!is_array($argv) || (count($argv) < 1))) { - logger("Release handled by hook.",LOGGER_DEBUG); + if ((!is_array($argv) || ($argc < 1))) { + logger("Release handled by hook.", LOGGER_DEBUG); return; } - logger('Master: release: ' . json_encode($argv), LOGGER_ALL,LOG_DEBUG); - $cls = '\\Zotlabs\\Daemon\\' . $argv[0]; - $cls::run($argc,$argv); + logger('Master: release: ' . json_encode($argv), LOGGER_ALL, LOG_DEBUG); + $cls = '\\Zotlabs\\Daemon\\' . $argv[0]; + $cls::run($argc, $argv); } } -- cgit v1.2.3 From 836637621d7cbe930917fac483af46a5abc6c081 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:23:23 +0000 Subject: more cleanup daemon/notifier --- Zotlabs/Daemon/Notifier.php | 407 ++++++++++++++++++++++---------------------- 1 file changed, 199 insertions(+), 208 deletions(-) diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php index 626299661..78e116d68 100644 --- a/Zotlabs/Daemon/Notifier.php +++ b/Zotlabs/Daemon/Notifier.php @@ -14,7 +14,6 @@ require_once('include/items.php'); require_once('include/bbcode.php'); - /* * This file was at one time responsible for doing all deliveries, but this caused * big problems on shared hosting systems, where the process might get killed by the @@ -81,198 +80,198 @@ require_once('include/bbcode.php'); */ - class Notifier { - static public function run($argc,$argv){ + static public function run($argc, $argv) { - if($argc < 3) + if ($argc < 3) return; - logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG); + logger('notifier: invoked: ' . print_r($argv, true), LOGGER_DEBUG); $cmd = $argv[1]; $item_id = $argv[2]; - if(! $item_id) + if (!$item_id) return; $sys = get_sys_channel(); - $deliveries = array(); + $deliveries = []; - $request = false; - $mail = false; - $top_level = false; - $location = false; - $recipients = array(); - $url_recipients = array(); - $normal_mode = true; - $packet_type = 'undefined'; + $request = false; + $mail = false; + $location = false; + $recipients = []; + $normal_mode = true; + $packet_type = 'undefined'; - if($cmd === 'mail' || $cmd === 'single_mail') { + if ($cmd === 'mail' || $cmd === 'single_mail') { $normal_mode = false; - $mail = true; - $private = true; - $message = q("SELECT * FROM mail WHERE id = %d LIMIT 1", - intval($item_id) + $mail = true; + $private = true; + $message = q("SELECT * FROM mail WHERE id = %d LIMIT 1", + intval($item_id) ); - if(! $message) { + if (!$message) { return; } xchan_mail_query($message[0]); - $uid = $message[0]['channel_id']; + $uid = $message[0]['channel_id']; $recipients[] = $message[0]['from_xchan']; // include clones $recipients[] = $message[0]['to_xchan']; - $item = $message[0]; - + $item = $message[0]; $encoded_item = encode_mail($item); $s = q("select * from channel where channel_id = %d limit 1", - intval($item['channel_id']) + intval($uid) ); - if($s) + if ($s) $channel = $s[0]; } - elseif($cmd === 'request') { - $channel_id = $item_id; - $xchan = $argv[3]; + elseif ($cmd === 'request') { + $channel_id = $item_id; + $xchan = $argv[3]; $request_message_id = $argv[4]; $s = q("select * from channel where channel_id = %d limit 1", intval($channel_id) ); - if($s) + if ($s) $channel = $s[0]; - $private = true; + $private = true; $recipients[] = $xchan; - $packet_type = 'request'; - $normal_mode = false; + $packet_type = 'request'; + $normal_mode = false; } - elseif($cmd === 'keychange') { + elseif ($cmd === 'keychange') { $channel = channelx_by_n($item_id); - $r = q("select abook_xchan from abook where abook_channel = %d", + + $r = q("select abook_xchan from abook where abook_channel = %d", intval($item_id) ); - if($r) { - foreach($r as $rr) { + if ($r) { + foreach ($r as $rr) { $recipients[] = $rr['abook_xchan']; } } - $private = false; + $private = false; $packet_type = 'keychange'; $normal_mode = false; } - elseif(in_array($cmd, [ 'permission_update', 'permission_reject', 'permission_accept', 'permission_create' ])) { + elseif (in_array($cmd, ['permission_update', 'permission_reject', 'permission_accept', 'permission_create'])) { // Get the (single) recipient $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0", intval($item_id) ); - if($r) { + if ($r) { $uid = $r[0]['abook_channel']; // Get the sender $channel = channelx_by_n($uid); - if($channel) { - $perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => ''); - - if($cmd === 'permission_create') - call_hooks('permissions_create',$perm_update); - elseif($cmd === 'permission_accept') - call_hooks('permissions_accept',$perm_update); - elseif($cmd === 'permission_reject') - call_hooks('permissions_reject',$perm_update); + if ($channel) { + $perm_update = ['sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '']; + + if ($cmd === 'permission_create') + call_hooks('permissions_create', $perm_update); + elseif ($cmd === 'permission_accept') + call_hooks('permissions_accept', $perm_update); + elseif ($cmd === 'permission_reject') + call_hooks('permissions_reject', $perm_update); else - call_hooks('permissions_update',$perm_update); + call_hooks('permissions_update', $perm_update); - if($perm_update['success']) { - if($perm_update['deliveries']) { + if ($perm_update['success']) { + if ($perm_update['deliveries']) { $deliveries[] = $perm_update['deliveries']; do_delivery($deliveries); } return; } else { - $recipients[] = $r[0]['abook_xchan']; - $private = false; - $packet_type = 'refresh'; - $packet_recips = array(array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig'],'hash' => $r[0]['xchan_hash'])); + $recipients[] = $r[0]['abook_xchan']; + $private = false; + $packet_type = 'refresh'; + $packet_recips = [['guid' => $r[0]['xchan_guid'], 'guid_sig' => $r[0]['xchan_guid_sig'], 'hash' => $r[0]['xchan_hash']]]; } } } } - elseif($cmd === 'refresh_all') { + elseif ($cmd === 'refresh_all') { logger('notifier: refresh_all: ' . $item_id); - $uid = $item_id; + $uid = $item_id; $channel = channelx_by_n($item_id); - $r = q("select abook_xchan from abook where abook_channel = %d", - intval($item_id) + + $r = q("select abook_xchan from abook where abook_channel = %d", + intval($uid) ); - if($r) { - foreach($r as $rr) { + if ($r) { + foreach ($r as $rr) { $recipients[] = $rr['abook_xchan']; } } - $private = false; + $private = false; $packet_type = 'refresh'; } - elseif($cmd === 'location') { + elseif ($cmd === 'location') { logger('notifier: location: ' . $item_id); $s = q("select * from channel where channel_id = %d limit 1", intval($item_id) ); - if($s) + if ($s) $channel = $s[0]; - $uid = $item_id; - $recipients = array(); - $r = q("select abook_xchan from abook where abook_channel = %d", - intval($item_id) + + $uid = $item_id; + $recipients = []; + + $r = q("select abook_xchan from abook where abook_channel = %d", + intval($uid) ); - if($r) { - foreach($r as $rr) { + if ($r) { + foreach ($r as $rr) { $recipients[] = $rr['abook_xchan']; } } - $encoded_item = array('locations' => Libzot::encode_locations($channel),'type' => 'location', 'encoding' => 'zot'); - $target_item = array('aid' => $channel['channel_account_id'],'uid' => $channel['channel_id']); - $private = false; - $packet_type = 'location'; - $location = true; + $encoded_item = ['locations' => Libzot::encode_locations($channel), 'type' => 'location', 'encoding' => 'zot']; + $target_item = ['aid' => $channel['channel_account_id'], 'uid' => $channel['channel_id']]; + $private = false; + $packet_type = 'location'; + $location = true; } - elseif($cmd === 'purge') { + elseif ($cmd === 'purge') { $xchan = $argv[3]; logger('notifier: purge: ' . $item_id . ' => ' . $xchan); - if (! $xchan) { + if (!$xchan) { return; } - $channel = channelx_by_n($item_id); - $recipients[] = $xchan; - $private = true; - $packet_type = 'purge'; + $channel = channelx_by_n($item_id); + $recipients[] = $xchan; + $private = true; + $packet_type = 'purge'; $packet_recips[] = ['hash' => $xchan]; } - elseif($cmd === 'purge_all') { + elseif ($cmd === 'purge_all') { logger('notifier: purge_all: ' . $item_id); $channel = channelx_by_n($item_id); $recipients = []; - $r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0", + $r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0", intval($item_id) ); - if (! $r) { + if (!$r) { return; } foreach ($r as $rr) { - $recipients[] = $rr['abook_xchan']; + $recipients[] = $rr['abook_xchan']; $packet_recips[] = ['hash' => $rr['abook_xchan']]; } - $private = false; + $private = false; $packet_type = 'purge'; @@ -287,7 +286,7 @@ class Notifier { intval($item_id) ); - if(! $r) + if (!$r) return; xchan_query($r); @@ -296,25 +295,22 @@ class Notifier { $target_item = $r[0]; - if(in_array($target_item['author']['xchan_network'], ['rss', 'anon'])) { + if (in_array($target_item['author']['xchan_network'], ['rss', 'anon'])) { logger('notifier: target item author is not a fetchable actor', LOGGER_DEBUG); return; } - $deleted_item = false; - - if(intval($target_item['item_deleted'])) { + if (intval($target_item['item_deleted'])) { logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG); - $deleted_item = true; } - if(! in_array(intval($target_item['item_type']), [ ITEM_TYPE_POST ] )) { - $hookinfo=[ - 'targetitem'=>$target_item, - 'deliver'=>false + if (!in_array(intval($target_item['item_type']), [ITEM_TYPE_POST])) { + $hookinfo = [ + 'targetitem' => $target_item, + 'deliver' => false ]; if (intval($target_item['item_type'] == ITEM_TYPE_CUSTOM)) { - call_hooks('customitem_deliver',$hookinfo); + call_hooks('customitem_deliver', $hookinfo); } if (!$hookinfo['deliver']) { @@ -328,14 +324,14 @@ class Notifier { // Check for non published items, but allow an exclusion for transmitting hidden file activities - if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) || + if (intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) || intval($target_item['item_blocked']) || - ( intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) { + (intval($target_item['item_hidden']) && ($target_item['obj_type'] !== ACTIVITY_OBJ_FILE))) { logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG); return; } - if(strpos($target_item['postopts'],'nodeliver') !== false) { + if (strpos($target_item['postopts'], 'nodeliver') !== false) { logger('notifier: target item is undeliverable', LOGGER_DEBUG); return; } @@ -343,17 +339,17 @@ class Notifier { $s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", intval($target_item['uid']) ); - if($s) + if ($s) $channel = $s[0]; - if($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) { + if ($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) { logger("notifier: Sending channel {$channel['channel_hash']} is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING); return; } - if($target_item['mid'] === $target_item['parent_mid']) { - $parent_item = $target_item; + if ($target_item['mid'] === $target_item['parent_mid']) { + $parent_item = $target_item; $top_level_post = true; } else { @@ -362,10 +358,10 @@ class Notifier { intval($target_item['parent']) ); - if(! $r) + if (!$r) return; - if(strpos($r[0]['postopts'],'nodeliver') !== false) { + if (strpos($r[0]['postopts'], 'nodeliver') !== false) { logger('notifier: target item is undeliverable', LOGGER_DEBUG, LOG_NOTICE); return; } @@ -373,34 +369,34 @@ class Notifier { xchan_query($r); $r = fetch_post_tags($r); - $parent_item = $r[0]; + $parent_item = $r[0]; $top_level_post = false; } // avoid looping of discover items 12/4/2014 - if($sys && $parent_item['uid'] == $sys['channel_id']) + if ($sys && $parent_item['uid'] == $sys['channel_id']) return; $encoded_item = encode_item($target_item); // Re-use existing signature unless the activity type changed to a Tombstone, which won't verify. - $m = ((intval($target_item['item_deleted'])) ? '' : get_iconfig($target_item,'activitystreams','signed_data')); + $m = ((intval($target_item['item_deleted'])) ? '' : get_iconfig($target_item, 'activitystreams', 'signed_data')); - if($m) { - $activity = json_decode($m,true); + if ($m) { + $activity = json_decode($m, true); } else { $activity = array_merge(['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', z_root() . ZOT_APSCHEMA_REV - ]], Activity::encode_activity($target_item) + ]], Activity::encode_activity($target_item) ); } - logger('target_item: ' . print_r($target_item,true), LOGGER_DEBUG); - logger('encoded: ' . print_r($activity,true), LOGGER_DEBUG); + logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG); + logger('encoded: ' . print_r($activity, true), LOGGER_DEBUG); // Send comments to the owner to re-deliver to everybody in the conversation // We only do this if the item in question originated on this site. This prevents looping. @@ -411,9 +407,7 @@ class Notifier { // flag on comments for an extended period. So we'll also call comment_local_origin() which looks at // the hostname in the message_id and provides a second (fallback) opinion. - $relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false); - - + $relay_to_owner = (((!$top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false); $uplink = false; @@ -425,43 +419,42 @@ class Notifier { // tag_deliver'd post which needs to be sent back to the original author - if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) { + if (($cmd === 'uplink') && intval($parent_item['item_uplink']) && (!$top_level_post)) { logger('notifier: uplink'); $uplink = true; } - if(($relay_to_owner || $uplink) && ($cmd !== 'relay')) { + if (($relay_to_owner || $uplink) && ($cmd !== 'relay')) { logger('notifier: followup relay', LOGGER_DEBUG); - $recipients = array(($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']); - $private = true; - if(! $encoded_item['flags']) - $encoded_item['flags'] = array(); + $recipients = [($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']]; + $private = true; + if (!$encoded_item['flags']) + $encoded_item['flags'] = []; $encoded_item['flags'][] = 'relay'; - $upstream = true; + $upstream = true; } else { logger('notifier: normal distribution', LOGGER_DEBUG); - if($cmd === 'relay') + if ($cmd === 'relay') logger('notifier: owner relay'); $upstream = false; // if our parent is a tag_delivery recipient, uplink to the original author causing // a delivery fork. - if(($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) { + if (($parent_item) && intval($parent_item['item_uplink']) && (!$top_level_post) && ($cmd !== 'uplink')) { // don't uplink a relayed post to the relay owner - if($parent_item['source_xchan'] !== $parent_item['owner_xchan']) { + if ($parent_item['source_xchan'] !== $parent_item['owner_xchan']) { logger('notifier: uplinking this item'); - Master::Summon(array('Notifier','uplink',$item_id)); + Master::Summon(['Notifier', 'uplink', $item_id]); } } - $private = false; - $recipients = collect_recipients($parent_item,$private); - + $private = false; + $recipients = collect_recipients($parent_item, $private); if ($top_level_post) { // remove clones who will receive the post via sync - $recipients = array_diff($recipients, [ $target_item['owner_xchan'] ]); + $recipients = array_diff($recipients, [$target_item['owner_xchan']]); } // FIXME add any additional recipients such as mentions, etc. @@ -474,32 +467,31 @@ class Notifier { // Generic delivery section, we have an encoded item and recipients // Now start the delivery process - $x = $encoded_item; + $x = $encoded_item; $x['title'] = 'private'; - $x['body'] = 'private'; - logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG); + $x['body'] = 'private'; + logger('notifier: encoded item: ' . print_r($x, true), LOGGER_DATA, LOG_DEBUG); //logger('notifier: encoded activity: ' . print_r($activity,true), LOGGER_DATA, LOG_DEBUG); stringify_array_elms($recipients); - if(! $recipients) { + if (!$recipients) { logger('no recipients'); return; } // logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG); - $env_recips = (($private) ? array() : null); - - $details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . protect_sprintf(implode(',',$recipients)) . ")"); + $env_recips = (($private) ? [] : null); - $recip_list = array(); + $details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . protect_sprintf(implode(',', $recipients)) . ")"); - if($details) { - foreach($details as $d) { + $recip_list = []; + if ($details) { + foreach ($details as $d) { $recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')'; - if($private) { + if ($private) { $env_recips[] = [ 'guid' => $d['xchan_guid'], 'guid_sig' => $d['xchan_guid_sig'], @@ -535,8 +527,8 @@ class Notifier { ]; call_hooks('notifier_process', $narr); - if($narr['queued']) { - foreach($narr['queued'] as $pq) + if ($narr['queued']) { + foreach ($narr['queued'] as $pq) $deliveries[] = $pq; } @@ -546,26 +538,26 @@ class Notifier { $env_recips = $narr['env_recips']; $packet_recips = $narr['packet_recips']; - if(($private) && (! $env_recips)) { + if (($private) && (!$env_recips)) { // shouldn't happen - logger('notifier: private message with no envelope recipients.' . print_r($argv,true), LOGGER_NORMAL, LOG_NOTICE); + logger('notifier: private message with no envelope recipients.' . print_r($argv, true), LOGGER_NORMAL, LOG_NOTICE); } - logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list,true), LOGGER_DEBUG); + logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list, true), LOGGER_DEBUG); // Now we have collected recipients (except for external mentions, FIXME) // Let's reduce this to a set of hubs; checking that the site is not dead. $hubs = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_version, site.site_project, site.site_dead from hubloc left join site on site_url = hubloc_url - where hubloc_hash in (" . protect_sprintf(implode(',',$recipients)) . ") + where hubloc_hash in (" . protect_sprintf(implode(',', $recipients)) . ") and hubloc_error = 0 and hubloc_deleted = 0" ); // public posts won't make it to the local public stream unless there's a recipient on this site. // This code block sees if it's a public post and localhost is missing, and if so adds an entry for the local sys channel to the $hubs list - if (! $private) { + if (!$private) { $found_localhost = false; if ($hubs) { foreach ($hubs as $h) { @@ -575,7 +567,7 @@ class Notifier { } } } - if (! $found_localhost) { + if (!$found_localhost) { $localhub = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_version, site.site_project, site.site_dead from hubloc left join site on site_url = hubloc_url where hubloc_id_url = '%s' and hubloc_error = 0 and hubloc_deleted = 0", dbesc(z_root() . '/channel/sys') @@ -586,7 +578,7 @@ class Notifier { } } - if(! $hubs) { + if (!$hubs) { logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE); return; } @@ -605,17 +597,17 @@ class Notifier { $hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all $dead = []; // known dead hubs - report them as undeliverable - foreach($hubs as $hub) { + foreach ($hubs as $hub) { if (intval($hub['site_dead'])) { $dead[] = $hub; continue; } - if($env_recips) { - foreach($env_recips as $er) { - if($hub['hubloc_hash'] === $er['hash']) { - if(! array_key_exists($hub['hubloc_host'] . $hub['hubloc_sitekey'], $hub_env)) { + if ($env_recips) { + foreach ($env_recips as $er) { + if ($hub['hubloc_hash'] === $er['hash']) { + if (!array_key_exists($hub['hubloc_host'] . $hub['hubloc_sitekey'], $hub_env)) { $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] = []; } $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']][] = $er; @@ -624,36 +616,36 @@ class Notifier { } - if($hub['hubloc_network'] == 'zot') { - if(! in_array($hub['hubloc_sitekey'],$keys)) { + if ($hub['hubloc_network'] == 'zot') { + if (!in_array($hub['hubloc_sitekey'], $keys)) { $hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network']; $dhubs[] = $hub; $keys[] = $hub['hubloc_sitekey']; } } else { - if(! in_array($hub['hubloc_url'],$urls)) { - if($hub['hubloc_url'] === z_root()) { + if (!in_array($hub['hubloc_url'], $urls)) { + if ($hub['hubloc_url'] === z_root()) { //deliver to local hub first array_unshift($hublist, $hub['hubloc_host'] . ' ' . $hub['hubloc_network']); array_unshift($dhubs, $hub); } else { $hublist[] = $hub['hubloc_host'] . ' ' . $hub['hubloc_network']; - $dhubs[] = $hub; + $dhubs[] = $hub; } $urls[] = $hub['hubloc_url']; } } } - logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG); + logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist, true), LOGGER_DEBUG, LOG_DEBUG); - foreach($dhubs as $hub) { + foreach ($dhubs as $hub) { - logger('notifier_hub: ' . $hub['hubloc_url'],LOGGER_DEBUG); + logger('notifier_hub: ' . $hub['hubloc_url'], LOGGER_DEBUG); - if(! in_array($hub['hubloc_network'], [ 'zot','zot6' ])) { + if (!in_array($hub['hubloc_network'], ['zot', 'zot6'])) { $narr = [ 'channel' => $channel, 'upstream' => $upstream, @@ -680,9 +672,9 @@ class Notifier { ]; - call_hooks('notifier_hub',$narr); - if($narr['queued']) { - foreach($narr['queued'] as $pq) + call_hooks('notifier_hub', $narr); + if ($narr['queued']) { + foreach ($narr['queued'] as $pq) $deliveries[] = $pq; } continue; @@ -698,11 +690,11 @@ class Notifier { // will invoke a delivery to those connections which are connected to just that // hub instance. - if($cmd === 'single_mail' || $cmd === 'single_activity') { + if ($cmd === 'single_mail' || $cmd === 'single_activity') { continue; } - if(! in_array($hub['hubloc_network'], [ 'zot','zot6' ])) { + if (!in_array($hub['hubloc_network'], ['zot', 'zot6'])) { continue; } @@ -710,31 +702,31 @@ class Notifier { // in the loop. The signature verification step can't handle dashes in the // hashes. - $hash = random_string(48); + $hash = random_string(48); $packet = null; $pmsg = ''; - if($packet_type === 'refresh' || $packet_type === 'purge') { - if($hub['hubloc_network'] === 'zot6') { - $packet = Libzot::build_packet($channel, $packet_type, ids_to_array($packet_recips,'hash')); + if ($packet_type === 'refresh' || $packet_type === 'purge') { + if ($hub['hubloc_network'] === 'zot6') { + $packet = Libzot::build_packet($channel, $packet_type, ids_to_array($packet_recips, 'hash')); } else { - $packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null)); + $packet = zot_build_packet($channel, $packet_type, (($packet_recips) ? $packet_recips : null)); } } - if($packet_type === 'keychange' && $hub['hubloc_network'] === 'zot') { - $pmsg = get_pconfig($channel['channel_id'],'system','keychange'); - $packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null)); + if ($packet_type === 'keychange' && $hub['hubloc_network'] === 'zot') { + $pmsg = get_pconfig($channel['channel_id'], 'system', 'keychange'); + $packet = zot_build_packet($channel, $packet_type, (($packet_recips) ? $packet_recips : null)); } - elseif($packet_type === 'request' && $hub['hubloc_network'] === 'zot') { - $env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : ''); - $packet = zot_build_packet($channel,$packet_type,$env,$hub['hubloc_sitekey'],$hub['site_crypto'], - $hash, array('message_id' => $request_message_id) + elseif ($packet_type === 'request' && $hub['hubloc_network'] === 'zot') { + $env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : ''); + $packet = zot_build_packet($channel, $packet_type, $env, $hub['hubloc_sitekey'], $hub['site_crypto'], + $hash, ['message_id' => $request_message_id] ); } - if($packet) { + if ($packet) { Queue::insert( [ 'hash' => $hash, @@ -750,11 +742,10 @@ class Notifier { else { $env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : ''); - - if($hub['hubloc_network'] === 'zot6') { + if ($hub['hubloc_network'] === 'zot6') { $zenv = []; - if($env) { - foreach($env as $e) { + if ($env) { + foreach ($env as $e) { $zenv[] = $e['hash']; } } @@ -767,11 +758,11 @@ class Notifier { // For public reshares, some comments to the reshare on the zot fork will not make it to zot6 // due to these different message models. This cannot be prevented at this time. - if($packet_type === 'activity' && $activity['type'] === 'Announce' && intval($target_item['item_private'])) { + if ($packet_type === 'activity' && $activity['type'] === 'Announce' && intval($target_item['item_private'])) { continue; } - $packet = Libzot::build_packet($channel,$packet_type,$zenv,$activity,'activitystreams',(($private) ? $hub['hubloc_sitekey'] : null),$hub['site_crypto']); + $packet = Libzot::build_packet($channel, $packet_type, $zenv, $activity, 'activitystreams', (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto']); } else { // currently zot6 delivery is only performed on normal items and not sync items or mail or anything else @@ -779,28 +770,28 @@ class Notifier { // with before switching to zot6 as the primary zot6 handler checks for the existence of a message delivery report // to trigger dequeue'ing - $z6 = (($encoded_item && $encoded_item['type'] === 'activity' && (! array_key_exists('allow_cid',$encoded_item))) ? true : false); - if($z6) { - $packet = zot6_build_packet($channel,'notify',$env, json_encode($encoded_item), (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash); + $z6 = (($encoded_item && $encoded_item['type'] === 'activity' && (!array_key_exists('allow_cid', $encoded_item))) ? true : false); + if ($z6) { + $packet = zot6_build_packet($channel, 'notify', $env, json_encode($encoded_item), (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'], $hash); } else { - $packet = zot_build_packet($channel,'notify',$env, (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash); + $packet = zot_build_packet($channel, 'notify', $env, (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'], $hash); } } // remove this after most hubs have updated to version 5.0 - if(stripos($hub['site_project'], 'hubzilla') !== false && version_compare($hub['site_version'], '4.7.3', '<=')) { - if($encoded_item['type'] === 'mail') { - $encoded_item['from']['network'] = 'zot'; + if (stripos($hub['site_project'], 'hubzilla') !== false && version_compare($hub['site_version'], '4.7.3', '<=')) { + if ($encoded_item['type'] === 'mail') { + $encoded_item['from']['network'] = 'zot'; $encoded_item['from']['guid_sig'] = str_replace('sha256.', '', $encoded_item['from']['guid_sig']); } else { - $encoded_item['owner']['network'] = 'zot'; + $encoded_item['owner']['network'] = 'zot'; $encoded_item['owner']['guid_sig'] = str_replace('sha256.', '', $encoded_item['owner']['guid_sig']); - if(strpos($encoded_item['author']['url'], z_root()) === 0) { - $encoded_item['author']['network'] = 'zot'; + if (strpos($encoded_item['author']['url'], z_root()) === 0) { + $encoded_item['author']['network'] = 'zot'; $encoded_item['author']['guid_sig'] = str_replace('sha256.', '', $encoded_item['author']['guid_sig']); } } @@ -819,7 +810,7 @@ class Notifier { ); // only create delivery reports for normal undeleted items - if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) { + if (is_array($target_item) && array_key_exists('postopts', $target_item) && (!$target_item['item_deleted']) && (!get_config('system', 'disable_dreport'))) { q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ", dbesc($target_item['mid']), dbesc($hub['hubloc_host']), @@ -835,21 +826,21 @@ class Notifier { $deliveries[] = $hash; } - if($normal_mode) { + if ($normal_mode) { $x = q("select * from hook where hook = 'notifier_normal'"); - if($x) { - Master::Summon( [ 'Deliver_hooks', $target_item['id'] ] ); + if ($x) { + Master::Summon(['Deliver_hooks', $target_item['id']]); } } - if($deliveries) + if ($deliveries) do_delivery($deliveries); logger('notifier: basic loop complete.', LOGGER_DEBUG); if ($dead) { foreach ($dead as $deceased) { - if (is_array($target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) { + if (is_array($target_item) && (!$target_item['item_deleted']) && (!get_config('system', 'disable_dreport'))) { q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s', '%s','%s','%s','%s','%s','%s','%s' ) ", dbesc($target_item['mid']), @@ -865,7 +856,7 @@ class Notifier { } } - call_hooks('notifier_end',$target_item); + call_hooks('notifier_end', $target_item); logger('notifer: complete.'); return; -- cgit v1.2.3 From 08d2fb4ed4e7573e81a646a194361976c0f8f0c3 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:24:44 +0000 Subject: more cleanup daemon/onedirsync --- Zotlabs/Daemon/Onedirsync.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Zotlabs/Daemon/Onedirsync.php b/Zotlabs/Daemon/Onedirsync.php index a952b8117..f29fbe5b8 100644 --- a/Zotlabs/Daemon/Onedirsync.php +++ b/Zotlabs/Daemon/Onedirsync.php @@ -11,14 +11,14 @@ require_once('include/dir_fns.php'); class Onedirsync { - static public function run($argc,$argv) { + static public function run($argc, $argv) { logger('onedirsync: start ' . intval($argv[1])); - if(($argc > 1) && (intval($argv[1]))) + if (($argc > 1) && (intval($argv[1]))) $update_id = intval($argv[1]); - if(! $update_id) { + if (!$update_id) { logger('onedirsync: no update'); return; } @@ -27,9 +27,9 @@ class Onedirsync { intval($update_id) ); - if(! $r) + if (!$r) return; - if(($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr'])) + if (($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (!$r[0]['ud_addr'])) return; // Have we probed this channel more recently than the other directory server @@ -41,8 +41,8 @@ class Onedirsync { dbesc($r[0]['ud_date']), intval(UPDATE_FLAGS_UPDATED) ); - if($x) { - $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'", + if ($x) { + q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'", intval(UPDATE_FLAGS_UPDATED), dbesc($r[0]['ud_addr']), intval(UPDATE_FLAGS_UPDATED), @@ -59,8 +59,8 @@ class Onedirsync { $h = Libzot::zot_record_preferred($h); - if(($h) && ($h['hubloc_status'] & HUBLOC_OFFLINE)) { - $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ", + if (($h) && ($h['hubloc_status'] & HUBLOC_OFFLINE)) { + q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ", intval(UPDATE_FLAGS_UPDATED), dbesc($r[0]['ud_addr']), intval(UPDATE_FLAGS_UPDATED) @@ -72,7 +72,7 @@ class Onedirsync { // we might have to pull this out some day, but for now update_directory_entry() // runs zot_finger() and is kind of zot specific - if($h && ! in_array($h['hubloc_network'], ['zot6', 'zot'])) + if ($h && !in_array($h['hubloc_network'], ['zot6', 'zot'])) return; Libzotdir::update_directory_entry($r[0]); -- cgit v1.2.3 From ef67e181610d6a116b90b151cdd363183c674f11 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:29:01 +0000 Subject: more cleanup daemon/onepoll --- Zotlabs/Daemon/Onepoll.php | 109 ++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index 93a5412b0..0228f10fb 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -2,6 +2,7 @@ namespace Zotlabs\Daemon; +use App; use Zotlabs\Lib\Libzot; require_once('include/zot.php'); @@ -10,20 +11,18 @@ require_once('include/socgraph.php'); class Onepoll { - static public function run($argc,$argv) { + static public function run($argc, $argv) { logger('onepoll: start'); - - if(($argc > 1) && (intval($argv[1]))) + + if (($argc > 1) && (intval($argv[1]))) $contact_id = intval($argv[1]); - if(! $contact_id) { + if (!$contact_id) { logger('onepoll: no contact'); return; } - $d = datetime_convert(); - $contacts = q("SELECT abook.*, xchan.*, account.* FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan where abook_id = %d @@ -32,38 +31,36 @@ class Onepoll { intval($contact_id), intval(ACCOUNT_OK), intval(ACCOUNT_UNVERIFIED) - ); + ); - if(! $contacts) { + if (!$contacts) { logger('onepoll: abook_id not found: ' . $contact_id); return; } $contact = $contacts[0]; - $t = $contact['abook_updated']; - $importer_uid = $contact['abook_channel']; - + $r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", intval($importer_uid) ); - if(! $r) + if (!$r) return; $importer = $r[0]; logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}"); - $last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE)) - ? datetime_convert('UTC','UTC','now - 7 days') - : datetime_convert('UTC','UTC',$contact['abook_updated'] . ' - 2 days') + $last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE)) + ? datetime_convert('UTC', 'UTC', 'now - 7 days') + : datetime_convert('UTC', 'UTC', $contact['abook_updated'] . ' - 2 days') ); - if($contact['xchan_network'] === 'rss') { + if ($contact['xchan_network'] === 'rss') { logger('onepoll: processing feed ' . $contact['xchan_name'], LOGGER_DEBUG); - $alive = handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']); + $alive = handle_feed($importer['channel_id'], $contact_id, $contact['xchan_hash']); if ($alive) { q("update abook set abook_connected = '%s' where abook_id = %d", dbesc(datetime_convert()), @@ -72,22 +69,22 @@ class Onepoll { } return; } - - if(! in_array($contact['xchan_network'],['zot','zot6'])) + + if (!in_array($contact['xchan_network'], ['zot', 'zot6'])) return; // update permissions - if($contact['xchan_network'] === 'zot6') - $x = Libzot::refresh($contact,$importer); + if ($contact['xchan_network'] === 'zot6') + $x = Libzot::refresh($contact, $importer); - if($contact['xchan_network'] === 'zot') - $x = zot_refresh($contact,$importer); + if ($contact['xchan_network'] === 'zot') + $x = zot_refresh($contact, $importer); $responded = false; $updated = datetime_convert(); $connected = datetime_convert(); - if(! $x) { + if (!$x) { // mark for death by not updating abook_connected, this is caught in include/poller.php q("update abook set abook_updated = '%s' where abook_id = %d", dbesc($updated), @@ -103,38 +100,38 @@ class Onepoll { $responded = true; } - if(! $responded) + if (!$responded) return; - if($contact['xchan_connurl']) { + if ($contact['xchan_connurl']) { $fetch_feed = true; - $x = null; + $x = null; // They haven't given us permission to see their stream - $can_view_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'their_perms','view_stream')); + $can_view_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'their_perms', 'view_stream')); - if(! $can_view_stream) + if (!$can_view_stream) $fetch_feed = false; // we haven't given them permission to send us their stream - $can_send_stream = intval(get_abconfig($importer_uid,$contact['abook_xchan'],'my_perms','send_stream')); - - if(! $can_send_stream) + $can_send_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'my_perms', 'send_stream')); + + if (!$can_send_stream) $fetch_feed = false; - if($fetch_feed) { + if ($fetch_feed) { - if(strpos($contact['xchan_connurl'],z_root()) === 0) { + if (strpos($contact['xchan_connurl'], z_root()) === 0) { // local channel - save a network fetch $c = channelx_by_hash($contact['xchan_hash']); - if($c) { - $x = [ - 'success' => true, - 'body' => json_encode( [ - 'success' => true, - 'messages' => zot_feed($c['channel_id'], $importer['xchan_hash'], [ 'mindate' => $last_update ]) + if ($c) { + $x = [ + 'success' => true, + 'body' => json_encode([ + 'success' => true, + 'messages' => zot_feed($c['channel_id'], $importer['xchan_hash'], ['mindate' => $last_update]) ]) ]; } @@ -142,43 +139,43 @@ class Onepoll { else { // remote fetch - $feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']); - $feedurl .= '?f=&mindate=' . urlencode($last_update) . '&zid=' . $importer['channel_address'] . '@' . \App::get_hostname(); + $feedurl = str_replace('/poco/', '/zotfeed/', $contact['xchan_connurl']); + $feedurl .= '?f=&mindate=' . urlencode($last_update) . '&zid=' . $importer['channel_address'] . '@' . App::get_hostname(); $recurse = 0; - $x = z_fetch_url($feedurl, false, $recurse, [ 'session' => true ]); + $x = z_fetch_url($feedurl, false, $recurse, ['session' => true]); } - logger('feed_update: ' . print_r($x,true), LOGGER_DATA); + logger('feed_update: ' . print_r($x, true), LOGGER_DATA); } - if(($x) && ($x['success'])) { + if (($x) && ($x['success'])) { $total = 0; logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl); - $j = json_decode($x['body'],true); - if($j['success'] && $j['messages']) { - foreach($j['messages'] as $message) { - $results = process_delivery(array('hash' => $contact['xchan_hash']), get_item_elements($message), - array(array('hash' => $importer['xchan_hash'])), false); - logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA); - $total ++; + $j = json_decode($x['body'], true); + if ($j['success'] && $j['messages']) { + foreach ($j['messages'] as $message) { + $results = process_delivery(['hash' => $contact['xchan_hash']], get_item_elements($message), + [['hash' => $importer['xchan_hash']]], false); + logger('onepoll: feed_update: process_delivery: ' . print_r($results, true), LOGGER_DATA); + $total++; } logger("onepoll: $total messages processed"); } } } - + // update the poco details for this connection - if($contact['xchan_connurl']) { + if ($contact['xchan_connurl']) { $r = q("SELECT xlink_id from xlink where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1", intval($contact['xchan_hash']), db_utcnow(), db_quoteinterval('1 DAY') ); - if(! $r) { - poco_load($contact['xchan_hash'],$contact['xchan_connurl']); + if (!$r) { + poco_load($contact['xchan_hash'], $contact['xchan_connurl']); } } -- cgit v1.2.3 From c7a82a6a84ff4bdb372ccfe16d3ec382b485e2de Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:33:19 +0000 Subject: more cleanup daemon/poller --- Zotlabs/Daemon/Poller.php | 141 ++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 74 deletions(-) diff --git a/Zotlabs/Daemon/Poller.php b/Zotlabs/Daemon/Poller.php index dfa628193..8cbdfab0d 100644 --- a/Zotlabs/Daemon/Poller.php +++ b/Zotlabs/Daemon/Poller.php @@ -4,53 +4,50 @@ namespace Zotlabs\Daemon; class Poller { - static public function run($argc,$argv) { + static public function run($argc, $argv) { - $maxsysload = intval(get_config('system','maxloadavg')); - if($maxsysload < 1) + $maxsysload = intval(get_config('system', 'maxloadavg')); + if ($maxsysload < 1) $maxsysload = 50; - if(function_exists('sys_getloadavg')) { + if (function_exists('sys_getloadavg')) { $load = sys_getloadavg(); - if(intval($load[0]) > $maxsysload) { + if (intval($load[0]) > $maxsysload) { logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.'); return; } } - $interval = intval(get_config('system','poll_interval')); - if(! $interval) - $interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval'))); + $interval = intval(get_config('system', 'poll_interval')); + if (!$interval) + $interval = ((get_config('system', 'delivery_interval') === false) ? 3 : intval(get_config('system', 'delivery_interval'))); // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it. $lockfile = 'store/[data]/poller'; - if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) - && (! get_config('system','override_poll_lockfile'))) { + if ((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) + && (!get_config('system', 'override_poll_lockfile'))) { logger("poller: Already running"); return; } - + // Create a lockfile. Needs two vars, but $x doesn't need to contain anything. + $x = ''; file_put_contents($lockfile, $x); logger('poller: start'); - - $manual_id = 0; - $generation = 0; - $force = false; - $restart = false; + $manual_id = 0; + $force = false; - if(($argc > 1) && ($argv[1] == 'force')) + if (($argc > 1) && ($argv[1] == 'force')) $force = true; - if(($argc > 1) && ($argv[1] == 'restart')) { - $restart = true; + if (($argc > 1) && ($argv[1] == 'restart')) { $generation = intval($argv[2]); - if(! $generation) + if (!$generation) return; } - if(($argc > 1) && intval($argv[1])) { + if (($argc > 1) && intval($argv[1])) { $manual_id = intval($argv[1]); $force = true; } @@ -59,17 +56,15 @@ class Poller { reload_plugins(); - $d = datetime_convert(); - // Only poll from those with suitable relationships - $abandon_sql = (($abandon_days) - ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY')) - : '' + $abandon_sql = (($abandon_days) + ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days) . ' DAY')) + : '' ); $randfunc = db_getfunc('RAND'); - + $contacts = q("SELECT abook.abook_updated, abook.abook_connected, abook.abook_feed, abook.abook_channel, abook.abook_id, abook.abook_archived, abook.abook_pending, abook.abook_ignored, abook.abook_blocked, @@ -84,119 +79,117 @@ class Poller { intval(ACCOUNT_UNVERIFIED) // FIXME ); - if($contacts) { - foreach($contacts as $contact) { + if ($contacts) { + foreach ($contacts as $contact) { - $update = false; + $update = false; $t = $contact['abook_updated']; $c = $contact['abook_connected']; - if(intval($contact['abook_feed'])) { - $min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes'); - if(! $min) - $min = intval(get_config('system','minimum_feedcheck_minutes')); - if(! $min) + if (intval($contact['abook_feed'])) { + $min = service_class_fetch($contact['abook_channel'], 'minimum_feedcheck_minutes'); + if (!$min) + $min = intval(get_config('system', 'minimum_feedcheck_minutes')); + if (!$min) $min = 60; - $x = datetime_convert('UTC','UTC',"now - $min minutes"); - if($c < $x) { - Master::Summon(array('Onepoll',$contact['abook_id'])); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); + $x = datetime_convert('UTC', 'UTC', "now - $min minutes"); + if ($c < $x) { + Master::Summon(['Onepoll', $contact['abook_id']]); + if ($interval) + @time_sleep_until(microtime(true) + (float)$interval); } continue; } - if(! in_array($contact['xchan_network'],['zot','zot6'])) + if (!in_array($contact['xchan_network'], ['zot', 'zot6'])) continue; - if($c == $t) { - if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) + if ($c == $t) { + if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 day")) $update = true; } else { - + // if we've never connected with them, start the mark for death countdown from now - - if($c <= NULL_DATE) { - $r = q("update abook set abook_connected = '%s' where abook_id = %d", + + if ($c <= NULL_DATE) { + q("update abook set abook_connected = '%s' where abook_id = %d", dbesc(datetime_convert()), intval($contact['abook_id']) ); - $c = datetime_convert(); + $c = datetime_convert(); $update = true; } // He's dead, Jim - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) { - $r = q("update abook set abook_archived = 1 where abook_id = %d", + if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 30 day")) > 0) { + q("update abook set abook_archived = 1 where abook_id = %d", intval($contact['abook_id']) ); - $update = false; continue; } - if(intval($contact['abook_archived'])) { - $update = false; + if (intval($contact['abook_archived'])) { continue; } // might be dead, so maybe don't poll quite so often - + // recently deceased, so keep up the regular schedule for 3 days - - if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0) - && (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0)) + + if ((strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $c . " + 3 day")) > 0) + && (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 1 day")) > 0)) $update = true; // After that back off and put them on a morphine drip - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) { + if (strcmp(datetime_convert('UTC', 'UTC', 'now'), datetime_convert('UTC', 'UTC', $t . " + 2 day")) > 0) { $update = true; } } - if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked'])) + if (intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked'])) continue; - if((! $update) && (! $force)) - continue; + if ((!$update) && (!$force)) + continue; - Master::Summon(array('Onepoll',$contact['abook_id'])); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); + Master::Summon(['Onepoll', $contact['abook_id']]); + if ($interval) + @time_sleep_until(microtime(true) + (float)$interval); } } $dirmode = intval(get_config('system', 'directory_mode')); - if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { + if ($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { $r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last <= '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ", intval(UPDATE_FLAGS_UPDATED), dbesc(NULL_DATE), db_utcnow(), db_quoteinterval('7 DAY') ); - if($r) { - foreach($r as $rr) { + if ($r) { + foreach ($r as $rr) { // If they didn't respond when we attempted before, back off to once a day // After 7 days we won't bother anymore - if($rr['ud_last'] > NULL_DATE) - if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day')) + if ($rr['ud_last'] > NULL_DATE) + if ($rr['ud_last'] > datetime_convert('UTC', 'UTC', 'now - 1 day')) continue; - Master::Summon(array('Onedirsync',$rr['ud_id'])); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); + Master::Summon(['Onedirsync', $rr['ud_id']]); + if ($interval) + @time_sleep_until(microtime(true) + (float)$interval); } } - } + } - set_config('system','lastpoll',datetime_convert()); + set_config('system', 'lastpoll', datetime_convert()); //All done - clear the lockfile -- cgit v1.2.3 From 8b93136773ab22784af7dae1f97a5da0e99158c7 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:35:00 +0000 Subject: more cleanup daemon/queue --- Zotlabs/Daemon/Queue.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Zotlabs/Daemon/Queue.php b/Zotlabs/Daemon/Queue.php index 4092da225..36bdcfe81 100644 --- a/Zotlabs/Daemon/Queue.php +++ b/Zotlabs/Daemon/Queue.php @@ -7,12 +7,12 @@ require_once('include/zot.php'); class Queue { - static public function run($argc,$argv) { + static public function run($argc, $argv) { require_once('include/items.php'); require_once('include/bbcode.php'); - if($argc > 1) + if ($argc > 1) $queue_id = $argv[1]; else $queue_id = EMPTY_STR; @@ -25,9 +25,9 @@ class Queue { $r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s", db_utcnow(), db_quoteinterval('3 DAY') ); - if($r) { - foreach($r as $rr) { - $h = parse_url($rr['outq_posturl']); + if ($r) { + foreach ($r as $rr) { + $h = parse_url($rr['outq_posturl']); $desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : ''); q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s", dbesc($desturl), @@ -40,7 +40,7 @@ class Queue { db_utcnow(), db_quoteinterval('3 DAY') ); - if($queue_id) { + if ($queue_id) { $r = q("SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1", dbesc($queue_id) ); @@ -53,7 +53,7 @@ class Queue { // so that we don't start off a thousand deliveries for a couple of dead hubs. // The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made). // Other drivers will have to do something different here and may need their own query. - + // Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the // "every 15 minutes" category. We probably need to prioritise them when inserted into the queue // or just prior to this query based on recent and long-term delivery history. If we have good reason to believe @@ -66,7 +66,7 @@ class Queue { db_utcnow() ); while ($r) { - foreach($r as $rv) { + foreach ($r as $rv) { queue_deliver($rv); } $r = q("SELECT *,$sqlrandfunc as rn FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s order by rn limit 1", @@ -74,10 +74,10 @@ class Queue { ); } } - if(! $r) + if (!$r) return; - foreach($r as $rv) { + foreach ($r as $rv) { queue_deliver($rv); } } -- cgit v1.2.3 From 08264f8d11d349bbda92233d984ad52c16c6b2d6 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 14:35:40 +0000 Subject: more cleanup daemon/thumbnail --- Zotlabs/Daemon/Thumbnail.php | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Zotlabs/Daemon/Thumbnail.php b/Zotlabs/Daemon/Thumbnail.php index e1f17c304..72034b870 100644 --- a/Zotlabs/Daemon/Thumbnail.php +++ b/Zotlabs/Daemon/Thumbnail.php @@ -5,30 +5,30 @@ namespace Zotlabs\Daemon; class Thumbnail { - static public function run($argc,$argv) { + static public function run($argc, $argv) { - if(! $argc == 2) + if (!$argc == 2) return; $c = q("select * from attach where hash = '%s' ", dbesc($argv[1]) ); - if(! $c) + if (!$c) return; $attach = $c[0]; - $preview_style = intval(get_config('system','thumbnail_security',0)); - $preview_width = intval(get_config('system','thumbnail_width',300)); - $preview_height = intval(get_config('system','thumbnail_height',300)); + $preview_style = intval(get_config('system', 'thumbnail_security', 0)); + $preview_width = intval(get_config('system', 'thumbnail_width', 300)); + $preview_height = intval(get_config('system', 'thumbnail_height', 300)); $p = [ 'attach' => $attach, 'preview_style' => $preview_style, 'preview_width' => $preview_width, 'preview_height' => $preview_height, - 'thumbnail' => null + 'thumbnail' => null ]; /** @@ -40,39 +40,39 @@ class Thumbnail { * * \e string \b thumbnail */ - call_hooks('thumbnail',$p); - if($p['thumbnail']) { + call_hooks('thumbnail', $p); + if ($p['thumbnail']) { return; } $default_controller = null; - + $files = glob('Zotlabs/Thumbs/*.php'); - if($files) { - foreach($files as $f) { - $clsname = '\\Zotlabs\\Thumbs\\' . ucfirst(basename($f,'.php')); - if(class_exists($clsname)) { + if ($files) { + foreach ($files as $f) { + $clsname = '\\Zotlabs\\Thumbs\\' . ucfirst(basename($f, '.php')); + if (class_exists($clsname)) { $x = new $clsname(); - if(method_exists($x,'Match')) { + if (method_exists($x, 'Match')) { $matched = $x->Match($attach['filetype']); - if($matched) { - $x->Thumb($attach,$preview_style,$preview_width,$preview_height); + if ($matched) { + $x->Thumb($attach, $preview_style, $preview_width, $preview_height); } } - if(method_exists($x,'MatchDefault')) { - $default_matched = $x->MatchDefault(substr($attach['filetype'],0,strpos($attach['filetype'],'/'))); - if($default_matched) { + if (method_exists($x, 'MatchDefault')) { + $default_matched = $x->MatchDefault(substr($attach['filetype'], 0, strpos($attach['filetype'], '/'))); + if ($default_matched) { $default_controller = $x; } } } } } - if(($default_controller) - && ((! file_exists(dbunescbin($attach['content']) . '.thumb')) + if (($default_controller) + && ((!file_exists(dbunescbin($attach['content']) . '.thumb')) || (filectime(dbunescbin($attach['content']) . 'thumb') < (time() - 60)))) { - $default_controller->Thumb($attach,$preview_style,$preview_width,$preview_height); + $default_controller->Thumb($attach, $preview_style, $preview_width, $preview_height); } } } -- cgit v1.2.3 From 6083bfea2f449a910da3622f5dac757a82379fc0 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 20:39:23 +0000 Subject: lib/activity cleanup and remove unused code - requires addon update --- Zotlabs/Lib/Activity.php | 1871 ++++++++++++++++++++++------------------------ 1 file changed, 908 insertions(+), 963 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 807216400..216dfab1a 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -3,6 +3,8 @@ namespace Zotlabs\Lib; use Zotlabs\Access\PermissionLimits; +use Zotlabs\Access\PermissionRoles; +use Zotlabs\Access\Permissions; use Zotlabs\Daemon\Master; use Zotlabs\Web\HTTPSig; @@ -13,71 +15,70 @@ class Activity { static function encode_object($x) { - - if(($x) && (! is_array($x)) && (substr(trim($x),0,1)) === '{' ) { - $x = json_decode($x,true); + if (($x) && (!is_array($x)) && (substr(trim($x), 0, 1)) === '{') { + $x = json_decode($x, true); } - if(is_array($x)) { + if (is_array($x)) { - if(array_key_exists('asld',$x)) { + if (array_key_exists('asld', $x)) { return $x['asld']; } - if($x['type'] === ACTIVITY_OBJ_PERSON) { - return self::fetch_person($x); + if ($x['type'] === ACTIVITY_OBJ_PERSON) { + return self::fetch_person($x); } - if($x['type'] === ACTIVITY_OBJ_PROFILE) { - return self::fetch_profile($x); + if ($x['type'] === ACTIVITY_OBJ_PROFILE) { + return self::fetch_profile($x); } - if(in_array($x['type'], [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_ARTICLE ] )) { - return self::fetch_item($x); + if (in_array($x['type'], [ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_ARTICLE])) { + return self::fetch_item($x); } - if($x['type'] === ACTIVITY_OBJ_THING) { - return self::fetch_thing($x); + if ($x['type'] === ACTIVITY_OBJ_THING) { + return self::fetch_thing($x); } - if($x['type'] === ACTIVITY_OBJ_EVENT) { - return self::fetch_event($x); + if ($x['type'] === ACTIVITY_OBJ_EVENT) { + return self::fetch_event($x); } - if($x['type'] === ACTIVITY_OBJ_PHOTO) { - return self::fetch_image($x); + if ($x['type'] === ACTIVITY_OBJ_PHOTO) { + return self::fetch_image($x); } - call_hooks('encode_object',$x); + call_hooks('encode_object', $x); } return $x; } - static function fetch($url,$channel = null) { + static function fetch($url, $channel = null) { $redirects = 0; - if(! check_siteallowed($url)) { + if (!check_siteallowed($url)) { logger('blacklisted: ' . $url); return null; } - if(! $channel) { + if (!$channel) { $channel = get_sys_channel(); } logger('fetch: ' . $url, LOGGER_DEBUG); - if(strpos($url,'x-zot:') === 0) { - $x = ZotURL::fetch($url,$channel); + if (strpos($url, 'x-zot:') === 0) { + $x = ZotURL::fetch($url, $channel); } else { $m = parse_url($url); // handle bearcaps if ($m['scheme'] === 'bear') { - $params = explode('&',$m['query']); + $params = explode('&', $m['query']); if ($params) { foreach ($params as $p) { - if (substr($p,0,2) === 'u=') { - $url = substr($p,2); + if (substr($p, 0, 2) === 'u=') { + $url = substr($p, 2); } - if (substr($p,0,2) === 't=') { - $token = substr($p,2); + if (substr($p, 0, 2) === 't=') { + $token = substr($p, 2); } } $m = parse_url($url); @@ -87,19 +88,19 @@ class Activity { $headers = [ 'Accept' => 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"', 'Host' => $m['host'], - 'Date' => datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'), + 'Date' => datetime_convert('UTC', 'UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'), '(request-target)' => 'get ' . get_request_string($url) ]; if (isset($token)) { $headers['Authorization'] = 'Bearer ' . $token; } - $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false); - $x = z_fetch_url($url, true, $redirects, [ 'headers' => $h ] ); + $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), false); + $x = z_fetch_url($url, true, $redirects, ['headers' => $h]); } - if($x['success']) { - $y = json_decode($x['body'],true); - logger('returned: ' . json_encode($y,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES), LOGGER_DEBUG); + if ($x['success']) { + $y = json_decode($x['body'], true); + logger('returned: ' . json_encode($y, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOGGER_DEBUG); return json_decode($x['body'], true); } else { @@ -110,8 +111,6 @@ class Activity { } - - static function fetch_person($x) { return self::fetch_profile($x); } @@ -120,13 +119,13 @@ class Activity { $r = q("select * from xchan where xchan_url like '%s' limit 1", dbesc($x['id'] . '/%') ); - if(! $r) { + if (!$r) { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($x['id']) ); - } - if(! $r) + } + if (!$r) return []; return self::encode_person($r[0]); @@ -140,7 +139,7 @@ class Activity { dbesc($x['id']) ); - if(! $r) + if (!$r) return []; $x = [ @@ -149,7 +148,7 @@ class Activity { 'name' => $r[0]['obj_term'] ]; - if($r[0]['obj_image']) + if ($r[0]['obj_image']) $x['image'] = $r[0]['obj_image']; return $x; @@ -158,7 +157,7 @@ class Activity { static function fetch_item($x) { - if (array_key_exists('source',$x)) { + if (array_key_exists('source', $x)) { // This item is already processed and encoded return $x; } @@ -166,8 +165,8 @@ class Activity { $r = q("select * from item where mid = '%s' limit 1", dbesc($x['id']) ); - if($r) { - xchan_query($r,true); + if ($r) { + xchan_query($r, true); $r = fetch_post_tags($r); if (in_array($r[0]['verb'], ['Create', 'Invite']) && $r[0]['obj_type'] === ACTIVITY_OBJ_EVENT) { $r[0]['verb'] = 'Invite'; @@ -180,19 +179,19 @@ class Activity { static function fetch_image($x) { $ret = [ - 'type' => 'Image', - 'id' => $x['id'], - 'name' => $x['title'], - 'content' => bbcode($x['body'], [ 'cache' => true ]), - 'source' => [ 'mediaType' => 'text/bbcode', 'content' => $x['body'] ], - 'published' => datetime_convert('UTC','UTC',$x['created'],ATOM_TIME), - 'updated' => datetime_convert('UTC','UTC', $x['edited'],ATOM_TIME), - 'url' => [ - 'type' => 'Link', - 'mediaType' => $x['link'][0]['type'], - 'href' => $x['link'][0]['href'], - 'width' => $x['link'][0]['width'], - 'height' => $x['link'][0]['height'] + 'type' => 'Image', + 'id' => $x['id'], + 'name' => $x['title'], + 'content' => bbcode($x['body'], ['cache' => true]), + 'source' => ['mediaType' => 'text/bbcode', 'content' => $x['body']], + 'published' => datetime_convert('UTC', 'UTC', $x['created'], ATOM_TIME), + 'updated' => datetime_convert('UTC', 'UTC', $x['edited'], ATOM_TIME), + 'url' => [ + 'type' => 'Link', + 'mediaType' => $x['link'][0]['type'], + 'href' => $x['link'][0]['href'], + 'width' => $x['link'][0]['width'], + 'height' => $x['link'][0]['height'] ] ]; return $ret; @@ -202,42 +201,42 @@ class Activity { // convert old Zot event objects to ActivityStreams Event objects - if (array_key_exists('content',$x) && array_key_exists('dtstart',$x)) { + if (array_key_exists('content', $x) && array_key_exists('dtstart', $x)) { $ev = bbtoevent($x['content']); - if($ev) { + if ($ev) { - if (! $ev['timezone']) { + if (!$ev['timezone']) { $ev['timezone'] = 'UTC'; } $actor = null; - if(array_key_exists('author',$x) && array_key_exists('link',$x['author'])) { + if (array_key_exists('author', $x) && array_key_exists('link', $x['author'])) { $actor = $x['author']['link'][0]['href']; } - $y = [ + $y = [ 'type' => 'Event', 'id' => z_root() . '/event/' . $ev['event_hash'], 'name' => $ev['summary'], -// 'summary' => bbcode($ev['summary'], [ 'cache' => true ]), + // 'summary' => bbcode($ev['summary'], [ 'cache' => true ]), // RFC3339 Section 4.3 - 'startTime' => (($ev['adjust']) ? datetime_convert($ev['timezone'],'UTC',$ev['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$ev['dtstart'],'Y-m-d\\TH:i:s-00:00')), - 'content' => bbcode($ev['description'], [ 'cache' => true ]), - 'location' => [ 'type' => 'Place', 'content' => bbcode($ev['location'], [ 'cache' => true ]) ], - 'source' => [ 'content' => format_event_bbcode($ev,true), 'mediaType' => 'text/bbcode' ], + 'startTime' => (($ev['adjust']) ? datetime_convert($ev['timezone'], 'UTC', $ev['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $ev['dtstart'], 'Y-m-d\\TH:i:s-00:00')), + 'content' => bbcode($ev['description'], ['cache' => true]), + 'location' => ['type' => 'Place', 'content' => bbcode($ev['location'], ['cache' => true])], + 'source' => ['content' => format_event_bbcode($ev, true), 'mediaType' => 'text/bbcode'], 'actor' => $actor, ]; - if(! $ev['nofinish']) { - $y['endTime'] = (($ev['adjust']) ? datetime_convert($ev['timezone'],'UTC',$ev['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$ev['dtend'],'Y-m-d\\TH:i:s-00:00')); + if (!$ev['nofinish']) { + $y['endTime'] = (($ev['adjust']) ? datetime_convert($ev['timezone'], 'UTC', $ev['dtend'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $ev['dtend'], 'Y-m-d\\TH:i:s-00:00')); } - + // copy attachments from the passed object - these are already formatted for ActivityStreams - if($x['attachment']) { + if ($x['attachment']) { $y['attachment'] = $x['attachment']; } - if($actor) { + if ($actor) { return $y; } } @@ -248,24 +247,24 @@ class Activity { } - static function encode_item_collection($items,$id,$type,$extra = null) { + static function encode_item_collection($items, $id, $type, $extra = null) { $ret = [ - 'id' => z_root() . '/' . $id, - 'type' => $type, + 'id' => z_root() . '/' . $id, + 'type' => $type, 'totalItems' => count($items), ]; - if($extra) - $ret = array_merge($ret,$extra); + if ($extra) + $ret = array_merge($ret, $extra); - if($items) { + if ($items) { $x = []; - foreach($items as $i) { + foreach ($items as $i) { $t = self::encode_activity($i); - if($t) + if ($t) $x[] = $t; } - if($type === 'OrderedCollection') + if ($type === 'OrderedCollection') $ret['orderedItems'] = $x; else $ret['items'] = $x; @@ -274,25 +273,25 @@ class Activity { return $ret; } - static function encode_follow_collection($items,$id,$type,$extra = null) { + static function encode_follow_collection($items, $id, $type, $extra = null) { $ret = [ - 'id' => z_root() . '/' . $id, - 'type' => $type, + 'id' => z_root() . '/' . $id, + 'type' => $type, 'totalItems' => count($items), ]; - if($extra) - $ret = array_merge($ret,$extra); + if ($extra) + $ret = array_merge($ret, $extra); - if($items) { + if ($items) { $x = []; - foreach($items as $i) { - if($i['xchan_url']) { + foreach ($items as $i) { + if ($i['xchan_url']) { $x[] = $i['xchan_url']; } } - if($type === 'OrderedCollection') + if ($type === 'OrderedCollection') $ret['orderedItems'] = $x; else $ret['items'] = $x; @@ -302,17 +301,15 @@ class Activity { } - - static function encode_item($i) { $ret = []; - if($i['verb'] === ACTIVITY_FRIEND) { + if ($i['verb'] === ACTIVITY_FRIEND) { // Hubzilla 'make-friend' activity, no direct mapping from AS1 to AS2 - make it a note $objtype = 'Note'; } - else { + else { $objtype = self::activity_obj_mapper($i['obj_type']); } @@ -321,13 +318,13 @@ class Activity { } if (intval($i['item_deleted'])) { - $ret['type'] = 'Tombstone'; + $ret['type'] = 'Tombstone'; $ret['formerType'] = $objtype; - $ret['id'] = $i['mid']; - if($i['id'] != $i['parent']) + $ret['id'] = $i['mid']; + if ($i['id'] != $i['parent']) $ret['inReplyTo'] = $i['thr_parent']; - $ret['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + $ret['to'] = [ACTIVITY_PUBLIC_INBOX]; return $ret; } @@ -336,7 +333,7 @@ class Activity { $ret = $i['obj']; } else { - $ret = json_decode($i['obj'],true); + $ret = json_decode($i['obj'], true); } } @@ -348,96 +345,95 @@ class Activity { $ret = $i['obj']; } else { - $ret = json_decode($i['obj'],true); + $ret = json_decode($i['obj'], true); } - - if(array_path_exists('actor/id',$ret)) { + + if (array_path_exists('actor/id', $ret)) { $ret['actor'] = $ret['actor']['id']; } } } - - $ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/item/' . urlencode($i['mid'])); + $ret['id'] = ((strpos($i['mid'], 'http') === 0) ? $i['mid'] : z_root() . '/item/' . urlencode($i['mid'])); $ret['diaspora:guid'] = $i['uuid']; - if($i['title']) + if ($i['title']) $ret['name'] = $i['title']; - $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); - if($i['created'] !== $i['edited']) - $ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME); + $ret['published'] = datetime_convert('UTC', 'UTC', $i['created'], ATOM_TIME); + if ($i['created'] !== $i['edited']) + $ret['updated'] = datetime_convert('UTC', 'UTC', $i['edited'], ATOM_TIME); if ($i['expires'] <= NULL_DATE) { - $ret['expires'] = datetime_convert('UTC','UTC',$i['expires'],ATOM_TIME); + $ret['expires'] = datetime_convert('UTC', 'UTC', $i['expires'], ATOM_TIME); } - if($i['app']) { - $ret['generator'] = [ 'type' => 'Application', 'name' => $i['app'] ]; + if ($i['app']) { + $ret['generator'] = ['type' => 'Application', 'name' => $i['app']]; } - if($i['location'] || $i['coord']) { - $ret['location'] = [ 'type' => 'Place' ]; - if($i['location']) { + if ($i['location'] || $i['coord']) { + $ret['location'] = ['type' => 'Place']; + if ($i['location']) { $ret['location']['name'] = $i['location']; } - if($i['coord']) { - $l = explode(' ',$i['coord']); - $ret['location']['latitude'] = $l[0]; + if ($i['coord']) { + $l = explode(' ', $i['coord']); + $ret['location']['latitude'] = $l[0]; $ret['location']['longitude'] = $l[1]; } } if (intval($i['item_wall']) && $i['mid'] === $i['parent_mid']) { - $ret['commentPolicy'] = map_scope(PermissionLimits::Get($i['uid'],'post_comments')); + $ret['commentPolicy'] = map_scope(PermissionLimits::Get($i['uid'], 'post_comments')); } if (intval($i['item_private']) === 2) { $ret['directMessage'] = true; } - if (array_key_exists('comments_closed',$i) && $i['comments_closed'] !== EMPTY_STR && $i['comments_closed'] !== NULL_DATE) { - if($ret['commentPolicy']) { + if (array_key_exists('comments_closed', $i) && $i['comments_closed'] !== EMPTY_STR && $i['comments_closed'] !== NULL_DATE) { + if ($ret['commentPolicy']) { $ret['commentPolicy'] .= ' '; } - $ret['commentPolicy'] .= 'until=' . datetime_convert('UTC','UTC',$i['comments_closed'],ATOM_TIME); + $ret['commentPolicy'] .= 'until=' . datetime_convert('UTC', 'UTC', $i['comments_closed'], ATOM_TIME); } $ret['attributedTo'] = $i['author']['xchan_url']; - if($i['id'] != $i['parent']) { - $ret['inReplyTo'] = ((strpos($i['thr_parent'],'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); + if ($i['id'] != $i['parent']) { + $ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); } - if($i['mimetype'] === 'text/bbcode') { - if($i['title']) - $ret['name'] = bbcode($i['title'], [ 'cache' => true ]); - if($i['summary']) - $ret['summary'] = bbcode($i['summary'], [ 'cache' => true ]); - $ret['content'] = bbcode($i['body'], [ 'cache' => true ]); - $ret['source'] = [ 'content' => $i['body'], 'mediaType' => 'text/bbcode' ]; + if ($i['mimetype'] === 'text/bbcode') { + if ($i['title']) + $ret['name'] = bbcode($i['title'], ['cache' => true]); + if ($i['summary']) + $ret['summary'] = bbcode($i['summary'], ['cache' => true]); + $ret['content'] = bbcode($i['body'], ['cache' => true]); + $ret['source'] = ['content' => $i['body'], 'mediaType' => 'text/bbcode']; } - $actor = self::encode_person($i['author'],false); - if($actor) + $actor = self::encode_person($i['author'], false); + if ($actor) $ret['actor'] = $actor; else return []; $t = self::encode_taxonomy($i); - if($t) { - $ret['tag'] = $t; + if ($t) { + $ret['tag'] = $t; } $a = self::encode_attachment($i); - if($a) { + if ($a) { $ret['attachment'] = $a; } - $public = (($i['item_private']) ? false : true); + $public = (($i['item_private']) ? false : true); $top_level = (($i['mid'] === $i['parent_mid']) ? true : false); if ($public) { - $ret['to'] = [ ACTIVITY_PUBLIC_INBOX ]; - $ret['cc'] = [ z_root() . '/followers/' . substr($i['author']['xchan_addr'],0,strpos($i['author']['xchan_addr'],'@')) ]; + $ret['to'] = [ACTIVITY_PUBLIC_INBOX]; + $ret['cc'] = [z_root() . '/followers/' . substr($i['author']['xchan_addr'], 0, strpos($i['author']['xchan_addr'], '@'))]; } else { @@ -450,7 +446,7 @@ class Activity { $ret['to'] = []; if ($ret['tag']) { foreach ($ret['tag'] as $mention) { - if (is_array($mention) && array_key_exists('href',$mention) && $mention['href']) { + if (is_array($mention) && array_key_exists('href', $mention) && $mention['href']) { $h = q("select * from hubloc where hubloc_id_url = '%s' limit 1", dbesc($mention['href']) ); @@ -461,7 +457,7 @@ class Activity { else { $addr = $h[0]['hubloc_id_url']; } - if (! in_array($addr,$ret['to'])) { + if (!in_array($addr, $ret['to'])) { $ret['to'][] = $addr; } } @@ -478,7 +474,7 @@ class Activity { else { $addr = $d[0]['hubloc_id_url']; } - if (! in_array($addr,$ret['to'])) { + if (!in_array($addr, $ret['to'])) { $ret['cc'][] = $addr; } } @@ -487,7 +483,7 @@ class Activity { $mentions = self::map_mentions($i); if (count($mentions) > 0) { - if (! $ret['to']) { + if (!$ret['to']) { $ret['to'] = $mentions; } else { @@ -505,25 +501,25 @@ class Activity { if ($item['tag'] && is_array($item['tag'])) { $ptr = $item['tag']; - if (! array_key_exists(0,$ptr)) { - $ptr = [ $ptr ]; + if (!array_key_exists(0, $ptr)) { + $ptr = [$ptr]; } foreach ($ptr as $t) { - if (! array_key_exists('type',$t)) + if (!array_key_exists('type', $t)) $t['type'] = 'Hashtag'; - switch($t['type']) { + switch ($t['type']) { case 'Hashtag': - $ret[] = [ 'ttype' => TERM_HASHTAG, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'],0,1) === '#') ? substr($t['name'],1) : $t['name']) ]; + $ret[] = ['ttype' => TERM_HASHTAG, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '#') ? substr($t['name'], 1) : $t['name'])]; break; case 'Mention': - $mention_type = substr($t['name'],0,1); + $mention_type = substr($t['name'], 0, 1); if ($mention_type === '!') { - $ret[] = [ 'ttype' => TERM_FORUM, 'url' => $t['href'], 'term' => escape_tags(substr($t['name'],1)) ]; + $ret[] = ['ttype' => TERM_FORUM, 'url' => $t['href'], 'term' => escape_tags(substr($t['name'], 1))]; } else { - $ret[] = [ 'ttype' => TERM_MENTION, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'],0,1) === '@') ? substr($t['name'],1) : $t['name']) ]; + $ret[] = ['ttype' => TERM_MENTION, 'url' => $t['href'], 'term' => escape_tags((substr($t['name'], 0, 1) === '@') ? substr($t['name'], 1) : $t['name'])]; } break; @@ -537,29 +533,28 @@ class Activity { } - static function encode_taxonomy($item) { $ret = []; - if($item['term']) { - foreach($item['term'] as $t) { - switch($t['ttype']) { + if ($item['term']) { + foreach ($item['term'] as $t) { + switch ($t['ttype']) { case TERM_HASHTAG: // href is required so if we don't have a url in the taxonomy, ignore it and keep going. - if($t['url']) { - $ret[] = [ 'type' => 'Hashtag', 'href' => $t['url'], 'name' => '#' . $t['term'] ]; + if ($t['url']) { + $ret[] = ['type' => 'Hashtag', 'href' => $t['url'], 'name' => '#' . $t['term']]; } break; case TERM_FORUM: - $ret[] = [ 'type' => 'Mention', 'href' => $t['url'], 'name' => '!' . $t['term'] ]; + $ret[] = ['type' => 'Mention', 'href' => $t['url'], 'name' => '!' . $t['term']]; break; case TERM_MENTION: - $ret[] = [ 'type' => 'Mention', 'href' => $t['url'], 'name' => '@' . $t['term'] ]; + $ret[] = ['type' => 'Mention', 'href' => $t['url'], 'name' => '@' . $t['term']]; break; - + default: break; } @@ -573,15 +568,15 @@ class Activity { $ret = []; - if($item['attach']) { - $atts = ((is_array($item['attach'])) ? $item['attach'] : json_decode($item['attach'],true)); - if($atts) { - foreach($atts as $att) { - if(strpos($att['type'],'image')) { - $ret[] = [ 'type' => 'Image', 'url' => $att['href'] ]; + if ($item['attach']) { + $atts = ((is_array($item['attach'])) ? $item['attach'] : json_decode($item['attach'], true)); + if ($atts) { + foreach ($atts as $att) { + if (strpos($att['type'], 'image')) { + $ret[] = ['type' => 'Image', 'url' => $att['href']]; } else { - $ret[] = [ 'type' => 'Link', 'mediaType' => $att['type'], 'href' => $att['href'] ]; + $ret[] = ['type' => 'Link', 'mediaType' => $att['type'], 'href' => $att['href']]; } } } @@ -590,11 +585,11 @@ class Activity { foreach ($item['iconfig'] as $att) { if ($att['sharing']) { $value = ((is_string($att['v']) && preg_match('|^a:[0-9]+:{.*}$|s', $att['v'])) ? unserialize($att['v']) : $att['v']); - $ret[] = [ 'type' => 'PropertyValue', 'name' => 'zot.' . $att['cat'] . '.' . $att['k'], 'value' => $value ]; + $ret[] = ['type' => 'PropertyValue', 'name' => 'zot.' . $att['cat'] . '.' . $att['k'], 'value' => $value]; } } } - + return $ret; } @@ -604,20 +599,20 @@ class Activity { if (is_array($item['attachment']) && $item['attachment']) { $ptr = $item['attachment']; - if (! array_key_exists(0,$ptr)) { - $ptr = [ $ptr ]; + if (!array_key_exists(0, $ptr)) { + $ptr = [$ptr]; } foreach ($ptr as $att) { $entry = []; if ($att['type'] === 'PropertyValue') { - if (array_key_exists('name',$att) && $att['name']) { - $key = explode('.',$att['name']); + if (array_key_exists('name', $att) && $att['name']) { + $key = explode('.', $att['name']); if (count($key) === 3 && $key[0] === 'zot') { - $entry['cat'] = $key[1]; - $entry['k'] = $key[2]; - $entry['v'] = $att['value']; + $entry['cat'] = $key[1]; + $entry['k'] = $key[2]; + $entry['v'] = $att['value']; $entry['sharing'] = '1'; - $ret[] = $entry; + $ret[] = $entry; } } } @@ -627,23 +622,22 @@ class Activity { } - static function decode_attachment($item) { $ret = []; - if($item['attachment']) { - foreach($item['attachment'] as $att) { + if ($item['attachment']) { + foreach ($item['attachment'] as $att) { $entry = []; - if($att['href']) + if ($att['href']) $entry['href'] = $att['href']; - elseif($att['url']) + elseif ($att['url']) $entry['href'] = $att['url']; - if($att['mediaType']) + if ($att['mediaType']) $entry['type'] = $att['mediaType']; - elseif($att['type'] === 'Image') + elseif ($att['type'] === 'Image') $entry['type'] = 'image/jpeg'; - if($entry) + if ($entry) $ret[] = $entry; } } @@ -652,210 +646,187 @@ class Activity { } - static function encode_activity($i, $recurse = false) { $ret = []; $reply = false; - if($i['verb'] === ACTIVITY_FRIEND) { + if ($i['verb'] === ACTIVITY_FRIEND) { // Hubzilla 'make-friend' activity, no direct mapping from AS1 to AS2 - make it a note $ret['obj'] = []; } $ret['type'] = self::activity_mapper($i['verb']); - $fragment = ''; if (intval($i['item_deleted']) && !$recurse) { $is_response = false; if (ActivityStreams::is_response_activity($ret['type'])) { $ret['type'] = 'Undo'; - $fragment = 'undo'; + $fragment = 'undo'; $is_response = true; } else { $ret['type'] = 'Delete'; - $fragment = 'delete'; + $fragment = 'delete'; } - $ret['id'] = str_replace('/item/','/activity/',$i['mid']) . '#' . $fragment; - $actor = self::encode_person($i['author'],false); + $ret['id'] = str_replace('/item/', '/activity/', $i['mid']) . '#' . $fragment; + $actor = self::encode_person($i['author'], false); if ($actor) $ret['actor'] = $actor; else - return []; + return []; - $obj = (($is_response) ? self::encode_activity($i,true) : self::encode_item($i,true)); + $obj = (($is_response) ? self::encode_activity($i, true) : self::encode_item($i)); if ($obj) { - if (array_path_exists('object/id',$obj)) { + if (array_path_exists('object/id', $obj)) { $obj['object'] = $obj['object']['id']; } unset($obj['cc']); - $obj['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + $obj['to'] = [ACTIVITY_PUBLIC_INBOX]; $ret['object'] = $obj; } else return []; - $ret['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + $ret['to'] = [ACTIVITY_PUBLIC_INBOX]; return $ret; } - if($ret['type'] === 'emojiReaction') { + if ($ret['type'] === 'emojiReaction') { // There may not be an object for these items for legacy reasons - it should be the conversation parent. $p = q("select * from item where mid = '%s' and uid = %d", dbesc($i['parent_mid']), intval($i['uid']) ); - if($p) { - xchan_query($p,true); - $p = fetch_post_tags($p); + if ($p) { + xchan_query($p, true); + $p = fetch_post_tags($p); $i['obj'] = self::encode_item($p[0]); // convert to zot6 emoji reaction encoding which uses the target object to indicate the // specific emoji instead of overloading the verb or type. - - $im = explode('#',$i['verb']); - if($im && count($im) > 1) + + $im = explode('#', $i['verb']); + if ($im && count($im) > 1) $emoji = $im[1]; - if(preg_match("/\[img(.*?)\](.*?)\[\/img\]/ism", $i['body'], $match)) { + if (preg_match("/\[img(.*?)\](.*?)\[\/img\]/ism", $i['body'], $match)) { $ln = $match[2]; } $i['tgt_type'] = 'Image'; - + $i['target'] = [ 'type' => 'Image', 'name' => $emoji, 'url' => (($ln) ? $ln : z_root() . '/images/emoji/' . $emoji . '.png') ]; - + } } - if (strpos($i['mid'],z_root() . '/item/') !== false) { - $ret['id'] = str_replace('/item/','/activity/',$i['mid']); + if (strpos($i['mid'], z_root() . '/item/') !== false) { + $ret['id'] = str_replace('/item/', '/activity/', $i['mid']); } - elseif (strpos($i['mid'],z_root() . '/event/') !== false) { - $ret['id'] = str_replace('/event/','/activity/',$i['mid']); + elseif (strpos($i['mid'], z_root() . '/event/') !== false) { + $ret['id'] = str_replace('/event/', '/activity/', $i['mid']); } else { - $ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/activity/' . urlencode($i['mid'])); + $ret['id'] = ((strpos($i['mid'], 'http') === 0) ? $i['mid'] : z_root() . '/activity/' . urlencode($i['mid'])); } $ret['diaspora:guid'] = $i['uuid']; - if($i['title']) - $ret['name'] = html2plain(bbcode($i['title'], [ 'cache' => true ])); + if ($i['title']) + $ret['name'] = html2plain(bbcode($i['title'], ['cache' => true])); - if($i['summary']) - $ret['summary'] = bbcode($i['summary'], [ 'cache' => true ]); + if ($i['summary']) + $ret['summary'] = bbcode($i['summary'], ['cache' => true]); - if($ret['type'] === 'Announce') { - $tmp = preg_replace('/\[share(.*?)\[\/share\]/ism',EMPTY_STR, $i['body']); - $ret['content'] = bbcode($tmp, [ 'cache' => true ]); - $ret['source'] = [ - 'content' => $i['body'], + if ($ret['type'] === 'Announce') { + $tmp = preg_replace('/\[share(.*?)\[\/share\]/ism', EMPTY_STR, $i['body']); + $ret['content'] = bbcode($tmp, ['cache' => true]); + $ret['source'] = [ + 'content' => $i['body'], 'mediaType' => 'text/bbcode' ]; } - $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); - if($i['created'] !== $i['edited']) - $ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME); - if($i['app']) { - $ret['generator'] = [ 'type' => 'Application', 'name' => $i['app'] ]; + $ret['published'] = datetime_convert('UTC', 'UTC', $i['created'], ATOM_TIME); + if ($i['created'] !== $i['edited']) + $ret['updated'] = datetime_convert('UTC', 'UTC', $i['edited'], ATOM_TIME); + if ($i['app']) { + $ret['generator'] = ['type' => 'Application', 'name' => $i['app']]; } - if($i['location'] || $i['coord']) { - $ret['location'] = [ 'type' => 'Place' ]; - if($i['location']) { + if ($i['location'] || $i['coord']) { + $ret['location'] = ['type' => 'Place']; + if ($i['location']) { $ret['location']['name'] = $i['location']; } - if($i['coord']) { - $l = explode(' ',$i['coord']); - $ret['location']['latitude'] = $l[0]; + if ($i['coord']) { + $l = explode(' ', $i['coord']); + $ret['location']['latitude'] = $l[0]; $ret['location']['longitude'] = $l[1]; } } - if($i['id'] != $i['parent']) { + if ($i['id'] != $i['parent']) { $reply = true; // inReplyTo needs to be set in the activity for followup actions (Like, Dislike, Announce, etc.), // but *not* for comments and RSVPs, where it should only be present in the object - - if (! in_array($ret['type'],[ 'Create','Update','Accept','Reject','TentativeAccept','TentativeReject' ])) { - $ret['inReplyTo'] = ((strpos($i['thr_parent'],'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); - } - if($i['item_private']) { - $d = q("select xchan_url, xchan_addr, xchan_name from item left join xchan on xchan_hash = author_xchan where id = %d limit 1", - intval($i['parent']) - ); - if($d) { - $is_directmessage = false; - $recips = get_iconfig($i['parent'], 'activitypub', 'recips'); - - if(array_path_exists('to', $recips) && in_array($i['author']['xchan_url'], $recips['to'])) { - $reply_url = $d[0]['xchan_url']; - $is_directmessage = true; - } - else { - $reply_url = z_root() . '/followers/' . substr($i['author']['xchan_addr'],0,strpos($i['author']['xchan_addr'],'@')); - } - - $reply_addr = (($d[0]['xchan_addr']) ? $d[0]['xchan_addr'] : $d[0]['xchan_name']); - } + if (!in_array($ret['type'], ['Create', 'Update', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject'])) { + $ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); } - } - $actor = self::encode_person($i['author'],false); - if($actor) + $actor = self::encode_person($i['author'], false); + if ($actor) $ret['actor'] = $actor; else - return []; + return []; - if(strpos($i['body'],'[/share]') !== false) { + if (strpos($i['body'], '[/share]') !== false) { $i['obj'] = null; } - if($i['obj']) { - if(! is_array($i['obj'])) { - $i['obj'] = json_decode($i['obj'],true); + if ($i['obj']) { + if (!is_array($i['obj'])) { + $i['obj'] = json_decode($i['obj'], true); } - if($i['obj']['type'] === ACTIVITY_OBJ_PHOTO) { + if ($i['obj']['type'] === ACTIVITY_OBJ_PHOTO) { $i['obj']['id'] = $i['mid']; } $obj = self::encode_object($i['obj']); - if($obj) + if ($obj) $ret['object'] = $obj; else return []; } else { $obj = self::encode_item($i); - if($obj) + if ($obj) $ret['object'] = $obj; else return []; } - if(array_path_exists('object/type',$ret) && $ret['object']['type'] === 'Event' && $ret['type'] === 'Create') { + if (array_path_exists('object/type', $ret) && $ret['object']['type'] === 'Event' && $ret['type'] === 'Create') { $ret['type'] = 'Invite'; } - if($i['target']) { - if(! is_array($i['target'])) { - $i['target'] = json_decode($i['target'],true); + if ($i['target']) { + if (!is_array($i['target'])) { + $i['target'] = json_decode($i['target'], true); } $tgt = self::encode_object($i['target']); - if($tgt) + if ($tgt) $ret['target'] = $tgt; else return []; @@ -868,12 +839,12 @@ class Activity { // addressing madness - $public = (($i['item_private']) ? false : true); + $public = (($i['item_private']) ? false : true); $top_level = (($reply) ? false : true); if ($public) { - $ret['to'] = [ ACTIVITY_PUBLIC_INBOX ]; - $ret['cc'] = [ z_root() . '/followers/' . substr($i['author']['xchan_addr'],0,strpos($i['author']['xchan_addr'],'@')) ]; + $ret['to'] = [ACTIVITY_PUBLIC_INBOX]; + $ret['cc'] = [z_root() . '/followers/' . substr($i['author']['xchan_addr'], 0, strpos($i['author']['xchan_addr'], '@'))]; } else { @@ -886,7 +857,7 @@ class Activity { $ret['to'] = []; if ($ret['tag']) { foreach ($ret['tag'] as $mention) { - if (is_array($mention) && array_key_exists('href',$mention) && $mention['href']) { + if (is_array($mention) && array_key_exists('href', $mention) && $mention['href']) { $h = q("select * from hubloc where hubloc_id_url = '%s' limit 1", dbesc($mention['href']) ); @@ -897,7 +868,7 @@ class Activity { else { $addr = $h[0]['hubloc_id_url']; } - if (! in_array($addr,$ret['to'])) { + if (!in_array($addr, $ret['to'])) { $ret['to'][] = $addr; } } @@ -915,7 +886,7 @@ class Activity { else { $addr = $d[0]['hubloc_id_url']; } - if (! in_array($addr,$ret['to'])) { + if (!in_array($addr, $ret['to'])) { $ret['cc'][] = $addr; } } @@ -924,7 +895,7 @@ class Activity { $mentions = self::map_mentions($i); if (count($mentions) > 0) { - if (! $ret['to']) { + if (!$ret['to']) { $ret['to'] = $mentions; } else { @@ -939,18 +910,18 @@ class Activity { static function map_mentions($i) { - if (! $i['term']) { + if (!$i['term']) { return []; } $list = []; foreach ($i['term'] as $t) { - if (! $t['url']) { + if (!$t['url']) { continue; } if ($t['ttype'] == TERM_MENTION) { - $url = self::lookup_term_url($t['url']); + $url = self::lookup_term_url($t['url']); $list[] = (($url) ? $url : $t['url']); } } @@ -963,7 +934,7 @@ class Activity { static function map_acl($i) { $ret = []; - if (! $i['item_private']) { + if (!$i['item_private']) { return $ret; } @@ -977,8 +948,8 @@ class Activity { } if ($i['allow_cid']) { - $tmp = expand_acl($i['allow_cid']); - $list = stringify_array($tmp,true); + $tmp = expand_acl($i['allow_cid']); + $list = stringify_array($tmp, true); if ($list) { $details = q("select hubloc_id_url from hubloc where hubloc_hash in (" . $list . ") and hubloc_id_url != ''"); if ($details) { @@ -1013,22 +984,22 @@ class Activity { static function encode_person($p, $extended = true) { - if(! $p['xchan_url']) + if (!$p['xchan_url']) return []; - if(! $extended) { + if (!$extended) { return $p['xchan_url']; } $ret = []; - $c = ((array_key_exists('channel_id',$p)) ? $p : channelx_by_hash($p['xchan_hash'])); + $c = ((array_key_exists('channel_id', $p)) ? $p : channelx_by_hash($p['xchan_hash'])); - $ret['type'] = 'Person'; + $ret['type'] = 'Person'; if ($c) { - $role = get_pconfig($c['channel_id'],'system','permissions_role'); - if (strpos($role,'forum') !== false) { + $role = get_pconfig($c['channel_id'], 'system', 'permissions_role'); + if (strpos($role, 'forum') !== false) { $ret['type'] = 'Group'; } } @@ -1037,23 +1008,23 @@ class Activity { $ret['id'] = channel_url($c); } else { - $ret['id'] = ((strpos($p['xchan_hash'],'http') === 0) ? $p['xchan_hash'] : $p['xchan_url']); + $ret['id'] = ((strpos($p['xchan_hash'], 'http') === 0) ? $p['xchan_hash'] : $p['xchan_url']); } - if($p['xchan_addr'] && strpos($p['xchan_addr'],'@')) - $ret['preferredUsername'] = substr($p['xchan_addr'],0,strpos($p['xchan_addr'],'@')); - $ret['name'] = $p['xchan_name']; - $ret['updated'] = datetime_convert('UTC','UTC',$p['xchan_name_date'],ATOM_TIME); - $ret['icon'] = [ + if ($p['xchan_addr'] && strpos($p['xchan_addr'], '@')) + $ret['preferredUsername'] = substr($p['xchan_addr'], 0, strpos($p['xchan_addr'], '@')); + $ret['name'] = $p['xchan_name']; + $ret['updated'] = datetime_convert('UTC', 'UTC', $p['xchan_name_date'], ATOM_TIME); + $ret['icon'] = [ 'type' => 'Image', - 'mediaType' => (($p['xchan_photo_mimetype']) ? $p['xchan_photo_mimetype'] : 'image/png' ), - 'updated' => datetime_convert('UTC','UTC',$p['xchan_photo_date'],ATOM_TIME), + 'mediaType' => (($p['xchan_photo_mimetype']) ? $p['xchan_photo_mimetype'] : 'image/png'), + 'updated' => datetime_convert('UTC', 'UTC', $p['xchan_photo_date'], ATOM_TIME), 'url' => $p['xchan_photo_l'], 'height' => 300, 'width' => 300, ]; - $ret['url'] = [ - [ + $ret['url'] = [ + [ 'type' => 'Link', 'mediaType' => 'text/html', 'href' => $p['xchan_url'] @@ -1071,7 +1042,7 @@ class Activity { 'publicKeyPem' => $p['xchan_pubkey'] ]; - $arr = [ 'xchan' => $p, 'encoded' => $ret ]; + $arr = ['xchan' => $p, 'encoded' => $ret]; call_hooks('encode_person', $arr); $ret = $arr['encoded']; @@ -1080,89 +1051,82 @@ class Activity { } - - - - - - static function activity_mapper($verb) { - if(strpos($verb,'/') === false) { + if (strpos($verb, '/') === false) { return $verb; } $acts = [ - 'http://activitystrea.ms/schema/1.0/post' => 'Create', - 'http://activitystrea.ms/schema/1.0/share' => 'Announce', - 'http://activitystrea.ms/schema/1.0/update' => 'Update', - 'http://activitystrea.ms/schema/1.0/like' => 'Like', - 'http://activitystrea.ms/schema/1.0/favorite' => 'Like', - 'http://purl.org/zot/activity/dislike' => 'Dislike', - 'http://activitystrea.ms/schema/1.0/tag' => 'Add', - 'http://activitystrea.ms/schema/1.0/follow' => 'Follow', - 'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow', - 'http://purl.org/zot/activity/attendyes' => 'Accept', - 'http://purl.org/zot/activity/attendno' => 'Reject', - 'http://purl.org/zot/activity/attendmaybe' => 'TentativeAccept', - 'Invite' => 'Invite', - 'Delete' => 'Delete', - 'Undo' => 'Undo' + 'http://activitystrea.ms/schema/1.0/post' => 'Create', + 'http://activitystrea.ms/schema/1.0/share' => 'Announce', + 'http://activitystrea.ms/schema/1.0/update' => 'Update', + 'http://activitystrea.ms/schema/1.0/like' => 'Like', + 'http://activitystrea.ms/schema/1.0/favorite' => 'Like', + 'http://purl.org/zot/activity/dislike' => 'Dislike', + 'http://activitystrea.ms/schema/1.0/tag' => 'Add', + 'http://activitystrea.ms/schema/1.0/follow' => 'Follow', + 'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow', + 'http://purl.org/zot/activity/attendyes' => 'Accept', + 'http://purl.org/zot/activity/attendno' => 'Reject', + 'http://purl.org/zot/activity/attendmaybe' => 'TentativeAccept', + 'Invite' => 'Invite', + 'Delete' => 'Delete', + 'Undo' => 'Undo' ]; - call_hooks('activity_mapper',$acts); + call_hooks('activity_mapper', $acts); - if(array_key_exists($verb,$acts) && $acts[$verb]) { + if (array_key_exists($verb, $acts) && $acts[$verb]) { return $acts[$verb]; } // Reactions will just map to normal activities - if(strpos($verb,ACTIVITY_REACT) !== false) + if (strpos($verb, ACTIVITY_REACT) !== false) return 'emojiReaction'; - if(strpos($verb,ACTIVITY_MOOD) !== false) + if (strpos($verb, ACTIVITY_MOOD) !== false) return 'Create'; - if(strpos($verb,ACTIVITY_FRIEND) !== false) + if (strpos($verb, ACTIVITY_FRIEND) !== false) return 'Create'; - if(strpos($verb,ACTIVITY_POKE) !== false) + if (strpos($verb, ACTIVITY_POKE) !== false) return 'Activity'; // We should return false, however this will trigger an uncaught execption and crash // the delivery system if encountered by the JSON-LDSignature library - + logger('Unmapped activity: ' . $verb); return 'Create'; - // return false; -} - + // return false; + } static function activity_decode_mapper($verb) { $acts = [ - 'http://activitystrea.ms/schema/1.0/post' => 'Create', - 'http://activitystrea.ms/schema/1.0/share' => 'Announce', - 'http://activitystrea.ms/schema/1.0/update' => 'Update', - 'http://activitystrea.ms/schema/1.0/like' => 'Like', - 'http://activitystrea.ms/schema/1.0/favorite' => 'Like', - 'http://purl.org/zot/activity/dislike' => 'Dislike', - 'http://activitystrea.ms/schema/1.0/tag' => 'Add', - 'http://activitystrea.ms/schema/1.0/follow' => 'Follow', - 'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow', - 'http://purl.org/zot/activity/attendyes' => 'Accept', - 'http://purl.org/zot/activity/attendno' => 'Reject', - 'http://purl.org/zot/activity/attendmaybe' => 'TentativeAccept', - 'Invite' => 'Invite', - 'Delete' => 'Delete', - 'Undo' => 'Undo' + 'http://activitystrea.ms/schema/1.0/post' => 'Create', + 'http://activitystrea.ms/schema/1.0/share' => 'Announce', + 'http://activitystrea.ms/schema/1.0/update' => 'Update', + 'http://activitystrea.ms/schema/1.0/like' => 'Like', + 'http://activitystrea.ms/schema/1.0/favorite' => 'Like', + 'http://purl.org/zot/activity/dislike' => 'Dislike', + 'http://activitystrea.ms/schema/1.0/tag' => 'Add', + 'http://activitystrea.ms/schema/1.0/follow' => 'Follow', + 'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow', + 'http://purl.org/zot/activity/attendyes' => 'Accept', + 'http://purl.org/zot/activity/attendno' => 'Reject', + 'http://purl.org/zot/activity/attendmaybe' => 'TentativeAccept', + 'Invite' => 'Invite', + 'Delete' => 'Delete', + 'Undo' => 'Undo' ]; - call_hooks('activity_decode_mapper',$acts); + call_hooks('activity_decode_mapper', $acts); - foreach($acts as $k => $v) { - if($verb === $v) { + foreach ($acts as $k => $v) { + if ($verb === $v) { return $k; } } @@ -1175,33 +1139,33 @@ class Activity { static function activity_obj_decode_mapper($obj) { $objs = [ - 'http://activitystrea.ms/schema/1.0/note' => 'Note', - 'http://activitystrea.ms/schema/1.0/note' => 'Article', - 'http://activitystrea.ms/schema/1.0/comment' => 'Note', - 'http://activitystrea.ms/schema/1.0/person' => 'Person', - 'http://purl.org/zot/activity/profile' => 'Profile', - 'http://activitystrea.ms/schema/1.0/photo' => 'Image', - 'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon', - 'http://activitystrea.ms/schema/1.0/event' => 'Event', - 'http://purl.org/zot/activity/location' => 'Place', - 'http://purl.org/zot/activity/chessgame' => 'Game', - 'http://purl.org/zot/activity/tagterm' => 'zot:Tag', - 'http://purl.org/zot/activity/thing' => 'Object', - 'http://purl.org/zot/activity/file' => 'zot:File', - 'http://purl.org/zot/activity/mood' => 'zot:Mood', - 'Invite' => 'Invite', - 'Question' => 'Question', - 'Document' => 'Document', - 'Audio' => 'Audio', - 'Video' => 'Video', - 'Delete' => 'Delete', - 'Undo' => 'Undo' + 'http://activitystrea.ms/schema/1.0/note' => 'Note', + 'http://activitystrea.ms/schema/1.0/note' => 'Article', + 'http://activitystrea.ms/schema/1.0/comment' => 'Note', + 'http://activitystrea.ms/schema/1.0/person' => 'Person', + 'http://purl.org/zot/activity/profile' => 'Profile', + 'http://activitystrea.ms/schema/1.0/photo' => 'Image', + 'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon', + 'http://activitystrea.ms/schema/1.0/event' => 'Event', + 'http://purl.org/zot/activity/location' => 'Place', + 'http://purl.org/zot/activity/chessgame' => 'Game', + 'http://purl.org/zot/activity/tagterm' => 'zot:Tag', + 'http://purl.org/zot/activity/thing' => 'Object', + 'http://purl.org/zot/activity/file' => 'zot:File', + 'http://purl.org/zot/activity/mood' => 'zot:Mood', + 'Invite' => 'Invite', + 'Question' => 'Question', + 'Document' => 'Document', + 'Audio' => 'Audio', + 'Video' => 'Video', + 'Delete' => 'Delete', + 'Undo' => 'Undo' ]; - call_hooks('activity_obj_decode_mapper',$objs); + call_hooks('activity_obj_decode_mapper', $objs); - foreach($objs as $k => $v) { - if($obj === $v) { + foreach ($objs as $k => $v) { + if ($obj === $v) { return $k; } } @@ -1211,44 +1175,42 @@ class Activity { } - - static function activity_obj_mapper($obj) { $objs = [ - 'http://activitystrea.ms/schema/1.0/note' => 'Note', - 'http://activitystrea.ms/schema/1.0/comment' => 'Note', - 'http://activitystrea.ms/schema/1.0/person' => 'Person', - 'http://purl.org/zot/activity/profile' => 'Profile', - 'http://activitystrea.ms/schema/1.0/photo' => 'Image', - 'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon', - 'http://activitystrea.ms/schema/1.0/event' => 'Event', - 'http://purl.org/zot/activity/location' => 'Place', - 'http://purl.org/zot/activity/chessgame' => 'Game', - 'http://purl.org/zot/activity/tagterm' => 'zot:Tag', - 'http://purl.org/zot/activity/thing' => 'Object', - 'http://purl.org/zot/activity/file' => 'zot:File', - 'http://purl.org/zot/activity/mood' => 'zot:Mood', - 'Invite' => 'Invite', - 'Question' => 'Question', - 'Audio' => 'Audio', - 'Video' => 'Video', - 'Delete' => 'Delete', - 'Undo' => 'Undo' + 'http://activitystrea.ms/schema/1.0/note' => 'Note', + 'http://activitystrea.ms/schema/1.0/comment' => 'Note', + 'http://activitystrea.ms/schema/1.0/person' => 'Person', + 'http://purl.org/zot/activity/profile' => 'Profile', + 'http://activitystrea.ms/schema/1.0/photo' => 'Image', + 'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon', + 'http://activitystrea.ms/schema/1.0/event' => 'Event', + 'http://purl.org/zot/activity/location' => 'Place', + 'http://purl.org/zot/activity/chessgame' => 'Game', + 'http://purl.org/zot/activity/tagterm' => 'zot:Tag', + 'http://purl.org/zot/activity/thing' => 'Object', + 'http://purl.org/zot/activity/file' => 'zot:File', + 'http://purl.org/zot/activity/mood' => 'zot:Mood', + 'Invite' => 'Invite', + 'Question' => 'Question', + 'Audio' => 'Audio', + 'Video' => 'Video', + 'Delete' => 'Delete', + 'Undo' => 'Undo' ]; - call_hooks('activity_obj_mapper',$objs); + call_hooks('activity_obj_mapper', $objs); if ($obj === 'Answer') { return 'Note'; } - if (strpos($obj,'/') === false) { + if (strpos($obj, '/') === false) { return $obj; } - if(array_key_exists($obj,$objs)) { + if (array_key_exists($obj, $objs)) { return $objs[$obj]; } @@ -1260,9 +1222,9 @@ class Activity { } - static function follow($channel,$act) { + static function follow($channel, $act) { - $contact = null; + $contact = null; $their_follow_id = null; /* @@ -1274,18 +1236,15 @@ class Activity { $person_obj = $act->actor; - if($act->type === 'Follow') { - $their_follow_id = $act->id; + if ($act->type === 'Follow') { + $their_follow_id = $act->id; } - elseif($act->type === 'Accept') { - $my_follow_id = z_root() . '/follow/' . $contact['id']; - } - - if(is_array($person_obj)) { + + if (is_array($person_obj)) { // store their xchan and hubloc - self::actor_store($person_obj['id'],$person_obj); + self::actor_store($person_obj['id'], $person_obj); // Find any existing abook record @@ -1293,74 +1252,74 @@ class Activity { dbesc($person_obj['id']), intval($channel['channel_id']) ); - if($r) { + if ($r) { $contact = $r[0]; } } - $x = \Zotlabs\Access\PermissionRoles::role_perms('social'); - $p = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']); - $their_perms = \Zotlabs\Access\Permissions::serialise($p); + $x = PermissionRoles::role_perms('social'); + $p = Permissions::FilledPerms($x['perms_connect']); + $their_perms = Permissions::serialise($p); - if($contact && $contact['abook_id']) { + if ($contact && $contact['abook_id']) { // A relationship of some form already exists on this site. - switch($act->type) { + switch ($act->type) { case 'Follow': // A second Follow request, but we haven't approved the first one - if($contact['abook_pending']) { + if ($contact['abook_pending']) { return; } // We've already approved them or followed them first // Send an Accept back to them - set_abconfig($channel['channel_id'],$person_obj['id'],'pubcrawl','their_follow_id', $their_follow_id); - Master::Summon([ 'Notifier', 'permissions_accept', $contact['abook_id'] ]); + set_abconfig($channel['channel_id'], $person_obj['id'], 'pubcrawl', 'their_follow_id', $their_follow_id); + Master::Summon(['Notifier', 'permissions_accept', $contact['abook_id']]); return; case 'Accept': // They accepted our Follow request - set default permissions - - set_abconfig($channel['channel_id'],$contact['abook_xchan'],'system','their_perms',$their_perms); + + set_abconfig($channel['channel_id'], $contact['abook_xchan'], 'system', 'their_perms', $their_perms); $abook_instance = $contact['abook_instance']; - - if(strpos($abook_instance,z_root()) === false) { - if($abook_instance) + + if (strpos($abook_instance, z_root()) === false) { + if ($abook_instance) $abook_instance .= ','; $abook_instance .= z_root(); - $r = q("update abook set abook_instance = '%s', abook_not_here = 0 + q("update abook set abook_instance = '%s', abook_not_here = 0 where abook_id = %d and abook_channel = %d", dbesc($abook_instance), intval($contact['abook_id']), intval($channel['channel_id']) ); } - + return; default: return; - + } } // No previous relationship exists. - if($act->type === 'Accept') { + if ($act->type === 'Accept') { // This should not happen unless we deleted the connection before it was accepted. return; } // From here on out we assume a Follow activity to somebody we have no existing relationship with - set_abconfig($channel['channel_id'],$person_obj['id'],'pubcrawl','their_follow_id', $their_follow_id); + set_abconfig($channel['channel_id'], $person_obj['id'], 'pubcrawl', 'their_follow_id', $their_follow_id); // The xchan should have been created by actor_store() above @@ -1368,17 +1327,17 @@ class Activity { dbesc($person_obj['id']) ); - if(! $r) { + if (!$r) { logger('xchan not found for ' . $person_obj['id']); return; } $ret = $r[0]; - $p = \Zotlabs\Access\Permissions::connect_perms($channel['channel_id']); - $my_perms = \Zotlabs\Access\Permissions::serialise($p['perms']); + $p = Permissions::connect_perms($channel['channel_id']); + $my_perms = Permissions::serialise($p['perms']); $automatic = $p['automatic']; - $closeness = get_pconfig($channel['channel_id'],'system','new_abook_closeness',80); + $closeness = get_pconfig($channel['channel_id'], 'system', 'new_abook_closeness', 80); $r = abook_store_lowlevel( [ @@ -1394,64 +1353,64 @@ class Activity { 'abook_instance' => z_root() ] ); - - if($my_perms) - set_abconfig($channel['channel_id'],$ret['xchan_hash'],'system','my_perms',$my_perms); - if($their_perms) - set_abconfig($channel['channel_id'],$ret['xchan_hash'],'system','their_perms',$their_perms); + if ($my_perms) + set_abconfig($channel['channel_id'], $ret['xchan_hash'], 'system', 'my_perms', $my_perms); + if ($their_perms) + set_abconfig($channel['channel_id'], $ret['xchan_hash'], 'system', 'their_perms', $their_perms); - if($r) { + + if ($r) { logger("New ActivityPub follower for {$channel['channel_name']}"); $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", intval($channel['channel_id']), dbesc($ret['xchan_hash']) ); - if($new_connection) { - \Zotlabs\Lib\Enotify::submit( + if ($new_connection) { + Enotify::submit( [ - 'type' => NOTIFY_INTRO, - 'from_xchan' => $ret['xchan_hash'], - 'to_xchan' => $channel['channel_hash'], - 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'], + 'type' => NOTIFY_INTRO, + 'from_xchan' => $ret['xchan_hash'], + 'to_xchan' => $channel['channel_hash'], + 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'], ] ); - if($my_perms && $automatic) { + if ($my_perms && $automatic) { // send an Accept for this Follow activity - Master::Summon([ 'Notifier', 'permissions_accept', $new_connection[0]['abook_id'] ]); + Master::Summon(['Notifier', 'permissions_accept', $new_connection[0]['abook_id']]); // Send back a Follow notification to them - Master::Summon([ 'Notifier', 'permissions_create', $new_connection[0]['abook_id'] ]); + Master::Summon(['Notifier', 'permissions_create', $new_connection[0]['abook_id']]); } - $clone = array(); - foreach($new_connection[0] as $k => $v) { - if(strpos($k,'abook_') === 0) { + $clone = []; + foreach ($new_connection[0] as $k => $v) { + if (strpos($k, 'abook_') === 0) { $clone[$k] = $v; } } unset($clone['abook_id']); unset($clone['abook_account']); unset($clone['abook_channel']); - - $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); - if($abconfig) + $abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']); + + if ($abconfig) $clone['abconfig'] = $abconfig; - Libsync::build_sync_packet($channel['channel_id'], [ 'abook' => array($clone) ] ); + Libsync::build_sync_packet($channel['channel_id'], ['abook' => [$clone]]); } } /* If there is a default group for this channel and permissions are automatic, add this member to it */ - if($channel['channel_default_group'] && $automatic) { - $g = Group::rec_byhash($channel['channel_id'],$channel['channel_default_group']); - if($g) - Group::member_add($channel['channel_id'],'',$ret['xchan_hash'],$g['id']); + if ($channel['channel_default_group'] && $automatic) { + $g = Group::rec_byhash($channel['channel_id'], $channel['channel_default_group']); + if ($g) + Group::member_add($channel['channel_id'], '', $ret['xchan_hash'], $g['id']); } @@ -1460,7 +1419,7 @@ class Activity { } - static function unfollow($channel,$act) { + static function unfollow($channel, $act) { $contact = null; @@ -1470,15 +1429,15 @@ class Activity { $person_obj = $act->actor; - if(is_array($person_obj)) { + if (is_array($person_obj)) { $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($person_obj['id']), intval($channel['channel_id']) ); - if($r) { + if ($r) { // remove all permissions they provided - del_abconfig($channel['channel_id'],$r[0]['xchan_hash'],'system','their_perms',EMPTY_STR); + del_abconfig($channel['channel_id'], $r[0]['xchan_hash'], 'system', 'their_perms'); } } @@ -1486,30 +1445,28 @@ class Activity { } + static function actor_store($url, $person_obj) { - - static function actor_store($url,$person_obj) { - - if(! is_array($person_obj)) + if (!is_array($person_obj)) return; $inbox = $person_obj['inbox']; // invalid identity - if (! $inbox || strpos($inbox,z_root()) !== false) { + if (!$inbox || strpos($inbox, z_root()) !== false) { return; } $name = $person_obj['name']; - if(! $name) + if (!$name) $name = $person_obj['preferredUsername']; - if(! $name) + if (!$name) $name = t('Unknown'); - if($person_obj['icon']) { - if(is_array($person_obj['icon'])) { - if(array_key_exists('url',$person_obj['icon'])) + if ($person_obj['icon']) { + if (is_array($person_obj['icon'])) { + if (array_key_exists('url', $person_obj['icon'])) $icon = $person_obj['icon']['url']; else $icon = $person_obj['icon'][0]['url']; @@ -1518,12 +1475,12 @@ class Activity { $icon = $person_obj['icon']; } - $links = false; + $links = false; $profile = false; if (is_array($person_obj['url'])) { - if (! array_key_exists(0,$person_obj['url'])) { - $links = [ $person_obj['url'] ]; + if (!array_key_exists(0, $person_obj['url'])) { + $links = [$person_obj['url']]; } else { $links = $person_obj['url']; @@ -1532,11 +1489,11 @@ class Activity { if ($links) { foreach ($links as $link) { - if (array_key_exists('mediaType',$link) && $link['mediaType'] === 'text/html') { + if (array_key_exists('mediaType', $link) && $link['mediaType'] === 'text/html') { $profile = $link['href']; } } - if (! $profile) { + if (!$profile) { $profile = $links[0]['href']; } } @@ -1544,28 +1501,28 @@ class Activity { $profile = $person_obj['url']; } - if (! $profile) { + if (!$profile) { $profile = $url; } $collections = []; - if($inbox) { + if ($inbox) { $collections['inbox'] = $inbox; - if($person_obj['outbox']) + if ($person_obj['outbox']) $collections['outbox'] = $person_obj['outbox']; - if($person_obj['followers']) + if ($person_obj['followers']) $collections['followers'] = $person_obj['followers']; - if($person_obj['following']) + if ($person_obj['following']) $collections['following'] = $person_obj['following']; - if($person_obj['endpoints'] && $person_obj['endpoints']['sharedInbox']) + if ($person_obj['endpoints'] && $person_obj['endpoints']['sharedInbox']) $collections['sharedInbox'] = $person_obj['endpoints']['sharedInbox']; } - if(array_key_exists('publicKey',$person_obj) && array_key_exists('publicKeyPem',$person_obj['publicKey'])) { - if($person_obj['id'] === $person_obj['publicKey']['owner']) { + if (array_key_exists('publicKey', $person_obj) && array_key_exists('publicKeyPem', $person_obj['publicKey'])) { + if ($person_obj['id'] === $person_obj['publicKey']['owner']) { $pubkey = $person_obj['publicKey']['publicKeyPem']; - if(strstr($pubkey,'RSA ')) { + if (strstr($pubkey, 'RSA ')) { $pubkey = rsatopem($pubkey); } } @@ -1574,19 +1531,19 @@ class Activity { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($url) ); - if(! $r) { + if (!$r) { // create a new record - $r = xchan_store_lowlevel( + xchan_store_lowlevel( [ - 'xchan_hash' => $url, - 'xchan_guid' => $url, - 'xchan_pubkey' => $pubkey, - 'xchan_addr' => '', - 'xchan_url' => $profile, - 'xchan_name' => $name, - 'xchan_name_date' => datetime_convert(), - 'xchan_network' => 'activitypub' + 'xchan_hash' => $url, + 'xchan_guid' => $url, + 'xchan_pubkey' => $pubkey, + 'xchan_addr' => '', + 'xchan_url' => $profile, + 'xchan_name' => $name, + 'xchan_name_date' => datetime_convert(), + 'xchan_network' => 'activitypub' ] ); } @@ -1595,12 +1552,12 @@ class Activity { // Record exists. Cache existing records for one week at most // then refetch to catch updated profile photos, names, etc. - $d = datetime_convert('UTC','UTC','now - 1 week'); - if($r[0]['xchan_name_date'] > $d) + $d = datetime_convert('UTC', 'UTC', 'now - 1 week'); + if ($r[0]['xchan_name_date'] > $d) return; // update existing record - $r = q("update xchan set xchan_name = '%s', xchan_pubkey = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", + q("update xchan set xchan_name = '%s', xchan_pubkey = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", dbesc($name), dbesc($pubkey), dbesc('activitypub'), @@ -1609,23 +1566,22 @@ class Activity { ); } - if($collections) { - set_xconfig($url,'activitypub','collections',$collections); + if ($collections) { + set_xconfig($url, 'activitypub', 'collections', $collections); } $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($url) ); - $m = parse_url($url); - if($m) { + if ($m) { $hostname = $m['host']; - $baseurl = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : ''); + $baseurl = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : ''); } - if(! $r) { - $r = hubloc_store_lowlevel( + if (!$r) { + hubloc_store_lowlevel( [ 'hubloc_guid' => $url, 'hubloc_hash' => $url, @@ -1641,12 +1597,12 @@ class Activity { ); } - if(! $icon) + if (!$icon) $icon = z_root() . '/' . get_default_profile_photo(300); - $photos = import_xchan_photo($icon,$url); - $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", - dbescdate(datetime_convert('UTC','UTC',$photos[5])), + $photos = import_xchan_photo($icon, $url); + q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", + dbescdate(datetime_convert('UTC', 'UTC', $photos[5])), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), @@ -1657,28 +1613,28 @@ class Activity { } - static function create_action($channel,$observer_hash,$act) { + static function create_action($channel, $observer_hash, $act) { - if(in_array($act->obj['type'], [ 'Note', 'Article', 'Video' ])) { - self::create_note($channel,$observer_hash,$act); + if (in_array($act->obj['type'], ['Note', 'Article', 'Video'])) { + self::create_note($channel, $observer_hash, $act); } } - static function announce_action($channel,$observer_hash,$act) { + static function announce_action($channel, $observer_hash, $act) { - if(in_array($act->type, [ 'Announce' ])) { - self::announce_note($channel,$observer_hash,$act); + if (in_array($act->type, ['Announce'])) { + self::announce_note($channel, $observer_hash, $act); } } - static function like_action($channel,$observer_hash,$act) { + static function like_action($channel, $observer_hash, $act) { - if(in_array($act->obj['type'], [ 'Note', 'Article', 'Video' ])) { - self::like_note($channel,$observer_hash,$act); + if (in_array($act->obj['type'], ['Note', 'Article', 'Video'])) { + self::like_note($channel, $observer_hash, $act); } @@ -1686,24 +1642,24 @@ class Activity { // sort function width decreasing - static function vid_sort($a,$b) { - if($a['width'] === $b['width']) + static function vid_sort($a, $b) { + if ($a['width'] === $b['width']) return 0; return (($a['width'] > $b['width']) ? -1 : 1); } - static function create_note($channel,$observer_hash,$act) { + static function create_note($channel, $observer_hash, $act) { $s = []; // Mastodon only allows visibility in public timelines if the public inbox is listed in the 'to' field. // They are hidden in the public timeline if the public inbox is listed in the 'cc' field. // This is not part of the activitypub protocol - we might change this to show all public posts in pubstream at some point. - $pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false); + $pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false); $is_sys_channel = is_sys_channel($channel['channel_id']); - $parent = ((array_key_exists('inReplyTo',$act->obj)) ? urldecode($act->obj['inReplyTo']) : ''); - if($parent) { + $parent = ((array_key_exists('inReplyTo', $act->obj)) ? urldecode($act->obj['inReplyTo']) : ''); + if ($parent) { $r = q("select * from item where uid = %d and ( mid = '%s' or mid = '%s' ) limit 1", intval($channel['channel_id']), @@ -1711,39 +1667,39 @@ class Activity { dbesc(basename($parent)) ); - if(! $r) { + if (!$r) { logger('parent not found.'); return; } - if($r[0]['owner_xchan'] === $channel['channel_hash']) { - if(! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream)) { + if ($r[0]['owner_xchan'] === $channel['channel_hash']) { + if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !($is_sys_channel && $pubstream)) { logger('no comment permission.'); return; } } - $s['parent_mid'] = $r[0]['mid']; - $s['owner_xchan'] = $r[0]['owner_xchan']; + $s['parent_mid'] = $r[0]['mid']; + $s['owner_xchan'] = $r[0]['owner_xchan']; $s['author_xchan'] = $observer_hash; } else { - if(! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream)) { + if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !($is_sys_channel && $pubstream)) { logger('no permission'); return; } $s['owner_xchan'] = $s['author_xchan'] = $observer_hash; } - + $abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($observer_hash), intval($channel['channel_id']) ); - + $content = self::get_content($act->obj); - if(! $content) { + if (!$content) { logger('no content'); return; } @@ -1756,105 +1712,105 @@ class Activity { $s['author_xchan'] = self::find_best_identity($s['author_xchan']); $s['owner_xchan'] = self::find_best_identity($s['owner_xchan']); - if(!$s['author_xchan']) { + if (!$s['author_xchan']) { logger('No author: ' . print_r($act, true)); } - if(!$s['owner_xchan']) { + if (!$s['owner_xchan']) { logger('No owner: ' . print_r($act, true)); } - if(!$s['author_xchan'] || !$s['owner_xchan']) + if (!$s['author_xchan'] || !$s['owner_xchan']) return; - $s['mid'] = urldecode($act->obj['id']); - $s['uuid'] = $act->obj['diaspora:guid']; + $s['mid'] = urldecode($act->obj['id']); + $s['uuid'] = $act->obj['diaspora:guid']; $s['plink'] = urldecode($act->obj['id']); - if($act->data['published']) { - $s['created'] = datetime_convert('UTC','UTC',$act->data['published']); + if ($act->data['published']) { + $s['created'] = datetime_convert('UTC', 'UTC', $act->data['published']); } - elseif($act->obj['published']) { - $s['created'] = datetime_convert('UTC','UTC',$act->obj['published']); + elseif ($act->obj['published']) { + $s['created'] = datetime_convert('UTC', 'UTC', $act->obj['published']); } - if($act->data['updated']) { - $s['edited'] = datetime_convert('UTC','UTC',$act->data['updated']); + if ($act->data['updated']) { + $s['edited'] = datetime_convert('UTC', 'UTC', $act->data['updated']); } - elseif($act->obj['updated']) { - $s['edited'] = datetime_convert('UTC','UTC',$act->obj['updated']); + elseif ($act->obj['updated']) { + $s['edited'] = datetime_convert('UTC', 'UTC', $act->obj['updated']); } if ($act->data['expires']) { - $s['expires'] = datetime_convert('UTC','UTC',$act->data['expires']); + $s['expires'] = datetime_convert('UTC', 'UTC', $act->data['expires']); } elseif ($act->obj['expires']) { - $s['expires'] = datetime_convert('UTC','UTC',$act->obj['expires']); + $s['expires'] = datetime_convert('UTC', 'UTC', $act->obj['expires']); } - if(! $s['created']) + if (!$s['created']) $s['created'] = datetime_convert(); - if(! $s['edited']) + if (!$s['edited']) $s['edited'] = $s['created']; - if(! $s['parent_mid']) + if (!$s['parent_mid']) $s['parent_mid'] = $s['mid']; - - $s['title'] = self::bb_content($content,'name'); - $s['summary'] = self::bb_content($content,'summary'); - $s['body'] = self::bb_content($content,'content'); + + $s['title'] = self::bb_content($content, 'name'); + $s['summary'] = self::bb_content($content, 'summary'); + $s['body'] = self::bb_content($content, 'content'); $s['verb'] = ACTIVITY_POST; $s['obj_type'] = ACTIVITY_OBJ_NOTE; $generator = $act->get_property_obj('generator'); - if(! $generator) - $generator = $act->get_property_obj('generator',$act->obj); + if (!$generator) + $generator = $act->get_property_obj('generator', $act->obj); - if($generator && array_key_exists('type',$generator) - && in_array($generator['type'], [ 'Application','Service' ] ) && array_key_exists('name',$generator)) { + if ($generator && array_key_exists('type', $generator) + && in_array($generator['type'], ['Application', 'Service']) && array_key_exists('name', $generator)) { $s['app'] = escape_tags($generator['name']); } - if($channel['channel_system']) { - if(! \Zotlabs\Lib\MessageFilter::evaluate($s,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) { + if ($channel['channel_system']) { + if (!MessageFilter::evaluate($s, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) { logger('post is filtered'); return; } } - if($abook) { - if(! post_is_importable($s,$abook[0])) { + if ($abook) { + if (!post_is_importable($s, $abook[0])) { logger('post is filtered'); return; } } - if($act->obj['conversation']) { - set_iconfig($s,'ostatus','conversation',$act->obj['conversation'],1); + if ($act->obj['conversation']) { + set_iconfig($s, 'ostatus', 'conversation', $act->obj['conversation'], 1); } $a = self::decode_taxonomy($act->obj); - if($a) { + if ($a) { $s['term'] = $a; } $a = self::decode_attachment($act->obj); - if($a) { + if ($a) { $s['attach'] = $a; } - if($act->obj['type'] === 'Note' && $s['attach']) { - $s['body'] .= self::bb_attach($s['attach'],$s['body']); + if ($act->obj['type'] === 'Note' && $s['attach']) { + $s['body'] .= self::bb_attach($s['attach'], $s['body']); } // we will need a hook here to extract magnet links e.g. peertube // right now just link to the largest mp4 we find that will fit in our // standard content region - if($act->obj['type'] === 'Video') { + if ($act->obj['type'] === 'Video') { $vtypes = [ 'video/mp4', @@ -1863,20 +1819,20 @@ class Activity { ]; $mps = []; - if(array_key_exists('url',$act->obj) && is_array($act->obj['url'])) { - foreach($act->obj['url'] as $vurl) { - if(in_array($vurl['mimeType'], $vtypes)) { - if(! array_key_exists('width',$vurl)) { + if (array_key_exists('url', $act->obj) && is_array($act->obj['url'])) { + foreach ($act->obj['url'] as $vurl) { + if (in_array($vurl['mimeType'], $vtypes)) { + if (!array_key_exists('width', $vurl)) { $vurl['width'] = 0; } $mps[] = $vurl; } } } - if($mps) { - usort($mps,[ __CLASS__, 'vid_sort' ]); - foreach($mps as $m) { - if(intval($m['width']) < 500) { + if ($mps) { + usort($mps, [__CLASS__, 'vid_sort']); + foreach ($mps as $m) { + if (intval($m['width']) < 500) { $s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]'; break; } @@ -1884,17 +1840,17 @@ class Activity { } } - if($act->recips && (! in_array(ACTIVITY_PUBLIC_INBOX,$act->recips))) + if ($act->recips && (!in_array(ACTIVITY_PUBLIC_INBOX, $act->recips))) $s['item_private'] = 1; - if (array_key_exists('directMessage',$act->obj) && intval($act->obj['directMessage'])) { + if (array_key_exists('directMessage', $act->obj) && intval($act->obj['directMessage'])) { $s['item_private'] = 2; } - set_iconfig($s,'activitypub','recips',$act->raw_recips); - if($parent) { - set_iconfig($s,'activitypub','rawmsg',$act->raw,1); + set_iconfig($s, 'activitypub', 'recips', $act->raw_recips); + if ($parent) { + set_iconfig($s, 'activitypub', 'rawmsg', $act->raw, 1); } $x = null; @@ -1903,8 +1859,8 @@ class Activity { dbesc($s['mid']), intval($s['uid']) ); - if($r) { - if($s['edited'] > $r[0]['edited']) { + if ($r) { + if ($s['edited'] > $r[0]['edited']) { $x = item_store_update($s); } else { @@ -1915,20 +1871,20 @@ class Activity { $x = item_store($s); } - if(is_array($x) && $x['item_id']) { - if($parent) { - if($s['owner_xchan'] === $channel['channel_hash']) { + if (is_array($x) && $x['item_id']) { + if ($parent) { + if ($s['owner_xchan'] === $channel['channel_hash']) { // We are the owner of this conversation, so send all received comments back downstream - Master::Summon(array('Notifier','comment-import',$x['item_id'])); + Master::Summon(['Notifier', 'comment-import', $x['item_id']]); } $r = q("select * from item where id = %d limit 1", intval($x['item_id']) ); - if($r) { - send_status_notifications($x['item_id'],$r[0]); + if ($r) { + send_status_notifications($x['item_id'], $r[0]); } } - sync_an_item($channel['channel_id'],$x['item_id']); + sync_an_item($channel['channel_id'], $x['item_id']); } } @@ -1940,26 +1896,25 @@ class Activity { dbesc($id) ); - if($x) { - return sprintf('@[zrl=%s]%s[/zrl]',$x[0]['xchan_url'],$x[0]['xchan_name']); + if ($x) { + return sprintf('@[zrl=%s]%s[/zrl]', $x[0]['xchan_url'], $x[0]['xchan_name']); } return '@{' . $id . '}'; } - - static function update_poll($item,$post) { - $multi = false; - $mid = $post['mid']; + static function update_poll($item, $post) { + $multi = false; + $mid = $post['mid']; $content = $post['title']; - - if (! $item) { + + if (!$item) { return false; } - $o = json_decode($item['obj'],true); - if ($o && array_key_exists('anyOf',$o)) { + $o = json_decode($item['obj'], true); + if ($o && array_key_exists('anyOf', $o)) { $multi = true; } @@ -1969,7 +1924,7 @@ class Activity { ); // prevent any duplicate votes by same author for oneOf and duplicate votes with same author and same answer for anyOf - + if ($r) { if ($multi) { foreach ($r as $rv) { @@ -1986,55 +1941,55 @@ class Activity { } } } - + $answer_found = false; - $found = false; + $found = false; if ($multi) { - for ($c = 0; $c < count($o['anyOf']); $c ++) { + for ($c = 0; $c < count($o['anyOf']); $c++) { if ($o['anyOf'][$c]['name'] === $content) { $answer_found = true; if (is_array($o['anyOf'][$c]['replies'])) { - foreach($o['anyOf'][$c]['replies'] as $reply) { - if(is_array($reply) && array_key_exists('id',$reply) && $reply['id'] === $mid) { + foreach ($o['anyOf'][$c]['replies'] as $reply) { + if (is_array($reply) && array_key_exists('id', $reply) && $reply['id'] === $mid) { $found = true; } } } - if (! $found) { - $o['anyOf'][$c]['replies']['totalItems'] ++; - $o['anyOf'][$c]['replies']['items'][] = [ 'id' => $mid, 'type' => 'Note' ]; + if (!$found) { + $o['anyOf'][$c]['replies']['totalItems']++; + $o['anyOf'][$c]['replies']['items'][] = ['id' => $mid, 'type' => 'Note']; } } } } else { - for ($c = 0; $c < count($o['oneOf']); $c ++) { + for ($c = 0; $c < count($o['oneOf']); $c++) { if ($o['oneOf'][$c]['name'] === $content) { $answer_found = true; if (is_array($o['oneOf'][$c]['replies'])) { - foreach($o['oneOf'][$c]['replies'] as $reply) { - if(is_array($reply) && array_key_exists('id',$reply) && $reply['id'] === $mid) { + foreach ($o['oneOf'][$c]['replies'] as $reply) { + if (is_array($reply) && array_key_exists('id', $reply) && $reply['id'] === $mid) { $found = true; } } } - if (! $found) { - $o['oneOf'][$c]['replies']['totalItems'] ++; - $o['oneOf'][$c]['replies']['items'][] = [ 'id' => $mid, 'type' => 'Note' ]; + if (!$found) { + $o['oneOf'][$c]['replies']['totalItems']++; + $o['oneOf'][$c]['replies']['items'][] = ['id' => $mid, 'type' => 'Note']; } } } } - logger('updated_poll: ' . print_r($o,true),LOGGER_DATA); - if ($answer_found && ! $found) { - $x = q("update item set obj = '%s', edited = '%s' where id = %d", + logger('updated_poll: ' . print_r($o, true), LOGGER_DATA); + if ($answer_found && !$found) { + q("update item set obj = '%s', edited = '%s' where id = %d", dbesc(json_encode($o)), dbesc(datetime_convert()), intval($item['id']) ); - Master::Summon( [ 'Notifier', 'wall-new', $item['id'] ] ); + Master::Summon(['Notifier', 'wall-new', $item['id']]); return true; } @@ -2042,47 +1997,46 @@ class Activity { } - static function decode_note($act) { $response_activity = false; $s = []; - if(is_array($act->obj)) { + if (is_array($act->obj)) { $content = self::get_content($act->obj); } - + $s['owner_xchan'] = $act->actor['id']; $s['author_xchan'] = $act->actor['id']; // ensure we store the original actor - self::actor_store($act->actor['id'],$act->actor); + self::actor_store($act->actor['id'], $act->actor); $s['mid'] = $act->obj['id']; - $s['uuid'] = $act->obj['diaspora:guid']; + $s['uuid'] = $act->obj['diaspora:guid']; $s['parent_mid'] = $act->parent_id; - if($act->data['published']) { - $s['created'] = datetime_convert('UTC','UTC',$act->data['published']); + if ($act->data['published']) { + $s['created'] = datetime_convert('UTC', 'UTC', $act->data['published']); } - elseif($act->obj['published']) { - $s['created'] = datetime_convert('UTC','UTC',$act->obj['published']); + elseif ($act->obj['published']) { + $s['created'] = datetime_convert('UTC', 'UTC', $act->obj['published']); } - if($act->data['updated']) { - $s['edited'] = datetime_convert('UTC','UTC',$act->data['updated']); + if ($act->data['updated']) { + $s['edited'] = datetime_convert('UTC', 'UTC', $act->data['updated']); } - elseif($act->obj['updated']) { - $s['edited'] = datetime_convert('UTC','UTC',$act->obj['updated']); + elseif ($act->obj['updated']) { + $s['edited'] = datetime_convert('UTC', 'UTC', $act->obj['updated']); } if ($act->data['expires']) { - $s['expires'] = datetime_convert('UTC','UTC',$act->data['expires']); + $s['expires'] = datetime_convert('UTC', 'UTC', $act->data['expires']); } elseif ($act->obj['expires']) { - $s['expires'] = datetime_convert('UTC','UTC',$act->obj['expires']); + $s['expires'] = datetime_convert('UTC', 'UTC', $act->obj['expires']); } - if(ActivityStreams::is_response_activity($act->type)) { + if (ActivityStreams::is_response_activity($act->type)) { $response_activity = true; @@ -2092,85 +2046,85 @@ class Activity { // over-ride the object timestamp with the activity - if($act->data['published']) { - $s['created'] = datetime_convert('UTC','UTC',$act->data['published']); + if ($act->data['published']) { + $s['created'] = datetime_convert('UTC', 'UTC', $act->data['published']); } - if($act->data['updated']) { - $s['edited'] = datetime_convert('UTC','UTC',$act->data['updated']); + if ($act->data['updated']) { + $s['edited'] = datetime_convert('UTC', 'UTC', $act->data['updated']); } $obj_actor = ((isset($act->obj['actor'])) ? $act->obj['actor'] : $act->get_actor('attributedTo', $act->obj)); // ensure we store the original actor - self::actor_store($obj_actor['id'],$obj_actor); + self::actor_store($obj_actor['id'], $obj_actor); $mention = self::get_actor_bbmention($obj_actor['id']); - if($act->type === 'Like') { - $content['content'] = sprintf( t('Likes %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content']; + if ($act->type === 'Like') { + $content['content'] = sprintf(t('Likes %1$s\'s %2$s'), $mention, $act->obj['type']) . "\n\n" . $content['content']; } - if($act->type === 'Dislike') { - $content['content'] = sprintf( t('Doesn\'t like %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content']; + if ($act->type === 'Dislike') { + $content['content'] = sprintf(t('Doesn\'t like %1$s\'s %2$s'), $mention, $act->obj['type']) . "\n\n" . $content['content']; } // handle event RSVPs - if (($act->obj['type'] === 'Event') || ($act->obj['type'] === 'Invite' && array_path_exists('object/type',$act->obj) && $act->obj['object']['type'] === 'Event')) { + if (($act->obj['type'] === 'Event') || ($act->obj['type'] === 'Invite' && array_path_exists('object/type', $act->obj) && $act->obj['object']['type'] === 'Event')) { if ($act->type === 'Accept') { - $content['content'] = sprintf( t('Will attend %s\'s event'),$mention) . EOL . EOL . $content['content']; + $content['content'] = sprintf(t('Will attend %s\'s event'), $mention) . EOL . EOL . $content['content']; } if ($act->type === 'Reject') { - $content['content'] = sprintf( t('Will not attend %s\'s event'),$mention) . EOL . EOL . $content['content']; + $content['content'] = sprintf(t('Will not attend %s\'s event'), $mention) . EOL . EOL . $content['content']; } if ($act->type === 'TentativeAccept') { - $content['content'] = sprintf( t('May attend %s\'s event'),$mention) . EOL . EOL . $content['content']; + $content['content'] = sprintf(t('May attend %s\'s event'), $mention) . EOL . EOL . $content['content']; } if ($act->type === 'TentativeReject') { - $content['content'] = sprintf( t('May not attend %s\'s event'),$mention) . EOL . EOL . $content['content']; + $content['content'] = sprintf(t('May not attend %s\'s event'), $mention) . EOL . EOL . $content['content']; } } - if($act->type === 'Announce') { - $content['content'] = sprintf( t('🔁 Repeated %1$s\'s %2$s'), $mention, $act->obj['type']); + if ($act->type === 'Announce') { + $content['content'] = sprintf(t('🔁 Repeated %1$s\'s %2$s'), $mention, $act->obj['type']); } if ($act->type === 'emojiReaction') { $content['content'] = (($act->tgt && $act->tgt['type'] === 'Image') ? '[img=32x32]' . $act->tgt['url'] . '[/img]' : '&#x' . $act->tgt['name'] . ';'); - } + } } - if(! $s['created']) + if (!$s['created']) $s['created'] = datetime_convert(); - if(! $s['edited']) + if (!$s['edited']) $s['edited'] = $s['created']; - $s['title'] = (($response_activity) ? EMPTY_STR : self::bb_content($content,'name')); - $s['summary'] = self::bb_content($content,'summary'); - $s['body'] = ((self::bb_content($content,'bbcode') && (! $response_activity)) ? self::bb_content($content,'bbcode') : self::bb_content($content,'content')); + $s['title'] = (($response_activity) ? EMPTY_STR : self::bb_content($content, 'name')); + $s['summary'] = self::bb_content($content, 'summary'); + $s['body'] = ((self::bb_content($content, 'bbcode') && (!$response_activity)) ? self::bb_content($content, 'bbcode') : self::bb_content($content, 'content')); - $s['verb'] = self::activity_decode_mapper($act->type); + $s['verb'] = self::activity_decode_mapper($act->type); // Mastodon does not provide update timestamps when updating poll tallies which means race conditions may occur here. if ($act->type === 'Update' && $act->obj['type'] === 'Question' && $s['edited'] === $s['created']) { $s['edited'] = datetime_convert(); } - if(in_array($act->type, [ 'Delete', 'Undo', 'Tombstone' ]) || ($act->type === 'Create' && $act->obj['type'] === 'Tombstone')) { + if (in_array($act->type, ['Delete', 'Undo', 'Tombstone']) || ($act->type === 'Create' && $act->obj['type'] === 'Tombstone')) { $s['item_deleted'] = 1; } $s['obj_type'] = self::activity_obj_decode_mapper($act->obj['type']); - if($s['obj_type'] === ACTIVITY_OBJ_NOTE && $s['mid'] !== $s['parent_mid']) { + if ($s['obj_type'] === ACTIVITY_OBJ_NOTE && $s['mid'] !== $s['parent_mid']) { $s['obj_type'] = ACTIVITY_OBJ_COMMENT; } $eventptr = null; - if ($act->obj['type'] === 'Invite' && array_path_exists('object/type',$act->obj) && $act->obj['object']['type'] === 'Event') { + if ($act->obj['type'] === 'Invite' && array_path_exists('object/type', $act->obj) && $act->obj['object']['type'] === 'Event') { $eventptr = $act->obj['object']; $s['mid'] = $s['parent_mid'] = $act->obj['id']; } - - if($act->obj['type'] === 'Event') { + + if ($act->obj['type'] === 'Event') { if ($act->type === 'Invite') { $s['mid'] = $s['parent_mid'] = $act->id; } @@ -2179,52 +2133,52 @@ class Activity { if ($eventptr) { - $s['obj'] = []; - $s['obj']['asld'] = $eventptr; - $s['obj']['type'] = ACTIVITY_OBJ_EVENT; - $s['obj']['id'] = $eventptr['id']; + $s['obj'] = []; + $s['obj']['asld'] = $eventptr; + $s['obj']['type'] = ACTIVITY_OBJ_EVENT; + $s['obj']['id'] = $eventptr['id']; $s['obj']['title'] = $eventptr['name']; - if(strpos($act->obj['startTime'],'Z')) + if (strpos($act->obj['startTime'], 'Z')) $s['obj']['adjust'] = true; else $s['obj']['adjust'] = false; - $s['obj']['dtstart'] = datetime_convert('UTC','UTC',$eventptr['startTime']); - if($act->obj['endTime']) - $s['obj']['dtend'] = datetime_convert('UTC','UTC',$eventptr['endTime']); + $s['obj']['dtstart'] = datetime_convert('UTC', 'UTC', $eventptr['startTime']); + if ($act->obj['endTime']) + $s['obj']['dtend'] = datetime_convert('UTC', 'UTC', $eventptr['endTime']); else $s['obj']['nofinish'] = true; $s['obj']['description'] = $eventptr['content']; - if(array_path_exists('location/content',$eventptr)) + if (array_path_exists('location/content', $eventptr)) $s['obj']['location'] = $eventptr['location']['content']; } else { - $s['obj'] = $act->obj; + $s['obj'] = $act->obj; } $generator = $act->get_property_obj('generator'); - if((! $generator) && (! $response_activity)) { - $generator = $act->get_property_obj('generator',$act->obj); + if ((!$generator) && (!$response_activity)) { + $generator = $act->get_property_obj('generator', $act->obj); } - if($generator && array_key_exists('type',$generator) - && in_array($generator['type'], [ 'Application', 'Service' ] ) && array_key_exists('name',$generator)) { + if ($generator && array_key_exists('type', $generator) + && in_array($generator['type'], ['Application', 'Service']) && array_key_exists('name', $generator)) { $s['app'] = escape_tags($generator['name']); } - if(! $response_activity) { + if (!$response_activity) { $a = self::decode_taxonomy($act->obj); - if($a) { + if ($a) { $s['term'] = $a; - foreach($a as $b) { - if($b['ttype'] === TERM_EMOJI) { - $s['title'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['title']); - $s['summary'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['summary']); - $s['body'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['body']); + foreach ($a as $b) { + if ($b['ttype'] === TERM_EMOJI) { + $s['title'] = str_replace($b['term'], '[img=16x16]' . $b['url'] . '[/img]', $s['title']); + $s['summary'] = str_replace($b['term'], '[img=16x16]' . $b['url'] . '[/img]', $s['summary']); + $s['body'] = str_replace($b['term'], '[img=16x16]' . $b['url'] . '[/img]', $s['body']); } } } @@ -2241,28 +2195,27 @@ class Activity { $s['iconfig'] = $a; } - if($act->obj['type'] === 'Note' && $s['attach']) { - $s['body'] .= self::bb_attach($s['attach'],$s['body']); + if ($act->obj['type'] === 'Note' && $s['attach']) { + $s['body'] .= self::bb_attach($s['attach'], $s['body']); } - if ($act->obj['type'] === 'Question' && in_array($act->type,['Create','Update'])) { + if ($act->obj['type'] === 'Question' && in_array($act->type, ['Create', 'Update'])) { if ($act->obj['endTime']) { - $s['comments_closed'] = datetime_convert('UTC','UTC', $act->obj['endTime']); + $s['comments_closed'] = datetime_convert('UTC', 'UTC', $act->obj['endTime']); } } if ($act->obj['closed']) { - $s['comments_closed'] = datetime_convert('UTC','UTC', $act->obj['closed']); - } - + $s['comments_closed'] = datetime_convert('UTC', 'UTC', $act->obj['closed']); + } // we will need a hook here to extract magnet links e.g. peertube // right now just link to the largest mp4 we find that will fit in our // standard content region - if(! $response_activity) { - if($act->obj['type'] === 'Video') { + if (!$response_activity) { + if ($act->obj['type'] === 'Video') { $vtypes = [ 'video/mp4', @@ -2273,27 +2226,27 @@ class Activity { $mps = []; $ptr = null; - if(array_key_exists('url',$act->obj)) { - if(is_array($act->obj['url'])) { - if(array_key_exists(0,$act->obj['url'])) { + if (array_key_exists('url', $act->obj)) { + if (is_array($act->obj['url'])) { + if (array_key_exists(0, $act->obj['url'])) { $ptr = $act->obj['url']; } else { - $ptr = [ $act->obj['url'] ]; + $ptr = [$act->obj['url']]; } - foreach($ptr as $vurl) { + foreach ($ptr as $vurl) { // peertube uses the non-standard element name 'mimeType' here - if(array_key_exists('mimeType',$vurl)) { - if(in_array($vurl['mimeType'], $vtypes)) { - if(! array_key_exists('width',$vurl)) { + if (array_key_exists('mimeType', $vurl)) { + if (in_array($vurl['mimeType'], $vtypes)) { + if (!array_key_exists('width', $vurl)) { $vurl['width'] = 0; } $mps[] = $vurl; } } - elseif(array_key_exists('mediaType',$vurl)) { - if(in_array($vurl['mediaType'], $vtypes)) { - if(! array_key_exists('width',$vurl)) { + elseif (array_key_exists('mediaType', $vurl)) { + if (in_array($vurl['mediaType'], $vtypes)) { + if (!array_key_exists('width', $vurl)) { $vurl['width'] = 0; } $mps[] = $vurl; @@ -2301,22 +2254,22 @@ class Activity { } } } - if($mps) { - usort($mps,[ __CLASS__, 'vid_sort' ]); - foreach($mps as $m) { - if(intval($m['width']) < 500 && self::media_not_in_body($m['href'],$s['body'])) { + if ($mps) { + usort($mps, [__CLASS__, 'vid_sort']); + foreach ($mps as $m) { + if (intval($m['width']) < 500 && self::media_not_in_body($m['href'], $s['body'])) { $s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]'; break; } } } - elseif(is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'],$s['body'])) { + elseif (is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'], $s['body'])) { $s['body'] .= "\n\n" . '[video]' . $act->obj['url'] . '[/video]'; } } } - if($act->obj['type'] === 'Audio') { + if ($act->obj['type'] === 'Audio') { $atypes = [ 'audio/mpeg', @@ -2326,50 +2279,50 @@ class Activity { $ptr = null; - if(array_key_exists('url',$act->obj)) { - if(is_array($act->obj['url'])) { - if(array_key_exists(0,$act->obj['url'])) { + if (array_key_exists('url', $act->obj)) { + if (is_array($act->obj['url'])) { + if (array_key_exists(0, $act->obj['url'])) { $ptr = $act->obj['url']; } else { - $ptr = [ $act->obj['url'] ]; + $ptr = [$act->obj['url']]; } - foreach($ptr as $vurl) { - if(in_array($vurl['mediaType'], $atypes) && self::media_not_in_body($vurl['href'],$s['body'])) { + foreach ($ptr as $vurl) { + if (in_array($vurl['mediaType'], $atypes) && self::media_not_in_body($vurl['href'], $s['body'])) { $s['body'] .= "\n\n" . '[audio]' . $vurl['href'] . '[/audio]'; break; } } } - elseif(is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'],$s['body'])) { + elseif (is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'], $s['body'])) { $s['body'] .= "\n\n" . '[audio]' . $act->obj['url'] . '[/audio]'; } } } - if($act->obj['type'] === 'Image') { + if ($act->obj['type'] === 'Image') { $ptr = null; - if(array_key_exists('url',$act->obj)) { - if(is_array($act->obj['url'])) { - if(array_key_exists(0,$act->obj['url'])) { + if (array_key_exists('url', $act->obj)) { + if (is_array($act->obj['url'])) { + if (array_key_exists(0, $act->obj['url'])) { $ptr = $act->obj['url']; } else { - $ptr = [ $act->obj['url'] ]; + $ptr = [$act->obj['url']]; } - foreach($ptr as $vurl) { - if(strpos($s['body'],$vurl['href']) === false) { - $bb_imgs .= '[zmg]' . $vurl['href'] . '[/zmg]' . "\n\n"; + foreach ($ptr as $vurl) { + if (strpos($s['body'], $vurl['href']) === false) { + $bb_imgs = '[zmg]' . $vurl['href'] . '[/zmg]' . "\n\n"; break; } } $s['body'] = $bb_imgs . $s['body']; } - elseif(is_string($act->obj['url'])) { - if(strpos($s['body'],$act->obj['url']) === false) { + elseif (is_string($act->obj['url'])) { + if (strpos($s['body'], $act->obj['url']) === false) { $s['body'] .= '[zmg]' . $act->obj['url'] . '[/zmg]' . "\n\n" . $s['body']; } } @@ -2377,36 +2330,36 @@ class Activity { } - if($act->obj['type'] === 'Page' && ! $s['body']) { + if ($act->obj['type'] === 'Page' && !$s['body']) { $ptr = null; $purl = EMPTY_STR; - if(array_key_exists('url',$act->obj)) { - if(is_array($act->obj['url'])) { - if(array_key_exists(0,$act->obj['url'])) { + if (array_key_exists('url', $act->obj)) { + if (is_array($act->obj['url'])) { + if (array_key_exists(0, $act->obj['url'])) { $ptr = $act->obj['url']; } else { - $ptr = [ $act->obj['url'] ]; + $ptr = [$act->obj['url']]; } - foreach($ptr as $vurl) { - if(array_key_exists('mediaType',$vurl) && $vurl['mediaType'] === 'text/html') { + foreach ($ptr as $vurl) { + if (array_key_exists('mediaType', $vurl) && $vurl['mediaType'] === 'text/html') { $purl = $vurl['href']; break; } - elseif(array_key_exists('mimeType',$vurl) && $vurl['mimeType'] === 'text/html') { + elseif (array_key_exists('mimeType', $vurl) && $vurl['mimeType'] === 'text/html') { $purl = $vurl['href']; break; } } } - elseif(is_string($act->obj['url'])) { + elseif (is_string($act->obj['url'])) { $purl = $act->obj['url']; } - if($purl) { + if ($purl) { $li = z_fetch_url(z_root() . '/linkinfo?binurl=' . bin2hex($purl)); - if($li['success'] && $li['body']) { + if ($li['success'] && $li['body']) { $s['body'] .= "\n" . $li['body']; } else { @@ -2418,32 +2371,31 @@ class Activity { } - - if(in_array($act->obj['type'],[ 'Note','Article','Page' ])) { + if (in_array($act->obj['type'], ['Note', 'Article', 'Page'])) { $ptr = null; - if(array_key_exists('url',$act->obj)) { - if(is_array($act->obj['url'])) { - if(array_key_exists(0,$act->obj['url'])) { + if (array_key_exists('url', $act->obj)) { + if (is_array($act->obj['url'])) { + if (array_key_exists(0, $act->obj['url'])) { $ptr = $act->obj['url']; } else { - $ptr = [ $act->obj['url'] ]; + $ptr = [$act->obj['url']]; } - foreach($ptr as $vurl) { - if(array_key_exists('mediaType',$vurl) && $vurl['mediaType'] === 'text/html') { + foreach ($ptr as $vurl) { + if (array_key_exists('mediaType', $vurl) && $vurl['mediaType'] === 'text/html') { $s['plink'] = $vurl['href']; break; } } } - elseif(is_string($act->obj['url'])) { + elseif (is_string($act->obj['url'])) { $s['plink'] = $act->obj['url']; } } } - if(! $s['plink']) { + if (!$s['plink']) { $s['plink'] = $s['mid']; } @@ -2456,24 +2408,24 @@ class Activity { } if (is_array($act->obj)) { - if (array_key_exists('directMessage',$act->obj) && intval($act->obj['directMessage'])) { + if (array_key_exists('directMessage', $act->obj) && intval($act->obj['directMessage'])) { $s['item_private'] = 2; } } - set_iconfig($s,'activitypub','recips',$act->raw_recips); + set_iconfig($s, 'activitypub', 'recips', $act->raw_recips); $parent = (($s['parent_mid'] && $s['parent_mid'] === $s['mid']) ? true : false); - if($parent) { - set_iconfig($s,'activitypub','rawmsg',$act->raw,1); + if ($parent) { + set_iconfig($s, 'activitypub', 'rawmsg', $act->raw, 1); } $hookinfo = [ 'act' => $act, - 's' => $s + 's' => $s ]; - call_hooks('decode_note',$hookinfo); + call_hooks('decode_note', $hookinfo); $s = $hookinfo['s']; @@ -2481,7 +2433,7 @@ class Activity { } - static function store($channel,$observer_hash,$act,$item,$fetch_parents = true) { + static function store($channel, $observer_hash, $act, $item, $fetch_parents = true) { $is_sys_channel = is_sys_channel($channel['channel_id']); @@ -2492,15 +2444,15 @@ class Activity { $pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false); $is_parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false); - if($is_parent && (! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream))) { + if ($is_parent && (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !($is_sys_channel && $pubstream))) { logger('no permission'); return; } - if(is_array($act->obj)) { + if (is_array($act->obj)) { $content = self::get_content($act->obj); } - if(! $content) { + if (!$content) { logger('no content'); return; } @@ -2513,19 +2465,19 @@ class Activity { $item['author_xchan'] = self::find_best_identity($item['author_xchan']); $item['owner_xchan'] = self::find_best_identity($item['owner_xchan']); - if(!$item['author_xchan']) { + if (!$item['author_xchan']) { logger('No author: ' . print_r($act, true)); } - if(!$item['owner_xchan']) { + if (!$item['owner_xchan']) { logger('No owner: ' . print_r($act, true)); } - if(!$item['author_xchan'] || !$item['owner_xchan']) + if (!$item['author_xchan'] || !$item['owner_xchan']) return; - if($channel['channel_system']) { - if(! MessageFilter::evaluate($item,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) { + if ($channel['channel_system']) { + if (!MessageFilter::evaluate($item, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) { logger('post is filtered'); return; } @@ -2536,32 +2488,32 @@ class Activity { intval($channel['channel_id']) ); - if($abook) { - if(! post_is_importable($item,$abook[0])) { + if ($abook) { + if (!post_is_importable($item, $abook[0])) { logger('post is filtered'); return; } } - if($act->obj['conversation']) { - set_iconfig($item,'ostatus','conversation',$act->obj['conversation'],1); + if ($act->obj['conversation']) { + set_iconfig($item, 'ostatus', 'conversation', $act->obj['conversation'], 1); } // This isn't perfect but the best we can do for now. $item['comment_policy'] = 'authenticated'; - set_iconfig($item,'activitypub','recips',$act->raw_recips); + set_iconfig($item, 'activitypub', 'recips', $act->raw_recips); - if(! $is_parent) { + if (!$is_parent) { $p = q("select parent_mid, id, obj_type from item where mid = '%s' and uid = %d limit 1", dbesc($item['parent_mid']), intval($item['uid']) ); - if(! $p) { - $a = (($fetch_parents) ? self::fetch_and_store_parents($channel,$act,$item) : false); - if($a) { + if (!$p) { + $a = (($fetch_parents) ? self::fetch_and_store_parents($channel, $item) : false); + if ($a) { $p = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", dbesc($item['parent_mid']), intval($item['uid']) @@ -2588,13 +2540,13 @@ class Activity { if ($p[0]['obj_type'] === 'Question') { - if ($item['obj_type'] === ACTIVITY_OBJ_NOTE && $item['title'] && (! $item['content'])) { + if ($item['obj_type'] === ACTIVITY_OBJ_NOTE && $item['title'] && (!$item['content'])) { $item['obj_type'] = 'Answer'; } } - if($p[0]['parent_mid'] !== $item['parent_mid']) { + if ($p[0]['parent_mid'] !== $item['parent_mid']) { $item['thr_parent'] = $item['parent_mid']; } else { @@ -2607,10 +2559,10 @@ class Activity { dbesc($item['mid']), intval($item['uid']) ); - if($r) { - if($item['edited'] > $r[0]['edited']) { + if ($r) { + if ($item['edited'] > $r[0]['edited']) { $item['id'] = $r[0]['id']; - $x = item_store_update($item); + $x = item_store_update($item); } else { return; @@ -2620,52 +2572,51 @@ class Activity { $x = item_store($item); } - if(is_array($x) && $x['item_id']) { - if($is_parent) { - if($item['owner_xchan'] === $channel['channel_hash']) { + if (is_array($x) && $x['item_id']) { + if ($is_parent) { + if ($item['owner_xchan'] === $channel['channel_hash']) { // We are the owner of this conversation, so send all received comments back downstream - Master::Summon(array('Notifier','comment-import',$x['item_id'])); + Master::Summon(['Notifier', 'comment-import', $x['item_id']]); } $r = q("select * from item where id = %d limit 1", intval($x['item_id']) ); - if($r) { - send_status_notifications($x['item_id'],$r[0]); + if ($r) { + send_status_notifications($x['item_id'], $r[0]); } } - sync_an_item($channel['channel_id'],$x['item_id']); + sync_an_item($channel['channel_id'], $x['item_id']); } } - static public function fetch_and_store_parents($channel,$act,$item) { + static public function fetch_and_store_parents($channel, $item) { logger('fetching parents'); $p = []; - $current_act = $act; $current_item = $item; - while($current_item['parent_mid'] !== $current_item['mid']) { + while ($current_item['parent_mid'] !== $current_item['mid']) { $n = self::fetch($current_item['parent_mid'], $channel); - if(! $n) { + if (!$n) { break; } $a = new ActivityStreams($n); //logger($a->debug()); - if(! $a->is_valid()) { + if (!$a->is_valid()) { break; } - if (is_array($a->actor) && array_key_exists('id',$a->actor)) { - self::actor_store($a->actor['id'],$a->actor); + if (is_array($a->actor) && array_key_exists('id', $a->actor)) { + self::actor_store($a->actor['id'], $a->actor); } $replies = null; - if(isset($a->obj['replies']['first']['items'])) { + if (isset($a->obj['replies']['first']['items'])) { $replies = $a->obj['replies']['first']['items']; // we already have this one array_diff($replies, [$current_item['mid']]); @@ -2673,11 +2624,11 @@ class Activity { $item = null; - switch($a->type) { + switch ($a->type) { case 'Create': case 'Update': - //case 'Like': - //case 'Dislike': + //case 'Like': + //case 'Dislike': case 'Announce': $item = self::decode_note($a); break; @@ -2687,31 +2638,30 @@ class Activity { } $hookinfo = [ - 'a' => $a, + 'a' => $a, 'item' => $item ]; - call_hooks('fetch_and_store',$hookinfo); + call_hooks('fetch_and_store', $hookinfo); $item = $hookinfo['item']; - if($item) { + if ($item) { - array_unshift($p,[ $a, $item, $replies]); - - if($item['parent_mid'] === $item['mid'] || count($p) > 20) { + array_unshift($p, [$a, $item, $replies]); + + if ($item['parent_mid'] === $item['mid'] || count($p) > 20) { break; } } - $current_act = $a; $current_item = $item; } - if($p) { - foreach($p as $pv) { - self::store($channel,$pv[0]->actor['id'],$pv[0],$pv[1],false); - if($pv[2]) + if ($p) { + foreach ($p as $pv) { + self::store($channel, $pv[0]->actor['id'], $pv[0], $pv[1], false); + if ($pv[2]) self::fetch_and_store_replies($channel, $pv[2]); } return true; @@ -2723,26 +2673,26 @@ class Activity { static public function fetch_and_store_replies($channel, $arr) { logger('fetching replies'); - logger(print_r($arr,true)); + logger(print_r($arr, true)); $p = []; - foreach($arr as $url) { + foreach ($arr as $url) { $n = self::fetch($url, $channel); - if(! $n) { + if (!$n) { break; } $a = new ActivityStreams($n); - if(! $a->is_valid()) { + if (!$a->is_valid()) { break; } $item = null; - switch($a->type) { + switch ($a->type) { case 'Create': case 'Update': case 'Like': @@ -2755,29 +2705,29 @@ class Activity { } $hookinfo = [ - 'a' => $a, + 'a' => $a, 'item' => $item ]; - call_hooks('fetch_and_store',$hookinfo); + call_hooks('fetch_and_store', $hookinfo); $item = $hookinfo['item']; - if($item) { - array_unshift($p,[ $a, $item ]); + if ($item) { + array_unshift($p, [$a, $item]); } } - if($p) { - foreach($p as $pv) { - self::store($channel,$pv[0]->actor['id'],$pv[0],$pv[1],false); + if ($p) { + foreach ($p as $pv) { + self::store($channel, $pv[0]->actor['id'], $pv[0], $pv[1], false); } } } - static function announce_note($channel,$observer_hash,$act) { + static function announce_note($channel, $observer_hash, $act) { $s = []; @@ -2788,29 +2738,29 @@ class Activity { // This is not part of the activitypub protocol - we might change this to show all public posts in pubstream at some point. $pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false); - if(! perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && ! ($is_sys_channel && $pubstream)) { + if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !($is_sys_channel && $pubstream)) { logger('no permission'); return; } $content = self::get_content($act->obj); - if(! $content) { + if (!$content) { logger('no content'); return; } $s['owner_xchan'] = $s['author_xchan'] = $observer_hash; - $s['aid'] = $channel['channel_account_id']; - $s['uid'] = $channel['channel_id']; - $s['mid'] = urldecode($act->obj['id']); + $s['aid'] = $channel['channel_account_id']; + $s['uid'] = $channel['channel_id']; + $s['mid'] = urldecode($act->obj['id']); $s['plink'] = urldecode($act->obj['id']); - if(! $s['created']) + if (!$s['created']) $s['created'] = datetime_convert(); - if(! $s['edited']) + if (!$s['edited']) $s['edited'] = $s['created']; @@ -2820,8 +2770,8 @@ class Activity { $s['obj_type'] = ACTIVITY_OBJ_NOTE; $s['app'] = t('ActivityPub'); - if($channel['channel_system']) { - if(! \Zotlabs\Lib\MessageFilter::evaluate($s,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) { + if ($channel['channel_system']) { + if (!MessageFilter::evaluate($s, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) { logger('post is filtered'); return; } @@ -2832,61 +2782,61 @@ class Activity { intval($channel['channel_id']) ); - if($abook) { - if(! post_is_importable($s,$abook[0])) { + if ($abook) { + if (!post_is_importable($s, $abook[0])) { logger('post is filtered'); return; } } - if($act->obj['conversation']) { - set_iconfig($s,'ostatus','conversation',$act->obj['conversation'],1); + if ($act->obj['conversation']) { + set_iconfig($s, 'ostatus', 'conversation', $act->obj['conversation'], 1); } $a = self::decode_taxonomy($act->obj); - if($a) { + if ($a) { $s['term'] = $a; } $a = self::decode_attachment($act->obj); - if($a) { + if ($a) { $s['attach'] = $a; } - $body = "[share author='" . urlencode($act->sharee['name']) . - "' profile='" . $act->sharee['url'] . - "' avatar='" . $act->sharee['photo_s'] . - "' link='" . ((is_array($act->obj['url'])) ? $act->obj['url']['href'] : $act->obj['url']) . - "' auth='" . ((is_matrix_url($act->obj['url'])) ? 'true' : 'false' ) . - "' posted='" . $act->obj['published'] . - "' message_id='" . $act->obj['id'] . - "']"; + $body = "[share author='" . urlencode($act->sharee['name']) . + "' profile='" . $act->sharee['url'] . + "' avatar='" . $act->sharee['photo_s'] . + "' link='" . ((is_array($act->obj['url'])) ? $act->obj['url']['href'] : $act->obj['url']) . + "' auth='" . ((is_matrix_url($act->obj['url'])) ? 'true' : 'false') . + "' posted='" . $act->obj['published'] . + "' message_id='" . $act->obj['id'] . + "']"; - if($content['name']) - $body .= self::bb_content($content,'name') . "\r\n"; + if ($content['name']) + $body .= self::bb_content($content, 'name') . "\r\n"; - $body .= self::bb_content($content,'content'); + $body .= self::bb_content($content, 'content'); - if($act->obj['type'] === 'Note' && $s['attach']) { - $body .= self::bb_attach($s['attach'],$body); + if ($act->obj['type'] === 'Note' && $s['attach']) { + $body .= self::bb_attach($s['attach'], $body); } $body .= "[/share]"; - $s['title'] = self::bb_content($content,'name'); - $s['body'] = $body; + $s['title'] = self::bb_content($content, 'name'); + $s['body'] = $body; - if($act->recips && (! in_array(ACTIVITY_PUBLIC_INBOX,$act->recips))) + if ($act->recips && (!in_array(ACTIVITY_PUBLIC_INBOX, $act->recips))) $s['item_private'] = 1; - set_iconfig($s,'activitypub','recips',$act->raw_recips); + set_iconfig($s, 'activitypub', 'recips', $act->raw_recips); $r = q("select created, edited from item where mid = '%s' and uid = %d limit 1", dbesc($s['mid']), intval($s['uid']) ); - if($r) { - if($s['edited'] > $r[0]['edited']) { + if ($r) { + if ($s['edited'] > $r[0]['edited']) { $x = item_store_update($s); } else { @@ -2897,35 +2847,35 @@ class Activity { $x = item_store($s); } - if(is_array($x) && $x['item_id']) { - if($s['owner_xchan'] === $channel['channel_hash']) { + if (is_array($x) && $x['item_id']) { + if ($s['owner_xchan'] === $channel['channel_hash']) { // We are the owner of this conversation, so send all received comments back downstream - Master::Summon(array('Notifier','comment-import',$x['item_id'])); + Master::Summon(['Notifier', 'comment-import', $x['item_id']]); } $r = q("select * from item where id = %d limit 1", intval($x['item_id']) ); - if($r) { - send_status_notifications($x['item_id'],$r[0]); + if ($r) { + send_status_notifications($x['item_id'], $r[0]); } - sync_an_item($channel['channel_id'],$x['item_id']); + sync_an_item($channel['channel_id'], $x['item_id']); } } - static function like_note($channel,$observer_hash,$act) { + static function like_note($channel, $observer_hash, $act) { $s = []; $parent = $act->obj['id']; - - if($act->type === 'Like') + + if ($act->type === 'Like') $s['verb'] = ACTIVITY_LIKE; - if($act->type === 'Dislike') + if ($act->type === 'Dislike') $s['verb'] = ACTIVITY_DISLIKE; - if(! $parent) + if (!$parent) return; $r = q("select * from item where uid = %d and ( mid = '%s' or mid = '%s' ) limit 1", @@ -2934,7 +2884,7 @@ class Activity { dbesc(urldecode(basename($parent))) ); - if(! $r) { + if (!$r) { logger('parent not found.'); return; } @@ -2942,14 +2892,14 @@ class Activity { xchan_query($r); $parent_item = $r[0]; - if($parent_item['owner_xchan'] === $channel['channel_hash']) { - if(! perm_is_allowed($channel['channel_id'],$observer_hash,'post_comments')) { + if ($parent_item['owner_xchan'] === $channel['channel_hash']) { + if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'post_comments')) { logger('no comment permission.'); return; } } - if($parent_item['mid'] === $parent_item['parent_mid']) { + if ($parent_item['mid'] === $parent_item['parent_mid']) { $s['parent_mid'] = $parent_item['mid']; } else { @@ -2957,31 +2907,29 @@ class Activity { $s['parent_mid'] = $parent_item['parent_mid']; } - $s['owner_xchan'] = $parent_item['owner_xchan']; + $s['owner_xchan'] = $parent_item['owner_xchan']; $s['author_xchan'] = $observer_hash; - + $s['aid'] = $channel['channel_account_id']; $s['uid'] = $channel['channel_id']; $s['mid'] = $act->id; - if(! $s['parent_mid']) + if (!$s['parent_mid']) $s['parent_mid'] = $s['mid']; - - $post_type = (($parent_item['resource_type'] === 'photo') ? t('photo') : t('post')); - $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $parent_item['plink'])); - $objtype = (($parent_item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); + $post_type = (($parent_item['resource_type'] === 'photo') ? t('photo') : t('post')); - $body = $parent_item['body']; + $links = [['rel' => 'alternate', 'type' => 'text/html', 'href' => $parent_item['plink']]]; + $objtype = (($parent_item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE); $z = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($parent_item['author_xchan']) ); - if($z) - $item_author = $z[0]; + if ($z) + $item_author = $z[0]; - $object = json_encode(array( + $object = json_encode([ 'type' => $post_type, 'id' => $parent_item['mid'], 'parent' => (($parent_item['thr_parent']) ? $parent_item['thr_parent'] : $parent_item['parent_mid']), @@ -2990,77 +2938,76 @@ class Activity { 'content' => $parent_item['body'], 'created' => $parent_item['created'], 'edited' => $parent_item['edited'], - 'author' => array( + 'author' => [ 'name' => $item_author['xchan_name'], 'address' => $item_author['xchan_addr'], 'guid' => $item_author['xchan_guid'], 'guid_sig' => $item_author['xchan_guid_sig'], - 'link' => array( - array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']), - array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])), - ), - ), JSON_UNESCAPED_SLASHES + 'link' => [ + ['rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']], + ['rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m']]], + ], + ], JSON_UNESCAPED_SLASHES ); - if($act->type === 'Like') + if ($act->type === 'Like') $bodyverb = t('%1$s likes %2$s\'s %3$s'); - if($act->type === 'Dislike') + if ($act->type === 'Dislike') $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); - $ulink = '[url=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/url]'; - $alink = '[url=' . $parent_item['author']['xchan_url'] . ']' . $parent_item['author']['xchan_name'] . '[/url]'; - $plink = '[url='. z_root() . '/display/' . urlencode($act->id) . ']' . $post_type . '[/url]'; - $s['body'] = sprintf( $bodyverb, $ulink, $alink, $plink ); + $ulink = '[url=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/url]'; + $alink = '[url=' . $parent_item['author']['xchan_url'] . ']' . $parent_item['author']['xchan_name'] . '[/url]'; + $plink = '[url=' . z_root() . '/display/' . urlencode($act->id) . ']' . $post_type . '[/url]'; + $s['body'] = sprintf($bodyverb, $ulink, $alink, $plink); - $s['app'] = t('ActivityPub'); + $s['app'] = t('ActivityPub'); // set the route to that of the parent so downstream hubs won't reject it. - $s['route'] = $parent_item['route']; + $s['route'] = $parent_item['route']; $s['item_private'] = $parent_item['item_private']; - $s['obj_type'] = $objtype; - $s['obj'] = $object; + $s['obj_type'] = $objtype; + $s['obj'] = $object; - if($act->obj['conversation']) { - set_iconfig($s,'ostatus','conversation',$act->obj['conversation'],1); + if ($act->obj['conversation']) { + set_iconfig($s, 'ostatus', 'conversation', $act->obj['conversation'], 1); } - if($act->recips && (! in_array(ACTIVITY_PUBLIC_INBOX,$act->recips))) + if ($act->recips && (!in_array(ACTIVITY_PUBLIC_INBOX, $act->recips))) $s['item_private'] = 1; - set_iconfig($s,'activitypub','recips',$act->raw_recips); + set_iconfig($s, 'activitypub', 'recips', $act->raw_recips); $result = item_store($s); - if($result['success']) { + if ($result['success']) { // if the message isn't already being relayed, notify others - if(intval($parent_item['item_origin'])) - Master::Summon(array('Notifier','comment-import',$result['item_id'])); - sync_an_item($channel['channel_id'],$result['item_id']); + if (intval($parent_item['item_origin'])) + Master::Summon(['Notifier', 'comment-import', $result['item_id']]); + sync_an_item($channel['channel_id'], $result['item_id']); } return; } - - static function bb_attach($attach,$body) { + static function bb_attach($attach, $body) { $ret = false; - foreach($attach as $a) { - if(strpos($a['type'],'image') !== false) { - if(self::media_not_in_body($a['href'],$body)) { + foreach ($attach as $a) { + if (strpos($a['type'], 'image') !== false) { + if (self::media_not_in_body($a['href'], $body)) { $ret .= "\n\n" . '[img]' . $a['href'] . '[/img]'; } } - if(array_key_exists('type',$a) && strpos($a['type'], 'video') === 0) { - if(self::media_not_in_body($a['href'],$body)) { + if (array_key_exists('type', $a) && strpos($a['type'], 'video') === 0) { + if (self::media_not_in_body($a['href'], $body)) { $ret .= "\n\n" . '[video]' . $a['href'] . '[/video]'; } } - if(array_key_exists('type',$a) && strpos($a['type'], 'audio') === 0) { - if(self::media_not_in_body($a['href'],$body)) { + if (array_key_exists('type', $a) && strpos($a['type'], 'audio') === 0) { + if (self::media_not_in_body($a['href'], $body)) { $ret .= "\n\n" . '[audio]' . $a['href'] . '[/audio]'; } } @@ -3072,40 +3019,40 @@ class Activity { // check for the existence of existing media link in body - static function media_not_in_body($s,$body) { - - if((strpos($body,']' . $s . '[/img]') === false) && - (strpos($body,']' . $s . '[/zmg]') === false) && - (strpos($body,']' . $s . '[/video]') === false) && - (strpos($body,']' . $s . '[/audio]') === false)) { + static function media_not_in_body($s, $body) { + + if ((strpos($body, ']' . $s . '[/img]') === false) && + (strpos($body, ']' . $s . '[/zmg]') === false) && + (strpos($body, ']' . $s . '[/video]') === false) && + (strpos($body, ']' . $s . '[/audio]') === false)) { return true; } return false; } - static function bb_content($content,$field) { + static function bb_content($content, $field) { require_once('include/html2bbcode.php'); require_once('include/event.php'); $ret = false; - if(is_array($content[$field])) { - foreach($content[$field] as $k => $v) { + if (is_array($content[$field])) { + foreach ($content[$field] as $k => $v) { $ret .= html2bbcode($v); // save this for auto-translate or dynamic filtering // $ret .= '[language=' . $k . ']' . html2bbcode($v) . '[/language]'; } } else { - if($field === 'bbcode' && array_key_exists('bbcode',$content)) { + if ($field === 'bbcode' && array_key_exists('bbcode', $content)) { $ret = $content[$field]; } else { $ret = html2bbcode($content[$field]); } } - if($field === 'content' && $content['event'] && (! strpos($ret,'[event'))) { + if ($field === 'content' && $content['event'] && (!strpos($ret, '[event'))) { $ret .= format_event_bbcode($content['event']); } @@ -3116,69 +3063,67 @@ class Activity { static function get_content($act) { $content = []; - $event = null; + $event = null; - if ((! $act) || (! is_array($act))) { + if ((!$act) || (!is_array($act))) { return $content; } - if($act['type'] === 'Event') { - $adjust = false; - $event = []; - $event['event_hash'] = $act['id']; - if(array_key_exists('startTime',$act) && strpos($act['startTime'],-1,1) === 'Z') { - $adjust = true; - $event['adjust'] = 1; - $event['dtstart'] = datetime_convert('UTC','UTC',$event['startTime'] . (($adjust) ? '' : 'Z')); - } - if(array_key_exists('endTime',$act)) { - $event['dtend'] = datetime_convert('UTC','UTC',$event['endTime'] . (($adjust) ? '' : 'Z')); - } - else { - $event['nofinish'] = true; - } - } - - foreach ([ 'name', 'summary', 'content' ] as $a) { - if (($x = self::get_textfield($act,$a)) !== false) { + if ($act['type'] === 'Event') { + $adjust = false; + $event = []; + $event['event_hash'] = $act['id']; + if (array_key_exists('startTime', $act) && strpos($act['startTime'], -1, 1) === 'Z') { + $adjust = true; + $event['adjust'] = 1; + $event['dtstart'] = datetime_convert('UTC', 'UTC', $event['startTime'] . (($adjust) ? '' : 'Z')); + } + if (array_key_exists('endTime', $act)) { + $event['dtend'] = datetime_convert('UTC', 'UTC', $event['endTime'] . (($adjust) ? '' : 'Z')); + } + else { + $event['nofinish'] = true; + } + } + + foreach (['name', 'summary', 'content'] as $a) { + if (($x = self::get_textfield($act, $a)) !== false) { $content[$a] = $x; } } - if($event) { + if ($event) { $event['summary'] = $content['name']; - if(! $event['summary']) { - if($content['summary']) { + if (!$event['summary']) { + if ($content['summary']) { $event['summary'] = html2plain($content['summary']); } } $event['description'] = html2bbcode($content['content']); - if($event['summary'] && $event['dtstart']) { + if ($event['summary'] && $event['dtstart']) { $content['event'] = $event; } } - if (array_path_exists('source/mediaType',$act) && array_path_exists('source/content',$act)) { + if (array_path_exists('source/mediaType', $act) && array_path_exists('source/content', $act)) { if ($act['source']['mediaType'] === 'text/bbcode') { $content['bbcode'] = purify_html($act['source']['content']); } } - - return $content; } - static function get_textfield($act,$field) { - + static function get_textfield($act, $field) { + $content = false; - if(array_key_exists($field,$act) && $act[$field]) + if (array_key_exists($field, $act) && $act[$field]) $content = purify_html($act[$field]); - elseif(array_key_exists($field . 'Map',$act) && $act[$field . 'Map']) { - foreach($act[$field . 'Map'] as $k => $v) { + elseif (array_key_exists($field . 'Map', $act) && $act[$field . 'Map']) { + foreach ($act[$field . 'Map'] as $k => $v) { $content[escape_tags($k)] = purify_html($v); } } @@ -3190,8 +3135,8 @@ class Activity { static function token_from_request() { - foreach ( [ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $s ) { - $auth = ((array_key_exists($s,$_SERVER) && strpos($_SERVER[$s],'Bearer ') === 0) + foreach (['REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION'] as $s) { + $auth = ((array_key_exists($s, $_SERVER) && strpos($_SERVER[$s], 'Bearer ') === 0) ? str_replace('Bearer ', EMPTY_STR, $_SERVER[$s]) : EMPTY_STR ); @@ -3200,8 +3145,8 @@ class Activity { } } - if (! $auth) { - if (array_key_exists('token',$_REQUEST) && $_REQUEST['token']) { + if (!$auth) { + if (array_key_exists('token', $_REQUEST) && $_REQUEST['token']) { $auth = $_REQUEST['token']; } } @@ -3211,7 +3156,7 @@ class Activity { static function find_best_identity($xchan) { - if(filter_var($xchan, FILTER_VALIDATE_URL)) { + if (filter_var($xchan, FILTER_VALIDATE_URL)) { $r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s' and hubloc_network in ('zot6', 'zot') and hubloc_deleted = 0", dbesc($xchan) ); -- cgit v1.2.3 From 4e9d8e1a8342d7ae603a3d6caf714ce8b43b00ac Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 Jan 2021 21:10:59 +0000 Subject: fix abandon days setting for onepoll --- Zotlabs/Daemon/Cron.php | 5 ----- Zotlabs/Daemon/Poller.php | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index e8fa3244f..cd7a710d3 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -170,11 +170,6 @@ class Cron { require_once('include/attach.php'); attach_upgrade(); - $abandon_days = intval(get_config('system', 'account_abandon_days')); - if ($abandon_days < 1) - $abandon_days = 0; - - // once daily run birthday_updates and then expire in background // FIXME: add birthday updates, both locally and for xprof for use diff --git a/Zotlabs/Daemon/Poller.php b/Zotlabs/Daemon/Poller.php index 8cbdfab0d..762f1349c 100644 --- a/Zotlabs/Daemon/Poller.php +++ b/Zotlabs/Daemon/Poller.php @@ -57,7 +57,7 @@ class Poller { reload_plugins(); // Only poll from those with suitable relationships - + $abandon_days = intval(get_config('system', 'account_abandon_days', 0)); $abandon_sql = (($abandon_days) ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days) . ' DAY')) : '' -- cgit v1.2.3 From 4da4f2367fe6d260709c02ec9750e03c61e7a31b Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 20 Jan 2021 13:18:48 +0100 Subject: Use Zot6 on pinned content sync between clones --- Zotlabs/Module/Pin.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Module/Pin.php b/Zotlabs/Module/Pin.php index 63b28754b..af949c0eb 100644 --- a/Zotlabs/Module/Pin.php +++ b/Zotlabs/Module/Pin.php @@ -6,8 +6,9 @@ namespace Zotlabs\Module; */ use App; +use Zotlabs\Lib\Libsync; -class Pin extends \Zotlabs\Web\Controller { +class Pin extends Zotlabs\Web\Controller { function init() { @@ -64,6 +65,6 @@ class Pin extends \Zotlabs\Web\Controller { http_status_exit(404, 'Not found'); } - build_sync_packet($r[0]['uid'], [ 'config' ]); + Libsync::build_sync_packet($r[0]['uid'], [ 'config' ]); } } -- cgit v1.2.3 From 15b2aa660ba99b7a17aa811041a40739f258672f Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 20 Jan 2021 13:53:09 +0100 Subject: Update Pin.php --- Zotlabs/Module/Pin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Pin.php b/Zotlabs/Module/Pin.php index af949c0eb..e02fb017b 100644 --- a/Zotlabs/Module/Pin.php +++ b/Zotlabs/Module/Pin.php @@ -8,7 +8,7 @@ namespace Zotlabs\Module; use App; use Zotlabs\Lib\Libsync; -class Pin extends Zotlabs\Web\Controller { +class Pin extends \Zotlabs\Web\Controller { function init() { -- cgit v1.2.3 From b242347fa1d41695edcdc378a2403b1621303da2 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 20 Jan 2021 20:17:50 +0000 Subject: onepoll via zot6 to /zotfeed which implements an outbox --- Zotlabs/Daemon/Externals.php | 2 +- Zotlabs/Daemon/Onepoll.php | 148 +++-- Zotlabs/Lib/ASCollection.php | 150 +++++ Zotlabs/Lib/Activity.php | 60 +- Zotlabs/Lib/Libzot.php | 1276 +++++++++++++++++++++--------------------- Zotlabs/Lib/ZotURL.php | 3 +- Zotlabs/Module/Zotfeed.php | 126 ++++- include/items.php | 20 +- include/network.php | 29 +- 9 files changed, 1086 insertions(+), 728 deletions(-) create mode 100644 Zotlabs/Lib/ASCollection.php diff --git a/Zotlabs/Daemon/Externals.php b/Zotlabs/Daemon/Externals.php index b657f9de4..3d6b0bd7b 100644 --- a/Zotlabs/Daemon/Externals.php +++ b/Zotlabs/Daemon/Externals.php @@ -82,7 +82,7 @@ class Externals { if ($j['success'] && $j['messages']) { $sys = get_sys_channel(); foreach ($j['messages'] as $message) { - // on these posts, clear any route info. + // on these posts, clear any route info. $message['route'] = ''; process_delivery(['hash' => 'undefined'], get_item_elements($message), [['hash' => $sys['xchan_hash']]], false, true); diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index 0228f10fb..568745608 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -2,13 +2,13 @@ namespace Zotlabs\Daemon; -use App; +use Zotlabs\Lib\Activity; +use Zotlabs\Lib\ActivityStreams; +use Zotlabs\Lib\ASCollection; use Zotlabs\Lib\Libzot; -require_once('include/zot.php'); require_once('include/socgraph.php'); - class Onepoll { static public function run($argc, $argv) { @@ -38,8 +38,7 @@ class Onepoll { return; } - $contact = $contacts[0]; - + $contact = array_shift($contacts); $importer_uid = $contact['abook_channel']; $r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", @@ -53,6 +52,7 @@ class Onepoll { logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}"); + // TODO: unused $last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] <= NULL_DATE)) ? datetime_convert('UTC', 'UTC', 'now - 7 days') : datetime_convert('UTC', 'UTC', $contact['abook_updated'] . ' - 2 days') @@ -103,80 +103,108 @@ class Onepoll { if (!$responded) return; - if ($contact['xchan_connurl']) { - $fetch_feed = true; - $x = null; + $fetch_feed = true; + $x = null; - // They haven't given us permission to see their stream + // They haven't given us permission to see their stream - $can_view_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'their_perms', 'view_stream')); + $can_view_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'their_perms', 'view_stream')); - if (!$can_view_stream) - $fetch_feed = false; + if (!$can_view_stream) + $fetch_feed = false; - // we haven't given them permission to send us their stream + // we haven't given them permission to send us their stream - $can_send_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'my_perms', 'send_stream')); + $can_send_stream = intval(get_abconfig($importer_uid, $contact['abook_xchan'], 'my_perms', 'send_stream')); - if (!$can_send_stream) - $fetch_feed = false; + if (!$can_send_stream) + $fetch_feed = false; - if ($fetch_feed) { + if ($fetch_feed) { - if (strpos($contact['xchan_connurl'], z_root()) === 0) { - // local channel - save a network fetch - $c = channelx_by_hash($contact['xchan_hash']); - if ($c) { - $x = [ - 'success' => true, - 'body' => json_encode([ - 'success' => true, - 'messages' => zot_feed($c['channel_id'], $importer['xchan_hash'], ['mindate' => $last_update]) - ]) - ]; - } + $max = intval(get_config('system', 'max_imported_posts', 30)); + + if (intval($max)) { + $cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections'); + + if (is_array($cl) && $cl) { + $url = ((array_key_exists('outbox', $cl)) ? $cl['outbox'] : ''); } else { - // remote fetch - - $feedurl = str_replace('/poco/', '/zotfeed/', $contact['xchan_connurl']); - $feedurl .= '?f=&mindate=' . urlencode($last_update) . '&zid=' . $importer['channel_address'] . '@' . App::get_hostname(); - $recurse = 0; - $x = z_fetch_url($feedurl, false, $recurse, ['session' => true]); + $url = str_replace('/poco/', '/zotfeed/', $contact['xchan_connurl']); } - logger('feed_update: ' . print_r($x, true), LOGGER_DATA); - } - - if (($x) && ($x['success'])) { - $total = 0; - logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl); - - $j = json_decode($x['body'], true); - if ($j['success'] && $j['messages']) { - foreach ($j['messages'] as $message) { - $results = process_delivery(['hash' => $contact['xchan_hash']], get_item_elements($message), - [['hash' => $importer['xchan_hash']]], false); - logger('onepoll: feed_update: process_delivery: ' . print_r($results, true), LOGGER_DATA); - $total++; + if ($url) { + logger('fetching outbox'); + $obj = new ASCollection($url, $importer, 0, $max); + $messages = $obj->get(); + if ($messages) { + foreach ($messages as $message) { + if (is_string($message)) { + $message = Activity::fetch($message, $importer); + } + $AS = new ActivityStreams($message); + if ($AS->is_valid() && is_array($AS->obj)) { + $item = Activity::decode_note($AS); + Activity::store($importer, $contact['abook_xchan'], $AS, $item); + } + } } - logger("onepoll: $total messages processed"); } } } + /* if ($fetch_feed) { + + if (strpos($contact['xchan_connurl'], z_root()) === 0) { + // local channel - save a network fetch + $c = channelx_by_hash($contact['xchan_hash']); + if ($c) { + $x = [ + 'success' => true, + 'body' => json_encode([ + 'success' => true, + 'messages' => zot_feed($c['channel_id'], $importer['xchan_hash'], ['mindate' => $last_update]) + ]) + ]; + } + } + else { + // remote fetch + + $feedurl = str_replace('/poco/', '/zotfeed/', $contact['xchan_connurl']); + $feedurl .= '?f=&mindate=' . urlencode($last_update) . '&zid=' . $importer['channel_address'] . '@' . App::get_hostname(); + $recurse = 0; + $x = z_fetch_url($feedurl, false, $recurse, ['session' => true]); + } + + logger('feed_update: ' . print_r($x, true), LOGGER_DATA); + } - // update the poco details for this connection + if (($x) && ($x['success'])) { + $total = 0; + logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl); + + $j = json_decode($x['body'], true); + if ($j['success'] && $j['messages']) { + foreach ($j['messages'] as $message) { + $results = process_delivery(['hash' => $contact['xchan_hash']], get_item_elements($message), + [['hash' => $importer['xchan_hash']]], false); + logger('onepoll: feed_update: process_delivery: ' . print_r($results, true), LOGGER_DATA); + $total++; + } + logger("onepoll: $total messages processed"); + } + } + */ - if ($contact['xchan_connurl']) { - $r = q("SELECT xlink_id from xlink - where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1", - intval($contact['xchan_hash']), - db_utcnow(), db_quoteinterval('1 DAY') - ); - if (!$r) { - poco_load($contact['xchan_hash'], $contact['xchan_connurl']); - } + // update the poco details for this connection + $r = q("SELECT xlink_id from xlink where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1", + intval($contact['xchan_hash']), + db_utcnow(), db_quoteinterval('1 DAY') + ); + if (!$r) { + poco_load($contact['xchan_hash'], $contact['xchan_connurl']); } return; diff --git a/Zotlabs/Lib/ASCollection.php b/Zotlabs/Lib/ASCollection.php new file mode 100644 index 000000000..392dd5d4e --- /dev/null +++ b/Zotlabs/Lib/ASCollection.php @@ -0,0 +1,150 @@ +get() to return an array of collection members. + */ +class ASCollection { + + private $channel = null; + private $nextpage = null; + private $limit = 0; + private $direction = 0; // 0 = forward, 1 = reverse + private $data = []; + private $history = []; + + function __construct($obj, $channel = null, $direction = 0, $limit = 0) { + + $this->channel = $channel; + $this->direction = $direction; + $this->limit = $limit; + + if (is_array($obj)) { + $data = $obj; + } + + if (is_string($obj)) { + $data = Activity::fetch($obj, $channel); + $this->history[] = $obj; + } + + if (!is_array($data)) { + return; + } + + if (!in_array($data['type'], ['Collection', 'OrderedCollection', 'OrderedCollectionPage'])) { + return false; + } + + if ($this->direction) { + if (array_key_exists('last', $data) && $data['last']) { + $this->nextpage = $data['last']; + } + } + else { + if (array_key_exists('first', $data) && $data['first']) { + $this->nextpage = $data['first']; + } + } + + if (isset($data['items']) && is_array($data['items'])) { + $this->data = (($this->direction) ? array_reverse($data['items']) : $data['items']); + } + elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) { + $this->data = (($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems']); + } + + if ($this->limit) { + if (count($this->data) > $limit) { + $this->data = array_slice($this->data, 0, $limit); + return; + } + } + + do { + $x = $this->next(); + } while ($x); + } + + function get() { + return $this->data; + } + + function next() { + + if (!$this->nextpage) { + return false; + } + + if (is_array($this->nextpage)) { + $data = $this->nextpage; + } + + if (is_string($this->nextpage)) { + if (in_array($this->nextpage, $this->history)) { + // recursion detected + return false; + } + $data = Activity::fetch($this->nextpage, $this->channel); + $this->history[] = $this->nextpage; + } + + if (!is_array($data)) { + return false; + } + + if (!in_array($data['type'], ['CollectionPage', 'OrderedCollectionPage'])) { + return false; + } + + $this->setnext($data); + + if (isset($data['items']) && is_array($data['items'])) { + $this->data = array_merge($this->data, (($this->direction) ? array_reverse($data['items']) : $data['items'])); + } + elseif (isset($data['orderedItems']) && is_array($data['orderedItems'])) { + $this->data = array_merge($this->data, (($this->direction) ? array_reverse($data['orderedItems']) : $data['orderedItems'])); + } + + if ($this->limit) { + if (count($this->data) > $this->limit) { + $this->data = array_slice($this->data, 0, $this->limit); + $this->nextpage = false; + return true; + } + } + + return true; + } + + function setnext($data) { + if ($this->direction) { + if (array_key_exists('prev', $data) && $data['prev']) { + $this->nextpage = $data['prev']; + } + elseif (array_key_exists('first', $data) && $data['first']) { + $this->nextpage = $data['first']; + } + else { + $this->nextpage = false; + } + } + else { + if (array_key_exists('next', $data) && $data['next']) { + $this->nextpage = $data['next']; + } + elseif (array_key_exists('last', $data) && $data['last']) { + $this->nextpage = $data['last']; + } + else { + $this->nextpage = false; + } + } + logger('nextpage: ' . $this->nextpage, LOGGER_DEBUG); + } +} \ No newline at end of file diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 216dfab1a..0f9160bf7 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2,6 +2,7 @@ namespace Zotlabs\Lib; +use App; use Zotlabs\Access\PermissionLimits; use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\Permissions; @@ -246,28 +247,69 @@ class Activity { } - - static function encode_item_collection($items, $id, $type, $extra = null) { + static function paged_collection_init($total, $id, $type = 'OrderedCollection') { $ret = [ 'id' => z_root() . '/' . $id, 'type' => $type, - 'totalItems' => count($items), + 'totalItems' => $total, ]; - if ($extra) - $ret = array_merge($ret, $extra); + + $numpages = $total / App::$pager['itemspage']; + $lastpage = (($numpages > intval($numpages)) ? intval($numpages) + 1 : $numpages); + + $ret['first'] = z_root() . '/' . App::$query_string . '?page=1'; + $ret['last'] = z_root() . '/' . App::$query_string . '?page=' . $lastpage; + + return $ret; + + } + + static function encode_item_collection($items, $id, $type, $total = 0) { + + if ($total > 100) { + $ret = [ + 'id' => z_root() . '/' . $id, + 'type' => $type . 'Page', + ]; + + $numpages = $total / App::$pager['itemspage']; + $lastpage = (($numpages > intval($numpages)) ? intval($numpages) + 1 : $numpages); + + $stripped = preg_replace('/([&|\?]page=[0-9]*)/', '', $id); + $stripped = rtrim($stripped, '/'); + + $ret['partOf'] = z_root() . '/' . $stripped; + + if (App::$pager['page'] < $lastpage) { + $ret['next'] = z_root() . '/' . $stripped . '?page=' . (intval(App::$pager['page']) + 1); + } + if (App::$pager['page'] > 1) { + $ret['prev'] = z_root() . '/' . $stripped . '?page=' . (intval(App::$pager['page']) - 1); + } + } + else { + $ret = [ + 'id' => z_root() . '/' . $id, + 'type' => $type, + 'totalItems' => $total, + ]; + } if ($items) { $x = []; foreach ($items as $i) { - $t = self::encode_activity($i); - if ($t) + $t = ((get_iconfig($i['id'], 'activitypub', 'rawmsg')) ? get_iconfig($i['id'], 'activitypub', 'rawmsg') : self::encode_activity($i)); + if ($t) { $x[] = $t; + } } - if ($type === 'OrderedCollection') + if ($type === 'OrderedCollection') { $ret['orderedItems'] = $x; - else + } + else { $ret['items'] = $x; + } } return $ret; diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index cde4c0145..8847f0975 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -34,7 +34,7 @@ class Libzot { */ static function new_uid($channel_nick) { $rawstr = z_root() . '/' . $channel_nick . '.' . mt_rand(); - return(base64url_encode(hash('whirlpool', $rawstr, true), true)); + return (base64url_encode(hash('whirlpool', $rawstr, true), true)); } @@ -100,13 +100,13 @@ class Libzot { */ static function build_packet($channel, $type = 'activity', $recipients = null, $msg = [], $encoding = 'activitystreams', $remote_key = null, $methods = '') { - $sig_method = get_config('system','signature_algorithm','sha256'); + $sig_method = get_config('system', 'signature_algorithm', 'sha256'); $data = [ 'type' => $type, 'encoding' => $encoding, 'sender' => $channel['channel_hash'], - 'site_id' => self::make_xchan_hash(z_root(), get_config('system','pubkey')), + 'site_id' => self::make_xchan_hash(z_root(), get_config('system', 'pubkey')), 'version' => System::get_zot_revision(), ]; @@ -116,8 +116,8 @@ class Libzot { if ($msg) { $actor = channel_url($channel); - if ($encoding === 'activitystreams' && array_key_exists('actor',$msg) && is_string($msg['actor']) && $actor === $msg['actor']) { - $msg = JSalmon::sign($msg,$actor,$channel['channel_prvkey']); + if ($encoding === 'activitystreams' && array_key_exists('actor', $msg) && is_string($msg['actor']) && $actor === $msg['actor']) { + $msg = JSalmon::sign($msg, $actor, $channel['channel_prvkey']); } $data['data'] = $msg; } @@ -125,12 +125,12 @@ class Libzot { unset($data['encoding']); } - logger('packet: ' . print_r($data,true), LOGGER_DATA, LOG_DEBUG); + logger('packet: ' . print_r($data, true), LOGGER_DATA, LOG_DEBUG); if ($remote_key) { $algorithm = self::best_algorithm($methods); if ($algorithm) { - $data = crypto_encapsulate(json_encode($data),$remote_key, $algorithm); + $data = crypto_encapsulate(json_encode($data), $remote_key, $algorithm); } } @@ -150,7 +150,7 @@ class Libzot { $x = [ 'methods' => $methods, - 'result' => '' + 'result' => '' ]; /** @@ -161,18 +161,18 @@ class Libzot { */ call_hooks('zot_best_algorithm', $x); - if($x['result']) + if ($x['result']) return $x['result']; - if($methods) { + if ($methods) { $x = explode(',', $methods); - if($x) { + if ($x) { $y = crypto_methods(); - if($y) { - foreach($y as $yv) { + if ($y) { + foreach ($y as $yv) { $yv = trim($yv); - if(in_array($yv, $x)) { - return($yv); + if (in_array($yv, $x)) { + return ($yv); } } } @@ -186,17 +186,17 @@ class Libzot { /** * @brief Send a zot message. * - * @see z_post_url() - * * @param string $url * @param string $data * @param array $channel (required if using zot6 delivery) * @param array $crypto (required if encrypted httpsig, requires hubloc_sitekey and site_crypto elements) * @return array see z_post_url() for returned data format + * @see z_post_url() + * */ - static function zot($url, $data, $channel = null,$crypto = null) { + static function zot($url, $data, $channel = null, $crypto = null) { - if($channel) { + if ($channel) { $headers = [ 'X-Zot-Token' => random_string(), 'Digest' => HTTPSig::generate_digest_header($data), @@ -204,8 +204,8 @@ class Libzot { '(request-target)' => 'post ' . get_request_string($url) ]; - $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false,'sha512', - (($crypto) ? [ 'key' => $crypto['hubloc_sitekey'], 'algorithm' => self::best_algorithm($crypto['site_crypto']) ] : false)); + $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), false, 'sha512', + (($crypto) ? ['key' => $crypto['hubloc_sitekey'], 'algorithm' => self::best_algorithm($crypto['site_crypto'])] : false)); } else { $h = []; @@ -213,7 +213,7 @@ class Libzot { $redirects = 0; - return z_post_url($url,$data,$redirects,((empty($h)) ? [] : [ 'headers' => $h ])); + return z_post_url($url, $data, $redirects, ((empty($h)) ? [] : ['headers' => $h])); } @@ -245,9 +245,9 @@ class Libzot { */ static function refresh($them, $channel = null, $force = false) { - logger('them: ' . print_r($them,true), LOGGER_DATA, LOG_DEBUG); + logger('them: ' . print_r($them, true), LOGGER_DATA, LOG_DEBUG); if ($channel) - logger('channel: ' . print_r($channel,true), LOGGER_DATA, LOG_DEBUG); + logger('channel: ' . print_r($channel, true), LOGGER_DATA, LOG_DEBUG); $url = null; @@ -261,12 +261,12 @@ class Libzot { // We'll order by reverse id to try and pick off the newest one first and hopefully end up with the // correct hubloc. If this doesn't work we may have to re-write this section to try them all. - if(array_key_exists('xchan_addr',$them) && $them['xchan_addr']) { + if (array_key_exists('xchan_addr', $them) && $them['xchan_addr']) { $r = q("select hubloc_id_url, hubloc_primary from hubloc where hubloc_addr = '%s' and hubloc_network = 'zot6' order by hubloc_id desc", dbesc($them['xchan_addr']) ); } - if(! $r) { + if (!$r) { $r = q("select hubloc_id_url, hubloc_primary from hubloc where hubloc_hash = '%s' order by hubloc_id desc", dbesc($them['xchan_hash']) ); @@ -275,16 +275,16 @@ class Libzot { if ($r) { foreach ($r as $rr) { if (intval($rr['hubloc_primary'])) { - $url = $rr['hubloc_id_url']; + $url = $rr['hubloc_id_url']; $record = $rr; } } - if (! $url) { + if (!$url) { $url = $r[0]['hubloc_id_url']; } } } - if (! $url) { + if (!$url) { logger('zot_refresh: no url'); return false; } @@ -293,64 +293,64 @@ class Libzot { dbesc($url) ); - if($s && intval($s[0]['site_dead']) && (! $force)) { + if ($s && intval($s[0]['site_dead']) && (!$force)) { logger('zot_refresh: site ' . $url . ' is marked dead and force flag is not set. Cancelling operation.'); return false; } - $record = Zotfinger::exec($url,$channel); + $record = Zotfinger::exec($url, $channel); // Check the HTTP signature $hsig = $record['signature']; - if($hsig && $hsig['signer'] === $url && $hsig['header_valid'] === true && $hsig['content_valid'] === true) + if ($hsig && $hsig['signer'] === $url && $hsig['header_valid'] === true && $hsig['content_valid'] === true) $hsig_valid = true; - if(! $hsig_valid) { - logger('http signature not valid: ' . print_r($hsig,true)); + if (!$hsig_valid) { + logger('http signature not valid: ' . print_r($hsig, true)); return false; } - logger('zot-info: ' . print_r($record,true), LOGGER_DATA, LOG_DEBUG); + logger('zot-info: ' . print_r($record, true), LOGGER_DATA, LOG_DEBUG); $x = self::import_xchan($record['data'], (($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED)); - if(! $x['success']) + if (!$x['success']) return false; - if($channel && $record['data']['permissions']) { - $permissions = explode(',',$record['data']['permissions']); + if ($channel && $record['data']['permissions']) { + $permissions = explode(',', $record['data']['permissions']); - if($permissions && is_array($permissions)) { - $old_read_stream_perm = get_abconfig($channel['channel_id'],$x['hash'],'their_perms','view_stream'); + if ($permissions && is_array($permissions)) { + $old_read_stream_perm = get_abconfig($channel['channel_id'], $x['hash'], 'their_perms', 'view_stream'); $permissions = Permissions::FilledPerms($permissions); - foreach($permissions as $k => $v) { - set_abconfig($channel['channel_id'],$x['hash'],'their_perms',$k,$v); + foreach ($permissions as $k => $v) { + set_abconfig($channel['channel_id'], $x['hash'], 'their_perms', $k, $v); } } - if(array_key_exists('profile',$record['data']) && array_key_exists('next_birthday',$record['data']['profile'])) { - $next_birthday = datetime_convert('UTC','UTC',$record['data']['profile']['next_birthday']); + if (array_key_exists('profile', $record['data']) && array_key_exists('next_birthday', $record['data']['profile'])) { + $next_birthday = datetime_convert('UTC', 'UTC', $record['data']['profile']['next_birthday']); } else { $next_birthday = NULL_DATE; } - $profile_assign = get_pconfig($channel['channel_id'],'system','profile_assign',''); + $profile_assign = get_pconfig($channel['channel_id'], 'system', 'profile_assign', ''); // Keep original perms to check if we need to notify them - $previous_perms = get_all_perms($channel['channel_id'],$x['hash']); + $previous_perms = get_all_perms($channel['channel_id'], $x['hash']); $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc($x['hash']), intval($channel['channel_id']) ); - if($r) { + if ($r) { // connection exists @@ -358,7 +358,7 @@ class Libzot { // we have as we may have updated the year after sending a notification; and resetting // to the one we just received would cause us to create duplicated events. - if(substr($r[0]['abook_dob'],5) == substr($next_birthday,5)) + if (substr($r[0]['abook_dob'], 5) == substr($next_birthday, 5)) $next_birthday = $r[0]['abook_dob']; $y = q("update abook set abook_dob = '%s' @@ -369,30 +369,30 @@ class Libzot { intval($channel['channel_id']) ); - if(! $y) + if (!$y) logger('abook update failed'); else { // if we were just granted read stream permission and didn't have it before, try to pull in some posts - if((! $old_read_stream_perm) && (intval($permissions['view_stream']))) - Master::Summon([ 'Onepoll', $r[0]['abook_id'] ]); + if ((!$old_read_stream_perm) && (intval($permissions['view_stream']))) + Master::Summon(['Onepoll', $r[0]['abook_id']]); } } else { - $p = Permissions::connect_perms($channel['channel_id']); + $p = Permissions::connect_perms($channel['channel_id']); $my_perms = $p['perms']; $automatic = $p['automatic']; // new connection - if($my_perms) { - foreach($my_perms as $k => $v) { - set_abconfig($channel['channel_id'],$x['hash'],'my_perms',$k,$v); + if ($my_perms) { + foreach ($my_perms as $k => $v) { + set_abconfig($channel['channel_id'], $x['hash'], 'my_perms', $k, $v); } } - $closeness = get_pconfig($channel['channel_id'],'system','new_abook_closeness',80); + $closeness = get_pconfig($channel['channel_id'], 'system', 'new_abook_closeness', 80); $y = abook_store_lowlevel( [ @@ -408,9 +408,9 @@ class Libzot { ] ); - if($y) { + if ($y) { logger("New introduction received for {$channel['channel_name']}"); - $new_perms = get_all_perms($channel['channel_id'],$x['hash'],false); + $new_perms = get_all_perms($channel['channel_id'], $x['hash'], false); // Send a clone sync packet and a permissions update if permissions have changed @@ -419,45 +419,45 @@ class Libzot { intval($channel['channel_id']) ); - if($new_connection) { - if(! Permissions::PermsCompare($new_perms,$previous_perms)) - Master::Summon([ 'Notifier', 'permission_create', $new_connection[0]['abook_id'] ]); + if ($new_connection) { + if (!Permissions::PermsCompare($new_perms, $previous_perms)) + Master::Summon(['Notifier', 'permission_create', $new_connection[0]['abook_id']]); Enotify::submit( [ - 'type' => NOTIFY_INTRO, - 'from_xchan' => $x['hash'], - 'to_xchan' => $channel['channel_hash'], - 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'] + 'type' => NOTIFY_INTRO, + 'from_xchan' => $x['hash'], + 'to_xchan' => $channel['channel_hash'], + 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'] ] ); - if(intval($permissions['view_stream'])) { - if(intval(get_pconfig($channel['channel_id'],'perm_limits','send_stream') & PERMS_PENDING) - || (! intval($new_connection[0]['abook_pending']))) - Master::Summon([ 'Onepoll', $new_connection[0]['abook_id'] ]); + if (intval($permissions['view_stream'])) { + if (intval(get_pconfig($channel['channel_id'], 'perm_limits', 'send_stream') & PERMS_PENDING) + || (!intval($new_connection[0]['abook_pending']))) + Master::Summon(['Onepoll', $new_connection[0]['abook_id']]); } // If there is a default group for this channel, add this connection to it // for pending connections this will happens at acceptance time. - if(! intval($new_connection[0]['abook_pending'])) { + if (!intval($new_connection[0]['abook_pending'])) { $default_group = $channel['channel_default_group']; - if($default_group) { - $g = Group::rec_byhash($channel['channel_id'],$default_group); - if($g) - Group::member_add($channel['channel_id'],'',$x['hash'],$g['id']); + if ($default_group) { + $g = Group::rec_byhash($channel['channel_id'], $default_group); + if ($g) + Group::member_add($channel['channel_id'], '', $x['hash'], $g['id']); } } unset($new_connection[0]['abook_id']); unset($new_connection[0]['abook_account']); unset($new_connection[0]['abook_channel']); - $abconfig = load_abconfig($channel['channel_id'],$new_connection['abook_xchan']); - if($abconfig) + $abconfig = load_abconfig($channel['channel_id'], $new_connection['abook_xchan']); + if ($abconfig) $new_connection['abconfig'] = $abconfig; - Libsync::build_sync_packet($channel['channel_id'], array('abook' => $new_connection)); + Libsync::build_sync_packet($channel['channel_id'], ['abook' => $new_connection]); } } @@ -489,9 +489,9 @@ class Libzot { static function gethub($arr, $multiple = false) { - if($arr['id'] && $arr['id_sig'] && $arr['location'] && $arr['location_sig']) { + if ($arr['id'] && $arr['id_sig'] && $arr['location'] && $arr['location_sig']) { - if(! check_siteallowed($arr['location'])) { + if (!check_siteallowed($arr['location'])) { logger('blacklisted site: ' . $arr['location']); return null; } @@ -509,12 +509,12 @@ class Libzot { dbesc($arr['location_sig']), dbesc($arr['site_id']) ); - if($r) { + if ($r) { logger('Found', LOGGER_DEBUG); return (($multiple) ? $r : $r[0]); } } - logger('Not found: ' . print_r($arr,true), LOGGER_DEBUG); + logger('Not found: ' . print_r($arr, true), LOGGER_DEBUG); return false; } @@ -532,16 +532,16 @@ class Libzot { dbesc($sender), dbesc($site_id) ); - if(! $r) { + if (!$r) { return null; } - if(! check_siteallowed($r[0]['hubloc_url'])) { + if (!check_siteallowed($r[0]['hubloc_url'])) { logger('blacklisted site: ' . $r[0]['hubloc_url']); return null; } - if(! check_channelallowed($r[0]['hubloc_hash'])) { + if (!check_channelallowed($r[0]['hubloc_hash'])) { logger('blacklisted channel: ' . $r[0]['hubloc_hash']); return null; } @@ -567,9 +567,9 @@ class Libzot { $hsig_valid = false; - $result = [ 'success' => false ]; + $result = ['success' => false]; - if(! $id) { + if (!$id) { return $result; } @@ -578,16 +578,16 @@ class Libzot { // Check the HTTP signature $hsig = $record['signature']; - if($hsig['signer'] === $id && $hsig['header_valid'] === true && $hsig['content_valid'] === true) { + if ($hsig['signer'] === $id && $hsig['header_valid'] === true && $hsig['content_valid'] === true) { $hsig_valid = true; } - if(! $hsig_valid) { - logger('http signature not valid: ' . print_r($hsig,true)); + if (!$hsig_valid) { + logger('http signature not valid: ' . print_r($hsig, true)); return $result; } $c = self::import_xchan($record['data']); - if($c['success']) { + if ($c['success']) { $result['success'] = true; } else { @@ -625,26 +625,26 @@ class Libzot { */ call_hooks('import_xchan', $arr); - $ret = array('success' => false); - $dirmode = intval(get_config('system','directory_mode')); + $ret = ['success' => false]; + $dirmode = intval(get_config('system', 'directory_mode')); $changed = false; - $what = ''; + $what = ''; - if(! ($arr['id'] && $arr['id_sig'])) { - logger('No identity information provided. ' . print_r($arr,true)); + if (!($arr['id'] && $arr['id_sig'])) { + logger('No identity information provided. ' . print_r($arr, true)); return $ret; } - $xchan_hash = self::make_xchan_hash($arr['id'],$arr['public_key']); + $xchan_hash = self::make_xchan_hash($arr['id'], $arr['public_key']); $arr['hash'] = $xchan_hash; $import_photos = false; - $sig_methods = ((array_key_exists('signing',$arr) && is_array($arr['signing'])) ? $arr['signing'] : [ 'sha256' ]); - $verified = false; + $sig_methods = ((array_key_exists('signing', $arr) && is_array($arr['signing'])) ? $arr['signing'] : ['sha256']); + $verified = false; - if(! self::verify($arr['id'],$arr['id_sig'],$arr['public_key'])) { + if (!self::verify($arr['id'], $arr['id_sig'], $arr['public_key'])) { logger('Unable to verify channel signature for ' . $arr['address']); return $ret; } @@ -652,7 +652,7 @@ class Libzot { $verified = true; } - if(! $verified) { + if (!$verified) { $ret['message'] = t('Unable to verify channel signature'); return $ret; } @@ -663,40 +663,40 @@ class Libzot { dbesc($xchan_hash) ); - if(! array_key_exists('connect_url', $arr)) + if (!array_key_exists('connect_url', $arr)) $arr['connect_url'] = ''; - if($r) { - if($arr['photo'] && array_key_exists('updated',$arr['photo']) && $r[0]['xchan_photo_date'] != $arr['photo']['updated']) { + if ($r) { + if ($arr['photo'] && array_key_exists('updated', $arr['photo']) && $r[0]['xchan_photo_date'] != $arr['photo']['updated']) { $import_photos = true; } // if we import an entry from a site that's not ours and either or both of us is off the grid - hide the entry. /** @TODO: check if we're the same directory realm, which would mean we are allowed to see it */ - $dirmode = get_config('system','directory_mode'); + $dirmode = get_config('system', 'directory_mode'); - if((($arr['site']['directory_mode'] === 'standalone') || ($dirmode & DIRECTORY_MODE_STANDALONE)) && ($arr['site']['url'] != z_root())) + if ((($arr['site']['directory_mode'] === 'standalone') || ($dirmode & DIRECTORY_MODE_STANDALONE)) && ($arr['site']['url'] != z_root())) $arr['searchable'] = false; $hidden = (1 - intval($arr['searchable'])); $hidden_changed = $adult_changed = $deleted_changed = $pubforum_changed = 0; - if(intval($r[0]['xchan_hidden']) != (1 - intval($arr['searchable']))) + if (intval($r[0]['xchan_hidden']) != (1 - intval($arr['searchable']))) $hidden_changed = 1; - if(intval($r[0]['xchan_selfcensored']) != intval($arr['adult_content'])) + if (intval($r[0]['xchan_selfcensored']) != intval($arr['adult_content'])) $adult_changed = 1; - if(intval($r[0]['xchan_deleted']) != intval($arr['deleted'])) + if (intval($r[0]['xchan_deleted']) != intval($arr['deleted'])) $deleted_changed = 1; // new style 6-MAR-2019 - if(array_key_exists('channel_type',$arr)) { - if($arr['channel_type'] === 'collection') { + if (array_key_exists('channel_type', $arr)) { + if ($arr['channel_type'] === 'collection') { // do nothing at this time. } - elseif($arr['channel_type'] === 'group') { + elseif ($arr['channel_type'] === 'group') { $arr['public_forum'] = 1; } else { @@ -706,27 +706,27 @@ class Libzot { // old style - if(intval($r[0]['xchan_pubforum']) != intval($arr['public_forum'])) + if (intval($r[0]['xchan_pubforum']) != intval($arr['public_forum'])) $pubforum_changed = 1; - if($arr['protocols']) { - $protocols = implode(',',$arr['protocols']); - if($protocols !== 'zot6') { - set_xconfig($xchan_hash,'system','protocols',$protocols); + if ($arr['protocols']) { + $protocols = implode(',', $arr['protocols']); + if ($protocols !== 'zot6') { + set_xconfig($xchan_hash, 'system', 'protocols', $protocols); } else { - del_xconfig($xchan_hash,'system','protocols'); + del_xconfig($xchan_hash, 'system', 'protocols'); } } - if(($r[0]['xchan_name_date'] != $arr['name_updated']) + if (($r[0]['xchan_name_date'] != $arr['name_updated']) || ($r[0]['xchan_connurl'] != $arr['primary_location']['connections_url']) || ($r[0]['xchan_addr'] != $arr['primary_location']['address']) || ($r[0]['xchan_follow'] != $arr['primary_location']['follow_url']) || ($r[0]['xchan_connpage'] != $arr['connect_url']) || ($r[0]['xchan_url'] != $arr['primary_location']['url']) - || $hidden_changed || $adult_changed || $deleted_changed || $pubforum_changed ) { + || $hidden_changed || $adult_changed || $deleted_changed || $pubforum_changed) { $rup = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s', xchan_connpage = '%s', xchan_hidden = %d, xchan_selfcensored = %d, xchan_deleted = %d, xchan_pubforum = %d, xchan_addr = '%s', xchan_url = '%s' where xchan_hash = '%s'", @@ -744,18 +744,18 @@ class Libzot { dbesc($xchan_hash) ); - logger('Update: existing: ' . print_r($r[0],true), LOGGER_DATA, LOG_DEBUG); - logger('Update: new: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG); - $what .= 'xchan '; + logger('Update: existing: ' . print_r($r[0], true), LOGGER_DATA, LOG_DEBUG); + logger('Update: new: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); + $what .= 'xchan '; $changed = true; } } else { $import_photos = true; - if((($arr['site']['directory_mode'] === 'standalone') + if ((($arr['site']['directory_mode'] === 'standalone') || ($dirmode & DIRECTORY_MODE_STANDALONE)) - && ($arr['site']['url'] != z_root())) + && ($arr['site']['url'] != z_root())) $arr['searchable'] = false; $x = xchan_store_lowlevel( @@ -782,11 +782,11 @@ class Libzot { ] ); - $what .= 'new_xchan'; + $what .= 'new_xchan'; $changed = true; } - if($import_photos) { + if ($import_photos) { require_once('include/photo/photo_driver.php'); @@ -795,13 +795,13 @@ class Libzot { $local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1", dbesc($xchan_hash) ); - if($local) { + if ($local) { $ph = z_fetch_url($arr['photo']['url'], true); - if($ph['success']) { + if ($ph['success']) { $hash = import_channel_photo($ph['body'], $arr['photo']['type'], $local[0]['channel_account_id'], $local[0]['channel_id']); - if($hash) { + if ($hash) { // unless proven otherwise $is_default_profile = 1; @@ -809,13 +809,13 @@ class Libzot { intval($local[0]['channel_account_id']), intval($local[0]['channel_id']) ); - if($profile) { - if(! intval($profile[0]['is_default'])) + if ($profile) { + if (!intval($profile[0]['is_default'])) $is_default_profile = 0; } // If setting for the default profile, unset the profile photo flag from any other photos I own - if($is_default_profile) { + if ($is_default_profile) { q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), @@ -827,20 +827,20 @@ class Libzot { } // reset the names in case they got messed up when we had a bug in this function - $photos = array( + $photos = [ z_root() . '/photo/profile/l/' . $local[0]['channel_id'], z_root() . '/photo/profile/m/' . $local[0]['channel_id'], z_root() . '/photo/profile/s/' . $local[0]['channel_id'], $arr['photo_mimetype'], false - ); + ]; } } else { $photos = import_xchan_photo($arr['photo']['url'], $xchan_hash); } - if($photos) { - if($photos[4]) { + if ($photos) { + if ($photos[4]) { // importing the photo failed somehow. Leave the photo_date alone so we can try again at a later date. // This often happens when somebody joins the matrix with a bad cert. $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' @@ -855,7 +855,7 @@ class Libzot { else { $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", - dbescdate(datetime_convert('UTC','UTC',$arr['photo_updated'])), + dbescdate(datetime_convert('UTC', 'UTC', $arr['photo_updated'])), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), @@ -863,7 +863,7 @@ class Libzot { dbesc($xchan_hash) ); } - $what .= 'photo '; + $what .= 'photo '; $changed = true; } } @@ -873,12 +873,12 @@ class Libzot { $s = Libsync::sync_locations($arr, $arr); - if($s) { - if($s['change_message']) + if ($s) { + if ($s['change_message']) $what .= $s['change_message']; - if($s['changed']) + if ($s['changed']) $changed = $s['changed']; - if($s['message']) + if ($s['message']) $ret['message'] .= $s['message']; } @@ -890,24 +890,24 @@ class Libzot { // Are we a directory server of some kind? $other_realm = false; - $realm = get_directory_realm(); - if(array_key_exists('site',$arr) - && array_key_exists('realm',$arr['site']) - && (strpos($arr['site']['realm'],$realm) === false)) + $realm = get_directory_realm(); + if (array_key_exists('site', $arr) + && array_key_exists('realm', $arr['site']) + && (strpos($arr['site']['realm'], $realm) === false)) $other_realm = true; - if($dirmode != DIRECTORY_MODE_NORMAL) { + if ($dirmode != DIRECTORY_MODE_NORMAL) { // We're some kind of directory server. However we can only add directory information // if the entry is in the same realm (or is a sub-realm). Sub-realms are denoted by // including the parent realm in the name. e.g. 'RED_GLOBAL:foo' would allow an entry to // be in directories for the local realm (foo) and also the RED_GLOBAL realm. - if(array_key_exists('profile',$arr) && is_array($arr['profile']) && (! $other_realm)) { - $profile_changed = Libzotdir::import_directory_profile($xchan_hash,$arr['profile'],$address,$ud_flags, 1); - if($profile_changed) { - $what .= 'profile '; + if (array_key_exists('profile', $arr) && is_array($arr['profile']) && (!$other_realm)) { + $profile_changed = Libzotdir::import_directory_profile($xchan_hash, $arr['profile'], $address, $ud_flags, 1); + if ($profile_changed) { + $what .= 'profile '; $changed = true; } } @@ -923,20 +923,20 @@ class Libzot { } } - if(array_key_exists('site',$arr) && is_array($arr['site'])) { + if (array_key_exists('site', $arr) && is_array($arr['site'])) { $profile_changed = self::import_site($arr['site']); - if($profile_changed) { - $what .= 'site '; + if ($profile_changed) { + $what .= 'site '; $changed = true; } } - if(($changed) || ($ud_flags == UPDATE_FLAGS_FORCED)) { + if (($changed) || ($ud_flags == UPDATE_FLAGS_FORCED)) { $guid = random_string() . '@' . \App::get_hostname(); - Libzotdir::update_modtime($xchan_hash,$guid,$address,$ud_flags); - logger('Changed: ' . $what,LOGGER_DEBUG); + Libzotdir::update_modtime($xchan_hash, $guid, $address, $ud_flags); + logger('Changed: ' . $what, LOGGER_DEBUG); } - elseif(! $ud_flags) { + elseif (!$ud_flags) { // nothing changed but we still need to update the updates record q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d) > 0 ", intval(UPDATE_FLAGS_UPDATED), @@ -945,12 +945,12 @@ class Libzot { ); } - if(! x($ret,'message')) { + if (!x($ret, 'message')) { $ret['success'] = true; - $ret['hash'] = $xchan_hash; + $ret['hash'] = $xchan_hash; } - logger('Result: ' . print_r($ret,true), LOGGER_DATA, LOG_DEBUG); + logger('Result: ' . print_r($ret, true), LOGGER_DATA, LOG_DEBUG); return $ret; } @@ -967,32 +967,32 @@ class Libzot { */ static function process_response($hub, $arr, $outq) { - logger('remote: ' . print_r($arr,true),LOGGER_DATA); + logger('remote: ' . print_r($arr, true), LOGGER_DATA); - if(! $arr['success']) { + if (!$arr['success']) { logger('Failed: ' . $hub); return; } $x = json_decode($arr['body'], true); - if(! $x) { + if (!$x) { logger('No json from ' . $hub); logger('Headers: ' . print_r($arr['header'], true), LOGGER_DATA, LOG_DEBUG); } - $x = crypto_unencapsulate($x, get_config('system','prvkey')); + $x = crypto_unencapsulate($x, get_config('system', 'prvkey')); - if(! is_array($x)) { - $x = json_decode($x,true); + if (!is_array($x)) { + $x = json_decode($x, true); } - if(! is_array($x)) { + if (!is_array($x)) { btlogger('failed communication - no response'); } - if($x) { - if(! $x['success']) { + if ($x) { + if (!$x['success']) { // handle remote validation issues @@ -1003,18 +1003,18 @@ class Libzot { ); } - if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) { + if (is_array($x) && array_key_exists('delivery_report', $x) && is_array($x['delivery_report'])) { - foreach($x['delivery_report'] as $xx) { - call_hooks('dreport_process',$xx); - if(is_array($xx) && array_key_exists('message_id',$xx) && DReport::is_storable($xx)) { + foreach ($x['delivery_report'] as $xx) { + call_hooks('dreport_process', $xx); + if (is_array($xx) && array_key_exists('message_id', $xx) && DReport::is_storable($xx)) { // legacy recipients add a space and their name to the xchan. split those if true. $legacy_recipient = strpos($xx['recipient'], ' '); - if($legacy_recipient !== false) { + if ($legacy_recipient !== false) { $legacy_recipient_parts = explode(' ', $xx['recipient'], 2); - $xx['recipient'] = $legacy_recipient_parts[0]; - $xx['name'] = $legacy_recipient_parts[1]; + $xx['recipient'] = $legacy_recipient_parts[0]; + $xx['name'] = $legacy_recipient_parts[1]; } q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s', '%s','%s','%s','%s','%s' ) ", @@ -1023,7 +1023,7 @@ class Libzot { dbesc($xx['recipient']), dbesc($xx['name']), dbesc($xx['status']), - dbesc(datetime_convert('UTC','UTC',$xx['date'])), + dbesc(datetime_convert('UTC', 'UTC', $xx['date'])), dbesc($xx['sender']) ); } @@ -1046,10 +1046,10 @@ class Libzot { // synchronous message types are handled immediately // async messages remain in the queue until processed. - if(intval($outq['outq_async'])) - Queue::remove($outq['outq_hash'],$outq['outq_channel']); + if (intval($outq['outq_async'])) + Queue::remove($outq['outq_hash'], $outq['outq_channel']); - logger('zot_process_response: ' . print_r($x,true), LOGGER_DEBUG); + logger('zot_process_response: ' . print_r($x, true), LOGGER_DEBUG); } /** @@ -1067,16 +1067,16 @@ class Libzot { * If everything checks out on the remote end, we will receive back a packet containing one or more messages, * which will be processed and delivered before this function ultimately returns. * - * @see zot_import() - * * @param array $arr * decrypted and json decoded notify packet from remote site * @return array from zot_import() + * @see zot_import() + * */ static function fetch($arr) { - logger('zot_fetch: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG); + logger('zot_fetch: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); return self::import($arr); @@ -1101,15 +1101,15 @@ class Libzot { */ static function import($arr) { - $env = $arr; + $env = $arr; $private = false; - $return = []; + $return = []; $result = null; - logger('Notify: ' . print_r($env,true), LOGGER_DATA, LOG_DEBUG); + logger('Notify: ' . print_r($env, true), LOGGER_DATA, LOG_DEBUG); - if(! is_array($env)) { + if (!is_array($env)) { logger('decode error'); return; } @@ -1117,59 +1117,59 @@ class Libzot { $message_request = false; - $has_data = array_key_exists('data',$env) && $env['data']; - $data = (($has_data) ? $env['data'] : false); + $has_data = array_key_exists('data', $env) && $env['data']; + $data = (($has_data) ? $env['data'] : false); $AS = null; - if($env['encoding'] === 'activitystreams') { + if ($env['encoding'] === 'activitystreams') { - $AS = new ActivityStreams($data); - if(! $AS->is_valid()) { - logger('Activity rejected: ' . print_r($data,true)); - return; - } - if (is_array($AS->obj)) { - $arr = Activity::decode_note($AS); - } - else { - $arr = []; - } + $AS = new ActivityStreams($data); + if (!$AS->is_valid()) { + logger('Activity rejected: ' . print_r($data, true)); + return; + } + if (is_array($AS->obj)) { + $arr = Activity::decode_note($AS); + } + else { + $arr = []; + } - logger($AS->debug(),LOGGER_DATA); + logger($AS->debug(), LOGGER_DATA); } $deliveries = null; - if(array_key_exists('recipients',$env) && count($env['recipients'])) { + if (array_key_exists('recipients', $env) && count($env['recipients'])) { logger('specific recipients'); - logger('recipients: ' . print_r($env['recipients'],true),LOGGER_DEBUG); + logger('recipients: ' . print_r($env['recipients'], true), LOGGER_DEBUG); $recip_arr = []; - foreach($env['recipients'] as $recip) { - $recip_arr[] = $recip; + foreach ($env['recipients'] as $recip) { + $recip_arr[] = $recip; } $r = false; - if($recip_arr) { - stringify_array_elms($recip_arr,true); - $recips = implode(',',$recip_arr); - $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " ) and channel_removed = 0 "); + if ($recip_arr) { + stringify_array_elms($recip_arr, true); + $recips = implode(',', $recip_arr); + $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " ) and channel_removed = 0 "); } - if(! $r) { + if (!$r) { logger('recips: no recipients on this site'); return; } // Response messages will inherit the privacy of the parent - if($env['type'] !== 'response') + if ($env['type'] !== 'response') $private = true; - $deliveries = ids_to_array($r,'hash'); + $deliveries = ids_to_array($r, 'hash'); // We found somebody on this site that's in the recipient list. } @@ -1182,33 +1182,33 @@ class Libzot { // and who are allowed to see them based on the sender's permissions // @fixme; - $deliveries = self::public_recips($env,$AS); + $deliveries = self::public_recips($env, $AS); } $deliveries = array_unique($deliveries); - if(! $deliveries) { + if (!$deliveries) { logger('No deliveries on this site'); return; } - if($has_data) { + if ($has_data) { - if(in_array($env['type'],['activity','response'])) { + if (in_array($env['type'], ['activity', 'response'])) { $r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s' ", dbesc($AS->actor['id']) ); - if($r) { + if ($r) { // selects a zot6 hash if available, otherwise use whatever we have - $r = self::zot_record_preferred($r); + $r = self::zot_record_preferred($r); $arr['author_xchan'] = $r['hubloc_hash']; } - if (! $arr['author_xchan']) { + if (!$arr['author_xchan']) { logger('No author!'); return; } @@ -1218,43 +1218,43 @@ class Libzot { ); // in individual delivery, change owner if needed - if($s) { + if ($s) { $arr['owner_xchan'] = $s[0]['hubloc_hash']; } else { $arr['owner_xchan'] = $env['sender']; } - if ($private && (! intval($arr['item_private']))) { + if ($private && (!intval($arr['item_private']))) { $arr['item_private'] = 1; } if ($arr['mid'] === $arr['parent_mid']) { - if (is_array($AS->obj) && array_key_exists('commentPolicy',$AS->obj)) { - $p = strstr($AS->obj['commentPolicy'],'until='); - if($p !== false) { - $arr['comments_closed'] = datetime_convert('UTC','UTC', substr($p,6)); - $arr['comment_policy'] = trim(str_replace($p,'',$AS->obj['commentPolicy'])); + if (is_array($AS->obj) && array_key_exists('commentPolicy', $AS->obj)) { + $p = strstr($AS->obj['commentPolicy'], 'until='); + if ($p !== false) { + $arr['comments_closed'] = datetime_convert('UTC', 'UTC', substr($p, 6)); + $arr['comment_policy'] = trim(str_replace($p, '', $AS->obj['commentPolicy'])); } else { - $arr['comment_policy'] = $AS->obj['commentPolicy']; + $arr['comment_policy'] = $AS->obj['commentPolicy']; } } } /// @FIXME - spoofable - if($AS->data['hubloc']) { + if ($AS->data['hubloc']) { $arr['item_verified'] = true; - if (! array_key_exists('comment_policy',$arr)) { + if (!array_key_exists('comment_policy', $arr)) { // set comment policy depending on source hub. Unknown or osada is ActivityPub. // Anything else we'll say is zot - which could have a range of project names $s = q("select site_project from site where site_url = '%s' limit 1", dbesc($r[0]['hubloc_url']) ); - if ((! $s) || (in_array($s[0]['site_project'],[ '', 'osada' ]))) { + if ((!$s) || (in_array($s[0]['site_project'], ['', 'osada']))) { $arr['comment_policy'] = 'authenticated'; } else { @@ -1262,28 +1262,28 @@ class Libzot { } } } - if($AS->data['signed_data']) { - IConfig::Set($arr,'activitystreams','signed_data',$AS->data['signed_data'],false); + if ($AS->data['signed_data']) { + IConfig::Set($arr, 'activitystreams', 'signed_data', $AS->data['signed_data'], false); } - logger('Activity received: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG); - logger('Activity recipients: ' . print_r($deliveries,true), LOGGER_DATA, LOG_DEBUG); + logger('Activity received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); + logger('Activity recipients: ' . print_r($deliveries, true), LOGGER_DATA, LOG_DEBUG); - $relay = (($env['type'] === 'response') ? true : false ); + $relay = (($env['type'] === 'response') ? true : false); - $result = self::process_delivery($env['sender'],$AS,$arr,$deliveries,$relay,false,$message_request); + $result = self::process_delivery($env['sender'], $AS, $arr, $deliveries, $relay, false, $message_request); } - elseif($env['type'] === 'sync') { + elseif ($env['type'] === 'sync') { // $arr = get_channelsync_elements($data); - $arr = json_decode($data,true); + $arr = json_decode($data, true); - logger('Channel sync received: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG); - logger('Channel sync recipients: ' . print_r($deliveries,true), LOGGER_DATA, LOG_DEBUG); + logger('Channel sync received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); + logger('Channel sync recipients: ' . print_r($deliveries, true), LOGGER_DATA, LOG_DEBUG); if ($env['encoding'] === 'hz') { - $result = Libsync::process_channel_sync_delivery($env['sender'],$arr,$deliveries); + $result = Libsync::process_channel_sync_delivery($env['sender'], $arr, $deliveries); } else { logger('sync packet type not supported.'); @@ -1305,15 +1305,15 @@ class Libzot { * @return boolean */ static function is_top_level($env, $act) { - if($env['encoding'] === 'zot' && array_key_exists('flags',$env) && in_array('thread_parent', $env['flags'])) { + if ($env['encoding'] === 'zot' && array_key_exists('flags', $env) && in_array('thread_parent', $env['flags'])) { return true; } - if($act) { - if(in_array($act->type, ['Like','Dislike'])) { + if ($act) { + if (in_array($act->type, ['Like', 'Dislike'])) { return false; } - $x = self::find_parent($env,$act); - if($x === $act->id || $x === $act->obj['id']) { + $x = self::find_parent($env, $act); + if ($x === $act->id || $x === $act->obj['id']) { return true; } } @@ -1321,12 +1321,12 @@ class Libzot { } - static function find_parent($env,$act) { - if($act) { - if(in_array($act->type, ['Like','Dislike'])) { + static function find_parent($env, $act) { + if ($act) { + if (in_array($act->type, ['Like', 'Dislike'])) { return $act->obj['id']; } - if($act->parent_id) { + if ($act->parent_id) { return $act->parent_id; } } @@ -1355,58 +1355,57 @@ class Libzot { require_once('include/channel.php'); $check_mentions = false; - $include_sys = false; + $include_sys = false; - if($msg['type'] === 'activity') { - $disable_discover_tab = get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false; - if(! $disable_discover_tab) + if ($msg['type'] === 'activity') { + $disable_discover_tab = get_config('system', 'disable_discover_tab') || get_config('system', 'disable_discover_tab') === false; + if (!$disable_discover_tab) $include_sys = true; $perm = 'send_stream'; - if(self::is_top_level($msg,$act)) { + if (self::is_top_level($msg, $act)) { $check_mentions = true; } } - elseif($msg['type'] === 'mail') + elseif ($msg['type'] === 'mail') $perm = 'post_mail'; $r = []; $c = q("select channel_id, channel_hash from channel where channel_removed = 0"); - if($c) { - foreach($c as $cc) { - if(perm_is_allowed($cc['channel_id'],$msg['sender'],$perm)) { + if ($c) { + foreach ($c as $cc) { + if (perm_is_allowed($cc['channel_id'], $msg['sender'], $perm)) { $r[] = $cc['channel_hash']; } } } - if($include_sys) { + if ($include_sys) { $sys = get_sys_channel(); - if($sys) + if ($sys) $r[] = $sys['channel_hash']; } - // look for any public mentions on this site // They will get filtered by tgroup_check() so we don't need to check permissions now - if($check_mentions) { + if ($check_mentions) { // It's a top level post. Look at the tags. See if any of them are mentions and are on this hub. - if($act && $act->obj) { - if(is_array($act->obj['tag']) && $act->obj['tag']) { - foreach($act->obj['tag'] as $tag) { - if($tag['type'] === 'Mention' && (strpos($tag['href'],z_root()) !== false)) { + if ($act && $act->obj) { + if (is_array($act->obj['tag']) && $act->obj['tag']) { + foreach ($act->obj['tag'] as $tag) { + if ($tag['type'] === 'Mention' && (strpos($tag['href'], z_root()) !== false)) { $address = basename($tag['href']); - if($address) { + if ($address) { $z = q("select channel_hash as hash from channel where channel_address = '%s' and channel_removed = 0 limit 1", dbesc($address) ); - if($z) { + if ($z) { $r[] = $z[0]['hash']; } } @@ -1420,15 +1419,15 @@ class Libzot { // everybody that stored a copy of the parent. This way we know we're covered. We'll check the // comment permissions when we deliver them. - $thread_parent = self::find_parent($msg,$act); + $thread_parent = self::find_parent($msg, $act); - if($thread_parent) { + if ($thread_parent) { $z = q("select channel_hash as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ", dbesc($thread_parent), dbesc($thread_parent) ); - if($z) { - foreach($z as $zv) { + if ($z) { + foreach ($z as $zv) { $r[] = $zv['hash']; } } @@ -1438,11 +1437,11 @@ class Libzot { // There are probably a lot of duplicates in $r at this point. We need to filter those out. // It's a bit of work since it's a multi-dimensional array - if($r) { + if ($r) { $r = array_values(array_unique($r)); } - logger('public_recips: ' . print_r($r,true), LOGGER_DATA, LOG_DEBUG); + logger('public_recips: ' . print_r($r, true), LOGGER_DATA, LOG_DEBUG); return $r; } @@ -1465,22 +1464,22 @@ class Libzot { // We've validated the sender. Now make sure that the sender is the owner or author - if(! $public) { - if($sender != $arr['owner_xchan'] && $sender != $arr['author_xchan']) { + if (!$public) { + if ($sender != $arr['owner_xchan'] && $sender != $arr['author_xchan']) { logger("Sender $sender is not owner {$arr['owner_xchan']} or author {$arr['author_xchan']} - mid {$arr['mid']}"); return; } } - foreach($deliveries as $d) { + foreach ($deliveries as $d) { $local_public = $public; - $DR = new DReport(z_root(),$sender,$d,$arr['mid']); + $DR = new DReport(z_root(), $sender, $d, $arr['mid']); $channel = channelx_by_hash($d); - if (! $channel) { + if (!$channel) { $DR->update('recipient not found'); $result[] = $DR->get(); continue; @@ -1488,16 +1487,16 @@ class Libzot { $DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>'); - if(($act) && ($act->obj) && (! is_array($act->obj))) { + if (($act) && ($act->obj) && (!is_array($act->obj))) { // The initial object fetch failed using the sys channel credentials. // Try again using the delivery channel credentials. // We will also need to re-parse the $item array, // but preserve any values that were set during anonymous parsing. - $o = Activity::fetch($act->obj,$channel); - if($o) { + $o = Activity::fetch($act->obj, $channel); + if ($o) { $act->obj = $o; - $arr = array_merge(Activity::decode_note($act),$arr); + $arr = array_merge(Activity::decode_note($act), $arr); } else { @@ -1516,7 +1515,7 @@ class Libzot { * access checks. */ - if($sender === $channel['channel_hash'] && $arr['author_xchan'] === $channel['channel_hash'] && $arr['mid'] === $arr['parent_mid']) { + if ($sender === $channel['channel_hash'] && $arr['author_xchan'] === $channel['channel_hash'] && $arr['mid'] === $arr['parent_mid']) { $DR->update('self delivery ignored'); $result[] = $DR->get(); continue; @@ -1526,32 +1525,32 @@ class Libzot { // for comments travelling upstream. Wait and catch them on the way down. // They may have been blocked by the owner. - if(intval($channel['channel_system']) && (! $arr['item_private']) && (! $relay)) { + if (intval($channel['channel_system']) && (!$arr['item_private']) && (!$relay)) { $local_public = true; $r = q("select xchan_selfcensored from xchan where xchan_hash = '%s' limit 1", dbesc($sender) ); // don't import sys channel posts from selfcensored authors - if($r && (intval($r[0]['xchan_selfcensored']))) { + if ($r && (intval($r[0]['xchan_selfcensored']))) { $local_public = false; continue; } - if(! MessageFilter::evaluate($arr,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) { + if (!MessageFilter::evaluate($arr, get_config('system', 'pubstream_incl'), get_config('system', 'pubstream_excl'))) { $local_public = false; continue; } } - $tag_delivery = tgroup_check($channel['channel_id'],$arr); + $tag_delivery = tgroup_check($channel['channel_id'], $arr); $perm = 'send_stream'; - if(($arr['mid'] !== $arr['parent_mid']) && ($relay)) + if (($arr['mid'] !== $arr['parent_mid']) && ($relay)) $perm = 'post_comments'; // This is our own post, possibly coming from a channel clone - if($arr['owner_xchan'] == $d) { + if ($arr['owner_xchan'] == $d) { $arr['item_wall'] = 1; } else { @@ -1560,15 +1559,15 @@ class Libzot { $friendofriend = false; - if ((! $tag_delivery) && (! $local_public)) { - $allowed = (perm_is_allowed($channel['channel_id'],$sender,$perm)); - if((! $allowed) && $perm === 'post_comments') { + if ((!$tag_delivery) && (!$local_public)) { + $allowed = (perm_is_allowed($channel['channel_id'], $sender, $perm)); + if ((!$allowed) && $perm === 'post_comments') { $parent = q("select * from item where mid = '%s' and uid = %d limit 1", dbesc($arr['parent_mid']), intval($channel['channel_id']) ); if ($parent) { - $allowed = can_comment_on_post($sender,$parent[0]); + $allowed = can_comment_on_post($sender, $parent[0]); } } @@ -1588,7 +1587,7 @@ class Libzot { // doesn't exist. if ($perm === 'send_stream') { - if (get_pconfig($channel['channel_id'],'system','hyperdrive',false) || $arr['verb'] === ACTIVITY_SHARE) { + if (get_pconfig($channel['channel_id'], 'system', 'hyperdrive', false) || $arr['verb'] === ACTIVITY_SHARE) { $allowed = true; } } @@ -1599,7 +1598,7 @@ class Libzot { $friendofriend = true; } - if (! $allowed) { + if (!$allowed) { logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}"); $DR->update('permission denied'); $result[] = $DR->get(); @@ -1609,7 +1608,7 @@ class Libzot { // logger('item: ' . print_r($arr,true), LOGGER_DATA); - if($arr['mid'] !== $arr['parent_mid']) { + if ($arr['mid'] !== $arr['parent_mid']) { logger('checking source: "' . $arr['mid'] . '" != "' . $arr['parent_mid'] . '"'); @@ -1624,7 +1623,7 @@ class Libzot { intval($channel['channel_id']) ); - if(! $r) { + if (!$r) { $DR->update('comment parent not found'); $result[] = $DR->get(); @@ -1639,9 +1638,9 @@ class Libzot { // the top level post is unlikely to be imported and // this is just an exercise in futility. - if((! $relay) && (! $request) && (! $local_public) - && perm_is_allowed($channel['channel_id'],$sender,'send_stream')) { - self::fetch_conversation($channel,$arr['parent_mid']); + if ((!$relay) && (!$request) && (!$local_public) + && perm_is_allowed($channel['channel_id'], $sender, 'send_stream')) { + self::fetch_conversation($channel, $arr['parent_mid']); } continue; } @@ -1650,13 +1649,13 @@ class Libzot { // route checking doesn't work correctly here because we've changed the privacy $r[0]['route'] = EMPTY_STR; // If this is a poll response, convert the obj_type to our (internal-only) "Answer" type - if ($arr['obj_type'] === ACTIVITY_OBJ_COMMENT && $arr['title'] && (! $arr['body'])) { + if ($arr['obj_type'] === ACTIVITY_OBJ_COMMENT && $arr['title'] && (!$arr['body'])) { $arr['obj_type'] = 'Answer'; } } - if($relay || $friendofriend || (intval($r[0]['item_private']) === 0 && intval($arr['item_private']) === 0)) { + if ($relay || $friendofriend || (intval($r[0]['item_private']) === 0 && intval($arr['item_private']) === 0)) { // reset the route in case it travelled a great distance upstream // use our parent's route so when we go back downstream we'll match // with whatever route our parent has. @@ -1664,7 +1663,7 @@ class Libzot { // but we are now getting comments via listener delivery // and if there is no privacy on this or the parent, we don't care about the route, // so just set the owner and route accordingly. - $arr['route'] = $r[0]['route']; + $arr['route'] = $r[0]['route']; $arr['owner_xchan'] = $r[0]['owner_xchan']; } else { @@ -1676,24 +1675,24 @@ class Libzot { // Always accept empty routes and firehose items (route contains 'undefined') . $existing_route = explode(',', $r[0]['route']); - $routes = count($existing_route); - if($routes) { - $last_hop = array_pop($existing_route); - $last_prior_route = implode(',',$existing_route); + $routes = count($existing_route); + if ($routes) { + $last_hop = array_pop($existing_route); + $last_prior_route = implode(',', $existing_route); } else { - $last_hop = ''; + $last_hop = ''; $last_prior_route = ''; } - if(in_array('undefined',$existing_route) || $last_hop == 'undefined' || $sender == 'undefined') + if (in_array('undefined', $existing_route) || $last_hop == 'undefined' || $sender == 'undefined') $last_hop = ''; $current_route = (($arr['route']) ? $arr['route'] . ',' : '') . $sender; - if($last_hop && $last_hop != $sender) { + if ($last_hop && $last_hop != $sender) { logger('comment route mismatch: parent route = ' . $r[0]['route'] . ' expected = ' . $current_route, LOGGER_DEBUG); - logger('comment route mismatch: parent msg = ' . $r[0]['id'],LOGGER_DEBUG); + logger('comment route mismatch: parent msg = ' . $r[0]['id'], LOGGER_DEBUG); $DR->update('comment route mismatch'); $result[] = $DR->get(); continue; @@ -1706,16 +1705,16 @@ class Libzot { } } - $ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'", + $ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'", intval($channel['channel_id']), dbesc($arr['owner_xchan']) ); $abook = (($ab) ? $ab[0] : null); - if(intval($arr['item_deleted'])) { + if (intval($arr['item_deleted'])) { // remove_community_tag is a no-op if this isn't a community tag activity - self::remove_community_tag($sender,$arr,$channel['channel_id']); + self::remove_community_tag($sender, $arr, $channel['channel_id']); // set these just in case we need to store a fresh copy of the deleted post. // This could happen if the delete got here before the original post did. @@ -1723,13 +1722,13 @@ class Libzot { $arr['aid'] = $channel['channel_account_id']; $arr['uid'] = $channel['channel_id']; - $item_id = self::delete_imported_item($sender,$act,$arr,$channel['channel_id'],$relay); + $item_id = self::delete_imported_item($sender, $act, $arr, $channel['channel_id'], $relay); $DR->update(($item_id) ? 'deleted' : 'delete_failed'); $result[] = $DR->get(); - if($relay && $item_id) { + if ($relay && $item_id) { logger('process_delivery: invoking relay'); - Master::Summon([ 'Notifier', 'relay', intval($item_id) ]); + Master::Summon(['Notifier', 'relay', intval($item_id)]); $DR->update('relayed'); $result[] = $DR->get(); } @@ -1746,11 +1745,11 @@ class Libzot { intval($channel['channel_id']) ); - if($r) { + if ($r) { // We already have this post. $item_id = $r[0]['id']; - if(intval($r[0]['item_deleted'])) { + if (intval($r[0]['item_deleted'])) { // It was deleted locally. $DR->update('update ignored'); $result[] = $DR->get(); @@ -1758,19 +1757,19 @@ class Libzot { continue; } // Maybe it has been edited? - elseif($arr['edited'] > $r[0]['edited']) { - $arr['id'] = $r[0]['id']; + elseif ($arr['edited'] > $r[0]['edited']) { + $arr['id'] = $r[0]['id']; $arr['uid'] = $channel['channel_id']; - if(($arr['mid'] == $arr['parent_mid']) && (! post_is_importable($arr,$abook))) { + if (($arr['mid'] == $arr['parent_mid']) && (!post_is_importable($arr, $abook))) { $DR->update('update ignored'); $result[] = $DR->get(); } else { - $item_result = self::update_imported_item($sender,$arr,$r[0],$channel['channel_id'],$tag_delivery); + $item_result = self::update_imported_item($sender, $arr, $r[0], $channel['channel_id'], $tag_delivery); $DR->update('updated'); $result[] = $DR->get(); - if(! $relay) - add_source_route($item_id,$sender); + if (!$relay) + add_source_route($item_id, $sender); } } else { @@ -1779,7 +1778,7 @@ class Libzot { // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit), // and at the same time not relay any other relayable posts more than once, because to do so is very wasteful. - if(! intval($r[0]['item_origin'])) + if (!intval($r[0]['item_origin'])) continue; } } @@ -1790,7 +1789,7 @@ class Libzot { // if it's a sourced post, call the post_local hooks as if it were // posted locally so that crosspost connectors will be triggered. - if(check_item_source($arr['uid'], $arr) || ($channel['xchan_pubforum'] == 1)) { + if (check_item_source($arr['uid'], $arr) || ($channel['xchan_pubforum'] == 1)) { /** * @hooks post_local * Called when an item has been posted on this machine via mod/item.php (also via API). @@ -1801,19 +1800,19 @@ class Libzot { $item_id = 0; - if(($arr['mid'] == $arr['parent_mid']) && (! post_is_importable($arr,$abook))) { + if (($arr['mid'] == $arr['parent_mid']) && (!post_is_importable($arr, $abook))) { $DR->update('post ignored'); $result[] = $DR->get(); } else { $item_result = item_store($arr); - if($item_result['success']) { + if ($item_result['success']) { $item_id = $item_result['item_id']; - $parr = [ - 'item_id' => $item_id, - 'item' => $arr, - 'sender' => $sender, - 'channel' => $channel + $parr = [ + 'item_id' => $item_id, + 'item' => $arr, + 'sender' => $sender, + 'channel' => $channel ]; /** * @hooks activity_received @@ -1825,8 +1824,8 @@ class Libzot { */ call_hooks('activity_received', $parr); // don't add a source route if it's a relay or later recipients will get a route mismatch - if(! $relay) - add_source_route($item_id,$sender); + if (!$relay) + add_source_route($item_id, $sender); } $DR->update(($item_id) ? 'posted' : 'storage failed: ' . $item_result['message']); $result[] = $DR->get(); @@ -1836,40 +1835,40 @@ class Libzot { // preserve conversations with which you are involved from expiration $stored = (($item_result && $item_result['item']) ? $item_result['item'] : false); - if((is_array($stored)) && ($stored['id'] != $stored['parent']) + if ((is_array($stored)) && ($stored['id'] != $stored['parent']) && ($stored['author_xchan'] === $channel['channel_hash'] || $stored['author_xchan'] === $channel['channel_hash'])) { retain_item($stored['item']['parent']); } - if($relay && $item_id) { + if ($relay && $item_id) { logger('Invoking relay'); - Master::Summon([ 'Notifier', 'relay', intval($item_id) ]); + Master::Summon(['Notifier', 'relay', intval($item_id)]); $DR->addto_update('relayed'); $result[] = $DR->get(); } } - if(! $deliveries) - $result[] = array('', 'no recipients', '', $arr['mid']); + if (!$deliveries) + $result[] = ['', 'no recipients', '', $arr['mid']]; logger('Local results: ' . print_r($result, true), LOGGER_DEBUG); return $result; } - static public function fetch_conversation($channel,$mid) { + static public function fetch_conversation($channel, $mid) { // Use Zotfinger to create a signed request - $a = Zotfinger::exec($mid,$channel); + $a = Zotfinger::exec($mid, $channel); - logger('received conversation: ' . print_r($a,true), LOGGER_DATA); + logger('received conversation: ' . print_r($a, true), LOGGER_DATA); - if($a['data']['type'] !== 'OrderedCollection') { + if ($a['data']['type'] !== 'OrderedCollection') { return; } - if(! intval($a['data']['totalItems'])) { + if (!intval($a['data']['totalItems'])) { return; } @@ -1879,45 +1878,44 @@ class Libzot { dbesc($a['signature']['signer']) ); - foreach($a['data']['orderedItems'] as $activity) { + foreach ($a['data']['orderedItems'] as $activity) { $AS = new ActivityStreams($activity); - if(! $AS->is_valid()) { - logger('FOF Activity rejected: ' . print_r($activity,true)); + if (!$AS->is_valid()) { + logger('FOF Activity rejected: ' . print_r($activity, true)); continue; } $arr = Activity::decode_note($AS); logger($AS->debug()); - $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($AS->actor['id']) ); - if(! $r) { - $y = import_author_xchan([ 'url' => $AS->actor['id'] ]); - if($y) { + if (!$r) { + $y = import_author_xchan(['url' => $AS->actor['id']]); + if ($y) { $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($AS->actor['id']) ); } - if(! $r) { + if (!$r) { logger('FOF Activity: no actor'); continue; } } - if($AS->obj['actor'] && $AS->obj['actor']['id'] && $AS->obj['actor']['id'] !== $AS->actor['id']) { - $y = import_author_xchan([ 'url' => $AS->obj['actor']['id'] ]); - if(! $y) { + if ($AS->obj['actor'] && $AS->obj['actor']['id'] && $AS->obj['actor']['id'] !== $AS->actor['id']) { + $y = import_author_xchan(['url' => $AS->obj['actor']['id']]); + if (!$y) { logger('FOF Activity: no object actor'); continue; } } - if($r) { + if ($r) { $arr['author_xchan'] = $r[0]['hubloc_hash']; } @@ -1925,7 +1923,7 @@ class Libzot { dbesc($a['signature']['signer']) ); - if($s) { + if ($s) { $arr['owner_xchan'] = $s[0]['hubloc_hash']; } else { @@ -1934,7 +1932,7 @@ class Libzot { /// @FIXME - spoofable - if($AS->data['hubloc']) { + if ($AS->data['hubloc']) { $arr['item_verified'] = true; } @@ -1945,7 +1943,7 @@ class Libzot { $s = q("select site_project from site where site_url = '%s' limit 1", dbesc($signer[0]['hubloc_url']) ); - if ((! $s) || (in_array($s[0]['site_project'],[ '', 'osada' ]))) { + if ((!$s) || (in_array($s[0]['site_project'], ['', 'osada']))) { $arr['comment_policy'] = 'authenticated'; } else { @@ -1954,14 +1952,14 @@ class Libzot { } - if($AS->data['signed_data']) { - IConfig::Set($arr,'activitystreams','signed_data',$AS->data['signed_data'],false); + if ($AS->data['signed_data']) { + IConfig::Set($arr, 'activitystreams', 'signed_data', $AS->data['signed_data'], false); } - logger('FOF Activity received: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG); + logger('FOF Activity received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); logger('FOF Activity recipient: ' . $channel['channel_hash'], LOGGER_DATA, LOG_DEBUG); - $result = self::process_delivery($arr['owner_xchan'],$AS, $arr, [ $channel['channel_hash'] ],false,false,true); + $result = self::process_delivery($arr['owner_xchan'], $AS, $arr, [$channel['channel_hash']], false, false, true); if ($result) { $ret = array_merge($ret, $result); } @@ -1984,12 +1982,12 @@ class Libzot { */ static function remove_community_tag($sender, $arr, $uid) { - if(! (activity_match($arr['verb'], ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM))) + if (!(activity_match($arr['verb'], ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM))) return; logger('remove_community_tag: invoked'); - if(! get_pconfig($uid,'system','blocktags')) { + if (!get_pconfig($uid, 'system', 'blocktags')) { logger('Permission denied.'); return; } @@ -1998,24 +1996,24 @@ class Libzot { dbesc($arr['mid']), intval($uid) ); - if(! $r) { + if (!$r) { logger('No item'); return; } - if(($sender != $r[0]['owner_xchan']) && ($sender != $r[0]['author_xchan'])) { + if (($sender != $r[0]['owner_xchan']) && ($sender != $r[0]['author_xchan'])) { logger('Sender not authorised.'); return; } $i = $r[0]; - if($i['target']) - $i['target'] = json_decode($i['target'],true); - if($i['object']) - $i['object'] = json_decode($i['object'],true); + if ($i['target']) + $i['target'] = json_decode($i['target'], true); + if ($i['object']) + $i['object'] = json_decode($i['object'], true); - if(! ($i['target'] && $i['object'])) { + if (!($i['target'] && $i['object'])) { logger('No target/object'); return; } @@ -2026,7 +2024,7 @@ class Libzot { dbesc($message_id), intval($uid) ); - if(! $r) { + if (!$r) { logger('No parent message'); return; } @@ -2038,28 +2036,28 @@ class Libzot { intval(TERM_HASHTAG), intval(TERM_COMMUNITYTAG), dbesc($i['object']['title']), - dbesc(get_rel_link($i['object']['link'],'alternate')) + dbesc(get_rel_link($i['object']['link'], 'alternate')) ); } /** * @brief Updates an imported item. * - * @see item_store_update() - * * @param string $sender * @param array $item * @param array $orig * @param int $uid * @param boolean $tag_delivery * @return void|array + * @see item_store_update() + * */ static function update_imported_item($sender, $item, $orig, $uid, $tag_delivery) { // If this is a comment being updated, remove any privacy information // so that item_store_update will set it from the original. - if($item['mid'] !== $item['parent_mid']) { + if ($item['mid'] !== $item['parent_mid']) { unset($item['allow_cid']); unset($item['allow_gid']); unset($item['deny_cid']); @@ -2070,7 +2068,7 @@ class Libzot { // we need the tag_delivery check for downstream flowing posts as the stored post // may have a different owner than the one being transmitted. - if(($sender != $orig['owner_xchan'] && $sender != $orig['author_xchan']) && (! $tag_delivery)) { + if (($sender != $orig['owner_xchan'] && $sender != $orig['author_xchan']) && (!$tag_delivery)) { logger('sender is not owner or author'); return; } @@ -2081,13 +2079,13 @@ class Libzot { // If we're updating an event that we've saved locally, we store the item info first // because event_addtocal will parse the body to get the 'new' event details - if($orig['resource_type'] === 'event') { + if ($orig['resource_type'] === 'event') { $res = event_addtocal($orig['id'], $uid); - if(! $res) + if (!$res) logger('update event: failed'); } - if(! $x['item_id']) + if (!$x['item_id']) logger('update_imported_item: failed: ' . $x['message']); else logger('update_imported_item'); @@ -2111,8 +2109,8 @@ class Libzot { logger('invoked', LOGGER_DEBUG); $ownership_valid = false; - $item_found = false; - $post_id = 0; + $item_found = false; + $post_id = 0; if ($item['verb'] === 'Tombstone') { // The id of the deleted thing is the item mid (activity id) @@ -2131,17 +2129,17 @@ class Libzot { dbesc($sender), dbesc($sender), dbesc($mid), - dbesc(str_replace('/activity/','/item/',$mid)), + dbesc(str_replace('/activity/', '/item/', $mid)), intval($uid) ); - if($r) { + if ($r) { $stored = $r[0]; // we proved ownership in the sql query $ownership_valid = true; - $post_id = $stored['id']; + $post_id = $stored['id']; $item_found = true; } else { @@ -2149,7 +2147,7 @@ class Libzot { logger('delete received for non-existent item or not owned by sender - ignoring.'); } - if($ownership_valid === false) { + if ($ownership_valid === false) { logger('delete_imported_item: failed: ownership issue'); return false; } @@ -2173,10 +2171,10 @@ class Libzot { } } - if($item_found) { - if(intval($stored['item_deleted'])) { + if ($item_found) { + if (intval($stored['item_deleted'])) { logger('delete_imported_item: item was already deleted'); - if(! $relay) + if (!$relay) return false; // This is a bit hackish, but may have to suffice until the notification/delivery loop is optimised @@ -2207,22 +2205,22 @@ class Libzot { static function process_mail_delivery($sender, $arr, $deliveries) { - $result = array(); + $result = []; - if($sender != $arr['from_xchan']) { + if ($sender != $arr['from_xchan']) { logger('process_mail_delivery: sender is not mail author'); return; } - foreach($deliveries as $d) { + foreach ($deliveries as $d) { - $DR = new DReport(z_root(),$sender,$d,$arr['mid']); + $DR = new DReport(z_root(), $sender, $d, $arr['mid']); $r = q("select * from channel where channel_hash = '%s' limit 1", dbesc($d['hash']) ); - if(! $r) { + if (!$r) { $DR->update('recipient not found'); $result[] = $DR->get(); continue; @@ -2232,7 +2230,7 @@ class Libzot { $DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>'); - if(! perm_is_allowed($channel['channel_id'],$sender,'post_mail')) { + if (!perm_is_allowed($channel['channel_id'], $sender, 'post_mail')) { /* * Always allow somebody to reply if you initiated the conversation. It's anti-social @@ -2241,13 +2239,13 @@ class Libzot { */ $return = false; - if($arr['parent_mid']) { + if ($arr['parent_mid']) { $return = q("select * from mail where mid = '%s' and channel_id = %d limit 1", dbesc($arr['parent_mid']), intval($channel['channel_id']) ); } - if(! $return) { + if (!$return) { logger("permission denied for mail delivery {$channel['channel_id']}"); $DR->update('permission denied'); $result[] = $DR->get(); @@ -2260,8 +2258,8 @@ class Libzot { dbesc($arr['mid']), intval($channel['channel_id']) ); - if($r) { - if(intval($arr['mail_recalled'])) { + if ($r) { + if (intval($arr['mail_recalled'])) { $x = q("delete from mail where id = %d and channel_id = %d", intval($r[0]['id']), intval($channel['channel_id']) @@ -2280,7 +2278,7 @@ class Libzot { else { $arr['account_id'] = $channel['channel_account_id']; $arr['channel_id'] = $channel['channel_id']; - $item_id = mail_store($arr); + $item_id = mail_store($arr); $DR->update('mail delivered'); $result[] = $DR->get(); } @@ -2293,12 +2291,12 @@ class Libzot { /** * @brief Processes delivery of profile. * - * @see import_directory_profile() - * * @param string $sender * @param array $arr * @param array $deliveries (unused) * @return void + * @see import_directory_profile() + * */ static function process_profile_delivery($sender, $arr, $deliveries) { @@ -2307,7 +2305,7 @@ class Libzot { $r = q("select xchan_addr from xchan where xchan_hash = '%s' limit 1", dbesc($sender) ); - if($r) { + if ($r) { Libzotdir::import_directory_profile($sender, $arr, $r[0]['xchan_addr'], UPDATE_FLAGS_UPDATED, 0); } } @@ -2329,16 +2327,16 @@ class Libzot { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($sender) ); - if($r) { - $xchan = [ 'id' => $r[0]['xchan_guid'], 'id_sig' => $r[0]['xchan_guid_sig'], - 'hash' => $r[0]['xchan_hash'], 'public_key' => $r[0]['xchan_pubkey'] ]; - } - if(array_key_exists('locations',$arr) && $arr['locations']) { - $x = Libsync::sync_locations($xchan,$arr,true); - logger('results: ' . print_r($x,true), LOGGER_DEBUG); - if($x['changed']) { + if ($r) { + $xchan = ['id' => $r[0]['xchan_guid'], 'id_sig' => $r[0]['xchan_guid_sig'], + 'hash' => $r[0]['xchan_hash'], 'public_key' => $r[0]['xchan_pubkey']]; + } + if (array_key_exists('locations', $arr) && $arr['locations']) { + $x = Libsync::sync_locations($xchan, $arr, true); + logger('results: ' . print_r($x, true), LOGGER_DEBUG); + if ($x['changed']) { //$guid = random_string() . '@' . App::get_hostname(); - Libzotdir::update_modtime($sender,$r[0]['xchan_guid'],$arr['locations'][0]['address'],UPDATE_FLAGS_UPDATED); + Libzotdir::update_modtime($sender, $r[0]['xchan_guid'], $arr['locations'][0]['address'], UPDATE_FLAGS_UPDATED); } } } @@ -2365,10 +2363,10 @@ class Libzot { */ static function check_location_move($sender_hash, $locations) { - if(! $locations) + if (!$locations) return; - if(count($locations) != 1) + if (count($locations) != 1) return; $loc = $locations[0]; @@ -2377,10 +2375,10 @@ class Libzot { dbesc($sender_hash) ); - if(! $r) + if (!$r) return; - if($loc['url'] !== z_root()) { + if ($loc['url'] !== z_root()) { $x = q("update channel set channel_moved = '%s' where channel_hash = '%s' limit 1", dbesc($loc['url']), dbesc($sender_hash) @@ -2390,7 +2388,7 @@ class Libzot { // of the move on singleton networks $arr = [ - 'channel' => $r[0], + 'channel' => $r[0], 'locations' => $locations ]; /** @@ -2407,23 +2405,23 @@ class Libzot { /** * @brief Returns an array with all known distinct hubs for this channel. * - * @see self::get_hublocs() * @param array $channel an associative array which must contain * * \e string \b channel_hash the hash of the channel * @return array an array with associative arrays + * @see self::get_hublocs() */ static function encode_locations($channel) { $ret = []; $x = self::get_hublocs($channel['channel_hash']); - if($x && count($x)) { - foreach($x as $hub) { + if ($x && count($x)) { + foreach ($x as $hub) { // if this is a local channel that has been deleted, the hubloc is no good - make sure it is marked deleted // so that nobody tries to use it. - if(intval($channel['channel_removed']) && $hub['hubloc_url'] === z_root()) + if (intval($channel['channel_removed']) && $hub['hubloc_url'] === z_root()) $hub['hubloc_deleted'] = 1; @@ -2442,15 +2440,15 @@ class Libzot { // version compatibility tweaks - if(! strpos($z['url_sig'],'.')) { + if (!strpos($z['url_sig'], '.')) { $z['url_sig'] = 'sha256.' . $z['url_sig']; } - if(! $z['id_url']) { - $z['id_url'] = $z['url'] . '/channel/' . substr($z['address'],0,strpos($z['address'],'@')); + if (!$z['id_url']) { + $z['id_url'] = $z['url'] . '/channel/' . substr($z['address'], 0, strpos($z['address'], '@')); } - if(! $z['site_id']) { - $z['site_id'] = Libzot::make_xchan_hash($z['url'],$z['sitekey']); + if (!$z['site_id']) { + $z['site_id'] = Libzot::make_xchan_hash($z['url'], $z['sitekey']); } $ret[] = $z; @@ -2469,10 +2467,10 @@ class Libzot { */ static function import_site($arr) { - if( (! is_array($arr)) || (! $arr['url']) || (! $arr['site_sig'])) + if ((!is_array($arr)) || (!$arr['url']) || (!$arr['site_sig'])) return false; - if(! self::verify($arr['url'], $arr['site_sig'], $arr['sitekey'])) { + if (!self::verify($arr['url'], $arr['site_sig'], $arr['sitekey'])) { logger('Bad url_sig'); return false; } @@ -2483,66 +2481,66 @@ class Libzot { $r = q("select * from site where site_url = '%s' limit 1", dbesc($arr['url']) ); - if($r) { - $exists = true; + if ($r) { + $exists = true; $siterecord = $r[0]; } $site_directory = 0; - if($arr['directory_mode'] == 'normal') + if ($arr['directory_mode'] == 'normal') $site_directory = DIRECTORY_MODE_NORMAL; - if($arr['directory_mode'] == 'primary') + if ($arr['directory_mode'] == 'primary') $site_directory = DIRECTORY_MODE_PRIMARY; - if($arr['directory_mode'] == 'secondary') + if ($arr['directory_mode'] == 'secondary') $site_directory = DIRECTORY_MODE_SECONDARY; - if($arr['directory_mode'] == 'standalone') + if ($arr['directory_mode'] == 'standalone') $site_directory = DIRECTORY_MODE_STANDALONE; $register_policy = 0; - if($arr['register_policy'] == 'closed') + if ($arr['register_policy'] == 'closed') $register_policy = REGISTER_CLOSED; - if($arr['register_policy'] == 'open') + if ($arr['register_policy'] == 'open') $register_policy = REGISTER_OPEN; - if($arr['register_policy'] == 'approve') + if ($arr['register_policy'] == 'approve') $register_policy = REGISTER_APPROVE; $access_policy = 0; - if(array_key_exists('access_policy',$arr)) { - if($arr['access_policy'] === 'private') + if (array_key_exists('access_policy', $arr)) { + if ($arr['access_policy'] === 'private') $access_policy = ACCESS_PRIVATE; - if($arr['access_policy'] === 'paid') + if ($arr['access_policy'] === 'paid') $access_policy = ACCESS_PAID; - if($arr['access_policy'] === 'free') + if ($arr['access_policy'] === 'free') $access_policy = ACCESS_FREE; - if($arr['access_policy'] === 'tiered') + if ($arr['access_policy'] === 'tiered') $access_policy = ACCESS_TIERED; } // don't let insecure sites register as public hubs - if(strpos($arr['url'],'https://') === false) + if (strpos($arr['url'], 'https://') === false) $access_policy = ACCESS_PRIVATE; - if($access_policy != ACCESS_PRIVATE) { + if ($access_policy != ACCESS_PRIVATE) { $x = z_fetch_url($arr['url'] . '/siteinfo.json'); - if(! $x['success']) + if (!$x['success']) $access_policy = ACCESS_PRIVATE; } - $directory_url = htmlspecialchars($arr['directory_url'],ENT_COMPAT,'UTF-8',false); - $url = htmlspecialchars(strtolower($arr['url']),ENT_COMPAT,'UTF-8',false); - $sellpage = htmlspecialchars($arr['sellpage'],ENT_COMPAT,'UTF-8',false); - $site_location = htmlspecialchars($arr['location'],ENT_COMPAT,'UTF-8',false); - $site_realm = htmlspecialchars($arr['realm'],ENT_COMPAT,'UTF-8',false); - $site_project = htmlspecialchars($arr['project'],ENT_COMPAT,'UTF-8',false); - $site_crypto = ((array_key_exists('encryption',$arr) && is_array($arr['encryption'])) ? htmlspecialchars(implode(',',$arr['encryption']),ENT_COMPAT,'UTF-8',false) : ''); - $site_version = ((array_key_exists('version',$arr)) ? htmlspecialchars($arr['version'],ENT_COMPAT,'UTF-8',false) : ''); + $directory_url = htmlspecialchars($arr['directory_url'], ENT_COMPAT, 'UTF-8', false); + $url = htmlspecialchars(strtolower($arr['url']), ENT_COMPAT, 'UTF-8', false); + $sellpage = htmlspecialchars($arr['sellpage'], ENT_COMPAT, 'UTF-8', false); + $site_location = htmlspecialchars($arr['location'], ENT_COMPAT, 'UTF-8', false); + $site_realm = htmlspecialchars($arr['realm'], ENT_COMPAT, 'UTF-8', false); + $site_project = htmlspecialchars($arr['project'], ENT_COMPAT, 'UTF-8', false); + $site_crypto = ((array_key_exists('encryption', $arr) && is_array($arr['encryption'])) ? htmlspecialchars(implode(',', $arr['encryption']), ENT_COMPAT, 'UTF-8', false) : ''); + $site_version = ((array_key_exists('version', $arr)) ? htmlspecialchars($arr['version'], ENT_COMPAT, 'UTF-8', false) : ''); // You can have one and only one primary directory per realm. // Downgrade any others claiming to be primary. As they have // flubbed up this badly already, don't let them be directory servers at all. - if(($site_directory === DIRECTORY_MODE_PRIMARY) + if (($site_directory === DIRECTORY_MODE_PRIMARY) && ($site_realm === get_directory_realm()) && ($arr['url'] != get_directory_primary())) { $site_directory = DIRECTORY_MODE_NORMAL; @@ -2550,12 +2548,12 @@ class Libzot { $site_flags = $site_directory; - if(array_key_exists('zot',$arr)) { - set_sconfig($arr['url'],'system','zot_version',$arr['zot']); + if (array_key_exists('zot', $arr)) { + set_sconfig($arr['url'], 'system', 'zot_version', $arr['zot']); } - if($exists) { - if(($siterecord['site_flags'] != $site_flags) + if ($exists) { + if (($siterecord['site_flags'] != $site_flags) || ($siterecord['site_access'] != $access_policy) || ($siterecord['site_directory'] != $directory_url) || ($siterecord['site_sellpage'] != $sellpage) @@ -2564,12 +2562,12 @@ class Libzot { || ($siterecord['site_project'] != $site_project) || ($siterecord['site_realm'] != $site_realm) || ($siterecord['site_crypto'] != $site_crypto) - || ($siterecord['site_version'] != $site_version) ) { + || ($siterecord['site_version'] != $site_version)) { $update = true; - // logger('import_site: input: ' . print_r($arr,true)); - // logger('import_site: stored: ' . print_r($siterecord,true)); + // logger('import_site: input: ' . print_r($arr,true)); + // logger('import_site: stored: ' . print_r($siterecord,true)); $r = q("update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d, site_project = '%s', site_version = '%s', site_crypto = '%s' where site_url = '%s'", @@ -2587,8 +2585,8 @@ class Libzot { dbesc($site_crypto), dbesc($url) ); - if(! $r) { - logger('Update failed. ' . print_r($arr,true)); + if (!$r) { + logger('Update failed. ' . print_r($arr, true)); } } else { @@ -2620,8 +2618,8 @@ class Libzot { ] ); - if(! $r) { - logger('Record create failed. ' . print_r($arr,true)); + if (!$r) { + logger('Record create failed. ' . print_r($arr, true)); } } @@ -2631,14 +2629,14 @@ class Libzot { /** * @brief Returns path to /rpost * - * @todo We probably should make rpost discoverable. - * * @param array $observer * * \e string \b xchan_url * @return string + * @todo We probably should make rpost discoverable. + * */ static function get_rpost_path($observer) { - if(! $observer) + if (!$observer) return ''; $parsed = parse_url($observer['xchan_url']); @@ -2659,11 +2657,11 @@ class Libzot { // we may only end up with one; which results in posts with no author name or photo and are a bit // of a hassle to repair. If either or both are missing, do a full discovery probe. - if(! array_key_exists('id',$x)) { + if (!array_key_exists('id', $x)) { return import_author_activitypub($x); } - $hash = self::make_xchan_hash($x['id'],$x['key']); + $hash = self::make_xchan_hash($x['id'], $x['key']); $desturl = $x['url']; @@ -2680,18 +2678,18 @@ class Libzot { $site_dead = false; - if($r1 && intval($r1[0]['site_dead'])) { + if ($r1 && intval($r1[0]['site_dead'])) { $site_dead = true; } // We have valid and somewhat fresh information. Always true if it is our own site. - if($r1 && $r2 && ( $r1[0]['hubloc_updated'] > datetime_convert('UTC','UTC','now - 1 week') || $r1[0]['hubloc_url'] === z_root() ) ) { + if ($r1 && $r2 && ($r1[0]['hubloc_updated'] > datetime_convert('UTC', 'UTC', 'now - 1 week') || $r1[0]['hubloc_url'] === z_root())) { logger('in cache', LOGGER_DEBUG); return $hash; } - logger('not in cache or cache stale - probing: ' . print_r($x,true), LOGGER_DEBUG,LOG_INFO); + logger('not in cache or cache stale - probing: ' . print_r($x, true), LOGGER_DEBUG, LOG_INFO); // The primary hub may be dead. Try to find another one associated with this identity that is // still alive. If we find one, use that url for the discovery/refresh probe. Otherwise, the dead site @@ -2699,15 +2697,15 @@ class Libzot { // cached entry and the identity is valid. It's just unreachable until they bring back their // server from the grave or create another clone elsewhere. - if($site_dead) { - logger('dead site - ignoring', LOGGER_DEBUG,LOG_INFO); + if ($site_dead) { + logger('dead site - ignoring', LOGGER_DEBUG, LOG_INFO); $r = q("select hubloc_id_url from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and site_dead = 0", dbesc($hash) ); - if($r) { - logger('found another site that is not dead: ' . $r[0]['hubloc_url'], LOGGER_DEBUG,LOG_INFO); + if ($r) { + logger('found another site that is not dead: ' . $r[0]['hubloc_url'], LOGGER_DEBUG, LOG_INFO); $desturl = $r[0]['hubloc_url']; } else { @@ -2715,8 +2713,8 @@ class Libzot { } } - $them = [ 'hubloc_id_url' => $desturl ]; - if(self::refresh($them)) + $them = ['hubloc_id_url' => $desturl]; + if (self::refresh($them)) return $hash; return false; @@ -2724,27 +2722,27 @@ class Libzot { static function zotinfo($arr) { - logger('arr: ' . print_r($arr,true)); + logger('arr: ' . print_r($arr, true)); $ret = []; - $zhash = ((x($arr,'guid_hash')) ? $arr['guid_hash'] : ''); - $zguid = ((x($arr,'guid')) ? $arr['guid'] : ''); - $zguid_sig = ((x($arr,'guid_sig')) ? $arr['guid_sig'] : ''); - $zaddr = ((x($arr,'address')) ? $arr['address'] : ''); - $ztarget = ((x($arr,'target_url')) ? $arr['target_url'] : ''); - $zsig = ((x($arr,'target_sig')) ? $arr['target_sig'] : ''); - $zkey = ((x($arr,'key')) ? $arr['key'] : ''); - $mindate = ((x($arr,'mindate')) ? $arr['mindate'] : ''); - $token = ((x($arr,'token')) ? $arr['token'] : ''); - $feed = ((x($arr,'feed')) ? intval($arr['feed']) : 0); - - if($ztarget) { + $zhash = ((x($arr, 'guid_hash')) ? $arr['guid_hash'] : ''); + $zguid = ((x($arr, 'guid')) ? $arr['guid'] : ''); + $zguid_sig = ((x($arr, 'guid_sig')) ? $arr['guid_sig'] : ''); + $zaddr = ((x($arr, 'address')) ? $arr['address'] : ''); + $ztarget = ((x($arr, 'target_url')) ? $arr['target_url'] : ''); + $zsig = ((x($arr, 'target_sig')) ? $arr['target_sig'] : ''); + $zkey = ((x($arr, 'key')) ? $arr['key'] : ''); + $mindate = ((x($arr, 'mindate')) ? $arr['mindate'] : ''); + $token = ((x($arr, 'token')) ? $arr['token'] : ''); + $feed = ((x($arr, 'feed')) ? intval($arr['feed']) : 0); + + if ($ztarget) { $t = q("select * from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($ztarget) ); - if($t) { + if ($t) { $ztarget_hash = $t[0]['hubloc_hash']; @@ -2762,21 +2760,21 @@ class Libzot { $r = null; - if(strlen($zhash)) { + if (strlen($zhash)) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_hash = '%s' limit 1", dbesc($zhash) ); } - elseif(strlen($zguid) && strlen($zguid_sig)) { + elseif (strlen($zguid) && strlen($zguid_sig)) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_guid = '%s' and channel_guid_sig = '%s' limit 1", dbesc($zguid), dbesc($zguid_sig) ); } - elseif(strlen($zaddr)) { - if(strpos($zaddr,'[system]') === false) { /* normal address lookup */ + elseif (strlen($zaddr)) { + if (strpos($zaddr, '[system]') === false) { /* normal address lookup */ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where ( channel_address = '%s' or xchan_addr = '%s' ) limit 1", dbesc($zaddr), @@ -2799,7 +2797,7 @@ class Libzot { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_system = 1 order by channel_id limit 1"); - if(! $r) { + if (!$r) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash where channel_removed = 0 order by channel_id limit 1"); } @@ -2807,45 +2805,45 @@ class Libzot { } else { $ret['message'] = 'Invalid request'; - return($ret); + return ($ret); } - if(! $r) { + if (!$r) { $ret['message'] = 'Item not found.'; - return($ret); + return ($ret); } $e = $r[0]; $id = $e['channel_id']; - $sys_channel = (intval($e['channel_system']) ? true : false); - $special_channel = (($e['channel_pageflags'] & PAGE_PREMIUM) ? true : false); - $adult_channel = (($e['channel_pageflags'] & PAGE_ADULT) ? true : false); + $sys_channel = (intval($e['channel_system']) ? true : false); + $special_channel = (($e['channel_pageflags'] & PAGE_PREMIUM) ? true : false); + $adult_channel = (($e['channel_pageflags'] & PAGE_ADULT) ? true : false); $censored = (($e['channel_pageflags'] & PAGE_CENSORED) ? true : false); - $searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true); + $searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true); $deleted = (intval($e['xchan_deleted']) ? true : false); - if($deleted || $censored || $sys_channel) + if ($deleted || $censored || $sys_channel) $searchable = false; $public_forum = false; - $role = get_pconfig($e['channel_id'],'system','permissions_role'); - if($role === 'forum' || $role === 'repository') { + $role = get_pconfig($e['channel_id'], 'system', 'permissions_role'); + if ($role === 'forum' || $role === 'repository') { $public_forum = true; } else { // check if it has characteristics of a public forum based on custom permissions. $m = Permissions::FilledAutoperms($e['channel_id']); - if($m) { - foreach($m as $k => $v) { - if($k == 'tag_deliver' && intval($v) == 1) - $ch ++; - if($k == 'send_stream' && intval($v) == 0) - $ch ++; - } - if($ch == 2) + if ($m) { + foreach ($m as $k => $v) { + if ($k == 'tag_deliver' && intval($v) == 1) + $ch++; + if ($k == 'send_stream' && intval($v) == 0) + $ch++; + } + if ($ch == 2) $public_forum = true; } } @@ -2856,128 +2854,128 @@ class Libzot { intval($e['channel_id']) ); - $profile = array(); + $profile = []; - if($p) { + if ($p) { - if(! intval($p[0]['publish'])) + if (!intval($p[0]['publish'])) $searchable = false; - $profile['description'] = $p[0]['pdesc']; - $profile['birthday'] = $p[0]['dob']; - if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],'UTC')) !== '')) + $profile['description'] = $p[0]['pdesc']; + $profile['birthday'] = $p[0]['dob']; + if (($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'], 'UTC')) !== '')) $profile['next_birthday'] = $bd; - if($age = age($p[0]['dob'],$e['channel_timezone'],'')) + if ($age = age($p[0]['dob'], $e['channel_timezone'], '')) $profile['age'] = $age; - $profile['gender'] = $p[0]['gender']; - $profile['marital'] = $p[0]['marital']; - $profile['sexual'] = $p[0]['sexual']; - $profile['locale'] = $p[0]['locality']; - $profile['region'] = $p[0]['region']; - $profile['postcode'] = $p[0]['postal_code']; - $profile['country'] = $p[0]['country_name']; - $profile['about'] = $p[0]['about']; - $profile['homepage'] = $p[0]['homepage']; - $profile['hometown'] = $p[0]['hometown']; - - if($p[0]['keywords']) { - $tags = array(); - $k = explode(' ',$p[0]['keywords']); - if($k) { - foreach($k as $kk) { - if(trim($kk," \t\n\r\0\x0B,")) { - $tags[] = trim($kk," \t\n\r\0\x0B,"); + $profile['gender'] = $p[0]['gender']; + $profile['marital'] = $p[0]['marital']; + $profile['sexual'] = $p[0]['sexual']; + $profile['locale'] = $p[0]['locality']; + $profile['region'] = $p[0]['region']; + $profile['postcode'] = $p[0]['postal_code']; + $profile['country'] = $p[0]['country_name']; + $profile['about'] = $p[0]['about']; + $profile['homepage'] = $p[0]['homepage']; + $profile['hometown'] = $p[0]['hometown']; + + if ($p[0]['keywords']) { + $tags = []; + $k = explode(' ', $p[0]['keywords']); + if ($k) { + foreach ($k as $kk) { + if (trim($kk, " \t\n\r\0\x0B,")) { + $tags[] = trim($kk, " \t\n\r\0\x0B,"); } } } - if($tags) + if ($tags) $profile['keywords'] = $tags; } } // Communication details - $ret['id'] = $e['xchan_guid']; - $ret['id_sig'] = self::sign($e['xchan_guid'], $e['channel_prvkey']); + $ret['id'] = $e['xchan_guid']; + $ret['id_sig'] = self::sign($e['xchan_guid'], $e['channel_prvkey']); $ret['primary_location'] = [ - 'address' => $e['xchan_addr'], - 'url' => $e['xchan_url'], - 'connections_url' => $e['xchan_connurl'], - 'follow_url' => $e['xchan_follow'], + 'address' => $e['xchan_addr'], + 'url' => $e['xchan_url'], + 'connections_url' => $e['xchan_connurl'], + 'follow_url' => $e['xchan_follow'], ]; - $ret['public_key'] = $e['xchan_pubkey']; - $ret['username'] = $e['channel_address']; - $ret['name'] = $e['xchan_name']; - $ret['name_updated'] = $e['xchan_name_date']; - $ret['photo'] = [ + $ret['public_key'] = $e['xchan_pubkey']; + $ret['username'] = $e['channel_address']; + $ret['name'] = $e['xchan_name']; + $ret['name_updated'] = $e['xchan_name_date']; + $ret['photo'] = [ 'url' => $e['xchan_photo_l'], 'type' => $e['xchan_photo_mimetype'], 'updated' => $e['xchan_photo_date'] ]; - $ret['channel_role'] = get_pconfig($e['channel_id'],'system','permissions_role','custom'); - $ret['protocols'] = [ 'zot6', 'zot' ]; - $ret['searchable'] = $searchable; - $ret['adult_content'] = $adult_channel; - $ret['public_forum'] = $public_forum; + $ret['channel_role'] = get_pconfig($e['channel_id'], 'system', 'permissions_role', 'custom'); + $ret['protocols'] = ['zot6', 'zot']; + $ret['searchable'] = $searchable; + $ret['adult_content'] = $adult_channel; + $ret['public_forum'] = $public_forum; - $ret['comments'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_comments')); - $ret['mail'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_mail')); + $ret['comments'] = map_scope(PermissionLimits::Get($e['channel_id'], 'post_comments')); + $ret['mail'] = map_scope(PermissionLimits::Get($e['channel_id'], 'post_mail')); - if($deleted) - $ret['deleted'] = $deleted; + if ($deleted) + $ret['deleted'] = $deleted; - if(intval($e['channel_removed'])) + if (intval($e['channel_removed'])) $ret['deleted_locally'] = true; // premium or other channel desiring some contact with potential followers before connecting. // This is a template - %s will be replaced with the follow_url we discover for the return channel. - if($special_channel) { + if ($special_channel) { $ret['connect_url'] = (($e['xchan_connpage']) ? $e['xchan_connpage'] : z_root() . '/connect/' . $e['channel_address']); } // This is a template for our follow url, %s will be replaced with a webbie - if(! $ret['follow_url']) + if (!$ret['follow_url']) $ret['follow_url'] = z_root() . '/follow?f=&url=%s'; - $permissions = get_all_perms($e['channel_id'],$ztarget_hash,false,false); + $permissions = get_all_perms($e['channel_id'], $ztarget_hash, false, false); - if($ztarget_hash) { + if ($ztarget_hash) { $permissions['connected'] = false; - $b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + $b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($ztarget_hash), intval($e['channel_id']) ); - if($b) + if ($b) $permissions['connected'] = true; } - if($permissions['view_profile']) - $ret['profile'] = $profile; + if ($permissions['view_profile']) + $ret['profile'] = $profile; $concise_perms = []; - if($permissions) { - foreach($permissions as $k => $v) { - if($v) { + if ($permissions) { + foreach ($permissions as $k => $v) { + if ($v) { $concise_perms[] = $k; } } - $permissions = implode(',',$concise_perms); + $permissions = implode(',', $concise_perms); } - $ret['permissions'] = $permissions; - $ret['permissions_for'] = $ztarget; + $ret['permissions'] = $permissions; + $ret['permissions_for'] = $ztarget; // array of (verified) hubs this channel uses $x = self::encode_locations($e); - if($x) + if ($x) $ret['locations'] = $x; $ret['site'] = self::site_info(); @@ -2997,58 +2995,58 @@ class Libzot { */ static function site_info() { - $signing_key = get_config('system','prvkey'); - $sig_method = get_config('system','signature_algorithm','sha256'); + $signing_key = get_config('system', 'prvkey'); + $sig_method = get_config('system', 'signature_algorithm', 'sha256'); - $ret = []; - $ret['site'] = []; - $ret['site']['url'] = z_root(); - $ret['site']['site_sig'] = self::sign(z_root(), $signing_key); - $ret['site']['post'] = z_root() . '/zot'; + $ret = []; + $ret['site'] = []; + $ret['site']['url'] = z_root(); + $ret['site']['site_sig'] = self::sign(z_root(), $signing_key); + $ret['site']['post'] = z_root() . '/zot'; $ret['site']['openWebAuth'] = z_root() . '/owa'; $ret['site']['authRedirect'] = z_root() . '/magic'; - $ret['site']['sitekey'] = get_config('system','pubkey'); + $ret['site']['sitekey'] = get_config('system', 'pubkey'); - $dirmode = get_config('system','directory_mode'); - if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL)) + $dirmode = get_config('system', 'directory_mode'); + if (($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL)) $ret['site']['directory_mode'] = 'normal'; - if($dirmode == DIRECTORY_MODE_PRIMARY) + if ($dirmode == DIRECTORY_MODE_PRIMARY) $ret['site']['directory_mode'] = 'primary'; - elseif($dirmode == DIRECTORY_MODE_SECONDARY) + elseif ($dirmode == DIRECTORY_MODE_SECONDARY) $ret['site']['directory_mode'] = 'secondary'; - elseif($dirmode == DIRECTORY_MODE_STANDALONE) + elseif ($dirmode == DIRECTORY_MODE_STANDALONE) $ret['site']['directory_mode'] = 'standalone'; - if($dirmode != DIRECTORY_MODE_NORMAL) + if ($dirmode != DIRECTORY_MODE_NORMAL) $ret['site']['directory_url'] = z_root() . '/dirsearch'; $ret['site']['encryption'] = crypto_methods(); - $ret['site']['zot'] = System::get_zot_revision(); + $ret['site']['zot'] = System::get_zot_revision(); // hide detailed site information if you're off the grid - if($dirmode != DIRECTORY_MODE_STANDALONE) { + if ($dirmode != DIRECTORY_MODE_STANDALONE) { - $register_policy = intval(get_config('system','register_policy')); + $register_policy = intval(get_config('system', 'register_policy')); - if($register_policy == REGISTER_CLOSED) + if ($register_policy == REGISTER_CLOSED) $ret['site']['register_policy'] = 'closed'; - if($register_policy == REGISTER_APPROVE) + if ($register_policy == REGISTER_APPROVE) $ret['site']['register_policy'] = 'approve'; - if($register_policy == REGISTER_OPEN) + if ($register_policy == REGISTER_OPEN) $ret['site']['register_policy'] = 'open'; - $access_policy = intval(get_config('system','access_policy')); + $access_policy = intval(get_config('system', 'access_policy')); - if($access_policy == ACCESS_PRIVATE) + if ($access_policy == ACCESS_PRIVATE) $ret['site']['access_policy'] = 'private'; - if($access_policy == ACCESS_PAID) + if ($access_policy == ACCESS_PAID) $ret['site']['access_policy'] = 'paid'; - if($access_policy == ACCESS_FREE) + if ($access_policy == ACCESS_FREE) $ret['site']['access_policy'] = 'free'; - if($access_policy == ACCESS_TIERED) + if ($access_policy == ACCESS_TIERED) $ret['site']['access_policy'] = 'tiered'; $ret['site']['accounts'] = account_total(); @@ -3056,24 +3054,24 @@ class Libzot { require_once('include/channel.php'); $ret['site']['channels'] = channel_total(); - $ret['site']['admin'] = get_config('system','admin_email'); + $ret['site']['admin'] = get_config('system', 'admin_email'); - $visible_plugins = array(); - if(is_array(\App::$plugins) && count(\App::$plugins)) { + $visible_plugins = []; + if (is_array(\App::$plugins) && count(\App::$plugins)) { $r = q("select * from addon where hidden = 0"); - if($r) - foreach($r as $rr) + if ($r) + foreach ($r as $rr) $visible_plugins[] = $rr['aname']; } - $ret['site']['plugins'] = $visible_plugins; - $ret['site']['sitehash'] = get_config('system','location_hash'); - $ret['site']['sitename'] = get_config('system','sitename'); - $ret['site']['sellpage'] = get_config('system','sellpage'); - $ret['site']['location'] = get_config('system','site_location'); - $ret['site']['realm'] = get_directory_realm(); - $ret['site']['project'] = System::get_platform_name(); - $ret['site']['version'] = System::get_project_version(); + $ret['site']['plugins'] = $visible_plugins; + $ret['site']['sitehash'] = get_config('system', 'location_hash'); + $ret['site']['sitename'] = get_config('system', 'sitename'); + $ret['site']['sellpage'] = get_config('system', 'sellpage'); + $ret['site']['location'] = get_config('system', 'site_location'); + $ret['site']['realm'] = get_directory_realm(); + $ret['site']['project'] = System::get_platform_name(); + $ret['site']['version'] = System::get_project_version(); } @@ -3154,36 +3152,36 @@ class Libzot { * @param string $alg (optional) default 'sha256' * @return string */ - static function sign($data,$key,$alg = 'sha256') { - if(! $key) + static function sign($data, $key, $alg = 'sha256') { + if (!$key) return 'no key'; $sig = ''; - openssl_sign($data,$sig,$key,$alg); + openssl_sign($data, $sig, $key, $alg); return $alg . '.' . base64url_encode($sig); } - static function verify($data,$sig,$key) { + static function verify($data, $sig, $key) { $verify = 0; - $x = explode('.',$sig,2); + $x = explode('.', $sig, 2); if ($key && count($x) === 2) { - $alg = $x[0]; + $alg = $x[0]; $signature = base64url_decode($x[1]); - $verify = @openssl_verify($data,$signature,$key,$alg); + $verify = @openssl_verify($data, $signature, $key, $alg); if ($verify === (-1)) { while ($msg = openssl_error_string()) { - logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR); + logger('openssl_verify: ' . $msg, LOGGER_NORMAL, LOG_ERR); } btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); } } - return(($verify > 0) ? true : false); + return (($verify > 0) ? true : false); } /** @@ -3192,25 +3190,25 @@ class Libzot { * @return boolean */ static function is_zot_request() { - $x = getBestSupportedMimeType([ 'application/x-zot+json' ]); + $x = getBestSupportedMimeType(['application/x-zot+json']); - return(($x) ? true : false); + return (($x) ? true : false); } static public function zot_record_preferred($arr, $check = 'hubloc_network') { - if(! $arr) { + if (!$arr) { return $arr; } - foreach($arr as $v) { - if($v[$check] === 'zot6') { + foreach ($arr as $v) { + if ($v[$check] === 'zot6') { return $v; } } - foreach($arr as $v) { - if($v[$check] === 'zot') { + foreach ($arr as $v) { + if ($v[$check] === 'zot') { return $v; } } diff --git a/Zotlabs/Lib/ZotURL.php b/Zotlabs/Lib/ZotURL.php index 98d1febe5..fa3959f69 100644 --- a/Zotlabs/Lib/ZotURL.php +++ b/Zotlabs/Lib/ZotURL.php @@ -23,9 +23,10 @@ class ZotURL { $portable_url = substr($url,6); $u = explode('/',$portable_url); $portable_id = $u[0]; + hz_syslog(print_r($u,true)); $hosts = self::lookup($portable_id); - + hz_syslog(print_r($hosts,true)); if(! $hosts) { return $ret; } diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php index 8c13682b4..6f4cd9fc4 100644 --- a/Zotlabs/Module/Zotfeed.php +++ b/Zotlabs/Module/Zotfeed.php @@ -1,29 +1,127 @@ true, + 'wall' => '1', + 'datequery' => $params['end'], + 'datequery2' => $params['begin'], + 'direction' => dbesc($params['direction']), + 'pages' => $params['pages'], + 'order' => dbesc('post'), + 'top' => $params['top'], + 'cat' => $params['cat'], + 'compat' => $params['compat'] + ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module + ); + + if ($total) { + App::set_pager_total($total); + App::set_pager_itemspage(100); + } + + if (App::$pager['unset'] && $total > 100) { + $ret = Activity::paged_collection_init($total, App::$query_string); + } + else { + $items = items_fetch( + [ + 'wall' => '1', + 'datequery' => $params['end'], + 'datequery2' => $params['begin'], + 'records' => intval(App::$pager['itemspage']), + 'start' => intval(App::$pager['start']), + 'direction' => dbesc($params['direction']), + 'pages' => $params['pages'], + 'order' => dbesc('post'), + 'top' => $params['top'], + 'cat' => $params['cat'], + 'compat' => $params['compat'] + ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module + ); + + $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); + } + + as_return_and_die($ret, $channel); + } + + /* $result = array('success' => false); - + $mindate = (($_REQUEST['mindate']) ? datetime_convert('UTC','UTC',$_REQUEST['mindate']) : ''); if(! $mindate) $mindate = datetime_convert('UTC','UTC', 'now - 14 days'); - + if(observer_prohibited()) { $result['message'] = 'Public access denied'; json_return_and_die($result); } - - $observer = \App::get_observer(); - + + $observer = App::get_observer(); + logger('observer: ' . get_observer_hash(), LOGGER_DEBUG); - + $channel_address = ((argc() > 1) ? argv(1) : ''); if($channel_address) { $r = q("select channel_id, channel_name from channel where channel_address = '%s' and channel_removed = 0 limit 1", @@ -40,12 +138,12 @@ class Zotfeed extends \Zotlabs\Web\Controller { $result['message'] = 'Channel not found.'; json_return_and_die($result); } - + logger('zotfeed request: ' . $r[0]['channel_name'], LOGGER_DEBUG); - $result['project'] = 'Hubzilla'; + $result['project'] = 'Hubzilla'; $result['messages'] = zot_feed($r[0]['channel_id'],$observer['xchan_hash'],array('mindate' => $mindate)); $result['success'] = true; json_return_and_die($result); + */ } - } diff --git a/include/items.php b/include/items.php index bfca354d1..5b9bbd1f9 100755 --- a/include/items.php +++ b/include/items.php @@ -4562,9 +4562,11 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C // only setup pagination on initial page view $pager_sql = ''; } else { - $itemspage = (($channel) ? get_pconfig($uid,'system','itemspage') : 10); - App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10)); - $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); + if(! $arr['total']) { + $itemspage = (($channel) ? get_pconfig($uid,'system','itemspage') : 20); + App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); + } } if (isset($arr['start']) && isset($arr['records'])) @@ -4613,6 +4615,18 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C // "New Item View" - show all items unthreaded in reverse created date order + if ($arr['total']) { + $items = q("SELECT count(item.id) AS total FROM item + WHERE $item_uids $item_restrict + $simple_update + $sql_extra $sql_nets $sql_extra3" + ); + if ($items) { + return intval($items[0]['total']); + } + return 0; + } + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE $item_uids $item_restrict $simple_update diff --git a/include/network.php b/include/network.php index 324a99eba..f5ff48fce 100644 --- a/include/network.php +++ b/include/network.php @@ -1,8 +1,10 @@ [ + ACTIVITYSTREAMS_JSONLD_REV, + 'https://w3id.org/security/v1', + z_root() . ZOT_APSCHEMA_REV + ]], $obj ); + + $headers = []; + $headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ; + $x['signature'] = LDSignatures::sign($x,$channel); + $ret = json_encode($x, JSON_UNESCAPED_SLASHES); + logger('data: ' . jindent($ret), LOGGER_DATA); + $headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'); + $headers['Digest'] = HTTPSig::generate_digest_header($ret); + $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; + + $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel)); + HTTPSig::set_headers($h); + + echo $ret; + killme(); + +} + /** * @brief Send HTTP status header. * @@ -1978,7 +2005,7 @@ function getBestSupportedMimeType($mimeTypes = null, $acceptedTypes = false) { // check if there is a different quality if (strpos($a, ';q=')) { // divide "mime/type;q=X" into two parts: "mime/type" i "X" - list($a, $q) = explode(';q=', $a); + [$a, $q] = explode(';q=', $a); } // mime-type $a is accepted with the quality $q // WARNING: $q == 0 means, that mime-type isn’t supported! -- cgit v1.2.3 From 57645386b2cd0adb1e8aa7a69d638853b32b6f08 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 20 Jan 2021 20:42:59 +0000 Subject: looks like we get arrays or json strings here for some reason --- Zotlabs/Daemon/Onepoll.php | 1 + Zotlabs/Lib/Activity.php | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index 568745608..388a78c81 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -138,6 +138,7 @@ class Onepoll { logger('fetching outbox'); $obj = new ASCollection($url, $importer, 0, $max); $messages = $obj->get(); + hz_syslog(print_r($messages,true)); if ($messages) { foreach ($messages as $message) { if (is_string($message)) { diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 0f9160bf7..aa121d98b 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -299,7 +299,13 @@ class Activity { if ($items) { $x = []; foreach ($items as $i) { - $t = ((get_iconfig($i['id'], 'activitypub', 'rawmsg')) ? get_iconfig($i['id'], 'activitypub', 'rawmsg') : self::encode_activity($i)); + $m = get_iconfig($i['id'], 'activitypub', 'rawmsg'); + if (is_string($m)) { + $t = json_decode($m, true); + } + else { + $t = $m; + } if ($t) { $x[] = $t; } -- cgit v1.2.3 From c5d37a08314c27afeeada724872e28ee7632a080 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 20 Jan 2021 20:43:51 +0000 Subject: remove logging --- Zotlabs/Daemon/Onepoll.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index 388a78c81..568745608 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -138,7 +138,6 @@ class Onepoll { logger('fetching outbox'); $obj = new ASCollection($url, $importer, 0, $max); $messages = $obj->get(); - hz_syslog(print_r($messages,true)); if ($messages) { foreach ($messages as $message) { if (is_string($message)) { -- cgit v1.2.3 From ad42890a0b32f612a2161366ad63ef0759de84da Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 20 Jan 2021 22:15:01 +0100 Subject: Swap key and cat for running pid tracking --- Zotlabs/Daemon/Expire.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php index 8ca92b6c5..c4ff8aec6 100644 --- a/Zotlabs/Daemon/Expire.php +++ b/Zotlabs/Daemon/Expire.php @@ -9,14 +9,14 @@ class Expire { cli_startup(); - $pid = get_config('expire', 'procid', false); + $pid = get_config('procid', 'expire', false); if ($pid && (function_exists('posix_kill') ? posix_kill($pid, 0) : true)) { - logger('Expire: procedure already run with pid ' . $pid, LOGGER_DEBUG); + logger('procedure already run with pid ' . $pid, LOGGER_DEBUG); return; } $pid = getmypid(); - set_config('expire', 'procid', $pid); + set_config('procid', 'expire', $pid); // perform final cleanup on previously delete items @@ -101,6 +101,6 @@ class Expire { logger('Expire: sys: done', LOGGER_DEBUG); } - del_config('expire', 'procid'); + del_config('procid', 'expire'); } } -- cgit v1.2.3 From 491dffd9b734c1f7aa879cca6e48eae5dc7b3f03 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 20 Jan 2021 22:18:27 +0100 Subject: Implement SQL query background caching --- Zotlabs/Daemon/Cache_query.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Zotlabs/Daemon/Cache_query.php diff --git a/Zotlabs/Daemon/Cache_query.php b/Zotlabs/Daemon/Cache_query.php new file mode 100644 index 000000000..c709c96b5 --- /dev/null +++ b/Zotlabs/Daemon/Cache_query.php @@ -0,0 +1,34 @@ + Date: Wed, 20 Jan 2021 22:24:00 +0100 Subject: Process public tags cloud in background --- include/taxonomy.php | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/include/taxonomy.php b/include/taxonomy.php index e06568d19..5681db88c 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -354,30 +354,32 @@ function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) { $sql_extra .= " and not term.term in ( " . stringify_array($unsafetags,true) . ") "; } } - - - $key = __FUNCTION__ . "-" . md5($site . $recent . $safemode . $limit . $type); - $content = Cache::get($key, '1 MINUTE'); - - if(! $content) { - // Fetch tags - $r = q("SELECT term, count(term) AS total FROM term LEFT JOIN item ON term.oid = item.id - where term.ttype = %d - and otype = %d and item_type = %d - $sql_extra $uids $item_normal - group by term order by total desc %s", - intval($type), - intval(TERM_OBJ_POST), - intval(ITEM_TYPE_POST), - ((intval($count)) ? "limit $count" : '') - ); - } else - $r = unserialize($content); - - if(! $r) - return array(); - else - Cache::set($key, serialize($r)); + + $key = __FUNCTION__ . "-" . md5($site . $recent . $safemode . $limit . $type); + + $content = Cache::get($key, '1 MINUTE'); + if(! $content) { + + $content = Cache::get($key, '1 WEEK'); + $arr = [ + "SELECT term, count(term) AS total FROM term LEFT JOIN item ON term.oid = item.id + WHERE term.ttype = %d + AND otype = %d + AND item_type = %d + $sql_extra $uids $item_normal + GROUP BY term ORDER BY total DESC %s", + intval($type), + intval(TERM_OBJ_POST), + intval(ITEM_TYPE_POST), + (intval($count) ? "LIMIT $count" : '') + ]; + + \Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, $arr ]); + } + + $r = unserialize($content); + if(! $r) + return []; return Zotlabs\Text\Tagadelic::calc($r); } -- cgit v1.2.3 From 8134e9cae0ebdb551db7d044f8bd5558ca6903cd Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 20 Jan 2021 22:28:38 +0100 Subject: Process channel categories list in background --- include/contact_widgets.php | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/include/contact_widgets.php b/include/contact_widgets.php index 3b22a3c6d..0719d4011 100644 --- a/include/contact_widgets.php +++ b/include/contact_widgets.php @@ -71,35 +71,39 @@ function categories_widget($baseurl,$selected = '') { $item_normal = item_normal(); - $key = __FUNCTION__ . "-" . App::$profile['profile_uid']; - $content = Cache::get($key, '5 MINUTE'); + $key = __FUNCTION__ . "-" . App::$profile['profile_uid']; + $content = Cache::get($key, '5 MINUTE'); if (! $content) { - $r = q("select distinct(term.term) from term join item on term.oid = item.id - where item.uid = %d - and term.uid = item.uid - and term.ttype = %d - and term.otype = %d - and item.owner_xchan = '%s' - and item.item_wall = 1 - and item.verb != '%s' + + $content = Cache::get($key, '1 MONTH'); + + $arr = [ + "SELECT distinct(term.term) FROM term JOIN item ON term.oid = item.id + WHERE item.uid = %d + AND term.uid = item.uid + AND term.ttype = %d + AND term.otype = %d + AND item.owner_xchan = '%s' + AND item.item_wall = 1 + AND item.verb != '%s' $item_normal $sql_extra - order by term.term asc", + ORDER BY term.term ASC", intval(App::$profile['profile_uid']), intval(TERM_CATEGORY), intval(TERM_OBJ_POST), dbesc(App::$profile['channel_hash']), dbesc(ACTIVITY_UPDATE) - ); + ]; + + \Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, $arr ]); } - else - $r = unserialize($content); - $terms = array(); - if($r && count($r)) { + $r = unserialize($content); - Cache::set($key, serialize($r)); + $terms = []; + if($r && count($r)) { foreach($r as $rr) $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : '')); -- cgit v1.2.3 From bdd6d878f1d83c1cc7b84ead5e171bf2c3a73b7c Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 21 Jan 2021 07:09:19 +0000 Subject: cleanup lib/libsync --- Zotlabs/Lib/Libsync.php | 529 ++++++++++++++++++++++++------------------------ 1 file changed, 263 insertions(+), 266 deletions(-) diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php index 7b968532a..e16b68cf8 100644 --- a/Zotlabs/Lib/Libsync.php +++ b/Zotlabs/Lib/Libsync.php @@ -2,9 +2,9 @@ namespace Zotlabs\Lib; -use Zotlabs\Lib\Libzot; -use Zotlabs\Lib\Queue; +use App; +use Zotlabs\Daemon\Master; class Libsync { @@ -23,21 +23,21 @@ class Libsync { logger('build_sync_packet'); - $keychange = (($packet && array_key_exists('keychange',$packet)) ? true : false); - if($keychange) { + $keychange = (($packet && array_key_exists('keychange', $packet)) ? true : false); + if ($keychange) { logger('keychange sync'); } - if(! $uid) + if (!$uid) $uid = local_channel(); - if(! $uid) + if (!$uid) return; $r = q("select * from channel where channel_id = %d limit 1", intval($uid) ); - if(! $r) + if (!$r) return; $channel = $r[0]; @@ -49,103 +49,103 @@ class Libsync { unset($channel['channel_salt']); - if(intval($channel['channel_removed'])) + if (intval($channel['channel_removed'])) return; $h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash = '%s' and hubloc_deleted = 0", dbesc(($keychange) ? $packet['keychange']['old_hash'] : $channel['channel_hash']) ); - if(! $h) + if (!$h) return; - $synchubs = array(); + $synchubs = []; - foreach($h as $x) { - if($x['hubloc_host'] == \App::get_hostname()) + foreach ($h as $x) { + if ($x['hubloc_host'] == App::get_hostname()) continue; $y = q("select site_dead from site where site_url = '%s' limit 1", dbesc($x['hubloc_url']) ); - if((! $y) || ($y[0]['site_dead'] == 0)) + if ((!$y) || ($y[0]['site_dead'] == 0)) $synchubs[] = $x; } - if(! $synchubs) + if (!$synchubs) return; - $env_recips = [ $channel['channel_hash'] ]; + $env_recips = [$channel['channel_hash']]; - if($packet) - logger('packet: ' . print_r($packet, true),LOGGER_DATA, LOG_DEBUG); + if ($packet) + logger('packet: ' . print_r($packet, true), LOGGER_DATA, LOG_DEBUG); - $info = (($packet) ? $packet : array()); - $info['type'] = 'sync'; + $info = (($packet) ? $packet : []); + $info['type'] = 'sync'; $info['encoding'] = 'hz'; // note: not zot, this packet is very platform specific - $info['relocate'] = ['channel_address' => $channel['channel_address'], 'url' => z_root() ]; + $info['relocate'] = ['channel_address' => $channel['channel_address'], 'url' => z_root()]; - if(array_key_exists($uid,\App::$config) && array_key_exists('transient',\App::$config[$uid])) { - $settings = \App::$config[$uid]['transient']; - if($settings) { + if (array_key_exists($uid, App::$config) && array_key_exists('transient', App::$config[$uid])) { + $settings = App::$config[$uid]['transient']; + if ($settings) { $info['config'] = $settings; } } - if($channel) { - $info['channel'] = array(); - foreach($channel as $k => $v) { + if ($channel) { + $info['channel'] = []; + foreach ($channel as $k => $v) { // filter out any joined tables like xchan - if(strpos($k,'channel_') !== 0) + if (strpos($k, 'channel_') !== 0) continue; // don't pass these elements, they should not be synchronised $disallowed = [ - 'channel_id','channel_account_id','channel_primary','channel_address', - 'channel_deleted','channel_removed','channel_system' + 'channel_id', 'channel_account_id', 'channel_primary', 'channel_address', + 'channel_deleted', 'channel_removed', 'channel_system' ]; - if(! $keychange) { + if (!$keychange) { $disallowed[] = 'channel_prvkey'; } - if(in_array($k,$disallowed)) + if (in_array($k, $disallowed)) continue; $info['channel'][$k] = $v; } } - if($groups_changed) { + if ($groups_changed) { $r = q("select hash as collection, visible, deleted, gname as name from pgrp where uid = %d", intval($uid) ); - if($r) + if ($r) $info['collections'] = $r; $r = q("select pgrp.hash as collection, pgrp_member.xchan as member from pgrp left join pgrp_member on pgrp.id = pgrp_member.gid where pgrp_member.uid = %d", intval($uid) ); - if($r) + if ($r) $info['collection_members'] = $r; } - $interval = ((get_config('system','delivery_interval') !== false) - ? intval(get_config('system','delivery_interval')) : 2 ); + $interval = ((get_config('system', 'delivery_interval') !== false) + ? intval(get_config('system', 'delivery_interval')) : 2); - logger('Packet: ' . print_r($info,true), LOGGER_DATA, LOG_DEBUG); + logger('Packet: ' . print_r($info, true), LOGGER_DATA, LOG_DEBUG); $total = count($synchubs); - foreach($synchubs as $hub) { + foreach ($synchubs as $hub) { $hash = random_string(); - $n = Libzot::build_packet($channel,'sync',$env_recips,json_encode($info),'hz',$hub['hubloc_sitekey'],$hub['site_crypto']); - Queue::insert(array( + $n = Libzot::build_packet($channel, 'sync', $env_recips, json_encode($info), 'hz', $hub['hubloc_sitekey'], $hub['site_crypto']); + Queue::insert([ 'hash' => $hash, 'account_id' => $channel['channel_account_id'], 'channel_id' => $channel['channel_id'], @@ -153,29 +153,29 @@ class Libsync { 'driver' => $hub['hubloc_network'], 'notify' => $n, 'msg' => EMPTY_STR - )); + ]); $x = q("select count(outq_hash) as total from outq where outq_delivered = 0"); - if(intval($x[0]['total']) > intval(get_config('system','force_queue_threshold',3000))) { + if (intval($x[0]['total']) > intval(get_config('system', 'force_queue_threshold', 3000))) { logger('immediate delivery deferred.', LOGGER_DEBUG, LOG_INFO); Queue::update($hash); continue; } - \Zotlabs\Daemon\Master::Summon(array('Deliver', $hash)); + Master::Summon(['Deliver', $hash]); $total = $total - 1; - if($interval && $total) - @time_sleep_until(microtime(true) + (float) $interval); + if ($interval && $total) + @time_sleep_until(microtime(true) + (float)$interval); } } /** * @brief * - * @param array $sender + * @param string $sender * @param array $arr * @param array $deliveries * @return array @@ -187,16 +187,16 @@ class Libsync { $result = []; - $keychange = ((array_key_exists('keychange',$arr)) ? true : false); + $keychange = ((array_key_exists('keychange', $arr)) ? true : false); foreach ($deliveries as $d) { $r = q("select * from channel where channel_hash = '%s' limit 1", dbesc($sender) ); - $DR = new \Zotlabs\Lib\DReport(z_root(),$sender,$d,'sync'); + $DR = new DReport(z_root(), $sender, $d, 'sync'); - if (! $r) { + if (!$r) { $DR->update('recipient not found'); $result[] = $DR->get(); continue; @@ -206,153 +206,152 @@ class Libsync { $DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>'); - $max_friends = service_class_fetch($channel['channel_id'],'total_channels'); - $max_feeds = account_service_class_fetch($channel['channel_account_id'],'total_feeds'); + $max_friends = service_class_fetch($channel['channel_id'], 'total_channels'); + $max_feeds = account_service_class_fetch($channel['channel_account_id'], 'total_feeds'); - if($channel['channel_hash'] != $sender) { + if ($channel['channel_hash'] != $sender) { logger('Possible forgery. Sender ' . $sender . ' is not ' . $channel['channel_hash']); $DR->update('channel mismatch'); $result[] = $DR->get(); continue; } - if($keychange) { - self::keychange($channel,$arr); + if ($keychange) { + self::keychange($channel, $arr); continue; } // if the clone is active, so are we - if(substr($channel['channel_active'],0,10) !== substr(datetime_convert(),0,10)) { + if (substr($channel['channel_active'], 0, 10) !== substr(datetime_convert(), 0, 10)) { q("UPDATE channel set channel_active = '%s' where channel_id = %d", dbesc(datetime_convert()), intval($channel['channel_id']) ); } - if(array_key_exists('config',$arr) && is_array($arr['config']) && count($arr['config'])) { - foreach($arr['config'] as $cat => $k) { - foreach($arr['config'][$cat] as $k => $v) - set_pconfig($channel['channel_id'],$cat,$k,$v); + if (array_key_exists('config', $arr) && is_array($arr['config']) && count($arr['config'])) { + foreach ($arr['config'] as $cat => $k) { + foreach ($arr['config'][$cat] as $k => $v) + set_pconfig($channel['channel_id'], $cat, $k, $v); } } - if(array_key_exists('obj',$arr) && $arr['obj']) - sync_objs($channel,$arr['obj']); + if (array_key_exists('obj', $arr) && $arr['obj']) + sync_objs($channel, $arr['obj']); - if(array_key_exists('likes',$arr) && $arr['likes']) - import_likes($channel,$arr['likes']); + if (array_key_exists('likes', $arr) && $arr['likes']) + import_likes($channel, $arr['likes']); - if(array_key_exists('app',$arr) && $arr['app']) - sync_apps($channel,$arr['app']); + if (array_key_exists('app', $arr) && $arr['app']) + sync_apps($channel, $arr['app']); - if(array_key_exists('addressbook',$arr) && $arr['addressbook']) - sync_addressbook($channel,$arr['addressbook']); + if (array_key_exists('addressbook', $arr) && $arr['addressbook']) + sync_addressbook($channel, $arr['addressbook']); - if(array_key_exists('calendar',$arr) && $arr['calendar']) - sync_calendar($channel,$arr['calendar']); + if (array_key_exists('calendar', $arr) && $arr['calendar']) + sync_calendar($channel, $arr['calendar']); - if(array_key_exists('chatroom',$arr) && $arr['chatroom']) - sync_chatrooms($channel,$arr['chatroom']); + if (array_key_exists('chatroom', $arr) && $arr['chatroom']) + sync_chatrooms($channel, $arr['chatroom']); - if(array_key_exists('conv',$arr) && $arr['conv']) - import_conv($channel,$arr['conv']); + if (array_key_exists('conv', $arr) && $arr['conv']) + import_conv($channel, $arr['conv']); - if(array_key_exists('mail',$arr) && $arr['mail']) - sync_mail($channel,$arr['mail']); + if (array_key_exists('mail', $arr) && $arr['mail']) + sync_mail($channel, $arr['mail']); - if(array_key_exists('event',$arr) && $arr['event']) - sync_events($channel,$arr['event']); + if (array_key_exists('event', $arr) && $arr['event']) + sync_events($channel, $arr['event']); - if(array_key_exists('event_item',$arr) && $arr['event_item']) - sync_items($channel,$arr['event_item'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null)); + if (array_key_exists('event_item', $arr) && $arr['event_item']) + sync_items($channel, $arr['event_item'], ((array_key_exists('relocate', $arr)) ? $arr['relocate'] : null)); - if(array_key_exists('item',$arr) && $arr['item']) - sync_items($channel,$arr['item'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null)); + if (array_key_exists('item', $arr) && $arr['item']) + sync_items($channel, $arr['item'], ((array_key_exists('relocate', $arr)) ? $arr['relocate'] : null)); // deprecated, maintaining for a few months for upward compatibility // this should sync webpages, but the logic is a bit subtle - if(array_key_exists('item_id',$arr) && $arr['item_id']) - sync_items($channel,$arr['item_id']); + if (array_key_exists('item_id', $arr) && $arr['item_id']) + sync_items($channel, $arr['item_id']); - if(array_key_exists('menu',$arr) && $arr['menu']) - sync_menus($channel,$arr['menu']); + if (array_key_exists('menu', $arr) && $arr['menu']) + sync_menus($channel, $arr['menu']); - if(array_key_exists('file',$arr) && $arr['file']) - sync_files($channel,$arr['file']); + if (array_key_exists('file', $arr) && $arr['file']) + sync_files($channel, $arr['file']); - if(array_key_exists('wiki',$arr) && $arr['wiki']) - sync_items($channel,$arr['wiki'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null)); + if (array_key_exists('wiki', $arr) && $arr['wiki']) + sync_items($channel, $arr['wiki'], ((array_key_exists('relocate', $arr)) ? $arr['relocate'] : null)); - if(array_key_exists('channel',$arr) && is_array($arr['channel']) && count($arr['channel'])) { + if (array_key_exists('channel', $arr) && is_array($arr['channel']) && count($arr['channel'])) { - $remote_channel = $arr['channel']; + $remote_channel = $arr['channel']; $remote_channel['channel_id'] = $channel['channel_id']; - if(array_key_exists('channel_pageflags',$arr['channel']) && intval($arr['channel']['channel_pageflags'])) { + if (array_key_exists('channel_pageflags', $arr['channel']) && intval($arr['channel']['channel_pageflags'])) { // Several pageflags are site-specific and cannot be sync'd. // Only allow those bits which are shareable from the remote and then // logically OR with the local flags - $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] & (PAGE_HIDDEN|PAGE_AUTOCONNECT|PAGE_APPLICATION|PAGE_PREMIUM|PAGE_ADULT); + $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] & (PAGE_HIDDEN | PAGE_AUTOCONNECT | PAGE_APPLICATION | PAGE_PREMIUM | PAGE_ADULT); $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] | $channel['channel_pageflags']; } $disallowed = [ - 'channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey', - 'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted', - 'channel_system', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook', - 'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall', - 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall', - 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish', + 'channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey', + 'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted', + 'channel_system', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook', + 'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall', + 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall', + 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish', 'channel_a_delegate' ]; - $clean = array(); - foreach($arr['channel'] as $k => $v) { - if(in_array($k,$disallowed)) + $clean = []; + foreach ($arr['channel'] as $k => $v) { + if (in_array($k, $disallowed)) continue; $clean[$k] = $v; } - if(count($clean)) { - foreach($clean as $k => $v) { - $r = dbq("UPDATE channel set " . dbesc($k) . " = '" . dbesc($v) - . "' where channel_id = " . intval($channel['channel_id']) ); + if (count($clean)) { + foreach ($clean as $k => $v) { + dbq("UPDATE channel set " . dbesc($k) . " = '" . dbesc($v) . "' where channel_id = " . intval($channel['channel_id'])); } } } - if(array_key_exists('abook',$arr) && is_array($arr['abook']) && count($arr['abook'])) { + if (array_key_exists('abook', $arr) && is_array($arr['abook']) && count($arr['abook'])) { $total_friends = 0; - $total_feeds = 0; + $total_feeds = 0; $r = q("select abook_id, abook_feed from abook where abook_channel = %d", intval($channel['channel_id']) ); - if($r) { + if ($r) { // don't count yourself $total_friends = ((count($r) > 0) ? count($r) - 1 : 0); - foreach($r as $rr) - if(intval($rr['abook_feed'])) - $total_feeds ++; + foreach ($r as $rr) + if (intval($rr['abook_feed'])) + $total_feeds++; } - $disallowed = array('abook_id','abook_account','abook_channel','abook_rating','abook_rating_text','abook_not_here'); + $disallowed = ['abook_id', 'abook_account', 'abook_channel', 'abook_rating', 'abook_rating_text', 'abook_not_here']; $fields = db_columns('abook'); - foreach($arr['abook'] as $abook) { + foreach ($arr['abook'] as $abook) { $abconfig = null; - if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) + if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) $abconfig = $abook['abconfig']; - if(! array_key_exists('abook_blocked',$abook)) { + if (!array_key_exists('abook_blocked', $abook)) { // convert from redmatrix $abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001) ? 1 : 0); $abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002) ? 1 : 0); @@ -364,20 +363,20 @@ class Libsync { $abook['abook_feed'] = (($abook['abook_flags'] & 0x0100) ? 1 : 0); } - $clean = array(); - if($abook['abook_xchan'] && $abook['entry_deleted']) { + $clean = []; + if ($abook['abook_xchan'] && $abook['entry_deleted']) { logger('Removing abook entry for ' . $abook['abook_xchan']); $r = q("select abook_id, abook_feed from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc($abook['abook_xchan']), intval($channel['channel_id']) ); - if($r) { - contact_remove($channel['channel_id'],$r[0]['abook_id']); - if($total_friends) - $total_friends --; - if(intval($r[0]['abook_feed'])) - $total_feeds --; + if ($r) { + contact_remove($channel['channel_id'], $r[0]['abook_id']); + if ($total_friends) + $total_friends--; + if (intval($r[0]['abook_feed'])) + $total_feeds--; } continue; } @@ -386,31 +385,31 @@ class Libsync { // This relies on the undocumented behaviour that red sites send xchan info with the abook // and import_author_xchan will look them up on all federated networks - if($abook['abook_xchan'] && $abook['xchan_addr']) { + if ($abook['abook_xchan'] && $abook['xchan_addr']) { $h = Libzot::get_hublocs($abook['abook_xchan']); - if(! $h) { + if (!$h) { $xhash = import_author_xchan(encode_item_xchan($abook)); - if(! $xhash) { + if (!$xhash) { logger('Import of ' . $abook['xchan_addr'] . ' failed.'); continue; } } } - foreach($abook as $k => $v) { - if(in_array($k,$disallowed) || (strpos($k,'abook') !== 0)) { + foreach ($abook as $k => $v) { + if (in_array($k, $disallowed) || (strpos($k, 'abook') !== 0)) { continue; } - if(! in_array($k,$fields)) { + if (!in_array($k, $fields)) { continue; } $clean[$k] = $v; } - if(! array_key_exists('abook_xchan',$clean)) + if (!array_key_exists('abook_xchan', $clean)) continue; - if(array_key_exists('abook_instance',$clean) && $clean['abook_instance'] && strpos($clean['abook_instance'],z_root()) === false) { + if (array_key_exists('abook_instance', $clean) && $clean['abook_instance'] && strpos($clean['abook_instance'], z_root()) === false) { $clean['abook_not_here'] = 1; } @@ -422,12 +421,12 @@ class Libsync { // make sure we have an abook entry for this xchan on this system - if(! $r) { - if($max_friends !== false && $total_friends > $max_friends) { + if (!$r) { + if ($max_friends !== false && $total_friends > $max_friends) { logger('total_channels service class limit exceeded'); continue; } - if($max_feeds !== false && intval($clean['abook_feed']) && $total_feeds > $max_feeds) { + if ($max_feeds !== false && intval($clean['abook_feed']) && $total_feeds > $max_feeds) { logger('total_feeds service class limit exceeded'); continue; } @@ -438,18 +437,16 @@ class Libsync { 'abook_channel' => $channel['channel_id'] ] ); - $total_friends ++; - if(intval($clean['abook_feed'])) - $total_feeds ++; + $total_friends++; + if (intval($clean['abook_feed'])) + $total_feeds++; } - if(count($clean)) { - foreach($clean as $k => $v) { - if($k == 'abook_dob') + if (count($clean)) { + foreach ($clean as $k => $v) { + if ($k == 'abook_dob') $v = dbescdate($v); - - $r = dbq("UPDATE abook set " . dbesc($k) . " = '" . dbesc($v) - . "' where abook_xchan = '" . dbesc($clean['abook_xchan']) . "' and abook_channel = " . intval($channel['channel_id'])); + dbq("UPDATE abook set " . dbesc($k) . " = '" . dbesc($v) . "' where abook_xchan = '" . dbesc($clean['abook_xchan']) . "' and abook_channel = " . intval($channel['channel_id'])); } } @@ -459,10 +456,10 @@ class Libsync { // translate_abook_perms_inbound($channel,$abook); - if($abconfig) { + if ($abconfig) { /// @fixme does not handle sync of del_abconfig - foreach($abconfig as $abc) { - set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']); + foreach ($abconfig as $abc) { + set_abconfig($channel['channel_id'], $abc['xchan'], $abc['cat'], $abc['k'], $abc['v']); } } } @@ -470,21 +467,21 @@ class Libsync { // sync collections (privacy groups) oh joy... - if(array_key_exists('collections',$arr) && is_array($arr['collections']) && count($arr['collections'])) { + if (array_key_exists('collections', $arr) && is_array($arr['collections']) && count($arr['collections'])) { $x = q("select * from pgrp where uid = %d", intval($channel['channel_id']) ); - foreach($arr['collections'] as $cl) { + foreach ($arr['collections'] as $cl) { $found = false; - if($x) { - foreach($x as $y) { - if($cl['collection'] == $y['hash']) { + if ($x) { + foreach ($x as $y) { + if ($cl['collection'] == $y['hash']) { $found = true; break; } } - if($found) { - if(($y['gname'] != $cl['name']) + if ($found) { + if (($y['gname'] != $cl['name']) || ($y['visible'] != $cl['visible']) || ($y['deleted'] != $cl['deleted'])) { q("update pgrp set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d", @@ -495,15 +492,15 @@ class Libsync { intval($channel['channel_id']) ); } - if(intval($cl['deleted']) && (! intval($y['deleted']))) { + if (intval($cl['deleted']) && (!intval($y['deleted']))) { q("delete from pgrp_member where gid = %d", intval($y['id']) ); } } } - if(! $found) { - $r = q("INSERT INTO pgrp ( hash, uid, visible, deleted, gname ) + if (!$found) { + q("INSERT INTO pgrp ( hash, uid, visible, deleted, gname ) VALUES( '%s', %d, %d, %d, '%s' ) ", dbesc($cl['collection']), intval($channel['channel_id']), @@ -517,16 +514,16 @@ class Libsync { // They need to be removed by marking deleted and removing the members. // This shouldn't happen except for clones created before this function was written. - if($x) { + if ($x) { $found_local = false; - foreach($x as $y) { - foreach($arr['collections'] as $cl) { - if($cl['collection'] == $y['hash']) { + foreach ($x as $y) { + foreach ($arr['collections'] as $cl) { + if ($cl['collection'] == $y['hash']) { $found_local = true; break; } } - if(! $found_local) { + if (!$found_local) { q("delete from pgrp_member where gid = %d", intval($y['id']) ); @@ -546,38 +543,38 @@ class Libsync { // now sync the members - if(array_key_exists('collection_members', $arr) + if (array_key_exists('collection_members', $arr) && is_array($arr['collection_members']) && count($arr['collection_members'])) { // first sort into groups keyed by the group hash - $members = array(); - foreach($arr['collection_members'] as $cm) { - if(! array_key_exists($cm['collection'],$members)) - $members[$cm['collection']] = array(); + $members = []; + foreach ($arr['collection_members'] as $cm) { + if (!array_key_exists($cm['collection'], $members)) + $members[$cm['collection']] = []; $members[$cm['collection']][] = $cm['member']; } // our group list is already synchronised - if($x) { - foreach($x as $y) { + if ($x) { + foreach ($x as $y) { // for each group, loop on members list we just received - if(isset($y['hash']) && isset($members[$y['hash']])) { - foreach($members[$y['hash']] as $member) { + if (isset($y['hash']) && isset($members[$y['hash']])) { + foreach ($members[$y['hash']] as $member) { $found = false; - $z = q("select xchan from pgrp_member where gid = %d and uid = %d and xchan = '%s' limit 1", + $z = q("select xchan from pgrp_member where gid = %d and uid = %d and xchan = '%s' limit 1", intval($y['id']), intval($channel['channel_id']), dbesc($member) ); - if($z) + if ($z) $found = true; // if somebody is in the group that wasn't before - add them - if(! $found) { + if (!$found) { q("INSERT INTO pgrp_member (uid, gid, xchan) VALUES( %d, %d, '%s' ) ", intval($channel['channel_id']), @@ -593,10 +590,10 @@ class Libsync { intval($y['id']), intval($channel['channel_id']) ); - if($m) { - foreach($m as $mm) { + if ($m) { + foreach ($m as $mm) { // if the local existing member isn't in the list we just received - remove them - if(! in_array($mm['xchan'],$members[$y['hash']])) { + if (!in_array($mm['xchan'], $members[$y['hash']])) { q("delete from pgrp_member where xchan = '%s' and gid = %d and uid = %d", dbesc($mm['xchan']), intval($y['id']), @@ -610,17 +607,17 @@ class Libsync { } } - if(array_key_exists('profile',$arr) && is_array($arr['profile']) && count($arr['profile'])) { + if (array_key_exists('profile', $arr) && is_array($arr['profile']) && count($arr['profile'])) { - $disallowed = array('id','aid','uid','guid'); + $disallowed = ['id', 'aid', 'uid', 'guid']; - foreach($arr['profile'] as $profile) { + foreach ($arr['profile'] as $profile) { $x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1", dbesc($profile['profile_guid']), intval($channel['channel_id']) ); - if(! $x) { + if (!$x) { profile_store_lowlevel( [ 'aid' => $channel['channel_account_id'], @@ -633,24 +630,24 @@ class Libsync { dbesc($profile['profile_guid']), intval($channel['channel_id']) ); - if(! $x) + if (!$x) continue; } - $clean = array(); - foreach($profile as $k => $v) { - if(in_array($k,$disallowed)) + $clean = []; + foreach ($profile as $k => $v) { + if (in_array($k, $disallowed)) continue; - if($profile['is_default'] && in_array($k,['photo','thumb'])) + if ($profile['is_default'] && in_array($k, ['photo', 'thumb'])) continue; - if($k === 'name') + if ($k === 'name') $clean['fullname'] = $v; - elseif($k === 'with') + elseif ($k === 'with') $clean['partner'] = $v; - elseif($k === 'work') + elseif ($k === 'work') $clean['employment'] = $v; - elseif(array_key_exists($k,$x[0])) + elseif (array_key_exists($k, $x[0])) $clean[$k] = $v; /** @@ -658,7 +655,7 @@ class Libsync { * We also need to import local photos if a custom photo is selected */ - if((strpos($profile['thumb'],'/photo/profile/l/') !== false) || intval($profile['is_default'])) { + if ((strpos($profile['thumb'], '/photo/profile/l/') !== false) || intval($profile['is_default'])) { $profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id']; $profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id']; } @@ -668,11 +665,11 @@ class Libsync { } } - if(count($clean)) { - foreach($clean as $k => $v) { - $r = dbq("UPDATE profile set " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v) - . "' where profile_guid = '" . dbesc($profile['profile_guid']) - . "' and uid = " . intval($channel['channel_id'])); + if (count($clean)) { + foreach ($clean as $k => $v) { + dbq("UPDATE profile set " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v) + . "' where profile_guid = '" . dbesc($profile['profile_guid']) + . "' and uid = " . intval($channel['channel_id'])); } } } @@ -687,7 +684,7 @@ class Libsync { */ call_hooks('process_channel_sync_delivery', $addon); - $DR = new \Zotlabs\Lib\DReport(z_root(),$d,$d,'sync','channel sync delivered'); + $DR = new DReport(z_root(), $d, $d, 'sync', 'channel sync delivered'); $DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>'); @@ -708,12 +705,12 @@ class Libsync { static function sync_locations($sender, $arr, $absolute = false) { - $ret = array(); + $ret = []; - if($arr['locations']) { + if ($arr['locations']) { - if($absolute) - Libzot::check_location_move($sender['hash'],$arr['locations']); + if ($absolute) + Libzot::check_location_move($sender['hash'], $arr['locations']); $xisting = q("select * from hubloc where hubloc_hash = '%s'", dbesc($sender['hash']) @@ -722,8 +719,8 @@ class Libsync { // See if a primary is specified $has_primary = false; - foreach($arr['locations'] as $location) { - if($location['primary']) { + foreach ($arr['locations'] as $location) { + if ($location['primary']) { $has_primary = true; break; } @@ -731,32 +728,32 @@ class Libsync { // Ensure that they have one primary hub - if(! $has_primary) + if (!$has_primary) $arr['locations'][0]['primary'] = true; - foreach($arr['locations'] as $location) { - if(! Libzot::verify($location['url'],$location['url_sig'],$sender['public_key'])) { + foreach ($arr['locations'] as $location) { + if (!Libzot::verify($location['url'], $location['url_sig'], $sender['public_key'])) { logger('Unable to verify site signature for ' . $location['url']); - $ret['message'] .= sprintf( t('Unable to verify site signature for %s'), $location['url']) . EOL; + $ret['message'] .= sprintf(t('Unable to verify site signature for %s'), $location['url']) . EOL; continue; } - for($x = 0; $x < count($xisting); $x ++) { - if(($xisting[$x]['hubloc_url'] === $location['url']) + for ($x = 0; $x < count($xisting); $x++) { + if (($xisting[$x]['hubloc_url'] === $location['url']) && ($xisting[$x]['hubloc_sitekey'] === $location['sitekey'])) { $xisting[$x]['updated'] = true; } } - if(! $location['sitekey']) { - logger('Empty hubloc sitekey. ' . print_r($location,true)); + if (!$location['sitekey']) { + logger('Empty hubloc sitekey. ' . print_r($location, true)); continue; } // Catch some malformed entries from the past which still exist - if(strpos($location['address'],'/') !== false) - $location['address'] = substr($location['address'],0,strpos($location['address'],'/')); + if (strpos($location['address'], '/') !== false) + $location['address'] = substr($location['address'], 0, strpos($location['address'], '/')); // match as many fields as possible in case anything at all changed. @@ -773,7 +770,7 @@ class Libsync { dbesc($location['callback']), dbesc($location['sitekey']) ); - if($r) { + if ($r) { logger('Hub exists: ' . $location['url'], LOGGER_DEBUG); // update connection timestamp if this is the site we're talking to @@ -781,9 +778,9 @@ class Libsync { $current_site = false; - $t = datetime_convert('UTC','UTC','now - 15 minutes'); + $t = datetime_convert('UTC', 'UTC', 'now - 15 minutes'); - if(array_key_exists('site',$arr) && $location['url'] == $arr['site']['url']) { + if (array_key_exists('site', $arr) && $location['url'] == $arr['site']['url']) { q("update hubloc set hubloc_connected = '%s', hubloc_updated = '%s' where hubloc_id = %d and hubloc_connected < '%s'", dbesc(datetime_convert()), dbesc(datetime_convert()), @@ -793,11 +790,11 @@ class Libsync { $current_site = true; } - if($current_site && intval($r[0]['hubloc_error'])) { + if ($current_site && intval($r[0]['hubloc_error'])) { q("update hubloc set hubloc_error = 0 where hubloc_id = %d", intval($r[0]['hubloc_id']) ); - if(intval($r[0]['hubloc_orphancheck'])) { + if (intval($r[0]['hubloc_orphancheck'])) { q("update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d", intval($r[0]['hubloc_id']) ); @@ -808,60 +805,60 @@ class Libsync { } // Remove pure duplicates - if(count($r) > 1) { - for($h = 1; $h < count($r); $h ++) { + if (count($r) > 1) { + for ($h = 1; $h < count($r); $h++) { q("delete from hubloc where hubloc_id = %d", intval($r[$h]['hubloc_id']) ); - $what .= 'duplicate_hubloc_removed '; + $what .= 'duplicate_hubloc_removed '; $changed = true; } } - if(intval($r[0]['hubloc_primary']) && (! $location['primary'])) { - $m = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id_url = '%s'", + if (intval($r[0]['hubloc_primary']) && (!$location['primary'])) { + q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id_url = '%s'", dbesc(datetime_convert()), dbesc($r[0]['hubloc_id_url']) ); $r[0]['hubloc_primary'] = intval($location['primary']); hubloc_change_primary($r[0]); - $what .= 'primary_hub '; + $what .= 'primary_hub '; $changed = true; } - elseif((! intval($r[0]['hubloc_primary'])) && ($location['primary'])) { - $m = q("update hubloc set hubloc_primary = 1, hubloc_updated = '%s' where hubloc_id = %d", + elseif ((!intval($r[0]['hubloc_primary'])) && ($location['primary'])) { + q("update hubloc set hubloc_primary = 1, hubloc_updated = '%s' where hubloc_id = %d", dbesc(datetime_convert()), intval($r[0]['hubloc_id']) ); // make sure hubloc_change_primary() has current data $r[0]['hubloc_primary'] = intval($location['primary']); hubloc_change_primary($r[0]); - $what .= 'primary_hub '; + $what .= 'primary_hub '; $changed = true; } - elseif($absolute) { + elseif ($absolute) { // Absolute sync - make sure the current primary is correctly reflected in the xchan $pr = hubloc_change_primary($r[0]); - if($pr) { - $what .= 'xchan_primary '; + if ($pr) { + $what .= 'xchan_primary '; $changed = true; } } - if(intval($r[0]['hubloc_deleted']) && (! intval($location['deleted']))) { - $n = q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id_url = '%s'", + if (intval($r[0]['hubloc_deleted']) && (!intval($location['deleted']))) { + q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id_url = '%s'", dbesc(datetime_convert()), dbesc($r[0]['hubloc_id_url']) ); - $what .= 'undelete_hub '; + $what .= 'undelete_hub '; $changed = true; } - elseif((! intval($r[0]['hubloc_deleted'])) && (intval($location['deleted']))) { + elseif ((!intval($r[0]['hubloc_deleted'])) && (intval($location['deleted']))) { logger('deleting hubloc: ' . $r[0]['hubloc_addr']); - $n = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id_url = '%s'", + q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id_url = '%s'", dbesc(datetime_convert()), dbesc($r[0]['hubloc_id_url']) ); - $what .= 'delete_hub '; + $what .= 'delete_hub '; $changed = true; } continue; @@ -870,8 +867,8 @@ class Libsync { // Existing hubs are dealt with. Now let's process any new ones. // New hub claiming to be primary. Make it so by removing any existing primaries. - if(intval($location['primary'])) { - $r = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_hash = '%s' and hubloc_primary = 1", + if (intval($location['primary'])) { + q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_hash = '%s' and hubloc_primary = 1", dbesc(datetime_convert()), dbesc($sender['hash']) ); @@ -879,7 +876,7 @@ class Libsync { logger('New hub: ' . $location['url']); - $r = hubloc_store_lowlevel( + hubloc_store_lowlevel( [ 'hubloc_guid' => $sender['id'], 'hubloc_guid_sig' => $sender['id_sig'], @@ -890,7 +887,7 @@ class Libsync { 'hubloc_primary' => intval($location['primary']), 'hubloc_url' => $location['url'], 'hubloc_url_sig' => $location['url_sig'], - 'hubloc_site_id' => Libzot::make_xchan_hash($location['url'],$location['sitekey']), + 'hubloc_site_id' => Libzot::make_xchan_hash($location['url'], $location['sitekey']), 'hubloc_host' => $location['host'], 'hubloc_callback' => $location['callback'], 'hubloc_sitekey' => $location['sitekey'], @@ -899,15 +896,15 @@ class Libsync { ] ); - $what .= 'newhub '; + $what .= 'newhub '; $changed = true; - if($location['primary']) { + if ($location['primary']) { $r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_sitekey = '%s'", dbesc($location['address']), dbesc($location['sitekey']) ); - if($r) { + if ($r) { $r = Libzot::zot_record_preferred($r); hubloc_change_primary($r); } @@ -916,15 +913,15 @@ class Libsync { // get rid of any hubs we have for this channel which weren't reported. - if($absolute && $xisting) { - foreach($xisting as $x) { - if(! array_key_exists('updated',$x)) { + if ($absolute && $xisting) { + foreach ($xisting as $x) { + if (!array_key_exists('updated', $x)) { logger('Deleting unreferenced hub location ' . $x['hubloc_addr']); - $r = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id_url = '%s'", + q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id_url = '%s'", dbesc(datetime_convert()), dbesc($x['hubloc_id_url']) ); - $what .= 'removed_hub '; + $what .= 'removed_hub '; $changed = true; } } @@ -935,22 +932,22 @@ class Libsync { } $ret['change_message'] = $what; - $ret['changed'] = $changed; + $ret['changed'] = $changed; return $ret; } - static function keychange($channel,$arr) { + static function keychange($channel, $arr) { // verify the keychange operation - if(! Libzot::verify($arr['channel']['channel_pubkey'],$arr['keychange']['new_sig'],$channel['channel_prvkey'])) { + if (!Libzot::verify($arr['channel']['channel_pubkey'], $arr['keychange']['new_sig'], $channel['channel_prvkey'])) { logger('sync keychange: verification failed'); return; } - $sig = Libzot::sign($channel['channel_guid'],$arr['channel']['channel_prvkey']); - $hash = Libzot::make_xchan_hash($channel['channel_guid'],$arr['channel']['channel_pubkey']); + $sig = Libzot::sign($channel['channel_guid'], $arr['channel']['channel_prvkey']); + $hash = Libzot::make_xchan_hash($channel['channel_guid'], $arr['channel']['channel_pubkey']); $r = q("update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s', @@ -961,16 +958,16 @@ class Libsync { dbesc($hash), intval($channel['channel_id']) ); - if(! $r) { + if (!$r) { logger('keychange sync: channel update failed'); return; - } + } $r = q("select * from channel where channel_id = %d", intval($channel['channel_id']) ); - if(! $r) { + if (!$r) { logger('keychange sync: channel retrieve failed'); return; } @@ -982,11 +979,11 @@ class Libsync { dbesc(z_root()) ); - if($h) { - foreach($h as $hv) { + if ($h) { + foreach ($h as $hv) { $hv['hubloc_guid_sig'] = $sig; $hv['hubloc_hash'] = $hash; - $hv['hubloc_url_sig'] = Libzot::sign(z_root(),$channel['channel_prvkey']); + $hv['hubloc_url_sig'] = Libzot::sign(z_root(), $channel['channel_prvkey']); hubloc_store_lowlevel($hv); } } @@ -999,12 +996,12 @@ class Libsync { dbesc($hash) ); - if(($x) && (! $check)) { + if (($x) && (!$check)) { $oldxchan = $x[0]; - foreach($x as $xv) { - $xv['xchan_guid_sig'] = $sig; - $xv['xchan_hash'] = $hash; - $xv['xchan_pubkey'] = $channel['channel_pubkey']; + foreach ($x as $xv) { + $xv['xchan_guid_sig'] = $sig; + $xv['xchan_hash'] = $hash; + $xv['xchan_pubkey'] = $channel['channel_pubkey']; xchan_store_lowlevel($xv); $newxchan = $xv; } @@ -1014,14 +1011,14 @@ class Libsync { dbesc($arr['keychange']['old_hash']) ); - if($a) { + if ($a) { q("update abook set abook_xchan = '%s' where abook_id = %d", dbesc($hash), intval($a[0]['abook_id']) ); } - xchan_change_key($oldxchan,$newxchan,$arr['keychange']); + xchan_change_key($oldxchan, $newxchan, $arr['keychange']); } -- cgit v1.2.3 From 28ae78c579d9423f81f89443c50aa240609fb8f3 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Thu, 21 Jan 2021 08:16:15 +0100 Subject: Higher log level --- Zotlabs/Daemon/Cache_query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Daemon/Cache_query.php b/Zotlabs/Daemon/Cache_query.php index c709c96b5..18d19cdf2 100644 --- a/Zotlabs/Daemon/Cache_query.php +++ b/Zotlabs/Daemon/Cache_query.php @@ -15,7 +15,7 @@ class Cache_query { $pid = get_config('procid', $key, false); if ($pid && (function_exists('posix_kill') ? posix_kill($pid, 0) : true)) { - logger($key . ': procedure already run with pid ' . $pid); + logger($key . ': procedure already run with pid ' . $pid, LOGGER_DEBUG); return; } -- cgit v1.2.3 From 3836e75c89573baca6b029a5fd36401696b86e8d Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Thu, 21 Jan 2021 09:08:53 +0100 Subject: Implement SQL query background caching --- Zotlabs/Daemon/Cache_query.php | 34 ++++++++++++++++++++++++++++ Zotlabs/Daemon/Expire.php | 8 +++---- include/contact_widgets.php | 38 ++++++++++++++++++-------------- include/taxonomy.php | 50 ++++++++++++++++++++++-------------------- 4 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 Zotlabs/Daemon/Cache_query.php diff --git a/Zotlabs/Daemon/Cache_query.php b/Zotlabs/Daemon/Cache_query.php new file mode 100644 index 000000000..18d19cdf2 --- /dev/null +++ b/Zotlabs/Daemon/Cache_query.php @@ -0,0 +1,34 @@ + $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : '')); diff --git a/include/taxonomy.php b/include/taxonomy.php index e06568d19..5681db88c 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -354,30 +354,32 @@ function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) { $sql_extra .= " and not term.term in ( " . stringify_array($unsafetags,true) . ") "; } } - - - $key = __FUNCTION__ . "-" . md5($site . $recent . $safemode . $limit . $type); - $content = Cache::get($key, '1 MINUTE'); - - if(! $content) { - // Fetch tags - $r = q("SELECT term, count(term) AS total FROM term LEFT JOIN item ON term.oid = item.id - where term.ttype = %d - and otype = %d and item_type = %d - $sql_extra $uids $item_normal - group by term order by total desc %s", - intval($type), - intval(TERM_OBJ_POST), - intval(ITEM_TYPE_POST), - ((intval($count)) ? "limit $count" : '') - ); - } else - $r = unserialize($content); - - if(! $r) - return array(); - else - Cache::set($key, serialize($r)); + + $key = __FUNCTION__ . "-" . md5($site . $recent . $safemode . $limit . $type); + + $content = Cache::get($key, '1 MINUTE'); + if(! $content) { + + $content = Cache::get($key, '1 WEEK'); + $arr = [ + "SELECT term, count(term) AS total FROM term LEFT JOIN item ON term.oid = item.id + WHERE term.ttype = %d + AND otype = %d + AND item_type = %d + $sql_extra $uids $item_normal + GROUP BY term ORDER BY total DESC %s", + intval($type), + intval(TERM_OBJ_POST), + intval(ITEM_TYPE_POST), + (intval($count) ? "LIMIT $count" : '') + ]; + + \Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, $arr ]); + } + + $r = unserialize($content); + if(! $r) + return []; return Zotlabs\Text\Tagadelic::calc($r); } -- cgit v1.2.3 From 93ac3c985fd35a9826c5421360da368ff07dd315 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 22 Jan 2021 10:06:50 +0000 Subject: implement externals via zot6 and zotfeed - part 1 --- Zotlabs/Daemon/Convo.php | 58 ++++++ Zotlabs/Daemon/Cron.php | 6 +- Zotlabs/Daemon/Externals.php | 148 ++++++++++++---- Zotlabs/Lib/Activity.php | 414 ++++++++++++++++++++++++++++++++++++++----- Zotlabs/Module/Zotfeed.php | 4 +- 5 files changed, 546 insertions(+), 84 deletions(-) create mode 100644 Zotlabs/Daemon/Convo.php diff --git a/Zotlabs/Daemon/Convo.php b/Zotlabs/Daemon/Convo.php new file mode 100644 index 000000000..f7478d778 --- /dev/null +++ b/Zotlabs/Daemon/Convo.php @@ -0,0 +1,58 @@ +get(); + + if ($messages) { + foreach ($messages as $message) { + if (is_string($message)) { + $message = Activity::fetch($message, $channel); + } + // set client flag because comments will probably just be objects and not full blown activities + // and that lets us use implied_create + $AS = new ActivityStreams($message); + if ($AS->is_valid() && is_array($AS->obj)) { + $item = Activity::decode_note($AS, true); + Activity::store($channel, $contact['abook_xchan'], $AS, $item); + } + } + } + } +} diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index cd7a710d3..2c0422ddd 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -201,7 +201,7 @@ class Cron { require_once('include/photo/photo_driver.php'); foreach ($r as $rr) { $photos = import_xchan_photo($rr['xchan_photo_l'], $rr['xchan_hash'], false, true); - $x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' + q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), @@ -219,8 +219,6 @@ class Cron { if (!$disable_discover_tab) Master::Summon(array('Externals')); - $generation = 0; - $restart = false; if (($argc > 1) && ($argv[1] == 'restart')) { @@ -232,8 +230,6 @@ class Cron { reload_plugins(); - $d = datetime_convert(); - // TODO check to see if there are any cronhooks before wasting a process if (!$restart) diff --git a/Zotlabs/Daemon/Externals.php b/Zotlabs/Daemon/Externals.php index 3d6b0bd7b..da05cad18 100644 --- a/Zotlabs/Daemon/Externals.php +++ b/Zotlabs/Daemon/Externals.php @@ -2,7 +2,10 @@ namespace Zotlabs\Daemon; -require_once('include/zot.php'); +use Zotlabs\Lib\Activity; +use Zotlabs\Lib\ActivityStreams; +use Zotlabs\Lib\ASCollection; + require_once('include/channel.php'); @@ -10,6 +13,9 @@ class Externals { static public function run($argc, $argv) { + logger('externals: start'); + + $importer = get_sys_channel(); $total = 0; $attempts = 0; @@ -27,12 +33,15 @@ class Externals { else { $randfunc = db_getfunc('RAND'); - // fixme this query does not deal with directory realms. + // fixme this query does not deal with directory realms. - $r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1", + $r = q("select site_url, site_pull from site where site_url != '%s' + and site_flags != %d and site_type = %d + and site_dead = 0 and site_project like '%s' and site_version > '5.3.1' order by $randfunc limit 1", dbesc(z_root()), intval(DIRECTORY_MODE_STANDALONE), - intval(SITE_TYPE_ZOT) + intval(SITE_TYPE_ZOT), + dbesc('hubzilla%') ); if ($r) $url = $r[0]['site_url']; @@ -57,41 +66,116 @@ class Externals { } if ($url) { - if ($r[0]['site_pull'] > NULL_DATE) - $mindate = urlencode(datetime_convert('', '', $r[0]['site_pull'] . ' - 1 day')); - else { - $days = get_config('externals', 'since_days'); - if ($days === false) - $days = 15; - $mindate = urlencode(datetime_convert('', '', 'now - ' . intval($days) . ' days')); + + $max = intval(get_config('system', 'max_imported_posts', 30)); + if (intval($max)) { + logger('externals: fetching outbox'); + + $feed_url = $url . '/zotfeed'; + $obj = new ASCollection($feed_url, $importer, 0, $max); + $messages = $obj->get(); + + if ($messages) { + foreach ($messages as $message) { + if (is_string($message)) { + $message = Activity::fetch($message, $importer); + } + $AS = new ActivityStreams($message); + if ($AS->is_valid() && is_array($AS->obj)) { + $item = Activity::decode_note($AS); + Activity::store($importer, $importer['xchan_hash'], $AS, $item, true); + $total++; + } + } + } + logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG); } + } + } + return; + + /* $total = 0; + $attempts = 0; + + logger('externals: startup', LOGGER_DEBUG); + + // pull in some public posts + + while ($total == 0 && $attempts < 3) { + $arr = ['url' => '']; + call_hooks('externals_url_select', $arr); - $feedurl = $url . '/zotfeed?f=&mindate=' . $mindate; + if ($arr['url']) { + $url = $arr['url']; + } + else { + $randfunc = db_getfunc('RAND'); + + // fixme this query does not deal with directory realms. + + $r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1", + dbesc(z_root()), + intval(DIRECTORY_MODE_STANDALONE), + intval(SITE_TYPE_ZOT) + ); + if ($r) + $url = $r[0]['site_url']; + } + + $blacklisted = false; - logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG); + if (!check_siteallowed($url)) { + logger('blacklisted site: ' . $url); + $blacklisted = true; + } + + $attempts++; - $x = z_fetch_url($feedurl); - if (($x) && ($x['success'])) { + // make sure we can eventually break out if somebody blacklists all known sites - q("update site set site_pull = '%s' where site_url = '%s'", - dbesc(datetime_convert()), - dbesc($url) - ); + if ($blacklisted) { + if ($attempts > 20) + break; + $attempts--; + continue; + } - $j = json_decode($x['body'], true); - if ($j['success'] && $j['messages']) { - $sys = get_sys_channel(); - foreach ($j['messages'] as $message) { - // on these posts, clear any route info. - $message['route'] = ''; - process_delivery(['hash' => 'undefined'], get_item_elements($message), - [['hash' => $sys['xchan_hash']]], false, true); - $total++; + if ($url) { + if ($r[0]['site_pull'] > NULL_DATE) + $mindate = urlencode(datetime_convert('', '', $r[0]['site_pull'] . ' - 1 day')); + else { + $days = get_config('externals', 'since_days'); + if ($days === false) + $days = 15; + $mindate = urlencode(datetime_convert('', '', 'now - ' . intval($days) . ' days')); + } + + $feedurl = $url . '/zotfeed?f=&mindate=' . $mindate; + + logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG); + + $x = z_fetch_url($feedurl); + if (($x) && ($x['success'])) { + + q("update site set site_pull = '%s' where site_url = '%s'", + dbesc(datetime_convert()), + dbesc($url) + ); + + $j = json_decode($x['body'], true); + if ($j['success'] && $j['messages']) { + $sys = get_sys_channel(); + foreach ($j['messages'] as $message) { + // on these posts, clear any route info. + $message['route'] = ''; + process_delivery(['hash' => 'undefined'], get_item_elements($message), + [['hash' => $sys['xchan_hash']]], false, true); + $total++; + } + logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG); + } } - logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG); } - } - } - } + }*/ } } diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index aa121d98b..d552a9b3c 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2481,34 +2481,168 @@ class Activity { } - static function store($channel, $observer_hash, $act, $item, $fetch_parents = true) { + static function store($channel, $observer_hash, $act, $item, $fetch_parents = true, $force = false) { $is_sys_channel = is_sys_channel($channel['channel_id']); + $is_child_node = false; + + // TODO: not implemented + // Pleroma scrobbles can be really noisy and contain lots of duplicate activities. Disable them by default. + /*if (($act->type === 'Listen') && ($is_sys_channel || get_pconfig($channel['channel_id'], 'system', 'allow_scrobbles', false))) { + return; + }*/ // Mastodon only allows visibility in public timelines if the public inbox is listed in the 'to' field. // They are hidden in the public timeline if the public inbox is listed in the 'cc' field. // This is not part of the activitypub protocol - we might change this to show all public posts in pubstream at some point. $pubstream = ((is_array($act->obj) && array_key_exists('to', $act->obj) && in_array(ACTIVITY_PUBLIC_INBOX, $act->obj['to'])) ? true : false); - $is_parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false); - if ($is_parent && (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !($is_sys_channel && $pubstream))) { + // TODO: this his handled in pubcrawl atm. + // very unpleasant and imperfect way of determining a Mastodon DM + /*if ($act->raw_recips && array_key_exists('to',$act->raw_recips) && is_array($act->raw_recips['to']) && count($act->raw_recips['to']) === 1 && $act->raw_recips['to'][0] === channel_url($channel) && ! $act->raw_recips['cc']) { + $item['item_private'] = 2; + }*/ + + // TODO: remove + // $is_parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false); + + if ($item['parent_mid'] && $item['parent_mid'] !== $item['mid']) { + $is_child_node = true; + } + + $allowed = false; + + // TODO: not implemented + // $permit_mentions = intval(PConfig::Get($channel['channel_id'], 'system','permit_all_mentions') && i_am_mentioned($channel,$item)); + + if ($is_child_node) { + $p = q("select * from item where mid = '%s' and uid = %d and item_wall = 1", + dbesc($item['parent_mid']), + intval($channel['channel_id']) + ); + if ($p) { + // check permissions against the author, not the sender + $allowed = perm_is_allowed($channel['channel_id'], $item['author_xchan'], 'post_comments'); + if ((!$allowed)/* && $permit_mentions*/) { + if ($p[0]['owner_xchan'] === $channel['channel_hash']) { + $allowed = false; + } + else { + $allowed = true; + } + } + + // TODO: not implemented + /*if (absolutely_no_comments($p[0])) { + $allowed = false; + }*/ + + if (!$allowed) { + logger('rejected comment from ' . $item['author_xchan'] . ' for ' . $channel['channel_address']); + logger('rejected: ' . print_r($item, true), LOGGER_DATA); + + // TODO: not implemented + // let the sender know we received their comment but we don't permit spam here. + // self::send_rejection_activity($channel,$item['author_xchan'],$item); + return; + } + + // TODO: not implemented + /*if (perm_is_allowed($channel['channel_id'],$item['author_xchan'],'moderated')) { + $item['item_blocked'] = ITEM_MODERATED; + }*/ + } + else { + $allowed = true; + // reject public stream comments that weren't sent by the conversation owner + if ($is_sys_channel && $pubstream && $item['owner_xchan'] !== $observer_hash) { + // TODO: check why? This would make it impossible to fetch externals via zotfeed where $observer_hash = sys channel + // $allowed = false; + } + } + + if ($p && $p[0]['obj_type'] === 'Question') { + if ($item['obj_type'] === 'Note' && $item['title'] && (!$item['content'])) { + $item['obj_type'] = 'Answer'; + } + } + } + else { + // The $item['item_fetched'] flag is set in fetch_and_store_parents(). + // In this case we should check against author permissions because sender is not owner. + if (perm_is_allowed($channel['channel_id'], (($item['item_fetched']) ? $item['author_xchan'] : $observer_hash), 'send_stream') || ($is_sys_channel && $pubstream)) { + $allowed = true; + } + // TODO: not implemented + /*if ($permit_mentions) { + $allowed = true; + }*/ + } + + // TODO: remove + /*if ($is_parent && (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !($is_sys_channel && $pubstream))) { logger('no permission'); return; + }*/ + + if (tgroup_check($channel['channel_id'], $item) && (!$is_child_node)) { + // for forum deliveries, make sure we keep a copy of the signed original + set_iconfig($item, 'activitypub', 'rawmsg', $act->raw, 1); + $allowed = true; } - if (is_array($act->obj)) { + // TODO: not implemented + /*if (intval($channel['channel_system'])) { + + if (! check_pubstream_channelallowed($observer_hash)) { + $allowed = false; + } + + // don't allow pubstream posts if the sender even has a clone on a pubstream denied site + + $h = q("select hubloc_url from hubloc where hubloc_hash = '%s'", + dbesc($observer_hash) + ); + if ($h) { + foreach ($h as $hub) { + if (! check_pubstream_siteallowed($hub['hubloc_url'])) { + $allowed = false; + break; + } + } + } + }*/ + + // TODO: not implemented + /*$blocked = LibBlock::fetch($channel['channel_id'],BLOCKTYPE_SERVER); + if ($blocked) { + foreach($blocked as $b) { + if (strpos($observer_hash,$b['block_entity']) !== false) { + $allowed = false; + } + } + }*/ + + if (!$allowed && !$force) { + logger('no permission'); + return; + } + + // TODO: remove + /*if (is_array($act->obj)) { $content = self::get_content($act->obj); } if (!$content) { logger('no content'); return; - } + }*/ $item['aid'] = $channel['channel_account_id']; $item['uid'] = $channel['channel_id']; - // Make sure we use the zot6 identity where applicable + // Some authors may be zot6 authors in which case we want to store their nomadic identity + // instead of their ActivityPub identity $item['author_xchan'] = self::find_best_identity($item['author_xchan']); $item['owner_xchan'] = self::find_best_identity($item['owner_xchan']); @@ -2543,18 +2677,35 @@ class Activity { } } - if ($act->obj['conversation']) { set_iconfig($item, 'ostatus', 'conversation', $act->obj['conversation'], 1); } // This isn't perfect but the best we can do for now. - $item['comment_policy'] = 'authenticated'; set_iconfig($item, 'activitypub', 'recips', $act->raw_recips); - if (!$is_parent) { + // TODO: inheritPrivacy should probably be set in encode activity. Zap does not do so yet - check what this is about + if (!(isset($act->data['inheritPrivacy']) && $act->data['inheritPrivacy'])) { + if ($item['item_private']) { + $item['item_restrict'] = $item['item_restrict'] & 1; + if ($is_child_node) { + $item['allow_cid'] = '<' . $channel['channel_hash'] . '>'; + $item['allow_gid'] = $item['deny_cid'] = $item['deny_gid'] = ''; + } + logger('restricted'); + } + } + + if (intval($act->sigok)) { + $item['item_verified'] = 1; + } + + $parent = null; + + // TODO: remove + /*if (!$is_parent) { $p = q("select parent_mid, id, obj_type from item where mid = '%s' and uid = %d limit 1", dbesc($item['parent_mid']), intval($item['uid']) @@ -2586,14 +2737,12 @@ class Activity { } } - if ($p[0]['obj_type'] === 'Question') { if ($item['obj_type'] === ACTIVITY_OBJ_NOTE && $item['title'] && (!$item['content'])) { $item['obj_type'] = 'Answer'; } } - if ($p[0]['parent_mid'] !== $item['parent_mid']) { $item['thr_parent'] = $item['parent_mid']; } @@ -2601,8 +2750,50 @@ class Activity { $item['thr_parent'] = $p[0]['parent_mid']; } $item['parent_mid'] = $p[0]['parent_mid']; + }*/ + + if ($is_child_node) { + + $parent = q("select * from item where mid = '%s' and uid = %d limit 1", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + if (!$parent) { + if (!plugin_is_installed('pubcrawl')) { + return; + } + else { + $fetch = false; + // TODO: debug + // if (perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && (PConfig::Get($channel['channel_id'],'system','hyperdrive',true)*/ || $act->type === 'Announce')) { + if (perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') || ($is_sys_channel && $pubstream)) { + $fetch = (($fetch_parents) ? self::fetch_and_store_parents($channel, $observer_hash, $item) : false); + } + if ($fetch) { + $parent = q("select * from item where mid = '%s' and uid = %d limit 1", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + } + else { + logger('no parent'); + return; + } + } + } + + if ($parent[0]['parent_mid'] !== $item['parent_mid']) { + $item['thr_parent'] = $item['parent_mid']; + } + else { + $item['thr_parent'] = $parent[0]['parent_mid']; + } + $item['parent_mid'] = $parent[0]['parent_mid']; } + // TODO: not implemented + // self::rewrite_mentions($item); + $r = q("select id, created, edited from item where mid = '%s' and uid = %d limit 1", dbesc($item['mid']), intval($item['uid']) @@ -2620,8 +2811,51 @@ class Activity { $x = item_store($item); } + // TODO: remove + /*$r = q("select id, created, edited from item where mid = '%s' and uid = %d limit 1", + dbesc($item['mid']), + intval($item['uid']) + ); + if ($r) { + if ($item['edited'] > $r[0]['edited']) { + $item['id'] = $r[0]['id']; + $x = item_store_update($item); + } + else { + return; + } + } + else { + $x = item_store($item); + }*/ + + if ($fetch_parents && $parent && !intval($parent[0]['item_private'])) { + logger('topfetch', LOGGER_DEBUG); + // if the thread owner is a connnection, we will already receive any additional comments to their posts + // but if they are not we can try to fetch others in the background + $x = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1", + intval($channel['channel_id']), + dbesc($parent[0]['owner_xchan']) + ); + if (!$x) { + // determine if the top-level post provides a replies collection + if ($parent[0]['obj']) { + $parent[0]['obj'] = json_decode($parent[0]['obj'], true); + } + logger('topfetch: ' . print_r($parent[0], true), LOGGER_ALL); + $id = ((array_path_exists('obj/replies/id', $parent[0])) ? $parent[0]['obj']['replies']['id'] : false); + if (!$id) { + $id = ((array_path_exists('obj/replies', $parent[0]) && is_string($parent[0]['obj']['replies'])) ? $parent[0]['obj']['replies'] : false); + } + if ($id) { + Master::Summon(['Convo', $id, $channel['channel_id'], $observer_hash]); + } + } + } + if (is_array($x) && $x['item_id']) { - if ($is_parent) { + if ($is_child_node) { if ($item['owner_xchan'] === $channel['channel_hash']) { // We are the owner of this conversation, so send all received comments back downstream Master::Summon(['Notifier', 'comment-import', $x['item_id']]); @@ -2636,10 +2870,26 @@ class Activity { sync_an_item($channel['channel_id'], $x['item_id']); } - } + // TODO: remove + /*if (is_array($x) && $x['item_id']) { + if ($is_parent) { + if ($item['owner_xchan'] === $channel['channel_hash']) { + // We are the owner of this conversation, so send all received comments back downstream + Master::Summon(['Notifier', 'comment-import', $x['item_id']]); + } + $r = q("select * from item where id = %d limit 1", + intval($x['item_id']) + ); + if ($r) { + send_status_notifications($x['item_id'], $r[0]); + } + } + sync_an_item($channel['channel_id'], $x['item_id']); + }*/ - static public function fetch_and_store_parents($channel, $item) { + } + static public function fetch_and_store_parents($channel, $observer_hash, $item) { logger('fetching parents'); $p = []; @@ -2647,42 +2897,35 @@ class Activity { $current_item = $item; while ($current_item['parent_mid'] !== $current_item['mid']) { - $n = self::fetch($current_item['parent_mid'], $channel); + $n = self::fetch($current_item['parent_mid']); if (!$n) { break; } - $a = new ActivityStreams($n); + // set client flag to convert objects to implied activities + $a = new ActivityStreams($n, null, true); + if ($a->type === 'Announce' && is_array($a->obj) + && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)) { + // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) + // Reparse the encapsulated Activity and use that instead + logger('relayed activity', LOGGER_DEBUG); + $a = new ActivityStreams($a->obj, null, true); + } - //logger($a->debug()); + logger($a->debug(), LOGGER_DATA); if (!$a->is_valid()) { + logger('not a valid activity'); break; } - if (is_array($a->actor) && array_key_exists('id', $a->actor)) { - self::actor_store($a->actor['id'], $a->actor); - } - - $replies = null; - if (isset($a->obj['replies']['first']['items'])) { - $replies = $a->obj['replies']['first']['items']; - // we already have this one - array_diff($replies, [$current_item['mid']]); + Activity::actor_store($a->actor['id'], $a->actor); } - $item = null; - - switch ($a->type) { - case 'Create': - case 'Update': - //case 'Like': - //case 'Dislike': - case 'Announce': - $item = self::decode_note($a); - break; - default: - break; + // ActivityPub sourced items are cacheable + $item = Activity::decode_note($a); + if (!$item) { + break; } $hookinfo = [ @@ -2695,22 +2938,22 @@ class Activity { $item = $hookinfo['item']; if ($item) { + $item['item_fetched'] = 1; + array_unshift($p, [$a, $item]); - array_unshift($p, [$a, $item, $replies]); - - if ($item['parent_mid'] === $item['mid'] || count($p) > 20) { + if ($item['parent_mid'] === $item['mid'] || count($p) > 100) { break; } - } + $current_item = $item; } if ($p) { foreach ($p as $pv) { - self::store($channel, $pv[0]->actor['id'], $pv[0], $pv[1], false); - if ($pv[2]) - self::fetch_and_store_replies($channel, $pv[2]); + if ($pv[0]->is_valid()) { + Activity::store($channel, $observer_hash, $pv[0], $pv[1], false); + } } return true; } @@ -2718,6 +2961,87 @@ class Activity { return false; } + /* + static public function fetch_and_store_parents($channel, $item) { + + logger('fetching parents'); + + $p = []; + + $current_item = $item; + + while ($current_item['parent_mid'] !== $current_item['mid']) { + $n = self::fetch($current_item['parent_mid'], $channel); + if (!$n) { + break; + } + $a = new ActivityStreams($n); + + //logger($a->debug()); + + if (!$a->is_valid()) { + break; + } + + if (is_array($a->actor) && array_key_exists('id', $a->actor)) { + self::actor_store($a->actor['id'], $a->actor); + } + + $replies = null; + if (isset($a->obj['replies']['first']['items'])) { + $replies = $a->obj['replies']['first']['items']; + // we already have this one + array_diff($replies, [$current_item['mid']]); + } + + $item = null; + + switch ($a->type) { + case 'Create': + case 'Update': + //case 'Like': + //case 'Dislike': + case 'Announce': + $item = self::decode_note($a); + break; + default: + break; + + } + + $hookinfo = [ + 'a' => $a, + 'item' => $item + ]; + + call_hooks('fetch_and_store', $hookinfo); + + $item = $hookinfo['item']; + + if ($item) { + + array_unshift($p, [$a, $item, $replies]); + + if ($item['parent_mid'] === $item['mid'] || count($p) > 20) { + break; + } + + } + $current_item = $item; + } + + if ($p) { + foreach ($p as $pv) { + self::store($channel, $pv[0]->actor['id'], $pv[0], $pv[1], false); + if ($pv[2]) + self::fetch_and_store_replies($channel, $pv[2]); + } + return true; + } + + return false; + } + */ static public function fetch_and_store_replies($channel, $arr) { logger('fetching replies'); diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php index 6f4cd9fc4..6a2d17101 100644 --- a/Zotlabs/Module/Zotfeed.php +++ b/Zotlabs/Module/Zotfeed.php @@ -77,10 +77,10 @@ class Zotfeed extends Controller { if ($total) { App::set_pager_total($total); - App::set_pager_itemspage(100); + App::set_pager_itemspage(10); } - if (App::$pager['unset'] && $total > 100) { + if (App::$pager['unset'] && $total > 10) { $ret = Activity::paged_collection_init($total, App::$query_string); } else { -- cgit v1.2.3 From 064effe5fd861be2623c7bd1f8a6037e6d470c29 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 22 Jan 2021 10:11:27 +0000 Subject: fix encode_item_collection() --- Zotlabs/Lib/Activity.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index d552a9b3c..197409a19 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -267,7 +267,7 @@ class Activity { static function encode_item_collection($items, $id, $type, $total = 0) { - if ($total > 100) { + if ($total > 30) { $ret = [ 'id' => z_root() . '/' . $id, 'type' => $type . 'Page', @@ -300,11 +300,17 @@ class Activity { $x = []; foreach ($items as $i) { $m = get_iconfig($i['id'], 'activitypub', 'rawmsg'); - if (is_string($m)) { - $t = json_decode($m, true); + if ($m) { + if (is_string($m)) + $t = json_decode($m,true); + else + $t = $m; } else { - $t = $m; + $t = self::encode_activity($i); + } + if ($t) { + $x[] = $t; } if ($t) { $x[] = $t; -- cgit v1.2.3 From e6aed4fb8ef5853f27100a2b9e2903323c874ce8 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 22 Jan 2021 11:12:39 +0100 Subject: implement externals via zot6 and zotfeed - part 2 --- Zotlabs/Module/Zotfeed.php | 42 ++++++++++++++++++++++++------------ boot.php | 2 +- include/items.php | 54 +++++++++++++++++++++++++++++++--------------- 3 files changed, 66 insertions(+), 32 deletions(-) diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php index 6f4cd9fc4..e838ae34c 100644 --- a/Zotlabs/Module/Zotfeed.php +++ b/Zotlabs/Module/Zotfeed.php @@ -19,19 +19,11 @@ class Zotfeed extends Controller { killme(); } - if (argc() < 2) { - killme(); - } - - $channel = channelx_by_nick(argv(1)); + $channel = ((argv(1)) ? channelx_by_nick(argv(1)) : get_sys_channel()); if (!$channel) { killme(); } - if (intval($channel['channel_system'])) { - killme(); - } - $sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR); if ($sigdata['portable_id'] && $sigdata['header_valid']) { $portable_id = $sigdata['portable_id']; @@ -60,10 +52,32 @@ class Zotfeed extends Controller { $params['cat'] = ((x($_REQUEST, 'cat')) ? escape_tags($_REQUEST['cat']) : ''); $params['compat'] = 1; + if (intval($channel['channel_system'])) { + $total = zot_feed($channel['channel_id'], $observer_hash, ['total' => true]); + + if ($total) { + App::set_pager_total($total); + App::set_pager_itemspage(30); + } + + if (App::$pager['unset'] && $total > 30) { + $ret = Activity::paged_collection_init($total, App::$query_string); + + } + else { + $items = zot_feed($channel['channel_id'], $observer_hash, []); + $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); + } + + as_return_and_die($ret, $channel); + + return; + } + $total = items_fetch( [ 'total' => true, - 'wall' => '1', + 'wall' => 1, 'datequery' => $params['end'], 'datequery2' => $params['begin'], 'direction' => dbesc($params['direction']), @@ -77,16 +91,17 @@ class Zotfeed extends Controller { if ($total) { App::set_pager_total($total); - App::set_pager_itemspage(100); + App::set_pager_itemspage(30); } - if (App::$pager['unset'] && $total > 100) { + if (App::$pager['unset'] && $total > 30) { $ret = Activity::paged_collection_init($total, App::$query_string); } else { + $items = items_fetch( [ - 'wall' => '1', + 'wall' => 1, 'datequery' => $params['end'], 'datequery2' => $params['begin'], 'records' => intval(App::$pager['itemspage']), @@ -99,7 +114,6 @@ class Zotfeed extends Controller { 'compat' => $params['compat'] ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module ); - $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); } diff --git a/boot.php b/boot.php index cd2704783..07bb2b7e2 100755 --- a/boot.php +++ b/boot.php @@ -50,7 +50,7 @@ require_once('include/attach.php'); require_once('include/bbcode.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '5.3.1' ); +define ( 'STD_VERSION', '5.3.2' ); define ( 'ZOT_REVISION', '6.0' ); define ( 'DB_UPDATE_VERSION', 1240 ); diff --git a/include/items.php b/include/items.php index 5b9bbd1f9..370aa5a93 100755 --- a/include/items.php +++ b/include/items.php @@ -4354,6 +4354,7 @@ function zot_feed($uid, $observer_hash, $arr) { if(! is_sys_channel($uid)) $sql_extra = item_permissions_sql($uid,$observer_hash); + $limit = " LIMIT 5000 "; if($mindate > NULL_DATE) { @@ -4375,17 +4376,38 @@ function zot_feed($uid, $observer_hash, $arr) { $item_normal = item_normal(); if(is_sys_channel($uid)) { - $nonsys_uids = q("SELECT channel_id FROM channel WHERE channel_system = 0"); $nonsys_uids_str = ids_to_querystr($nonsys_uids,'channel_id'); - $r = q("SELECT parent, postopts FROM item + if ($arr['total']) { + $items = q("SELECT count(created) AS total FROM item + WHERE uid IN ( %s ) + AND item_private = 0 + $sql_extra $item_normal", + dbesc($nonsys_uids_str) + ); + if ($items) { + return intval($items[0]['total']); + } + return 0; + } + + $itemspage = (($channel) ? get_pconfig($uid,'system','itemspage') : 30); + App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 30)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); + + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE uid IN ( %s ) AND item_private = 0 - $item_normal - $sql_extra ORDER BY created ASC $limit", - intval($nonsys_uids_str) + $item_normal $sql_extra + ORDER BY item.created DESC $pager_sql", + dbesc($nonsys_uids_str) ); + + xchan_query($items); + $items = fetch_post_tags($items,true); + + return $items; } else { $r = q("SELECT parent, postopts FROM item @@ -4411,7 +4433,6 @@ function zot_feed($uid, $observer_hash, $arr) { $parents_str = ids_to_querystr($parents,'parent'); $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); - $item_normal = item_normal(); $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal $sys_query ", @@ -4563,8 +4584,8 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $pager_sql = ''; } else { if(! $arr['total']) { - $itemspage = (($channel) ? get_pconfig($uid,'system','itemspage') : 20); - App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $itemspage = (($channel) ? get_pconfig($uid,'system','itemspage') : 10); + App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10)); $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); } } @@ -4602,7 +4623,6 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C require_once('include/security.php'); $sql_extra .= item_permissions_sql($channel['channel_id'],$observer_hash); - if($arr['pages']) $item_restrict = " AND item_type = " . ITEM_TYPE_WEBPAGE . " "; else @@ -4616,7 +4636,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C // "New Item View" - show all items unthreaded in reverse created date order if ($arr['total']) { - $items = q("SELECT count(item.id) AS total FROM item + $items = dbq("SELECT count(item.id) AS total FROM item WHERE $item_uids $item_restrict $simple_update $sql_extra $sql_nets $sql_extra3" @@ -4627,11 +4647,11 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C return 0; } - $items = q("SELECT item.*, item.id AS item_id FROM item - WHERE $item_uids $item_restrict - $simple_update - $sql_extra $sql_nets $sql_extra3 - ORDER BY item.received DESC $pager_sql" + $items = dbq("SELECT item.*, item.id AS item_id FROM item + WHERE $item_uids $item_restrict + $simple_update + $sql_extra $sql_nets $sql_extra3 + ORDER BY item.received DESC $pager_sql" ); require_once('include/items.php'); @@ -4652,7 +4672,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C // Fetch a page full of parent items for this page - $r = q("SELECT distinct item.id AS item_id, item.$ordering FROM item + $r = dbq("SELECT distinct item.id AS item_id, item.$ordering FROM item left join abook on item.author_xchan = abook.abook_xchan WHERE $item_uids $item_restrict AND item.parent = item.id @@ -4663,7 +4683,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C } else { // update - $r = q("SELECT item.parent AS item_id FROM item + $r = dbq("SELECT item.parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan WHERE $item_uids $item_restrict $simple_update and (abook.abook_blocked = 0 or abook.abook_flags is null) -- cgit v1.2.3 From 92f420f77c830163fe7d58d98ed3eefb4d79bbed Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 22 Jan 2021 10:42:58 +0000 Subject: cleanup --- Zotlabs/Daemon/Externals.php | 2 +- Zotlabs/Module/Zotfeed.php | 4 +-- include/items.php | 70 +++++++++++++++++++++----------------------- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/Zotlabs/Daemon/Externals.php b/Zotlabs/Daemon/Externals.php index da05cad18..064b3f71d 100644 --- a/Zotlabs/Daemon/Externals.php +++ b/Zotlabs/Daemon/Externals.php @@ -37,7 +37,7 @@ class Externals { $r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d - and site_dead = 0 and site_project like '%s' and site_version > '5.3.1' order by $randfunc limit 1", + and site_dead = 0 and site_project like '%s' and site_version > '5.3.1' order by $randfunc limit 1", dbesc(z_root()), intval(DIRECTORY_MODE_STANDALONE), intval(SITE_TYPE_ZOT), diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php index e838ae34c..17b0e3057 100644 --- a/Zotlabs/Module/Zotfeed.php +++ b/Zotlabs/Module/Zotfeed.php @@ -66,7 +66,7 @@ class Zotfeed extends Controller { } else { $items = zot_feed($channel['channel_id'], $observer_hash, []); - $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); + $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); } as_return_and_die($ret, $channel); @@ -114,7 +114,7 @@ class Zotfeed extends Controller { 'compat' => $params['compat'] ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module ); - $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); + $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); } as_return_and_die($ret, $channel); diff --git a/include/items.php b/include/items.php index 370aa5a93..7229b66eb 100755 --- a/include/items.php +++ b/include/items.php @@ -4318,55 +4318,54 @@ function fetch_post_tags($items, $link = false) { */ function zot_feed($uid, $observer_hash, $arr) { - $result = array(); - $mindate = null; + $result = []; + $mindate = null; $message_id = null; - $wall = true; + $wall = true; require_once('include/security.php'); - if(array_key_exists('mindate',$arr)) { - $mindate = datetime_convert('UTC','UTC',$arr['mindate']); + if (array_key_exists('mindate', $arr)) { + $mindate = datetime_convert('UTC', 'UTC', $arr['mindate']); } - if(array_key_exists('message_id',$arr)) { + if (array_key_exists('message_id', $arr)) { $message_id = $arr['message_id']; } - if(array_key_exists('wall',$arr)) { + if (array_key_exists('wall', $arr)) { $wall = intval($arr['wall']); } - if(! $mindate) + if (!$mindate) $mindate = NULL_DATE; $mindate = dbesc($mindate); logger('zot_feed: requested for uid ' . $uid . ' from observer ' . $observer_hash, LOGGER_DEBUG); - if($message_id) - logger('message_id: ' . $message_id,LOGGER_DEBUG); + if ($message_id) + logger('message_id: ' . $message_id, LOGGER_DEBUG); - if(! perm_is_allowed($uid,$observer_hash,'view_stream')) { + if (!perm_is_allowed($uid, $observer_hash, 'view_stream')) { logger('zot_feed: permission denied.'); return $result; } - if(! is_sys_channel($uid)) - $sql_extra = item_permissions_sql($uid,$observer_hash); - + if (!is_sys_channel($uid)) + $sql_extra = item_permissions_sql($uid, $observer_hash); $limit = " LIMIT 5000 "; - if($mindate > NULL_DATE) { + if ($mindate > NULL_DATE) { $sql_extra .= " and ( created > '$mindate' or changed > '$mindate' ) "; } - if($message_id) { + if ($message_id) { $sql_extra .= " and mid = '" . dbesc($message_id) . "' "; - $limit = ''; + $limit = ''; } - if($wall) { + if ($wall) { $sql_extra .= " and item_wall = 1 "; } @@ -4375,9 +4374,9 @@ function zot_feed($uid, $observer_hash, $arr) { $item_normal = item_normal(); - if(is_sys_channel($uid)) { - $nonsys_uids = q("SELECT channel_id FROM channel WHERE channel_system = 0"); - $nonsys_uids_str = ids_to_querystr($nonsys_uids,'channel_id'); + if (is_sys_channel($uid)) { + $nonsys_uids = q("SELECT channel_id FROM channel WHERE channel_system = 0"); + $nonsys_uids_str = ids_to_querystr($nonsys_uids, 'channel_id'); if ($arr['total']) { $items = q("SELECT count(created) AS total FROM item @@ -4392,7 +4391,7 @@ function zot_feed($uid, $observer_hash, $arr) { return 0; } - $itemspage = (($channel) ? get_pconfig($uid,'system','itemspage') : 30); + $itemspage = (($uid) ? get_pconfig($uid, 'system', 'itemspage') : 30); App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 30)); $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); @@ -4405,7 +4404,7 @@ function zot_feed($uid, $observer_hash, $arr) { ); xchan_query($items); - $items = fetch_post_tags($items,true); + $items = fetch_post_tags($items, true); return $items; } @@ -4420,19 +4419,19 @@ function zot_feed($uid, $observer_hash, $arr) { $parents = []; - if($r) { - foreach($r as $rv) { - if(array_key_exists($rv['parent'],$parents)) + if ($r) { + foreach ($r as $rv) { + if (array_key_exists($rv['parent'], $parents)) continue; - if(strpos($rv['postopts'],'nodeliver') !== false) + if (strpos($rv['postopts'], 'nodeliver') !== false) continue; $parents[$rv['parent']] = $rv; - if(count($parents) > 200) + if (count($parents) > 200) break; } - $parents_str = ids_to_querystr($parents,'parent'); - $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); + $parents_str = ids_to_querystr($parents, 'parent'); + $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal $sys_query ", @@ -4440,25 +4439,24 @@ function zot_feed($uid, $observer_hash, $arr) { ); } - if($items) { + if ($items) { xchan_query($items); $items = fetch_post_tags($items); require_once('include/conversation.php'); - $items = conv_sort($items,'ascending'); + $items = conv_sort($items, 'ascending'); } else - $items = array(); + $items = []; - logger('zot_feed: number items: ' . count($items),LOGGER_DEBUG); + logger('zot_feed: number items: ' . count($items), LOGGER_DEBUG); - foreach($items as $item) + foreach ($items as $item) $result[] = encode_item($item); return $result; } - function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = CLIENT_MODE_NORMAL,$module = 'network') { $result = array('success' => false); -- cgit v1.2.3 From 3f34c73f095bfef8703e01d3d8750f3599095065 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Fri, 22 Jan 2021 15:37:49 +0100 Subject: Decode SQL query array --- Zotlabs/Daemon/Cache_query.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Zotlabs/Daemon/Cache_query.php b/Zotlabs/Daemon/Cache_query.php index 18d19cdf2..5f92ae6d0 100644 --- a/Zotlabs/Daemon/Cache_query.php +++ b/Zotlabs/Daemon/Cache_query.php @@ -24,8 +24,10 @@ class Cache_query { array_shift($argv); array_shift($argv); + + $arr = json_decode(base64_decode($argv[0]), true); - $r = call_user_func_array('q', $argv); + $r = call_user_func_array('q', $arr); if($r) Cache::set($key, serialize($r)); -- cgit v1.2.3 From bfb9f102343936b94064dd64765b235c45477839 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Fri, 22 Jan 2021 15:38:40 +0100 Subject: Encode SQL query array --- include/taxonomy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/taxonomy.php b/include/taxonomy.php index 5681db88c..88d0a9196 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -374,7 +374,7 @@ function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) { (intval($count) ? "LIMIT $count" : '') ]; - \Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, $arr ]); + \Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, base64_encode(json_encode($arr)) ]); } $r = unserialize($content); -- cgit v1.2.3 From 7bc03401062768b88b1ba46c2f5e24f4d6b133db Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Fri, 22 Jan 2021 15:39:48 +0100 Subject: Encode SQL query array --- include/contact_widgets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/contact_widgets.php b/include/contact_widgets.php index 0719d4011..a5f867b0f 100644 --- a/include/contact_widgets.php +++ b/include/contact_widgets.php @@ -97,7 +97,7 @@ function categories_widget($baseurl,$selected = '') { dbesc(ACTIVITY_UPDATE) ]; - \Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, $arr ]); + \Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, base64_encode(json_encode($arr)) ]); } $r = unserialize($content); -- cgit v1.2.3 From fbbc53838c04e6b85ac24a65fcf0c9c5795fdef7 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 23 Jan 2021 12:35:02 +0000 Subject: fix ramsey/uuid exception --- include/text.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/text.php b/include/text.php index d6b196f1e..1e08d136c 100644 --- a/include/text.php +++ b/include/text.php @@ -7,7 +7,7 @@ use Zotlabs\Lib as Zlib; use Michelf\MarkdownExtra; use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Zotlabs\Lib\SvgSanitizer; @@ -3824,7 +3824,7 @@ function new_uuid() { try { $hash = Uuid::uuid4()->toString(); - } catch (UnsatisfiedDependencyException $e) { + } catch (UnableToBuildUuidException $e) { $hash = random_string(48); } @@ -3842,7 +3842,7 @@ function uuid_from_url($url) { try { $hash = Uuid::uuid5(Uuid::NAMESPACE_URL, $url)->toString(); - } catch (UnsatisfiedDependencyException $e) { + } catch (UnableToBuildUuidException $e) { $hash = md5($url); } return $hash; -- cgit v1.2.3 From 893847c649a9f3eb99cbaa8fc3bb795bc3184b7a Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sat, 23 Jan 2021 13:58:05 +0100 Subject: Fix duplicate profile photos creation for clones --- Zotlabs/Lib/Libzot.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 8847f0975..150a6af03 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -667,9 +667,8 @@ class Libzot { $arr['connect_url'] = ''; if ($r) { - if ($arr['photo'] && array_key_exists('updated', $arr['photo']) && $r[0]['xchan_photo_date'] != $arr['photo']['updated']) { + if ($arr['photo'] && array_key_exists('updated', $arr['photo']) && $arr['photo']['updated'] > $r[0]['xchan_photo_date']) $import_photos = true; - } // if we import an entry from a site that's not ours and either or both of us is off the grid - hide the entry. /** @TODO: check if we're the same directory realm, which would mean we are allowed to see it */ -- cgit v1.2.3 From 33951dc1e4695bece701b85275d4c282c1936150 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sat, 23 Jan 2021 14:00:38 +0100 Subject: Remove duplicated profile photos --- Zotlabs/Update/_1241.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Zotlabs/Update/_1241.php diff --git a/Zotlabs/Update/_1241.php b/Zotlabs/Update/_1241.php new file mode 100644 index 000000000..1b2024aad --- /dev/null +++ b/Zotlabs/Update/_1241.php @@ -0,0 +1,24 @@ + Date: Sat, 23 Jan 2021 16:22:29 +0100 Subject: Bump DB update version --- boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot.php b/boot.php index 07bb2b7e2..490e847af 100755 --- a/boot.php +++ b/boot.php @@ -53,7 +53,7 @@ define ( 'PLATFORM_NAME', 'hubzilla' ); define ( 'STD_VERSION', '5.3.2' ); define ( 'ZOT_REVISION', '6.0' ); -define ( 'DB_UPDATE_VERSION', 1240 ); +define ( 'DB_UPDATE_VERSION', 1241 ); define ( 'PROJECT_BASE', __DIR__ ); -- cgit v1.2.3 From 74441f2f00fe1a8be4930879822fb6ef6040896c Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sat, 23 Jan 2021 21:38:03 +0100 Subject: Don't fetch profile photos from own hub --- Zotlabs/Lib/Libzot.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 150a6af03..ee1f54ec8 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -795,7 +795,10 @@ class Libzot { dbesc($xchan_hash) ); if ($local) { - $ph = z_fetch_url($arr['photo']['url'], true); + + $ph = false; + if (strpos($arr['photo']['url'], z_root()) === false) + $ph = z_fetch_url($arr['photo']['url'], true); if ($ph['success']) { $hash = import_channel_photo($ph['body'], $arr['photo']['type'], $local[0]['channel_account_id'], $local[0]['channel_id']); -- cgit v1.2.3 From e4ed5ed264bf660b893e18d85775f9b08c133564 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sat, 23 Jan 2021 21:45:20 +0100 Subject: Do not store multiple profile images thumbnails --- include/photo/photo_driver.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index f61919eea..542d932f6 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -401,8 +401,17 @@ function import_channel_photo($photo, $type, $aid, $uid) { logger('Importing channel photo for ' . $uid, LOGGER_DEBUG); + $r = q("SELECT resource_id FROM photo WHERE uid = %d AND photo_usage = %d AND imgscale = %d", + intval($uid), + intval(PHOTO_PROFILE), + intval(PHOTO_RES_PROFILE_300) + ); + if ($r) + hash = $r[0]['resource_id']; + else + $hash = photo_new_resource(); + $photo_failure = false; - $hash = photo_new_resource(); $filename = $hash; $img = photo_factory($photo, $type); -- cgit v1.2.3 From 0a13c794abe7dfd5e92c396d8a4ea6bfc9a3c11c Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sat, 23 Jan 2021 21:55:50 +0100 Subject: Variable typo --- include/photo/photo_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index 542d932f6..1ce2fd6e3 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -407,7 +407,7 @@ function import_channel_photo($photo, $type, $aid, $uid) { intval(PHOTO_RES_PROFILE_300) ); if ($r) - hash = $r[0]['resource_id']; + $hash = $r[0]['resource_id']; else $hash = photo_new_resource(); -- cgit v1.2.3 From 4fbedb67508fd670493bf3be4f6a91160c4f1024 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 24 Jan 2021 15:00:01 +0000 Subject: extra check for item_private in fetch_and_store_parents() --- Zotlabs/Lib/Activity.php | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 197409a19..46ce075fd 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2598,9 +2598,10 @@ class Activity { $allowed = true; } - // TODO: not implemented - /*if (intval($channel['channel_system'])) { + if ($is_sys_channel) { + + /* TODO: not implemented if (! check_pubstream_channelallowed($observer_hash)) { $allowed = false; } @@ -2618,7 +2619,12 @@ class Activity { } } } - }*/ + */ + + if (intval($item['item_private'])) { + $allowed = false; + } + } // TODO: not implemented /*$blocked = LibBlock::fetch($channel['channel_id'],BLOCKTYPE_SERVER); @@ -2945,9 +2951,20 @@ class Activity { if ($item) { $item['item_fetched'] = 1; - array_unshift($p, [$a, $item]); - if ($item['parent_mid'] === $item['mid'] || count($p) > 100) { + if (intval($channel['channel_system']) && intval($item['item_private'])) { + $p = []; + break; + } + + if (count($p) > 100) { + $p = []; + break; + } + + array_unshift($p,[ $a, $item ]); + + if ($item['parent_mid'] === $item['mid']) { break; } } -- cgit v1.2.3 From 2035828042e50f2c23f55d80b19fb898b170e6e5 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 24 Jan 2021 19:55:29 +0000 Subject: revert externals/zotfeed functionality due to scaling issues. Save zotfeed consumers that are not our contacts in thread listeners --- Zotlabs/Daemon/Cron.php | 3 ++- Zotlabs/Module/Zotfeed.php | 49 +++++++++++++++++++++++----------------------- include/items.php | 31 +++++------------------------ 3 files changed, 32 insertions(+), 51 deletions(-) diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index 2c0422ddd..4732dfa75 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -215,9 +215,10 @@ class Cron { // pull in some public posts - $disable_discover_tab = get_config('system', 'disable_discover_tab') || get_config('system', 'disable_discover_tab') === false; +/* $disable_discover_tab = get_config('system', 'disable_discover_tab') || get_config('system', 'disable_discover_tab') === false; if (!$disable_discover_tab) Master::Summon(array('Externals')); +*/ $restart = false; diff --git a/Zotlabs/Module/Zotfeed.php b/Zotlabs/Module/Zotfeed.php index 17b0e3057..2566924aa 100644 --- a/Zotlabs/Module/Zotfeed.php +++ b/Zotlabs/Module/Zotfeed.php @@ -6,13 +6,13 @@ use App; use Zotlabs\Lib\Activity; use Zotlabs\Lib\ActivityStreams; use Zotlabs\Lib\Config; +use Zotlabs\Lib\ThreadListener; use Zotlabs\Web\Controller; use Zotlabs\Web\HTTPSig; class Zotfeed extends Controller { function init() { - if (ActivityStreams::is_as_request()) { if (observer_prohibited(true)) { @@ -24,6 +24,10 @@ class Zotfeed extends Controller { killme(); } + if (intval($channel['channel_system'])) { + killme(); + } + $sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR); if ($sigdata['portable_id'] && $sigdata['header_valid']) { $portable_id = $sigdata['portable_id']; @@ -52,28 +56,6 @@ class Zotfeed extends Controller { $params['cat'] = ((x($_REQUEST, 'cat')) ? escape_tags($_REQUEST['cat']) : ''); $params['compat'] = 1; - if (intval($channel['channel_system'])) { - $total = zot_feed($channel['channel_id'], $observer_hash, ['total' => true]); - - if ($total) { - App::set_pager_total($total); - App::set_pager_itemspage(30); - } - - if (App::$pager['unset'] && $total > 30) { - $ret = Activity::paged_collection_init($total, App::$query_string); - - } - else { - $items = zot_feed($channel['channel_id'], $observer_hash, []); - $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); - } - - as_return_and_die($ret, $channel); - - return; - } - $total = items_fetch( [ 'total' => true, @@ -114,7 +96,26 @@ class Zotfeed extends Controller { 'compat' => $params['compat'] ], $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module ); - $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); + + if ($items && $observer_hash) { + + // check to see if this observer is a connection. If not, register any items + // belonging to this channel for notification of deletion/expiration + + $x = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + intval($channel['channel_id']), + dbesc($observer_hash) + ); + if (!$x) { + foreach ($items as $item) { + if (strpos($item['mid'], z_root()) === 0) { + ThreadListener::store($item['mid'], $observer_hash); + } + } + } + } + + $ret = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', $total); } as_return_and_die($ret, $channel); diff --git a/include/items.php b/include/items.php index 7229b66eb..83108455f 100755 --- a/include/items.php +++ b/include/items.php @@ -4375,38 +4375,17 @@ function zot_feed($uid, $observer_hash, $arr) { $item_normal = item_normal(); if (is_sys_channel($uid)) { + $nonsys_uids = q("SELECT channel_id FROM channel WHERE channel_system = 0"); $nonsys_uids_str = ids_to_querystr($nonsys_uids, 'channel_id'); - if ($arr['total']) { - $items = q("SELECT count(created) AS total FROM item - WHERE uid IN ( %s ) - AND item_private = 0 - $sql_extra $item_normal", - dbesc($nonsys_uids_str) - ); - if ($items) { - return intval($items[0]['total']); - } - return 0; - } - - $itemspage = (($uid) ? get_pconfig($uid, 'system', 'itemspage') : 30); - App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 30)); - $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); - - $items = q("SELECT item.*, item.id AS item_id FROM item + $r = q("SELECT parent, postopts FROM item WHERE uid IN ( %s ) AND item_private = 0 - $item_normal $sql_extra - ORDER BY item.created DESC $pager_sql", + $item_normal + $sql_extra ORDER BY created ASC $limit", dbesc($nonsys_uids_str) ); - - xchan_query($items); - $items = fetch_post_tags($items, true); - - return $items; } else { $r = q("SELECT parent, postopts FROM item @@ -4432,6 +4411,7 @@ function zot_feed($uid, $observer_hash, $arr) { $parents_str = ids_to_querystr($parents, 'parent'); $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); + $item_normal = item_normal(); $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal $sys_query ", @@ -4456,7 +4436,6 @@ function zot_feed($uid, $observer_hash, $arr) { return $result; } - function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = CLIENT_MODE_NORMAL,$module = 'network') { $result = array('success' => false); -- cgit v1.2.3 From 552796286e4a2a61cc6020b7aa785dc88553e2d0 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sun, 24 Jan 2021 21:03:34 +0100 Subject: Add support filesystem storage for xchan profile photos --- Zotlabs/Lib/Hashpath.php | 55 ++++++++++++++++++++ Zotlabs/Module/Photo.php | 6 +-- Zotlabs/Photo/PhotoDriver.php | 31 +++++++---- doc/hidden_configs.bb | 2 +- include/import.php | 2 +- include/photo/photo_driver.php | 43 +++++++--------- util/storageconv | 113 +++++++++++++++++++++++++---------------- 7 files changed, 168 insertions(+), 84 deletions(-) create mode 100644 Zotlabs/Lib/Hashpath.php diff --git a/Zotlabs/Lib/Hashpath.php b/Zotlabs/Lib/Hashpath.php new file mode 100644 index 000000000..f3b25d2b6 --- /dev/null +++ b/Zotlabs/Lib/Hashpath.php @@ -0,0 +1,55 @@ +saveImage($arr['os_syspath'])) + + if (array_key_exists('uid', $arr) && ! in_array($scale, [ PHOTO_RES_PROFILE_300, PHOTO_RES_PROFILE_80, PHOTO_RES_PROFILE_48 ])) { + $channel = channelx_by_n($arr['uid']); + $arr['os_syspath'] = 'store/' . $channel['channel_address'] . '/' . $arr['os_path'] . '-' . $scale; + } + else + $arr['os_syspath'] = Hashpath::path($arr['resource_id'], 'store/[data]/[xchan]', 2, 1) . '-' . $scale; + + if (! $this->saveImage($arr['os_syspath'])) return false; } else diff --git a/doc/hidden_configs.bb b/doc/hidden_configs.bb index 42c9e67b8..27ea415bd 100644 --- a/doc/hidden_configs.bb +++ b/doc/hidden_configs.bb @@ -62,7 +62,7 @@ Options are: [*= system.email_notify_icon_url ] URL of image (32x32) to display in email notifications (HTML bodies). [*= system.expire_delivery_reports ] Expiration in days for delivery reports - default 10 [*= system.expire_limit ] Don't expire any more than this number of posts per channel per expiration run to keep from exhausting memory. Default 5000. - [*= system.filesystem_storage_thumbnails ] If '1', use filesystem instead SQL database to store thumbnails. Default is '0'. Introduced in 4.2 + [*= system.photo_storage_type] If '1', use filesystem instead SQL database to store thumbnails. Default is '0'. Introduced in 4.2 [*= system.hidden_version_siteinfo ] If true, do not report the software version on siteinfo pages (system.hide_version also hides the version on these pages, this setting *only* hides the version on siteinfo pages). [*= system.hide_help ] Don't display help documentation link in nav bar [*= system.hide_in_statistics ] Tell the red statistics servers to completely hide this hub in hub lists. diff --git a/include/import.php b/include/import.php index b512e1f11..8ce582ede 100644 --- a/include/import.php +++ b/include/import.php @@ -1469,7 +1469,7 @@ function sync_files($channel, $files) { fclose($fp); // Override remote hub thumbnails storage settings - if(! boolval(get_config('system','filesystem_storage_thumbnails', 0))) { + if(! boolval(get_config('system','photo_storage_type', 1))) { $p['os_storage'] = 0; $p['content'] = file_get_contents($stored_image); @unlink($stored_image); diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index 1ce2fd6e3..057711f1e 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -205,7 +205,11 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) { if($thing) $hash = photo_new_resource(); else { - $r = q("SELECT resource_id, edited, mimetype, expires, description FROM photo WHERE xchan = '%s' AND photo_usage = %d AND imgscale = 4 LIMIT 1", dbesc($xchan), intval(PHOTO_XCHAN)); + $r = q("SELECT resource_id, edited, mimetype, expires, description FROM photo WHERE xchan = '%s' AND photo_usage = %d AND imgscale = %d LIMIT 1", + dbesc($xchan), + intval(PHOTO_XCHAN), + intval(PHOTO_RES_PROFILE_300) + ); if($r) { $hash = $r[0]['resource_id']; $modified = $r[0]['edited']; @@ -316,26 +320,20 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) { 'filename' => basename($photo), 'album' => $album, 'photo_usage' => $flags, - 'imgscale' => 4, 'edited' => $modified, 'description' => (array_key_exists('etag', $hdrs) ? $hdrs['etag'] : ''), 'expires' => gmdate('Y-m-d H:i:s', (isset($expires) ? $expires : time() + 86400)) ]; - $r = $img->save($p); - if($r === false) - $photo_failure = true; + $r1 = $img->storeThumbnail($p, PHOTO_RES_PROFILE_300); $img->scaleImage(80); - $p['imgscale'] = 5; - $r = $img->save($p); - if($r === false) - $photo_failure = true; + $r2 = $img->storeThumbnail($p, PHOTO_RES_PROFILE_80); $img->scaleImage(48); - $p['imgscale'] = 6; - $r = $img->save($p); - if($r === false) + $r3 = $img->storeThumbnail($p, PHOTO_RES_PROFILE_48); + + if($r1 === false || $r2 === false || $r3 === false) $photo_failure = true; $photo = z_root() . '/photo/' . $hash . '-4'; @@ -424,31 +422,26 @@ function import_channel_photo($photo, $type, $aid, $uid) { 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), - 'photo_usage' => PHOTO_PROFILE, - 'imgscale' => 4, + 'photo_usage' => PHOTO_PROFILE ]; // photo size $img->scaleImageSquare(300); - $r = $img->save($p); - if($r === false) - $photo_failure = true; + $r1 = $img->storeThumbnail($p, PHOTO_RES_PROFILE_300); // thumb size $img->scaleImage(80); - $p['imgscale'] = 5; - $r = $img->save($p); - if($r === false) - $photo_failure = true; + $r2 = $img->storeThumbnail($p, PHOTO_RES_PROFILE_80); // micro size $img->scaleImage(48); - $p['imgscale'] = 6; - $r = $img->save($p); - if($r === false) + $r3 = $img->storeThumbnail($p, PHOTO_RES_PROFILE_48); + + if($r1 === false || $r2 === false || $r3 === false) $photo_failure = true; - } else { + } + else { logger('Invalid image.'); $photo_failure = true; } diff --git a/util/storageconv b/util/storageconv index 992c906b8..52bb77fbb 100755 --- a/util/storageconv +++ b/util/storageconv @@ -18,6 +18,8 @@ require_once('include/cli_startup.php'); cli_startup(); +use Zotlabs\Lib\Hashpath; + if($argc == 1) { usage(); killme(); @@ -25,15 +27,20 @@ if($argc == 1) { if($argc == 2) { - $storage = (intval(get_config('system','filesystem_storage_thumbnails', 0)) > 0 ? 1 : 0); + $storage = (intval(get_config('system','photo_storage_type', 1)) > 0 ? 1 : 0); echo 'Current storage set to: ' . ($storage ? 'filesystem' : 'SQL database') . PHP_EOL; switch($argv[1]) { case 'stats': $x = q("SELECT COUNT(resource_id) AS qty FROM photo WHERE photo_usage = 0 AND os_storage = 1 AND imgscale = 0"); echo 'Local images: ' . $x[0]['qty'] . PHP_EOL; - $x = q("SELECT COUNT(id) AS qty FROM photo WHERE resource_id IN (SELECT DISTINCT resource_id FROM photo WHERE photo_usage = 0 and os_storage = 1) AND imgscale > 0"); - echo 'Thumbnails total: ' . $x[0]['qty'] . PHP_EOL; - $x = q("SELECT COUNT(id) AS qty FROM photo WHERE resource_id IN (SELECT DISTINCT resource_id FROM photo WHERE photo_usage = 0 and os_storage = 1) AND os_storage != %d AND imgscale > 0", + $x = q("SELECT COUNT(resource_id) AS qty FROM photo WHERE photo_usage = 0 AND imgscale > 0"); + echo 'Image thumbnails: ' . $x[0]['qty'] . PHP_EOL; + $xx = intval($x[0]['qty']); + $x = q("SELECT COUNT(resource_id) AS qty FROM photo WHERE photo_usage IN (1, 2)"); + echo 'Imported profiles thumbnails: ' . $x[0]['qty'] . PHP_EOL; + $xx += intval($x[0]['qty']); + echo 'Thumbnails total: ' . $xx . PHP_EOL; + $x = q("SELECT COUNT(id) AS qty FROM photo WHERE os_storage != %d AND imgscale > 0", $storage ); echo 'Thumbnails to convert: ' . $x[0]['qty'] . PHP_EOL; @@ -41,87 +48,108 @@ if($argc == 2) { case 'fs': if($storage == 0) { - echo 'Please set system.filesystem_storage_thumbnails to 1 before move thumbnails to filesystem storage' . PHP_EOL; + echo 'Please set system.photo_storage_type to 1 before move thumbnails to filesystem storage' . PHP_EOL; break; } - $x = q("SELECT resource_id, content FROM photo WHERE photo_usage = 0 AND os_storage = 1 AND imgscale = 0"); + $cur_id = 0; + $i = 0; - if($x) { - foreach($x as $xx) { - - $n = q("SELECT id, imgscale, content FROM photo WHERE resource_id = '%s' AND os_storage != %d AND imgscale > 0", - dbesc($xx['resource_id']), - $storage - ); + $r = dbq("SELECT COUNT(id) AS max_num FROM photo WHERE os_storage = 0 AND imgscale > 0"); + $max_num = $r[0]['max_num']; - $img_path = dbunescbin($xx['content']); - - foreach($n as $nn) { - - echo '.'; - - $filename = $img_path . '-' . $nn['imgscale']; + while ($i < $max_num) { + + $x = q("SELECT id, uid, resource_id, content, imgscale FROM photo WHERE id > %d AND os_storage = 0 AND imgscale > 0 ORDER BY id LIMIT 10", + intval($cur_id) + ); - if(! file_put_contents($filename, dbunescbin($nn['content']))) { - echo 'Failed to save file ' . $filename . PHP_EOL; + if($x) { + foreach($x as $xx) { + + if ($xx['uid'] == 0 || in_array($xx['imgscale'], [4, 5, 6])) + $filename = Hashpath::path($xx['resource_id'], 'store/[data]/[xchan]', 2, 1) . '-' . $xx['imgscale']; + else { + $z = q("SELECT channel_address FROM channel WHERE channel_id = %d", + intval($xx['uid']) + ); + $filename = 'store/' . $z[0]['channel_address'] . '/' . $xx['resource_id'] . '-' . $xx['imgscale']; + } + + if(! file_put_contents($filename, dbunescbin($xx['content']))) { + echo PHP_EOL . 'Failed to save file ' . $filename . PHP_EOL; continue; } - + $z = q("UPDATE photo SET content = '%s', os_storage = 1 WHERE id = %d", dbescbin($filename), - intval($nn['id']) + intval($xx['id']) ); if(! $z) { @unlink($filename); - echo 'Failed to update metadata for saved file ' . $filename . PHP_EOL; + echo PHP_EOL . 'Failed to update metadata for saved file ' . $filename . PHP_EOL; } + $cur_id = $xx['id']; + + echo '.'; + $i++; } } + echo ($i % 100 == 0 ? $i : ''); } + echo $i . PHP_EOL . 'Total thumbnails processed: ' . $i; break; case 'db': if($storage == 1) { - echo 'Please set system.filesystem_storage_thumbnails to 0 before move thumbnails to SQL database storage' . PHP_EOL; + echo 'Please set system.photo_storage_type to 0 before move thumbnails to SQL database storage' . PHP_EOL; break; } - $x = q("SELECT resource_id FROM photo WHERE photo_usage = 0 AND os_storage = 1 AND imgscale = 0"); - - if($x) { - foreach($x as $xx) { + $cur_id = 0; + $i = 0; - $n = q("SELECT id, content FROM photo WHERE resource_id = '%s' AND os_storage != %d AND imgscale > 0", - dbesc($xx['resource_id']), - $storage - ); - - foreach($n as $nn) { - - echo '.'; + $r = dbq("SELECT COUNT(id) AS max_num FROM photo WHERE os_storage = 1 AND imgscale > 0"); + $max_num = $r[0]['max_num']; + + while ($i < $max_num) { + + $x = q("SELECT id, uid, resource_id, content, imgscale FROM photo WHERE id > %d AND os_storage = 1 AND imgscale > 0 ORDER BY id LIMIT 10", + intval($cur_id) + ); + + if($x) { + foreach($x as $xx) { - $filename = dbunescbin($nn['content']); + $filename = dbunescbin($xx['content']); + $content = file_get_contents($filename); if($content) { $z = q("UPDATE photo SET content = '%s', os_storage = 0 WHERE id = %d", dbescbin($content), - intval($nn['id']) + intval($xx['id']) ); if(! $z) { - echo 'Failed to update stored file metadata ' . $filename . PHP_EOL; + echo PHP_EOL . 'Failed to update stored file metadata ' . $filename . PHP_EOL; continue; } @unlink($filename); } else - echo 'Can not read file contents ' . $filename . PHP_EOL; + echo PHP_EOL . 'Can not read file contents ' . $filename . PHP_EOL; + + $cur_id = $xx['id']; + + echo '.'; + $i++; } } + echo ($i % 100 == 0 ? $i : ''); } + echo $i . PHP_EOL . 'Total files processed: ' . $i; break; default: @@ -129,6 +157,5 @@ if($argc == 2) { return; } - echo PHP_EOL; } -- cgit v1.2.3 From 3ed444b4b4cb1817ab1c780138d4bef0b8909876 Mon Sep 17 00:00:00 2001 From: Charlie Root Date: Mon, 25 Jan 2021 18:35:28 +0200 Subject: Run storageconv from web server user --- util/storageconv | 0 util/storageconv.sh | 6 ++++++ 2 files changed, 6 insertions(+) mode change 100755 => 100644 util/storageconv create mode 100755 util/storageconv.sh diff --git a/util/storageconv b/util/storageconv old mode 100755 new mode 100644 diff --git a/util/storageconv.sh b/util/storageconv.sh new file mode 100755 index 000000000..90abdf0ef --- /dev/null +++ b/util/storageconv.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +WWWUSER=$(ps aux | egrep '([a|A]pache|[h|H]ttpd|lighttpd|[n|N]ginx|h2o)' | awk '{ print $1}' | uniq | grep -v `whoami` | tail -1) + +sudo -u $WWWUSER php util/storageconv $* + -- cgit v1.2.3 From 0e9d99c603d84b76c4774aa39dc782992bd91cdc Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 25 Jan 2021 20:27:50 +0000 Subject: expose manual public item import from searchbar, set commen_policy in Activity::store() to what we get if we get something otherwise default to authenticated, comments by the owner have the relay flag set and therefor $perm will be not be set to post_comments - always check if we own the parent in lib/libzot (not only if $perm = send_stream) if otherwise not allowed --- Zotlabs/Lib/Activity.php | 24 ++-- Zotlabs/Lib/Libzot.php | 15 ++- Zotlabs/Module/Network.php | 2 +- Zotlabs/Module/Search.php | 285 ++++++++++++++++++++++++--------------------- 4 files changed, 178 insertions(+), 148 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 46ce075fd..3afc70b28 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2488,7 +2488,6 @@ class Activity { } static function store($channel, $observer_hash, $act, $item, $fetch_parents = true, $force = false) { - $is_sys_channel = is_sys_channel($channel['channel_id']); $is_child_node = false; @@ -2523,6 +2522,7 @@ class Activity { // $permit_mentions = intval(PConfig::Get($channel['channel_id'], 'system','permit_all_mentions') && i_am_mentioned($channel,$item)); if ($is_child_node) { + $p = q("select * from item where mid = '%s' and uid = %d and item_wall = 1", dbesc($item['parent_mid']), intval($channel['channel_id']) @@ -2560,6 +2560,7 @@ class Activity { }*/ } else { + $allowed = true; // reject public stream comments that weren't sent by the conversation owner if ($is_sys_channel && $pubstream && $item['owner_xchan'] !== $observer_hash) { @@ -2575,6 +2576,7 @@ class Activity { } } else { + // The $item['item_fetched'] flag is set in fetch_and_store_parents(). // In this case we should check against author permissions because sender is not owner. if (perm_is_allowed($channel['channel_id'], (($item['item_fetched']) ? $item['author_xchan'] : $observer_hash), 'send_stream') || ($is_sys_channel && $pubstream)) { @@ -2694,7 +2696,7 @@ class Activity { } // This isn't perfect but the best we can do for now. - $item['comment_policy'] = 'authenticated'; + $item['comment_policy'] = ((isset($act->data['commentPolicy'])) ? $act->data['commentPolicy'] : 'authenticated'); set_iconfig($item, 'activitypub', 'recips', $act->raw_recips); @@ -2777,9 +2779,9 @@ class Activity { else { $fetch = false; // TODO: debug - // if (perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && (PConfig::Get($channel['channel_id'],'system','hyperdrive',true)*/ || $act->type === 'Announce')) { + // if (perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') && (PConfig::Get($channel['channel_id'],'system','hyperdrive',true) || $act->type === 'Announce')) { if (perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') || ($is_sys_channel && $pubstream)) { - $fetch = (($fetch_parents) ? self::fetch_and_store_parents($channel, $observer_hash, $item) : false); + $fetch = (($fetch_parents) ? self::fetch_and_store_parents($channel, $observer_hash, $item, $force) : false); } if ($fetch) { $parent = q("select * from item where mid = '%s' and uid = %d limit 1", @@ -2901,7 +2903,7 @@ class Activity { } - static public function fetch_and_store_parents($channel, $observer_hash, $item) { + static public function fetch_and_store_parents($channel, $observer_hash, $item, $force = false) { logger('fetching parents'); $p = []; @@ -2909,18 +2911,19 @@ class Activity { $current_item = $item; while ($current_item['parent_mid'] !== $current_item['mid']) { - $n = self::fetch($current_item['parent_mid']); + $n = self::fetch($current_item['parent_mid'], $channel); + if (!$n) { break; } - // set client flag to convert objects to implied activities - $a = new ActivityStreams($n, null, true); + + $a = new ActivityStreams($n); if ($a->type === 'Announce' && is_array($a->obj) && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead logger('relayed activity', LOGGER_DEBUG); - $a = new ActivityStreams($a->obj, null, true); + $a = new ActivityStreams($a->obj); } logger($a->debug(), LOGGER_DATA); @@ -2933,7 +2936,6 @@ class Activity { Activity::actor_store($a->actor['id'], $a->actor); } - // ActivityPub sourced items are cacheable $item = Activity::decode_note($a); if (!$item) { @@ -2975,7 +2977,7 @@ class Activity { if ($p) { foreach ($p as $pv) { if ($pv[0]->is_valid()) { - Activity::store($channel, $observer_hash, $pv[0], $pv[1], false); + Activity::store($channel, $observer_hash, $pv[0], $pv[1], false, $force); } } return true; diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index ee1f54ec8..13a75bb6c 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -1235,8 +1235,14 @@ class Libzot { if (is_array($AS->obj) && array_key_exists('commentPolicy', $AS->obj)) { $p = strstr($AS->obj['commentPolicy'], 'until='); if ($p !== false) { - $arr['comments_closed'] = datetime_convert('UTC', 'UTC', substr($p, 6)); - $arr['comment_policy'] = trim(str_replace($p, '', $AS->obj['commentPolicy'])); + $comments_closed_at = datetime_convert('UTC', 'UTC', substr($p, 6)); + if ($comments_closed_at === $arr['created']) { + $arr['item_nocomment'] = 1; + } + else { + $arr['comments_closed'] = $comments_closed_at; + $arr['comment_policy'] = trim(str_replace($p, '', $AS->obj['commentPolicy'])); + } } else { $arr['comment_policy'] = $AS->obj['commentPolicy']; @@ -1545,8 +1551,7 @@ class Libzot { } $tag_delivery = tgroup_check($channel['channel_id'], $arr); - - $perm = 'send_stream'; + $perm = 'send_stream'; if (($arr['mid'] !== $arr['parent_mid']) && ($relay)) $perm = 'post_comments'; @@ -1563,7 +1568,7 @@ class Libzot { if ((!$tag_delivery) && (!$local_public)) { $allowed = (perm_is_allowed($channel['channel_id'], $sender, $perm)); - if ((!$allowed) && $perm === 'post_comments') { + if (!$allowed) { $parent = q("select * from item where mid = '%s' and uid = %d limit 1", dbesc($arr['parent_mid']), intval($channel['channel_id']) diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index e9edd8de3..84c2463d6 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -20,7 +20,7 @@ class Network extends \Zotlabs\Web\Controller { return; } - if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?'])) + if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']) || strpos($_GET['search'], 'https://') === 0) goaway('search' . '?f=&search=' . $_GET['search']); if(count($_GET) < 2) { diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php index c22bf2836..95510c349 100644 --- a/Zotlabs/Module/Search.php +++ b/Zotlabs/Module/Search.php @@ -1,85 +1,110 @@ ' . "\r\n"; $o .= '
      ' . "\r\n"; - + $o .= '

      ' . t('Search') . '

      '; - - if(x(\App::$data,'search')) - $search = trim(\App::$data['search']); + + if (x(App::$data, 'search')) + $search = trim(App::$data['search']); else - $search = ((x($_GET,'search')) ? trim(escape_tags(rawurldecode($_GET['search']))) : ''); - + $search = ((x($_GET, 'search')) ? trim(escape_tags(rawurldecode($_GET['search']))) : ''); + $tag = false; - if(x($_GET,'tag')) { - $tag = true; - $search = ((x($_GET,'tag')) ? trim(escape_tags(rawurldecode($_GET['tag']))) : ''); + if (x($_GET, 'tag')) { + $tag = true; + $search = ((x($_GET, 'tag')) ? trim(escape_tags(rawurldecode($_GET['tag']))) : ''); } - $o .= search($search,'search-box','/search',((local_channel()) ? true : false)); - - if(strpos($search,'#') === 0) { - $tag = true; - $search = substr($search,1); + $o .= search($search, 'search-box', '/search', ((local_channel()) ? true : false)); + + if (local_channel() && strpos($search, 'https://') === 0) { + $j = Activity::fetch($search, App::get_channel()); + if ($j) { + $AS = new ActivityStreams($j); + + if ($AS->is_valid()) { + // check if is_an_actor, otherwise import activity + if (is_array($AS->obj) && !ActivityStreams::is_an_actor($AS->obj)) { + // The boolean flag enables html cache of the item + $item = Activity::decode_note($AS); + if ($item) { + logger('parsed_item: ' . print_r($item, true), LOGGER_DATA); + Activity::store(App::get_channel(), $observer_hash, $AS, $item, true, true); + goaway(z_root() . '/display/' . gen_link_id($item['mid'])); + } + } + } + } } - if(strpos($search,'@') === 0) { - $search = substr($search,1); + + if (strpos($search, '#') === 0) { + $tag = true; + $search = substr($search, 1); + } + if (strpos($search, '@') === 0) { + $search = substr($search, 1); goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search); } - if(strpos($search,'!') === 0) { - $search = substr($search,1); + if (strpos($search, '!') === 0) { + $search = substr($search, 1); goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search); } - if(strpos($search,'?') === 0) { - $search = substr($search,1); + if (strpos($search, '?') === 0) { + $search = substr($search, 1); goaway(z_root() . '/help' . '?f=1&navsearch=1&search=' . $search); } - + // look for a naked webbie - if(strpos($search,'@') !== false) { + if (strpos($search, '@') !== false) { goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search); } - - if(! $search) + + if (!$search) return $o; - - if($tag) { - $wildtag = str_replace('*','%',$search); + + if ($tag) { + $wildtag = str_replace('*', '%', $search); $sql_extra = sprintf(" AND item.id IN (select oid from term where otype = %d and ttype in ( %d , %d) and term like '%s') ", intval(TERM_OBJ_POST), intval(TERM_HASHTAG), @@ -88,80 +113,80 @@ class Search extends \Zotlabs\Web\Controller { ); } else { - $regstr = db_getfunc('REGEXP'); + $regstr = db_getfunc('REGEXP'); $sql_extra = sprintf(" AND (item.title $regstr '%s' OR item.body $regstr '%s') ", dbesc(protect_sprintf(preg_quote($search))), dbesc(protect_sprintf(preg_quote($search)))); } - + // Here is the way permissions work in the search module... // Only public posts can be shown // OR your own posts if you are a logged in member // No items will be shown if the member has a blocked profile wall. - - if((! $update) && (! $load)) { - + + if ((!$update) && (!$load)) { + // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. - + $o .= '' . "\r\n"; $o .= "\r\n"; - - \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + . "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; \r\n"; + + App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), [ '$baseurl' => z_root(), - '$pgtype' => 'search', - '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'), - '$gid' => '0', - '$cid' => '0', - '$cmin' => '(-1)', - '$cmax' => '(-1)', - '$star' => '0', - '$liked' => '0', - '$conv' => '0', - '$spam' => '0', - '$fh' => '0', - '$dm' => '0', + '$pgtype' => 'search', + '$uid' => ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : '0'), + '$gid' => '0', + '$cid' => '0', + '$cmin' => '(-1)', + '$cmax' => '(-1)', + '$star' => '0', + '$liked' => '0', + '$conv' => '0', + '$spam' => '0', + '$fh' => '0', + '$dm' => '0', '$nouveau' => '0', - '$wall' => '0', - '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), - '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), - '$search' => (($tag) ? urlencode('#') : '') . $search, - '$xchan' => '', - '$order' => '', - '$file' => '', - '$cats' => '', - '$tags' => '', - '$mid' => '', - '$verb' => '', - '$net' => '', - '$dend' => '', - '$dbegin' => '' - )); - - - } - + '$wall' => '0', + '$list' => ((x($_REQUEST, 'list')) ? intval($_REQUEST['list']) : 0), + '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1), + '$search' => (($tag) ? urlencode('#') : '') . $search, + '$xchan' => '', + '$order' => '', + '$file' => '', + '$cats' => '', + '$tags' => '', + '$mid' => '', + '$verb' => '', + '$net' => '', + '$dend' => '', + '$dbegin' => '' + ]); + + + } + $item_normal = item_normal_search(); - $pub_sql = public_permissions_sql($observer_hash); - + $pub_sql = public_permissions_sql($observer_hash); + require_once('include/channel.php'); - + $sys = get_sys_channel(); - - if(($update) && ($load)) { - $itemspage = get_pconfig(local_channel(),'system','itemspage'); - \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10)); - $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); - + + if (($update) && ($load)) { + $itemspage = get_pconfig(local_channel(), 'system', 'itemspage'); + App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); + // in case somebody turned off public access to sys channel content with permissions - - if(! perm_is_allowed($sys['channel_id'],$observer_hash,'view_stream')) + + if (!perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream')) $sys['xchan_hash'] .= 'disabled'; - - if($load) { + + if ($load) { $r = null; - - if(local_channel()) { + + if (local_channel()) { $r = q("SELECT mid, MAX(id) as item_id from item WHERE ((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' AND item.deny_gid = '' AND item_private = 0 ) OR ( item.uid = %d )) OR item.owner_xchan = '%s' ) @@ -172,11 +197,11 @@ class Search extends \Zotlabs\Web\Controller { dbesc($sys['xchan_hash']) ); } - if($r === null) { + if ($r === null) { $r = q("SELECT mid, MAX(id) as item_id from item WHERE (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' AND item.deny_gid = '' AND item_private = 0 ) - and owner_xchan in ( " . stream_perms_xchans(($observer) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) + and owner_xchan in ( " . stream_perms_xchans(($observer) ? (PERMS_NETWORK | PERMS_PUBLIC) : PERMS_PUBLIC) . " )) $pub_sql ) OR owner_xchan = '%s') $item_normal $sql_extra @@ -184,51 +209,49 @@ class Search extends \Zotlabs\Web\Controller { dbesc($sys['xchan_hash']) ); } - if($r) { - $str = ids_to_querystr($r,'item_id'); - $r = q("select *, id as item_id from item where id in ( " . $str . ") order by created desc "); + if ($r) { + $str = ids_to_querystr($r, 'item_id'); + $r = q("select *, id as item_id from item where id in ( " . $str . ") order by created desc "); } } else { - $r = array(); + $r = []; } - - } - - if($r) { + + if ($r) { xchan_query($r); - $items = fetch_post_tags($r,true); - } else { - $items = array(); - } - - - if($format == 'json') { - $result = array(); + $items = fetch_post_tags($r, true); + } + else { + $items = []; + } + + if ($format == 'json') { + $result = []; require_once('include/conversation.php'); - foreach($items as $item) { + foreach ($items as $item) { $item['html'] = zidify_links(bbcode($item['body'])); - $x = encode_item($item); - $x['html'] = prepare_text($item['body'],$item['mimetype']); - $result[] = $x; + $x = encode_item($item); + $x['html'] = prepare_text($item['body'], $item['mimetype']); + $result[] = $x; } - json_return_and_die(array('success' => true,'messages' => $result)); + json_return_and_die(['success' => true, 'messages' => $result]); } - - if($tag) - $o .= '

      ' . sprintf( t('Items tagged with: %s'),$search) . '

      '; + + if ($tag) + $o .= '

      ' . sprintf(t('Items tagged with: %s'), $search) . '

      '; else - $o .= '

      ' . sprintf( t('Search results for: %s'),$search) . '

      '; - - $o .= conversation($items,'search',$update,'client'); - + $o .= '

      ' . sprintf(t('Search results for: %s'), $search) . '

      '; + + $o .= conversation($items, 'search', $update, 'client'); + $o .= '
      '; - + return $o; } - - + + } -- cgit v1.2.3 From d4198223bc1fd06e9b9fe969edb5d03811889def Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Mon, 25 Jan 2021 21:52:17 +0100 Subject: invoke channel discovery by hash instead of address and add thread listeners only if we also send them the post --- Zotlabs/Module/Channel.php | 3 +-- Zotlabs/Module/Item.php | 11 ++++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index fe7341e52..11f4d3a52 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -73,7 +73,7 @@ class Channel extends Controller { } } else { - $data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'] ])); + $data = json_encode(Libzot::zotinfo([ 'guid_hash' => $channel['channel_hash'] ])); } $headers = [ @@ -87,7 +87,6 @@ class Channel extends Controller { killme(); } - if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { $which = $channel['channel_address']; $profile = argv(1); diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 83424a50d..3d83bcf8f 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -132,13 +132,14 @@ class Item extends Controller { $i = Activity::encode_item_collection($items, 'conversation/' . $item_id, 'OrderedCollection'); - if($portable_id) { - ThreadListener::store(z_root() . '/item/' . $item_id,$portable_id); - } if(! $i) http_status_exit(404, 'Not found'); + if($portable_id) { + ThreadListener::store(z_root() . '/item/' . $item_id,$portable_id); + } + $x = array_merge(['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', @@ -237,6 +238,10 @@ class Item extends Controller { if(! $i) http_status_exit(404, 'Not found'); + if($portable_id) { + ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); + } + $x = array_merge(['@context' => [ ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1', -- cgit v1.2.3 From 82dbdf7c70dddeb88fd698c20bdba83e847a8109 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Tue, 26 Jan 2021 10:07:41 +0100 Subject: fix issues in Activity::encode_item_collection() after recent changes --- Zotlabs/Lib/Activity.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 3afc70b28..8ad114a4d 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -292,7 +292,7 @@ class Activity { $ret = [ 'id' => z_root() . '/' . $id, 'type' => $type, - 'totalItems' => $total, + 'totalItems' => count($items), ]; } @@ -312,9 +312,6 @@ class Activity { if ($t) { $x[] = $t; } - if ($t) { - $x[] = $t; - } } if ($type === 'OrderedCollection') { $ret['orderedItems'] = $x; -- cgit v1.2.3 From 777af6e7ad6c6307567010cee262a0f1d8831083 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 26 Jan 2021 09:21:16 +0000 Subject: Libzot::fetch_conversation() fixes --- Zotlabs/Lib/Libzot.php | 64 +++++++++++++++++++++-------------------------- Zotlabs/Lib/Zotfinger.php | 1 - 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 13a75bb6c..fd30f05f5 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -1250,8 +1250,6 @@ class Libzot { } } - - /// @FIXME - spoofable if ($AS->data['hubloc']) { $arr['item_verified'] = true; @@ -1274,7 +1272,6 @@ class Libzot { IConfig::Set($arr, 'activitystreams', 'signed_data', $AS->data['signed_data'], false); } - logger('Activity received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG); logger('Activity recipients: ' . print_r($deliveries, true), LOGGER_DATA, LOG_DEBUG); @@ -1867,43 +1864,61 @@ class Libzot { // Use Zotfinger to create a signed request + logger('fetching conversation: ' . $mid, LOGGER_DEBUG); + $a = Zotfinger::exec($mid, $channel); logger('received conversation: ' . print_r($a, true), LOGGER_DATA); + if (!$a) { + return false; + } + if ($a['data']['type'] !== 'OrderedCollection') { - return; + return false; } - if (!intval($a['data']['totalItems'])) { - return; + $obj = new ASCollection($a['data'], $channel); + $items = $obj->get(); + + if (!$items) { + return false; } $ret = []; + $signer = q("select hubloc_hash, hubloc_url from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($a['signature']['signer']) ); - foreach ($a['data']['orderedItems'] as $activity) { + foreach ($items as $activity) { $AS = new ActivityStreams($activity); + if ($AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj) + && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj)) { + // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) + // Reparse the encapsulated Activity and use that instead + logger('relayed activity', LOGGER_DEBUG); + $AS = new ActivityStreams($AS->obj); + } + if (!$AS->is_valid()) { logger('FOF Activity rejected: ' . print_r($activity, true)); continue; } $arr = Activity::decode_note($AS); - logger($AS->debug()); + // logger($AS->debug()); - $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", + $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1", dbesc($AS->actor['id']) ); if (!$r) { $y = import_author_xchan(['url' => $AS->actor['id']]); if ($y) { - $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", + $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' limit 1", dbesc($AS->actor['id']) ); } @@ -1926,39 +1941,17 @@ class Libzot { $arr['author_xchan'] = $r[0]['hubloc_hash']; } - $s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", - dbesc($a['signature']['signer']) - ); - - if ($s) { - $arr['owner_xchan'] = $s[0]['hubloc_hash']; + if ($signer) { + $arr['owner_xchan'] = $signer[0]['hubloc_hash']; } else { $arr['owner_xchan'] = $a['signature']['signer']; } - - /// @FIXME - spoofable - if ($AS->data['hubloc']) { + if ($AS->data['hubloc'] || $arr['author_xchan'] === $arr['owner_xchan']) { $arr['item_verified'] = true; } - // set comment policy depending on source hub. Unknown or osada is ActivityPub. - // Anything else we'll say is zot - which could have a range of project names - - if ($signer) { - $s = q("select site_project from site where site_url = '%s' limit 1", - dbesc($signer[0]['hubloc_url']) - ); - if ((!$s) || (in_array($s[0]['site_project'], ['', 'osada']))) { - $arr['comment_policy'] = 'authenticated'; - } - else { - $arr['comment_policy'] = 'contacts'; - } - } - - if ($AS->data['signed_data']) { IConfig::Set($arr, 'activitystreams', 'signed_data', $AS->data['signed_data'], false); } @@ -1975,7 +1968,6 @@ class Libzot { return $ret; } - /** * @brief Remove community tag. * diff --git a/Zotlabs/Lib/Zotfinger.php b/Zotlabs/Lib/Zotfinger.php index e853d6ebc..faaf28f35 100644 --- a/Zotlabs/Lib/Zotfinger.php +++ b/Zotlabs/Lib/Zotfinger.php @@ -34,7 +34,6 @@ class Zotfinger { $result = []; - $redirects = 0; $x = z_post_url($resource,$data,$redirects, [ 'headers' => $h ] ); -- cgit v1.2.3 From de34dac6cc3467280bc99b01e9ecf7470161a5d0 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 26 Jan 2021 09:56:28 +0000 Subject: port youtube embed fix from zap --- include/oembed.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/oembed.php b/include/oembed.php index eeae7a174..1550eaacf 100755 --- a/include/oembed.php +++ b/include/oembed.php @@ -189,6 +189,13 @@ function oembed_fetch_url($embedurl){ $entries = $xpath->query("//link[@type='application/json+oembed']"); foreach($entries as $e){ $href = $e->getAttributeNode("href")->nodeValue; + + // Youtube will happily hand us an http oembed URL even if we specify an https link; and the returned http link will fail with a 40x if you try and fetch it + // This is not our bug, but good luck getting google to fix it. + if (strpos($href,'http:') === 0 && strpos($href,'youtu') !== false) { + $href = str_replace('http:','https:', $href); + } + $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); if($x['success']) $txt = $x['body']; -- cgit v1.2.3 From 6878445319374c3d98932b26a3a58a99c754df8f Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 26 Jan 2021 10:29:03 +0000 Subject: use mail envelope instead of lock icon for direct messages --- Zotlabs/Lib/ThreadItem.php | 2 ++ include/conversation.php | 3 +++ view/tpl/conv_item.tpl | 2 +- view/tpl/conv_list.tpl | 2 +- view/tpl/search_item.tpl | 2 +- 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index b7eecbd94..2fb07c1cb 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -102,6 +102,7 @@ class ThreadItem { || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) ? t('Private Message') : false); + $locktype = $item['item_private']; $shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false); @@ -432,6 +433,7 @@ class ThreadItem { 'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''), 'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''), 'lock' => $lock, + 'locktype' => $locktype, 'delayed' => $item['item_delayed'], 'privacy_warning' => $privacy_warning, 'verified' => $verified, diff --git a/include/conversation.php b/include/conversation.php index 087e8c135..002edef51 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -739,6 +739,8 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa ? t('Private Message') : false ); + $locktype = $item['item_private']; + $likebuttons = false; $shareable = false; @@ -783,6 +785,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa 'name' => $profile_name, 'sparkle' => $sparkle, 'lock' => $lock, + 'locktype' => $locktype, 'thumb' => $profile_avatar, 'title' => $item['title'], 'body' => $body['html'], diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl index 78601c40d..b021509d3 100755 --- a/view/tpl/conv_item.tpl +++ b/view/tpl/conv_item.tpl @@ -48,7 +48,7 @@ {{if $item.lock}} {{/if}} diff --git a/view/tpl/conv_list.tpl b/view/tpl/conv_list.tpl index 113cf2324..ee5dc9742 100755 --- a/view/tpl/conv_list.tpl +++ b/view/tpl/conv_list.tpl @@ -43,7 +43,7 @@ {{if $item.lock}} {{/if}} diff --git a/view/tpl/search_item.tpl b/view/tpl/search_item.tpl index 3e986ea21..f94aaf37d 100755 --- a/view/tpl/search_item.tpl +++ b/view/tpl/search_item.tpl @@ -36,7 +36,7 @@ {{if $item.lock}} {{/if}}
      -- cgit v1.2.3 From f0ee4c3cef6c148bd397ad6a1e71ce86aa43565a Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 26 Jan 2021 10:35:24 +0000 Subject: port fix from zap: catch a complex edge case where some public stream comments were not being delivered and should have been --- Zotlabs/Lib/Activity.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 8ad114a4d..388d74d91 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -292,7 +292,7 @@ class Activity { $ret = [ 'id' => z_root() . '/' . $id, 'type' => $type, - 'totalItems' => count($items), + 'totalItems' => $total, ]; } @@ -2525,6 +2525,9 @@ class Activity { intval($channel['channel_id']) ); if ($p) { + // set the owner to the owner of the parent + $item['owner_xchan'] = $p[0]['owner_xchan']; + // check permissions against the author, not the sender $allowed = perm_is_allowed($channel['channel_id'], $item['author_xchan'], 'post_comments'); if ((!$allowed)/* && $permit_mentions*/) { @@ -2560,9 +2563,8 @@ class Activity { $allowed = true; // reject public stream comments that weren't sent by the conversation owner - if ($is_sys_channel && $pubstream && $item['owner_xchan'] !== $observer_hash) { - // TODO: check why? This would make it impossible to fetch externals via zotfeed where $observer_hash = sys channel - // $allowed = false; + if ($is_sys_channel && $pubstream && $item['owner_xchan'] !== $observer_hash && ! $fetch_parents) { // TODO: check why? This would make it impossible to fetch externals via zotfeed where $observer_hash = sys channel + $allowed = false; } } -- cgit v1.2.3 From 74f8f2d956a24fbff04c3feeec50466bb3aea931 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 26 Jan 2021 12:11:01 +0000 Subject: thread listener improvements --- Zotlabs/Module/Activity.php | 14 ++++++++++++-- Zotlabs/Module/Item.php | 14 ++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Zotlabs/Module/Activity.php b/Zotlabs/Module/Activity.php index b75f0b245..48f2663cf 100644 --- a/Zotlabs/Module/Activity.php +++ b/Zotlabs/Module/Activity.php @@ -143,8 +143,8 @@ class Activity extends Controller { http_status_exit(403, 'Forbidden'); $i = ZlibActivity::encode_item_collection($nitems,'conversation/' . $item_id,'OrderedCollection'); - if($portable_id) { - ThreadListener::store(z_root() . '/activity/' . $item_id,$portable_id); + if($portable_id && (! intval($items[0]['item_private']))) { + ThreadListener::store(z_root() . '/activity/' . $item_id, $portable_id); } if(! $i) @@ -239,6 +239,16 @@ class Activity extends Controller { xchan_query($r,true); $items = fetch_post_tags($r,false); + if ($portable_id && (! intval($items[0]['item_private']))) { + $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + intval($items[0]['uid']), + dbesc($portable_id) + ); + if (! $c) { + ThreadListener::store(z_root() . '/activity/' . $item_id, $portable_id); + } + } + $channel = channelx_by_n($items[0]['uid']); $x = array_merge( ['@context' => [ diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 3d83bcf8f..b30adeb53 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -136,8 +136,8 @@ class Item extends Controller { if(! $i) http_status_exit(404, 'Not found'); - if($portable_id) { - ThreadListener::store(z_root() . '/item/' . $item_id,$portable_id); + if($portable_id && (! intval($items[0]['item_private']))) { + ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); } $x = array_merge(['@context' => [ @@ -238,8 +238,14 @@ class Item extends Controller { if(! $i) http_status_exit(404, 'Not found'); - if($portable_id) { - ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); + if ($portable_id && (! intval($items[0]['item_private']))) { + $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + intval($items[0]['uid']), + dbesc($portable_id) + ); + if (! $c) { + ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); + } } $x = array_merge(['@context' => [ -- cgit v1.2.3 From f813671b672a55873856649ea3405d52218c1500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20S=2E=20Budzi=C5=84ski?= Date: Wed, 27 Jan 2021 10:57:30 +0100 Subject: Merge branch 'translation-pl' into 'dev' Translation pl Polish translations (used on hub.hubzilla.pl) - view/pl: 100% - doc/pl: ~40% - doc/context/pl: 100% - doc/macros/pl: 100% See merge request hubzilla/core!1902 --- CHANGELOG | 1 - .../pl/admin/addons/assets/addon_repo_gui_1.png | Bin 0 -> 16983 bytes doc/context/pl/admin/addons/help.html | 14 + doc/context/pl/admin/logs/help.html | 20 + doc/context/pl/admin/queue/help.html | 7 + doc/context/pl/admin/security/help.html | 8 + doc/context/pl/appman/help.html | 10 + doc/context/pl/apps/edit/help.html | 7 + doc/context/pl/apps/help.html | 15 + doc/context/pl/cards/help.html | 31 + doc/context/pl/channel/help.html | 13 + doc/context/pl/chat/help.html | 19 + doc/context/pl/cloud/help.html | 17 + doc/context/pl/connections/help.html | 24 + doc/context/pl/connections/ifpending/help.html | 24 + doc/context/pl/connedit/help.html | 44 + doc/context/pl/events/help.html | 18 + doc/context/pl/mail/help.html | 25 + doc/context/pl/network/help.html | 36 + doc/context/pl/photos/help.html | 15 + doc/context/pl/profile/help.html | 17 + doc/context/pl/profiles/help.html | 49 + doc/context/pl/settings/account/help.html | 49 + doc/context/pl/settings/channel/help.html | 49 + doc/context/pl/settings/features/help.html | 35 + doc/context/pl/settings/tokens/help.html | 43 + doc/context/pl/webpages/help.html | 24 + doc/context/pl/wiki/help.html | 29 + doc/macros/pl/addons_footer.bb | 2 + doc/macros/pl/cloud_footer.bb | 2 + doc/macros/pl/main_footer.bb | 1 + doc/macros/pl/troubleshooting_footer.bb | 2 + doc/pl/AdvancedSearch.md | 52 + doc/pl/Features.md | 107 + doc/pl/TermsOfService.md | 9 + doc/pl/Translations.md | 89 + doc/pl/about/about.bb | 181 + doc/pl/about/about_hub.bb | 7 + doc/pl/about/project.bb | 181 + doc/pl/accounts_profiles_channels_basics.bb | 20 + doc/pl/acl_dialog_post.html | 42 + doc/pl/addons.bb | 117 + doc/pl/addons_gnusocial.bb | 64 + doc/pl/admin/administrator_guide.md | 593 + doc/pl/admin/hub_snapshots.md | 127 + doc/pl/admins.bb | 15 + doc/pl/bugs.bb | 31 + doc/pl/general.bb | 18 + doc/pl/main.bb | 20 + doc/pl/member/assets/qr_text_to_post.png | Bin 0 -> 273 bytes doc/pl/member/assets/zat_dialog.png | Bin 0 -> 81837 bytes doc/pl/member/bbcode.html | 343 + doc/pl/member/member_faq.bb | 11 + doc/pl/member/member_guide.bb | 1028 ++ doc/pl/toc.html | 75 + util/hmessages.po | 17550 ++++++++++--------- view/pl/cert_bad_eml.tpl | 19 + view/pl/cron_bad_eml.tpl | 16 + view/pl/hmessages.mo | Bin 0 -> 296728 bytes view/pl/hmessages.po | 16453 +++++++++++++++++ view/pl/hmessages.pot | 15710 +++++++++++++++++ view/pl/hstrings.php | 3575 ++++ view/pl/htconfig.tpl | 111 + view/pl/lostpass_eml.tpl | 33 + view/pl/passchanged_eml.tpl | 23 + view/pl/register_open_eml.tpl | 18 + view/pl/register_verify_eml.tpl | 24 + view/pl/register_verify_member.tpl | 33 + view/pl/update_fail_eml.tpl | 22 + view/theme/redbasic/css/blockmode.css | 0 view/theme/redbasic/css/mod_page.css | 0 view/theme/redbasic/css/narrow_navbar.css | 0 view/theme/redbasic/css/sloppy_photos.css | 0 view/theme/redbasic/css/style.css | 0 ..._black_diagonal_stripes_background_seamless.gif | Bin ..._white_diagonal_stripes_background_seamless.gif | Bin view/theme/redbasic/img/screenshot.png | Bin view/theme/redbasic/js/redbasic.js | 0 view/theme/redbasic/php/config.php | 0 view/theme/redbasic/php/style.php | 0 view/theme/redbasic/php/theme.php | 0 view/theme/redbasic/php/theme_init.php | 0 view/theme/redbasic/schema/Focus-Boxy.css | 0 view/theme/redbasic/schema/Focus-Boxy.php | 0 view/theme/redbasic/schema/Focus-Light.css | 0 view/theme/redbasic/schema/Focus-Light.php | 0 view/theme/redbasic/schema/dark.css | 0 view/theme/redbasic/schema/dark.php | 0 view/theme/redbasic/tpl/theme_settings.tpl | 0 89 files changed, 48658 insertions(+), 8709 deletions(-) create mode 100644 doc/context/pl/admin/addons/assets/addon_repo_gui_1.png create mode 100644 doc/context/pl/admin/addons/help.html create mode 100644 doc/context/pl/admin/logs/help.html create mode 100644 doc/context/pl/admin/queue/help.html create mode 100644 doc/context/pl/admin/security/help.html create mode 100644 doc/context/pl/appman/help.html create mode 100644 doc/context/pl/apps/edit/help.html create mode 100644 doc/context/pl/apps/help.html create mode 100644 doc/context/pl/cards/help.html create mode 100644 doc/context/pl/channel/help.html create mode 100644 doc/context/pl/chat/help.html create mode 100644 doc/context/pl/cloud/help.html create mode 100644 doc/context/pl/connections/help.html create mode 100644 doc/context/pl/connections/ifpending/help.html create mode 100644 doc/context/pl/connedit/help.html create mode 100644 doc/context/pl/events/help.html create mode 100644 doc/context/pl/mail/help.html create mode 100644 doc/context/pl/network/help.html create mode 100644 doc/context/pl/photos/help.html create mode 100644 doc/context/pl/profile/help.html create mode 100644 doc/context/pl/profiles/help.html create mode 100644 doc/context/pl/settings/account/help.html create mode 100644 doc/context/pl/settings/channel/help.html create mode 100644 doc/context/pl/settings/features/help.html create mode 100644 doc/context/pl/settings/tokens/help.html create mode 100644 doc/context/pl/webpages/help.html create mode 100644 doc/context/pl/wiki/help.html create mode 100644 doc/macros/pl/addons_footer.bb create mode 100644 doc/macros/pl/cloud_footer.bb create mode 100644 doc/macros/pl/main_footer.bb create mode 100644 doc/macros/pl/troubleshooting_footer.bb create mode 100644 doc/pl/AdvancedSearch.md create mode 100644 doc/pl/Features.md create mode 100644 doc/pl/TermsOfService.md create mode 100644 doc/pl/Translations.md create mode 100644 doc/pl/about/about.bb create mode 100644 doc/pl/about/about_hub.bb create mode 100644 doc/pl/about/project.bb create mode 100644 doc/pl/accounts_profiles_channels_basics.bb create mode 100644 doc/pl/acl_dialog_post.html create mode 100644 doc/pl/addons.bb create mode 100644 doc/pl/addons_gnusocial.bb create mode 100644 doc/pl/admin/administrator_guide.md create mode 100644 doc/pl/admin/hub_snapshots.md create mode 100644 doc/pl/admins.bb create mode 100644 doc/pl/bugs.bb create mode 100644 doc/pl/general.bb create mode 100644 doc/pl/main.bb create mode 100644 doc/pl/member/assets/qr_text_to_post.png create mode 100644 doc/pl/member/assets/zat_dialog.png create mode 100644 doc/pl/member/bbcode.html create mode 100644 doc/pl/member/member_faq.bb create mode 100644 doc/pl/member/member_guide.bb create mode 100644 doc/pl/toc.html create mode 100644 view/pl/cert_bad_eml.tpl create mode 100644 view/pl/cron_bad_eml.tpl create mode 100644 view/pl/hmessages.mo create mode 100644 view/pl/hmessages.po create mode 100644 view/pl/hmessages.pot create mode 100644 view/pl/hstrings.php create mode 100644 view/pl/htconfig.tpl create mode 100644 view/pl/lostpass_eml.tpl create mode 100644 view/pl/passchanged_eml.tpl create mode 100644 view/pl/register_open_eml.tpl create mode 100644 view/pl/register_verify_eml.tpl create mode 100644 view/pl/register_verify_member.tpl create mode 100644 view/pl/update_fail_eml.tpl mode change 100644 => 100755 view/theme/redbasic/css/blockmode.css mode change 100644 => 100755 view/theme/redbasic/css/mod_page.css mode change 100644 => 100755 view/theme/redbasic/css/narrow_navbar.css mode change 100644 => 100755 view/theme/redbasic/css/sloppy_photos.css mode change 100644 => 100755 view/theme/redbasic/css/style.css mode change 100644 => 100755 view/theme/redbasic/img/gray_and_black_diagonal_stripes_background_seamless.gif mode change 100644 => 100755 view/theme/redbasic/img/gray_and_white_diagonal_stripes_background_seamless.gif mode change 100644 => 100755 view/theme/redbasic/img/screenshot.png mode change 100644 => 100755 view/theme/redbasic/js/redbasic.js mode change 100644 => 100755 view/theme/redbasic/php/config.php mode change 100644 => 100755 view/theme/redbasic/php/style.php mode change 100644 => 100755 view/theme/redbasic/php/theme.php mode change 100644 => 100755 view/theme/redbasic/php/theme_init.php mode change 100644 => 100755 view/theme/redbasic/schema/Focus-Boxy.css mode change 100644 => 100755 view/theme/redbasic/schema/Focus-Boxy.php mode change 100644 => 100755 view/theme/redbasic/schema/Focus-Light.css mode change 100644 => 100755 view/theme/redbasic/schema/Focus-Light.php mode change 100644 => 100755 view/theme/redbasic/schema/dark.css mode change 100644 => 100755 view/theme/redbasic/schema/dark.php mode change 100644 => 100755 view/theme/redbasic/tpl/theme_settings.tpl diff --git a/CHANGELOG b/CHANGELOG index 0c54ababf..2c384ca97 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -41,7 +41,6 @@ Hubzilla 5.2 (2021-01-13) - Fix typo in notifier command - Fix profile title/description allowed more than 191 characters - Addons - Queueworker: cleanup whitespace - Queueworker: add some tweaks to prevent deadlocks for postgresql diff --git a/doc/context/pl/admin/addons/assets/addon_repo_gui_1.png b/doc/context/pl/admin/addons/assets/addon_repo_gui_1.png new file mode 100644 index 000000000..37139b345 Binary files /dev/null and b/doc/context/pl/admin/addons/assets/addon_repo_gui_1.png differ diff --git a/doc/context/pl/admin/addons/help.html b/doc/context/pl/admin/addons/help.html new file mode 100644 index 000000000..fe63718df --- /dev/null +++ b/doc/context/pl/admin/addons/help.html @@ -0,0 +1,14 @@ +
      +
      Ogólne
      +
      Ta strona zarządza instalacją dodatków (zwanych też wtyczkami).
      +
      Zarządzanie repozytorium
      +
      Jeśli serwer internetowy ma niezbędne uprawnienia do zapisu, zobaczysz przycisk Zarządzaj repozytoriami, + co otwiera panel sterowania do zarządzania zainstalowanymi repozytoriami wtyczek. Te repozytoria są + przechowywane w katalogu extension/addon/[nazwa repozytorium]/. + Oficjalne repozytorium dodatków Hubzilla można dodać, wprowadzając adres URL repozytorium + https://framagit.org/hubzilla/addons.git + i wybierając nazwę repozytorium, na przykład oficjalne. Powinieneś zobaczyć to repozytorium na liście + podobnej do tej: +
      +
      +
      diff --git a/doc/context/pl/admin/logs/help.html b/doc/context/pl/admin/logs/help.html new file mode 100644 index 000000000..1d79d6a8c --- /dev/null +++ b/doc/context/pl/admin/logs/help.html @@ -0,0 +1,20 @@ +
      +
      Ogólne
      +
      + Ta strona umożliwia dostosowanie ustawień dziennika oraz przeglądanie + istniejącego dziennika. +
      +
      Ustawienia dziennika
      +
      + Po włączeniu opcji debugowania informacje o zdarzeniach systemowych zaczną + być dołączane do pliku określonego w polu "Plik dziennika" (ścieżka jest + względna w stosunku do katalogu głównego huba, na przykład /var/www). + Zauważ, że ten plik musi być możliwy do zapisywania przez serwer WWW.
      +
      Pozion rejestracji
      +
      + Opcja poziomu dziennika umożliwia ustawienie ilości informacji dołączanych + do pliku dziennika. Ostrzeżenie: zwiększenie tego poziomu może szybko + zwiększyć rozmiar pliku dziennika do ponad 100 MB, szczególnie w hubach z + więcej niż kilkoma członkami. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/admin/queue/help.html b/doc/context/pl/admin/queue/help.html new file mode 100644 index 000000000..76277e0c2 --- /dev/null +++ b/doc/context/pl/admin/queue/help.html @@ -0,0 +1,7 @@ +
      +
      Ogólne
      +
      + Statystyki kolejki pokazują, ile postów znajduje się w kolejce do dostarczenia + do innych hubów. Priorytet jest powiązany z liczbą nieudanych prób dostawy. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/admin/security/help.html b/doc/context/pl/admin/security/help.html new file mode 100644 index 000000000..0e582e6b4 --- /dev/null +++ b/doc/context/pl/admin/security/help.html @@ -0,0 +1,8 @@ +
      +
      Ogólne
      +
      + Ta strona zawiera różne ustawienia administratora związane z bezpieczeństwem. + Aby zapisać zmiany wprowadzone w tych ustawieniach, musisz nacisnąć przycisk + "Prześlij". +
      +
      \ No newline at end of file diff --git a/doc/context/pl/appman/help.html b/doc/context/pl/appman/help.html new file mode 100644 index 000000000..867b5b482 --- /dev/null +++ b/doc/context/pl/appman/help.html @@ -0,0 +1,10 @@ +
      +
      Ogólne
      +
      + Edytowanie poszczególnych właściwości wybranej aplikacji. Kategorie umożliwiają + sortowanie aplikacji, aby ułatwić znajdowanie ich na liście. Wsparcie dla + niestandardowych aplikacji, które Ty lub Twój administrator możecie wybrać, + obejmuje pola, takie jak ""Cena aplikacji"" i "Lokalizacja zakupu"", które nie + są zastosowane w podstawowych aplikacjach Hubzilla. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/apps/edit/help.html b/doc/context/pl/apps/edit/help.html new file mode 100644 index 000000000..42db07d17 --- /dev/null +++ b/doc/context/pl/apps/edit/help.html @@ -0,0 +1,7 @@ +
      +
      Ogólne
      +
      + Edytowanie lub usuwanie aplikacje za pomocą przycisków sterowania widocznych + na liście obok każdej ikony aplikacji. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/apps/help.html b/doc/context/pl/apps/help.html new file mode 100644 index 000000000..7ad3bef5c --- /dev/null +++ b/doc/context/pl/apps/help.html @@ -0,0 +1,15 @@ +
      +
      Ogólne
      +
      + Ta strona pokazuje, jakie aplikacje są dostępne na Twoim kanale, w tym zarówno + aplikacje podstawowe, jak i te dostarczane przez dodatki. Aby dodać aplikację + do menu aplikacji oznacz gwiazdką + aplikację na poniższej liście. +
      +
      Zarządzanie aplikacjami
      +
      + Naciśnij przycisk "Zarządzaj aplikacjami", aby otworzyć stronę, na której + możesz edytować nazwę, kategorie i inne właściwości swoich aplikacji. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/cards/help.html b/doc/context/pl/cards/help.html new file mode 100644 index 000000000..f60d66f1c --- /dev/null +++ b/doc/context/pl/cards/help.html @@ -0,0 +1,31 @@ +
      +
      Ogólne
      +
      + Karty reprezentują trwały obszar współpracy, który jest niezależny od + strumienia społecznościowego. Są nieco lżejsze niż strony internetowe i wiki, + dzięki czemu zapewniają szybką organizację informacji i mają tę zaletę, że + umożliwiają współpracę i komentowanie. Są dobrze przystosowane do pomocy w + organizowaniu złożonych zadań, w przypadku których często pojawiają się + aktualizacje i informacje zwrotne. +
      +
      Dodanie karty
      +
      + Tworzenie nowej karty jest bardzo podobne do tworzenia nowego postaa.

      +
        +
      • + Nazwa linku do strony: nazwa linku do strony jest nazwą + karty dla statycznego adresu URL +
      • +
      • + Tytuł: Tytuł jest wyświetlany u góry karty +
      • +
      • + Kategorie: Jeśli na swoim kanale masz włączoną + funkcjonalność kategorii postów , + możesz dodawać kategorie do karty. Te kategorie zapełniają listę + Kategorie na lewym panelu i umożliwiają filtrowanie + kolekcji kart. +
      • +
      +
      +
      diff --git a/doc/context/pl/channel/help.html b/doc/context/pl/channel/help.html new file mode 100644 index 000000000..bd454c361 --- /dev/null +++ b/doc/context/pl/channel/help.html @@ -0,0 +1,13 @@ +
      +
      Ogólne
      +
      + To jest strona główna kanału. Jest ona podobna do "ściany" profilu w kontekście + sieci społecznościowej. Posty utworzone w kanale są wyświetlane zgodnie z + uprawnieniami obserwatora do oglądania treści. +
      +
      Tworzenie posta
      +
      + Jeśli masz uprawnienia do tworzenia postów na stronie kanału, u góry zobaczysz + edytor postów. +
      +
      diff --git a/doc/context/pl/chat/help.html b/doc/context/pl/chat/help.html new file mode 100644 index 000000000..3cd4e346f --- /dev/null +++ b/doc/context/pl/chat/help.html @@ -0,0 +1,19 @@ +
      +
      Ogólne
      +
      + Twórz pokoje rozmów i wykorzystuj je do komunikacji w czasie rzeczywistym, + używając standardowego systemu uprawnień Hubzilla do kontroli dostępu do + pokojów rozmów. +
      +
      Tworzenie nowego pokoju rozmów
      +
      + Użyj przycisku "Utwórz nowy", aby utworzyć nowy pokój rozmów. Wpisz nazwę i + jak długo wiadomości mają być przechowywane. +
      +
      Czatowanie
      +
      + Wpisz wiadomość w polu wiadomości i naciśnij "Prześlij". Możesz ustawić status, + wybierając przycisk menu pokoju rozmów sieciowych obok przycisku "Wyślij". + Inne osoby "w pokoju"" są widoczne w panelu bocznym w panelu „Członkowie czatu”. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/cloud/help.html b/doc/context/pl/cloud/help.html new file mode 100644 index 000000000..419ed01ee --- /dev/null +++ b/doc/context/pl/cloud/help.html @@ -0,0 +1,17 @@ +
      +
      Ogólne
      +
      + Ta strona wyświetla pliki "w chmurze" kanału. To co widi przeglądajacy zależy + od jego indywidualnych uprawnień do plików, które ustawia właściciel kanału. + Jeśli masz uprawnienia do tworzenia i przesyłania plików, zobaczysz przyciski + kontrolne nad listą plików. +
      +
      Karty zawartości kanału
      +
      + Karty zawarości kanału to linki do innych treści publikowanych przez kanał. + Karta Informacje prowadzi do profilu kanału. Karta Zdjęcia + prowadzi do galerii zdjęć kanału. Zakładka Pliki zawiera linki do + ogólnych plików udostępnionych do publikacji w kanale. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/connections/help.html b/doc/context/pl/connections/help.html new file mode 100644 index 000000000..837184334 --- /dev/null +++ b/doc/context/pl/connections/help.html @@ -0,0 +1,24 @@ +
      +
      Ogólne
      +
      + Ta strona wyświetla listę wszystkich połączeń tego kanału. Lista można + posortować i przefiltrować + za pomocą przycisku menu obok przycisku wyszukiwania . +
      +
      Szczegóły połączenia
      +
      + Każdy wpis na liście przedstawia szczegóły określonego połączenia. + Przezroczysty obraz awatara wskazuje na zarchiwizowane połączenie. +
      +
      Stan połączenie
      +
      + Połączenie może mieć różne stany: +
        +
      • Zarchiwizowane
      • +
      • Zignorowane
      • +
      • Zablokowane
      • +
      • Ukryte
      • +
      +
      +
      \ No newline at end of file diff --git a/doc/context/pl/connections/ifpending/help.html b/doc/context/pl/connections/ifpending/help.html new file mode 100644 index 000000000..b2d05947a --- /dev/null +++ b/doc/context/pl/connections/ifpending/help.html @@ -0,0 +1,24 @@ +
      +
      Ogólne
      +
      + Ta strona wyświetla listę wszystkich połączeń tego kanału. Lista można + posortować i przefiltrować + za pomocą przycisku menu obok przycisku wyszukiwania. +
      +
      Szczegóły połączenia
      +
      + Każdy wpis na liście przedstawia szczegóły określonego połączenia. + Przezroczysty obraz awatara wskazuje na zarchiwizowane połączenie. +
      +
      Stan połączenia
      +
      + Połączenie może mieć różne stany: +
        +
      • Zarchiwizowane
      • +
      • Zignorowane
      • +
      • Zablokowane
      • +
      • Ukryte
      • +
      +
      +
      \ No newline at end of file diff --git a/doc/context/pl/connedit/help.html b/doc/context/pl/connedit/help.html new file mode 100644 index 000000000..31a47c1fc --- /dev/null +++ b/doc/context/pl/connedit/help.html @@ -0,0 +1,44 @@ +
      +
      Ogólne
      +
      + Ta strona umożliwia zmianę lub edycję dowolnych indywidualnych ustawień dla + określonego połączenia lub całkowite usunięcie połączenia. Być może dotarłeś + do tej strony po utworzeniu lub zatwierdzeniu nowego połączenia. Jeśli tak, + nie musisz nic robić. Twoje połączenie zostało już nawiązane. + Możesz chcieć dodać je do grupy lub dostosować specjalne + uprawnienia, a ta strona jest prezentowana, abyś mógł to zrobić przy okazji + ustanowienie nowego połączenia. +
      +
      Narzędzia do połączeń
      +
      + Menu naarzędzi połączeń + umożliwia dostęp do kilku ustawień. Wyświetl profil, wyświetl ostatnią aktywność, + odśwież uprawnienia, ustaw lub zresetuj flagi (blokuj, ignoruj, archiwizuj, ukryj) + i usuń połączenie. +
      +
      Grupy prywatności
      +
      + Każde połączenie może być przypisane do jednej lub więcej grup prywatności + w celu grupowania kolekcji znajomych z dostępem do określonych postów, + multimediów i innych treści. Możesz dodać je tutaj do istniejącej grupy + prywatności lub utworzyć nową grupę prywatności. Po dodaniu ich do istniejącej + grupy akcja jest natychmiastowa i nie musisz przesyłać formularza. +
      +
      Indywidualne uprawniena
      +
      + Udzielanie uprawnień jest zwykle automatyczne i nie wymaga żadnych działań + z Twojej strony. Możesz jednak chcieć dostosować określone uprawnienia dla + tego połączenia, które są inne niż dla innych. +
      +
      Ustawienia specyficznych funkcji
      +
      + Szereg indywidualnych ustawień jest kontrolowanych za pomocą dodatkowych + funkcji, które mogą, ale nie muszą być aktywowane na Twoim hubie lub na Twoim + kanale. Kilka opcjonalnych funkcji ma ustawienia dla każdego połączenia, + które można ustawić na tej stronie za pomocą dodatkowych zakładek formularza. +
      +
      diff --git a/doc/context/pl/events/help.html b/doc/context/pl/events/help.html new file mode 100644 index 000000000..542661fa5 --- /dev/null +++ b/doc/context/pl/events/help.html @@ -0,0 +1,18 @@ +
      +
      Ogólne
      +
      + Na tej stronie wyświetlany jest kalendarz wydarzeń, który należy do Ciebie + oraz kalendarze, które zostały Ci udostępnione z innych kanałów. + /dd> +
      Widok kalendarza
      +
      + Kalendarz może być wyświetlany w trybie miesiąca, tygodnia lub dnia, przy użyciu + opcji widocznych na panelu bocznym. +
      +
      Eksport/Import
      +
      + Eksportuj lub importuj wydarzenia kalendarza przy użyciu plików w standardowym + formacie iCalendar (.ics). +
      +
      \ No newline at end of file diff --git a/doc/context/pl/mail/help.html b/doc/context/pl/mail/help.html new file mode 100644 index 000000000..b8497709c --- /dev/null +++ b/doc/context/pl/mail/help.html @@ -0,0 +1,25 @@ +
      +
      Ogólne
      +
      + Wiadomości wyświetlane w poczcie prywatnej są widoczne tylko dla Ciebie i + pojedynczego odbiorcy. +
      +
      Widok łączony
      +
      + Wybór opcji Widok łączony spowoduje wyświetlanie całych rozmów w ciągłym + wątku. Dostępne rozmowy są wyświetlane poniżej menu w panelu bocznym. +
      +
      Skrzynka odbiorcza/nadawcza
      +
      + Poszczególne wysłane wiadomości można wyświetlić, wybierając opcję + Skrzynka nadawcza, a wiadomości przychodzące - za pomocą filtru + Skrzynka odbiorcza. +
      +
      Nowa wiadomość
      +
      + Poszczególne wiadomości mają raporty doręczenia, które można wyświetlić za + pomocą rozwijanego menu. Wysłane wiadomości można również odwołać, posługując + się tym samym menu, co może uniemożliwić odbiorcy przegląd takich wiadomości, + jeśli jeszcze ich nie przeczytał. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/network/help.html b/doc/context/pl/network/help.html new file mode 100644 index 000000000..cbc6c035c --- /dev/null +++ b/doc/context/pl/network/help.html @@ -0,0 +1,36 @@ +
      +
      Ogólne
      +
      + Strona strumienia sieciowego wyświetla strumień postów i rozmów, zwykle + uporządkowanych według ostatnio zaktualizowanych. Jest to strona wysoce konfigurowalna. +
      +
      Tworzenie posta
      +
      + U góry strony znajduje się pole tekstowe z napisem "Udostępnij". Kliknięcie + tego pola otwiera nowy edytor postówów. Edytor postów można dostosowywać, ale + podstawowy edytor udostępnia pola dla treści posta i opcjonalnego tytułu. + Przyciski poniżej obszaru tekstowego po lewej stronie zapewniają skróty do + formatowania tekstu i wstawiania linków, obrazów i innych danych do posta. + Przyciski po prawej stronie zapewniają podgląd posta, ustawienia uprawnień do + publikowania oraz przycisk Prześlij do wysłania posta. +
      +
      Grupy prywatności
      +
      + Utworzone grupy prywatności są wyświetlane w panelu bocznym. Wybranie ich + powoduje filtrowanie postów do tych utworzonych przez kanały w wybranej grupie. +
      +
      Uprawnienia do posta
      +
      + Lista kontroli dostępu (ACL) służy do określania, kto może zobaczyć Twój nowy + post. Naciśnięcie przycisku ACL obok przycisku Prześlij spowoduje wyświetlenie + okna dialogowego, w którym możesz wybrać kanały albo grupy prywatności, które + będą widzieć post. Możesz także wybrać, komu wyraźnie odmówiono dostęp. + Załóżmy na przykład, że planujesz przyjęcie niespodziankę dla znajomego. + Możesz wysłać zaproszenie do wszystkich w swojej grupie Znajomi + oprócz znajomego, którego zaskakujesz. W tym przypadku "pokazujesz" + go grupie Znajomi, ale "nie pokazujesz" tej jednej osobie. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/photos/help.html b/doc/context/pl/photos/help.html new file mode 100644 index 000000000..e9ff7ee9d --- /dev/null +++ b/doc/context/pl/photos/help.html @@ -0,0 +1,15 @@ +
      +
      Ogólne
      +
      + Na tej stronie wyświetlane są albumy ze zdjęciami opublikowane w kanale. + Widoczność obrazów zależy od indywidualnych uprawnień odwiedzającego do tych zdjęć. +
      +
      Zakładki treści kanału
      +
      + Karty treści kanału to odnośniki do innych treści publikowanych przez kanał. + Karta Informacje prowadzi do profilu kanału. Karta Zdjęcia + prowadzi do galerii zdjęć kanału. Zakładka Pliki zawiera linki do + ogólnych plików udostępnionych w kanale. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/profile/help.html b/doc/context/pl/profile/help.html new file mode 100644 index 000000000..9ec5b0e73 --- /dev/null +++ b/doc/context/pl/profile/help.html @@ -0,0 +1,17 @@ +
      +
      Ogólne
      +
      + To jest strona profilu kanału. Zwykle wyświetla informacje opisujące kanał. + Jeśli na przykład kanał reprezentuje osobę w sieci społecznościowej, profil + może zawierać informacje kontaktowe i inne dane osobowe tej osoby. Kanały mogą + mieć wiele profili, przy czym wyświetlany profil zależy od obserwatora. +
      +
      Zakładki treści kanału
      +
      + Karty treści kanału to odnośniki do innych treści publikowanych przez kanał. + Karta Informacje prowadzi do profilu kanału. Karta Zdjęcia + prowadzi do galerii zdjęć kanału. Zakładka Pliki zawiera linki do ogólnych + plików opublikowanych i udostępnionych w kanale. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/profiles/help.html b/doc/context/pl/profiles/help.html new file mode 100644 index 000000000..18953a829 --- /dev/null +++ b/doc/context/pl/profiles/help.html @@ -0,0 +1,49 @@ +
      +
      Ogólne
      +
      + Po zarejestrowaniu konta w matrycy, utworzony został również + profil i kanał. +
      +
      Konto
      +
      + Masz teraz jedno konto. Składa się z Twojego adresu e-mail i + hasła. Za pomocą swojego konta uzyskujesz dostęp do profili i kanałów. + Pomyśl o swoim koncie jak o sposobie uwierzytelniania w jednym + serwisie Hubzilla. To pozwala wykonywać różne czynności, takie jak + tworzenie profili i kanałów, za pomocą których można łączyć się z + innymi osobami. +
      +
      Profil
      +
      + Z pewnością już zarejestrowałeś/zarejestrowałaś się w innych usługach + internetowych, takich jak fora lub społeczności internetowe. W nich + wszystkich trzeba było podać pewne informacje o sobie, takie jak data + urodzenia, kraj, wiek i upodobania. W przeciwieństwie do nich + usługi Hubzilla daje Ci przewagę tworzenia wielu profili . + W ten sposób możesz rozróżniać profil przeznaczone specjalnie dla + wszystkich (Twój profil publiczny), od profili przeznaczonych dla + współpracowników, rodziny czy partnera. Potraktuj swój profil + jak pojemnik zawierający podstawowe informacje o Tobie, jakie + przekazujesz innym osobom. +
      +
      Kanał
      +
      + Podczas rejestracji utworzyłeś/utworzyłaś swój pierwszy kanał. + Tak, poza kilkoma profilami, również możesz mieć kilka kanałów. Na + początku może to być nieco zagmatwane, ale wyjaśnijmy to. Już masz + utworzony jeden kanał. Możesz używać go do publicznego komunikowania + się z osobami w życiu codziennym. Lecz być może jesteś zapalonym + czytelnikiem książek a wielu ludzi się tym nudzi. Otwierasz więc + drugi kanał dla miłośników książek, gdzie wszyscy mogą rozmawiać + o książkach tyle, ile zechcą. Oczywiście jest to nowy strumień postów, + z nowym profilem (... lub nowymi profilami) i zupełnie z innymi + kontaktami. Niektóre połączenia mogą istnieć w obu kanałach, ale będą + takie, które będą występować wyłącznie w jednym z nich. Ty po prostu + przełączaj się między nimi tak, jak w prawdziwym życiu, gdy rozmawiasz + z ludźmi, których spotykasz na ulicy lub z osobami, które spotykasz + specjalnie, aby porozmawiać o książkach. Możesz nawet połączyć się + ze sobą lub lepiej: ze swoim innym kanał. :) Pomyśl o kanałach + jak o różnych przestrzeniach poświęconych różnym tematom, w których + spotykasz się z różnymi osobami. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/settings/account/help.html b/doc/context/pl/settings/account/help.html new file mode 100644 index 000000000..0507c73cf --- /dev/null +++ b/doc/context/pl/settings/account/help.html @@ -0,0 +1,49 @@ +
      +
      Ogólne
      +
      + Po zarejestrowaniu konta w matrycy, utworzony został również + profil i kanał. +
      +
      Konto
      +
      + Masz teraz jedno konto. Składa się z Twojego adresu e-mail i + hasła. Za pomocą swojego konta uzyskujesz dostęp do profili i kanałów. + Pomyśl o swoim koncie jak o sposobie uwierzytelniania w jednym + serwisie Hubzilla. To pozwala wykonywać różne czynności, takie jak + tworzenie profili i kanałów, za pomocą których można łączyć się z + innymi osobami. +
      +
      Profil
      +
      + Z pewnością już zarejestrowałeś/zarejestrowałaś się w innych usługach + internetowych, takich jak fora lub społeczności internetowe. W nich + wszystkich trzeba było podać pewne informacje o sobie, takie jak data + urodzenia, kraj, wiek i upodobania. W przeciwieństwie do nich + usługi Hubzilla daje Ci przewagę tworzenia wielu profili . + W ten sposób możesz rozróżniać profil przeznaczone specjalnie dla + wszystkich (Twój profil publiczny), od profili przeznaczonych dla + współpracowników, rodziny czy partnera. Potraktuj swój profil + jak pojemnik zawierający podstawowe informacje o Tobie, jakie + przekazujesz innym osobom. +
      +
      Kanał
      +
      + Podczas rejestracji utworzyłeś/utworzyłaś swój pierwszy kanał. + Tak, poza kilkoma profilami, również możesz mieć kilka kanałów. Na + początku może to być nieco zagmatwane, ale wyjaśnijmy to. Już masz + utworzony jeden kanał. Możesz używać go do publicznego komunikowania + się z osobami w życiu codziennym. Lecz być może jesteś zapalonym + czytelnikiem książek a wielu ludzi się tym nudzi. Otwierasz więc + drugi kanał dla miłośników książek, gdzie wszyscy mogą rozmawiać + o książkach tyle, ile zechcą. Oczywiście jest to nowy strumień postów, + z nowym profilem (... lub nowymi profilami) i zupełnie z innymi + kontaktami. Niektóre połączenia mogą istnieć w obu kanałach, ale będą + takie, które będą występować wyłącznie w jednym z nich. Ty po prostu + przełączaj się między nimi tak, jak w prawdziwym życiu, gdy rozmawiasz + z ludźmi, których spotykasz na ulicy lub z osobami, które spotykasz + specjalnie, aby porozmawiać o książkach. Możesz nawet połączyć się + ze sobą lub lepiej: ze swoim innym kanał. :) Pomyśl o kanałach + jak o różnych przestrzeniach poświęconych różnym tematom, w których + spotykasz się z różnymi osobami. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/settings/channel/help.html b/doc/context/pl/settings/channel/help.html new file mode 100644 index 000000000..0507c73cf --- /dev/null +++ b/doc/context/pl/settings/channel/help.html @@ -0,0 +1,49 @@ +
      +
      Ogólne
      +
      + Po zarejestrowaniu konta w matrycy, utworzony został również + profil i kanał. +
      +
      Konto
      +
      + Masz teraz jedno konto. Składa się z Twojego adresu e-mail i + hasła. Za pomocą swojego konta uzyskujesz dostęp do profili i kanałów. + Pomyśl o swoim koncie jak o sposobie uwierzytelniania w jednym + serwisie Hubzilla. To pozwala wykonywać różne czynności, takie jak + tworzenie profili i kanałów, za pomocą których można łączyć się z + innymi osobami. +
      +
      Profil
      +
      + Z pewnością już zarejestrowałeś/zarejestrowałaś się w innych usługach + internetowych, takich jak fora lub społeczności internetowe. W nich + wszystkich trzeba było podać pewne informacje o sobie, takie jak data + urodzenia, kraj, wiek i upodobania. W przeciwieństwie do nich + usługi Hubzilla daje Ci przewagę tworzenia wielu profili . + W ten sposób możesz rozróżniać profil przeznaczone specjalnie dla + wszystkich (Twój profil publiczny), od profili przeznaczonych dla + współpracowników, rodziny czy partnera. Potraktuj swój profil + jak pojemnik zawierający podstawowe informacje o Tobie, jakie + przekazujesz innym osobom. +
      +
      Kanał
      +
      + Podczas rejestracji utworzyłeś/utworzyłaś swój pierwszy kanał. + Tak, poza kilkoma profilami, również możesz mieć kilka kanałów. Na + początku może to być nieco zagmatwane, ale wyjaśnijmy to. Już masz + utworzony jeden kanał. Możesz używać go do publicznego komunikowania + się z osobami w życiu codziennym. Lecz być może jesteś zapalonym + czytelnikiem książek a wielu ludzi się tym nudzi. Otwierasz więc + drugi kanał dla miłośników książek, gdzie wszyscy mogą rozmawiać + o książkach tyle, ile zechcą. Oczywiście jest to nowy strumień postów, + z nowym profilem (... lub nowymi profilami) i zupełnie z innymi + kontaktami. Niektóre połączenia mogą istnieć w obu kanałach, ale będą + takie, które będą występować wyłącznie w jednym z nich. Ty po prostu + przełączaj się między nimi tak, jak w prawdziwym życiu, gdy rozmawiasz + z ludźmi, których spotykasz na ulicy lub z osobami, które spotykasz + specjalnie, aby porozmawiać o książkach. Możesz nawet połączyć się + ze sobą lub lepiej: ze swoim innym kanał. :) Pomyśl o kanałach + jak o różnych przestrzeniach poświęconych różnym tematom, w których + spotykasz się z różnymi osobami. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/settings/features/help.html b/doc/context/pl/settings/features/help.html new file mode 100644 index 000000000..a33e546f4 --- /dev/null +++ b/doc/context/pl/settings/features/help.html @@ -0,0 +1,35 @@ +
      +
      Ogólne
      +
      + Ta strona umożliwia skonfigurowanie ustawień dla wielu dodatkowych funkcji Hubzilli. +
      +
      Główne cechy
      +
      + Ogólne ustawienia funkcji zawierają opcje związane z Twoim kanałem, takie jak + hosting strony internetowej i wiki. +
      +
      Funkcje kompozycji postów
      +
      + Funkcje kompozycji postów zapewniają dodatkowe opcje i możliwości podczas + tworzenia nowych postów. +
      +
      Sieć i fitrowanie strumienia
      +
      + Te ustawienia modyfikują funkcje związane z filtrowaniem i kontrolowaniem widoku + przychodzących postów. +
      +
      Narzędzia postów i komentarzy
      +
      + Ustawienia te zapewniają dodatkowe narzędzia do kategoryzowania postów + i umożliwiają dodatkowe metody komentowania, takie jak emoji lub tagowanie + społecznościowe. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/settings/tokens/help.html b/doc/context/pl/settings/tokens/help.html new file mode 100644 index 000000000..cebe30ced --- /dev/null +++ b/doc/context/pl/settings/tokens/help.html @@ -0,0 +1,43 @@ +
      +
      Tokeny dostępu gościa
      +
      + Aby ułatwić udostępnianie prywatnych zasobów osobom niebędącym członkami + lub członkami sfederyzowanych węzłów (hubów) i zapewnić zabezpieczone + wykrywaniem danych identyfikacyjnych, Hubzilla zawiera mechanizm tworzenia + i zarządzania tymczasowymi ("jednorazowymi") loginami, zwanymi "tokenami + dostępu Zot”. Tokeny te, będące swojego rodzaju danymi uwierzytelniającymi, + mogą być używane do uwierzytelniania w serwisie Hubzilla wyłącznie w celu + uzyskania dostępu do uprzywilejowanych lub kontrolowanych zasobów (pliki, + zdjęcia, posty, strony internetowe, pokoje rozmów itp.). +
      +
      Utworzenie tokenu
      +
      + Formularz do tworzenia i edycji akceptuje trzy parametry: czytelną dla + człowieka nazwę, hasło lub token dostępu oraz opconalną okres ważności. + Po wygaśnięciu token dostępu nie jest już ważny, nie może być już używany + i będzie automatycznie usunięte z listy kont tymczasowych. Pole hasła + w formularzach tworzenia i edycji wyświetla tekst tokenu dostępu, a nie + zasłonięte hasło. +
      +
      Udostępnienie tokenu
      +
      + Nie jest narzucony sposób udostępniania tych tokenów innym osobom. Można + użyć dowolnej metody komunikacji. Wszystkie utworzone tokeny są dodawane + do selektora listy kontroli dostępu i mogą być używane wszędzie tam, gdzie + są dostępne listy kontroli dostępu. + + Przykład: Odwiedzający nawiguje w przeglądarce do Twojąej witryny. + Ma podany przez Ciebie token dostępu i próbuje odwiedzić jeden z Twoich + albumów ze zdjęciami (który jest ograniczony do przeglądania tylko przez + Ciebie i jedną tymczasową tożsamość). Odmowa dostępu. + + Odwiedzający wybiera teraz opcję „Zaloguj się” z paska nawigacji menu. + To wyświetli stronę logowania. Wpisuje tam nazwę i hasło, które podałeś + i może teraz przeglądać zabezpieczony album ze zdjęciami. + + Alternatywnie możesz udostępnić łącze do chronionego pliku, dodając parametr + "&zat=abc123" do adresu URL, gdzie ciąg "abc123" to token dostępu lub + hasło do tymczasowego logowania. Nie są wymagane dalsze negocjacje + a żądany zasób zostanie wyświetlony. +
      +
      \ No newline at end of file diff --git a/doc/context/pl/webpages/help.html b/doc/context/pl/webpages/help.html new file mode 100644 index 000000000..64858fcf6 --- /dev/null +++ b/doc/context/pl/webpages/help.html @@ -0,0 +1,24 @@ +
      +
      Ogólne
      +
      + Możesz tworzyć modułowe, rozpoznające tożsamość witryny internetowe, składające + się z elementów, które można udostępniać. +
      +
      Strony
      +
      + Tutaj znajduje się lista Twoich "stron" z przypisanymi adresami URL, + pod którymi osoby mogą je odwiedzać. Struktura stron jest zwykle opisywana + przez powiązany układ, a ich zawartość jest tworzona ze zbioru bloków. +
      +
      Narzędzia do przenoszenia stron internetowych
      +
      + Narzędzia do przenoszenia witryn umożliwiają importowanie i eksportowanie wielu + elementów strony internetowej (stron, układów, bloków). Możesz zaimportować + te alementy albo z przesłanego pliku ZIP, albo z istniejącego folderu plików + w chmurze. Możesz je wyeksportować do pliku zip zawierającego wybraną + grupę elementów strony internetowej w formie zgodnej z narzędziem do importowania + lub możesz wyeksportować bezpośrednio do folderu plików w chmurze. + Czytaj więcej ... +
      +
      \ No newline at end of file diff --git a/doc/context/pl/wiki/help.html b/doc/context/pl/wiki/help.html new file mode 100644 index 000000000..6aa6a7192 --- /dev/null +++ b/doc/context/pl/wiki/help.html @@ -0,0 +1,29 @@ +
      +
      Ogólne
      +
      + Każda wiki to zbiór stron utworzonych jako pliki tekstowe w formacie Markdown. +
      +
      Wykaz Wiki
      +
      + Strony wiki należące do kanału, do przeglądania którego masz uprawnienia, + są wymienione w panelu bocznym. +
      +
      Historia strony
      +
      + Zapisywana jest każda wersja strony, aby umożliwić szybkie przywrócenie. + Kliknij kartę Historia, aby wyświetlić historię zmian strony, w tym + datę i autora każdej z nich. Przycisk przywróć załaduje wybraną wersję, ale + nie zapisze automatycznie strony. +
      +
      Strony
      +
      + Lista stron wiki znajduje się w panelu Strony Wiki. Przed zapisaniem + zmian na stronie za pomocą rozwijanego menu Strona można + wprowadzić + własny komunikat, który będzie wyświetlany w + Historii + strony przeglądarki wraz z wersją. +
      +
      diff --git a/doc/macros/pl/addons_footer.bb b/doc/macros/pl/addons_footer.bb new file mode 100644 index 000000000..f16d5cce3 --- /dev/null +++ b/doc/macros/pl/addons_footer.bb @@ -0,0 +1,2 @@ +Return to the [zrl=[baseurl]/help/addons]Dokumentacja dodatków[/zrl] +Return to the [zrl=[baseurl]/help/main]Główna dokumentacja[/zrl] diff --git a/doc/macros/pl/cloud_footer.bb b/doc/macros/pl/cloud_footer.bb new file mode 100644 index 000000000..a9db7f819 --- /dev/null +++ b/doc/macros/pl/cloud_footer.bb @@ -0,0 +1,2 @@ +Return to the [zrl=[baseurl]/help/cloud]Dokumentacja chmury[/zrl] +Return to the [zrl=[baseurl]/help/main]Główna strona dokumentacji[/zrl] diff --git a/doc/macros/pl/main_footer.bb b/doc/macros/pl/main_footer.bb new file mode 100644 index 000000000..8bf25fed5 --- /dev/null +++ b/doc/macros/pl/main_footer.bb @@ -0,0 +1 @@ +Powróć do [zrl=[baseurl]/help/main]głównej strony dokumentacji[/zrl] diff --git a/doc/macros/pl/troubleshooting_footer.bb b/doc/macros/pl/troubleshooting_footer.bb new file mode 100644 index 000000000..19328ad64 --- /dev/null +++ b/doc/macros/pl/troubleshooting_footer.bb @@ -0,0 +1,2 @@ +[zrl=[baseurl]/help/troubleshooting]Dokumentacja dotycząca rozwiązywania problemów[/zrl] +[zrl=[baseurl]/help/troubleshooting]Główna strona dokumentacji[/zrl] diff --git a/doc/pl/AdvancedSearch.md b/doc/pl/AdvancedSearch.md new file mode 100644 index 000000000..f76ddf99e --- /dev/null +++ b/doc/pl/AdvancedSearch.md @@ -0,0 +1,52 @@ +Zaawansowane przeszukiwanie katalogu +==================================== + +Zaawansowane wyszukiwanie w katalogu jest włączone w "Trybie eksperta" na stronie Ustawienia > Dodatkowe funkcje. + +Na stronie katalogu, w widżecie "Znajdź kanały" (zazwyczaj na pasku bocznym) widoczna jest opcja "Zaawansowane". Kliknięcie jej otwiera kolejne pole wyszukiwania umożliwiające wprowadzenie żądań wyszukiwania zaawansowanego. + +Zaawansowane żądania zawierają: + +* name=xxx +[Nazwa kanału zawiera xxx] + +* address=xxx +[Adres kanału (webbie) zawiera xxx] + +* locale=xxx +[Lokalizaja (zazwyczaj 'city') zawiera xxx] + +* region=xxx +[Region (stan/terytorium) zawiera xxx] + +* postcode=xxx +[Kod pocztowy lub kod ZIP zawiera xxx] + +* country=xxx +[Nazwa kraju zawiera xxx] + +* gender=xxx +[Płeć zawiera xxx] + +* marital=xxx +[Stan cywilny zawiera xxx] + +* sexual=xxx +[Preferencje seksualne zawierają xxx] + +* keywords=xxx +[Słowa kluczowe zawierają xxx] + +Istnieje wiele powodów, dla których dopasowanie może nie zwrócić tego, czego szukasz, ponieważ wiele kanałów nie podaje szczegółowych informacji w swoim domyślnym (publicznym) profilu, a wiele z tych pól umożliwia wprowadzanie dowolnego tekstu w kilku językach - i sprawia to trudność w dokładnym dopasowaniu. Na przykład możesz uzyskać lepszy wynik, chcąc znaleźć kogoś w USA, nie za pomocą frazy `'country = u'` (bo pojawią sie też kanały z Niemiec, Bułgarii i Australii), a za pomocą fraz US, U.S.A, USA, United States, itd. + +Przyszłe wersje tego narzędzia mogą już działać lepiej. + +Żądania można łączyć ze sobą za pomocą operatorów `and`, `or` lub `and not`. + +Frazy zawierające spacje należy ujmowć w cudzysłowy. + +Przykład: + + name="charlie brown" and country=canada and not gender=female + +#include doc/macros/pl/main_footer.bb; diff --git a/doc/pl/Features.md b/doc/pl/Features.md new file mode 100644 index 000000000..1977df379 --- /dev/null +++ b/doc/pl/Features.md @@ -0,0 +1,107 @@ +Dodatkowe możliwości +==================== + +Domyślny interfejs $Projectname został zaprojektowany tak, aby był dobrze uporządkowany. Istnieje ogromna liczba dodatkowych funkcji (niektóre są bardzo przydatne), które można włączyć i jak najlepiej wykorzystać. Można je znaleźć pod klikając link [Dodatkowe funkcje](settings/features) na stronie [Ustawienia](settings). + +**Wygaśnięcie treści** + +Usuwanie postów, komentarzy albo prywatnych wiadomości w określonym terminie. Do edytora postów zostaje dodany dodatkowy przycisk, za pomoca któreg można ustawić termin wygaśnięcia publikacji. Zwykle data jest wyświetlana w formacie „rrrr-mm-dd gg: mm”, ale w języku angielskim ma się nieco większą swobodę i można używać większości rozpoznawalnych odniesień do dat, takich jak "next Thursday" czy "+1 day". W określonym terminie (podanym lub zajmującym około dziesięciu minut, w zależności od częstotliwości sprawdzania zdalnego systemu) element jest usuwany. + +**Wiele profili** + +Możliwość tworzenia wielu profili, które są widoczne tylko dla określonych osób lub grup. Twój profil domyślny może być widoczny dla każdego, ale wszystkie profile dodatkowe mogą zawierać inne lub dodatkowe informacje i mogą być widoczne tylko dla tych, do których jest przypisany. + +**Strony internetowe** + +Zapewnia możliwość korzystania z funkcji projektowania stron internetowych i tworzenia niestandardowych stron internetowych na podstawie własnej zawartości, a także projektowania stron z układami stron, niestandardowymi elemntami menu i blokami treści. + + +**Prywatne notatki** + +Na stronach, na których jest to dostępne (Twoja matryca i osobiste strony internetowe), zapewnia widżet do tworzenia i przechowywania osobistych przypomnień i notatek. + +**Ulepszone albumy ze zdjęciami** + +Zapewnia przeglądarkę albumów zdjęć, która ma nieco ładniejszy interfejs niż zwykły album. + +**Rozszerzone udostępnianie tożsamości** + +Domyślnie Twoja tożsamość "podróżuje" z Tobą, gdy przeglądasz matrycę zdalnych witryn - tam też wiedzą kim jesteś i mogą wyświetlać Ci treści, które tylko Ty widzisz. Dzięki rozszerzonemu udostępnianiu tożsamości możesz dostarczyć te informacje do dowolnej odwiedzanej witryny z poziomu swojej matrycy. + +**Tryb ekspercki** + +Pozwala to zobaczyć niektóre zaawansowane opcje konfiguracji, które mogą dezorientować niektóre osoby lub powodować problemy z obsługą. Funkcjonalność ta może zapewnić pełną kontrolę nad funkcjami i kolorami motywu - dzięki czemu można dostosować dużą liczbę ustawień motywu wyświetlania do własnych upodobań. + +**Kanał Premium** + +Dzięki temu możesz ustawić ograniczenia i warunki dotyczące tych, które łączą się z Twoim kanałem. Może to być używane przez celebrytów lub kogoś, kto chce postawić jakieś warunki osobom, które chcą się połączyć z tym kanałe. Jednym z warunków moze byc dokonanie płatności za połączenie. + +**Edytor tekstu formatowanego** + +Edytor postów dostępny z poziomy matrycy jest edytorem zwykłego tekstu, ale matryca pozwala na stosowanie szerokieo zakresu znaczników przy użyciu BBcode. Edytor wizualny jest natomiast edytorem WYSIWIG (what you see is what you get - otrzymujesz to, co widzisz)i zapewnia wszystkie najczęściej używane znaczniki BBcode. + +**Podgląd wpisu** + +Umożliwia podgląd postów i komentarzy dokładnie tak, jak wyglądałyby na stronie przed ich opublikowaniem. + +**Źródła kanałów** + +Automatycznie importuje i ponownie publikuje zawartość kanału z innych kanałów lub źródeł. Umożliwia to tworzenie podkanałów i superkanałów z treści publikowanych gdzie indziej. Zasady są takie, że treść musi być publiczna, a właściciel kanału musi udzielić Ci pozwolenia na pozyskiwanie swojego kanału. + +**Jeszcze więcej szyfrowania** + +Stadardowo, prywatne wiadomości są szyfrowane podczas transportu i przechowywania. W dzisiejszych czasach to szyfrowanie może nie wystarczyć, jeśli twoja komunikacja jest wyjątkowo wrażliwa. Ta opcja umożliwia dodatkowo szyfrowanie treści "end-toend" za pomocą wspólnego tajnego klucza. Sposób, w jaki odbiorca pozna tajny klucz, zależy wyłącznie od Ciebie. Możesz podać wskazówkę, na przykład "imię pierwszego psa cioci Kloci". + +**Wyszukiwanie wg daty** + +Daje to możliwość wybierania postów według zakresów dat + +**Filtr grup prywatności** + +Włączenie tego widżetu umożliwia wyświetlanie strumienia postów tylko z wybranych grup połączeń. Powoduje to również przełączenie uprawnień wychodzących podczas przeglądania grupy prywatności. Jest to podobne do "kręgów" Google czy też "aspektów" w Disaporze. + +**Zapisane wyszukiwania** + +Udostępnia widżet wyszukiwania na stronie matrycy, który może zapisywać wybrane frazy wyszukiwania do ponownego wykorzystania. + +**Zakładka Osobiste** + +Włącz tą kartę, aby wyświetlać tylko wpisy matrycowe, z którymi w jakiś sposób wchodziłeś w interakcję, jako autor lub współautor konwersacji. + +**Zakładka Nowy** + +Włącza tą kartę, aby wyświetlać wszystkich nowych działania matrycy jako węża strażackiego lub osi czasu. + +**Narzedzia zaprzyjaźnienia** + +Filtrowanie aktywności strumienia matrycy według głębokości relacji. + +**Edytuj wysłane posty** + +Mozliwość edytowania i poprawiania postów i komentarzy juz po wysłaniu. + +**Tagowanie** + +Możliwość tagowania istniejących postów, w tym napisanych przez innych. + +**Kategorie postów** + +Możliwość dodawania kategorie do postów na swoim kanale + +**Zapisane foldery** + +Możliwość umieszczania postów w folderach lub tagach do późniejszego przywołania. + +**Dezaprobata postów** + +Możliwość dezaprobaty ("niepolubienia") wpisów i komentarzy. + +**Gwiazdkowanie postów** + +Możliwość oznaczania specjalnych postów znakiem gwiazdki + +**Chmura tagów** + +Udostępnienie osobistej chmury tagów na stronie swojego kanału + +#include doc/macros/pl/main_footer.bb; diff --git a/doc/pl/TermsOfService.md b/doc/pl/TermsOfService.md new file mode 100644 index 000000000..9b42edc4a --- /dev/null +++ b/doc/pl/TermsOfService.md @@ -0,0 +1,9 @@ +Regulamin serwisu +================= + +#include doc/pl/SiteTOS.md; + +Polityka prywatności +==================== + +#include doc/pl/gdpr1.md; \ No newline at end of file diff --git a/doc/pl/Translations.md b/doc/pl/Translations.md new file mode 100644 index 000000000..4b9e2793b --- /dev/null +++ b/doc/pl/Translations.md @@ -0,0 +1,89 @@ +Tłumaczenie $Projectname +======================== + +Procedura tłumaczenia +--------------------- + +Ciągi używane w interfejsie użytkownika $Projectname są tłumaczone +w [Transifex][1], a następnie przeniesione do repozytorium Git na +github. Jeśli chcesz pomóc w tłumaczeniu dla dowolnego języka, czy +to poprawianie warunków, czy tłumaczenie $Projectname na plik aktualnie +nieobsługiwany język, zarejestruj konto na transifex.com i skontaktuj +się z tamtejszym zespołem tłumaczy Redmatrix. + +Tłumaczenie $Projectname jest proste. Po prostu użyj narzędzia online +w transifex. Jeśli nie chcesz mieć do czynienia z git & co. w porządku, +regularnie sprawdzamy status tłumaczeń i importujemy je do drzewa +źródłowego na github, aby inni mogli z nich korzystać. + +Nie uwzględniamy każdego tłumaczenia z transifex w drzewie źródłowym, +aby uniknąć rozproszonego i zakłóconego ogólnego doświadczenia. Jako +niewykształcone przypuszczenie mamy dolną granicę 50% przetłumaczonych +ciągów, zanim włączymy język. Limit ten jest oceniany tylko na podstawie +ilości przetłumaczonych ciągów przy założeniu, że najbardziej widoczne +ciągi dla interfejsu użytkownika zostaną przetłumaczone jako pierwsze +przez zespół tłumaczący. Jeśli uważasz, że Twoje tłumaczenie będzie +przydatne przed tym limitem, skontaktuj się z nami, a prawdopodobnie +uwzględnimy pracę Twoich zespołów w drzewie źródłowym. + +Jeśli chcesz samodzielnie przenieść swoją pracę do drzewa źródłowego, +zrób to i skontaktuj się z nami i zadaj pytanie, które się pojawi. +Proces jest prosty, a oprogramowanie $Projectname jest dostarczane ze wszystkimi +niezbędnymi narzędziami. + +Lokalizacją przetłumaczonych plików jest w drzewie źródłowym katalog +`/view/LNG-CODE/`, ggdzie LNG-CODE jest używanym kodem języka, np. +`de` dla niemieckiego lub `fr` dla francuskiego. +W przypadku szablonów wiadomości e-mail (pliki `*.tpl`) po prostu umieść +je w katalogu i gotowe. Przetłumaczone łańcuchy pochodzą z pliku +"hmessages.po" z transifex, który należy przetłumaczyć na plik PHP +używany przez $Projectname. Aby to zrobić, umieść plik w wymienionym +wyżej katalogu i użyj narzędzia `po2php` z katalogu `util` w instalacji +$Projectname. + +Zakładając, że chcesz przetłumaczyć niemiecką wersję umieszczoną pliku +`view/de/hmessages.po`, wykonaj następujące czynności. + +1. Przejdź w wierszu polecenia do katalogu głównego instalacji $Projectname + +2. Wykonaj skrypt `po2php`, który jest umieszczono tłumaczenia dla pliku `hstrings.php`, który jest używany w $Projectname. + + $> php util/po2php.php view/de/hmessages.po + + Dane wyjściowe skryptu zostaną umieszczone w `view/de/hstrings.php, gdzie + froemdoca oczekuje tego pliku, więc możesz natychmiast przetestować swoje + tłumaczenie. + +3. Odwiedź swoją stronę $Projectname, aby sprawdzić, czy nadal działa w języku, który właśnie przetłumaczyłeś. Jeśli nie, spróbuj znaleźć błąd, najprawdopodobniej PHP da ci wskazówkę w opisie błędu w `log/warnings.about`. + + W celu debugowania możesz również spróbować "uruchomić" plik za pomocą PHP. Nie powinno to dawać żadnych wyników, jeśli plik jest w porządku, ale może dać wskazówkę dotyczącą wyszukiwania błędu. + + $> php view/de/hstrings.php + +4. Zatwierdź te dwa pliki z sensownym komunikatem o zatwierdzeniu do repozytorium git, wypchnij je do rozwidlenia repozytorium $Projectname na github i wydaj żądanie ściągnięcia dla tego zatwierdzenia. + +Narzędzia +--------- + +Oprócz skryptu po2php, jest jeszcze w katalogu "util" w drzewie źródłowym $Projectname +kilka narzędzi do tłumaczenia. Jeśli tylko chcesz przetłumacz $Projectname na inny +język, którego nie potrzebujesz najbardziej, ale da Ci to wyobrażenie o procesie +tłumaczenia $Projectname. + +Więcej informacji można znaleźć w pliku utils/README. + +Znane problemy +-------------- + +* $Projectname używa ustawień języka przeglądarki odwiedzających, aby określić + język interfejsu użytkownika. W większości przypadków to działa, ale są pewne + znane dziwactwa. +* wczesne tłumaczenia są oparte na przekładach Friendica, jeśli znajdziesz jakieś + błędy, daj nam znać lub popraw je w Transifex. + +Linki +------ +[1]: http://www.transifex.com/projects/p/hubzilla/ + + +#include doc/pl/macros/main_footer.bb; diff --git a/doc/pl/about/about.bb b/doc/pl/about/about.bb new file mode 100644 index 000000000..73d710cbc --- /dev/null +++ b/doc/pl/about/about.bb @@ -0,0 +1,181 @@ +[h3]Co to jest $Projectname?[/h3] +$Projectname to bezpłatny i otwartoźródłowy zestaw aplikacji i usług internetowych działających na specjalnym serwerze internetowym, zwanym "hubem", który może łączyć się z innymi hubami w sfederalizowanej sieci internetowej. +$Projectname zapewnia użytkownikom zaawansowaną komunikację, tożsamości i usług kontroli dostępu, które bezproblemowo współpracują w różnych domenach i niezależnych witrynach internetowych. Pozwala użytkownikom [b]publicznie[/b] lub [b]prywatnie[/b] publikować treści za pośrednictwem "kanałów" (ang. channel), które są podstawowymi, zabezpieczonymi kryptograficznie tożsamościami zapewniającymi uwierzytelnianie niezależnie od hubów, które je hostują. To rewolucyjne wyzwolenie tożsamości online z poszczególnych serwerów i domen jest nazywane "tożsamością nomadyczną" i jest oparte na protokole Zot, nowej strukturze zdecentralizowanej kontroli dostępu ze szczegółowymi, rozszerzalnymi uprawnieniami. +Z praktycznego punktu widzenia członków danego huba, korzystających z oprogramowania $Projectname, oferuje ono szereg znanych, zintegrowanych aplikacji i usług internetowych, w tym: +[ul] +[li]wątki dyskusyjne w sieciach społecznościowych[/li] +[li]przechowywanie plików w chmurze[/li] +[li]kalendarz i kontakty (z obsługą CalDAV i CardDAV)[/li] +[li]hosting stron internetowych z systemem zarządzania treścią[/li] +[li]wiki[/li] +[li]i dużo więcej ...[/li][/ul] +Chociaż wszystkie te aplikacje i usługi można znaleźć w innych pakietach oprogramowania, tylko $Projectname pozwala ustawić uprawnienia dla grup i osób, [b]które mogą nawet nie mieć kont na Twoim hubie[/b]! W typowych aplikacjach internetowych, jeśli chcesz udostępniać rzeczy prywatnie w Internecie, osoby, którym udostępniasz dane, muszą mieć konta na serwerze, na którym znajdują się Twoje dane; w przeciwnym razie serwer nie może uwierzytelniać odwiedzających witrynę, aby wiedzieć, czy przyznać im dostęp. $Projectname rozwiązuje ten problem za pomocą zaawansowanego systemu zdalnego uwierzytelniania, który weryfikuje tożsamość odwiedzających, wykorzystując techniki obejmujące kryptografię klucza publicznego. +Dzięki oferowanym aplikacjom, $Projectname świetnie się nadaje do budowy platformy komunikacyjno-publikacyjnej o charkterze społecznościowym dla realnych grup społecznych, takich jak rodziny, lokalne grupy, organizacje społeczne, środowiska szkolne, wspólnoty mieszkańców czy wspólnoty religijne. + +[h3]Stos programów[/h3] +Pakiet oprogramowania $Projectname jest stosunkowo standardową aplikacją serwerową napisaną głównie w PHP i MySQL i [url=https://framagit.org/$Projectname/core/blob/master/install/INSTALL.txt]wymagającą niewiele więcej niż serwera WWW, bazy danych zgodnej z MySQL i języka skryptowego PHP[/url]. System został zaprojektowany tak, aby był łatwy do zainstalowania przez osoby z podstawowymi umiejętnościami administrowania witryną, na typowych platformach współdzielonego hostingu, z uwzglednieniem szerokiej gamy sprzętu komputerowego. Można go również łatwo rozszerzyć za pomocą wtyczek i motywów oraz innych narzędzi innych firm. + +[h3]Słownik[/h3] +[dl terms="b"] +[*= hub ([i]ang. hub[/i])] Instancja tego oprogramowania działająca na standardowym serwerze WWW + +[*= siatka, grid ([i]w oryginale ang., grid[/i])] Globalna sieć hubów, które wymieniają między sobą informacje za pomocą protokołu Zot. Nie są to tylko huby oparte na $Projectname, ale wszystkie hubyy implementujace protokół Zot. + +[*= kanał ([i]ang. channel[/i])] Techniczny odpowiednik tożsamości. Kanał może reprezentować osobę, blog lub forum, żeby wymienić tylko kilka. Kanały mogą łączyć się z innymi kanałami w celu udostępniania informacji z bardzo szczegółowymi uprawnieniami. + +[*= klon ([i]ang. clone[/i])] Kanały mogą mieć klony powiązane z oddzielnymi i niepowiązanymi kontami w niezależnych hubach. Komunikacja współdzielona z kanałem jest synchronizowana między klonami kanału, co umożliwia kanałowi wysyłanie i odbieranie wiadomości oraz dostęp do współdzielonych treści z wielu hubów. Zapewnia to odporność na awarie sieci i sprzętu, które mogą stanowić poważny problem w przypadku serwerów WWW z własnym hostingiem lub o ograniczonych zasobach. Klonowanie umożliwia całkowite przeniesienie kanału z jednego huba do drugiego, zabierając ze sobą dane i połączenia. Zobacz "tożsamość nomadyczna". + +[*= tożsamość nomadyczna ([i]ang. nomadic identity[/i])] Możliwość uwierzytelniania i łatwej migracji tożsamości w niezależnych hubach i domenach internetowych. Tożsamość nomadyczna zapewnia prawdziwą własność tożsamości online, ponieważ tożsamości kanałów kontrolowanych przez konto w hubie nie są powiązane z samym hubem. hub bardziej przypomina "hosta" kanałów. W serwisie $Projectname nie masz "konta" na serwerze, tak jak na typowych serwisach internetowych - posiadasz tożsamość, którą możesz przenosić ze sobą po całej siatce za pomocą klonów. + +[*= [url=[baseurl]/help/developer/zot_protocol]Protokół Zot[/url]] Nowy protokół, oparty na JSON, do wdrażania bezpiecznej, zdecentralizowanej komunikacji i usług. Różni się od wielu innych protokołów komunikacyjnych, budując komunikację na podstawie zdecentralizowanej struktury tożsamości i uwierzytelniania. Składnik uwierzytelniania jest koncepcyjnie podobny do OpenID, ale jest odizolowany od tożsamości opartej na DNS. Tam, gdzie to możliwe, zdalne uwierzytelnianie jest ciche i niewidoczne. Zapewnia to mechanizm kontroli dostępu rozproszonego na skalę sieci WWW, który jest dyskretny. +[/dl] + +[h3]Możliwości[/h3] +Ten rozdział zawiera listę niektórych podstawowych funkcjonalności platformy $Projectname, które są dołączone do oficjalnej wersji. $Projectname to platforma o dużych możliwościach rozbudowy, więc więcej funkcji i możliwości można dodać za pomocą dodatkowych motywów i wtyczek. + +[h4]Suwak zaprzyjaźnienia (Affinity Slider)[/h4] +Dodając połączenia w serwisie $Projectname, członkowie mają możliwość przypisania poziomów "zaprzyjażnienia" ([i]ang. affinity[/i]), czyli określenia, jak bliska jest twoja przyjaźń z osobą reprezentowaną przez nowe połączenia. Na przykład, dodając osobę, której blog obserwujesz, możesz przypisać jej kanałowi poziom zaprzyjaźnienia "Znajomi". + +Z drugiej strony, dodając kanał przyjaciela, możesz go umieścić na poziomie zaprzyjaźnienia "Przyjaciele". + +Gdy to zrobisz, narzędzie "Suwak zaprzyjaźnienia", które zwykle pojawia się u góry głównej strony kanału (matrycy), dostosowuje zawartość strony tak, aby zawierała elementy z żądanego zakresu zaprzyjaźnienia. Kanały spoza tego zakresu nie będą wyświetlane, chyba że dostosujesz suwak, aby to uwzględnić. + +Suwak zaprzyjażnienia umożliwia natychmiastowe filtrowanie dużych ilości treści, pogrupowanych według poziomów zaprzyjaźnienia. + +[h4]Filtrowanie połączeń (Connection Filtering)[/h4] +Masz możliwość precyzyjnego kontrolowania tego, co pojawia się w Twoim strumieniu za pomocą opcjonalnego "Filtra połączeń" ([i]ang. Connection Filter[/i]). Po włączeniu Edytor połączeń zapewnia dane wejściowe do wybierania kryteriów, które należy dopasować, aby uwzględnić lub wykluczyć określony post z określonego kanału. Gdy post został dopuszczony, wszystkie komentarze do tego posta są dozwolone, niezależnie od tego, czy spełniają kryteria wyboru. Możesz wybrać słowa, które jeśli są obecne, blokują post lub zapewniają, że zostanie uwzględniony w Twoim strumieniu. Wyrażenia regularne mogą być używane do jeszcze dokładniejszej kontroli, a także hasztagów, a nawet wykrytego języka postu. + +[h4]Listy kontrolne dostępu (Access Control Lists - ACL)[/h4] +Udostępniając zawartość, członkowie mają możliwość ograniczenia tego, kto widzi zawartość. Klikając na kłódkę pod polem udostępniania, można wybrać odbiorców postu, klikając ich nazwy. + +Po wysłaniu, wiadomość będzie widoczna tylko dla nadawcy i wybranych odbiorców. Innymi słowami, wiadomość nie pojawi się na jakichkolwiek publicznych ścianach. + +Listy kontroli dostępu mogą być stosowane do treści i postów, zdjęć, wydarzeń, stron internetowych, pokojów rozmów i plików. + +[h4]Jednokrotne uwierzytelnianie (Single Sign-on)[/h4] +Listy kontroli dostępu działają dla wszystkich kanałów w siatce dzięki naszej unikalnej technologii pojedynczego logowania. Większość linków wewnętrznych zapewnia token tożsamości, który można zweryfikować w innych witrynach $Projectname i wykorzystać do kontrolowania dostępu do prywatnych zasobów. Logujesz się raz do swojego centrum domowego. Następnie uwierzytelnianie we wszystkich zasobach serwisu $Projectname jest "magiczne". + +[h4]Magazyn plików z obsługą WebDAV[/h4] +Pliki można przesyłać do osobistego obszaru przechowywania za pomocą narzędzi systemu operacyjnego (w większości przypadków metodą przeciągnij i upuść). Możesz chronić te pliki za pomocą list kontroli dostępu dla dowolnej kombinacji członków Hubzilli (w tym niektórych członków sieci stron trzecich) lub upublicznić je. + +[h4]Albumy fotograficzne[/h4] +Przechowuj zdjęcia w albumach. Wszystkie Twoje zdjęcia mogą być chronione listami kontroli dostępu. + +[h4]Kalendarze zdarzeń[/h4] +Twórz zdarzenia i zadania oraz zarządzaj nimi, które mogą być również chronione za pomocą list kontroli dostępu. Wydarzenia można importować i eksportować do innego oprogramowania przy użyciu standardowego formatu vcalendar lub iCal i udostępniać w postach innym osobom. Wydarzenia urodzinowe są automatycznie dodawane od znajomych i konwertowane na właściwą strefę czasową, dzięki czemu będziesz dokładnie wiedzieć, kiedy mają miejsce urodziny - bez względu na to, gdzie się znajdujesz na świecie w stosunku do osoby urodzonej w dniu urodzin. Wydarzenia są zwykle tworzone za pomocą liczników obecności, dzięki czemu Twoi znajomi i kontakty mogą natychmiast [url=https://pl.wikipedia.org/wiki/RSVP_(skr%C3%B3towiec]RSVP[/url]. + +[h4]Czaty[/h4] +Możesz utworzyć dowolną liczbę osobistych czatów i zezwolić na dostęp za pośrednictwem list kontroli dostępu. Są one zazwyczaj bezpieczniejsze niż XMPP, IRC i inne rodzaje przesyłania wiadomości błyskawicznych, chociaż zezwalamy również na korzystanie z tych innych usług za pośrednictwem wtyczek. + +[h4]Tworzenie stron internetowych[/h4] +$Projectname ma wiele narzędzi do tworzenia stron internetowych systemu CMS, w tym do edycji układu, menu, bloków, widżetów i regionów strony i treści. Dostęp do wszystkich tych elementów można kontrolować, tak aby powstałe strony były prywatne dla zamierzonych odbiorców. + +[h4]Aplikacje[/h4] +Aplikacje mogą być tworzone i rozpowszechniane przez członków. Różnią się one od tradycyjnych aplikacji typu "vendor lockin", ponieważ są całkowicie kontrolowane przez autora - który może zapewnić kontrolę dostępu do stron aplikacji docelowej i odpowiednio pobierać opłaty za ten dostęp. Większość aplikacji w Hubzilli jest bezpłatna i mogą być łatwo tworzone przez osoby bez umiejętności programowania. + +[h4]Układ stron (Layout)[/h4] +Układ strony jest oparty na języku opisu o nazwie Comanche. $Projectname sama jest napisana w układach Comanche, które możesz zmieniać. Pozwala to na poziom dostosowania, którego zwykle nie znajdziesz w tak zwanych "środowiskach wielu użytkowników". + +[h4]Zakładki (Bookmarks)[/h4] +Udostępniaj i zapisuj albo zarządzaj zakładkami z linków podanych na czacie. + +[h4]Szyfrowanie wiadomości prywatnych i kwestie prywatności[/h4] +Prywatna poczta jest przechowywana w ukrytym formacie. Chociaż nie jest to "kuloodporne", zwykle zapobiega przypadkowemu podsłuchiwaniu przez administratora witryny lub usługodawcę internetowego. + +Każdy kanał serwisu $Projectname ma swój własny unikalny zestaw prywatnych i powiązanych publicznych kluczy RSA 4096-bitowych, generowanych podczas pierwszego tworzenia kanałów. Służy do ochrony przesyłanych prywatnych wiadomości i postów. + +Ponadto wiadomości mogą być tworzone przy użyciu "szyfrowania end-to-end", którego nie mogą odczytać operatorzy serwisów $Projectname, dostawcy usług internetowych ani nikt, kto nie zna hasła. + +Wiadomości publiczne na ogół nie są szyfrowane podczas przesyłania ani przechowywania. + +Prywatne wiadomości mogą zostać wycofane po wysłaniu, chociaż nie ma gwarancji, że odbiorca ich jeszcze nie przeczytał. + +Posty i wiadomości mogą być tworzone z datą wygaśnięcia, po którym zostaną usunięte lub usunięte ze strony odbiorcy. + +[h4]Federalizacja usług (Service Federation)[/h4] +Oprócz dodatkowych "łączników cross-post" do różnych alternatywnych sieci, istnieje natywna obsługa importu treści z kanałów RSS i Atom i wykorzystywania jej do tworzenia specjalnych kanałów. Dostępne są również wtyczki do komunikacji z innymi sieciami za pomocą protokołów Diaspora i GNU-Social (OStatus). Sieci te nie obsługują tożsamości nomadycznej ani kontroli dostępu między domenami. Jednak podstawowa komunikacja jest obsługiwana: do i z Diaspora, Friendica, GNU-Social, Mastodon i innych dostawców, którzy używają tych protokołów. + +Istnieje również eksperymentalna obsługa uwierzytelniania OpenID, której można używać na listach kontroli dostępu. To jest jeszcze w trakcie tworzenia, ale poeksperymentować można. Twój hub $Projectname może być używany jako dostawca OpenID do uwierzytelniania członków w zewnętrznych usługach korzystających z tej technologii. + +Kanały mogą mieć uprawnienia, aby stać się "kanałami pochodnymi", w przypadku gdy dwa lub więcej istniejących kanałów łączy się, tworząc nowy kanał tematyczny. + +[h4]Grupy prywatności (Privacy Group)[/h4] +Nasza implementacja grup prywatności jest podobna do "kręgów" w Google i "aspektów" w Diasporze. Pozwala to na filtrowanie przychodzącego strumienia według wybranych grup i automatyczne ustawianie wychodzącej listy kontroli dostępu tylko na te z tej grupy prywatności podczas publikowania. Możesz to zmienić w dowolnym momencie (przed wysłaniem postu). + + +[h4]Usługi katalogowe (Directory Services)[/h4] +Zapewniamy łatwy dostęp do katalogu członków i udostępniamy zdecentralizowane narzędzia, które mogą dostarczać "sugestie" znajomych. Katalogi to zwykłe serwisy $Projectname, które zdecydowały się zaakceptować rolę serwera katalogowego. Wymaga to więcej zasobów niż większość typowych serwisów, więc nie jest to ustawienie domyślne. Katalogi są synchronizowane i dublowane, dzięki czemu wszystkie zawierają aktualne informacje o całej sieci (z zastrzeżeniem normalnych opóźnień propagacji). + +[h4]TLS/SSL[/h4] +W przypadku hubów $Projectname, które używają TLS/SSL, komunikacja między klientem a serwerem jest szyfrowana za pomocą protokołu TLS/SSL. Biorąc pod uwagę niedawno ujawnione w mediach fakty dotyczące powszechnego, globalnego nadzoru i obchodzenia szyfrowania przez NSA i GCHQ, uzasadnione jest założenie, że komunikacja chroniona przez HTTPS może być zagrożona na różne sposoby. W konsekwencji prywatna komunikacja jest szyfrowana na wyższym poziomie przed wysłaniem na zewnątrz. + +[h4]Konfiguracja kanałów[/h4] +Podczas tworzenia kanału wybierana jest rola, która stosuje szereg wstępnie skonfigurowanych ustawień zabezpieczeń i prywatności. Są one wybierane z uwzględnieniem najlepszych praktyk, aby zachować prywatność na żądanym poziomie. + +W przypadku wybrania "własnej" roli prywatności każdy kanał umożliwia precyzyjne ustawienie uprawnień dla różnych aspektów komunikacji. Na przykład, pod nagłówkiem "Ustawienia bezpieczeństwa i prywatności", każdy aspekt w lewej części strony ma sześć (6) możliwych opcji przeglądania i dostępu, które można wybrać, klikając menu rozwijane. Istnieje również wiele innych ustawień prywatności, które możesz edytować. Dostępne opcje: + + - Nikt oprócz ciebie. + - Tylko ci, którym wyraźnie zezwalasz. + - Ktoś w twojej książce adresowej. + - Każdy na tej stronie. + - Każdy w tej sieci. + - Każdy jest uwierzytelniony. + - Każdy w internecie. + + +[h4]Prywatne i publiczne fora[/h4] +Fora to zazwyczaj kanały, w których może uczestniczyć wielu autorów. Obecnie istnieją dwa mechanizmy publikowania postów na forach: + + - posty "wall-to-wall" i + - mechanizm tagów forowych @mention. + +Fora mogą być tworzone przez każdego i używane w dowolnym celu. Katalog zawiera opcję wyszukiwania forów publicznych. Fora prywatne mogą być publikowane tylko dla członków i często tylko przez nich widoczne. + +[h4]Klonowanie kont[/h4] +Konta platformy $Projectname nazywane są *tożsamościami nomadycznymi*, ponieważ tożsamość członka nie jest powiązana z hubem, w którym tożsamość została pierwotnie utworzona. Na przykład, kiedy tworzysz konto na Facebooku lub Gmailu, jest ono powiązane z tymi usługami - mie może działać poza Facebook.com czy Gmail.com. + +Z drugiej strony załóżmy, że utworzyłeś tożsamość $Projectname o nazwie [code]tina@$Projectnamehub.com[/code]. Możesz sklonować ją do innego huba $Projectname, wybierając tę ​​samą lub inną nazwę, np. [code]liveForever@Some$ProjectnameHub.info[/code]. + +Oba kanały są teraz zsynchronizowane, co oznacza, że ​​wszystkie Twoje kontakty i preferencje zostaną zduplikowane na klonie. Nie ma znaczenia, czy wyślesz post z pierwotnego centrum, czy z nowego. Posty będą dublowane na obu kontach. + +To dość rewolucyjna funkcja, jeśli weźmiemy pod uwagę kilka scenariuszy: + + - Co się stanie, jeśli hub, w którym oparta jest tożsamość, nagle przestanie działać? Bez sklonowania tożsamości członek tego huba nie będzie mógł się komunikować, dopóki hub nie wróci do trybu online (bez wątpienia wielu z Was widziało i przeklęło "Fail Whale" na Twitterze). Dzięki klonowaniu wystarczy zalogować się na sklonowane konto, a życie toczy się normalnie. + + - Administrator twojego huba nie może już sobie pozwolić na opłacanie swojego bezpłatnego i publicznego huba $Projectname. Zapowiada, że ​​hub zostanie zamknięty za dwa tygodnie. Dzięki temu masz wystarczająco dużo czasu na sklonowanie swojej tożsamośc i zachowanie relacji, znajomych i treści z zamykanego serwisu $Projectname. + + - A jeśli Twoja tożsamość podlega rządowej cenzurze? Twój dostawca huba może zostać zmuszony do usunięcia Twojego konta wraz z wszelkimi tożsamościami i powiązanymi danymi. Dzięki klonowaniu, $Projectname stawia opór cenzurze. Możesz mieć setki klonów, jeśli chcesz, wszystkie nazwane inaczej i istniejące w wielu różnych hubach, rozrzuconych po Internecie. + +$Projectname oferuje interesujące nowe możliwości prywatności. Więcej informacji można znaleźć na stronie "Najlepsze praktyki w komunikacji prywatnej". +Obowiązują pewne zastrzeżenia. Aby uzyskać pełne wyjaśnienie klonowania tożsamości, przeczytaj stronę "JAK SKLONOWAĆ SWOJĄ TOŻSAMOŚĆ". + +[h4]Wiele profili[/h4] +Można utworzyć dowolną liczbę profili zawierających różne informacje, które mogą być widoczne dla niektórych Twoich kontaktów i znajomych. Profil "domyślny" może być widoczny dla każdego i może zawierać ograniczone informacje, a więcej informacji jest dostępnych dla wybranych grup lub osób. Oznacza to, że profil (i zawartość witryny), który widzą Twoi znajomi pijący piwo, może być inny niż to, co widzą Twoi współpracownicy, a także zupełnie inny niż to, co jest widoczne dla ogółu społeczeństwa. + +[h4]Kopia zapasowa konta[/h4] + +$Projectname oferuje prosty sposób wykonywania kopii zapasowej konta za jednym kliknięciem, z której możesz pobrać pełną kopię zapasową swoich profili. Kopie zapasowe można następnie wykorzystać do sklonowania lub przywrócenia profilu. + +[h4]Usuwanie konta[/h4] +Konta można natychmiast usunąć, klikając link. Otóż to. Wszystkie powiązane treści są następnie usuwane z siatki (w tym posty i wszelkie inne treści utworzone przez usunięty profil). W zależności od liczby posiadanych połączeń proces usuwania zdalnej zawartości może zająć trochę czasu, ale zaplanowany jest tak szybko, jak to możliwe. + +[h4]Usuwanie treści[/h4] +Wszelkie treści utworzone w Hubzilli pozostają pod kontrolą członka (lub kanału), który je pierwotnie utworzył. W dowolnym momencie członek może usunąć wiadomość lub zakres wiadomości. Proces usuwania zapewnia, że treść zostanie usunięta, niezależnie od tego, czy została opublikowana w głównym (macierzystym) hubie kanału, czy w innym hubie, gdzie kanał został zdalnie uwierzytelniony za pośrednictwem Zot (protokół komunikacji i uwierzytelniania $Projectname). + +[h4]Media[/h4] +Podobnie jak każdy inny nowoczesny system blogowania, sieć społecznościowa lub usługa mikroblogowania, $Projectname obsługuje przesyłanie plików, osadzanie filmów, łączenie stron internetowych. + +[h4]Podgląd i edycja[/h4] +Posty i komentarze można przeglądać przed wysłaniem i edytować po wysłaniu. + +[h4]Głosowanie i konsensus[/h4] +Posty mogą być przekształcane w elementy "konsensusu", które pozwalają czytelnikom oferować opinie, które są zestawiane w liczniki "zgadzam się", "nie zgadzam się" i "wstrzymuję się". Pozwala to ocenić zainteresowanie pomysłami i tworzyć nieformalne ankiety. + +[h4]Rozszerzaie $Projectname[/h4] + +$Projectname może zostać rozszerzona na wiele sposobów, poprzez dostosowanie witryny, personalizację, ustawienia opcji, motywy i dodatki - wtyczki. + +[h4]API[/h4] + +Interfejs API jest dostępny do użytku przez usługi stron trzecich. Wtyczka zapewnia również podstawową implementację interfejsu API Twittera (dla którego istnieją setki narzędzi innych firm). Dostęp można zapewnić za pomocą loginu i hasła lub protokołu OAuth, a klient może zarejestrować aplikacje OAuth. + diff --git a/doc/pl/about/about_hub.bb b/doc/pl/about/about_hub.bb new file mode 100644 index 000000000..d338a563c --- /dev/null +++ b/doc/pl/about/about_hub.bb @@ -0,0 +1,7 @@ +[h3]Informacja o serwisie[/h3] +[list][*][url=[baseurl]/siteinfo]Informacja o serwisie[/url] +[*][url=[baseurl]/siteinfo/json]Informacja o serwisie (format JSON)[/url][/list] +[h3]Regulamin serwisu[/h3] +[list][*][url=[baseurl]/help/TermsOfService]Warunki świadczenia usług[/url][/list] +#include doc/pl/SiteTOS.md; + diff --git a/doc/pl/about/project.bb b/doc/pl/about/project.bb new file mode 100644 index 000000000..f8c24acd7 --- /dev/null +++ b/doc/pl/about/project.bb @@ -0,0 +1,181 @@ +[h3]Zarządzanie projektem $Projectname[/h3] +Zarządzanie $Projectname odnosi się do zarządzania tym projektem i zwłaszcza jak do rozwiązywania konfliktów w tym projekcie. + +[h4]Zarządzanie społecznością[/h4] +Projekt jest utrzymywany przez społeczność $Projectname i decyzje podejmowane są w ramach tej społeczności. +Struktura zarządzania ciągle ewoluuje. Do czasu zakończenia tworzenia struktura, decyzje są podejmowane w następującej kolejności: + +[ol] +[*] Opóźniony konsensus + +Jeśli propozycja projektu zostanie złożona na jednym z forów zarządzania projektem i nie ma poważnych zastrzeżeń w "rozsądnym" terminie od daty złożenia wniosku (zazwyczaj zapewniamy wszystkim zainteresowanym 2-3 dni na ustosunkowanie się), nie musi być głosowania aby decyzja została podjęta i propozyzja zostanie uznana za zatwierdzoną przez aklamację. Po tym czasie mogą zostać zgłoszone jakieś zastrzeżenie i oabawy, ale jeśli zostaną one uwzględnione podczas dyskusji i przedstawione zostaną rozwiązania, nadal będą uznawane za zatwierdzone. + + +[*] Weto + +Starsi deweloperzy, z długim stażem w projekcie. mogą zawetować każdą decyzję. Decyzja może zostać podjęta dopiero po usunięciu weta lub przedłożeniu alternatywnej propozycji. + + +[*] Głosowanie społeczności + +Decyzja, która nie ma wyraźnego mandatu lub wyraźnego konsensusu, ale nie jest zawetowana, może zostać podjęta po głosowaniu spółeczności. Obecnie jest to zwykłe popularne głosowanie na jednym z odpowiednich forów społeczności. W tej chwili o wyniku decyduje głosowanie powszechne. Może się to zmienić w przyszłości, jeśli społeczność przyjmie model zarządzania "przez radę". Ten dokument zostanie wówczas zaktualizowany o zaktualizowane zasady zarządzania. +[/ol] + +Głosowanie społeczności nie zawsze zapewnia Powszechnie akceptowany wynik i może polaryzować społeczność, wytwarzając frakcje (stąd przyczyna, dla której rozważane są inne modele). Jeśli propozycja została przegłosowana, nadal jest kilka rozwiązań, które można zrobić, aby propozycja została przesłana ponownie z nieco innymi parametrami (przekształcenie na dodatek, przekształcenie na opcjonalną funkcję, która jest domyślnie wyłączona itp.). Jeśli zainteresowanie funkcją jest duże, a głosowanie jest „bliskie”, może to wywołać wiele złych uczuć wśród przegranych wyborców. W przypadku tak bliskich głosów [b] zdecydowanie zaleca się [/ b], aby wnioskodawca podjął kroki w celu rozwiązania wszelkich zgłoszonych wątpliwości i ponownie przedłożył. + +[h4]Polityka prywatności[/h4] + +Q: Kto może widzieć moją treść? + +A: Domyślnie KAŻDY w internecie, chyba że ograniczysz do niej dostęp. $Projectname pozwala wybrać żądany poziom prywatności. Treści podlegające ograniczeniom NIE będą widoczne dla "sieci szpiegowskich" i reklamodawców. Będą chroniona przed podsłuchem przez osoby postronne - najlepiej jak potrafimy. Administratorzy centrów z wystarczającymi umiejętnościami i cierpliwością MOGĄ być w stanie podsłuchiwać niektóre prywatne wiadomości, ale muszą dołożyć starań, aby to zrobić. W $Projectname istnieją tryby prywatności, które są nawet odporne na podsłuchiwanie przez wykwalifikowanych i zdeterminowanych administratorów hubów. + +Q: Czy moje treści mogą zostać ocenzurowane? + +A: Z założenie, $Projectname (jako sieć) NIE MOŻE cenzurować twoich treści. Administratorzy serwerów i hubów podlegają lokalnemu prawodawstwu i MOGĄ usunąć budzące zastrzeżenia treści ze swojego serwisu (huba). Każdy może zostać administratorem huba, w tym Ty. Dlatego publikuj treści, które w innym przypadku mogłyby zostać ocenzurowane. Nadal MOŻESZ podlegać lokalnemu prawodawstwu. + +[h5]Definicje[/h5] + +**$Projectname** + +Inaczej nazywana "siecią", $Projectname jest zbiorem pojedynczych komputerów (serwerów) (czyli **hubów**. ang. *hubs*), które łączą się razem, tworząc większą sieć kooperacyjną. + +**hub** (ang. *hub*) + +Pojedynczy komputer lub serwer podłączony do $Projectname. Jest on dostarczany przez **administratora huba** i może być publiczny lub prywatny, płatnu lub bezpłatny. + +*administrator huba** + +Operator systemu pojedynczego huba. + +[h5]Polityki[/h5] + +**Informacja publiczna** + +Wszelkie informacje lub cokolwiek zamieszczone przez Ciebie w $Projectname MOŻE być publiczne lub widoczne dla każdego w Internecie. W miarę możliwości $Projectname pozwala chronić zawartość i ograniczać, kto może ją oglądać. + +Twoje zdjęcie profilowe, nazwa Twojego kanału i lokalizacja (adres URL lub adres sieciowy) Twojego kanału są widoczne dla każdego w internecie, a kontrola prywatności nie wpływa na wyświetlanie tych elementów. + +MOŻESZ dodatkowo podać inne informacje profilowe. Wszelkie informacje, które podajesz w swoim „domyślnym” lub **publicznym profilu** MOGĄ zostać przesłane do innych hubów w $Projectname i dodatkowo MOGĄ zostać wyświetlone w katalogu kanałów. Możesz ograniczyć wyświetlanie tych informacji profilowych. Może być ograniczone tylko do członków twojego huba lub tylko połączeń (znajomych) lub innych ograniczonych grup widzów, zgodnie z twoim życzeniem. Jeśli chcesz, aby Twój profil był ograniczony, musisz ustawić odpowiednie ustawienia prywatności lub po prostu NIE podawać dodatkowych informacji. + +**Treść** + +Treści, które udostępniasz (posty ze statusami, zdjęcia, pliki itp.) Należą do Ciebie. $Projectname domyślnie publikuje treści w sposób otwarty i widoczny dla każdego w internecie (PUBLICZNY). MOŻESZ kontrolować to w ustawieniach swojego kanału i ograniczyć domyślne uprawnienia lub MOŻESZ ograniczyć widoczność każdego pojedynczego opublikowanego elementu oddzielnie (PRYWATNE). Programiści $Projectname zapewnią, że ograniczone treści będą widoczne TYLKO dla osób z listy ograniczeń - najlepiej jak potrafią. + +Treści (zwłaszcza posty statusowe), które udostępniasz innym sieciom lub które udostępniłeś komukolwiek w Internecie (PUBLICZNE), nie mogą być łatwo cofnięte po ich opublikowaniu. MOGĄ być udostępniane innym sieciom i udostępniane za pośrednictwem kanałów RSS / Atom. Może być również rozpowszechniany na innych stronach $ Projectname. MOŻE pojawiać się w innych sieciach i witrynach internetowych oraz być widoczny w wyszukiwarkach internetowych. Jeśli nie chcesz tego domyślnego zachowania, dostosuj ustawienia swojego kanału i ogranicz listę osób, które mogą oglądać Twoje treści. + +**Komentarze i wpisy na forach** + +Komentarze do postów stworzonych przez innych oraz posty oznaczone jako posty na forum należą do Ciebie jako twórcy (autora), ale ich dystrybucja nie jest pod Twoją bezpośrednią kontrolą i zrzekasz się NIEKTÓRYCH praw do tych elementów. Te posty i komentarze MOGĄ być ponownie rozpowszechniane wśród innych i MOGĄ być widoczne dla każdego w internecie. W przypadku komentarzy, twórca "pierwszej wiadomości" w wątku (rozmowie), na który odpowiadasz, kontroluje dystrybucję wszystkich komentarzy i odpowiedzi na tę wiadomość. Jest on "właścicielem" i dlatego ma określone prawa w odniesieniu do całej rozmowy (w tym wszystkich zawartych w niej komentarzy). Nadal możesz edytować lub usuwać komentarz, ale właściciel konwersacji ma również prawa do edytowania, usuwania, ponownej dystrybucji i tworzenia kopii zapasowych i przywracania dowolnej lub całej zawartości konwersacji. + +**Informacja prywatna** + +Programiści $Projectname zapewnią, że każda dostarczona przez Ciebie zawartość oznaczona jako PRYWATNA będzie chroniona przed podsłuchem - najlepiej jak potrafią. Zawartość kanału prywatnego MOŻE być widoczna w bazie danych każdego zaangażowanego administratora centrum, ale prywatne wiadomości są ukrywane w bazie danych. To ostatnie oznacza, że jest to bardzo trudne, ale NIE niemożliwe, aby te treści były widoczne dla administratora centrum. Treść kanału prywatnego i wiadomości prywatne są również usuwane z powiadomień e-mail. Pełne szyfrowanie jest oferowane jako funkcja opcjonalna i NIE MOŻE być widoczne, nawet dla zdeterminowanego administratora. + +[h5]Prywatność tożsamości[/h5] + +Prywatność dla Twojej tożsamości to kolejny aspekt. Ponieważ masz zdecentralizowaną tożsamość w $Projectname, Twoja prywatność wykracza poza domowy hub. Jeśli chcesz mieć pełną kontrolę nad swoją prywatnością i bezpieczeństwem, powinieneś uruchomić własny hub na dedykowanym serwerze. Dla wielu osób jest to skomplikowane ale może poszerzyć ich możliwości techniczne. Wymieńmy więc kilka środków ostrożności, które możesz podjąć, aby zapewnić sobie jak największą prywatność. + +Zdecentralizowana tożsamość ma wiele zalet i daje wiele interesujących funkcji, ale powinieneś być świadomy faktu, że Twoja tożsamość jest znana innym hubom w sieci $Projectname. Jedną z tych zalet jest to, że inne kanały mogą udostępniać dostosowane treści i umożliwiać oglądanie prywatnych rzeczy (takich jak prywatne zdjęcia, które inni chcą Ci udostępnić). Z tego powodu te kanały muszą wiedzieć, kim jesteś. Ale rozumiemy, że czasami te inne kanały wiedzą od Ciebie więcej, niż byś sobie tego życzył. Na przykład wtyczka Visage, która może poinformować właściciela kanału o ostatniej wizycie w jego profilu. Możesz łatwo zrezygnować z tego niskiego poziomu i uważamy, że jest to nieszkodliwe śledzenie. + +* Możesz włączyć [Do Not Track (DNT)](http://donottrack.us/) w swojej przeglądarce internetowej. Szanujemy tą nową propozycję polityki prywatności. Wszystkie nowoczesne przeglądarki obsługują DNT. Znajdziesz to w ustawieniach prywatności swojej przeglądarki lub możesz zapoznać się z instrukcją przeglądarki internetowej. Nie wpłynie to na funkcjonalność $Projectname. To ustawienie jest prawdopodobnie wystarczające dla większości ludzi. + +* Możesz [wyłączyć publikację](ustawienia) swojego kanału w naszym katalogu kanałów. Jeśli chcesz, aby ludzie mogli znaleźć Twój kanał, podaj im adres swojego kanału. Uważamy, że jest to dobra wskazówka, że wolisz dodatkową prywatność i automatycznie włączasz opcję "Nie śledź", jeśli tak jest. + +* Możesz mieć zablokowany hub. Oznacza to, że wszystkie kanały i treści w tym centrum nie są publiczne ani widoczne dla świata zewnętrznego. To jest coś, co może zrobić tylko administrator centrum. Szanujemy to również i automatycznie włączamy opcję "Nie śledź:, jeśli jest ustawiona. + +[h5]Cenzura[/h5] + +$Projectname to globalna sieć obejmująca wszystkie religie i kultury. Nie oznacza to, że każdy członek sieci czuje się tak samo jak Ty w spornych kwestiach, a niektórzy ludzie mogą MOCNO sprzeciwić się publikowanym przez Ciebie treściom. Ogólnie rzecz biorąc, jeśli chcesz opublikować coś, o czym wiesz, że nie jest powszechnie akceptowane, najlepszym rozwiązaniem jest ograniczenie odbiorców za pomocą kontroli prywatności do małego kręgu znajomych. + +$Projectname jako dostawca sieci nie może cenzurować zawartości. Jednak administratorzy hubów MOGĄ cenzurować wszelkie treści, które pojawiają się w ich hubie, aby zachować zgodność z lokalnym prawem, a nawet osobistym osądem. Ich decyzja jest ostateczna. Jeśli masz problemy z jakimkolwiek administratorem huba, możesz przenieść swoje konto i wpisy do innej witryny, która jest bardziej zgodna z Twoimi oczekiwaniami. Sprawdzaj (okresowo) [Warunki świadczenia usług](help/TermsOfService) swojego huba, aby poznać wszelkie zasady lub wytyczne. Jeśli Twoje treści składają się z materiałów, które są nielegalne lub mogą powodować problemy, MOCNO zachęcamy do hostowania własnych (zostań administratorem własnego huba). Mimo to. możesz stwierdzić, że Twoje treści są zablokowane w niektórych hubach, ale $Projectname jako sieć nie może wogóle zablokować ich publikowania. + +$Projectname ZALECA, aby administratorzy hubów zapewnili okres karencji wynoszący 1-2 dni między ostrzeżeniem właściciela konta o treści, którą należy usunąć, a fizycznym usunięciem lub wyłączeniem konta. Dzięki temu właściciel treści będzie mógł wyeksportować metadane swojego kanału i zaimportować je do innej witryny. W rzadkich przypadkach treść może mieć taki charakter, że uzasadnia natychmiastowe zamknięcie konta. To jest decyzja właściciela huba, a nie decyzja $Projectname. + +Jeśli zazwyczaj i regularnie publikujesz treści dla dorosłych lub obraźliwe, MOCNO zachęcamy do oznaczenia swojego konta jako „NSFW” (Not Safe For Work). Zapobiegnie to wyświetlaniu Twojego zdjęcia profilowego w katalogu, z wyjątkiem przeglądających, którzy zdecydowali się wyłączyć „tryb bezpieczny”. Jeśli administratorzy katalogu uznają Twoje zdjęcie profilowe za nieobyczajne lub obraźliwe, administrator katalogu MOŻE oznaczyć Twoje zdjęcie profilowe jako NSFW. Obecnie nie ma oficjalnego mechanizmu do zakwestionowania lub cofnięcia tej decyzji, dlatego NALEŻY oznaczyć własne konto jako NSFW, jeśli może być nieodpowiednie dla ogółu odbiorców. + +[h3]Podziękowania[/h3] + +Dziękujemy wszystkim, którzy przez lata pomagali i przyczynili się do powstania projektu i jego poprzednikom. Możliwe, że przegapiliśmy Twoje imię, ale jest to niezamierzone. Dziękujemy również społeczności i jej członkom za dostarczenie cennego wkładu, bez którego cały ten wysiłek byłby bez znaczenia. + +Warto również docenić wkład i rozwiązania problemów, które powstały w wyniku dyskusji między członkami i twórcami innych, nieco powiązanych i konkurujących ze sobą projektów; +nawet jeśli mieliśmy sporadyczne nieporozumienia. + +[list] +[li]Mike Macgirvin[/li] +[li]Fabio Comuni[/li] +[li]Simon L'nu[/li] +[li]marijus[/li] +[li]Tobias Diekershoff[/li] +[li]fabrixxm[/li] +[li]tommy tomson[/li] +[li]Simon[/li] +[li]zottel[/li] +[li]Christian Vogeley[/li] +[li]jeroenpraat[/li] +[li]Michael Vogel[/li] +[li]erik[/li] +[li]Zach Prezkuta[/li] +[li]Paolo T[/li] +[li]Michael Meer[/li] +[li]Michael[/li] +[li]Abinoam P. Marques Jr[/li] +[li]Tobias Hößl[/li] +[li]Alexander Kampmann[/li] +[li]Olaf Conradi[/li] +[li]Paolo Tacconi[/li] +[li]tobiasd[/li] +[li]Devlon Duthie[/li] +[li]Zvi ben Yaakov (a.k.a rdc)[/li] +[li]Alexandre Hannud Abdo[/li] +[li]Olivier Migeot[/li] +[li]Chris Case[/li] +[li]Klaus Weidenbach[/li] +[li]Michael Johnston[/li] +[li]olivierm[/li] +[li]Vasudev Kamath[/li] +[li]pixelroot[/li] +[li]Max Weller[/li] +[li]duthied[/li] +[li]Martin Schmitt[/li] +[li]Sebastian Egbers[/li] +[li]Erkan Yilmaz[/li] +[li]sasiflo[/li] +[li]Stefan Parviainen[/li] +[li]Haakon Meland Eriksen[/li] +[li]Oliver Hartmann (23n)[/li] +[li]Erik Lundin[/li] +[li]habeascodice[/li] +[li]sirius[/li] +[li]Charles[/li] +[li]Tony Baldwin[/li] +[li]Hauke Zuehl[/li] +[li]Keith Fernie[/li] +[li]Anne Walk[/li] +[li]toclimb[/li] +[li]Daniel Frank[/li] +[li]Matthew Exon[/li] +[li]Michal Supler[/li] +[li]Tobias Luther[/li] +[li]U-SOUND\mike[/li] +[li]mrjive[/li] +[li]nostupidzone[/li] +[li]tonnerkiller[/li] +[li]Antoine G[/li] +[li]Christian Drechsler[/li] +[li]Ludovic Grossard[/li] +[li]RedmatrixCanada[/li] +[li]Stanislav Lechev [0xAF][/li] +[li]aweiher[/li] +[li]bufalo1973[/li] +[li]dsp1986[/li] +[li]felixgilles[/li] +[li]ike[/li] +[li]maase2[/li] +[li]mycocham[/li] +[li]ndurchx[/li] +[li]pafcu[/li] +[li]Simó Albert i Beltran[/li] +[li]Manuel Reva[/li] +[li]Manuel Jiménez Friaza[/li] +[li]Gustav Wall aka "neue medienordnung plus"[/li] +[/list] diff --git a/doc/pl/accounts_profiles_channels_basics.bb b/doc/pl/accounts_profiles_channels_basics.bb new file mode 100644 index 000000000..57d45dfdf --- /dev/null +++ b/doc/pl/accounts_profiles_channels_basics.bb @@ -0,0 +1,20 @@ +[size=large][b]Konta, profile i kanały[/b][/size] + +Po zarejestrowaniu [i]konta[/i], trzeba również utworzyć [i]profil[/i] i [i]kanał[/i]. + +[b]Konto[/b] +W serwisie &Projectname masz [i]jedno[/i] konto. Składa się z Twojego konta e-mail i hasła. Za pomocą swojego konta uzyskujesz dostęp do swojego profilu i kanału. + +[i]Pomyśl o swoim koncie jak o sposobie uwierzytelniania w jednym serwisie $Projectname. Pozwala to na takie rzeczy, jak tworzenie profili i kanałów, za pomocą których możesz łączyć się z innymi osobami.[/i] + +[b]Profil[/b] +Z pewnością masz już doświadczenie w rejestrowaniu się w jakichś usługach internetowych, takich jak fora lub społeczności internetowe. We wszystkich przypadkach trzeba było podać pewne informacje o sobie, takie jak data urodzenia, kraj, wiek i upodobania. [observer=1]Jeśli chcesz, możesz zobaczyć swój profil tutaj: [baseurl]/profile/[observer.webname] i edytować go, klikając ikonę ołówka obok swojego awatara.[/observer] +W przeciwieństwie do innych usług, $Projectname oferuje Ci możliwość tworzenia [i]wielu profilii[/i]. W ten sposób możesz rozróżnić profile skierowane specjalnie do wszystkich (Twój profil publiczny), współpracowników, rodziny czy partnera. +[i]Potraktuj swój profil jako podstawowe informacje o sobie, które przekazujesz innym osobom.[/i] + +[b]Kanał[/b] +Podczas rejestracji tworzysz swój pierwszy [i]kanał[/i]. Podobnie jak w przypadku profili, możesz mieć kilka kanałów. Na początku może to być nieco zagmatwane, ale wyjaśnijmy to. Masz już jeden kanał. Możesz używać go dla publicznie, aby komunikować się z ludźmi w codziennym życiu. Ale być może jesteś zapalonym czytelnikiem książek i wielu ludzi się tym nudzi. Otwierasz więc [i]drugi kanał[/i] tylko dla miłośników książek, na którym wszyscy mogą rozmawiać o książkach tyle, ile chcesz. Oczywiście jest to nowy strumień postów, z nowym profilem (... lub nowymi profilami ...) i zupełnie innymi kontaktami. Niektóre połączenia mogą istnieć w obu kanałach, ale będą takie, które dotyczą tylko jednego z nich. Ty sam po prostu przełączasz się między nimi, tak jak w prawdziwym życiu, kiedy rozmawiasz z ludźmi, których spotykasz na ulicy lub z osobami, które spotykasz specjalnie, aby porozmawiać o książkach. Możesz nawet połączyć się ze sobą lub lepiej: z innym kanałem. :) +[i]Pomyśl o kanale jako o różnych przestrzeniach poświęconych różnym tematom, w których spotykasz się z różnymi ludźmi.[/i] + +#include doc/macros/pl/main_footer.bb; + diff --git a/doc/pl/acl_dialog_post.html b/doc/pl/acl_dialog_post.html new file mode 100644 index 000000000..1be9f4bc6 --- /dev/null +++ b/doc/pl/acl_dialog_post.html @@ -0,0 +1,42 @@ + + +

      Uprawnienia dla wpisu

      + +

      +Okno dialogowe uprawnień pozwala wybrać, które kanały albo grupy prywatności +mogą widzieć wpis. Można też wybrać, komu wyraźnie odmawia się dostępu. Załóżmy +na przykład, że planujesz niespodziewane przyjęcie dla znajomego. Możesz wysłać +zaproszenie do wszystkich w swojej grupie Znajomi oprócz znajomego, +któremu chcesz zrobić niespodziankę. W tym przypadku ustawiasz "Pokaż" grupie +Znajomi, ale ""Nie pokazuj" tej jednej osobie. +

      + +
      +
      Wskazówka! +
      +Kolor obramowania każdego kanału wskazuje, czy ten kanał — lub jedną z grup, +do której należy — będzie mieć dostęp do wpisu. Kolor obramowania będzie +również wskazywać, kiedy kanał lub grupa, do której należy, została wyraźnie +ustawiona na "Nie pokazuj". +
      +
      + +

      Dlaczego nie mogę edytować uprawnień do wpisu po jego zapisaniu?

      + +

      +Możesz zmienić uprawnienia do swoich plików, zdjęć i polubień, ale nie do wpisów +po ich zapisaniu. Główny powód jest taki, że po zapisaniu wpisu jest on rozpowszechniany +na kanale publicznym, a stamtąd na inne serwery Hubzilla lub tym, którym chciałeś +go pokazać. Tak jak nie możesz odzyskać czegoś, co przekazałeś innej osobie, nie +możesz zmienić uprawnień do wpisów Hubzilli. Musielibyśmy śledzić wszędzie, gdzie +trafia Twój wpis, śledzić wszystkich, którym pozwoliłeś go zobaczyć, a następnie +śledzić, od kogo go usunąć. +

      +

      +Jeśli wpis jest publiczny, jest to jeszcze trudniejsze, ponieważ Hubzilla jest siecią +globalną i nie ma możliwości śledzenia wpisu, nie mówiąc już o jego niezawodnym +odzyskaniu. Inne sieci, które mogą otrzymać Twój wpis, nie mają niezawodnego sposobu +na usunięcie lub odzyskanie wpisu. +

      diff --git a/doc/pl/addons.bb b/doc/pl/addons.bb new file mode 100644 index 000000000..6a9cf425b --- /dev/null +++ b/doc/pl/addons.bb @@ -0,0 +1,117 @@ +[h3]Wtyczki/Dodatki[/h3] +[list=1] +[*] abcjsplugin - tworzenie zapisów nitowych w swoich wpisach +[*] adultphotoflag - zapobiega wyświetlaniu zdjęć NSFW w albumach publicznych +[*] authchoose - wysyłanie potwierdzenia tożsamości tylko do witryn znajomych +[*] b2tbtn - zapewnia przycisk powodujący przejście bezpośrednio na górę strony, jeśli przewinie się dużo treści dół okna +[*] bbmath - możliwość używania skomplikowanych wyrażeń matematycznych w swoich wpisach +[*] bookmarker - zamienianie #^ w linkach zakładek we wpisach +[*] buglink - umieszcza ikonę zgłaszania błędów w lewym dolnym rogu każdej strony +[*] calc - kalkulator naukowy +[*] chess - interaktywne gry w szachy z uwzględnieniem tożsamości międzydomenowej +[*] chords - generowanie wykresów palcowania i alternatyw dla każdego znanego akordu gitarowego +[*] custom_home - ustawianie własnej strony jako strony początkowej huba +[*] diaspora - emulator protokołu Diaspora +[*] dirstats - wyświetlanie interesujących statystyk generowanych przez serwer katalogowy +[*] docs - alternatywne strony dokumentacji +[*] donate - dostarcza stronę dofinansowania +[*] dreamhost - zapewnia bardziej niezawodną usługę na hostingu współdzielonym Dreamhost +[*] dwpost - krzyżowe wpisy do Dreamwidth +[*] emojione - zezwala na uzywanie emojis jako emotikonów +[*] extcron - stosowanie zewnętrznej usługi cron do uruchamiania zaplanowanych zadań huba +[*] firefox - dostarcza link do zainstalowania API Sharing Firefoxa +[*] flattrwidget - dostarcza przyciski "Flattr Us" +[*] flip - tworzenie odwróconego tekstu +[*] fortunate - wyświetla losowy cytat (plik cookie fortune). Wymaga skonfigurowania serwera fortune. +[*] friendica - protokół Friendica (DFRN). W tworzeniu. +[*] frphotos - importowanie albumów fotograficznych z Friendica +[*] gnusoc - protokół GNU-Social (OStatus). W tworzeniu. +[*] hexit - narzędzie do konwersji szesnastkowej +[*] hilite - umożliwia podświetlanie bloków kodu, specyficzne dla języka programowania, zawartych we wpisach +[*] hubwall - wysyłanie wiadomosci e-mail administratora na wszystkie konta w hubie +[*] ijpost - krzyżówe wpisy do Insanejournal +[*] irc - połączenie z czatami IRC +[*] jappixmini - czat XMPP +[*] js_upload - przesyłanie jednocześnie wiele zdjęć do albumów fotograficznych +[*] keepout - zapobiega prawie całkowicie korzystaniu z witryny bez zalogowania się, bardziej restrykcyjne niż ustawienie "blokuj publiczne" +[*] ldapauth - logowanie przez konto LDAP lub domenę Windows Active Directory +[*] libertree - publikowanie w Libertree +[*] likebanner - tworzenie obrazu banera "polub nas na red#matrix" +[*] ljpost - publikowanie w LiveJournal +[*] logrot - narzędzie rotowania plik dziennika zdarzeń +[*] mahjongg - gra w chińskie puzzle +[*] mailhost - umożliwienie wyboru jednego kanału dla otrzymywania powiadomień e-mail, gdy używa się wiele sklonowanych kanałów +[*] mailtest - interfejs do testowania systemu wysyłania poczty +[*] metatag - dostarcza strony przyjazne SEO +[*] mayan_places - ustawia pole lokalizacji na losowe miasto w świecie Majów +[*] morechoice - dodatkowe wybór płci i preferencji seksualnych dla profili (nie jest to bezpieczne) +[*] moremoods - dodatkowe opcje nastroju (mood) +[*] morepokes - dodatkowe opcje szturchania (poke) (nie są bezpieczne) +[*] msgfooter - podawanie formuły prawniczej lub innego tekstu w każdym wychodzącym wpisie +[*] noembed - używanie noembed.com jako dodatku do natywnej funkcjonalności oembed w $Projectname (obecnie nie działa) +[*] nofed - zapobiega "federacji" wpisów w kanale, utrzymuje całą interakcję na stronie właściciela kanału +[*] nsabait - dodawaj do swoich wpisów losowe hashtagi związane z terroryzmem +[*] nsfw - bardzo polecana wtyczka do zwijania postów z nieodpowiednimi treściami +[*] openclipatar - wybór zdjęcia profilowego spośród setek obrazów bez tantiem +[*] openid - uwierzytelnianie OpenID i serwer OpenID. Twój adres URL OpenID to [observer.baseurl]/id/[observer.webname] +[*] opensearch - umożliwienie swojej witrynie stania się dostawcą wyszukiwania w przeglądarce +[*] openstreetmap - renderowanie lokalizacji i mapy za pomocą OpenStreetMap +[*] pageheader - wyświetlanie tekstu u góry na każdej stronie serwisu +[*] phpmailer - alternatywny system dostarczania poczty z większą konfigurowalnością +[*] piwik - analityka witryn internetowych typu open source +[*] planets - ustawianie pola lokalizacji na losową planetę z Gwiezdnych Wojen +[*] pong - klasyczna gra w ponga +[*] pubcrawl - emulator protokołu ActivityPub +[*] pubsubhubbub - protokół PuSH dla zoptymalizowanego dostarczania wiadomości do subskrybentów (wymagany przez protokół GNU-Social) +[*] pumpio - publikowanie w Pump.io +[*] qrator - generowanie obrazów kodu QR +[*] rainbowtag - wyświetlanie chmury tagów i kategorii w kolorach +[*] randpost - bot wpis/odpowiedz oparty i wymagający fortunate +[*] redfiles - import magazynu plików z redmatrix +[*] redphotos - import albumów fotograficznych z redmatrix +[*] redred - wpisy krzyzowe do innych kanałów Red Matrix lun Hubzilla +[*] rendezvous - grupowe śledzenie lokalizacji +[*] rtof - publikowanie w Friendica +[*] sendzid - dodawanie parametróe uwierzytelniających "zid" do wszystkich linków wychodzących, nie tylko linków w sieci +[*] skeleton - przykładowa wtyczka pokazująca sposób tworzenia wtyczek +[*] smiley_pack - rozszerzenie wbudowanej obsługi buziek (emotikonów) +[*] smileybutton - zapewnia selektor buźki w oknie wpisu +[*] startpage - umowżliwia ustawienie przekierowania do preferowanej osobistej strony po zalogowaniu +[*] statistics - generator statystyk Diaspora +[*] statusnet - wpisy krzyżówe do GNU-social i StatusNet [zrl=[baseurl]/help/addons_gnusocial]Posting To Gnu Social[/zrl] +[*] std_embeds - umożłiwia niefiltrowane osadzanie dla popularnych dostawców strumieni, takich jak youtube, vimeo i soundcloud +[*] superblock - bardzo zalecane - całkowite blokowanie obraźliwuch kanałów w swoim strumieniu +[*] testdrive - zmienia hub w witrynę testową z kontami, które wygasają po okresie próbnym +[*] tictac - 3D tic-tac-toe +[*] torch - aplikacja podświetlania (flashlight) +[*] tour - prezentacja funkcji dla nowych członków +[*] tripleaes - wtyczka demonstracyjna zapewniająca niestandardowe algorytmy szyfrowania +[*] twitter - publikowanie w Twitter +[*] twitter_api - API kompatybilne z Twitter i Statusnet +[*] upload_limits - odkrywa, jakie ustawienia serwera (jest ich kilka) mogą powodować niepowodzenie przesyłania dużych zdjęć +[*] visage - pokaż odwiedzającym swój kanał +[*] webmention - przetwarzanie stron internetowych +[*] wholikesme - dostarcza stronę wyświetlającą listę kontaktów, które najbardziej "polubiły" Twoje wpisy +[*] webRTC - użycie zewnętrznego serwera (mayfirst.org) do negocjowania połączeń webRTC +[*] wppost - publikowanie w WordPress (lub w innych serwisach stosujących XMLRPC Wordpress) +[*] xmpp - XMPP czat oparty na converse.js +[/list] + +[h3]Repozytoria dodatków[/h3] + +[b]Zdecydowanie zalecamy[/b], aby autorzy dodatków publikowali (przesyłali) je do repozytorium dodatków projektu. Ma to kilka zalet. Programiści projektów mogą łatwo naprawić luki w zabezpieczeniach i wprowadzać zmiany, aby dostosować się do ostatnich zmian w kodzie podstawowym. Dodatki dostarczane w repozytoriach innych firm są uważane za niezaufane. Jeśli podstawowy kod projektu zmieni się w niekompatybilny sposób, może nie być innej alternatywy niż fizyczne usunięcie lub zmiana nazw plików dodatków, aby ponownie uruchomić witrynę. Często tylko autor wtyczki / dodatku może pomóc Ci odzyskać kontrolę nad Twoją witryną, a programiści projektów nie są w stanie Ci pomóc; ponieważ z definicji konfiguracja Twojej witryny została zmodyfikowana w sposób, którego nie możemy łatwo przetestować ani zweryfikować. + +Z tych powodów [b]zdecydowanie zalecamy[/b], aby NIE instalować dodatków z repozytoriów innych firm. + +Zdajemy sobie również sprawę, że niektórzy programiści wolą pracować samodzielnie i nie chcą z różnych powodów, aby ich kod był mieszany z repozytorium projektu. Ci programiści mogą ułatwić rozwiązywanie problemów i debugowanie, udostępniając plik README w odpowiednim repozytorium kodu, w którym opisano proces przesyłania poprawek i poprawek błędów. Zaleca się również, aby te projekty zapewniały zarówno gałąź "dev" (rozwój), jak i "master" (produkcja), która śledzi bieżące gałęzie projektu o tych nazwach. Dzieje się tak, ponieważ dev i master często nie są kompatybilne z punktu widzenia interfejsów bibliotek. Zdecydowanie zaleca się również, aby wersje repozytorium były oznaczone i przeniesione do przodu w ciągu 24 godzin od wydania projektu. Jest to poważna niedogodność dla wszystkich zaangażowanych osób i może powodować przestoje w zakładach produkcyjnych podczas przeprowadzania tego procesu; co jest jeszcze jednym powodem, dla którego [b]zdecydowanie zalecamy[/b], aby dodatki były przesyłane do repozytorium dodatków projektu i aby NIE instalować takich dodatków innych firm. + + +[url=https://framagit.org/hubzilla/addons]https://framagit.org/hubzilla/addons[/url] Główne repozytorium dodatków projektu. + +[url=https://github.com/23n/red-addons]https://github.com/23n/red-addons[/url] Repozytorium Olivera (mayan_places i flip) + + + +#include doc/macros/main_footer.bb; + + diff --git a/doc/pl/addons_gnusocial.bb b/doc/pl/addons_gnusocial.bb new file mode 100644 index 000000000..a35af6e1f --- /dev/null +++ b/doc/pl/addons_gnusocial.bb @@ -0,0 +1,64 @@ +[b]Jak przesyłać wpisy do instancji GNUsocial[/b] + +Zacznij od instancji GNUSocial, w której masz swoje konto. + +W instancji GNUSocial przejdź do Ustawienia > Połączenia. W prawej kolumnie, w sekcji "Programiści", kliknij link "Zarejestruj aplikację kliencką OAuth, która ma być używana z tym wystąpieniem StatusNet". Ten link można znaleźć w Twojej instancji tutaj: + +https://yourgnusocialinstance.org/settings/oauthapps + +Następnie kliknij łącze "Zarejestruj nową aplikację". Pojawi się nowy formularz zgłoszeniowy. Oto, co należy zrobić na każdym polu. + +Ikona. Pobierz ikonę $Projectname znajdującą się pod tym linkiem, po zapisaniu jej na swoim komputerze: + +https://framagit.org/hubzilla/core/blob/master/images/rm-32.png + +Nazwa. Nadaj aplikacji odpowiednią nazwę. Wywołaj swoją witrynę hubzilli. Możesz preferować r2g. + +Opis. Użyj tego pola, aby opisać przeznaczenie aplikacji. Dodaj coś o efekcie użycia krzyżowego wysyłania z $Projectname do GNUsocial. + +Źródłowy adres URL. Wpisz nazwę domeny głównej witryny Red, której używasz. Nie zapomnij wpisać "s" w https://yourhubzillasite.com. Jeśli Twoja instalacja Red jest subdomeną, prawdopodobnie będzie to wymagane. + +Organizacja. Jeśli używasz tej instancji $Projectname dla grupy lub firmy, wypełnij to pole. + +Strona główna. Jeśli Twoja grupa korzysta z subdomeny, prawdopodobnie zechcesz umieścić tutaj identyfikator URI domeny głównej. + +Adres URL wywołania zwrotnego. Pozostaw puste. + +Typ aplikacji: wybierz "desktop." + +Domyślny dostęp: wybierz "Read-write." + +Wszystkie pola oprócz adresu URL wywołania zwrotnego muszą być wypełnione. + +Kliknij przycisk "Zapisz". + +Następnie kliknij ikonę lub nazwę aplikacji, aby wyświetlić informacje, które musisz wstawić w $Projectname. + +***** + +Otwórz teraz nową kartę lub okno i przejdź do swojego konta $Projectname, do ustawień Ustawienia > Właściwości. Znajdź ustawienia publikowania StatusNet. + +Wstaw w $Projectname ciągi liczb, podane na stronie GNUsocial, do pól klucza konsumenta i hasła konsumenta. + +Podstawową ścieżką API (pamiętaj o końcowym znaku /) będzie adres Twojej domeny i ścieżki "/api/". Prawdopodobnie będzie wyglądać tak: + +https://yourgnusocialinstance.org/api/ + +W przypadku wątpliwości sprawdź witrynę instancji GNUsocial, aby znaleźć adresy URL domeny tokenu żądania, tokenu dostępu i autoryzacji. Będzie to pierwsza część adresu URL domene, bez "/oauth/...." + +Nazwa aplikacji StatusNet: Wstaw nazwę, którą nadałeś aplikacji w witrynie GNUsocial. + +Kliknij "Prześlij". + +Pojawi się przycisk "Zaloguj się do StatusNet". Kliknij go, a otworzy się zakładka lub okno w witrynie GNUsocial, w którym możesz kliknąć "Zezwól". Po kliknięciu i pomyślnej autoryzacji pojawi się numer kodu bezpieczeństwa. Skopiuj go i wróć do aplikacji $Projectname, którą właśnie opuściłeś i wstaw ją w polu: "Tutaj skopiuj kod bezpieczeństwa ze StatusNet". Kliknij "Prześlij". + +Jeśli się powiedzie, Twoje informacje z instancji GNUsocial powinny pojawić się w aplikacji $Projectname. + +Jeśli chcesz, masz teraz do wyboru kilka opcji, które należy również potwierdzić, klikając "Prześlij". Najbardziej interesująca jest opcja "Domyślnie wysyłaj publiczne wpisy do StatusNet". Ta opcja automatycznie wysyła wszystkie wpisy, które napisałeś na koncie $Projectname do Twojej instancji GNUsocial. + +Jeśli nie wybierzesz tej opcji, będziesz mieć możliwość ręcznego wysłania wpisu do swojej instancji GNUsocial. W tym celu, najpierw otwórz wpis (klikając w obszarze tekstowym wpisu) i kliknik ikonę kłódki obok przycisku "Udostępnij". Wybierz ikonę GNUsocial składającą się z trzech kolorowych dymków dialogowych. Zamknij to okno, a następnie wykonaj swój wpis. + +Jeśli wszystko pójdzie dobrze, właśnie wysłałeś swój wpis z $Projectname na swoje konto w instancji GNUsocial. + +#include doc/macros/addons_footer.bb; + diff --git a/doc/pl/admin/administrator_guide.md b/doc/pl/admin/administrator_guide.md new file mode 100644 index 000000000..540828e0d --- /dev/null +++ b/doc/pl/admin/administrator_guide.md @@ -0,0 +1,593 @@ +### Przegląd + +$Projectname to więcej niż prosta aplikacja internetowa. Jest to złożony system +komunikacyjny, który bardziej przypomina serwer poczty elektronicznej niż serwer +WWW. Aby zapewnić niezawodność i wydajność, wiadomości są dostarczane w tle i +umieszczane w kolejce do późniejszego dostarczenia, gdy lokacje są wyłączone. +Ten rodzaj funkcjonalności wymaga nieco więcej zasobów hosta niż typowy dziennik. +Nie każdy dostawca hostingu PHP-MySQL będzie w stanie obsługiwać $Projectname. Tak więc, przed instalacją zapoznaj się z wymaganiami i potwierdź je u dostawcy usług hostingowych. + +Bardzo staraliśmy się, aby Hubzilla działała na zwykłych platformach hostingowych, takich jak te używane do hostowania blogów Wordpress i stron internetowych Drupal. Będzie ona działać na większości systemów VPS Linux. Platformy Windows LAMP, takie jak XAMPP i WAMP, nie są obecnie oficjalnie obsługiwane, jednak mile widziane są poprawki, jeśli uda Ci się je uruchomić. + +### Gdzie można znaleźć więcej pomocy + +Jeśli napotkasz problemy lub sam masz jakiś problem, które nie zostały opisane w tej dokumentacji, poinformuj nas o tym za pośrednictwem narzędzia do [śledzenia problemów na Github](https://framagit.org/hubzilla/core/issues). Prosimy o jak najdokładniejsze opisanie swojego środowiska operacyjnego i podanie jak największej ilości informacji o wszelkich komunikatach o błędach, które mogą się pojawić, abyśmy mogli zapobiec ich występowaniu w przyszłości. Ze względu na dużą różnorodność istniejących systemów operacyjnych i platform PHP możemy mieć ograniczone możliwości debugowania instalacji PHP lub pozyskiwania brakujących modułów, ale dołożymy wszelkich starań, aby rozwiązać wszelkie ogólne problemy z kodem. + +### Zanim zaczniesz + +#### Wybierz nazwę domeny lub subdomeny dla swojego serwera + +Platformę $Projectname można zainstalować tylko w katalogu głównym domeny lub +subdomeny i nie może ona działać na niestandardowych portach TCP. + +#### Zdecyduj, czy będziesz używać SSL i uzyskaj certyfikat SSL przed instalacją oprogramowania + +POWINNO się używać SSL. Jeśli używasz SSL, MUSISZ użyć certyfikatu uznawanego +przez przeglądarki. **NIE WOLNO używać certyfikatów z podpisem własnym!** + +Przetestuj swój certyfikat przed instalacją. Narzędzie internetowe do testowania +certyfikatu jest dostępne pod adresem `http://www.digicert.com/help/`. +Odwiedzając witrynę po raz pierwszy, użyj adresu URL SSL (`https: //`), jeśli +protokół SSL jest dostępny. Pozwoli to uniknąć późniejszych problemów. Procedura +instalacji nie pozwoli na użycie certyfikatu, który nie jest zaufany dla przeglądarki. + +To ograniczenie zostało wprowadzone, ponieważ Twoje publiczne wpisy mogą zawierać +odniesienia do obrazów na Twoim hubie. Inni członkowie przeglądający swój strumień +w innych centrach otrzymają ostrzeżenia, jeśli Twój certyfikat nie jest zaufany +w ich przeglądarce internetowej. To zmyli wiele osób, ponieważ jest to +zdecentralizowana sieć i otrzymają ostrzeżenie o Twoim hubie podczas przeglądania +własnego huba i mogą pomyśleć, że ich własny hub ma problem. Te ostrzeżenia +są bardzo techniczne i przerażające dla niektórych osób, z których wielu nie +będzie wiedziało, jak postępować, z wyjątkiem przestrzegania zaleceń przeglądarki. +Jest to destrukcyjne dla społeczności. To powiedziawszy, zdajemy sobie sprawę z +problemów związanych z obecną infrastrukturą certyfikatów i zgadzamy się, że +istnieje wiele problemów, ale to nie zmienia wymagania. + +Bezpłatne certyfikaty zgodne z przeglądarkami są dostępne od dostawców, takich +jak StartSSL i LetsEncrypt. + +Jeśli NIE używasz SSL, może wystąpić opóźnienie do minuty dla startowego skryptu +instalacyjnego - podczas sprawdzania portu SSL, aby zobaczyć, czy tam jest wszystko +w porządku. Podczas komunikowania się z nowymi witrynami Hubzilla zawsze najpierw +próbuje połączyć się z portem SSL, zanim powróci do mniej bezpiecznego połączenia. +Jeśli nie używasz SSL, twój serwer WWW NIE MOŻE w ogóle nasłuchiwać na porcie 443. + +Jeśli używasz LetsEncrypt do dostarczania certyfikatów i tworzenia pliku pod +`well-known` lub `acme-challenge`, aby LetsEncrypt mógł zweryfikować własność +domeny, usuń lub zmień nazwę katalogu `.well-known` zaraz po wygenerowaniu +certyfikatu. $Projectname zapewni własną procedurę obsługi usług `.well-know` po +zainstalowaniu, a istniejący katalog w tej lokalizacji może uniemożliwić poprawne +działanie niektórych z tych usług. Nie powinno to stanowić problemu w przypadku +Apache, ale może to być problem z Nginx lub innymi platformami serwera internetowego. + +### Wdrożenie +Nowy hub można wdrożyć na kilka sposobów: + +* ręczna inastalaja na istniejącym serwerze; +* automatyczna instalacja na istniejącym serwerze przy użyciu skryptu instalacyjnego; +* automatyczne wdrożenie przy użyciu prywatnego serwera wirtualnego OpenShift (VPS).) + +### Wymagania +* Apache z włączonym modułem `mod-rewrite` i ustawioną dyrektywą "AllowOverride + All", tak aby można było stosować plik `.htaccess`. Niektóre osoby z powodzeniem + stosowały Nginx czy Lighttpd.Przykładowe skrypty konfiguracyjne są dostępne na + tej platformie w [doc/install](). Apache and Nginx mają najlepsze wsparcie. + +* PHP 7.1 lub w wersji wyższej. + * _Proszę mieć na uwadze, że w niektórych środowiskach hostinu + współdzielonego, wersja wiersza poleceń PHP różni się od wersji + serwera internetowego_ + +* Dostęp do wiersza poleceń PHP z ustawionym w pliku php.ini parametrem + `register_argc_argv` na `true` i bez ograniczeń dostawcy hostingu w zakresie + stosowania fumkcji `exec()` i `proc_open()`. + +* Rozszerzenia curl, gd (z obsługą co najmmniej jpeg i png), mysqli, mbstring, + mcrypt, zip i openssl. Tozszerzenie imagick nie jest wymagane ale jest zalecane. + +* Wymagane jest rozszerzenie xml, jeśli chce sie mieć działajacą obsługę webdav. + +* Jakaś forma serwera pocztowego lub bramy pocztowej, taka jak działa PHP mail(). + +* Serwer bazy danych Mysql 5.x lub MariaDB lub PostgreSQL. + +* Możliwość planowania zadań dla crona. + +* WYMAGANA jest instalacja w katalogu głównym hosta WWW (wirtualnego hosta w + Apache i bloku w Nginx). + +### Instalacja ręczna + +##### Krok 1. + +Rozpakuj pliki $Projectname do katalogu głównego obszaru dokumentów serwera WWW. +Jeśli kopiujesz drzewo katalogów na swój serwer WWW, upewnij się, że dołączasz +ukryte pliki, takie jak `.htaccess`. + +Jeśli możesz to zrobić, zalecamy użycie Git do sklonowania repozytorium źródłowego +zamiast używania spakowanego pliku tar lub zip. To znacznie ułatwia późniejszą +aktualizację oprogramowania. Polecenie Linux do sklonowania repozytorium do katalogu +"mywebsite: wyglądałoby tak: + + git clone https://framagit.org/hubzilla/core.git mywebsite + +a następnie, w dowolnym momencie, możesz pobrać najnowsze zmiany za pomocą: + + git pull + +upewnij się, że istniejeją foldery `store/[data]/smarty3` i `store` i że są +one możliwe do zapisu przez właściciela procesu serwera WWW: + + mkdir -p "store/[data]/smarty3" + chmod -R 777 store + +To uprawnienie (777) jest bardzo niebezpieczne i jeśli masz wystarczające +uprawnienia i wiedzę powinieneś umożliwić zapisywanie w tych katalogach tylko +przez serwer WWW i użytkownika, który uruchomia crona (patrz poniżej), jeśli jest +taki. W wielu współdzielonych środowiskach hostingowych może to być trudne, bez +zgłoszenia problemu u dostawcy. Powyższe uprawnienia pozwolą oprogramowaniu +działać, ale nie są optymalne. + +Aby działały niektóre internetowe narzędzia administracyjne, serwer WWW musi mieć +możliwość zapisu w następujących katalogach: + +* `addon` +* `extend` +* `view/theme` +* `widget` + +##### Krok 2. + +Utwórz pustą bazę danych i zanotuj szczegóły dostępu (nazwa hosta, nazwa +użytkownika, hasło, nazwa bazy danych). Biblioteki bazy danych PDO powracają do +komunikacji przez gniazdo uniksowe, gdy nazwą hosta jest `localhost`, ale +niektóre osoby zgłosiły problemy z implementacją gniazda. Użyj gniazd, jeśli +Twoje uprawnienia na to pozwalają. W przeciwnym razie, jeśli baza danych jest +udostępniana na hoście `localhost`, jako nazwę hosta wpisz `127.0.0.1`. + +Wewnętrznie używamy teraz biblioteki PDO do połączeń z bazą danych. Jeśli masz +do czynienia z konfigyracją bazy danych, którą nie możesz obsłużyć poprzez +formularz konfiguracyjny (ma przykład w przypadku uzywania MySQL z nietypową +lokalizacją gniazd) - możesz podać ciąg połączenia PDO jako nazwę hosta. +Na przykład: + + :/path/to/socket.file + +W razie potrzeby nadal trzeba wypełnić w formularzu konfiguracyjnym wszystkie +inne wartości mające zastosowanie. + +##### Krok 3. + +Utwórz pusty plik o nazwie `.htconfig.php` i uczyń go możliwymm do zapisania +przez serwer WWW. Krok ten wykonaj, jeśli wiesz, że serwer WWW nie będzie +mógł sam utworzyć tego pliku. + +##### Krok 4. + +Odwiedź swoją witrynę za pomocą przeglądarki internetowej i postępuj zgodnie z +instrukcjami. Zanotuj wszelkie komunikaty o błędach i popraw je przed +kontynuowaniem. Jeśli używasz protokołu SSL (od znanego urzędu autoryzacyjnego), +użyj schematu `https` w adresie URL swojej witryny. + +##### Krok 5. + +Jeśli automatyczna instalacja nie powiedzie się z jakiegoś powodu, +sprawdź następujące rzeczy: + +* Czy istnieje plik `.htconfig.php`? Jeśli nie, edytuj plik `htconfig.php` + i zmień w nim ustawienia systemowe. Następnie zmień jego nazwę na .htconfig.php. +* Czy baza danych jest wypełniona. Jeśli nie, zaimportuj treść skryptu + `install/schema_xxxxx.sql` w phpmyadmin lub wierszu poleceń mysql (zamień + 'xxxxx' na własciwy typ bazy danych). + +##### Krok 6. + +Po udanej instalacji odwiedż ponownie swoją witrynę i zarejestruj swoje osobiste +konto. Błędy rejestracji powinny dać sie naprawić automatycznie. + +Jeśli w tym momencie wystąpiła jakakolwiek *krytyczna* awaria, to na ogół +przyczyna leży w źle funkcjonującej bazie danych. W takim przypadku, aby zacząć +od nowa, usuń lub zmień nazwę pliku `.htconfig.php` i usuń tabele bazy danych. + +Aby Twoje konto miało dostęp administratora, powinno to być utworzone jako +pierwsze, a adres e-mail podany podczas rejestracji musi być zgodny z adresem +administratora podanym podczas instalacji. Jeśli stało sie inaczej, aby dać +dostęp administracyjny jakiemuś kontu, dodaj `4096` w rekordzie tabeli +`account_roles` tego konta. + +Ze względu na bezpieczeństwo witryny, nie ma możliwości zapewnienia dostępu +administracyjnego za pomocą formularzy konfiguracyjnych. + +##### Krok 7. BARDZO WAŻNY! + +Skonfiguruj zadanie Crona lub *zadanie zaplanowane*, tak aby uruchamiać menedżera +Crona co 10-15 minut w celu przetwarzania i konserwacji w tle. Przykład: + + cd /base/directory; /path/to/php Zotlabs/Daemon/Master.php Cron + + +Zmień tutaj `/base/directory` i `/path/to/php` na właściwe dla siebie ścieżki. + +Jeśli używasz serwera linuksowego, uruchom polecenie `crontab -e` i dodaj wiersz +taki jak poniżej, zmieniając odpowiednio ścieżki i ustawienia: + + */10 * * * * cd /home/myname/mywebsite; /usr/bin/php Zotlabs/Daemon/Master.php Cron > /dev/null 2>&1 + +Lokalizację PHP na ogół można ustalić wykonując polecenie `which php`. Jeśli +masz problemy z ustawienie Crona, skontaktuj się z dostawcą hostingu w celu +uzyskania pomocy. Hubzilla nie będzie działać prawidłowo bez tego kroku. + +Powinno się również sprawdzić ustawienie parametru +`App::$config['system']['php_path']` w pliku `.htconfig.php`. +Powinno to wyglądać tak (zmień to zgodnie z lokalizacją PHP w swoim systemie): + + + App::$config['system']['php_path'] = '/usr/local/php56/bin/php'; + +#### Oficjalne dodatki + +##### Instalacja + +Przejdź do swojej witryny. Następnie sklonuj repozytorium dodatków (osobno). +Nadamy temu repozytorium pseudonim `hzaddons`. Możesz pobrać inne repozytoria +dodatków Hubzilla, nadając im różne pseudonimy: + + cd mywebsite + util/add_addon_repo https://framagit.org/hubzilla/addons.git hzaddons + +##### Aktualizacja + +W celu aktualizacji drzewa dodatków, powinno się, z poziomu głównego katalogu +witryny, wydać polecenie aktualizacji tego repozytorium: + + cd mywebsite + util/update_addon_repo hzaddons + +Stwórz reprezentację dokumentacji online z możliwością wyszukiwania. Możesz to +zrobić za każdym razem, gdy dokumentacja jest aktualizowana: + + cd mywebsite + util/importdoc + +### Automatyczna instalacja poprzez skrypt .homeinstall + +Istnieje skrypt powłoki `.homeinstall/hubzilla-setup.sh`, który po +uruchomieniu zainstaluje Hubzillę i jego zależności na nowej instalacji stabilnej +dystrybucji Debiana 9 (Stetch). Powinien działać na podobnych systemach Linux, +ale wyniki mogą się różnić. + +#### Wymagania + +Skrypt instalacyjny został pierwotnie zaprojektowany dla małego serwera +sprzętowego za routerem domowym. Jednak został przetestowany też na kilku +systemach z Debian 9: + +* Home-PC (Debian-9.2-amd64) i Rapberry-Pi 3 (Rasbian = Debian 9.3) + * Połączenie z Internetem i domowy router + * Mini-PC lub Raspi połaczone z router + * Napęd USB dla kopii zapasowych + * Świeża instalacja Debian na swoim mini-pc + * Router z otwartymi portami 80 i 443 dla Debiana + +#### Etapy instalacji +1. `apt-get install git` +1. `mkdir -p /var/www/html` +1. `cd /var/www/html` +1. `git clone https://framagit.org/hubzilla/core.git .` +1. `nano .homeinstall/hubzilla-config.txt` +1. `cd .homeinstall/` +1. `./hubzilla-setup.sh` +1. `service apache2 reload` +1. Open your domain with a browser and step throught the initial configuration of $Projectname. + +### Zalecane dodatki + +Zalecamy zainstalowanie następujących dodatków we wszystkich publicznych witrynach: + + nsfw - hide inappropriate posts/comments + superblock - block content from offensive channels + +### Dodatki federacyjne + +Kilka społeczności internetowych zaczęło łączyć się przy użyciu wspólnych +protokołów. Stosowane protokoły mają nieco ograniczone możliwości. Na przykład +protokół GNU-Social nie oferuje żadnych trybów prywatności, a protokół Diaspora +jest nieco bardziej restrykcyjny w zakresie dozwolonych rodzajów komunikacji. +Wszystkie komentarze muszą być podpisane w bardzo unikalny sposób przez +oryginalnego autora. Rozważany jest również protokół ActivityPub, który może być +obsługiwany w przyszłości. Żaden inny istniejący protokół nie obsługuje +lokalizacji nomadycznej używanej w tym projekcie. Stwarza to pewne problemy z +obsługą, ponieważ niektóre funkcje działają w niektórych sieciach, a w innych nie. +Niemniej jednak protokoły federacyjne umożliwiają nawiązywanie połączeń ze znacznie +większą społecznością ludzi na całym świecie. Są dostarczane jako dodatki. + +* _diaspora_ - protokół diaspory używany przez Diasporę i Friendica. Najpierw + należy włączyć „Diaspora Statistics” (statystyki), aby włączyć wszystkie + dostępne funkcje. + +* _gnusoc_ - protokół społecznościowy GNU, używany przez GNU-Social, Mastodon i + kilka innych społeczności. Ten dodatek wymaga najpierw zainstalowania usługi + `pubsubhubbub` (także dodatku). + +Każdy członek Twojej siatki musi indywidualnie zdecydować, czy zezwolić na te +protokoły, ponieważ mogą one kolidować z kilkoma pożądanymi podstawowymi funkcjami +i możliwościami Hubzilla (takimi jak migracja kanałów i klonowanie). Robi się to +na swojej stronie _Ustawienia_ -> _Ustawienia funkcji i dodatków_. Administrator +może również ustawić: + + util/config system.diaspora_allowed 1 + util/config system.gnusoc_allowed 1 + +i włączać te protokoły automatycznie dla wszystkich nowo tworzonych kanałów. + +### Klasy usług + +Klasy usług pozwalają na ustawienie limitów zasobów systemowych poprzez +ograniczenie tego, co mogą robić poszczególne konta, w tym przechowywania plików +i najwyższych limitów wpisów. Zdefiniuj niestandardowe klasy usług zgodnie ze +swoimi potrzebami w pliku `.htconfig.php`. Na przykład utwórz klasę standard +i premium, używając następujących wierszy: + + // Service classes + + App::$config['system']['default_service_class']='standard'; // this is the default service class that is attached to every new account + + // configuration for standard service class + App::$config['service_class']['standard'] = + array('photo_upload_limit'=>2097152, // total photo storage limit per channel (here 2MB) + 'total_identities' =>1, // number of channels an account can create + 'total_items' =>0, // number of top level posts a channel can create. Applies only to top level posts of the channel user, other posts and comments are unaffected + 'total_pages' =>100, // number of pages a channel can create + 'total_channels' =>100, // number of channels the user can add, other users can still add this channel, even if the limit is reached + 'attach_upload_limit' =>2097152, // total attachment storage limit per channel (here 2MB) + 'chatters_inroom' =>20); + + // configuration for premium service class + App::$config['service_class']['premium'] = + array('photo_upload_limit'=>20000000000, // total photo storage limit per channel (here 20GB) + 'total_identities' =>20, // number of channels an account can create + 'total_items' =>20000, // number of top level posts a channel can create. Applies only to top level posts of the channel user, other posts and comments are unaffected + 'total_pages' =>400, // number of pages a channel can create + 'total_channels' =>2000, // number of channels the user can add, other users can still add this channel, even if the limit is reached + 'attach_upload_limit' =>20000000000, // total attachment storage limit per channel (here 20GB) + 'chatters_inroom' =>100); + +Aby zastosować klasę usług do istniejącego konta, użyj narzędzia wiersza poleceń +z katalogu głównego instalacji Hubzilla: + +* uzyskanie listy klas usług: + + util/service_class + + +* ustawienie domyślnej klasy usług na `firstclass`: + + util/config system default_service_class firstclass + +* uzyskanie listy usług, które należą do klasy `firstclass`: + + util/service_class firstclass + +* ustawienie całkowitego użycia dysku ze zdjęciami `firstclass` na 10 milionów bajtów + + util/service_class firstclass photo_upload_limit 10000000 + +* ustawienie konta z identyfikatorem 5 na klasę `firstclass` (z potwierdzeniem): + + util/service_class --account=5 firstclass + +* ustawienie konta, które jest właścicielem kanału `bdziennikchan` na klasę `firstclass` (z potwierdzeniem) + + util/service_class --channel=bdziennikchan firstclass + +**Service class limit options** + +##### Opcje limitów klas usług: + +* `photo_upload_limit` - maksymalna łączna liczba bajtów na zdjęcia +* `total_items` - maksymalna liczba wpisów na najwyższym poziomie +* `total_pages` - maksymalna liczba stron comanche +* `total_identities` - maksymalna liczba kanałów posiadanych na koncie +* `total_channels` - maksymalna liczba kanałów +* `total_feeds` - maksymalna liczba kanałów RSS +* `attach_upload_limit` - maksymalna pojemność przesyłania plików (w bajtach) +* `minimum_feedcheck_minutes` - najniższe ustawienie dozwolone dla odpytywania kanałów RSS +* `chatrooms` - maksymalna liczba czatów +* `chatters_inroom` - maksymalna liczba rozmówców w czacie +* `access_tokens` - maksymalna liczba tokenów dostępu gościa na kanał + +### Zarządzanie motywami + +#### Przykład zarządzania repozytorium + +1) Przejdź na poziom katalogu głównego serwera: + + ``` + root@hub:/root# cd /var/www + ``` + +2) Dodaj repozytorium motywu i nadaj mu nazwę + + ``` + root@hub:/var/www# util/add_theme_repo https://github.com/DeadSuperHero/redmatrix-themes.git DeadSuperHero + ``` +3) Zaktualizuj repozytorium motywu + + ``` + root@hub:/var/www# util/update_theme_repo DeadSuperHero + ``` + +### Katalog kanałów + +#### Słowa kluczowe + +Na stronie katalogu kanałów może pojawiać się „chmura tagów” słów kluczowych. +Jeśli chcesz ukryć te słowa kluczowe, które są pobierane z serwera katalogów, +możesz użyć narzędzia `config`: + + util/config system disable_directory_keywords 1 + +Jeśli twój hub pracuje w trybie autonomicznym, ponieważ nie chcesz łączyć się +z globalną siecią, możesz zamiast tego ustawić opcję systemową `directory_server` +na wartość pustą: + + util/config system directory_server "" + +### Administrowanie + +#### Administrowanie witryną + +Administracja witryną jest zwykle wykonywana za pośrednictwem strony administratora +znajdującej się na ścieżce `/admin` adresu URL Twojej witryny. Aby uzyskać dostęp +do tej strony, trzeba mieć uprawnienia administratora na serwerze. Prawa +administracyjne są przyznawane pierwszemu kontu, które zostało zarejestrowane w +witrynie, pod warunkiem, że adres e-mail tego konta dokładnie odpowiada adresowi +e-mail podanemu jako adres e-mail administratora podczas konfiguracji. + +Istnieje kilka sposobów, w jakie może to się nie powieść i pozostawić system bez +konta administratora, na przykład jeśli pierwsze konto, które zostało utworzone, +miało inny adres e-mail niż adres e-mail administratora, który został podany +podczas konfiguracji. + +Ze względów bezpieczeństwa w systemie nie ma strony internetowej ani interfejsu, +który daje dostęp administratora. Jeśli potrzebujesz poprawić sytuację, w której +system nie ma konta administratora, musisz to zrobić edytując tabelę kont w bazie +danych. Nie ma innego wyjścia. Aby to zrobić, będziesz musiał zlokalizować wpis +w tabeli kont, który należy do żądanego administratora i ustawić `account_roles` +dla tego wpisu na `4096`. Będziesz wtedy mógł uzyskać dostęp do strony +administratora z menu profilu twojego systemu lub bezpośrednio na ścieżce `/admin`. + +Hub może mieć wielu administratorów i nie ma ograniczeń co do ich liczby. +Powtórz powyższą procedurę dla każdego konta, któremu chcesz przyznać uprawnienia +administracyjne. + +### Rozwiązywanie problemów + +#### Pliki dzienników + +Plik dziennika systemowego jest niezwykle przydatnym źródłem informacji do +śledzenia błędów. Można to włączyć na stronie konfiguracji `admin/dziennik`. +Ustawienie poziomu o wartości `dziennikGER_DEBUG` jest preferowany w stabilnej +instalacji produkcyjnej. Większość problemów związanych z komunikacją lub +przechowywaniem jest tutaj wymieniona. Ustawienie na `dziennikGER_DATA` +zapewnia znacznie więcej szczegółów, ale może wypełnić dysk. W obu przypadkach +zalecamy użycie `dziennikrotate` w systemie operacyjnym do cyklicznego tworzenia +dzienników i usuwania starszych wpisów. + +Na dole twojego `.htconfig.php` znajduje się kilka linii (zakomentowanych), +które umożliwiają rejestrowanie błędów PHP. Zgłaszane są problemy ze składnią i +wykonywaniem kodu i jest to też pierwszym miejscem, w którym należy szukać +problemów, które powodują "biały ekran" lub pustą stronę. Zwykle jest to wynikiem +problemów z kodem lub składnią. Błędy bazy danych są zgłaszane do pliku dziennika +systemowego, ale uznaliśmy, że przydatne jest umieszczenie w katalogu najwyższego +poziomu pliku `dbfail.out`, który gromadzi tylko informacje o problemach +związanych z bazą danych. Jeśli plik istnieje i można go zapisać, będą rejestrowane +w nim błędy bazy danych, a także w pliku dziennika systemowego. + +W przypadku błędów "500: problemy mogą być często rejestrowane w dziennikach +serwera internetowego, często w `/var/dziennik/apache2/error.dziennik` lub +podobnym. Zapoznaj się z dokumentacją systemu operacyjnego. + +Istnieją trzy różne obiekty dziennika. + +**Pierwsza to dziennik błędów bazy danych**. Jest on używane tylko wtedy, gdy +tworzy ssię plik o specyficznej nazwie `dbfail.out` w folderze głównym swojej +witryny i pozwala się na zapisywanie w nim przez serwer WWW. Jeśli masz +jakiekolwiek zapytania do bazy danych, które nie powiodły się, wszystkie są +zgłaszane tutaj. Zwykle wskazują na literówki w naszych zapytaniach, ale występują +również w przypadku rozłączenia serwera bazy danych lub uszkodzenia tabel. +W rzadkich przypadkach zobaczymy tutaj warunki wyścigu, w których dwa procesy +próbowały utworzyć wpis `xchan` lub `cache`z tym samym identyfikatorem. Należy +zbadać wszelkie inne błędy (zwłaszcza błędy uporczywe). + +**Drugi to dziennik błędów PHP**. Jest tworzony przez procesor języka i zgłasza +tylko problemy powstałe w środowisku językowym. Znowu mogą to być błędy składniowe +lub błędy programistyczne, ale generalnie są one fatalne i skutkują "białym ekranem"; +na przykład PHP kończy działanie. Prawdopodobnie powinieneś zajrzeć do tego pliku +też, jeśli coś pójdzie nie tak, co nie powoduje białego ekranu. Często zdarza się, +że plik ten jest pusty przez wiele dni. + +Na dole dostarczonego pliku `.htconfig.php` znajduje się kilka linii, które, +jeśli nie są zakomentowane, włączają dziennik PHP (niezwykle przydatny do +znajdowania źródła błędów białego ekranu). Nie jest to robione domyślnie ze względu +na potencjalne problemy z własnością pliku dziennika i uprawnieniami do zapisu +oraz fakt, że domyślnie nie ma rotacji pliku dziennika. + +**Trzeci to "dziennik aplikacji"**. Jest to używane przez Hubzillę do zgłaszania +tego, co dzieje się w programie i zwykle zapisywane są tu wszelkie trudności lub +nieoczekiwane dane, które otrzymaliśmy. Czasami zgłasza się tu również komunikaty +o stanie "pulsu", aby wskazać, że osiągnęliśmy określony punkt w skrypcie. Jest +to dla nas najważniejszy plik dziennika, ponieważ tworzymy go samodzielnie +wyłącznie w celu zgłaszania stanu zadań w tle i wszystkiego, co wydaje się dziwne +lub nie na miejscu. To może nie być śmiertelne, ale może po prostu nieoczekiwane. +Jeśli wykonujesz zadanie i występuje problem, daj nam znać, co znajduje się w tym +pliku, gdy wystąpił problem. Proszę nie wysyłaj mi 100 milionów zrzutów, tylko +mnie wkurzysz! Tylko kilka odpowiednich wierszy, abym mógł wykluczyć kilkaset +tysięcy wierszy kodu i skoncentrować się na tym, gdzie zaczyna się pojawiać +problem. + +To są dzienniki Twojej witryny, a nie moje. Zgłaszamy poważne problemy na każdym +poziomie dziennika. Gorąco polecam poziom dziennika `DEBUG` dla większości witryn. +Dostarcza on trochę dodatkowych informacji i nie tworzy dużych plików dziennika. +Kiedy pojawia się problem, który uniemożliwia wszelkie próby śledzenia, możesz +wtedy włączyć na krótki czas poziom `DATA`, aby uchwycić wszystkie szczegóły +struktur, z którymi mieliśmy do czynienia w tym czasie. Ten poziom dziennika +zajmuje dużo miejsca, więc jest zalecany tylko na krótkie okresy lub w przypadku +witryn testowych dla programistów. + +Zalecam skonfigurowanie `logrotate` zarówno dla dziennika php, jak i dziennika +aplikacji. Zazwyczaj co tydzień lub dwa zaglądam do `dbfail.out`, naprawiam +zgłoszone problemy i zaczynam od nowego pliku. Podobnie jest z plikiem dziennika +PHP. Odwołuję się do tego od czasu do czasu, aby sprawdzić, czy jest coś, co +wymaga naprawy. + +Jeśli coś pójdzie nie tak i nie jest to błąd krytyczny, patrzę na plik dziennika +aplikacji. Często robię to: + +``` +tail -f logfile.out +``` + +ponieważ powtarza operację, która ma problemy. Często wstawiam w kodzie dodatkowe +instrukcje logowania, jeśli nie ma żadnej wskazówki, co się dzieje. Nawet coś tak +prostego jak "got here" lub drukuję wartości zmiennej, która może być podejrzana. +Ty też możesz to zrobić - wręcz zachęcam Cię do tego. Gdy już znajdziesz to, czego +potrzebujesz, możesz wykonać: + +``` +git checkout file.php +``` + +aby natychmiast wyczyścić wszystkie dodane elementy rejestrowania. Skorzystaj z +informacji z tego dziennika i wszelkich szczegółów, które możesz podać podczas +badania problemu, aby zgłosić błąd - chyba że analiza wskazuje na źródło problemu. +W takim przypadku po prostu to napraw. + +##### Rotowanie plików dziennika + +1. Włącz dodatek *Logrot* w [oficjalnym repozytorium dodatków hubzilla](https://framagit.org/hubzilla/addons). +1. Utwórz katalog w swoim katalogu głównym o nazwie `log` z uprawnieniami do zapisu przez serwer WWW. +1. Przejdź do ustawień administratora programu *Logrot* i wprowadź nazwę folderu, a także maksymalny rozmiar i liczbę zachowanych plików dziennika. + +#### Zgłaszanie problemów + +Zgłaszając problemy, staraj się podać jak najwięcej szczegółów, które mogą być +potrzebne programistom do odtworzenia problemu i podać pełny tekst wszystkich +komunikatów o błędach. + +Zachęcamy do dołożenia wszelkich starań, aby wykorzystać te dzienniki w połączeniu +z posiadanym kodem źródłowym w celu rozwiązywania problemów i znajdowania ich +przyczyn. Społeczność często jest w stanie pomóc, ale tylko Ty masz dostęp do +plików dziennika swojej witryny i ich udostępnianie jest uważane za zagrożenie +bezpieczeństwa. + +Jeśli problem z kodem został odkryty, zgłoś go w bugtrackerze projektu +(https://framagit.org/hubzilla/core/issues). Ponownie podaj jak najwięcej szczegółów, +aby uniknąć ciągłego zadawania pytań o konfigurację lub powielanie problemu, +abyśmy mogli przejść od razu do problemu i dowiedzieć się, co z nim zrobić. +Zapraszamy również do oferowania własnych rozwiązań i przesyłania poprawek. +W rzeczywistości zachęcamy do tego, ponieważ wszyscy jesteśmy wolontariuszami i +mamy mało wolnego czasu. Im więcej osób pomaga, tym łatwiejsze jest obciążenie +pracą dla wszystkich. W porządku, jeśli Twoje rozwiązanie nie jest idealne. +Wszystko pomaga i być może uda nam się to poprawić. + diff --git a/doc/pl/admin/hub_snapshots.md b/doc/pl/admin/hub_snapshots.md new file mode 100644 index 000000000..1a5bd2d4f --- /dev/null +++ b/doc/pl/admin/hub_snapshots.md @@ -0,0 +1,127 @@ +### Hub Snapshot Tools + +Programiści Hubzilli często muszą przełączać się między gałęziami, które mogą +mieć niekompatybilne schematy lub zawartość bazy danych. Poniższe dwa skrypty +tworzą i przywracają pełne migawki instancji Hubzilli, w tym zarówno główny +katalog sieciowy, jak i stan całej bazy danych. Każdy skrypt wymaga pliku +konfiguracyjnego o nazwie `hub-snapshot.conf` znajdującego się w tym samym +folderze i zawiera on określone katalogi i szczegóły bazy danych huba. + +### Konfiguracja + +Format pliku konfiguracyjnego jest bardzo ścisły. Między nazwą zmiennej a +wartością nie może być spacji. Zastąp tylko treść w cudzysłowach swoją +konfiguracją. Zapisz ten plik jako `hub-snapshot.conf` obok skryptów. + + # Location of hub root. Typically this is the location of the Hubzilla repo clone. + HUBROOT="/var/www/" + # MySQL database name + DBNAME="hubzilla" + # MySQL database user + DBUSER="hubzilla" + # MySQL database password + DBPWD="akeufajeuwfb" + # The target snapshot folder where the git repo will be initialized + SNAPSHOTROOT="/root/snapshots/hubzilla/" + +### Migawka + +Przykład użycia: + + sh hub-snapshot.sh my-hub.conf "Commit message for the snapshot" + +**hub-snapshot.sh**: + + #!/bin/bash + + if ! [ -f "$1" ]; then + echo "$1 is not a valid file. Aborting..." + exit 1 + fi + source "$1" + #echo "$DBNAME" + #echo "$DBUSER" + #echo "$DBPWD" + #echo "$HUBROOT" + #echo "$SNAPSHOTROOT" + MESSAGE="snapshot: $2" + + if [ "$DBPWD" == "" -o "$SNAPSHOTROOT" == "" -o "$DBNAME" == "" -o "$DBUSER" == "" -o "$HUBROOT" == "" ]; then + echo "Required variable is not set. Aborting..." + exit 1 + fi + + if [ ! -d "$SNAPSHOTROOT"/db/ ]; then + mkdir -p "$SNAPSHOTROOT"/db/ + fi + if [ ! -d "$SNAPSHOTROOT"/www/ ]; then + mkdir -p "$SNAPSHOTROOT"/www/ + fi + + if [ ! -d "$SNAPSHOTROOT"/www/ ] || [ ! -d "$SNAPSHOTROOT"/db/ ]; then + echo "Error creating snapshot directories. Aborting..." + exit 1 + fi + + echo "Export database..." + mysqldump -u "$DBUSER" -p"$DBPWD" "$DBNAME" > "$SNAPSHOTROOT"/db/"$DBNAME".sql + echo "Copy hub root files..." + rsync -va --delete --exclude=.git* "$HUBROOT"/ "$SNAPSHOTROOT"/www/ + + cd "$SNAPSHOTROOT" + + if [ ! -d ".git" ]; then + git init + fi + if [ ! -d ".git" ]; then + echo "Cannot initialize git repo. Aborting..." + exit 1 + fi + + git add -A + echo "Commit hub snapshot..." + git commit -a -m "$MESSAGE" + + exit 0 + +### Przywracanie + + #!/bin/bash + # Restore hub to a previous state. Input hub config and commit hash + + if ! [ -f "$1" ]; then + echo "$1 is not a valid file. Aborting..." + exit 1 + fi + source "$1" + COMMIT=$2 + + if [ "$DBPWD" == "" -o "$SNAPSHOTROOT" == "" -o "$DBNAME" == "" -o "$DBUSER" == "" -o "$HUBROOT" == "" ]; then + echo "Required variable is not set. Aborting..." + exit 1 + fi + RESTOREDIR="$(mktemp -d)/" + + if [ ! -d "$RESTOREDIR" ]; then + echo "Cannot create restore directory. Aborting..." + exit 1 + fi + echo "Cloning the snapshot repo..." + git clone "$SNAPSHOTROOT" "$RESTOREDIR" + cd "$RESTOREDIR" + echo "Checkout requested snapshot..." + git checkout "$COMMIT" + echo "Restore hub root files..." + rsync -a --delete --exclude=.git* "$RESTOREDIR"/www/ "$HUBROOT"/ + echo "Restore hub database..." + mysql -u "$DBUSER" -p"$DBPWD" "$DBNAME" < "$RESTOREDIR"/db/"$DBNAME".sql + + chown -R www-data:www-data "$HUBROOT"/{store,extend,addon,.htlog,.htconfig.php} + + echo "Restored hub to snapshot $COMMIT" + echo "Removing temporary files..." + + rm -rf "$RESTOREDIR" + + exit 0 + diff --git a/doc/pl/admins.bb b/doc/pl/admins.bb new file mode 100644 index 000000000..e27b3ae73 --- /dev/null +++ b/doc/pl/admins.bb @@ -0,0 +1,15 @@ +[h2]Dokumentacja dla administratorów huba[/h2] +[h3]Wdrozenie swojego huba[/h3] +[zrl=[baseurl]/help/install]Instalacja[/zrl] +[zrl=[baseurl]/help/red2pi]Instalowanie $Projectname na Raspberry Pi[/zrl] +[zrl=[baseurl]/help/Hubzilla_on_OpenShift]$Projectname na OpenShift[/zrl] +[h3]Utrzymywanie swojego huba[/h3] +[zrl=[baseurl]/help/troubleshooting]Wskazówki dotyczące rozwiązywania problemów[/zrl] +[zrl=[baseurl]/help/theme_management]Zarządzanie motywami[/zrl] +[zrl=[baseurl]/help/hidden_configs]Poprawianie ukrytych konfiguracji $Projectname[/zrl] +[zrl=[baseurl]/help/service_classes]Klasy usługi[/zrl] +[zrl=[baseurl]/help/directories]Praca z katalogami i ich konfigurowanie[/zrl] +[h3]Najczęściej zadawane pytania[/h3] +[zrl=[baseurl]/help/faq_admins]FAQ dla administratorów[/zrl] + +#include doc/macros/main_footer.bb; diff --git a/doc/pl/bugs.bb b/doc/pl/bugs.bb new file mode 100644 index 000000000..de1ed03a5 --- /dev/null +++ b/doc/pl/bugs.bb @@ -0,0 +1,31 @@ +[h2]Błędy, problemy i rzeczy, które pojawiają się w nocy ...[/h2] +[h3]Coś poszło nie tak! Kto jest odpowiedzialny za naprawianie tego?[/h3] + +[b]$Projectname Community Server[/b] + +$Projectname Community Server to oprogramowanie typu Open Source, które jest utrzymywane przez "społeczność" - zasadniczo nieopłacanych ochotników. Nikt nie jest odpowiedzialny za naprawianie błędów. Pracujemy razem, aby oprogramowanie i sieć działały płynnie i bez błędów. Jesteś członkiem tej społeczności, więc potrzebujemy również Twojej pomocy, aby zapewnić wysokiej jakości oprogramowanie. Nie ma mitycznych "programistów", którzy w magiczny sposób wszystko naprawiają. Do nas wszystkich należy włączenie się i pomoc. + +Pierwszą rzeczą, którą musisz zrobić, jest porozimieć się z administratorem huba - osobą, która obsługuje Twoją witrynę i zarządza nią. Znajdują się ona w wyjątkowej sytuacji, ponieważ ma dostęp do wewnętrznego oprogramowania i bazy danych oraz [b]plików dziennika[/b] i będzie musiała zaangażować się w naprawę problemu. Inne osoby "w sieci" nie mogą naprawdę Ci tym pomóc. Pierwszą rzeczą, jaką musi zrobić administrator huba, jest przejrzenie dzienników i podjecie próby odtworzenia problemu. Dlatego staraj się być tak pomocny i uprzejmy, jak to tylko możliwe, pomagając mu przyjrzeć się problemowi. + +Aby znaleźć swojego administratora huba (jeśli nie wiesz, kim on jest), zajrzyj na [url=[baseurl]/siteinfo]tą stronę[/url]. Jeśli nie podał on żadnych informacji kontaktowych na tej stronie lub nie podał "Impressum", zobacz [url=[baseurl]/siteinfo.json]podsumowanie informacji o tej witrynie[/url] znajdujące się pod nagłówkiem "admin:". + +Zdecydowanie zaleca się, aby administratorzy huba wypełniali raporty o błędach, tak aby możliwe było dołączenie odpowiedniego plik dziennika i informacji z bazy danych istotnych dla problemu oraz aby byli oni gotowi do wypróbowania rozwiązań i testów uzupełniających. Bez tego poziomu współpracy rozwiązanie problemu może nie być możliwe. + +[h3]Jestem administratorem huba, co mam zrobić?[/h3] + +Oprogramowania zapewniające tą usługę sieciową jest typu Open Source i jest dostępne do wglądu. Zachęcamy wszystkich do zapoznania się z kodem i zobaczenia, jak wszystko działa i sprawdzenia, czy nie robimy nic złego lub niedbałego. Jeśli został zgłoszony komunikat o błędzie, często można przeszukać pliki źródłowe tego komunikatu o błędzie i dowiedzieć się, co go spowodowało. Dzięki tym informacjom i plikom dziennika serwisu możliwe będzie ustalenie sekwencji zdarzeń prowadzących do błędu. Problem mogą powodować również serwisy zewnętrzne i jego źródłem wcale nie musi być Twój serwis, ale inne miejsce w sieci. Spróbuj określić punkty końcowe komunikacji (huby lub serwisy), których dotyczy problem i skontaktuj się z administratorem tego serwisu lub tych serwisów. Spróbuj podać czas zdarzenia, w którym coś poszło nie tak, aby można go było znaleźć w dziennikach. Współpracuj z innymi administratorami, aby spróbować znaleźć przyczynę problemu. Pliki dziennika są Twoim przyjacielem. Kiedy w oprogramowaniu dzieje się coś, czego się nie spodziewaliśmy, prawie zawsze zostało to zarejestrowane. + +[h3]Biały ekran śmierci[/h3] + +Jeśli podczas robienia czegoś pojawia się pusty biały ekran, prawie zawsze jest to błąd kodu lub składni. W pliku .htconfig.php serwisu znajdują się instrukcje, które pozwolą administratorowi witryny na włączenie rejestrowania składni. Zalecamy wszystkim witrynom korzystanie z tego. Po włączeniu rejestrowania składni powtórz sekwencję, która doprowadziła do błędu, a powinna ona zarejestrować nieprawidłową linię kodu. Mamy nadzieję, że dzięki tym informacjom uda Ci się rozwiązać problem. Gdy to zrobisz, prześlij poprawkę "upstream", abyśmy mogli udostępnić poprawkę pozostałym członkom projektu i innym społecznościom. To jest kluczowa zaleta korzystania z oprogramowania Open Source - dzielimy się mim wszyscy. + +[h3]Jestem głupi. Nie wiem, co jest nie tak.[/h3] + +W tej sytuacji warto omówić tę kwestię na jednym z forów internetowych. Może być ich kilka, a niektóre mogą bardziej pasować do Twojego ojczystego języka. W tej chwili kanał "Hubzilla Support" (support@zotadel.net) jest zalecanym forum do omawiania błędów. + +Jeśli członkowie społeczności z wykształceniem i doświadczeniem w zakresie inżynierii oprogramowania nie mogą Ci od razu pomóc, zrozum, że są wolontariuszami i mogą mieć dużo innej pracy i zobowiązań w tym czasie. W tym momencie musisz zgłosić błąd. Aby to zrobić, będziesz potrzebować konta na framagit.org. Zarejestruj się, a następnie odwiedź https://framagit.org/hubzilla/core/issues. Utwórz tutaj problem i podaj wszystkie te same informacje, które podałeś online. Nie pomijaj niczego. + +Następnie musisz zaczekać. Jeśli jest to poważny problem, może zostać szybko rozwiązany, ale nikt nie jest odpowiedzialny za naprawianie błędów. Jeśli problem utrzymuje się bez rozwiązania, poświęć trochę czasu na zbadanie samemu problemu. Zapytaj o wszystko, czego nie rozumiesz a co jest związane z tym problemem. Dowiesz się więcej o tym, jak działa oprogramowanie i prawdopodobnie dowiesz się, dlaczego teraz nie działa. Ostatecznie to ktoś w społeczności ma zamiar to naprawić, a ty jesteś członkiem społeczności. Tak właśnie działa proces Open Source. + +Inne osoby pracujące nad rozwiązaniem problemu mogą potrzebować dowiedzieć się więcej, więc odrób swoją pracę domową i udokumentuj, co się dzieje i wszystko, czego próbowałeś. Nie mów "Zrobiłem xyz i to nie działa". To nam nic nie mówi. Powiedz nam dokładnie, jakie kroki podjąłeś i jaki był rezultat, a także co się w rezultacie wydarzyło. Jaką stronę (URL) przeglądałeś lub jaki formularz wypełniałeś? Jeśli były jakieś komunikaty o błędach, nie mów "wystąpił komunikat o błędzie". Powiedz nam dokładnie, o czym była wiadomość. Powiedz nam również, z jakiego huba korzystasz, jakiej wersji oprogramowania używasz i wszelkie inne szczegóły, które mogą być unikalne na temat konfiguracji Twojej witryny. Rozumie się, że możesz chcieć zachować prywatność niektórych informacji i swoich połączeń, jednak jeśli nie chcesz udostępniać informacji potrzebnych innym osobom do odtworzenia i rozwiązania problemu, może on nie zostać naprawiony. + diff --git a/doc/pl/general.bb b/doc/pl/general.bb new file mode 100644 index 000000000..0dc15ea91 --- /dev/null +++ b/doc/pl/general.bb @@ -0,0 +1,18 @@ +[h2]Informacja o projekcie i serwisie[/h2] +[h3]$Projectname[/h3] +[zrl=[baseurl]/help/Privacy]Polityka prywatności[/zrl] +[zrl=[baseurl]/help/project/governance]Zarządzanie projektem[/zrl] +[zrl=[baseurl]/help/contributor/convenant]Porozumienie projektowe i kodeks postępowania[/zrl] + +[h3]Źródła zewnętrzne[/h3] +[zrl=[baseurl]/help/external-resource-links]Wykaz zasobów zewnętrznych[/zrl] +[url=https://framagit.org/hubzilla/core/]Główna witryna internetowa[/url] +[url=https://framagit.org/hubzilla/addons]Witryna dodatków[/url] +[url=[baseurl]/help/credits]Podziękowania od $Projectname[/url] +[h3]O tym hubie $Projectname[/h3] +[zrl=[baseurl]/help/TermsOfService]Warunki świadczenia usług dla tego huba[/zrl] +[zrl=[baseurl]/siteinfo]Inormacja o hubie (/siteinfo)[/zrl] +[zrl=[baseurl]/siteinfo/json]Szczegółowe informacje techniczne w formacie JSON(/siteinfo/json)[/zrl] + +#include doc/macros/main_footer.bb; + diff --git a/doc/pl/main.bb b/doc/pl/main.bb new file mode 100644 index 000000000..24caa1453 --- /dev/null +++ b/doc/pl/main.bb @@ -0,0 +1,20 @@ +[img][baseurl]/images/hubzilla-banner.png[/img] + +[zrl=[baseurl]/help/about]Co to jest $Projectname?[/zrl] +$Projectname to bezpłatny i otwartoźródłowy zestaw aplikacji i usług internetowych działających na specjalnym serwerze internetowym, zwanym "hubem", który może łączyć się z innymi hubami w sfederalizowanej sieci internetowej. + +[zrl=[baseurl]/help/features]Możliwości $Projectname[/zrl] +$Projectname zapewnia użytkownikom zaawansowaną komunikację, tożsamości i usług kontroli dostępu, które bezproblemowo współpracują w różnych domenach i niezależnych witrynach internetowych. Pozwala użytkownikom [b]publicznie[/b] lub [b]prywatnie[/b] publikować treści za pośrednictwem "kanałów" (ang. channel), które są podstawowymi, zabezpieczonymi kryptograficznie tożsamościami zapewniającymi uwierzytelnianie niezależnie od hubów, które je hostują. To rewolucyjne wyzwolenie tożsamości online z poszczególnych serwerów i domen jest nazywane "tożsamością nomadyczną" i jest oparte na protokole Zot, nowej strukturze zdecentralizowanej kontroli dostępu ze szczegółowymi, rozszerzalnymi uprawnieniami. +Z praktycznego punktu widzenia członków danego huba, korzystających z oprogramowania $Projectname, oferuje ono szereg znanych, zintegrowanych aplikacji i usług internetowych, w tym: +[ul] +[li]wątki dyskusyjne w sieciach społecznościowych[/li] +[li]przechowywanie plików w chmurze[/li] +[li]kalendarz i kontakty (z obsługą CalDAV i CardDAV)[/li] +[li]hosting stron internetowych z systemem zarządzania treścią[/li] +[li]wiki[/li] +[li]i dużo więcej ...[/li][/ul] +Chociaż wszystkie te aplikacje i usługi można znaleźć w innych pakietach oprogramowania, tylko $Projectname pozwala ustawić uprawnienia dla grup i osób, [b]które mogą nawet nie mieć kont na Twoim hubie[/b]! W typowych aplikacjach internetowych, jeśli chcesz udostępniać rzeczy prywatnie w Internecie, osoby, którym udostępniasz dane, muszą mieć konta na serwerze, na którym znajdują się Twoje dane; w przeciwnym razie serwer nie może uwierzytelniać odwiedzających witrynę, aby wiedzieć, czy przyznać im dostęp. $Projectname rozwiązuje ten problem za pomocą zaawansowanego systemu zdalnego uwierzytelniania, który weryfikuje tożsamość odwiedzających, wykorzystując techniki obejmujące kryptografię klucza publicznego. +Dzięki oferowanym aplikacjom, $Projectname świetnie się nadaje do budowy platformy komunikacyjno-publikacyjnej o charkterze społecznościowym dla realnych grup społecznych, takich jak rodziny, lokalne grupy, organizacje społeczne, środowiska szkolne, wspólnoty mieszkańców czy wspólnoty religijne. + +[zrl=[baseurl]/help/what_is_zot]Co to jest Zot?[/zrl] +Jest to nowy protokół, oparty na JSON, do wdrażania bezpiecznej, zdecentralizowanej komunikacji i usług. Różni się od wielu innych protokołów komunikacyjnych, budując komunikację na podstawie zdecentralizowanej struktury tożsamości i uwierzytelniania. Składnik uwierzytelniania jest koncepcyjnie podobny do OpenID, ale jest odizolowany od tożsamości opartej na DNS. Tam, gdzie to możliwe, zdalne uwierzytelnianie jest ciche i niewidoczne. Zapewnia to mechanizm kontroli dostępu rozproszonego na skalę sieci WWW, który jest dyskretny. diff --git a/doc/pl/member/assets/qr_text_to_post.png b/doc/pl/member/assets/qr_text_to_post.png new file mode 100644 index 000000000..887c85492 Binary files /dev/null and b/doc/pl/member/assets/qr_text_to_post.png differ diff --git a/doc/pl/member/assets/zat_dialog.png b/doc/pl/member/assets/zat_dialog.png new file mode 100644 index 000000000..892964e95 Binary files /dev/null and b/doc/pl/member/assets/zat_dialog.png differ diff --git a/doc/pl/member/bbcode.html b/doc/pl/member/bbcode.html new file mode 100644 index 000000000..655c021ee --- /dev/null +++ b/doc/pl/member/bbcode.html @@ -0,0 +1,343 @@ + +

      Informator o BBCode

      +

      +W Hubzilla stosowana jest własna odmiana BBCode. Niniejszy informator jest +treściwym opisem składni tej odmiany BBCode. +

      + +

      Dekracja tekstu

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Składnia BBcodeTekst formatowany
      [b]pogrubiony[/b]pogrubiony
      [i]pochyły[/i]pochyły
      [u]podkreślony[/u]podkreślony
      [s]przekreślony[/s]przekreślony
      [color=red]czerwony[/color]czerwony
      [hl]podświetlony[/hl]podświetlony
      [font=courier]jaiś tekst[/font] jakiś tekst
      [quote]cytat[/quote]
      cytat
      [quote=Author]Autor? Ja? Nie, nie, nie...[/quote]Autor napisał:
      Autor? Ja? Nie, nie, nie...
      + [size=small]tekst mały (small)[/size]
      + [size=xx-large]tekst wielki (xx-large)[/size]
      + [size=20]tekst z czcionką 20px[/size]
      +
      + Opcje rozmiaru obejmują: xx-small, small, medium, large, xx-large
      tekst mały (small)
      tekst wielki ()xx-large)
      tekst z czcionką 20px
      Dodanie poziomego paska +[hr] +Tak jak to + + Dodanie poziomego paska


      Tak jak to +
      To jest +[center]wyśrodkowany[/center] +tekst + To jest
      wyśrodkowany

      tekst +
      + +

      Bloki kodu

      +Kod można renderować generalnie w formacie blokowym lub wbudowanym (w zależności od tego, czy w tekście znajdują się znaki nowego wiersza) lub można określić obsługiwany język dla rozszerzonego podświetlania składni. Podświetlanie składni wymaga odpowiedniej wtyczki renderującej, takiej jak hilite. Obsługiwane języki z wtyczką hilite to php, css, mysql, sql, abap, diff, html, perl, ruby, vbscript, avrc, dtd, java, xml, cpp, python, javascript, js, json, sh. +

      +Jeśli wtyczka renderująca nie jest zainstalowana lub określono nieobsługiwany język, dane wyjściowe bloków kodu z podświetleniem składni są takie same, jak znacznik kodu formatu bloku. +

      + + + + + + + + + + + + + + + +
      Składnia BBcodeWyjście
      [code]funkcja bbcode() { }[/code]funkcja bbcode() { }
      [code=php]funkcja bbcode() {
      + $variable = true;
      + if( $variable ) {
      + echo "true";
      + }
      +}[/code]
      1.  function bbcode() {
      2.    $variable = true;
      3.    if( $variable ) {
      4.      echo "true";
      5.    }
      6.  }
      [nobb][nobb]W ten sposób [i]możesz[/i] +[u]pokazać[/u] jak użyć składnię +[hl]BBcode[/hl][/nobb][/nobb][nobb]W ten sposób [i]możesz[/i] [u]pokazać[/u] jak uzyć składnię []hl]BBcode[/hl][/nobb]
      + +

      Listy

      + + + + + + + + + + + + + + + + + + +
      Składnia BBcodeWyrenderowana lista
      [ul]
      +[*] Pierwszy element listy
      +[*] Drugo element listy
      +[/ul]
      • Pierwszy element listy
      • Drugi element listy
      [ol]
      +[*] Pierwszy element listy
      +[*] Drugi element listy
      +[/ol]
      • Pierwszy element listy
      • Drugi element listy
      [list=A]
      +[*] Pierwszy element listy
      +[*] Drugi element listy
      +[/list]
      + Elementami listy są 1, i, I, a, A.
      • Pierwszy element listy
      • Drugi element listy
      [dl terms="b"]
      +[*= Pierwsze hasło] Opis pierwszego hasła
      +[*= Drugie hasło] Opis drugiego hasła
      +[/dl]
      + Opcje stylu hasła mogą być kombinacją tekstu: +
      +
      b
      z czcionką bold
      +
      i
      z czcionką italic
      +
      u
      z czcionką underline
      +
      m
      z czcionką monospace
      +
      l
      z czcionką large
      +
      h
      poziomego — tak jak tta lista definicyjna
      +
      +
      +
      Pierwsze hasło
      Opis pierwszego hasła
      +
      Drugie hasło
      Opis drugiego hasła
      + +

      Tabele

      + + + + + + + + + + + + + + + + +
      Składnia BBcodeWyrenderowana tabela
      [table border=0]
      +[tr]
      +[th]Nagłówek 1[/th][th]Nagłówek 2[/th]
      +[/tr]
      +[tr][td]Treść[/td][td]Treść[/td][/tr]
      +[tr][td]Treść[/td][td]Treść[/td][/tr]
      +[/table]
      +
      Nagłówek 1Nagłówek 2
      ContentContent
      TreśćTreść
      [table border=1]
      +[tr]
      +[th]Nagłówek 1[/th][th]Nagłówek 2[/th]
      +[/tr]
      +[tr][td]Treść[/td][td]Treść[/td][/tr]
      +[tr][td]Treść[/td][td]Treść[/td][/tr]
      +[/table]
      +
      Nagłówek 1Nagłówek 2
      ContentContent
      TreśćTreść
      [table]
      +[tr]
      +[th]Nagłówek 1[/th][th]Nagłówek 2[/th]
      +[/tr]
      +[tr][td]Treść[/td][td]Treść[/td][/tr]
      +[tr][td]Treść[/td][td]Treść[/td][/tr]
      +[/table]
      Nagłówek 1Nagłówek 2
      TreśćTreść
      TreśćTreść
      +
      + +

      Odnośniki i treść osadzona

      + + + + + + + + + + + + + + + + +
      Składnia BBcodeWyjście
      [video]URL wideo[/video]
      +[audio]URL audio[/audio]
      [url=https://hubzilla.org]Hubzilla[/url]Hubzilla
      Obraz [img]https://example.org/image.jpg[/img] +w jakimś tekście + Obraz Image/photo w jakimś tekście +
      + + +

      Kod specyficzny dla $Projectname

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Składnia BBcodeWyjście
      Wersja tagu [url] wykorzystująca magiczne uwierzytelnianie + [zrl=https://hubzilla.org]Link rozpoznający tożsamość[/zrl] + https://hubzilla.org/?zid=[observer=1][observer.address][/observer][observer=0]your_channel@your.home.hub[/observer]
      Wersja tagu [img] wykorzystująca magiczną uwierzytelnianie + [zmg]https://hubzilla.org/some/photo.jpg[/zmg] + Obraz jest widoczny tylko dla osób uwierzytelnionych i za zgodą właściciela kanału.
      Wyjście zależne od obserwatora: + [nobb][observer=1]Tekst do wyświetlenia, jeśli obserwator JEST uwierzytelniony[/observer][/nobb] +
      + + [nobb][observer=0]Tekst wyświetlany, jeśli obserwator NIE JEST uwierzytelniony[/observer][/nobb] + +
      + + [nobb][observer.language=en]Tekst wyświetlany, jeśli językiem obserwatora jest angielski[/observer][/nobb] + +
      + + [nobb][observer.language!=de]Tekst wyświetlany, jeśli językiem obserwatora nie jest język niemiecki[/observer][/nobb] + +
      + + [nobb][observer.url][/nobb] + + adres URL kanału obserwatora
      + + [nobb][observer.baseurl][/nobb] + + witryna WWW obserwatora
      + + [nobb][observer.name][/nobb] + + nazwa obserwatora
      + + [nobb][observer.webname][/nobb] + + krótka nazwa w adresie URL obserwatora
      + + [nobb][observer.address][/nobb] + + adres (ZOT-id) obserwatora
      + + [nobb][observer.photo][/nobb] + + zdjęcie profilowe obserwatora
      Co to jest spoiler?
      + [spoiler]Tekst, który chcesz ukryć.[/spoiler]
      + Co to jest spoiler? +
      [toc data-toc='div.page-body' data-toc-headings='h1,h2']
      +Utwórz spis treści na stronie internetowej lub stronie wiki. Proszę zapoznać się z oryginalnym widżetem TOC jQuery aby uzyskać więcej informacji. +
        +
      • Opcjonalny parametr: 'data-toc'. Jeśli pominięty, domyślną wartością jest „body”
      • +
      • Opcjonalny parametr: 'data-toc-headings'. Jeśli pominięty, wartość domyślna to „h1, h2, h3”
      • +
      [nobb][rpost=title]Tekst do publikacji[/rpost][/nobb]
      +Obserwator wróci do swojego macierzystego huba, aby wprowadzić post z określonym tytułem i treścią. Obie opcje są opcjonalne
      [baseurl]/rpost?f=&title=title&body=Text+to+post
      Wymaga to wtyczki qrator.
      [qr]tekst do publikacji[/qr]
      Wymaga to odpowiedniej wtyczki mapy, takiej jak openstreetmap. + [map]Wygenerowanie wbudowanej mapy przy użyciu aktualnych współrzędnych plakatu w przeglądarce, jeśli lokalizacja przeglądarki jest włączona
      Wymaga to odpowiedniej wtyczki mapy, takiej jak openstreetmap. + [map=latitude,longitude]Wygenerowanie mapy przy wykorzystaniu współrzędnych globalnych.
      Wymaga to odpowiedniej wtyczki mapy, takiej jak openstreetmap. + [map]Nazwa miejsca[/map] +Wygenerowanie mapy dla podanej nazwanej lokalizacji. Zwracana jest pierwsza pasująca lokalizacja. Na przykład „Sydney” zazwyczaj zwraca Sydney w Australii, a nie Sydney w Nowej Szkocji w Kanadzie, chyba że określono dokładniejszą lokalizację. Zdecydowanie zalecamy skorzystanie z narzędzia podglądu posta, aby upewnić się, że masz prawidłową lokalizację przed wysłaniem postu. +
      [&copy;] ©
      diff --git a/doc/pl/member/member_faq.bb b/doc/pl/member/member_faq.bb new file mode 100644 index 000000000..1da05ef92 --- /dev/null +++ b/doc/pl/member/member_faq.bb @@ -0,0 +1,11 @@ +[h3]Najczęściej zadawane pytania[/h3] +[h4]Mogę edytować tekst postu po jego zapisaniu, ale czy istnieje sposób na zmianę uprawnień?[/h4] +Krótka odpowiedź: Nie, nie ma takiej mozliwości. Są ku temu istotne powody. Możesz zmienić uprawnienia do swoich plików, zdjęć i polubień, ale nie do postów po ich zapisaniu. Główny powód jest taki, że po zapisaniu posta jest on rozpowszechniony albo na kanał publiczny, a stamtąd na inne serwery $Projectname albo do tych, do których miał trafić. Tak jak nie możesz odzyskać czegoś, co dałeś innej osobie, nie możesz zmienić uprawnień do postów w $Projectname. Musielibyśmy śledzić wszędzie, gdzie trafia Twój wpis, śledzić wszystkich, którym pozwoliłeś go zobaczyć, a następnie śledzić, od kogo go usunąć. +Jeśli post jest publiczny, jest to jeszcze trudniejsze, ponieważ $Projectname to globalna sieć i nie ma możliwości śledzenia posta, nie mówiąc już o jego niezawodnym odzyskaniu. Inne sieci, które mogą otrzymały Twój post, nie mają niezawodnego sposobu usunięcia lub odzyskania posta. +[h4]Pobrałem swój kanał i zaimportowałem go (sklonowałem swoją tożsamość) do innej witryny, ale nie ma treści, postów ani zdjęć. Co jest nie tak???[/h4] +Posty i zdjęcia oraz inne pliki są dostarczane niezależnie od podstawowych informacji o kanale. Wynika to z ograniczeń pamięci związanych z przechowywaniem rozmów i archiwizowania zdjęć. Wpisy i rozmowy mogą być synchronizowane niezależnie od podstawowych informacji o kanale. Zdjęcia i archiwa plików można przesyłać za pomocą wtyczki, takiej jak „redfiles”, która obecnie jest oznaczona jako „eksperymentalna”. Tworząc tę funkcję, pomyśleliśmy, że najważniejsze jest zachowanie wszystkich kontaktów. Twoi znajomi widzieli już Twoje stare treści. Posty i rozmowy miały następny priorytet i można je teraz synchronizować. Pliki i zdjęcia są ostatnim elementem, który całkowicie działa. Kiedy znajdziemy kogoś chętnego do zakończenia wdrażania tego, będzie to zrobione. :) +[h4]Nie widzę zasobów prywatnych[/h4] +Prawdopodobnie wyłączone są pliki cookie stron trzecich. Musisz je włączyć, aby zdalne uwierzytelnianie działało. +[h4]Jest wiele obcojęzycznych postów. Przetłumaczmy je automatycznie.[/h4] +Istnieje również wiele [b]prywatnych[/b] obcojęzycznych postów, ale usługi automatycznego tłumaczenia wymagałyby od nas przekazywania tych prywatnych wiadomości do usługi tłumaczeniowej. Nie wiemy, jak zostaną one wykorzystane na tych serwisach. Właściwie to wiemy, dzięki Edwardowi Snowdenowi. Naszym najlepszym rozwiązaniem jest projekt o nazwie [b][i]Apertium[/i][/ b], który jest tłumaczem open source, który możemy zainstalować lokalnie. Obecnie brakuje tłumaczeń na język niemiecki - które są najczęściej żądanymi tłumaczeniami w matrycy. Po raz kolejny zostanie to zrealizowane, gdy znajdziemy kogoś, kto naprawdę chce, aby to się stało. + diff --git a/doc/pl/member/member_guide.bb b/doc/pl/member/member_guide.bb new file mode 100644 index 000000000..5a80c6510 --- /dev/null +++ b/doc/pl/member/member_guide.bb @@ -0,0 +1,1028 @@ +[h3]Przegląd[/h3] + +Chociaż wiele funkcji i możliwości Hubzilli jest znanych osobom, które korzystały z serwisów społecznościowych i oprogramowania do blogowania, istnieje również sporo nowych koncepcji i funkcji, z którymi większość osób wcześniej się nie zetknęła. Niektóre z nowych pomysłów są związane ze zdecentralizowanym charakterem sieci; inne są związane z zaawansowanym systemem uprawnień, który jest niezbędny do ochrony prywatności danych. Celem tego przewodnika jest pomóc w zrozumieniu, jak tworzyć, konfigurować i używać tożsamość nomadyczną. + +[h3]Rejestracja[/h3] + +Nie wszystkie serwisy oparte na $Projectname umożliwiają otwartą rejestrację. Jeśli rejestracja jest dozwolona, zobaczysz łącze "Rejestracja" bezpośrednio pod formularzem logowania na stronie głównej serwisu. Kliknięcie tego linku przeniesie Ciebie do strony rejestracyjnej. W niektórych serwisach. link ten może przekierować do innej witryny, która umożliwia rejestrację. Ponieważ wszystkie serwisy Hubzilla są połączone, nie ma znaczenia, gdzie znajduje się Twoje konto. + +[b]Twój ades e-mail[/b] + +Proszę o wprowadzenie poprawnego adresu e-mail. Twój adres e-mail nigdy nie jest publikowany. Ten adres będzie używany do aktywacji konta, do ewentualnego wysyłania powiadomień o przychodzących wiadomościach lub wpisach oraz do odzyskiwania utraconych haseł. + +[b]Hasło[/b] + +Wprowadź wybrane hasło i powtórz je w drugim polu, aby upewnić się, że zostało wpisane poprawnie. Ponieważ Hubzilla oferuje zdecentralizowaną tożsamość, Twoje konto może zalogować Cię do wielu innych serwisów internetowych sieci Hubzilla. + +[b]Regulamin serwisu[/b] + +Kliknij to łącze, aby przeczytać dokument [zrl=[baseurl]/help/TermsOfService]Regulamin serwisu[/zrl]. Po ich przeczytaniu zaznacz pole w formularzu rejestracyjnym, aby to potwierdzić. + +[b]Rejestracja[/b] + +Po podaniu niezbędnych informacji, kliknij przycisk „Zarejestruj się”. Niektóre serwisy mogą wymagać zatwierdzenia rejestracji przez administratora, zanim zostanie ona przetworzona, o czym osoba rejestrująca się zostanie powiadomiona. Trzba więc śledzić swoją pocztę e-mail (w tym folder ze spamem) w celu potwierdzenia rejestracji. + +[h3]Kanały[/h3] + +[h4][b]Co to są kanały?[/b][/h4] + +Kanały to zbiory treści powiązane z profilem. Kanał może mieć różną formę. Może reprezentować Ciebie (kanał osobisty), być witryną internetową, forum, albumem ze zdjęciami, czymkolwiek. Dla większości osób pierwszym kanałem jest kanał osobisty, reprezentujący tą osobę. + +Najważniejsze cechy kanału, który reprezentuje "Ciebie", to: +[ul] +[*]Bezpieczna i prywatna komunikacja "wolna od spamu" + +[*]Tożsamość i "pojedyncze logowanie" w całej sieci Hubzilla; + +[*]Kotrola prywatności i uprawnienia, które obejmują całą sieć; + +[*]Usugi katalogowe (np. Książka telefoniczna). +[/ul] +Krótko mówiąc, kanał, który reprezentuje Ciebie, "opisuje Ciebie w internecie". + +[h4][b]Uprawnienia w kanale oparte na rolach[/b][/h4] + +W celu uproszczenia zarządzaniem uprawnieniami w kanałach, w Hubzilla wprowadzono "role uprawnieniowe". Podczas tworzenia nowego kanału użytkownik jest proszony o wybranie roli jaką ma pełnić kanał. Z każdą z takich ról związany jest zestaw uprawnień. Najpopularniejszą rolą uprawnień jest rola sieci społecznościowej. Ma się wiele innych możliwości, dzięki opcjom, które są analogiczne do grup i stron na Facebooku, przestrzeni współpracy, kanałów aktualności (RSS) i nie tylko. Te role automatycznie konfigurują kilka różnych zmiennych systemowych, od uprawnień przyznanych znajomym, po domyślne ustawienia prywatności i opcje widoczności. Dostępne są zaawansowane konfiguracje, które umożliwiają dostosowanie każdego z tych parametrów do własnych potrzeb. Stwierdziliśmy jednak, że większość ludzi woli "ustawić i zapomnieć". Dalej opisano niektóre z różnych ról, które są obecnie dostępne oraz ich wpływ na prywatność uzytkownika i zdolność do interakcji. + +[h5][b]Kanał społecznościowy[/b][/h5] + +[b]- federacyjny[/b] + +Kanał tego rodzaju jest bardzo liberalnym profilem społecznościowym, który jest kompatybilny z innymi federacyjnymi sieciami społecznościowymi. Zasady zezwoleń są podobne do Twittera i w większości zgodne z Diasporą i Mastodonem. Prywatność ma niższy priorytet niż łatwość dostępu i łączenia się z innymi. Każdy w sieci Fediverse może komentować Twoje publiczne wpisy i wysyłać Ci prywatną pocztę. Domyślnie posty i inne publikowane elementy są publiczne, ale można do nich ograniczyć dostęp przy ich tworzeniu. Jesteś wymieniony w katalogu. Twoja obecność w Internecie i połączenia są widoczne dla innych. Ten tryb może zwiększyć narażenie na niepożądaną komunikację i spam. Rola ta nie jest ogólnie zalecana, chyba że musisz regularnie kontaktować się z członkami innych sieci. + +[b]- przeważnie publiczny[/b] + +Kanał jest typowym profilem społecznościowym. Twoje wpisy i opublikowane elementy są domyślnie publiczne, ale możesz to zmienić podczas tworzenia elementu i ograniczyć dostęp do niego. Jesteś wymieniony w katalogu. Twoja obecność w Internecie i połączenia są widoczne dla innych. Tylko osoby z bezpośrednich kontaktów mogą komentować Twoje publiczne wpisy i wysyłać Ci prywatną pocztę. Zasady pozwoleń są podobne do Facebooka. + +[b]- ograniczony[/b] + +Domyślnie wszystkie wpisy i opublikowane elementy są wysyłane do prywatnej grupy prywatności "Znajomi" i nie są upubliczniane. Do tej grupy prywatności są dodawani nowi znajomi. Jeśli chcesz, możesz to zmienić i utworzyć publiczny wpis lub inny publicznie dostępny element. Jesteś wymieniony w katalogu. Twoja obecność online (na czacie) i Twoje kontakty (znajomi) są widoczne dla przeglądających Twój profil. + +[b]- prywatny[/b] + +Domyślnie wszystkie wpisy i opublikowane elementy są wysyłane do grupy prywatności "Znajomi". Do tej grupy dodawani są Twoi nowi znajomi. Możesz to zmienić i utworzyć publiczny wpis lub inny element publiczny, jeśli chcesz. NIE jesteś wymieniony w katalogu. Tylko osoby z Twoich kontaktów mogą zobaczyć Twoje inne połączenia. Twoja obecność w Internecie jest ukryta. + + +[h5][b]Forum[/b][/h5] + +[b]- przeważnie publiczne[/b] + +Kanał typowy dla publicznego forum. Wpisy i publikowane elementy są domyślnie publiczne. Członkowie mogą publikować przez "!wzmiankę" lub wpis pełny. Zablokowane jest publikowanie zdjęć i innych elementów. Kanał jest widoczny w katalogu. Członkowie są dodawani automatycznie. + +[b]- ograniczone[/b] + +Domyślnie wszystkie wpisy i opublikowane elementy są wysyłane do grupy prywatności "Znajomi" kanału. Do tej grupy dodawani są nowi znajomi. Członkowie mogą publikować przez "!wzmiankę" lub wpis pełny, ale wpisy i odpowiedzi mogą być również widoczne dla innych odbiorców wpisów najwyższego poziomu, którzy nie są członkami. Kanał jest widoczny w katalogu. Członkowie muszą być ręcznie dodani przez właściciela forum. + +[b]- prywatne[/b] + +Domyślnie wszystkie wpisy i opublikowane elementy są wysyłane do grupy prywatności "Znajomi". Do tej grupy dodawani są nowi znajomi. Właściciel może to zmienić i w razie potrzeby utworzyć publiczny wpis lub element publiczny. Członkowie tego nie mogą. NIE jesteś wymieniony w katalogu. Tylko osoby z Twoich kontaktów mogą zobaczyć Twoje inne połączenia. Twoja obecność w Internecie jest ukryta. Członkowie muszą być dodani ręcznie przez właściciela forum. Wysyłanie przez "!wzmiankę" jest wyłączone. Wpisy można publikować wyłącznie za pośrednictwem wpisów pełnych i wysyłać do członków grupy prywatności "Znajomi". Nie są oni publicznie widoczni. + +[h5][b]Kanał RSS[/b][/h5] + +[b]- publiczny[/b] + +Podobne do kanału społecznościowego - głównie publicznego, ale dostosowany do źródeł kanałów RSS. Elementy mogą być swobodnie publikowane i pozyskiwane. Obecność w Internecie jest bez znaczenia, dlatego jest ukryta. Nowe połączenia są automatycznie zatwierdzane. + + +[b]- ograniczony[/b] + +Kanał nie jest wymieniony w katalogu. Obecność w Internecie jest bez znaczenia, dlatego jest ukryta. Kanał jest publikowany tylko dla członków grupy prywatności "Przyjaciele". Nowe połączenia są automatycznie dodawane do tej grupy prywatności. Członkowie muszą zostać ręcznie zatwierdzeni przez właściciela kanału. + + +[h5][b]Kanał specjalny[/b][/h5] + +[b]- celebrycki lub mównica[/b] + +Autorzy są wymienieni w katalogu. Komunikaty są domyślnie publiczne. Obecność w Internecie jest ukryta. Nie wolno komentować ani odpisywać w jakiejkolwiek formie, chociaż odwiedzający mogą "polubić" profil autora. + + +[b]- repozytorium gupowe[/b] + +Forum publiczne, które umożliwia członkom publikowanie plików, zdjęć i stron internetowych. + +[h5][b]Tryb niestandardowy i ekspercki[/b][/h5] + +Prywatność i uprawnienia ustawia się ręcznie, aby dopasować je do swoich potrzeb. + + +[h4][b]Tworzenie kanałów[/b][/h4] + +Po utworzeniu konta zostanie wyświetlony ekran "Dodaj kanał". Zwykle pierwszym kanałem będzie ten, który reprezentuje Ciebie, więc użycie własnego imienia i nazwiska (lub pseudonimu) jako nazwy kanału jest dobrym pomysłem. Nazwę kanału należy traktować jako tytuł lub krótki opis kanału. Pole "Wybierz krótki pseudonim" jest podobne do pola "Nazwa użytkownika". Wykorzystamy wszystko, co tu wpiszesz, do utworzenia adresu kanału, którego będą używać inne osoby do łączenia się z Twoim kanałem, a Ty będziesz używać to do logowania się w innych witrynach. Wygląda to jak adres e-mail i ma postać [i]pseudonim@serwis_twojej_rejestracji.xyz[/i]. + +Możesz tworzyć dodatkowe kanały, korzystając z odnośnika "Menedżer kanałów". + +Gdy to zrobisz, Twój kanał będzie gotowy do użycia. Pod adresem [observer=1][observer.url][/observer][observer=0][baseurl]/channel/username[/observer] znajdziesz "strumień" swojego kanału. Tutaj pojawi się Twoja ostatnia aktywność w odwrotnej kolejności chronologicznej. Jeśli opublikujesz wpis w polu oznaczonym "udostępnij", wpis pojawi się u góry Twojego strumienia. Znajdziesz tu również linki do wszystkich innych obszarów komunikacji tego kanału. Menu z ikoną "hamburger" w większości motywów zapewnia nawigację do innych składników systemu i aplikacji. Strona "Zdjęcia" zawiera albumy ze zdjęciami, a strona "Wydarzenia" zawiera wydarzenia udostępnione przez Ciebie i Twoje kontakty. + +[h4][b]Profile[/b][/h4] + +W $Projectname użytkownik może mieć wiele profili. Można używać różnych profili, aby pokazać różne "strony siebie" różnym odbiorcom. Różni się to od posiadania różnych kanałów. Różne kanały pozwalają na przesyłanie zupełnie różnych zestawów informacji. Można mieć kanał dla siebie, kanał dla swojej drużyny sportowej, kanał dla swojej witryny internetowej lub cokolwiek innego. Profil pozwala na precyzyjne stopniowanie "aspektów" kanału. Na przykład Twój domyślny profil publiczny może mówić "Cześć, jestem Fred i lubię się śmiać". Możesz pokazać swoim bliskim znajomym profil z dopiskiem "i ja też lubię rzucać krasnoludami". + +Zawsze masz profil nazywany profilem "domyślnym" lub "publicznym". Ten profil jest zawsze ogólnodostępny i nie można go ukryć (mogą występować rzadkie wyjątki w witrynach uruchamianych prywatnie lub odłączonych). Można i raczej powinno się ograniczyć informacje, które udostępnia się w swoim profilu publicznym. + +Tak więc, jeśli chcesz, aby inni znajomi mogli Cię znaleźć, warto mieć następujące informacje w swoim profilu publicznym: + +[ul][*]Twoje prawdziwe imię i nazwisko lub przynajmniej pseudonim, który wszyscy znają; +[*]Twoje zdjęcie; +[*]Twoją lokalizacja, przynajmniej na poziomie kraju.[/ul] + +Ponadto, jeśli chcesz poznać osoby, które mają podobne zainteresowania, poświęć chwilę i dodaj do swojego profilu kilka "słów kluczowych". Na przykład "muzyka, linux, fotografia" lub cokolwiek innego. Możesz dodać dowolną liczbę słów kluczowych. + +Aby utworzyć alternatywny profil, najpierw przejdź do [zrl=[baseurl]/settings/features]Ustawienia > Dodatkowe funkcje[/zrl] i włącz tam opcję "Wiele profili", w przeciwnym razie nie będziesz mieć możliwości korzystania z więcej niż tylko profilu domyślnego. + +Następnie wybierz "Edytuj profile" z menu swojej witryny Hubzilla. Możesz edytować istniejący profil, zmienić zdjęcie profilowe, dodać rzeczy do profilu lub utworzyć nowy profil. Możesz także utworzyć "klon" istniejącego profilu, jeśli chcesz zmienić tylko kilka elementów, ale nie chcesz ponownie wprowadzać wszystkich informacji. Aby to zrobić, kliknij profil, który chcesz sklonować i wybierz tam "Klonuj ten profil". + +Na liście swoich profili możesz również wybrać kontakty, które mogą zobaczyć Twój dodatkowy profil. Wystarczy kliknąć "Edytuj widoczność" obok profilu (dostępne tylko dla profili, które nie są Twoim profilem domyślnym), a następnie kliknąć określone połączenia, aby je dodać lub usunąć z grupy osób, które mogą wyświetlać ten profil. + +Po wybraniu profilu osoba przeglądająca Twój profil zobaczy przypisany przez Ciebie profil prywatny. Jeśli nie są oni uwierzytelnieni, zobaczą Twój profil publiczny. + +Istnieje ustawienie, które pozwala opublikować swój profil w katalogu i zapewnić, że będzie można go znaleźć innym. Możesz zmienić to ustawienie na stronie "Ustawienia". + +Jeśli nie chcesz, aby Cię widziano w internecie, ustaw swój profil jako prywatny. + +[h4][b]Słowa kluczowe i wyszukiwanie w katalogu[/b][/h4] + +Na stronie katalogu możesz wyszukiwać osoby z opublikowanymi profilami. Obecnie przeszukiwane jest tylko pole nazwy i słowa kluczowe. Możesz również umieścić takie słowa kluczowe w swoim domyślnym profilu - które mogą być używane do wyszukiwania wspólnych zainteresowań z innymi członkami. Słowa kluczowe są używane w narzędziu propozycji kanałów i chociaż nie są widoczne w katalogu, są wyświetlane, gdy ktoś odwiedza stronę Twojego profilu. + +Na stronie "Połączenia" oraz w katalogu znajduje się odnośnik, odpowiednio do "Sugestii" lub "Propozycji kanałów". Pozwoli to znaleźć kanały, które mają pasujące lub podobne słowa kluczowe. Im więcej podasz słów kluczowych, tym trafniejsze będą wyniki wyszukiwania. Są one sortowane według trafności. + +Przecztaj też: + +[zrl=[baseurl]/help/pl/AdvancedSearch]Zaawansowane przeszukiwanie[/zrl] + +[h4][b]Siatka, uprawnienia i delegowanie[/b][/h4] + +Strona "Siatka" zawiera wszystkie najnowsze wpisy z całej sieci Hubzilla, wykazane w odwrotnej kolejności chronologicznej. Posty, które się tutaj pojawiają, zależą w dużej mierze od ustawionych przez siebie preferencji. Na najbardziej liberalnym poziomie uprawnień będziesz otrzymywać posty od zupełnie obcych osób. Na drugim końcu skali możesz zobaczyć wpisy tylko od znajomych - lub, jeśli czujesz się naprawdę niezainteresowany społecznością, tylko własne wpisy. + +Jak wspomniano na początku, możliwych jest wiele innych rodzajów kanałów, jednak procedura tworzenia jest taka sama. Różnica między kanałami polega przede wszystkim na przypisanych uprawnieniach. Na przykład kanał umożliwiający udostępnianie dokumentów współpracownikom w pracy prawdopodobnie wymagałby bardziej liberalnych ustawień "Może zapisywać w moim" publicznym "magazynie plików" niż na koncie osobistym. + +Możesz również przekazać kontrolę nad wpisami i połączeniami swoich kanałów, ale nie nad ich konfiguracjami, innemu kanałowi. Odbywa się to poprzez edycję połączenia i przypisanie mu uprawnień do administrowania zasobami Twojego kanału. + +[h3]Przyłączanie się do kanałów[/h3] + +Połączenie jest w $Projectname określane jako zestaw uprawnień, które nadało się komuś innemu do dostępu do swoich treści. W tradycyjnych aplikacjach sieci społecznościowych wszystkie połączenia mają takie same uprawnienia lub najwyżej dwa poziomy ("znajomi" i "obserwujący"). W Hubzilla można ustawić (dostosować) szereg oddzielnych uprawnień w zależności od sytuacji i relacji, jakie masz z innym kanałem. Możesz zezwolić komuś na wyświetlanie swoich postów, ale nie zdjęć. Możesz również odmówić im pozwolenia na komentowanie swoich postów lub wysyłanie prywatnych wiadomości do Ciebie. + +Jak przyłączyć się do jakiegoś kanału? + +Najpierw musisz znaleźć kanał, z którym chcesz się połączyć. Można to zrobić na dwa sposoby. Po pierwsze, ustaw opcję "Może przesyłać mi swój strumień i posty z kanału" na zezwoleniea dla "Wszystkich w tej sieci", co spowoduje dostęp do wpisów od zupełnie obcych osób do Twojej matrycy. Zapewni ci to dużo treści publicznych i miejmy nadzieję, że pomoże Ci znaleźć interesujących, zabawnych ludzi, fora i kanały. + +Następną rzeczą, jaką możesz zrobić, jest przejrzenie katalogu. Katalog jest dostępny w każdej witrynie Hubzilli, co oznacza, że wyszukiwanie z poziomu własnej witryny przyniesie wyniki z całej sieci. Możesz wyszukiwać według nazwy, zainteresowania, lokalizacji i słowa kluczowego. + +Jeśli znasz już czyjąś "webbie", możesz bezpośrednio się z tą osobą skontaktować. Webbie to identyfikator, który wygląda jak adres e-mail (na przykład bob@example.com), ale odnosi się do kogoś w otwartej sieci społecznościowej. Aby się połączyć, osoby te muszą używać kompatybilnego protokołu sieciowego. Domyślnie, nasze oprogramowanie obsługuje protokół "Zot", jednak dodatkowe protokoły mogą być dostarczane za pośrednictwem wtyczek (dodatków). Więcej informacji na temat łączenia się z kanałami w innych sieciach znajduje się poniżej. + +Aby połączyć się z innymi kanałem $Projectname: + +Odwiedź profil tego kanału, klikając jego zdjęcie w katalogu, matrycy lub komentarzach, a otworzy się strona główna kanału w przeglądarce kanału. Po lewej stronie ekranu zwykle jest widoczny link o nazwie "Connect". Kliknij i gotowe. W zależności od ustawień kanału, z którym się łączysz, być może będziesz musiał poczekać, aż właściciel zatwierdzi połączenie, ale nie musisz nic robić. Po zainicjowaniu połączenia zostaniesz przeniesiony do edytora połączeń. Dzięki temu możesz przypisać określone uprawnienia do tego kanału, jeśli chcesz wprowadzić jakiekolwiek zmiany. + +Aby połączyć się z kanałami w innych sieciach niż sieć $Projectname: + +Proces łączenia się z kanałami w innych sieciach (takich jak GNU-Social, Mastodon czy Diaspora) jest podobny - wpisz odpowiednie "webbie" do pola "Dodaj nowe połączenia" na stronie "Połączenia". Jednak zanim to zrobisz, odwiedź stronę "Ustawienia" ("Ustawienia funkcji i dodatków") i upewnij się, że w Twoim hubie jest dostępny odpowiedni protokół (Diaspora, GNU-Social/OStatus lub ActivityPub) i [b][i]jest aktywowany[/i] dla Twojego kanału[/b]. Te sieci (protokoły) nie obsługują migracji kont i niezależności lokalizacji, więc jeśli przeniesiesz lokalizację lub sklonujesz swój kanał w inne miejsce, komunikacja z tymi połączeniami może się nie udać. Z tego powodu protokoły te nie są domyślnie aktywowane, ale ich aktywacja wymaga Twojej zgodą. Aktywacja tych protokołów wiąże się z podjęciem ważkiego rozstrzygniecia korzyści płynących z kmunikowania się ze znajomymi w tych sieciach a z drugiej strony, zapewnieniem odporności konta na awarie serwera. + +Niektóre rodzaje komunikacji oferują więcej niż jeden protokół. Jeśli chcesz połączyć się z kimś na Mastodonie (na przykład), możesz użyć do komunikacji protokołu "Ostatus" lub "AactivityPub". Generalnie, protokół "ActivityPub" zapewnia lepszą obsługę niż "Ostatus", ale Hubzilla często wybiera pierwszy protokół, który odkryje i może to nie być to, czego chcesz. Możesz połączyć się z kimś przez określony protokół, poprzedzając nazwę protokołu w nawiasach kwadratowych na tym "webbie". Na przykład: + +[code] +[activitypub]https://foo.bar/foobar +[ostatus]foobar@foo.bar +[diaspora]foobar@foo.bar +[zot]foobar@foo.bar +[feed]https://foo.bar/foobar +[/code] + +Aby połączyć zię z kanałami RSS: + +Administrator huba może zezwolić na łączenie się z kanałami RSS. Proces łączenia się z kanałem RSS jest taki sam, z wyjątkiem wpisania (lub wklejenia) adresu URL kanału w polu "Dodaj nowe połączenie". Kanały są przetwarzane tylko raz lub dwa razy dziennie, a administrator huba może nałożyć ograniczenia na liczbę dodawanych kanałów. + +[h4][b]Blokowanie, ignorowanie, archiwizowanie i ukrywanie kanałów[/b][/h4] + +Kanały w książce adresowej mogą mieć statusy, takie jak [i]zablokowany[/i], [i]ignorowany[/i], [i]zarchiwizowany[/i] i [i]ukryty[/i]. Na stronie połączeń możesz zobaczyć zakładki, które wyświetlają kanały o tych statusach. Na stronach edycji połączenia możesz zmienić status kanału. + +Oto ich znaczenie: + +[b]Zablokowany:[/b] w kanale nie moża odczytywać elementów, niezależnie od uprawnień, ani zapisywać cokolwiek. + +[b]Ignorowany:[/b] w kanale można odczytywać elementy, jeśli ma się odpowiednie uprawnienia, ale nie można tu nic zapisywać. + +[b]Ukryty:[/b] kanał nie pojawia się na liście połączeń profilu, nikt nie może zobaczyć, że jesteś połączony, ale trzeba mieć na uwadze, że treści mogą nadal pojawiać się innych połączeniach, na przykład w odpowiedziach na wpisy. + +[b]Archiwizowany:[/b] jeśli kanał nie jest dostępny przez 30 dni, jest automatycznie oznaczany jako "zarchiwizowany". Wszystkie dane zostają zachowane, ale zatrzymane zostaje odpytywanie kanału w poszukiwaniu nowych informacji i usuwa się go z autouzupełniania. Jeśli później dowiesz się, że kanał wrócił do trybu online, możesz ręcznie przywrócić go z archiwum. + +[h4][b]Kanały Premium[/b][/h4] + +Niektóre kanały są oznaczone jako "kanały premium" i mogą wymagać pewnych działań ze strony odwiedzajacego, zanim będzie on mógł nawiązać połączenie. Przycisk "Połącz" w przypadku tych kanałów przeniesie Cię do strony zawierającej szczegółowe informacje o warunkach, które ustanowił właściciel kanału. Jeśli warunki zostaną zaakceptowane, połączenie będzie kontynuowane normalnie. W niektórych przypadkach, na przykład w przypadku celebrytów i światowej sławy wydawców, może to wymagać zapłaty. Jeśli nie zgadzasz się z warunkami, połączenie nie będzie kontynuowane lub może być kontynuowane, ale z ograniczonymi uprawnieniami dozwolonymi dla twoich interakcji z tym kanałem. + +[h3]Uprawnienia[/h3] +Uprawnienia w $Projectname są pełniejsze niż te, do których możesz być przyzwyczajony. To pozwala nam zdefiniować lepiej oceniane relacje niż czarno-białe: "ta osoba jest moim przyjacielem, więc może zrobić wszystko" lub "ta osoba nie jest moim przyjacielem, więc nie może nic zrobić", jak to ma miejsce w innych serwisach społecznościowych. + +[h4][b]Role uprawnieniowe[/b][/h4] + +Tworząc kanał, można wybrać różne "role" dla tego kanału. Tworzą one całą rodzinę uprawnień i ustawień prywatności, które są odpowiednie dla tej roli. Typowe role to "Społeczne - głównie publiczne", "Społeczne - głównie prywatne", "Forum - publiczne" i wiele innych. Zapewniają one pewien poziom prostoty zarządzania uprawnieniami. Wystarczy wybrać rolę, a odpowiednie uprawnienia zostaną zastosowane automatycznie. Możesz także wybrać "Tryb niestandardowy/ekspercki" i zmienić indywidualne ustawienia uprawnień w dowolny sposób. + +[h4][b]Domyślne ograniczenia uprawnień[/b][/h4] + +Istnieje wiele indywidualnych uprawnień. Kontrolują one wszystko, od przeglądania strumienia po możliwość czatowania z Tobą. Każde pozwolenie ma limit. Zakres tych uprawnień waha się od "Tylko ja" do "Wszyscy w Internecie" - chociaż niektóre zakresy mogą nie być dostępne dla niektórych uprawnień. Limit dotyczy każdej opublikowanej rzeczy, którą tworzysz, a która nie ma kontroli prywatności ani kontroli dostępu. Na przykład, jeśli publikujesz zdjęcie i nie wybrałeś określonej grupy odbiorców z pozwoleniem na jego przeglądanie, stosujemy ten limit. Te ograniczenia dotyczą wszystkiego w ramach tej reguły pozwolenia, więc nie możesz zastosować ograniczenia do jednego zdjęcia. Limit dotyczy wszystkich Twoich zdjęć. Jeśli wszystkie Twoje zdjęcia są widoczne dla wszystkich w Internecie i ograniczysz limit tylko do znajomych, wszystkie Twoje zdjęcia będą teraz widoczne tylko dla znajomych. + +[h4][b]Kontrola dostępu[/b][/h4] + +Kontrola dostępu jest preferowaną metodą zarządzania prywatnością w [i]większości[/i] przypadków, zamiast stosowania ograniczania uprawnień. Polega ona na utworzeniu list połączeń lub grup prywatności (lub obu na raz) i na podstawie listy kontroli dostępu (ACL) użytkownik decyduje, czy zezwolenie jest dozwolone. Lista kontroli dostępu jest dołączona do wszystkiego, co się publikuje. W przeciwieństwie do ograniczeń uprawnień, zmiana listy kontroli dostępu na jednym zdjęciu nie ma wpływu na żadne z pozostałych zdjęć. Możesz użyć grup prywatności i "domyślnej listy kontroli dostępu", aby utworzyć i zautomatyzować zarządzanie listami kontroli dostępu, tak aby zapewnić dowolny poziom prywatności dla wszystkiego, co publikujesz. + +Zdecydowanie zalecamy skorzystanie z ustawień "typowej sieci społecznościowej" podczas tworzenia pierwszego kanału, ponieważ umożliwia to innym komunikowanie się z Tobą i pomaga w razie trudności. Przekonasz się, że te ustawienia zapewniają tyle prywatności, ile chcesz - kiedy tego chcesz; ale także pozwalają komunikować się publicznie, jeśli zechcesz. Po opanowaniu obsługi możesz swobodnie korzystać z dużo bardziej prywatnych ustawień. + +[dl terms="l"] +[*= Zakresy uprawnień to:] +[dl terms="i"] + [*= Nikt oprócz Ciebie ] To jest oczywiste. Tylko Ty będziesz mieć dostęp. + + [*= Tylko ci, którym jawnie zezwalasz ] Domyślnie osoby, z którymi nie jesteś połączony i wszystkie nowe kontakty będą miały odmowę tego uprawnienia. Można robić wyjątki dla poszczególnych kanałów na ich ekranie edycji kontaktów. + + [*= Każdy w Twojej książce adresowej ] Każdy, kto nie znajduje się w Twojej książce adresowej ma odmowę dostępu, ale każdy kogo zaakceptujesz jako kontakt, uzyska zezwolenie. Jest to sposób stosowany na większości starszych platform. + + [*= Każdy na tym hubie ] Każdy, kto ma kanał w tym samym hubie co Ty, będzie miał pozwolenie. Każdemu, kto jest zarejestrowany na innym hubie, odmawia się dostępu. + + [*= Każdy w tej sieci ] Każdy w sieci $Projectname będzie miał zatwierdzone to pozwolenie. Nawet zupełnie obce osoby. Jednak każdemu, kto nie jest zalogowany (uwierzytelniony), tego dostępu się odmiawia. + + [*= Każdy uwierzytelniony ] Jest to podobne do uprawnienia "każdy w tej sieci", z tym wyjątkiem, że może obejmować każdego, kto może uwierzytelnić się w jakikolwiek sposób - a zatem może obejmować odwiedzających z innych sieci. + + [*= Token dostępu gościa] Umożliwia to udostępnianie pliku, folderu, zdjęcia, albumu lub kanału określonej osobie lub grupie osób. Nie muszą być członkami Hubzilli. Możesz ustawić ważność tokenu dostępu. + + [*= Każdy w Internecie ] Element jest całkowicie publiczny. To pozwolenie umożliwia dostęp każdemu. +[/dl] +[*= Indywidualne uprawnienia, to:] +[dl terms="i"] + [*= Można wyświetlać mój "publiczny" strumień i posty. ] To uprawnienie określa, kto może oglądać "strumień" Twojego kanału, czyli nieprywatne wpisy, które pojawiają się na karcie "Strona główna", gdy jesteś zalogowany. + + [*= Można wyświetlać mój "publiczny" profil kanału. ] To uprawnienie określa, kto może wyświetlać profil Twojego kanału. Dotyczy to zakładki "o mnie". + + [*= Można wyświetlać moje "publiczne" albumy zdjęć. ] To uprawnienie określa, kto może wyświetlać Twoje albumy ze zdjęciami. Poszczególne zdjęcia mogą nadal być publikowane do bardziej prywatnej grupy osób. + + [*= Można wyświetlać moją "publiczną" książkę adresową. ] To uprawnienie określa, kto może wyświetlać Twoje kontakty. Są to połączenia wyświetlane w sekcji "Wyświetl połączenia". + + [*= Można wyświetlać mój "publiczny" magazyn plików. ] To uprawnienie określa, kto może wyświetlać Twoje publiczne pliki przechowywane w "chmurze" serwisu. + + [*= Można wyświetlać moje "publiczne" strony. ] To uprawnienie określa, kto może wyświetlać Twoje publiczne strony internetowe. + + [*= Można przesyłać mi strumień ich kanału i posty. ] To uprawnienie określa, czyje wpisy będą wyświetlane na Twoim kanale. Jeśli Twój kanał jest kanałem osobistym (tj. Ty jako osoba), prawdopodobnie chciałbyś ustawić to przynajmniej tak, że "każdy z mojej książki adresowej". Osobisty kanał notatek prawdopodobnie chciałbyś ustawić na "nikt oprócz mnie". Ustawienie tego na "każdy w sieci” spowoduje wyświetlenie wpisów od zupełnie obcych osób, co jest dobrą formą rozeznania sieci. + + [*= Można publikować na stronie mojego kanału ("ścianie"). ] To uprawnienie określa, kto może umieszczać swoje wpisy na Twojej ścianie po przejściu do Twojego kanału. + + [*= Można komentować moje posty. ] To uprawnienie określa, kto może komentować posty, które tworzysz. Zwykle chce się, aby pasowało to do uprawnienia "można wyświetlać mój publiczny strumień i wpisy”. + + [*= Można wysyłać mi prywatne wiadomości pocztowe. ] Określa to, kto może wysyłać Ci prywatne wiadomości (zotmail). + + [*= Można publikować zdjęcia w moich albumach ze zdjęciami. ] To określa, kto może publikować zdjęcia w Twoich albumach. Jest to bardzo przydatne w przypadku kanałów przypominających forum, na których połączenia mogą nie być ze sobą połączone. + + [*= Można przekazywać dalej do wszystkich kontaktów z mojego kanału za pomocą +tagów post. ] Użycie wzmianek (@-) spowoduje odtworzenie kopii twojego wpisu na określonym profilu, tak jakbyś opublikował go na ścianie kanału. To ustawienie określa, czy jakieś osoby mogą w ten sposób publikować na Twoim kanale. + + [*= Można ze mną rozmawiać (jeśli jestem dostępny). ] Określa to, kto może dołączyć do publicznych czatów utworzonych na Twoim kanale. + + [*= Można zapisywać w moim "publicznym" magazynie plików. ] To określa, kto może przesyłać pliki do Twojego publicznego magazynu plików lub "chmury". + + [*= Można edytować moje "publiczne" strony. ] Określa to, kto może edytować Twoje strony internetowe. Jest to przydatne w przypadku witryn typu wiki lub witryn z wieloma redaktorami. + + [*= Można zarządzać zasobami mojego kanału. ] To określa, kto może mieć pełną kontrolę nad Twoim kanałem. Zwykle powinno być to ustawione na "nikt oprócz mnie". +[/dl][/dl] +[i]Uwaga:[/i] +Wtyczki (dodatki) mogą zapewniać specjalne ustawienia uprawnień, więc możesz otrzymać dodatkowe ustawienia uprawnień wykraczające poza to, co opisano tutaj. + +Jeśli ustawisz którekolwiek z tych uprawnień na "tylko te, na które wyraźnie zezwalam", możesz określać indywidualne uprawnienia na ekranie edycji połączenia. + +[h4][b]Koligacja[/b][/h4] + +Ekran edycji połączenia oferuje suwak do wyboru stopnia "przyjaźni" z połączeniem (to narzędzie można włączyć na karcie "Dodatkowe funkcje" na stronie "Ustawienia"). Potraktuj to jako miarę tego, jak bardzo ich lubisz lub nie lubisz. Wartość 1 jest dla osób, które lubisz, których wpisy chcesz widzieć cały czas; 99 jest dla osób, na których Ci nie zależy i których wpisy możesz chcieć przeglądać tylko od czasu do czasu. Po przypisaniu tutaj wartości możesz użyć narzędzia koligacji na stronie matrycy do filtrowania treści na podstawie tej liczby. + +Suwak na stronie matrycy ma zarówno wartość minimalną, jak i maksymalną. Wpisy będą wyświetlane tylko od osób mieszczących się w tym zakresie. Koligacja nie ma związku z uprawnieniami i jest przydatna tylko w połączeniu z funkcją narzędzia koligacji. + +[h3]Tokeny dostępu gościa[/h3] +Tokeny dostępu gościa (czasami nazywane "tokenami dostępu Zot") umożliwiają udostępnianie pliku, folderu, zdjęcia, albumu lub kanału określonej osobie lub grupie osób, które nie są członkami hubu Hubzilli. Te tokeny umożliwiają udostępnianie poszczególnych elementów poprzez wysłanie linku zawierającego token w adresie URL; alternatywnie, osoby mogą faktycznie logować się przy użyciu poświadczeń tokena, po czym mogą bezproblemowo przeglądać zawartość udostępnioną temu tokenowi. + +W celu utworzenia tokenów dostępu gościa i zarządzać nimi, otwórz stronę ustawień "Tokeny dostępu gościa". Przy każdym załadowaniu strony generowany jest losowy token, który umożliwia utworzenie specjalnego adresu URL zawierającego ten token i opcjonalnie określenie daty wygaśnięcia. Istniejące tokeny są wymienione poniżej okna dialogowego i można je edytować, wybierać lub usuwać. + +Tokenowi gościa można przyznać dodatkowe uprawnienia, rozszerzając opcje "Indywidualnych uprawnień" i wybierając ustawienia prywatności, takie jak "Może wyświetlać strumień i wpisy mojego kanału" lub "Może rozmawiać ze mną". + +[url=[baseurl]/help/feature/access_tokens]Więcej informacji...[/url] + +[img][baseurl]/doc/member/assets/zat_dialog.png[/img] + +[h3]Język znaczników[/h3] +$Projectname obsługuje kilka języków znaczników do zaawansowanego formatowania treści. Domyślnym językiem znaczników jest [url=[baseurl]/help/pl/member/bbcode]własny wariant BBcode[/url], dostosowany do użytku w Hubzilli. BBcode jest obsługiwany dla postów, stron wiki i elementów stron internetowych. Strony Wiki i elementy stron internetowych można również pisać przy użyciu standardowego języka Markdown. +[table border=0] +[tr][th]Typ treści[/th][th]Obsługiwany język[/th][/tr] +[tr][td]Post[/td][td][url=[baseurl]/help/pl/member/bbcode]BBcode[/url][/td][/tr] +[tr][td]Wiki[/td][td][url=[baseurl]/help/pl/member/bbcode]BBcode[/url], Markdown[/td][/tr] +[tr][td]Elementy stron WWW[/td][td][url=[baseurl]/help/pl/member/bbcode]BBcode[/url], Markdown, HTML[/td][/tr] +[/table] + +[h3]Tagi i wzmianki[/h3] +Podobnie jak wiele innych platform, $Projectname używa specjalnej notacji wewnątrz wiadomości, aby wskazać "tagi" lub powiązania kontekstowe z innymi podmiotami. + +[h4][b]Wzmianki[/b][/h4] +Kanały (profile) są oznaczane przez swoją nazwę poprzedzoną znakiem ed, np. [code]@Jacek[/code]. Jest to wykorzystywane w mechaniźmie wzmianek. + +Kiedy zaczniesz wspominać o kimś w swoim poście (wstawiając znak @), mechanizm ten utworzy pole z autouzupełnianiem, aby można było wybrać z Twoich bezpośrednich kontaktów określoną osobę (kanał). Możesz wybrać z listy ten kanał, który chcesz wzmiankować. + +Jeśli wspomniana osoba znajduje się na liście odbiorców postu, otrzyma powiadomienie o tym znaczniku. + +[h4][b]Wzmianki dostarczania[/b][/h4] + +Znak wykrzyknika ([b]![/b]) oznacza [i]wzmiankę dostarczania[/i] wstawioną na forum lub specjalnym kanale, która umożliwia rozesłanie wisu do wielu odbiorców. + +[code] +@Gardening - wzmiankowanie forum Gardening + +!Gardening - wzmiankowanie forum Gardening i równoczesne opublikowanie wpisu w "sieci" Gardening " (np. rozesłanie wpisu do wszystkich członków tej sieci, jeśli ma się na to pozwolenie). +[/code] + +Uwaga: w poprzednich wersjach, format wzmianki dostarczania miał postać [code]@forum+[.code] (plus na końcu). Ten mechanizm nie jest już obsługiwany. + +[h4][b]Wzmianki prywatności[/b][/h4] +Jeśli chcesz ograniczyć wpis do jednej osoby lub kilku osób, możesz to zrobić, wybierając kanały lub grupy prywatności w narzędziu do ochrony prywatności. Możesz także po prostu oznaczyć je tagiem prywatności. Znacznik prywatności to nazwa poprzedzona znakami [code]@![/code], co zmienia również uprawnienia prywatności posta, tak aby zawierały tylko te osoby, którym chcesz dostarczyć post. Można wstawić więcej niż jeden tag prywatności, na przykład tagi [code]@!Bob[/code] i [code]@!Linda[/code] sposowdują wysłanie posta tylko do Boba i Lindy. Ten mechanizm zastępuje selektor prywatności. + +Fora mogą być wzmiankowane w ten sam sposób. Wzmianka [code]!!dogs[/code] będzie powodować publikowanie prywatnie na forum "dogs". Forum ponownie dostarczy post do wszystkich członków forum, ale Twoi obserwatorzy nie zobaczą go, chyba że są również członkami forum "dogs". + +Można także oznaczyć grupy prywatności, które są "publiczne". Gdy tworzysz lub edytujesz grupę prywatności, jest dostępne pole wyboru, które umożliwia innym osobom zobaczenie członków grupy. Jeśli to pole jest zaznaczone dla grupy i oznaczysz post, na przykład tagiem [code]@!Friends[/code] - zostanie on ograniczony do grupy Friends. Zanim to zrobisz, sprawdź, czy grupa jest publiczna, ponieważ nie ma innego sposobu na wycofanie postu niz jego usunięcie. Nazwa grupy pojawi się w poście i powiadomi członków tej grupy, że są jej członkami. + +[h4][b]Wzmianki a komentarze[/b][/h4] +Powyższe mechanizmy mają zastosowanie tylko do postów "najwyższego poziomu". Wzmianka o kanale z którymkolwiek z powyższych mechanizmów nie ma wpływu na komentarze, poza tym, że wzmiankowany kanał może otrzymać powiadomienie, jeśli był już uwzględniony w rozmowie jako odbiorca. + +[h4][b]Tagi tematyczne (hasztagi)[/b][/h4] +[i]Tagi tematyczne[/i], zwane też [i]hasztagami[/i], mają format terminu poprzedzonego znakiem hash ([b]#[/b]). Powoduje to utworzenie w poście łącza do ogólnoserwisowego wyszukiwania podanego terminu. Na przykład, [code]#cars[/code] zapewni link do wyszukiwania dla wszystkich postów zawierających słowo kluczowe [code]cars[/code] w Twoim serwisie. W tagach tematycznych powinno się używać terminów nie krótszych niż trzy znaki. Krótsze terminy wyszukiwania prawdopodobnie nie przyniosą żadnych wyników wyszukiwania, chociaż zależy to od konfiguracji bazy danych. + +Tagi tematyczne zawierające same cyfry nie są zwykle dozwolone, np. [code]#1[/code]. Jeśli chcesz użyć hashtagu numerycznego, dodaj tekst opisowy, np. [code]#2012-wybory[/code] lub umieść cały termin w podwójnych cudzysłowach (na przykład [code]#"2012"[/code]). Podwójne cudzysłowy są również wymagane, jeśli termin zawiera spacje ([code]#"My tag[/code]`) i mogą być wymagane, jeśli tag zawiera znaki interpunkcyjne lub znaki diakrytyczne ([code]#"EndsWithPeriod."[/code], [code]#"Exciting!!!"[/code], [code]#"Ósmy pasażer"[/code] itp.). + +[h4][b]Zakładki[/b][/h4] +Zakładki wskazują link, który można zapisać w folderze zakładek. Używają sekwencji [code]#^[/code], po której następuje link. Często są one generowane automatycznie. Jeśli zainstalowany jest dodatek "bookmarker", sekwencja ta zostanie przekonwertowana na ikonę zakładki podczas przeglądania inline postu lub komentarza, a kliknięcie ikony spowoduje zapisanie zakładki. Jeśli dodatek bookmarker nie jest zainstalowany, można wykorzystać rozwijane menu posta, które zawiera łącze do zapisania zakładki lub zakładek. + +[h4][b]Ręczne wzmiankowanie[/b][/h4] +Na przykład, tag [code]@billy[/code] oznaczy połączenie, którego nazwa lub adres sieciowy to "billy" (dopasowanie dokładne). Jeśli masz dwa połączenia z nazwą lub adresem sieciowym billy, na przykład [code]billy@server1.hubzilla.org[/code] i [code]billy@server2.hubzilla2.org[/code], będziesz musiał podać pełny adres, inaczej wyniki będą niejednoznaczne i niewłaściwa osoba może zostać oznaczona. + +Tag [code]@"Robert Johnson"[/code] oznaczy Roberta Johnsona. Podwójne cudzysłowy są wymagane, jeśli oznaczona nazwa zawiera spacje. + +[h3]Strony internetowe[/h3] + +$Projectname umożliwia członkom i dozwolonym połączeniom tworzenie statycznych stron internetowych. Aby aktywować tę funkcję, włącz funkcję [b]Strony internetowe[/b] w sekcji [b][url=[baseurl]/settings/features/]Dodatkowe funkcjonalności[/url][/b]. + +Po włączeniu, na stronie kanału pojawi się nowa karta zatytułowana "Strony internetowe". Kliknięcie tego linku przeniesie Cię do edytora stron internetowych. Strony będą dostępne pod adresem [b][baseurl]/page/[observer=1][observer.webname][/observer][observer=0]channelname[/observer]/pagelinktitle[/b] + +Pole "Tytuł linku do strony" umożliwia określenie tytułu linku do strony tego adresu URL. Jeśli tytuł linku do strony nie jest ustawiony, ustawimy go automatycznie, używając identyfikatora wiadomości elementu. + +Pod polem tworzenia strony pojawi się lista istniejących stron z linkiem "Edytuj". Kliknięcie tego przeniesie Cię do edytora podobnego do edytora postów, w którym możesz wprowadzać zmiany na swoich stronach internetowych. + +[h4][b]Używanie bloków[/b][/h4] + +Bloki mogą być częściami stron internetowych. Podstawowy kod HTML bloku wygląda następująco: +[code] +
      + Block Content +
      + +[/code] + +Jeśli blok ma zawartość tekstową (html), może również zawierać elementy menu. Na przykład, zawartość: +[code] +

      HTML block content

      + [menu]menuname[/menu] + +[/code] +wytworzy HTML taki jak ten: +[code] +
      +

      HTML block content

      +
      + +
      +
      + +[/code] + +Makro [code]$content[/code] umożliwia osadzenie całej treści strony internetowej. W tym celu wystarczy utwórzyć taki blok: +[code] + $content + +[/code] +jako treść. Aby blok pojawił się na stronie internetowej, musi być zdefiniowany w układzie strony wewnątrz regionu. +[code] + [region=aside] + [block]blockname[/block] + [/region] + +[/code] + +Wygląd bloku można zmieniać w układzie strony. + +W regionie można przypisać własne klasy (css). Ten kod: +[code] + [region=aside] + [block=myclass]blockname[/block] + [/region] + +[/code] +wytworzy taki HTML: +[code] +
      + Block Content +
      + +[/code] + +Za pomocą zmiennej [code]wrap[/code] z bloku można usunąć otaczające go znaczniki [code]
      [/code]. Ten kod: +[code] + [region=aside] + [block][var=wrap]none[/var]blockname[/block] + [/region] + +[/code] +wytworzy taki HTML: +[code] + Treść bloku +[/code] + +[h4][b]Narzędzie importy elementów strony internetowej[/b][/h4] + +Istnieją dwie metody importowania elementów strony internetowej: przesyłanie pliku ZIP lub odwoływanie się do lokalnego folderu plików w chmurze. Obie metody wymagają określenia elementów strony sieci internetowej przy użyciu określonej struktury folderów. Narzędzie importu umożliwia zaimportowanie wszystkich elementów niezbędnych do zbudowania całej witryny lub zestawu witryn. Celem jest uwzględnienie zewnętrznego tworzenia stron internetowych, a także narzędzi upraszczających i automatyzujących wdrażanie w hubie. + +[h5] Struktura folderu [/h5] +Definicje elementów muszą być przechowywane w katalogu głównym repozytorium w folderach o nazwie odpowiadającej typowi elementu: +[code] + /pages/ + /blocks/ + /layouts/ +[/code] + +Każdy element tych typów musi być zdefiniowany w osobnym podfolderze przy użyciu dwóch plików: jednego w formacie JSON dla metadanych i drugiego w zwykłym formacie testowym dla zawartości elementu. + +[h5] Elementy strony [/h5] +Page element metadata is specified in a JSON-formatted file called [code]page.json[/code] with the following properties: +[list] +[*] title +[*] pagelink +[*] mimetype +[*] layout +[*] contentfile +[/list] +[b]Example[/b] + +Files: +[code] + /pages/my-page/page.json + /pages/my-page/my-page.bbcode +[/code] +Content of [code]page.json[/code]: +[code] + { + "title": "My Page", + "pagelink": "mypage", + "mimetype": "text/bbcode", + "layout": "my-layout", + "contentfile": "my-page.bbcode" + } +[/code] +[h5] Layout elements [/h5] + +Layout element metadata is specified in a JSON-formatted file called [code]layout.json[/code] with the following properties: +[list] +[*] name +[*] description +[*] contentfile +[/list] +[b]Example[/b] + +Files: +[code] + /layouts/my-layout/layout.json + /layouts/my-layout/my-layout.bbcode +[/code] +Content of [code]layout.json[/code]: +[code] + { + "name": "my-layout", + "description": "Layout for my project page", + "contentfile": "my-layout.bbcode" + } +[/code] + +[h5] Block elements [/h5] + +Block element metadata is specified in a JSON-formatted file called [code]block.json[/code] with the following properties: +[list] +[*] name +[*] title +[*] mimetype +[*] contentfile +[/list] +[b]Example[/b] + +Files: +[code] + /blocks/my-block/block.json + /blocks/my-block/my-block.html +[/code] +Content of [code]block.json[/code]: + +[code] + { + "name": "my-block", + "title": "", + "mimetype": "text/html", + "contentfile": "my-block.html" + } +[/code] + +[h3]Comanche Page Description Language[/h3] + +Comanche is a markup language similar to [url=[baseurl]/help/member/bbcode]BBcode[/url] with which to create elaborate and complex web pages by assembling them from a series of components - some of which are pre-built and others which can be defined on the fly. Comanche uses a Page Decription Language to create these pages. + +Comanche primarily chooses what content will appear in various regions of the page. The various regions have names and these names can change depending on what layout template you choose. + +[h4]Page Templates[/h4] +Currently there are five layout templates, unless your site provides additional layouts. + +[dl terms="b"] +[*= default] +The default template defines a "nav" region across the top, "aside" as a fixed width sidebar, +"content" for the main content region, and "footer" for a page footer. + +[*= full] +The full template defines the same as the default template with the exception that there is no "aside" region. + +[*= choklet] +The choklet template provides a number of fluid layout styles which can be specified by flavour: +[list] +[*] (default flavour) - a two column layout similar to the "default" template, but more fluid +[*] bannertwo - a two column layout with a banner region, compatible with the "default" template on small displays +[*] three - three column layout (adds a "right_aside" region to the default template) +[*] edgestwo - two column layout with fixed side margins +[*] edgesthree - three column layout with fixed side margins +[*] full - three column layout with fixed side margins and adds a "header" region beneath the navigation bar +[/list] + +[*= redable] +A template for reading longer texts full screen (so without navigation bar). Three columns: aside, content and right_aside. +For maximum readability it is advised to only use the middle content column. + +[*= zen] +Gives you the freedom to do everything yourself. Just a blank page with a content region. +[/dl] + +To choose a layout template, use the 'template' tag. + +[code] + [template]full[/template] + +[/code] + +To choose the "choklet" template with the "three" flavour: + +[code] + [template=three]choklet[/template] + +[/code] + +The default template will be used if no other template is specified. The template can use any names it desires for content regions. You will be using 'region' tags to decide what content to place in the respective regions. + +Three "macros" have been defined for your use. +[code] + $htmlhead - replaced with the site head content. + $nav - replaced with the site navigation bar content. + $content - replaced with the main page content. + +[/code] + +By default, $nav is placed in the "nav" page region and $content is placed in the "content" region. You only need to use these macros if you wish to re-arrange where these items appear, either to change the order or to move them to other regions. + + +To select a theme for your page, use the 'theme' tag. +[code] + [theme]suckerberg[/theme] + +[/code] +This will select the theme named "suckerberg". By default your channel's preferred theme will be used. + +[code] + [theme=passion]suckerberg[/theme] + +[/code] +This will select the theme named "suckerberg" and select the "passion" schema (theme variant). Alternatively it may be possible to use a condensed theme notation for this. + +[code] + [theme]suckerberg:passion[/theme] + +[/code] + +The condensed notation isn't part of Comanche itself but is recognised by $Projectname platform as a theme specifier. + +[h4]Navbar[/h4] + +[code] + [navbar]tucson[/navbar] +[/code] + +Use the 'tucson' navbar template and CSS rules. By default the 'default' navbar template will be used. + + +[h4]Regions[/h4] +Each region has a name, as noted above. You will specify the region of interest using a 'region' tag, which includes the name. Any content you wish placed in this region should be placed between the opening region tag and the closing tag. + +[code] + [region=htmlhead]....content goes here....[/region] + [region=aside]....content goes here....[/region] + [region=nav]....content goes here....[/region] + [region=content]....content goes here....[/region] + +[/code] + +[h4]CSS and Javascript[/h4] +We have the possibility to include javascript and css libraries in the htmlhead region. At present we make use of jquery (js), bootstrap (css/js) and foundation (css/js). +This will overwrite the selected themes htmlhead. + +[code] + [region=htmlhead] + [css]bootstrap[/css] + [js]jquery[/js] + [js]bootstrap[/js] + [/region] + +[/code] + +[h4]Menus and Blocks[/h4] +Your webpage creation tools allow you to create menus and blocks, in addition to page content. These provide a chunk of existing content to be placed in whatever regions and whatever order you specify. Each of these has a name which you define when the menu or block is created. + +[code] + [menu]mymenu[/menu] + +[/code] +This places the menu called "mymenu" at this location on the page, which must be inside a region. + +[code] + [menu=horizontal]mymenu[/menu] + +[/code] +This places the menu called "mymenu" at this location on the page, which must be inside a region. Additionally it applies the "horizontal" class to the menu. "horizontal" is defined in the redbasic theme. It may or may not be available in other themes. + +[code] + [menu][var=wrap]none[/var]mymenu[/menu] + +[/code] +The variable [var=wrap]none[/var] in a block removes the wrapping div element from the menu. + +[code] + [block]contributors[/block] +[/code] +This places a block named "contributors" in this region. + +[code] + [block=someclass]contributors[/block] + +[/code] +This places a block named "contributors" in this region. Additionally it applies the "someclass" class to the block. This replaces the default block classes "bblock widget". + +[code] + [block][var=wrap]none[/var]contributors[/block] + +[/code] +The variable [var=wrap]none[/var] in a block removes the wrapping div element from the block. + +[h4]Widgets[/h4] +Widgets are executable apps provided by the system which you can place on your page. Some widgets take arguments which allows you to tailor the widget to your purpose. System widgets are listed [url=help/Widgets]here[/url]. Widgets can also ve created by plugins, themes, or your site administrator to provide additional functionality. + + +Widgets and arguments are specified with the 'widget' and 'var' tags. +[code] + [widget=recent_visitors][var=count]24[/var][/widget] + +[/code] + +This loads the "recent_visitors" widget and supplies it with the argument "count" set to "24". + +[h4]Comments[/h4] +The 'comment' tag is used to delimit comments. These comments will not appear on the rendered page. + +[code] + [comment]This is a comment[/comment] + +[/code] + +[h4]Conditional Execution[/h4] +You can use an 'if' construct to make decisions. These are currently based on system configuration variable or the current observer. + +[code] + [if $config.system.foo] + ... the configuration variable system.foo evaluates to 'true'. + [else] + ... the configuration variable system.foo evaluates to 'false'. + [/if] + + [if $observer] + ... this content will only be show to authenticated viewers + [/if] + +[/code] + + The 'else' clause is optional. + + Several tests are supported besides boolean evaluation. + +[code] + [if $config.system.foo == bar] + ... the configuration variable system.foo is equal to the string 'bar' + [/if] + [if $config.system.foo != bar] + ... the configuration variable system.foo is not equal to the string 'bar' + [/if] + [if $config.system.foo {} bar ] + ... the configuration variable system.foo is a simple array containing a value 'bar' + [/if] + [if $config.system.foo {*} bar] + ... the configuration variable system.foo is a simple array containing a key named 'bar' + [/if] +[/code] + +[h4]Complex Example[/h4] +[code] + [comment]use an existing page template which provides a banner region plus 3 columns beneath it[/comment] + + [template]3-column-with-header[/template] + + [comment]Use the "darknight" theme[/comment] + + [theme]darkknight[/theme] + + [comment]Use the existing site navigation menu[/comment] + + [region=nav]$nav[/region] + + [region=side] + + [comment]Use my chosen menu and a couple of widgets[/comment] + + [menu]myfavouritemenu[/menu] + + [widget=recent_visitors] + [var=count]24[/var] + [var=names_only]1[/var] + [/widget] + + [widget=tagcloud][/widget] + [block]donate[/block] + + [/region] + + + + [region=middle] + + [comment]Show the normal page content[/comment] + + $content + + [/region] + + + + [region=right] + + [comment]Show my condensed channel "wall" feed and allow interaction if the observer is allowed to interact[/comment] + + [widget]channel[/widget] + + [/region] + +[/code] + + +[h3]Personal Cloud Storage[/h3] + +$Projectname provides an ability to store privately and/or share arbitrary files with friends. + +You may either upload files from your computer into your storage area, or copy them directly from the operating system using the WebDAV protocol. + +On many public servers there may be limits on disk usage. + +[h4]File Attachments[/h4] + +The quickest and easiest way to share files is through file attachments. In the row of icons below the status post editor is a tool to upload attachments. Click the tool, select a file and submit. After the file is uploaded, you will see an attachment code placed inside the text region. Do not edit this line or it may break the ability for your friends to see the attachment. You can use the post permissions dialogue box or privacy hashtags to restrict the visibility of the file - which will be set to match the permissions of the post your are sending. + +To delete attachments or change the permissions on the stored files, visit [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username replacing username with the nickname you provided during channel creation[/observer]. + +[h4]Web Access[/h4] + +Your files are visible on the web at the location [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username[/observer] to anybody who is allowed to view them. If the viewer has sufficient privileges, they may also have the ability to create new files and folders/directories. This should only be used for smaller files and photos (up to a few megabytes) as it uses internal memory. For larger files (videos, music, etc.), please upload using WebDAV. These files may still be retrieved via web access. + +[h4]WebDAV access[/h4] + +WebDAV provides a way to copy files directly to or from your computer's operating system, where your cloud files appear as a virtual disk drive. This should be used to upload large files such as video and audio; as it is not limited to available memory. See [zrl=help/member/member_guide#Cloud_Desktop_Clients]Cloud Desktop Clients[/zrl] below. + +[h4]CalDAV and CardDAV access on Android[/h4] + +You can sync you calendar and contacts on Android with your Hub. + +The following steps where tested for [url=https://f-droid.org/en/packages/at.bitfire.davdroid/]DAVdroid[/url] +[list] +[*] install DAVdroid +[*] add account +[*] use "URL" and "user name" to login +[list] +[*] base url is [baseurl]/cdav +[*] user name is [observer=1][observer.webname][/observer][observer=0]username[/observer] +[/list] +[/list] + +To share your calendar visit [observer.baseurl]/cdav/calendar + + +[h4]Permissions[/h4] + +When using WebDAV, the file is created with your channel's default file permissions and this cannot be changed from within the operating system. It also may not be as restrictive as you would like. What we've found is that the preferred method of making files private is to first create folders or directories; then visit [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username[/observer] select the directory and change the permissions. Do this before you put anything into the directory. The directory permissions take precedence so you can then put files or other folders into that container and they will be protected from unwanted viewers by the directory permissions. It is common for folks to create a "personal" or "private" folder which is restricted to themselves. You can use this as a personal cloud to store anything from anywhere on the web or any computer and it is protected from others. You might also create folders for "family" and "friends" with permission granted to appropriate privacy groups. + +[h3]Cloud Desktop Clients[/h3] + + +[h4]Cloud Desktop Clients - Windows[/h4] + +WebDAV using Windows 7 graphical user interface wizard: +1. Left-click the Start-button to open the start menu. +2. Right-click the My computer icon to access its menu. +3. Left-click Map network drive... to open the connection dialog wizard. +4. Type '[baseurl]/dav/nickname' in the textbox (replace nickname with your channel nickname) and click the Complete button. +5. Type your $Projectname channel nickname. IMPORTANT - NO at-sign or domain name. +6. Type your $Projectname password + +[h4]Cloud Desktop Clients - Linux[/h4] + +[h5]Mount as a filesystem[/h5] + +[b]Mounting As A Filesystem[/b] + +To install your cloud directory as a filesystem, you first need davfs2 installed. 99% of the time, this will be included in your distributions repositories. In Debian + +[code]apt-get install davfs2[/code] + +If you want to let normal users mount the filesystem + +[code] dpkg-reconfigure davfs2[/code] + +and select "yes" at the prompt. + +Now you need to add any user you want to be able to mount dav to the davfs2 group + +[code]usermod -aG davfs2 <DesktopUser>[/code] + +[b]Note:[/b] on some systems the user group may be different, i.e. - "network" +on Arch Linux. If in doubt, check the davfs documentation for your +particular OS. + +Edit /etc/fstab + +[code]nano /etc/fstab[/code] + + to include your cloud directory by adding + +[code] +[baseurl]/dav/ /mount/point davfs user,noauto,uid=<DesktopUser>,file_mode=600,dir_mode=700 0 1 +[/code] + +Where [baseurl] is the URL of your hub, /mount/point is the location you want to mount the cloud, and <DesktopUser> is the user you log in to one your computer. Note that if you are mounting as a normal user (not root) the mount point must be in your home directory. + +For example, if I wanted to mount my cloud to a directory called 'cloud' in my home directory, and my username was bob, my fstab would be + +[code][baseurl]/dav/ /home/bob/cloud davfs user,noauto,uid=bob,file_mode=600,dir_mode=700 0 1[/code] + +Now, create the mount point. + +[code]mkdir /home/bob/cloud[/code] + +and also create a directory file to store your credentials + +[code]mkdir /home/bob/.davfs2[/code] + +Create a file called 'secrets' + +[code]nano /home/bob/.davfs2/secrets[/code] + +and add your cloud login credentials + +[code] +[baseurl]/dav <username> <password> +[/code] + +Where <username> and <password> are the username and password [i]for your hub[/i]. + +Don't let this file be writeable by anyone who doesn't need it with + +[code]chmod 600 /home/bob/.davfs2/secrets[/code] + +Finally, mount the drive. + +[code]mount [baseurl]/dav[/code] + +You can now find your cloud at /home/bob/cloud and use it as though it were part of your local filesystem - even if the applications you are using have no dav support themselves. + +[b]Troubleshooting[/b] + +With some webservers and certain configurations, you may find davfs2 creating files with 0 bytes file size where other clients work just fine. This is generally caused by cache and locks. If you are affected by this issue, you need to edit your davfs2 configuration. + +[code]nano /etc/davfs2/davfs2.conf[/code] + +Your distribution will provide a sample configuration, and this file should already exist, however, most of it will be commented out with a # at the beginning of the line. + +First step is to remove locks. + +Edit the use_locks line so it reads [code]use_locks 0[/code]. + +Unmount your file system, remount your file system, and try copying over a file from the command line. Note you should copy a new file, and not overwrite an old one for this test. Leave it a minute or two then do [code]ls -l -h[/code] and check the file size of your new file is still greater than 0 bytes. If it is, stop there, and do nothing else. + +If that still doesn't work, disable the cache. Note that this has a performance impact so should only be done if disabling locks didn't solve your problem. Edit the cache_size and set it to [code]cache_size 0[/code] and also set file_refresh to [code]file_refresh 0[/code]. Unmount your filesystem, remount your file system, and test it again. + +If it [i]still[/i] doesn't work, there is one more thing you can try. (This one is caused by a bug in older versions of dav2fs itself, so updating to a new version may also help). Enable weak etag dropping by setting [code]drop_weak_etags 1[/code]. Unmount and remount your filesystem to apply the changes. + + +[h5]Dolphin[/h5] +Visit webdavs://example.com/dav where "example.com" is the URL of your hub. + +When prompted for a username and password, enter your channel name (the first part of your webbie - no @ or domain name) and password for your normal account. + +Note, if you are already logged in to the web interface via Konqueror, you will not be prompted for further authentication. + +[h5]Konqueror[/h5] + +Simply visit webdavs://example.com/dav after logging in to your hub, where "example.com" is the URL of your hub. + +No further authentication is required if you are logged in to your hub in the normal manner. + +Additionally, if one has authenticated at a different hub during their normal browser session, your identity will be passed to the cloud for these hubs too - meaning you can access any private files on any server, as long as you have permissions to see them, as long as you have visited that site earlier in your session. + +This functionality is normally restricted to the web interface, and is not available to any desktop software other than KDE. + +[h5]Nautilus[/h5] + +1. Open a File browsing window (that's Nautilus) +2. Select File > Connect to server from the menu +3. Type davs://<domain_name>/dav/<your_channelname> and click Connect +4. You will be prompted for your channel name (same as above) and password +5. Your personal DAV directory will be shown in the window + +[h5]Nemo[/h5] + +For (file browser) Nemo 1.8.2 under Linux Mint 15, Cinnamon 1.8.8. Nemo ist the standard file browser there. + +1st way +type "davs://<domain_name>/dav/<your_channelname>" in the address bar. + +2nd way +Menu > file > connect to server +Fill the dialog +- Server: hubzilla_domain_name +- Type: Secure WebDAV (https) +- Folder: /dav +- Username: yourchannelname +- Password: yourpassword + +Once open you can set a bookmark. + +[h5]Server Notes[/h5] + +Note: There have been reported issues with clients that use "chunked transfer encoding", which includes Apple iOS services, and also the "AnyClient" and "CyberDuck" tools. These work fine for downloads, but uploads often end up with files of zero size. This is caused by an incorrect implemention of chunked encoding in some current FCGI (fast-cgi) implementations. Apache running with PHP as a module does not have these issues, but when running under FCGI you may need to use alternative clients or use the web uploader. At the time of this writing the issue has been open and no updates provided for at least a year. If you encounter zero size files with other clients, please check the client notes; as there are occasional configuration issues which can also produce these symptoms. + +[h3]Saved Searches[/h3] + +In order to quickly find information, the 'saved search' widget may be used. This widget may be presented as a sidebar tool on your network page and possibly from your channel page. It is differentiated from the 'navigation bar' search tool in that it does not search the entire site, but only the subset of information available to your channel. + +Additionally the search terms you provide may activate a one-time search or be saved in a list for re-use. Saving the search item also invokes the search in addition to adding it to the saved list (which is displayed below the search text entry box). Any item in the list may be discarded if it is no longer needed. + +The saved search widget will provide autocompletion of channels (the results are prefixed with '@'), and hashtags (prefixed with '#'). You do not need to enter these tags; although entering the desired tag will reduce the autocomplete results to only hold the relevant information. The behaviour maps as follows: + +[list] +[*]@name - search your network stream for posts or comments written by 'name'. This will also change the post editor permissions to include only 'name'; as if this was a privacy group. +[*]#hashtag - search you network stream for posts containing #hashtag. +[*]text - search your network stream for posts containing 'text'. +[/list] + + +[h3]Remove Channel or Account[/h3] + +[h4]Remove Channel[/h4] + +Select the 'Remove Channel' link on your channel settings page or visit the URL: + + [baseurl]/removeme + +You will need to confirm your password and the channel you are currently logged into will be removed. + +[hl][i][b]This is irreversible.[/b][/i][/hl] + +If you have identity clones on other hubs this only removes by default the channel instance which exists on this hub. + +[h4]Remove Account[/h4] + +Select 'Remove Account' from your account settings page or visit the URL: + + [baseurl]/removeaccount + +You will need to confirm your password and the account you are currently logged into will be removed. + +[hl][i][b]This is irreversible.[/b][/i][/hl] + +All your channels will be deleted. If you have identity clones on other hubs this only removes by default the channels instances which exists on this hub. + diff --git a/doc/pl/toc.html b/doc/pl/toc.html new file mode 100644 index 000000000..cadc5676a --- /dev/null +++ b/doc/pl/toc.html @@ -0,0 +1,75 @@ +
      +
      +
      +

      + Poradniki +

      +
      +
      + +
      +
      +
      +
      +

      + Dla członków +

      +
      + +
      +
      +
      +

      + Dla administratorów +

      +
      + +
      +
      +
      +

      + Dla deweloperów +

      +
      + +
      +
      +
      +

      + Informacje o ... +

      +
      + +
      +
      diff --git a/util/hmessages.po b/util/hmessages.po index 2679119a1..961e07f2f 100644 --- a/util/hmessages.po +++ b/util/hmessages.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: 5.2RC\n" +"Project-Id-Version: 5.2.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-01-05 08:42+0000\n" +"POT-Creation-Date: 2021-01-21 12:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,15560 +17,15694 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../view/theme/redbasic/php/config.php:15 -#: ../../addon/cart/submodules/orderoptions.php:335 -#: ../../addon/cart/submodules/orderoptions.php:359 -#: ../../addon/cart/submodules/orderoptions.php:435 -#: ../../addon/cart/submodules/orderoptions.php:459 ../../include/text.php:3381 -#: ../../Zotlabs/Module/Admin/Site.php:191 -msgid "Default" -msgstr "" - -#: ../../view/theme/redbasic/php/config.php:16 -#: ../../view/theme/redbasic/php/config.php:19 -msgid "Focus (Hubzilla default)" +#: ../../Zotlabs/Access/Permissions.php:56 +msgid "Can view my channel stream and posts" msgstr "" -#: ../../view/theme/redbasic/php/config.php:94 -#: ../../addon/channelreputation/channelreputation.php:143 -#: ../../addon/openclipatar/openclipatar.php:53 -#: ../../addon/photocache/Mod_Photocache.php:67 -#: ../../addon/redred/Mod_Redred.php:90 ../../addon/redphotos/redphotos.php:136 -#: ../../addon/statusnet/Mod_Statusnet.php:193 -#: ../../addon/statusnet/Mod_Statusnet.php:251 -#: ../../addon/statusnet/Mod_Statusnet.php:306 -#: ../../addon/statusnet/statusnet.php:602 ../../addon/rtof/Mod_Rtof.php:72 -#: ../../addon/wppost/Mod_Wppost.php:109 -#: ../../addon/content_import/Mod_content_import.php:142 -#: ../../addon/openstreetmap/openstreetmap.php:155 -#: ../../addon/ijpost/Mod_Ijpost.php:72 -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:65 -#: ../../addon/dwpost/Mod_Dwpost.php:80 -#: ../../addon/startpage/Mod_Startpage.php:73 ../../addon/mail/Mod_Mail.php:310 -#: ../../addon/twitter/Mod_Twitter.php:184 -#: ../../addon/pumpio/Mod_Pumpio.php:115 -#: ../../addon/cart/submodules/subscriptions.php:410 -#: ../../addon/cart/submodules/hzservices.php:643 -#: ../../addon/cart/submodules/orderoptions.php:312 -#: ../../addon/cart/submodules/orderoptions.php:412 -#: ../../addon/cart/submodules/manualcat.php:248 -#: ../../addon/cart/Settings/Cart.php:132 -#: ../../addon/cart/Settings/Cart.php:142 ../../addon/cart/cart.php:1376 -#: ../../addon/nofed/Mod_Nofed.php:53 -#: ../../addon/smileybutton/Mod_Smileybutton.php:55 -#: ../../addon/redfiles/redfiles.php:124 ../../addon/diaspora/diaspora.php:75 -#: ../../addon/diaspora/Mod_Diaspora.php:100 ../../addon/piwik/piwik.php:95 -#: ../../addon/workflow/workflow.php:1461 -#: ../../addon/workflow/workflow.php:1520 -#: ../../addon/workflow/workflow.php:1639 -#: ../../addon/workflow/workflow.php:2742 -#: ../../addon/workflow/Settings/Mod_WorkflowSettings.php:94 -#: ../../addon/likebanner/likebanner.php:57 -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:56 ../../addon/hubwall/hubwall.php:95 -#: ../../addon/flashcards/Mod_Flashcards.php:262 -#: ../../addon/libertree/Mod_Libertree.php:70 ../../addon/logrot/logrot.php:35 -#: ../../addon/skeleton/Mod_Skeleton.php:51 -#: ../../addon/socialauth/Mod_SocialAuth.php:330 -#: ../../addon/nsfw/Mod_Nsfw.php:61 ../../addon/mailtest/mailtest.php:100 -#: ../../addon/ljpost/Mod_Ljpost.php:82 ../../addon/hzfiles/hzfiles.php:86 -#: ../../addon/pageheader/Mod_Pageheader.php:54 ../../addon/irc/irc.php:45 -#: ../../addon/xmpp/Mod_Xmpp.php:70 ../../include/js_strings.php:22 -#: ../../Zotlabs/Widget/Wiki_pages.php:42 -#: ../../Zotlabs/Widget/Wiki_pages.php:99 -#: ../../Zotlabs/Widget/Eventstools.php:16 ../../Zotlabs/Module/Tokens.php:188 -#: ../../Zotlabs/Module/Import_items.php:129 -#: ../../Zotlabs/Module/Import.php:645 ../../Zotlabs/Module/Setup.php:304 -#: ../../Zotlabs/Module/Setup.php:344 ../../Zotlabs/Module/Group.php:151 -#: ../../Zotlabs/Module/Group.php:167 ../../Zotlabs/Module/Oauth.php:111 -#: ../../Zotlabs/Module/Chat.php:209 ../../Zotlabs/Module/Chat.php:248 -#: ../../Zotlabs/Module/Poke.php:217 ../../Zotlabs/Module/Mitem.php:259 -#: ../../Zotlabs/Module/Filestorage.php:208 -#: ../../Zotlabs/Module/Connect.php:107 ../../Zotlabs/Module/Editpost.php:86 -#: ../../Zotlabs/Module/Admin/Themes.php:158 -#: ../../Zotlabs/Module/Admin/Features.php:66 -#: ../../Zotlabs/Module/Admin/Security.php:120 -#: ../../Zotlabs/Module/Admin/Accounts.php:168 -#: ../../Zotlabs/Module/Admin/Site.php:293 -#: ../../Zotlabs/Module/Admin/Logs.php:84 -#: ../../Zotlabs/Module/Admin/Channels.php:147 -#: ../../Zotlabs/Module/Admin/Account_edit.php:73 -#: ../../Zotlabs/Module/Admin/Profs.php:178 -#: ../../Zotlabs/Module/Admin/Addons.php:442 -#: ../../Zotlabs/Module/Events.php:501 ../../Zotlabs/Module/Permcats.php:129 -#: ../../Zotlabs/Module/Mood.php:158 ../../Zotlabs/Module/Appman.php:155 -#: ../../Zotlabs/Module/Email_validation.php:40 -#: ../../Zotlabs/Module/Photos.php:1058 ../../Zotlabs/Module/Photos.php:1098 -#: ../../Zotlabs/Module/Photos.php:1216 ../../Zotlabs/Module/Profiles.php:725 -#: ../../Zotlabs/Module/Invite.php:168 ../../Zotlabs/Module/Xchan.php:15 -#: ../../Zotlabs/Module/Affinity.php:87 ../../Zotlabs/Module/Rate.php:166 -#: ../../Zotlabs/Module/Settings/Network.php:62 -#: ../../Zotlabs/Module/Settings/Features.php:48 -#: ../../Zotlabs/Module/Settings/Channel.php:495 -#: ../../Zotlabs/Module/Settings/Account.php:103 -#: ../../Zotlabs/Module/Settings/Events.php:42 -#: ../../Zotlabs/Module/Settings/Manage.php:43 -#: ../../Zotlabs/Module/Settings/Channel_home.php:91 -#: ../../Zotlabs/Module/Settings/Calendar.php:42 -#: ../../Zotlabs/Module/Settings/Display.php:188 -#: ../../Zotlabs/Module/Settings/Directory.php:42 -#: ../../Zotlabs/Module/Settings/Editor.php:42 -#: ../../Zotlabs/Module/Settings/Connections.php:42 -#: ../../Zotlabs/Module/Settings/Photos.php:42 -#: ../../Zotlabs/Module/Settings/Profiles.php:52 -#: ../../Zotlabs/Module/Settings/Conversation.php:49 -#: ../../Zotlabs/Module/Defperms.php:266 ../../Zotlabs/Module/Pconfig.php:116 -#: ../../Zotlabs/Module/Oauth2.php:116 ../../Zotlabs/Module/Thing.php:328 -#: ../../Zotlabs/Module/Thing.php:381 ../../Zotlabs/Module/Pdledit.php:108 -#: ../../Zotlabs/Module/Wiki.php:215 ../../Zotlabs/Module/Connedit.php:896 -#: ../../Zotlabs/Module/Locs.php:132 ../../Zotlabs/Module/Sources.php:125 -#: ../../Zotlabs/Module/Sources.php:162 ../../Zotlabs/Lib/ThreadItem.php:825 -#: ../../Zotlabs/Storage/Browser.php:375 -msgid "Submit" +#: ../../Zotlabs/Access/Permissions.php:57 +msgid "Can send me their channel stream and posts" msgstr "" -#: ../../view/theme/redbasic/php/config.php:98 -msgid "Theme settings" +#: ../../Zotlabs/Access/Permissions.php:58 +msgid "Can view my default channel profile" msgstr "" -#: ../../view/theme/redbasic/php/config.php:99 -msgid "Narrow navbar" +#: ../../Zotlabs/Access/Permissions.php:59 +msgid "Can view my connections" msgstr "" -#: ../../view/theme/redbasic/php/config.php:99 -#: ../../view/theme/redbasic/php/config.php:116 -#: ../../addon/channelreputation/channelreputation.php:111 -#: ../../addon/redred/Mod_Redred.php:63 -#: ../../addon/statusnet/Mod_Statusnet.php:260 -#: ../../addon/statusnet/Mod_Statusnet.php:282 -#: ../../addon/statusnet/Mod_Statusnet.php:291 ../../addon/rtof/Mod_Rtof.php:49 -#: ../../addon/wppost/Mod_Wppost.php:86 ../../addon/wppost/Mod_Wppost.php:90 -#: ../../addon/wppost/Mod_Wppost.php:94 -#: ../../addon/content_import/Mod_content_import.php:137 -#: ../../addon/content_import/Mod_content_import.php:138 -#: ../../addon/ijpost/Mod_Ijpost.php:61 -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:45 -#: ../../addon/dwpost/Mod_Dwpost.php:61 ../../addon/dwpost/Mod_Dwpost.php:65 -#: ../../addon/twitter/Mod_Twitter.php:162 -#: ../../addon/twitter/Mod_Twitter.php:171 ../../addon/pumpio/Mod_Pumpio.php:94 -#: ../../addon/pumpio/Mod_Pumpio.php:98 ../../addon/pumpio/Mod_Pumpio.php:102 -#: ../../addon/cart/submodules/subscriptions.php:153 -#: ../../addon/cart/submodules/subscriptions.php:425 -#: ../../addon/cart/submodules/hzservices.php:65 -#: ../../addon/cart/submodules/hzservices.php:649 -#: ../../addon/cart/submodules/hzservices.php:653 -#: ../../addon/cart/submodules/orderoptions.php:72 -#: ../../addon/cart/submodules/orderoptions.php:338 -#: ../../addon/cart/submodules/orderoptions.php:362 -#: ../../addon/cart/submodules/orderoptions.php:438 -#: ../../addon/cart/submodules/orderoptions.php:462 -#: ../../addon/cart/submodules/paypalbutton.php:87 -#: ../../addon/cart/submodules/paypalbutton.php:95 -#: ../../addon/cart/submodules/paypalbuttonV2.php:88 -#: ../../addon/cart/submodules/paypalbuttonV2.php:96 -#: ../../addon/cart/submodules/manualcat.php:63 -#: ../../addon/cart/submodules/manualcat.php:254 -#: ../../addon/cart/submodules/manualcat.php:258 -#: ../../addon/cart/Settings/Cart.php:61 ../../addon/cart/Settings/Cart.php:73 -#: ../../addon/cart/cart.php:1370 ../../addon/nofed/Mod_Nofed.php:42 -#: ../../addon/smileybutton/Mod_Smileybutton.php:44 -#: ../../addon/libertree/Mod_Libertree.php:59 -#: ../../addon/socialauth/Mod_SocialAuth.php:214 -#: ../../addon/ljpost/Mod_Ljpost.php:63 ../../addon/ljpost/Mod_Ljpost.php:67 -#: ../../addon/ljpost/Mod_Ljpost.php:71 ../../include/conversation.php:1466 -#: ../../include/dir_fns.php:142 ../../include/dir_fns.php:143 -#: ../../include/dir_fns.php:144 ../../Zotlabs/Module/Import.php:634 -#: ../../Zotlabs/Module/Import.php:638 ../../Zotlabs/Module/Import.php:639 -#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177 -#: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257 -#: ../../Zotlabs/Module/Filestorage.php:203 -#: ../../Zotlabs/Module/Filestorage.php:211 -#: ../../Zotlabs/Module/Admin/Site.php:259 ../../Zotlabs/Module/Events.php:478 -#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Api.php:99 -#: ../../Zotlabs/Module/Photos.php:673 ../../Zotlabs/Module/Profiles.php:683 -#: ../../Zotlabs/Module/Settings/Channel.php:311 -#: ../../Zotlabs/Module/Settings/Display.php:88 -#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 -#: ../../Zotlabs/Module/Defperms.php:198 ../../Zotlabs/Module/Wiki.php:227 -#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 -#: ../../Zotlabs/Module/Connedit.php:788 ../../Zotlabs/Module/Sources.php:124 -#: ../../Zotlabs/Module/Sources.php:159 ../../Zotlabs/Lib/Libzotdir.php:164 -#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:167 -#: ../../Zotlabs/Storage/Browser.php:303 ../../Zotlabs/Storage/Browser.php:304 -#: ../../Zotlabs/Storage/Browser.php:305 ../../Zotlabs/Storage/Browser.php:382 -#: ../../Zotlabs/Storage/Browser.php:384 ../../Zotlabs/Storage/Browser.php:545 -#: ../../boot.php:1704 -msgid "No" +#: ../../Zotlabs/Access/Permissions.php:60 +msgid "Can view my file storage and photos" msgstr "" -#: ../../view/theme/redbasic/php/config.php:99 -#: ../../view/theme/redbasic/php/config.php:116 -#: ../../addon/channelreputation/channelreputation.php:111 -#: ../../addon/redred/Mod_Redred.php:63 -#: ../../addon/statusnet/Mod_Statusnet.php:260 -#: ../../addon/statusnet/Mod_Statusnet.php:282 -#: ../../addon/statusnet/Mod_Statusnet.php:291 ../../addon/rtof/Mod_Rtof.php:49 -#: ../../addon/wppost/Mod_Wppost.php:86 ../../addon/wppost/Mod_Wppost.php:90 -#: ../../addon/wppost/Mod_Wppost.php:94 -#: ../../addon/content_import/Mod_content_import.php:137 -#: ../../addon/content_import/Mod_content_import.php:138 -#: ../../addon/ijpost/Mod_Ijpost.php:61 -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:45 -#: ../../addon/dwpost/Mod_Dwpost.php:61 ../../addon/dwpost/Mod_Dwpost.php:65 -#: ../../addon/twitter/Mod_Twitter.php:162 -#: ../../addon/twitter/Mod_Twitter.php:171 ../../addon/pumpio/Mod_Pumpio.php:94 -#: ../../addon/pumpio/Mod_Pumpio.php:98 ../../addon/pumpio/Mod_Pumpio.php:102 -#: ../../addon/cart/submodules/subscriptions.php:153 -#: ../../addon/cart/submodules/subscriptions.php:425 -#: ../../addon/cart/submodules/hzservices.php:65 -#: ../../addon/cart/submodules/hzservices.php:649 -#: ../../addon/cart/submodules/hzservices.php:653 -#: ../../addon/cart/submodules/orderoptions.php:72 -#: ../../addon/cart/submodules/orderoptions.php:337 -#: ../../addon/cart/submodules/orderoptions.php:361 -#: ../../addon/cart/submodules/orderoptions.php:437 -#: ../../addon/cart/submodules/orderoptions.php:461 -#: ../../addon/cart/submodules/paypalbutton.php:87 -#: ../../addon/cart/submodules/paypalbutton.php:95 -#: ../../addon/cart/submodules/paypalbuttonV2.php:88 -#: ../../addon/cart/submodules/paypalbuttonV2.php:96 -#: ../../addon/cart/submodules/manualcat.php:63 -#: ../../addon/cart/submodules/manualcat.php:254 -#: ../../addon/cart/submodules/manualcat.php:258 -#: ../../addon/cart/Settings/Cart.php:61 ../../addon/cart/Settings/Cart.php:73 -#: ../../addon/cart/cart.php:1370 ../../addon/nofed/Mod_Nofed.php:42 -#: ../../addon/smileybutton/Mod_Smileybutton.php:44 -#: ../../addon/libertree/Mod_Libertree.php:59 -#: ../../addon/socialauth/Mod_SocialAuth.php:214 -#: ../../addon/ljpost/Mod_Ljpost.php:63 ../../addon/ljpost/Mod_Ljpost.php:67 -#: ../../addon/ljpost/Mod_Ljpost.php:71 ../../include/conversation.php:1466 -#: ../../include/dir_fns.php:142 ../../include/dir_fns.php:143 -#: ../../include/dir_fns.php:144 ../../Zotlabs/Module/Import.php:634 -#: ../../Zotlabs/Module/Import.php:638 ../../Zotlabs/Module/Import.php:639 -#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177 -#: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257 -#: ../../Zotlabs/Module/Filestorage.php:203 -#: ../../Zotlabs/Module/Filestorage.php:211 -#: ../../Zotlabs/Module/Admin/Site.php:261 ../../Zotlabs/Module/Events.php:478 -#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Api.php:98 -#: ../../Zotlabs/Module/Photos.php:673 ../../Zotlabs/Module/Profiles.php:683 -#: ../../Zotlabs/Module/Settings/Channel.php:311 -#: ../../Zotlabs/Module/Settings/Display.php:88 -#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 -#: ../../Zotlabs/Module/Defperms.php:198 ../../Zotlabs/Module/Wiki.php:227 -#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 -#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 -#: ../../Zotlabs/Lib/Libzotdir.php:164 ../../Zotlabs/Lib/Libzotdir.php:165 -#: ../../Zotlabs/Lib/Libzotdir.php:167 ../../Zotlabs/Storage/Browser.php:303 -#: ../../Zotlabs/Storage/Browser.php:304 ../../Zotlabs/Storage/Browser.php:305 -#: ../../Zotlabs/Storage/Browser.php:382 ../../Zotlabs/Storage/Browser.php:384 -#: ../../Zotlabs/Storage/Browser.php:545 ../../boot.php:1704 -msgid "Yes" +#: ../../Zotlabs/Access/Permissions.php:61 +msgid "Can upload/modify my file storage and photos" msgstr "" -#: ../../view/theme/redbasic/php/config.php:100 -msgid "Navigation bar background color" +#: ../../Zotlabs/Access/Permissions.php:62 +msgid "Can view my channel webpages" msgstr "" -#: ../../view/theme/redbasic/php/config.php:101 -msgid "Navigation bar icon color " +#: ../../Zotlabs/Access/Permissions.php:63 +msgid "Can view my wiki pages" msgstr "" -#: ../../view/theme/redbasic/php/config.php:102 -msgid "Navigation bar active icon color " +#: ../../Zotlabs/Access/Permissions.php:64 +msgid "Can create/edit my channel webpages" msgstr "" -#: ../../view/theme/redbasic/php/config.php:103 -msgid "Link color" +#: ../../Zotlabs/Access/Permissions.php:65 +msgid "Can write to my wiki pages" msgstr "" -#: ../../view/theme/redbasic/php/config.php:104 -msgid "Set font-color for banner" +#: ../../Zotlabs/Access/Permissions.php:66 +msgid "Can post on my channel (wall) page" msgstr "" -#: ../../view/theme/redbasic/php/config.php:105 -msgid "Set the background color" +#: ../../Zotlabs/Access/Permissions.php:67 +msgid "Can comment on or like my posts" msgstr "" -#: ../../view/theme/redbasic/php/config.php:106 -msgid "Set the background image" +#: ../../Zotlabs/Access/Permissions.php:68 +msgid "Can send me private mail messages" msgstr "" -#: ../../view/theme/redbasic/php/config.php:107 -msgid "Set the background color of items" +#: ../../Zotlabs/Access/Permissions.php:69 +msgid "Can like/dislike profiles and profile things" msgstr "" -#: ../../view/theme/redbasic/php/config.php:108 -msgid "Set the background color of comments" +#: ../../Zotlabs/Access/Permissions.php:70 +msgid "Can forward to all my channel connections via ! mentions in posts" msgstr "" -#: ../../view/theme/redbasic/php/config.php:109 -msgid "Set font-size for the entire application" +#: ../../Zotlabs/Access/Permissions.php:71 +msgid "Can chat with me" msgstr "" -#: ../../view/theme/redbasic/php/config.php:109 -msgid "Examples: 1rem, 100%, 16px" +#: ../../Zotlabs/Access/Permissions.php:72 +msgid "Can source my public posts in derived channels" msgstr "" -#: ../../view/theme/redbasic/php/config.php:110 -msgid "Set font-color for posts and comments" +#: ../../Zotlabs/Access/Permissions.php:73 +msgid "Can administer my channel" msgstr "" -#: ../../view/theme/redbasic/php/config.php:111 -msgid "Set radius of corners" +#: ../../Zotlabs/Access/PermissionRoles.php:287 +msgid "Social Networking" msgstr "" -#: ../../view/theme/redbasic/php/config.php:111 -msgid "Example: 4px" +#: ../../Zotlabs/Access/PermissionRoles.php:288 +msgid "Social - Federation" msgstr "" -#: ../../view/theme/redbasic/php/config.php:112 -msgid "Set shadow depth of photos" +#: ../../Zotlabs/Access/PermissionRoles.php:289 +msgid "Social - Mostly Public" msgstr "" -#: ../../view/theme/redbasic/php/config.php:113 -msgid "Set maximum width of content region in pixel" +#: ../../Zotlabs/Access/PermissionRoles.php:290 +msgid "Social - Restricted" msgstr "" -#: ../../view/theme/redbasic/php/config.php:113 -msgid "Leave empty for default width" +#: ../../Zotlabs/Access/PermissionRoles.php:291 +msgid "Social - Private" msgstr "" -#: ../../view/theme/redbasic/php/config.php:114 -msgid "Set size of conversation author photo" +#: ../../Zotlabs/Access/PermissionRoles.php:294 +msgid "Community Forum" msgstr "" -#: ../../view/theme/redbasic/php/config.php:115 -msgid "Set size of followup author photos" +#: ../../Zotlabs/Access/PermissionRoles.php:295 +msgid "Forum - Mostly Public" msgstr "" -#: ../../view/theme/redbasic/php/config.php:116 -msgid "Show advanced settings" +#: ../../Zotlabs/Access/PermissionRoles.php:296 +msgid "Forum - Restricted" msgstr "" -#: ../../util/nconfig.php:34 -msgid "Source channel not found." +#: ../../Zotlabs/Access/PermissionRoles.php:297 +msgid "Forum - Private" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:101 -#: ../../addon/channelreputation/channelreputation.php:102 -#: ../../addon/cart/myshop.php:144 ../../addon/cart/myshop.php:180 -#: ../../addon/cart/myshop.php:214 ../../addon/cart/myshop.php:261 -#: ../../addon/cart/myshop.php:296 ../../addon/cart/myshop.php:319 -msgid "Access Denied" +#: ../../Zotlabs/Access/PermissionRoles.php:300 +msgid "Feed Republish" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:109 -msgid "Enable Community Moderation" +#: ../../Zotlabs/Access/PermissionRoles.php:301 +msgid "Feed - Mostly Public" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:117 -msgid "Reputation automatically given to new members" +#: ../../Zotlabs/Access/PermissionRoles.php:302 +msgid "Feed - Restricted" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:118 -msgid "Reputation will never fall below this value" +#: ../../Zotlabs/Access/PermissionRoles.php:305 +msgid "Special Purpose" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:119 -msgid "Minimum reputation before posting is allowed" +#: ../../Zotlabs/Access/PermissionRoles.php:306 +msgid "Special - Celebrity/Soapbox" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:120 -msgid "Minimum reputation before commenting is allowed" +#: ../../Zotlabs/Access/PermissionRoles.php:307 +msgid "Special - Group Repository" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:121 -msgid "Minimum reputation before a member is able to moderate other posts" +#: ../../Zotlabs/Access/PermissionRoles.php:310 +#: ../../Zotlabs/Module/Cdav.php:1384 ../../Zotlabs/Module/Profiles.php:797 +#: ../../Zotlabs/Module/Connedit.php:927 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 ../../include/selectors.php:115 +#: ../../include/selectors.php:151 ../../include/connections.php:741 +#: ../../include/connections.php:748 ../../include/event.php:1429 +#: ../../include/event.php:1436 +msgid "Other" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:122 -msgid "" -"Max ratio of moderator's reputation that can be added to/deducted from " -"reputation of person being moderated" +#: ../../Zotlabs/Access/PermissionRoles.php:311 +msgid "Custom/Expert Mode" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:123 -msgid "Reputation \"cost\" to post" +#: ../../Zotlabs/Module/Authtest.php:16 ../../Zotlabs/Module/Pdledit.php:35 +#: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Events.php:277 +#: ../../Zotlabs/Module/Bookmarks.php:70 ../../Zotlabs/Module/Webpages.php:133 +#: ../../Zotlabs/Module/Profiles.php:200 ../../Zotlabs/Module/Profiles.php:637 +#: ../../Zotlabs/Module/Like.php:230 ../../Zotlabs/Module/Defperms.php:182 +#: ../../Zotlabs/Module/Layouts.php:71 ../../Zotlabs/Module/Layouts.php:78 +#: ../../Zotlabs/Module/Layouts.php:89 ../../Zotlabs/Module/Group.php:15 +#: ../../Zotlabs/Module/Group.php:31 ../../Zotlabs/Module/Appman.php:87 +#: ../../Zotlabs/Module/Message.php:18 ../../Zotlabs/Module/Moderate.php:15 +#: ../../Zotlabs/Module/New_channel.php:105 +#: ../../Zotlabs/Module/New_channel.php:130 +#: ../../Zotlabs/Module/Filestorage.php:20 +#: ../../Zotlabs/Module/Filestorage.php:78 +#: ../../Zotlabs/Module/Filestorage.php:96 +#: ../../Zotlabs/Module/Filestorage.php:119 +#: ../../Zotlabs/Module/Filestorage.php:165 +#: ../../Zotlabs/Module/Card_edit.php:51 +#: ../../Zotlabs/Module/Viewconnections.php:28 +#: ../../Zotlabs/Module/Viewconnections.php:33 ../../Zotlabs/Module/Wiki.php:59 +#: ../../Zotlabs/Module/Wiki.php:285 ../../Zotlabs/Module/Wiki.php:428 +#: ../../Zotlabs/Module/Blocks.php:73 ../../Zotlabs/Module/Blocks.php:80 +#: ../../Zotlabs/Module/Locs.php:100 ../../Zotlabs/Module/Connedit.php:396 +#: ../../Zotlabs/Module/Profile_photo.php:338 +#: ../../Zotlabs/Module/Profile_photo.php:351 +#: ../../Zotlabs/Module/Sharedwithme.php:19 +#: ../../Zotlabs/Module/Editlayout.php:67 +#: ../../Zotlabs/Module/Editlayout.php:90 ../../Zotlabs/Module/Manage.php:10 +#: ../../Zotlabs/Module/Item.php:485 ../../Zotlabs/Module/Item.php:504 +#: ../../Zotlabs/Module/Item.php:514 ../../Zotlabs/Module/Item.php:1442 +#: ../../Zotlabs/Module/Rate.php:113 ../../Zotlabs/Module/Page.php:34 +#: ../../Zotlabs/Module/Page.php:133 ../../Zotlabs/Module/Achievements.php:34 +#: ../../Zotlabs/Module/Regmod.php:20 ../../Zotlabs/Module/Editblock.php:67 +#: ../../Zotlabs/Module/Chat.php:113 ../../Zotlabs/Module/Chat.php:118 +#: ../../Zotlabs/Module/Vote.php:19 ../../Zotlabs/Module/Display.php:425 +#: ../../Zotlabs/Module/Photos.php:71 ../../Zotlabs/Module/Channel.php:177 +#: ../../Zotlabs/Module/Channel.php:332 ../../Zotlabs/Module/Channel.php:371 +#: ../../Zotlabs/Module/Cards.php:86 ../../Zotlabs/Module/Connections.php:32 +#: ../../Zotlabs/Module/Editpost.php:17 ../../Zotlabs/Module/Block.php:24 +#: ../../Zotlabs/Module/Block.php:74 ../../Zotlabs/Module/Common.php:38 +#: ../../Zotlabs/Module/Editwebpage.php:68 +#: ../../Zotlabs/Module/Editwebpage.php:89 +#: ../../Zotlabs/Module/Editwebpage.php:107 +#: ../../Zotlabs/Module/Editwebpage.php:121 ../../Zotlabs/Module/Profile.php:85 +#: ../../Zotlabs/Module/Profile.php:101 +#: ../../Zotlabs/Module/Article_edit.php:51 ../../Zotlabs/Module/Thing.php:282 +#: ../../Zotlabs/Module/Thing.php:302 ../../Zotlabs/Module/Thing.php:343 +#: ../../Zotlabs/Module/Suggest.php:32 +#: ../../Zotlabs/Module/Notifications.php:11 +#: ../../Zotlabs/Module/Articles.php:89 ../../Zotlabs/Module/Setup.php:206 +#: ../../Zotlabs/Module/Mitem.php:129 ../../Zotlabs/Module/Mood.php:126 +#: ../../Zotlabs/Module/Register.php:80 +#: ../../Zotlabs/Module/Channel_calendar.php:230 +#: ../../Zotlabs/Module/Invite.php:21 ../../Zotlabs/Module/Invite.php:102 +#: ../../Zotlabs/Module/Service_limits.php:11 +#: ../../Zotlabs/Module/Cover_photo.php:341 +#: ../../Zotlabs/Module/Cover_photo.php:354 ../../Zotlabs/Module/Menu.php:130 +#: ../../Zotlabs/Module/Menu.php:141 ../../Zotlabs/Module/Sources.php:80 +#: ../../Zotlabs/Module/Poke.php:157 ../../Zotlabs/Module/Network.php:19 +#: ../../Zotlabs/Module/Attach_edit.php:90 +#: ../../Zotlabs/Module/Attach_edit.php:99 +#: ../../Zotlabs/Module/Attach_edit.php:106 +#: ../../Zotlabs/Module/Settings.php:59 ../../Zotlabs/Module/Viewsrc.php:19 +#: ../../Zotlabs/Web/WebServer.php:116 ../../Zotlabs/Lib/Chatroom.php:135 +#: ../../include/photos.php:27 ../../include/attach.php:156 +#: ../../include/attach.php:205 ../../include/attach.php:278 +#: ../../include/attach.php:329 ../../include/attach.php:424 +#: ../../include/attach.php:438 ../../include/attach.php:445 +#: ../../include/attach.php:527 ../../include/attach.php:1091 +#: ../../include/attach.php:1164 ../../include/attach.php:1327 +#: ../../include/items.php:3996 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:53 +#: ../../extend/addon/hzaddons/keepout/keepout.php:36 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:25 +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:44 +msgid "Permission denied." msgstr "" -#: ../../addon/channelreputation/channelreputation.php:124 -msgid "Reputation \"cost\" to comment" +#: ../../Zotlabs/Module/Pdledit.php:27 +msgid "Layout updated." msgstr "" -#: ../../addon/channelreputation/channelreputation.php:125 -msgid "" -"Reputation automatically recovers at this rate per hour until it reaches " -"minimum_to_post" +#: ../../Zotlabs/Module/Pdledit.php:43 +msgid "PDL Editor App" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:126 -msgid "" -"When minimum_to_moderate > reputation > minimum_to_post reputation recovers " -"at this rate per hour" +#: ../../Zotlabs/Module/Pdledit.php:43 ../../Zotlabs/Module/Cdav.php:876 +#: ../../Zotlabs/Module/Bookmarks.php:78 ../../Zotlabs/Module/Webpages.php:48 +#: ../../Zotlabs/Module/Defperms.php:190 ../../Zotlabs/Module/Pubstream.php:20 +#: ../../Zotlabs/Module/Group.php:107 ../../Zotlabs/Module/Oauth.php:100 +#: ../../Zotlabs/Module/Oauth2.php:106 ../../Zotlabs/Module/Wiki.php:52 +#: ../../Zotlabs/Module/Chat.php:100 ../../Zotlabs/Module/Uexport.php:61 +#: ../../Zotlabs/Module/Cards.php:51 ../../Zotlabs/Module/Affinity.php:52 +#: ../../Zotlabs/Module/Randprof.php:29 ../../Zotlabs/Module/Suggest.php:40 +#: ../../Zotlabs/Module/Notes.php:57 ../../Zotlabs/Module/Tokens.php:99 +#: ../../Zotlabs/Module/Articles.php:52 ../../Zotlabs/Module/Mood.php:134 +#: ../../Zotlabs/Module/Permcats.php:63 ../../Zotlabs/Module/Probe.php:18 +#: ../../Zotlabs/Module/Invite.php:110 ../../Zotlabs/Module/Lang.php:17 +#: ../../Zotlabs/Module/Sources.php:88 ../../Zotlabs/Module/Poke.php:165 +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22 +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50 +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:58 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:23 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:38 +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35 +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20 +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33 +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35 +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:39 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21 +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:43 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21 +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34 +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50 +msgid "Not Installed" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:140 -msgid "Community Moderation Settings" +#: ../../Zotlabs/Module/Pdledit.php:44 +msgid "Provides the ability to edit system page layouts" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:232 -msgid "Channel Reputation" +#: ../../Zotlabs/Module/Pdledit.php:57 ../../Zotlabs/Module/Pdledit.php:100 +msgid "Edit System Page Description" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:233 -#: ../../include/acl_selectors.php:155 ../../Zotlabs/Widget/Pinned.php:160 -#: ../../Zotlabs/Module/Photos.php:1275 ../../Zotlabs/Lib/ThreadItem.php:495 -#: ../../Zotlabs/Storage/Browser.php:404 -msgid "Close" +#: ../../Zotlabs/Module/Pdledit.php:78 +msgid "(modified)" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:236 -msgid "An Error has occurred." +#: ../../Zotlabs/Module/Pdledit.php:78 ../../Zotlabs/Module/Lostpass.php:133 +msgid "Reset" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:254 -msgid "Upvote" +#: ../../Zotlabs/Module/Pdledit.php:95 +msgid "Layout not found." msgstr "" -#: ../../addon/channelreputation/channelreputation.php:255 -msgid "Downvote" +#: ../../Zotlabs/Module/Pdledit.php:101 +msgid "Module Name:" msgstr "" -#: ../../addon/channelreputation/channelreputation.php:414 -msgid "Can moderate reputation on my channel." +#: ../../Zotlabs/Module/Pdledit.php:102 +msgid "Layout Help" msgstr "" -#: ../../addon/superblock/superblock.php:337 -msgid "Block Completely" +#: ../../Zotlabs/Module/Pdledit.php:103 +msgid "Edit another layout" msgstr "" -#: ../../addon/superblock/Mod_Superblock.php:20 -msgid "Superblock App" +#: ../../Zotlabs/Module/Pdledit.php:104 +msgid "System layout" msgstr "" -#: ../../addon/superblock/Mod_Superblock.php:20 -#: ../../addon/nsabait/Mod_Nsabait.php:20 -#: ../../addon/rainbowtag/Mod_Rainbowtag.php:21 -#: ../../addon/photocache/Mod_Photocache.php:42 -#: ../../addon/gallery/Mod_Gallery.php:58 -#: ../../addon/planets/Mod_Planets.php:20 ../../addon/redred/Mod_Redred.php:50 -#: ../../addon/statusnet/Mod_Statusnet.php:146 ../../addon/rtof/Mod_Rtof.php:36 -#: ../../addon/wppost/Mod_Wppost.php:43 ../../addon/hsse/Mod_Hsse.php:21 -#: ../../addon/ijpost/Mod_Ijpost.php:35 -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:40 -#: ../../addon/dwpost/Mod_Dwpost.php:39 -#: ../../addon/startpage/Mod_Startpage.php:50 -#: ../../addon/twitter/Mod_Twitter.php:78 ../../addon/pumpio/Mod_Pumpio.php:53 -#: ../../addon/sendzid/Mod_Sendzid.php:20 ../../addon/nofed/Mod_Nofed.php:33 -#: ../../addon/smileybutton/Mod_Smileybutton.php:35 -#: ../../addon/diaspora/Mod_Diaspora.php:58 -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:34 -#: ../../addon/libertree/Mod_Libertree.php:35 -#: ../../addon/hideaside/Mod_Hideaside.php:23 -#: ../../addon/skeleton/Mod_Skeleton.php:32 ../../addon/nsfw/Mod_Nsfw.php:33 -#: ../../addon/gnusoc/Mod_Gnusoc.php:22 ../../addon/ljpost/Mod_Ljpost.php:38 -#: ../../addon/authchoose/Mod_Authchoose.php:28 -#: ../../addon/pageheader/Mod_Pageheader.php:34 -#: ../../addon/xmpp/Mod_Xmpp.php:35 ../../Zotlabs/Module/Tokens.php:99 -#: ../../Zotlabs/Module/Group.php:107 ../../Zotlabs/Module/Oauth.php:100 -#: ../../Zotlabs/Module/Chat.php:100 ../../Zotlabs/Module/Poke.php:165 -#: ../../Zotlabs/Module/Cdav.php:876 ../../Zotlabs/Module/Webpages.php:48 -#: ../../Zotlabs/Module/Pubstream.php:20 ../../Zotlabs/Module/Permcats.php:63 -#: ../../Zotlabs/Module/Lang.php:17 ../../Zotlabs/Module/Uexport.php:61 -#: ../../Zotlabs/Module/Mood.php:134 ../../Zotlabs/Module/Cards.php:51 -#: ../../Zotlabs/Module/Articles.php:52 ../../Zotlabs/Module/Bookmarks.php:78 -#: ../../Zotlabs/Module/Probe.php:18 ../../Zotlabs/Module/Invite.php:110 -#: ../../Zotlabs/Module/Notes.php:57 ../../Zotlabs/Module/Affinity.php:52 -#: ../../Zotlabs/Module/Defperms.php:190 ../../Zotlabs/Module/Oauth2.php:106 -#: ../../Zotlabs/Module/Randprof.php:29 ../../Zotlabs/Module/Pdledit.php:43 -#: ../../Zotlabs/Module/Wiki.php:52 ../../Zotlabs/Module/Suggest.php:40 -#: ../../Zotlabs/Module/Sources.php:88 -msgid "Not Installed" -msgstr "" - -#: ../../addon/superblock/Mod_Superblock.php:21 -msgid "Block channels" +#: ../../Zotlabs/Module/Pdledit.php:108 ../../Zotlabs/Module/Events.php:501 +#: ../../Zotlabs/Module/Profiles.php:725 ../../Zotlabs/Module/Import.php:645 +#: ../../Zotlabs/Module/Defperms.php:266 ../../Zotlabs/Module/Group.php:151 +#: ../../Zotlabs/Module/Group.php:167 ../../Zotlabs/Module/Appman.php:155 +#: ../../Zotlabs/Module/Oauth.php:111 ../../Zotlabs/Module/Import_items.php:129 +#: ../../Zotlabs/Module/Connect.php:107 +#: ../../Zotlabs/Module/Filestorage.php:208 ../../Zotlabs/Module/Oauth2.php:116 +#: ../../Zotlabs/Module/Wiki.php:215 ../../Zotlabs/Module/Locs.php:132 +#: ../../Zotlabs/Module/Connedit.php:896 ../../Zotlabs/Module/Rate.php:166 +#: ../../Zotlabs/Module/Xchan.php:15 ../../Zotlabs/Module/Chat.php:209 +#: ../../Zotlabs/Module/Chat.php:248 ../../Zotlabs/Module/Photos.php:1058 +#: ../../Zotlabs/Module/Photos.php:1098 ../../Zotlabs/Module/Photos.php:1216 +#: ../../Zotlabs/Module/Editpost.php:86 ../../Zotlabs/Module/Affinity.php:87 +#: ../../Zotlabs/Module/Pconfig.php:116 +#: ../../Zotlabs/Module/Admin/Themes.php:158 +#: ../../Zotlabs/Module/Admin/Security.php:120 +#: ../../Zotlabs/Module/Admin/Accounts.php:168 +#: ../../Zotlabs/Module/Admin/Features.php:66 +#: ../../Zotlabs/Module/Admin/Channels.php:147 +#: ../../Zotlabs/Module/Admin/Logs.php:84 +#: ../../Zotlabs/Module/Admin/Account_edit.php:73 +#: ../../Zotlabs/Module/Admin/Addons.php:442 +#: ../../Zotlabs/Module/Admin/Site.php:293 +#: ../../Zotlabs/Module/Admin/Profs.php:178 ../../Zotlabs/Module/Thing.php:328 +#: ../../Zotlabs/Module/Thing.php:381 +#: ../../Zotlabs/Module/Email_validation.php:40 +#: ../../Zotlabs/Module/Tokens.php:188 ../../Zotlabs/Module/Setup.php:304 +#: ../../Zotlabs/Module/Setup.php:344 ../../Zotlabs/Module/Mitem.php:259 +#: ../../Zotlabs/Module/Mood.php:158 ../../Zotlabs/Module/Permcats.php:129 +#: ../../Zotlabs/Module/Settings/Account.php:103 +#: ../../Zotlabs/Module/Settings/Events.php:42 +#: ../../Zotlabs/Module/Settings/Profiles.php:52 +#: ../../Zotlabs/Module/Settings/Editor.php:42 +#: ../../Zotlabs/Module/Settings/Features.php:48 +#: ../../Zotlabs/Module/Settings/Manage.php:43 +#: ../../Zotlabs/Module/Settings/Display.php:188 +#: ../../Zotlabs/Module/Settings/Photos.php:42 +#: ../../Zotlabs/Module/Settings/Channel.php:495 +#: ../../Zotlabs/Module/Settings/Connections.php:42 +#: ../../Zotlabs/Module/Settings/Calendar.php:42 +#: ../../Zotlabs/Module/Settings/Directory.php:42 +#: ../../Zotlabs/Module/Settings/Channel_home.php:91 +#: ../../Zotlabs/Module/Settings/Network.php:62 +#: ../../Zotlabs/Module/Settings/Conversation.php:49 +#: ../../Zotlabs/Module/Invite.php:168 ../../Zotlabs/Module/Sources.php:125 +#: ../../Zotlabs/Module/Sources.php:162 ../../Zotlabs/Module/Poke.php:217 +#: ../../Zotlabs/Storage/Browser.php:382 ../../Zotlabs/Lib/ThreadItem.php:825 +#: ../../Zotlabs/Widget/Wiki_pages.php:42 +#: ../../Zotlabs/Widget/Wiki_pages.php:99 +#: ../../Zotlabs/Widget/Eventstools.php:16 ../../include/js_strings.php:22 +#: ../../extend/addon/hzaddons/irc/irc.php:45 +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:95 +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:57 +#: ../../extend/addon/hzaddons/piwik/piwik.php:95 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:143 +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:51 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:90 +#: ../../extend/addon/hzaddons/cart/cart.php:1376 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:312 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:412 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:643 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:410 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:248 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:132 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:142 +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:86 +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:100 +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:75 +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:155 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:82 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1461 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1520 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1639 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2742 +#: ../../extend/addon/hzaddons/workflow/Settings/Mod_WorkflowSettings.php:94 +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:70 +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:61 +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:67 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:70 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:602 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:193 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:251 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:306 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:65 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:72 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:262 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:330 +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:136 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:184 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:80 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:53 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:142 +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:54 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:310 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:53 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:55 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:72 +#: ../../extend/addon/hzaddons/logrot/logrot.php:35 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:109 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:115 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:100 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:124 +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:56 +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:73 +#: ../../view/theme/redbasic/php/config.php:94 +msgid "Submit" msgstr "" -#: ../../addon/superblock/Mod_Superblock.php:63 -msgid "superblock settings updated" +#: ../../Zotlabs/Module/Z6trans.php:19 +msgid "Update to Hubzilla 5.0 step 2" msgstr "" -#: ../../addon/superblock/Mod_Superblock.php:87 -msgid "Currently blocked" +#: ../../Zotlabs/Module/Z6trans.php:21 +msgid "To complete the update please run" msgstr "" -#: ../../addon/superblock/Mod_Superblock.php:89 -msgid "No channels currently blocked" +#: ../../Zotlabs/Module/Z6trans.php:23 +msgid "php util/z6convert.php" msgstr "" -#: ../../addon/superblock/Mod_Superblock.php:91 -#: ../../Zotlabs/Module/Tagrm.php:137 ../../Zotlabs/Module/Admin/Addons.php:459 -#: ../../Zotlabs/Module/Profile_photo.php:501 -#: ../../Zotlabs/Module/Cover_photo.php:424 ../../Zotlabs/Module/Photos.php:996 -msgid "Remove" +#: ../../Zotlabs/Module/Z6trans.php:25 +msgid "from the terminal." msgstr "" -#: ../../addon/nsabait/Mod_Nsabait.php:20 -#: ../../addon/nsabait/Mod_Nsabait.php:24 -msgid "NSA Bait App" +#: ../../Zotlabs/Module/Dreport.php:10 ../../Zotlabs/Module/Dreport.php:82 +#: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Cloud.php:123 +#: ../../Zotlabs/Module/Like.php:332 ../../Zotlabs/Module/Group.php:99 +#: ../../Zotlabs/Module/Import_items.php:120 +#: ../../Zotlabs/Module/Subthread.php:86 ../../Zotlabs/Module/Share.php:72 +#: ../../Zotlabs/Web/WebServer.php:115 ../../include/items.php:439 +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:75 +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:119 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:109 +msgid "Permission denied" msgstr "" -#: ../../addon/nsabait/Mod_Nsabait.php:24 -#: ../../addon/rainbowtag/Mod_Rainbowtag.php:26 -#: ../../addon/planets/Mod_Planets.php:23 ../../addon/hsse/Mod_Hsse.php:26 -#: ../../addon/hideaside/Mod_Hideaside.php:27 -#: ../../addon/authchoose/Mod_Authchoose.php:33 -msgid "Installed" +#: ../../Zotlabs/Module/Dreport.php:59 +msgid "Invalid message" msgstr "" -#: ../../addon/nsabait/Mod_Nsabait.php:26 -msgid "Make yourself a political target" +#: ../../Zotlabs/Module/Dreport.php:93 +msgid "no results" msgstr "" -#: ../../addon/visage/Mod_Visage.php:21 -msgid "Who viewed my channel/profile" +#: ../../Zotlabs/Module/Dreport.php:107 +msgid "channel sync processed" msgstr "" -#: ../../addon/visage/Mod_Visage.php:25 -msgid "Recent Channel/Profile Viewers" +#: ../../Zotlabs/Module/Dreport.php:111 +msgid "queued" msgstr "" -#: ../../addon/visage/Mod_Visage.php:36 -msgid "No entries." +#: ../../Zotlabs/Module/Dreport.php:115 +msgid "posted" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:50 -#: ../../addon/openclipatar/openclipatar.php:128 -msgid "System defaults:" +#: ../../Zotlabs/Module/Dreport.php:119 +msgid "accepted for delivery" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:54 -msgid "Preferred Clipart IDs" +#: ../../Zotlabs/Module/Dreport.php:123 +msgid "updated" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:54 -msgid "List of preferred clipart ids. These will be shown first." +#: ../../Zotlabs/Module/Dreport.php:126 +msgid "update ignored" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:55 -msgid "Default Search Term" +#: ../../Zotlabs/Module/Dreport.php:129 +msgid "permission denied" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:55 -msgid "The default search term. These will be shown second." +#: ../../Zotlabs/Module/Dreport.php:133 +msgid "recipient not found" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:56 -msgid "Return After" +#: ../../Zotlabs/Module/Dreport.php:136 +msgid "mail recalled" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:56 -msgid "Page to load after image selection." +#: ../../Zotlabs/Module/Dreport.php:139 +msgid "duplicate mail received" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:57 ../../include/nav.php:112 -#: ../../include/conversation.php:1080 ../../Zotlabs/Module/Connedit.php:600 -#: ../../Zotlabs/Lib/Apps.php:344 -msgid "View Profile" +#: ../../Zotlabs/Module/Dreport.php:142 +msgid "mail delivered" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:58 ../../include/nav.php:117 -#: ../../include/channel.php:1542 -msgid "Edit Profile" +#: ../../Zotlabs/Module/Dreport.php:162 +#, php-format +msgid "Delivery report for %1$s" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:59 -msgid "Profile List" +#: ../../Zotlabs/Module/Dreport.php:166 ../../Zotlabs/Widget/Wiki_pages.php:41 +#: ../../Zotlabs/Widget/Wiki_pages.php:98 +msgid "Options" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:61 -msgid "Order of Preferred" +#: ../../Zotlabs/Module/Dreport.php:167 +msgid "Redeliver" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:61 -msgid "Sort order of preferred clipart ids." +#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63 +msgid "Invalid profile identifier." msgstr "" -#: ../../addon/openclipatar/openclipatar.php:62 -#: ../../addon/openclipatar/openclipatar.php:68 -msgid "Newest first" +#: ../../Zotlabs/Module/Profperm.php:111 +msgid "Profile Visibility Editor" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:65 -msgid "As entered" +#: ../../Zotlabs/Module/Profperm.php:113 ../../Zotlabs/Lib/Apps.php:362 +#: ../../include/channel.php:1886 +msgid "Profile" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:67 -msgid "Order of other" +#: ../../Zotlabs/Module/Profperm.php:115 +msgid "Click on a contact to add or remove." msgstr "" -#: ../../addon/openclipatar/openclipatar.php:67 -msgid "Sort order of other clipart ids." +#: ../../Zotlabs/Module/Profperm.php:124 +msgid "Visible To" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:69 -msgid "Most downloaded first" +#: ../../Zotlabs/Module/Profperm.php:140 +#: ../../Zotlabs/Module/Connections.php:217 +msgid "All Connections" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:70 -msgid "Most liked first" +#: ../../Zotlabs/Module/Cloud.php:120 +msgid "Not found" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:72 -msgid "Preferred IDs Message" +#: ../../Zotlabs/Module/Cloud.php:126 +msgid "Please refresh page" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:72 -msgid "Message to display above preferred results." +#: ../../Zotlabs/Module/Cloud.php:129 +msgid "Unknown error" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:78 -msgid "Uploaded by: " +#: ../../Zotlabs/Module/Authorize.php:17 +msgid "Unknown App" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:78 -msgid "Drawn by: " +#: ../../Zotlabs/Module/Authorize.php:29 +msgid "Authorize" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:182 -#: ../../addon/openclipatar/openclipatar.php:194 -msgid "Use this image" +#: ../../Zotlabs/Module/Authorize.php:30 +#, php-format +msgid "Do you authorize the app %s to access your channel data?" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:192 -msgid "Or select from a free OpenClipart.org image:" +#: ../../Zotlabs/Module/Authorize.php:32 ../../include/acl_selectors.php:146 +msgid "Allow" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:195 -msgid "Search Term" +#: ../../Zotlabs/Module/Authorize.php:33 +#: ../../Zotlabs/Module/Admin/Accounts.php:174 +msgid "Deny" msgstr "" -#: ../../addon/openclipatar/openclipatar.php:232 -msgid "Unknown error. Please try again later." +#: ../../Zotlabs/Module/Cdav.php:818 ../../Zotlabs/Module/Events.php:28 +msgid "Calendar entries imported." msgstr "" -#: ../../addon/openclipatar/openclipatar.php:298 -#: ../../Zotlabs/Module/Profile_photo.php:254 -msgid "" -"Shift-reload the page or clear browser cache if the new photo does not " -"display immediately." +#: ../../Zotlabs/Module/Cdav.php:820 ../../Zotlabs/Module/Events.php:30 +msgid "No calendar entries found." msgstr "" -#: ../../addon/openclipatar/openclipatar.php:308 -msgid "Profile photo updated successfully." +#: ../../Zotlabs/Module/Cdav.php:876 +msgid "CardDAV App" msgstr "" -#: ../../addon/bookmarker/bookmarker.php:38 -#: ../../Zotlabs/Lib/ThreadItem.php:472 -msgid "Save Bookmarks" +#: ../../Zotlabs/Module/Cdav.php:877 +msgid "CalDAV capable addressbook" msgstr "" -#: ../../addon/queueworker/Mod_Queueworker.php:77 -msgid "Max queueworker threads" +#: ../../Zotlabs/Module/Cdav.php:943 ../../Zotlabs/Module/Cal.php:167 +#: ../../Zotlabs/Module/Channel_calendar.php:393 +msgid "Link to source" msgstr "" -#: ../../addon/queueworker/Mod_Queueworker.php:91 -msgid "Assume workers dead after ___ seconds" +#: ../../Zotlabs/Module/Cdav.php:1009 ../../Zotlabs/Module/Events.php:468 +msgid "Event title" msgstr "" -#: ../../addon/queueworker/Mod_Queueworker.php:105 -msgid "" -"Pause before starting next task: (microseconds. Minimum 100 = .0001 seconds)" +#: ../../Zotlabs/Module/Cdav.php:1010 ../../Zotlabs/Module/Events.php:474 +msgid "Start date and time" msgstr "" -#: ../../addon/queueworker/Mod_Queueworker.php:116 -msgid "Queueworker Settings" +#: ../../Zotlabs/Module/Cdav.php:1011 +msgid "End date and time" msgstr "" -#: ../../addon/queueworker/Mod_Queueworker.php:119 ../../include/text.php:1151 -#: ../../include/text.php:1163 ../../Zotlabs/Widget/Notes.php:23 -#: ../../Zotlabs/Module/Admin/Profs.php:94 -#: ../../Zotlabs/Module/Admin/Profs.php:114 ../../Zotlabs/Module/Filer.php:54 -#: ../../Zotlabs/Module/Rbmark.php:32 ../../Zotlabs/Module/Rbmark.php:104 -msgid "Save" +#: ../../Zotlabs/Module/Cdav.php:1012 ../../Zotlabs/Module/Events.php:497 +msgid "Timezone:" msgstr "" -#: ../../addon/rainbowtag/Mod_Rainbowtag.php:15 -msgid "Add some colour to tag clouds" +#: ../../Zotlabs/Module/Cdav.php:1014 ../../Zotlabs/Module/Events.php:481 +#: ../../Zotlabs/Module/Appman.php:145 ../../Zotlabs/Module/Rbmark.php:101 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:173 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:655 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:260 +msgid "Description" msgstr "" -#: ../../addon/rainbowtag/Mod_Rainbowtag.php:21 -#: ../../addon/rainbowtag/Mod_Rainbowtag.php:26 -msgid "Rainbow Tag App" +#: ../../Zotlabs/Module/Cdav.php:1015 ../../Zotlabs/Module/Events.php:483 +#: ../../Zotlabs/Module/Profiles.php:511 ../../Zotlabs/Module/Profiles.php:736 +#: ../../Zotlabs/Module/Locs.php:128 ../../Zotlabs/Module/Pubsites.php:53 +#: ../../include/js_strings.php:25 +msgid "Location" msgstr "" -#: ../../addon/rainbowtag/Mod_Rainbowtag.php:34 -msgid "Rainbow Tag" +#: ../../Zotlabs/Module/Cdav.php:1035 ../../Zotlabs/Module/Events.php:697 +#: ../../Zotlabs/Module/Events.php:706 ../../Zotlabs/Module/Photos.php:947 +#: ../../Zotlabs/Module/Cal.php:205 +msgid "Previous" msgstr "" -#: ../../addon/photocache/Mod_Photocache.php:27 -msgid "Photo Cache settings saved." +#: ../../Zotlabs/Module/Cdav.php:1036 ../../Zotlabs/Module/Events.php:698 +#: ../../Zotlabs/Module/Events.php:707 ../../Zotlabs/Module/Photos.php:956 +#: ../../Zotlabs/Module/Cal.php:206 ../../Zotlabs/Module/Setup.php:260 +msgid "Next" msgstr "" -#: ../../addon/photocache/Mod_Photocache.php:36 -msgid "" -"Photo Cache addon saves a copy of images from external sites locally to " -"increase your anonymity in the web." +#: ../../Zotlabs/Module/Cdav.php:1037 ../../Zotlabs/Module/Events.php:708 +#: ../../Zotlabs/Module/Cal.php:207 +msgid "Today" msgstr "" -#: ../../addon/photocache/Mod_Photocache.php:42 -msgid "Photo Cache App" +#: ../../Zotlabs/Module/Cdav.php:1038 ../../Zotlabs/Module/Events.php:703 +msgid "Month" msgstr "" -#: ../../addon/photocache/Mod_Photocache.php:53 -msgid "Minimal photo size for caching" +#: ../../Zotlabs/Module/Cdav.php:1039 ../../Zotlabs/Module/Events.php:704 +msgid "Week" msgstr "" -#: ../../addon/photocache/Mod_Photocache.php:55 -msgid "In pixels. From 1 up to 1024, 0 will be replaced with system default." +#: ../../Zotlabs/Module/Cdav.php:1040 ../../Zotlabs/Module/Events.php:705 +msgid "Day" msgstr "" -#: ../../addon/photocache/Mod_Photocache.php:64 -msgid "Photo Cache" +#: ../../Zotlabs/Module/Cdav.php:1041 +msgid "List month" msgstr "" -#: ../../addon/gallery/gallery.php:43 ../../addon/gallery/Mod_Gallery.php:136 -msgid "Gallery" +#: ../../Zotlabs/Module/Cdav.php:1042 +msgid "List week" msgstr "" -#: ../../addon/gallery/gallery.php:46 -msgid "Photo Gallery" +#: ../../Zotlabs/Module/Cdav.php:1043 +msgid "List day" msgstr "" -#: ../../addon/gallery/Mod_Gallery.php:49 ../../include/channel.php:1439 -#: ../../Zotlabs/Module/Hcard.php:12 ../../Zotlabs/Module/Editwebpage.php:32 -#: ../../Zotlabs/Module/Profile.php:20 ../../Zotlabs/Module/Webpages.php:39 -#: ../../Zotlabs/Module/Filestorage.php:59 ../../Zotlabs/Module/Connect.php:17 -#: ../../Zotlabs/Module/Achievements.php:15 ../../Zotlabs/Module/Cards.php:42 -#: ../../Zotlabs/Module/Blocks.php:33 ../../Zotlabs/Module/Editblock.php:31 -#: ../../Zotlabs/Module/Editlayout.php:31 ../../Zotlabs/Module/Articles.php:43 -#: ../../Zotlabs/Module/Menu.php:92 ../../Zotlabs/Module/Layouts.php:31 -msgid "Requested profile is not available." +#: ../../Zotlabs/Module/Cdav.php:1051 +msgid "More" msgstr "" -#: ../../addon/gallery/Mod_Gallery.php:58 -msgid "Gallery App" +#: ../../Zotlabs/Module/Cdav.php:1052 +msgid "Less" msgstr "" -#: ../../addon/gallery/Mod_Gallery.php:59 -msgid "A simple gallery for your photo albums" +#: ../../Zotlabs/Module/Cdav.php:1053 ../../Zotlabs/Module/Cdav.php:1388 +#: ../../Zotlabs/Module/Profiles.php:801 ../../Zotlabs/Module/Oauth.php:53 +#: ../../Zotlabs/Module/Oauth.php:137 ../../Zotlabs/Module/Oauth2.php:58 +#: ../../Zotlabs/Module/Oauth2.php:144 ../../Zotlabs/Module/Connedit.php:931 +#: ../../Zotlabs/Module/Admin/Addons.php:457 ../../Zotlabs/Lib/Apps.php:536 +msgid "Update" msgstr "" -#: ../../addon/planets/Mod_Planets.php:20 -#: ../../addon/planets/Mod_Planets.php:23 -msgid "Random Planet App" +#: ../../Zotlabs/Module/Cdav.php:1054 +msgid "Select calendar" msgstr "" -#: ../../addon/planets/Mod_Planets.php:25 -msgid "" -"Set a random planet from the Star Wars Empire as your location when posting" +#: ../../Zotlabs/Module/Cdav.php:1055 ../../Zotlabs/Widget/Cdav.php:143 +msgid "Channel Calendars" msgstr "" -#: ../../addon/openid/Mod_Id.php:53 ../../addon/mail/Mod_Mail.php:25 -#: ../../addon/pumpio/pumpio.php:44 ../../addon/keepout/keepout.php:36 -#: ../../include/photos.php:27 ../../include/items.php:3979 -#: ../../include/attach.php:156 ../../include/attach.php:205 -#: ../../include/attach.php:278 ../../include/attach.php:329 -#: ../../include/attach.php:424 ../../include/attach.php:438 -#: ../../include/attach.php:445 ../../include/attach.php:527 -#: ../../include/attach.php:1091 ../../include/attach.php:1164 -#: ../../include/attach.php:1327 ../../Zotlabs/Module/Article_edit.php:51 -#: ../../Zotlabs/Module/Attach_edit.php:90 -#: ../../Zotlabs/Module/Attach_edit.php:99 -#: ../../Zotlabs/Module/Attach_edit.php:106 ../../Zotlabs/Module/Network.php:19 -#: ../../Zotlabs/Module/Register.php:80 ../../Zotlabs/Module/Setup.php:206 -#: ../../Zotlabs/Module/Viewconnections.php:28 -#: ../../Zotlabs/Module/Viewconnections.php:33 -#: ../../Zotlabs/Module/Channel.php:177 ../../Zotlabs/Module/Channel.php:332 -#: ../../Zotlabs/Module/Channel.php:371 ../../Zotlabs/Module/Group.php:15 -#: ../../Zotlabs/Module/Group.php:31 ../../Zotlabs/Module/Card_edit.php:51 -#: ../../Zotlabs/Module/Editwebpage.php:68 -#: ../../Zotlabs/Module/Editwebpage.php:89 -#: ../../Zotlabs/Module/Editwebpage.php:107 -#: ../../Zotlabs/Module/Editwebpage.php:121 ../../Zotlabs/Module/Chat.php:113 -#: ../../Zotlabs/Module/Chat.php:118 -#: ../../Zotlabs/Module/Channel_calendar.php:230 -#: ../../Zotlabs/Module/Like.php:230 ../../Zotlabs/Module/Poke.php:157 -#: ../../Zotlabs/Module/Item.php:485 ../../Zotlabs/Module/Item.php:504 -#: ../../Zotlabs/Module/Item.php:514 ../../Zotlabs/Module/Item.php:1442 -#: ../../Zotlabs/Module/Mitem.php:129 ../../Zotlabs/Module/Profile.php:85 -#: ../../Zotlabs/Module/Profile.php:101 -#: ../../Zotlabs/Module/Sharedwithme.php:19 -#: ../../Zotlabs/Module/Webpages.php:133 -#: ../../Zotlabs/Module/Filestorage.php:20 -#: ../../Zotlabs/Module/Filestorage.php:78 -#: ../../Zotlabs/Module/Filestorage.php:96 -#: ../../Zotlabs/Module/Filestorage.php:119 -#: ../../Zotlabs/Module/Filestorage.php:165 -#: ../../Zotlabs/Module/Editpost.php:17 -#: ../../Zotlabs/Module/Achievements.php:34 ../../Zotlabs/Module/Events.php:277 -#: ../../Zotlabs/Module/Manage.php:10 ../../Zotlabs/Module/Authtest.php:16 -#: ../../Zotlabs/Module/Viewsrc.php:19 ../../Zotlabs/Module/Moderate.php:15 -#: ../../Zotlabs/Module/Display.php:425 ../../Zotlabs/Module/Common.php:38 -#: ../../Zotlabs/Module/New_channel.php:105 -#: ../../Zotlabs/Module/New_channel.php:130 -#: ../../Zotlabs/Module/Service_limits.php:11 ../../Zotlabs/Module/Mood.php:126 -#: ../../Zotlabs/Module/Appman.php:87 ../../Zotlabs/Module/Cards.php:86 -#: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Regmod.php:20 -#: ../../Zotlabs/Module/Blocks.php:73 ../../Zotlabs/Module/Blocks.php:80 -#: ../../Zotlabs/Module/Message.php:18 ../../Zotlabs/Module/Vote.php:19 -#: ../../Zotlabs/Module/Profile_photo.php:338 -#: ../../Zotlabs/Module/Profile_photo.php:351 -#: ../../Zotlabs/Module/Editblock.php:67 ../../Zotlabs/Module/Settings.php:59 -#: ../../Zotlabs/Module/Editlayout.php:67 -#: ../../Zotlabs/Module/Editlayout.php:90 -#: ../../Zotlabs/Module/Connections.php:32 -#: ../../Zotlabs/Module/Cover_photo.php:341 -#: ../../Zotlabs/Module/Cover_photo.php:354 ../../Zotlabs/Module/Photos.php:71 -#: ../../Zotlabs/Module/Page.php:34 ../../Zotlabs/Module/Page.php:133 -#: ../../Zotlabs/Module/Profiles.php:200 ../../Zotlabs/Module/Profiles.php:637 -#: ../../Zotlabs/Module/Articles.php:89 ../../Zotlabs/Module/Bookmarks.php:70 -#: ../../Zotlabs/Module/Invite.php:21 ../../Zotlabs/Module/Invite.php:102 -#: ../../Zotlabs/Module/Block.php:24 ../../Zotlabs/Module/Block.php:74 -#: ../../Zotlabs/Module/Rate.php:113 ../../Zotlabs/Module/Menu.php:130 -#: ../../Zotlabs/Module/Menu.php:141 ../../Zotlabs/Module/Defperms.php:182 -#: ../../Zotlabs/Module/Thing.php:282 ../../Zotlabs/Module/Thing.php:302 -#: ../../Zotlabs/Module/Thing.php:343 ../../Zotlabs/Module/Pdledit.php:35 -#: ../../Zotlabs/Module/Wiki.php:59 ../../Zotlabs/Module/Wiki.php:285 -#: ../../Zotlabs/Module/Wiki.php:428 ../../Zotlabs/Module/Suggest.php:32 -#: ../../Zotlabs/Module/Connedit.php:396 -#: ../../Zotlabs/Module/Notifications.php:11 -#: ../../Zotlabs/Module/Layouts.php:71 ../../Zotlabs/Module/Layouts.php:78 -#: ../../Zotlabs/Module/Layouts.php:89 ../../Zotlabs/Module/Locs.php:100 -#: ../../Zotlabs/Module/Sources.php:80 ../../Zotlabs/Lib/Chatroom.php:135 -#: ../../Zotlabs/Web/WebServer.php:116 -msgid "Permission denied." +#: ../../Zotlabs/Module/Cdav.php:1055 ../../Zotlabs/Widget/Cdav.php:129 +#: ../../Zotlabs/Widget/Cdav.php:143 +msgid "CalDAV Calendars" msgstr "" -#: ../../addon/openid/Mod_Id.php:85 ../../include/selectors.php:60 -#: ../../include/selectors.php:77 ../../include/channel.php:1722 -msgid "Male" -msgstr "" - -#: ../../addon/openid/Mod_Id.php:87 ../../include/selectors.php:60 -#: ../../include/selectors.php:77 ../../include/channel.php:1720 -msgid "Female" +#: ../../Zotlabs/Module/Cdav.php:1056 ../../Zotlabs/Module/Cdav.php:1389 +#: ../../Zotlabs/Module/Webpages.php:257 ../../Zotlabs/Module/Profiles.php:802 +#: ../../Zotlabs/Module/Oauth.php:174 ../../Zotlabs/Module/Card_edit.php:129 +#: ../../Zotlabs/Module/Oauth2.php:195 ../../Zotlabs/Module/Blocks.php:162 +#: ../../Zotlabs/Module/Connedit.php:660 ../../Zotlabs/Module/Connedit.php:932 +#: ../../Zotlabs/Module/Editlayout.php:138 +#: ../../Zotlabs/Module/Editblock.php:139 ../../Zotlabs/Module/Photos.php:1179 +#: ../../Zotlabs/Module/Connections.php:328 +#: ../../Zotlabs/Module/Editwebpage.php:167 +#: ../../Zotlabs/Module/Article_edit.php:128 +#: ../../Zotlabs/Module/Admin/Accounts.php:175 +#: ../../Zotlabs/Module/Admin/Channels.php:149 +#: ../../Zotlabs/Module/Admin/Profs.php:176 ../../Zotlabs/Module/Thing.php:269 +#: ../../Zotlabs/Storage/Browser.php:384 ../../Zotlabs/Lib/Apps.php:558 +#: ../../Zotlabs/Lib/ThreadItem.php:170 ../../include/conversation.php:730 +#: ../../include/conversation.php:775 +msgid "Delete" msgstr "" -#: ../../addon/openid/Mod_Openid.php:30 -msgid "OpenID protocol error. No ID returned." +#: ../../Zotlabs/Module/Cdav.php:1057 +msgid "Delete all" msgstr "" -#: ../../addon/openid/Mod_Openid.php:76 ../../addon/openid/Mod_Openid.php:178 -#: ../../Zotlabs/Zot/Auth.php:264 -#, php-format -msgid "Welcome %s. Remote authentication successful." +#: ../../Zotlabs/Module/Cdav.php:1058 ../../Zotlabs/Module/Cdav.php:1390 +#: ../../Zotlabs/Module/Filer.php:56 ../../Zotlabs/Module/Profiles.php:803 +#: ../../Zotlabs/Module/Oauth.php:112 ../../Zotlabs/Module/Oauth.php:138 +#: ../../Zotlabs/Module/Card_edit.php:131 ../../Zotlabs/Module/Oauth2.php:117 +#: ../../Zotlabs/Module/Oauth2.php:145 ../../Zotlabs/Module/Wiki.php:368 +#: ../../Zotlabs/Module/Wiki.php:401 ../../Zotlabs/Module/Fbrowser.php:66 +#: ../../Zotlabs/Module/Fbrowser.php:88 ../../Zotlabs/Module/Connedit.php:933 +#: ../../Zotlabs/Module/Profile_photo.php:507 +#: ../../Zotlabs/Module/Editlayout.php:140 +#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Editpost.php:110 +#: ../../Zotlabs/Module/Tagrm.php:15 ../../Zotlabs/Module/Tagrm.php:138 +#: ../../Zotlabs/Module/Editwebpage.php:169 +#: ../../Zotlabs/Module/Article_edit.php:130 +#: ../../Zotlabs/Module/Admin/Addons.php:427 +#: ../../Zotlabs/Module/Cover_photo.php:428 +#: ../../Zotlabs/Storage/Browser.php:383 ../../include/conversation.php:1458 +#: ../../include/conversation.php:1511 +#: ../../extend/addon/hzaddons/hsse/hsse.php:209 +#: ../../extend/addon/hzaddons/hsse/hsse.php:258 +msgid "Cancel" msgstr "" -#: ../../addon/openid/Mod_Openid.php:188 ../../include/auth.php:320 -msgid "Login failed." +#: ../../Zotlabs/Module/Cdav.php:1059 ../../Zotlabs/Module/Cdav.php:1387 +#: ../../Zotlabs/Module/Webpages.php:254 ../../Zotlabs/Module/Profiles.php:800 +#: ../../Zotlabs/Module/Layouts.php:185 +#: ../../Zotlabs/Module/New_channel.php:189 ../../Zotlabs/Module/Blocks.php:159 +#: ../../Zotlabs/Module/Connedit.php:930 ../../Zotlabs/Module/Cards.php:113 +#: ../../Zotlabs/Module/Articles.php:117 ../../Zotlabs/Module/Menu.php:182 +#: ../../Zotlabs/Storage/Browser.php:365 ../../Zotlabs/Storage/Browser.php:538 +#: ../../Zotlabs/Widget/Cdav.php:140 ../../Zotlabs/Widget/Cdav.php:178 +msgid "Create" msgstr "" -#: ../../addon/openid/openid.php:49 -msgid "" -"We encountered a problem while logging in with the OpenID you provided. " -"Please check the correct spelling of the ID." +#: ../../Zotlabs/Module/Cdav.php:1060 +msgid "Sorry! Editing of recurrent events is not yet implemented." msgstr "" -#: ../../addon/openid/openid.php:49 -msgid "The error message was:" +#: ../../Zotlabs/Module/Cdav.php:1070 ../../Zotlabs/Storage/Browser.php:293 +#: ../../Zotlabs/Storage/Browser.php:388 ../../Zotlabs/Storage/Browser.php:403 +#: ../../Zotlabs/Widget/Appcategories.php:43 +#: ../../include/contact_widgets.php:108 ../../include/contact_widgets.php:152 +#: ../../include/contact_widgets.php:197 ../../include/contact_widgets.php:232 +#: ../../include/taxonomy.php:418 ../../include/taxonomy.php:500 +#: ../../include/taxonomy.php:520 ../../include/taxonomy.php:541 +msgid "Categories" msgstr "" -#: ../../addon/openid/MysqlProvider.php:52 -msgid "First Name" +#: ../../Zotlabs/Module/Cdav.php:1372 ../../Zotlabs/Module/Group.php:155 +#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth.php:139 +#: ../../Zotlabs/Module/Oauth2.php:118 ../../Zotlabs/Module/Oauth2.php:146 +#: ../../Zotlabs/Module/Wiki.php:218 ../../Zotlabs/Module/Connedit.php:915 +#: ../../Zotlabs/Module/Sharedwithme.php:106 ../../Zotlabs/Module/Chat.php:257 +#: ../../Zotlabs/Module/Admin/Channels.php:159 +#: ../../Zotlabs/Storage/Browser.php:377 +#: ../../Zotlabs/Lib/NativeWikiPage.php:564 +#: ../../Zotlabs/Widget/Wiki_page_history.php:22 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:172 +msgid "Name" msgstr "" -#: ../../addon/openid/MysqlProvider.php:53 -msgid "Last Name" +#: ../../Zotlabs/Module/Cdav.php:1373 ../../Zotlabs/Module/Connedit.php:916 +msgid "Organisation" msgstr "" -#: ../../addon/openid/MysqlProvider.php:54 ../../addon/redred/Mod_Redred.php:75 -msgid "Nickname" +#: ../../Zotlabs/Module/Cdav.php:1374 ../../Zotlabs/Module/Connedit.php:917 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2617 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2678 +msgid "Title" msgstr "" -#: ../../addon/openid/MysqlProvider.php:55 -msgid "Full Name" +#: ../../Zotlabs/Module/Cdav.php:1375 ../../Zotlabs/Module/Profiles.php:788 +#: ../../Zotlabs/Module/Connedit.php:918 +msgid "Phone" msgstr "" -#: ../../addon/openid/MysqlProvider.php:56 -#: ../../addon/openid/MysqlProvider.php:57 ../../addon/redred/Mod_Redred.php:71 -#: ../../addon/rtof/Mod_Rtof.php:57 ../../include/network.php:1737 -#: ../../Zotlabs/Module/Cdav.php:1376 +#: ../../Zotlabs/Module/Cdav.php:1376 ../../Zotlabs/Module/Profiles.php:789 +#: ../../Zotlabs/Module/Connedit.php:919 #: ../../Zotlabs/Module/Admin/Accounts.php:171 -#: ../../Zotlabs/Module/Admin/Accounts.php:183 -#: ../../Zotlabs/Module/Profiles.php:789 ../../Zotlabs/Module/Connedit.php:919 +#: ../../Zotlabs/Module/Admin/Accounts.php:183 ../../include/network.php:1737 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:56 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:57 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57 msgid "Email" msgstr "" -#: ../../addon/openid/MysqlProvider.php:58 -#: ../../addon/openid/MysqlProvider.php:59 -#: ../../addon/openid/MysqlProvider.php:60 ../../Zotlabs/Lib/Apps.php:361 -msgid "Profile Photo" +#: ../../Zotlabs/Module/Cdav.php:1377 ../../Zotlabs/Module/Profiles.php:790 +#: ../../Zotlabs/Module/Connedit.php:920 +msgid "Instant messenger" msgstr "" -#: ../../addon/openid/MysqlProvider.php:61 -msgid "Profile Photo 16px" +#: ../../Zotlabs/Module/Cdav.php:1378 ../../Zotlabs/Module/Profiles.php:791 +#: ../../Zotlabs/Module/Connedit.php:921 +msgid "Website" msgstr "" -#: ../../addon/openid/MysqlProvider.php:62 -msgid "Profile Photo 32px" +#: ../../Zotlabs/Module/Cdav.php:1379 ../../Zotlabs/Module/Profiles.php:504 +#: ../../Zotlabs/Module/Profiles.php:792 ../../Zotlabs/Module/Locs.php:129 +#: ../../Zotlabs/Module/Connedit.php:922 +#: ../../Zotlabs/Module/Admin/Channels.php:160 +msgid "Address" msgstr "" -#: ../../addon/openid/MysqlProvider.php:63 -msgid "Profile Photo 48px" +#: ../../Zotlabs/Module/Cdav.php:1380 ../../Zotlabs/Module/Profiles.php:793 +#: ../../Zotlabs/Module/Connedit.php:923 +msgid "Note" msgstr "" -#: ../../addon/openid/MysqlProvider.php:64 -msgid "Profile Photo 64px" +#: ../../Zotlabs/Module/Cdav.php:1381 ../../Zotlabs/Module/Profiles.php:794 +#: ../../Zotlabs/Module/Connedit.php:924 ../../include/connections.php:734 +#: ../../include/event.php:1422 +msgid "Mobile" msgstr "" -#: ../../addon/openid/MysqlProvider.php:65 -msgid "Profile Photo 80px" +#: ../../Zotlabs/Module/Cdav.php:1382 ../../Zotlabs/Module/Profiles.php:795 +#: ../../Zotlabs/Module/Connedit.php:925 ../../include/connections.php:735 +#: ../../include/event.php:1423 +msgid "Home" msgstr "" -#: ../../addon/openid/MysqlProvider.php:66 -msgid "Profile Photo 128px" +#: ../../Zotlabs/Module/Cdav.php:1383 ../../Zotlabs/Module/Profiles.php:796 +#: ../../Zotlabs/Module/Connedit.php:926 ../../include/connections.php:738 +#: ../../include/event.php:1426 +msgid "Work" msgstr "" -#: ../../addon/openid/MysqlProvider.php:67 ../../include/event.php:123 -msgid "Timezone" +#: ../../Zotlabs/Module/Cdav.php:1385 ../../Zotlabs/Module/Profiles.php:798 +#: ../../Zotlabs/Module/Connedit.php:928 +msgid "Add Contact" msgstr "" -#: ../../addon/openid/MysqlProvider.php:68 -#: ../../Zotlabs/Module/Profiles.php:769 -msgid "Homepage URL" +#: ../../Zotlabs/Module/Cdav.php:1386 ../../Zotlabs/Module/Profiles.php:799 +#: ../../Zotlabs/Module/Connedit.php:929 +msgid "Add Field" msgstr "" -#: ../../addon/openid/MysqlProvider.php:69 ../../Zotlabs/Lib/Apps.php:359 -msgid "Language" +#: ../../Zotlabs/Module/Cdav.php:1391 ../../Zotlabs/Module/Connedit.php:934 +msgid "P.O. Box" msgstr "" -#: ../../addon/openid/MysqlProvider.php:70 -msgid "Birth Year" +#: ../../Zotlabs/Module/Cdav.php:1392 ../../Zotlabs/Module/Connedit.php:935 +msgid "Additional" msgstr "" -#: ../../addon/openid/MysqlProvider.php:71 -msgid "Birth Month" +#: ../../Zotlabs/Module/Cdav.php:1393 ../../Zotlabs/Module/Connedit.php:936 +msgid "Street" msgstr "" -#: ../../addon/openid/MysqlProvider.php:72 -msgid "Birth Day" +#: ../../Zotlabs/Module/Cdav.php:1394 ../../Zotlabs/Module/Connedit.php:937 +msgid "Locality" msgstr "" -#: ../../addon/openid/MysqlProvider.php:73 -msgid "Birthdate" +#: ../../Zotlabs/Module/Cdav.php:1395 ../../Zotlabs/Module/Connedit.php:938 +msgid "Region" msgstr "" -#: ../../addon/openid/MysqlProvider.php:74 -#: ../../Zotlabs/Module/Profiles.php:488 -msgid "Gender" +#: ../../Zotlabs/Module/Cdav.php:1396 ../../Zotlabs/Module/Connedit.php:939 +msgid "ZIP Code" msgstr "" -#: ../../addon/moremoods/moremoods.php:19 -msgid "lonely" +#: ../../Zotlabs/Module/Cdav.php:1397 ../../Zotlabs/Module/Profiles.php:759 +#: ../../Zotlabs/Module/Connedit.php:940 +msgid "Country" msgstr "" -#: ../../addon/moremoods/moremoods.php:20 -msgid "drunk" +#: ../../Zotlabs/Module/Cdav.php:1456 +msgid "Default Calendar" msgstr "" -#: ../../addon/moremoods/moremoods.php:21 -msgid "horny" +#: ../../Zotlabs/Module/Cdav.php:1467 +msgid "Default Addressbook" msgstr "" -#: ../../addon/moremoods/moremoods.php:22 -msgid "stoned" +#: ../../Zotlabs/Module/Api.php:74 ../../Zotlabs/Module/Api.php:95 +msgid "Authorize application connection" msgstr "" -#: ../../addon/moremoods/moremoods.php:23 -msgid "fucked up" +#: ../../Zotlabs/Module/Api.php:75 +msgid "Return to your app and insert this Security Code:" msgstr "" -#: ../../addon/moremoods/moremoods.php:24 -msgid "clusterfucked" +#: ../../Zotlabs/Module/Api.php:85 +msgid "Please login to continue." msgstr "" -#: ../../addon/moremoods/moremoods.php:25 -msgid "crazy" +#: ../../Zotlabs/Module/Api.php:97 +msgid "" +"Do you want to authorize this application to access your posts and contacts, " +"and/or create new posts for you?" msgstr "" -#: ../../addon/moremoods/moremoods.php:26 -msgid "hurt" +#: ../../Zotlabs/Module/Api.php:98 ../../Zotlabs/Module/Events.php:478 +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Profiles.php:683 +#: ../../Zotlabs/Module/Import.php:634 ../../Zotlabs/Module/Import.php:638 +#: ../../Zotlabs/Module/Import.php:639 ../../Zotlabs/Module/Defperms.php:198 +#: ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Filestorage.php:211 ../../Zotlabs/Module/Wiki.php:227 +#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 +#: ../../Zotlabs/Module/Photos.php:673 ../../Zotlabs/Module/Admin/Site.php:261 +#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177 +#: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257 +#: ../../Zotlabs/Module/Settings/Display.php:88 +#: ../../Zotlabs/Module/Settings/Channel.php:311 +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:311 +#: ../../Zotlabs/Storage/Browser.php:312 ../../Zotlabs/Storage/Browser.php:389 +#: ../../Zotlabs/Storage/Browser.php:391 ../../Zotlabs/Storage/Browser.php:552 +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:166 +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1466 +#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144 +#: ../../include/dir_fns.php:145 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +#: ../../extend/addon/hzaddons/cart/cart.php:1370 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:72 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:337 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:361 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:437 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:461 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:65 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:649 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:653 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:88 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:96 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:61 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:73 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:214 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +#: ../../view/theme/redbasic/php/config.php:99 +#: ../../view/theme/redbasic/php/config.php:116 ../../boot.php:1710 +msgid "Yes" msgstr "" -#: ../../addon/moremoods/moremoods.php:27 -msgid "sleepy" +#: ../../Zotlabs/Module/Api.php:99 ../../Zotlabs/Module/Events.php:478 +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Profiles.php:683 +#: ../../Zotlabs/Module/Import.php:634 ../../Zotlabs/Module/Import.php:638 +#: ../../Zotlabs/Module/Import.php:639 ../../Zotlabs/Module/Defperms.php:198 +#: ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Filestorage.php:211 ../../Zotlabs/Module/Wiki.php:227 +#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 +#: ../../Zotlabs/Module/Connedit.php:788 ../../Zotlabs/Module/Photos.php:673 +#: ../../Zotlabs/Module/Admin/Site.php:259 ../../Zotlabs/Module/Mitem.php:176 +#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:256 +#: ../../Zotlabs/Module/Mitem.php:257 +#: ../../Zotlabs/Module/Settings/Display.php:88 +#: ../../Zotlabs/Module/Settings/Channel.php:311 +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:311 +#: ../../Zotlabs/Storage/Browser.php:312 ../../Zotlabs/Storage/Browser.php:389 +#: ../../Zotlabs/Storage/Browser.php:391 ../../Zotlabs/Storage/Browser.php:552 +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:166 +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1466 +#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144 +#: ../../include/dir_fns.php:145 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +#: ../../extend/addon/hzaddons/cart/cart.php:1370 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:72 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:338 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:362 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:438 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:462 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:65 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:649 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:653 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:88 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:96 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:61 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:73 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:214 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +#: ../../view/theme/redbasic/php/config.php:99 +#: ../../view/theme/redbasic/php/config.php:116 ../../boot.php:1710 +msgid "No" msgstr "" -#: ../../addon/moremoods/moremoods.php:28 -msgid "grumpy" +#: ../../Zotlabs/Module/Dirsearch.php:28 ../../Zotlabs/Module/Regdir.php:52 +msgid "This site is not a directory server" msgstr "" -#: ../../addon/moremoods/moremoods.php:29 -msgid "high" +#: ../../Zotlabs/Module/Dirsearch.php:37 +msgid "This directory server requires an access token" msgstr "" -#: ../../addon/moremoods/moremoods.php:30 -msgid "semi-conscious" +#: ../../Zotlabs/Module/Filer.php:53 +msgid "Enter a folder name" msgstr "" -#: ../../addon/moremoods/moremoods.php:31 -msgid "in love" +#: ../../Zotlabs/Module/Filer.php:53 +msgid "or select an existing folder (doubleclick)" msgstr "" -#: ../../addon/moremoods/moremoods.php:32 -msgid "in lust" +#: ../../Zotlabs/Module/Filer.php:54 ../../Zotlabs/Module/Admin/Profs.php:94 +#: ../../Zotlabs/Module/Admin/Profs.php:114 ../../Zotlabs/Module/Rbmark.php:32 +#: ../../Zotlabs/Module/Rbmark.php:104 ../../Zotlabs/Widget/Notes.php:23 +#: ../../include/text.php:1151 ../../include/text.php:1163 +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:119 +msgid "Save" msgstr "" -#: ../../addon/moremoods/moremoods.php:33 -msgid "naked" +#: ../../Zotlabs/Module/Filer.php:55 ../../Zotlabs/Lib/ThreadItem.php:184 +msgid "Save to Folder" msgstr "" -#: ../../addon/moremoods/moremoods.php:34 -msgid "stinky" +#: ../../Zotlabs/Module/Events.php:113 +#: ../../Zotlabs/Module/Channel_calendar.php:57 +msgid "Event can not end before it has started." msgstr "" -#: ../../addon/moremoods/moremoods.php:35 -msgid "sweaty" +#: ../../Zotlabs/Module/Events.php:115 ../../Zotlabs/Module/Events.php:124 +#: ../../Zotlabs/Module/Events.php:146 +#: ../../Zotlabs/Module/Channel_calendar.php:59 +#: ../../Zotlabs/Module/Channel_calendar.php:67 +#: ../../Zotlabs/Module/Channel_calendar.php:84 +msgid "Unable to generate preview." msgstr "" -#: ../../addon/moremoods/moremoods.php:36 -msgid "bleeding out" +#: ../../Zotlabs/Module/Events.php:122 +#: ../../Zotlabs/Module/Channel_calendar.php:65 +msgid "Event title and start time are required." msgstr "" -#: ../../addon/moremoods/moremoods.php:37 -msgid "victorious" +#: ../../Zotlabs/Module/Events.php:144 ../../Zotlabs/Module/Events.php:271 +#: ../../Zotlabs/Module/Channel_calendar.php:82 +#: ../../Zotlabs/Module/Channel_calendar.php:224 +msgid "Event not found." msgstr "" -#: ../../addon/moremoods/moremoods.php:38 -msgid "defeated" +#: ../../Zotlabs/Module/Events.php:266 ../../Zotlabs/Module/Like.php:435 +#: ../../Zotlabs/Module/Tagger.php:75 +#: ../../Zotlabs/Module/Channel_calendar.php:219 +#: ../../include/conversation.php:132 ../../include/text.php:2255 +#: ../../include/event.php:1259 +msgid "event" msgstr "" -#: ../../addon/moremoods/moremoods.php:39 -msgid "envious" +#: ../../Zotlabs/Module/Events.php:468 +msgid "Edit event title" msgstr "" -#: ../../addon/moremoods/moremoods.php:40 -msgid "jealous" +#: ../../Zotlabs/Module/Events.php:468 ../../Zotlabs/Module/Events.php:473 +#: ../../Zotlabs/Module/Profiles.php:747 ../../Zotlabs/Module/Profiles.php:751 +#: ../../Zotlabs/Module/Appman.php:143 ../../Zotlabs/Module/Appman.php:144 +#: ../../include/datetime.php:211 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:334 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:358 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:434 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:458 +msgid "Required" msgstr "" -#: ../../addon/dirstats/dirstats.php:94 -msgid "Hubzilla Directory Stats" +#: ../../Zotlabs/Module/Events.php:470 +msgid "Categories (comma-separated list)" msgstr "" -#: ../../addon/dirstats/dirstats.php:95 -msgid "Total Hubs" +#: ../../Zotlabs/Module/Events.php:471 +msgid "Edit Category" msgstr "" -#: ../../addon/dirstats/dirstats.php:97 -msgid "Hubzilla Hubs" +#: ../../Zotlabs/Module/Events.php:471 +msgid "Category" msgstr "" -#: ../../addon/dirstats/dirstats.php:99 -msgid "Friendica Hubs" +#: ../../Zotlabs/Module/Events.php:474 +msgid "Edit start date and time" msgstr "" -#: ../../addon/dirstats/dirstats.php:101 -msgid "Diaspora Pods" +#: ../../Zotlabs/Module/Events.php:475 ../../Zotlabs/Module/Events.php:478 +msgid "Finish date and time are not known or not relevant" msgstr "" -#: ../../addon/dirstats/dirstats.php:103 -msgid "Hubzilla Channels" +#: ../../Zotlabs/Module/Events.php:477 +msgid "Edit finish date and time" msgstr "" -#: ../../addon/dirstats/dirstats.php:105 -msgid "Friendica Channels" +#: ../../Zotlabs/Module/Events.php:477 +msgid "Finish date and time" msgstr "" -#: ../../addon/dirstats/dirstats.php:107 -msgid "Diaspora Channels" +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Events.php:480 +msgid "Adjust for viewer timezone" msgstr "" -#: ../../addon/dirstats/dirstats.php:109 -msgid "Aged 35 and above" +#: ../../Zotlabs/Module/Events.php:479 +msgid "" +"Important for events that happen in a particular place. Not practical for " +"global holidays." msgstr "" -#: ../../addon/dirstats/dirstats.php:111 -msgid "Aged 34 and under" +#: ../../Zotlabs/Module/Events.php:481 +msgid "Edit Description" msgstr "" -#: ../../addon/dirstats/dirstats.php:113 -msgid "Average Age" +#: ../../Zotlabs/Module/Events.php:483 +msgid "Edit Location" msgstr "" -#: ../../addon/dirstats/dirstats.php:115 -msgid "Known Chatrooms" +#: ../../Zotlabs/Module/Events.php:486 ../../Zotlabs/Module/Webpages.php:262 +#: ../../Zotlabs/Module/Photos.php:1099 ../../Zotlabs/Lib/ThreadItem.php:835 +#: ../../include/conversation.php:1402 +#: ../../extend/addon/hzaddons/hsse/hsse.php:153 +msgid "Preview" msgstr "" -#: ../../addon/dirstats/dirstats.php:117 -msgid "Known Tags" +#: ../../Zotlabs/Module/Events.php:487 ../../include/conversation.php:1478 +#: ../../extend/addon/hzaddons/hsse/hsse.php:225 +msgid "Permission settings" msgstr "" -#: ../../addon/dirstats/dirstats.php:119 -msgid "" -"Please note Diaspora and Friendica statistics are merely those **this " -"directory** is aware of, and not all those known in the network. This also " -"applies to chatrooms," +#: ../../Zotlabs/Module/Events.php:502 +msgid "Advanced Options" msgstr "" -#: ../../addon/redred/Mod_Redred.php:24 -msgid "Channel is required." +#: ../../Zotlabs/Module/Events.php:613 +msgid "l, F j" msgstr "" -#: ../../addon/redred/Mod_Redred.php:29 ../../Zotlabs/Module/Network.php:322 -msgid "Invalid channel." +#: ../../Zotlabs/Module/Events.php:641 +#: ../../Zotlabs/Module/Channel_calendar.php:371 +msgid "Edit event" msgstr "" -#: ../../addon/redred/Mod_Redred.php:38 -msgid "Hubzilla Crosspost Connector Settings saved." +#: ../../Zotlabs/Module/Events.php:643 +#: ../../Zotlabs/Module/Channel_calendar.php:373 +msgid "Delete event" msgstr "" -#: ../../addon/redred/Mod_Redred.php:50 -#: ../../addon/statusnet/Mod_Statusnet.php:146 -msgid "Hubzilla Crosspost Connector App" +#: ../../Zotlabs/Module/Events.php:669 ../../include/text.php:2074 +msgid "Link to Source" msgstr "" -#: ../../addon/redred/Mod_Redred.php:51 -msgid "Relay public postings to another Hubzilla channel" +#: ../../Zotlabs/Module/Events.php:677 +#: ../../Zotlabs/Module/Channel_calendar.php:407 +msgid "calendar" msgstr "" -#: ../../addon/redred/Mod_Redred.php:63 -msgid "Send public postings to Hubzilla channel by default" +#: ../../Zotlabs/Module/Events.php:696 +msgid "Edit Event" msgstr "" -#: ../../addon/redred/Mod_Redred.php:67 -msgid "Hubzilla API Path" +#: ../../Zotlabs/Module/Events.php:696 +msgid "Create Event" msgstr "" -#: ../../addon/redred/Mod_Redred.php:67 ../../addon/rtof/Mod_Rtof.php:53 -msgid "https://{sitename}/api" +#: ../../Zotlabs/Module/Events.php:699 ../../include/channel.php:1889 +msgid "Export" msgstr "" -#: ../../addon/redred/Mod_Redred.php:71 -msgid "Hubzilla login name" +#: ../../Zotlabs/Module/Events.php:702 ../../Zotlabs/Module/Webpages.php:261 +#: ../../Zotlabs/Module/Layouts.php:198 ../../Zotlabs/Module/Wiki.php:213 +#: ../../Zotlabs/Module/Wiki.php:409 ../../Zotlabs/Module/Blocks.php:166 +#: ../../Zotlabs/Module/Pubsites.php:61 +msgid "View" msgstr "" -#: ../../addon/redred/Mod_Redred.php:75 -msgid "Hubzilla channel name" +#: ../../Zotlabs/Module/Events.php:739 +msgid "Event removed" msgstr "" -#: ../../addon/redred/Mod_Redred.php:79 -msgid "Hubzilla password" +#: ../../Zotlabs/Module/Events.php:742 +#: ../../Zotlabs/Module/Channel_calendar.php:494 +msgid "Failed to remove event" msgstr "" -#: ../../addon/redred/Mod_Redred.php:87 -msgid "Hubzilla Crosspost Connector" +#: ../../Zotlabs/Module/Help.php:23 +msgid "Documentation Search" msgstr "" -#: ../../addon/redred/redred.php:50 -msgid "Post to Hubzilla" +#: ../../Zotlabs/Module/Help.php:83 ../../include/nav.php:434 +msgid "About" msgstr "" -#: ../../addon/redphotos/redphotos.php:106 -msgid "Photos imported" +#: ../../Zotlabs/Module/Help.php:84 ../../Zotlabs/Module/Group.php:156 +msgid "Members" msgstr "" -#: ../../addon/redphotos/redphotos.php:119 -#: ../../addon/redfiles/redfiles.php:109 ../../addon/hzfiles/hzfiles.php:75 -#: ../../include/items.php:439 ../../Zotlabs/Module/Import_items.php:120 -#: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Group.php:99 -#: ../../Zotlabs/Module/Like.php:332 ../../Zotlabs/Module/Cloud.php:123 -#: ../../Zotlabs/Module/Share.php:72 ../../Zotlabs/Module/Subthread.php:86 -#: ../../Zotlabs/Module/Dreport.php:10 ../../Zotlabs/Module/Dreport.php:82 -#: ../../Zotlabs/Web/WebServer.php:115 -msgid "Permission denied" +#: ../../Zotlabs/Module/Help.php:85 +msgid "Administrators" msgstr "" -#: ../../addon/redphotos/redphotos.php:129 -msgid "Redmatrix Photo Album Import" +#: ../../Zotlabs/Module/Help.php:86 +msgid "Developers" msgstr "" -#: ../../addon/redphotos/redphotos.php:130 -msgid "This will import all your Redmatrix photo albums to this channel." +#: ../../Zotlabs/Module/Help.php:87 +msgid "Tutorials" msgstr "" -#: ../../addon/redphotos/redphotos.php:131 -#: ../../addon/redfiles/redfiles.php:121 -msgid "Redmatrix Server base URL" +#: ../../Zotlabs/Module/Help.php:98 +msgid "$Projectname Documentation" msgstr "" -#: ../../addon/redphotos/redphotos.php:132 -#: ../../addon/redfiles/redfiles.php:122 -msgid "Redmatrix Login Username" +#: ../../Zotlabs/Module/Help.php:99 +msgid "Contents" msgstr "" -#: ../../addon/redphotos/redphotos.php:133 -#: ../../addon/redfiles/redfiles.php:123 -msgid "Redmatrix Login Password" +#: ../../Zotlabs/Module/Bookmarks.php:62 +msgid "Bookmark added" msgstr "" -#: ../../addon/redphotos/redphotos.php:134 -msgid "Import just this album" +#: ../../Zotlabs/Module/Bookmarks.php:78 +msgid "Bookmarks App" msgstr "" -#: ../../addon/redphotos/redphotos.php:134 -msgid "Leave blank to import all albums" +#: ../../Zotlabs/Module/Bookmarks.php:79 +msgid "Bookmark links from posts and manage them" msgstr "" -#: ../../addon/redphotos/redphotos.php:135 -msgid "Maximum count to import" +#: ../../Zotlabs/Module/Bookmarks.php:92 +msgid "My Bookmarks" msgstr "" -#: ../../addon/redphotos/redphotos.php:135 -msgid "0 or blank to import all available" +#: ../../Zotlabs/Module/Bookmarks.php:103 +msgid "My Connections Bookmarks" msgstr "" -#: ../../addon/redphotos/redphotohelper.php:71 ../../addon/pubcrawl/as.php:2057 -#: ../../addon/diaspora/Receiver.php:1597 ../../include/text.php:2252 -#: ../../include/conversation.php:128 ../../Zotlabs/Module/Like.php:433 -#: ../../Zotlabs/Module/Tagger.php:71 ../../Zotlabs/Module/Subthread.php:112 -#: ../../Zotlabs/Lib/Activity.php:2971 -msgid "photo" +#: ../../Zotlabs/Module/Webpages.php:39 ../../Zotlabs/Module/Layouts.php:31 +#: ../../Zotlabs/Module/Connect.php:17 ../../Zotlabs/Module/Filestorage.php:59 +#: ../../Zotlabs/Module/Blocks.php:33 ../../Zotlabs/Module/Editlayout.php:31 +#: ../../Zotlabs/Module/Achievements.php:15 +#: ../../Zotlabs/Module/Editblock.php:31 ../../Zotlabs/Module/Cards.php:42 +#: ../../Zotlabs/Module/Editwebpage.php:32 ../../Zotlabs/Module/Profile.php:20 +#: ../../Zotlabs/Module/Articles.php:43 ../../Zotlabs/Module/Hcard.php:12 +#: ../../Zotlabs/Module/Menu.php:92 ../../include/channel.php:1439 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:49 +msgid "Requested profile is not available." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:61 -msgid "" -"Please contact your site administrator.
      The provided API URL is not " -"valid." +#: ../../Zotlabs/Module/Webpages.php:48 +msgid "Webpages App" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:98 -msgid "We could not contact the GNU social API with the Path you entered." +#: ../../Zotlabs/Module/Webpages.php:49 +msgid "Provide managed web pages on your channel" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:130 -msgid "GNU social settings updated." +#: ../../Zotlabs/Module/Webpages.php:69 +msgid "Import Webpage Elements" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:147 -msgid "" -"Relay public postings to a connected GNU social account (formerly StatusNet)" +#: ../../Zotlabs/Module/Webpages.php:70 +msgid "Import selected" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:181 -msgid "Globally Available GNU social OAuthKeys" +#: ../../Zotlabs/Module/Webpages.php:93 +msgid "Export Webpage Elements" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:183 -msgid "" -"There are preconfigured OAuth key pairs for some GNU social servers " -"available. If you are using one of them, please use these credentials.
      If not feel free to connect to any other GNU social instance (see below)." +#: ../../Zotlabs/Module/Webpages.php:94 +msgid "Export selected" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:198 -msgid "Provide your own OAuth Credentials" +#: ../../Zotlabs/Module/Webpages.php:252 ../../Zotlabs/Lib/Apps.php:341 +#: ../../include/nav.php:524 +msgid "Webpages" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:200 -msgid "" -"No consumer key pair for GNU social found. Register your Hubzilla Account as " -"an desktop client on your GNU social account, copy the consumer key pair " -"here and enter the API base root.
      Before you register your own OAuth " -"key pair ask the administrator if there is already a key pair for this " -"Hubzilla installation at your favourite GNU social installation." +#: ../../Zotlabs/Module/Webpages.php:255 ../../Zotlabs/Module/Layouts.php:193 +#: ../../Zotlabs/Module/Group.php:253 ../../Zotlabs/Module/Oauth.php:173 +#: ../../Zotlabs/Module/Card_edit.php:99 ../../Zotlabs/Module/Oauth2.php:194 +#: ../../Zotlabs/Module/Wiki.php:211 ../../Zotlabs/Module/Wiki.php:384 +#: ../../Zotlabs/Module/Blocks.php:160 ../../Zotlabs/Module/Editlayout.php:114 +#: ../../Zotlabs/Module/Editblock.php:114 +#: ../../Zotlabs/Module/Connections.php:320 +#: ../../Zotlabs/Module/Connections.php:362 +#: ../../Zotlabs/Module/Connections.php:382 +#: ../../Zotlabs/Module/Editwebpage.php:142 +#: ../../Zotlabs/Module/Article_edit.php:98 +#: ../../Zotlabs/Module/Admin/Profs.php:175 ../../Zotlabs/Module/Thing.php:268 +#: ../../Zotlabs/Module/Menu.php:176 ../../Zotlabs/Lib/Apps.php:557 +#: ../../Zotlabs/Lib/ThreadItem.php:148 ../../Zotlabs/Widget/Cdav.php:138 +#: ../../Zotlabs/Widget/Cdav.php:175 ../../include/channel.php:1538 +#: ../../include/channel.php:1542 ../../include/menu.php:120 +msgid "Edit" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:204 -msgid "OAuth Consumer Key" +#: ../../Zotlabs/Module/Webpages.php:256 ../../Zotlabs/Module/Layouts.php:194 +#: ../../Zotlabs/Module/Wiki.php:301 ../../Zotlabs/Module/Blocks.php:161 +#: ../../Zotlabs/Module/Photos.php:1078 ../../Zotlabs/Widget/Cdav.php:136 +#: ../../include/conversation.php:1435 +#: ../../extend/addon/hzaddons/hsse/hsse.php:186 +msgid "Share" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:208 -msgid "OAuth Consumer Secret" +#: ../../Zotlabs/Module/Webpages.php:263 +msgid "Actions" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:212 -msgid "Base API Path" +#: ../../Zotlabs/Module/Webpages.php:264 +msgid "Page Link" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:212 -msgid "Remember the trailing /" +#: ../../Zotlabs/Module/Webpages.php:265 +msgid "Page Title" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:216 -msgid "GNU social application name" +#: ../../Zotlabs/Module/Webpages.php:266 ../../Zotlabs/Module/Layouts.php:191 +#: ../../Zotlabs/Module/Blocks.php:157 ../../Zotlabs/Module/Menu.php:178 +msgid "Created" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:239 -msgid "" -"To connect to your GNU social account click the button below to get a " -"security code from GNU social which you have to copy into the input box " -"below and submit the form. Only your public posts will be " -"posted to GNU social." +#: ../../Zotlabs/Module/Webpages.php:267 ../../Zotlabs/Module/Layouts.php:192 +#: ../../Zotlabs/Module/Blocks.php:158 ../../Zotlabs/Module/Menu.php:179 +msgid "Edited" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:241 -msgid "Log in with GNU social" +#: ../../Zotlabs/Module/Webpages.php:295 +msgid "Invalid file type." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:244 -msgid "Copy the security code from GNU social here" +#: ../../Zotlabs/Module/Webpages.php:307 +msgid "Error opening zip file" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:254 -msgid "Cancel Connection Process" +#: ../../Zotlabs/Module/Webpages.php:318 +msgid "Invalid folder path." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:256 -msgid "Current GNU social API is" +#: ../../Zotlabs/Module/Webpages.php:345 +msgid "No webpage elements detected." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:260 -msgid "Cancel GNU social Connection" +#: ../../Zotlabs/Module/Webpages.php:420 +msgid "Import complete." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:272 -#: ../../addon/twitter/Mod_Twitter.php:147 -msgid "Currently connected to: " +#: ../../Zotlabs/Module/Profiles.php:26 ../../Zotlabs/Module/Profiles.php:186 +#: ../../Zotlabs/Module/Profiles.php:243 ../../Zotlabs/Module/Profiles.php:661 +msgid "Profile not found." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:277 -msgid "" -"Note: Due your privacy settings (Hide your profile " -"details from unknown viewers?) the link potentially included in public " -"postings relayed to GNU social will lead the visitor to a blank page " -"informing the visitor that the access to your profile has been restricted." +#: ../../Zotlabs/Module/Profiles.php:46 +msgid "Profile deleted." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:282 -msgid "Post to GNU social by default" +#: ../../Zotlabs/Module/Profiles.php:70 ../../Zotlabs/Module/Profiles.php:107 +msgid "Profile-" msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:282 -msgid "" -"If enabled your public postings will be posted to the associated GNU-social " -"account by default" +#: ../../Zotlabs/Module/Profiles.php:92 ../../Zotlabs/Module/Profiles.php:129 +msgid "New profile created." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:291 -#: ../../addon/twitter/Mod_Twitter.php:171 -msgid "Clear OAuth configuration" +#: ../../Zotlabs/Module/Profiles.php:113 +msgid "Profile unavailable to clone." msgstr "" -#: ../../addon/statusnet/Mod_Statusnet.php:303 -msgid "GNU-Social Crosspost Connector" +#: ../../Zotlabs/Module/Profiles.php:148 +msgid "Profile unavailable to export." msgstr "" -#: ../../addon/statusnet/statusnet.php:145 -msgid "Post to GNU social" +#: ../../Zotlabs/Module/Profiles.php:254 +msgid "Profile Name is required." msgstr "" -#: ../../addon/statusnet/statusnet.php:593 -#: ../../Zotlabs/Module/Admin/Site.php:301 -msgid "Site name" +#: ../../Zotlabs/Module/Profiles.php:461 +msgid "Marital Status" msgstr "" -#: ../../addon/statusnet/statusnet.php:594 -msgid "API URL" +#: ../../Zotlabs/Module/Profiles.php:465 +msgid "Romantic Partner" msgstr "" -#: ../../addon/statusnet/statusnet.php:595 ../../addon/twitter/twitter.php:506 -#: ../../Zotlabs/Module/Oauth.php:115 ../../Zotlabs/Module/Oauth.php:141 -#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 -msgid "Consumer Secret" +#: ../../Zotlabs/Module/Profiles.php:469 ../../Zotlabs/Module/Profiles.php:774 +msgid "Likes" msgstr "" -#: ../../addon/statusnet/statusnet.php:596 ../../addon/twitter/twitter.php:505 -#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:140 -msgid "Consumer Key" +#: ../../Zotlabs/Module/Profiles.php:473 ../../Zotlabs/Module/Profiles.php:775 +msgid "Dislikes" msgstr "" -#: ../../addon/statusnet/statusnet.php:597 -msgid "Application name" +#: ../../Zotlabs/Module/Profiles.php:477 ../../Zotlabs/Module/Profiles.php:782 +msgid "Work/Employment" msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:24 -msgid "Friendica Crosspost Connector Settings saved." +#: ../../Zotlabs/Module/Profiles.php:480 +msgid "Religion" msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:36 -msgid "Friendica Crosspost Connector App" +#: ../../Zotlabs/Module/Profiles.php:484 +msgid "Political Views" msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:37 -msgid "Relay public postings to a connected Friendica account" +#: ../../Zotlabs/Module/Profiles.php:488 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:74 +msgid "Gender" msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:49 -msgid "Send public postings to Friendica by default" +#: ../../Zotlabs/Module/Profiles.php:492 +msgid "Sexual Preference" msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:53 -msgid "Friendica API Path" +#: ../../Zotlabs/Module/Profiles.php:496 +msgid "Homepage" msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:57 -msgid "Friendica login name" +#: ../../Zotlabs/Module/Profiles.php:500 +msgid "Interests" msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:61 -msgid "Friendica password" +#: ../../Zotlabs/Module/Profiles.php:596 +msgid "Profile updated." msgstr "" -#: ../../addon/rtof/Mod_Rtof.php:69 -msgid "Friendica Crosspost Connector" +#: ../../Zotlabs/Module/Profiles.php:680 +msgid "Hide your connections list from viewers of this profile" msgstr "" -#: ../../addon/rtof/rtof.php:51 -msgid "Post to Friendica" +#: ../../Zotlabs/Module/Profiles.php:724 +msgid "Edit Profile Details" msgstr "" -#: ../../addon/wppost/wppost.php:46 -msgid "Post to WordPress" +#: ../../Zotlabs/Module/Profiles.php:726 +msgid "View this profile" msgstr "" -#: ../../addon/wppost/wppost.php:173 ../../addon/wppost/Mod_Wppost.php:98 -#: ../../addon/dwpost/Mod_Dwpost.php:69 ../../addon/dwpost/dwpost.php:134 -#: ../../addon/ljpost/ljpost.php:134 ../../Zotlabs/Module/Wiki.php:384 -msgid "Source" +#: ../../Zotlabs/Module/Profiles.php:727 ../../Zotlabs/Module/Profiles.php:826 +#: ../../include/channel.php:1561 +msgid "Edit visibility" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:30 -msgid "Wordpress Settings saved." +#: ../../Zotlabs/Module/Profiles.php:728 +msgid "Profile Tools" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:43 -msgid "Wordpress Post App" +#: ../../Zotlabs/Module/Profiles.php:729 +msgid "Change cover photo" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:44 -msgid "Post to WordPress or anything else which uses the wordpress XMLRPC API" +#: ../../Zotlabs/Module/Profiles.php:730 ../../include/channel.php:1531 +msgid "Change profile photo" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:69 -msgid "WordPress username" +#: ../../Zotlabs/Module/Profiles.php:731 +msgid "Create a new profile using these settings" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:73 -msgid "WordPress password" +#: ../../Zotlabs/Module/Profiles.php:732 +msgid "Clone this profile" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:77 -msgid "WordPress API URL" +#: ../../Zotlabs/Module/Profiles.php:733 +msgid "Delete this profile" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:78 -msgid "Typically https://your-blog.tld/xmlrpc.php" +#: ../../Zotlabs/Module/Profiles.php:734 +msgid "Add profile things" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:81 -msgid "WordPress blogid" +#: ../../Zotlabs/Module/Profiles.php:735 +msgid "Personal" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:82 -msgid "For multi-user sites such as wordpress.com, otherwise leave blank" +#: ../../Zotlabs/Module/Profiles.php:737 +msgid "Relationship" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:86 -msgid "Post to WordPress by default" +#: ../../Zotlabs/Module/Profiles.php:738 ../../Zotlabs/Widget/Newmember.php:51 +#: ../../include/datetime.php:58 +msgid "Miscellaneous" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:90 -msgid "Forward comments (requires hubzilla_wp plugin)" +#: ../../Zotlabs/Module/Profiles.php:740 +msgid "Import profile from file" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:94 ../../addon/dwpost/Mod_Dwpost.php:65 -#: ../../addon/ljpost/Mod_Ljpost.php:71 -msgid "Add link to original post" +#: ../../Zotlabs/Module/Profiles.php:741 +msgid "Export profile to file" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:98 ../../addon/dwpost/Mod_Dwpost.php:69 -msgid "Link description (default:" +#: ../../Zotlabs/Module/Profiles.php:742 +msgid "Your gender" msgstr "" -#: ../../addon/wppost/Mod_Wppost.php:106 -msgid "Wordpress Post" +#: ../../Zotlabs/Module/Profiles.php:743 +msgid "Marital status" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:27 -msgid "No server specified" +#: ../../Zotlabs/Module/Profiles.php:744 +msgid "Sexual preference" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:73 -msgid "Posts imported" +#: ../../Zotlabs/Module/Profiles.php:747 +msgid "Profile name" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:113 -msgid "Files imported" +#: ../../Zotlabs/Module/Profiles.php:749 +msgid "This is your default profile." msgstr "" -#: ../../addon/content_import/Mod_content_import.php:122 -msgid "" -"This addon app copies existing content and file storage to a cloned/copied " -"channel. Once the app is installed, visit the newly installed app. This will " -"allow you to set the location of your original channel and an optional date " -"range of files/conversations to copy." +#: ../../Zotlabs/Module/Profiles.php:751 +msgid "Your full name" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:135 -#: ../../Zotlabs/Lib/Apps.php:332 -msgid "Content Import" +#: ../../Zotlabs/Module/Profiles.php:752 +msgid "Short title/tescription" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:136 -msgid "" -"This will import all your conversations and cloud files from a cloned " -"channel on another server. This may take a while if you have lots of posts " -"and or files." +#: ../../Zotlabs/Module/Profiles.php:752 +msgid "Maximal 190 characters" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:137 -msgid "Include posts" +#: ../../Zotlabs/Module/Profiles.php:755 +msgid "Street address" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:137 -msgid "Conversations, Articles, Cards, and other posted content" +#: ../../Zotlabs/Module/Profiles.php:756 +msgid "Locality/City" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:138 -msgid "Include files" +#: ../../Zotlabs/Module/Profiles.php:757 +msgid "Region/State" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:138 -msgid "Files, Photos and other cloud storage" +#: ../../Zotlabs/Module/Profiles.php:758 +msgid "Postal/Zip code" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:139 -msgid "Original Server base URL" +#: ../../Zotlabs/Module/Profiles.php:764 +msgid "Who (if applicable)" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:140 -#: ../../addon/hzfiles/hzfiles.php:84 -msgid "Since modified date yyyy-mm-dd" +#: ../../Zotlabs/Module/Profiles.php:764 +msgid "Examples: cathy123, Cathy Williams, cathy@example.com" msgstr "" -#: ../../addon/content_import/Mod_content_import.php:141 -#: ../../addon/hzfiles/hzfiles.php:85 -msgid "Until modified date yyyy-mm-dd" +#: ../../Zotlabs/Module/Profiles.php:765 +msgid "Since (date)" msgstr "" -#: ../../addon/hsse/hsse.php:82 ../../include/conversation.php:1328 -msgid "Set your location" +#: ../../Zotlabs/Module/Profiles.php:768 +msgid "Tell us about yourself" msgstr "" -#: ../../addon/hsse/hsse.php:83 ../../include/conversation.php:1329 -msgid "Clear browser location" +#: ../../Zotlabs/Module/Profiles.php:769 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:68 +msgid "Homepage URL" msgstr "" -#: ../../addon/hsse/hsse.php:95 ../../addon/mail/Mod_Mail.php:166 -#: ../../addon/mail/Mod_Mail.php:309 ../../include/conversation.php:1341 -#: ../../Zotlabs/Module/Article_edit.php:100 -#: ../../Zotlabs/Module/Card_edit.php:101 -#: ../../Zotlabs/Module/Editwebpage.php:143 ../../Zotlabs/Module/Chat.php:220 -#: ../../Zotlabs/Module/Editblock.php:116 -msgid "Insert web link" +#: ../../Zotlabs/Module/Profiles.php:770 +msgid "Hometown" msgstr "" -#: ../../addon/hsse/hsse.php:99 ../../include/conversation.php:1345 -msgid "Embed (existing) photo from your photo albums" +#: ../../Zotlabs/Module/Profiles.php:771 +msgid "Political views" msgstr "" -#: ../../addon/hsse/hsse.php:134 ../../addon/mail/Mod_Mail.php:119 -#: ../../addon/mail/Mod_Mail.php:240 ../../include/conversation.php:1380 -#: ../../Zotlabs/Module/Chat.php:218 -msgid "Please enter a link URL:" +#: ../../Zotlabs/Module/Profiles.php:772 +msgid "Religious views" msgstr "" -#: ../../addon/hsse/hsse.php:135 ../../include/conversation.php:1381 -msgid "Tag term:" +#: ../../Zotlabs/Module/Profiles.php:773 +msgid "Keywords used in directory listings" msgstr "" -#: ../../addon/hsse/hsse.php:136 ../../include/conversation.php:1382 -msgid "Where are you right now?" +#: ../../Zotlabs/Module/Profiles.php:773 +msgid "Example: fishing photography software" msgstr "" -#: ../../addon/hsse/hsse.php:139 ../../include/conversation.php:1385 -#: ../../Zotlabs/Module/Profile_photo.php:509 -#: ../../Zotlabs/Module/Cover_photo.php:430 ../../Zotlabs/Module/Wiki.php:403 -msgid "Choose images to embed" +#: ../../Zotlabs/Module/Profiles.php:776 +msgid "Musical interests" msgstr "" -#: ../../addon/hsse/hsse.php:140 ../../include/conversation.php:1386 -#: ../../Zotlabs/Module/Profile_photo.php:510 -#: ../../Zotlabs/Module/Cover_photo.php:431 ../../Zotlabs/Module/Wiki.php:404 -msgid "Choose an album" +#: ../../Zotlabs/Module/Profiles.php:777 +msgid "Books, literature" msgstr "" -#: ../../addon/hsse/hsse.php:141 ../../include/conversation.php:1387 -msgid "Choose a different album..." +#: ../../Zotlabs/Module/Profiles.php:778 +msgid "Television" msgstr "" -#: ../../addon/hsse/hsse.php:142 ../../include/conversation.php:1388 -#: ../../Zotlabs/Module/Profile_photo.php:512 -#: ../../Zotlabs/Module/Cover_photo.php:433 ../../Zotlabs/Module/Wiki.php:406 -msgid "Error getting album list" +#: ../../Zotlabs/Module/Profiles.php:779 +msgid "Film/Dance/Culture/Entertainment" msgstr "" -#: ../../addon/hsse/hsse.php:143 ../../include/conversation.php:1389 -#: ../../Zotlabs/Module/Profile_photo.php:513 -#: ../../Zotlabs/Module/Cover_photo.php:434 ../../Zotlabs/Module/Wiki.php:407 -msgid "Error getting photo link" +#: ../../Zotlabs/Module/Profiles.php:780 +msgid "Hobbies/Interests" msgstr "" -#: ../../addon/hsse/hsse.php:144 ../../include/conversation.php:1390 -#: ../../Zotlabs/Module/Profile_photo.php:514 -#: ../../Zotlabs/Module/Cover_photo.php:435 ../../Zotlabs/Module/Wiki.php:408 -msgid "Error getting album" +#: ../../Zotlabs/Module/Profiles.php:781 +msgid "Love/Romance" msgstr "" -#: ../../addon/hsse/hsse.php:145 ../../include/conversation.php:1391 -msgid "Comments enabled" +#: ../../Zotlabs/Module/Profiles.php:783 +msgid "School/Education" msgstr "" -#: ../../addon/hsse/hsse.php:146 ../../include/conversation.php:1392 -msgid "Comments disabled" +#: ../../Zotlabs/Module/Profiles.php:784 +msgid "Contact information and social networks" msgstr "" -#: ../../addon/hsse/hsse.php:153 ../../include/conversation.php:1402 -#: ../../Zotlabs/Module/Webpages.php:262 ../../Zotlabs/Module/Events.php:486 -#: ../../Zotlabs/Module/Photos.php:1099 ../../Zotlabs/Lib/ThreadItem.php:835 -msgid "Preview" +#: ../../Zotlabs/Module/Profiles.php:785 +msgid "My other channels" msgstr "" -#: ../../addon/hsse/hsse.php:186 ../../include/conversation.php:1435 -#: ../../Zotlabs/Widget/Cdav.php:136 ../../Zotlabs/Module/Webpages.php:256 -#: ../../Zotlabs/Module/Blocks.php:161 ../../Zotlabs/Module/Photos.php:1078 -#: ../../Zotlabs/Module/Wiki.php:301 ../../Zotlabs/Module/Layouts.php:194 -msgid "Share" +#: ../../Zotlabs/Module/Profiles.php:787 +msgid "Communications" msgstr "" -#: ../../addon/hsse/hsse.php:195 ../../include/conversation.php:1444 -msgid "Page link name" +#: ../../Zotlabs/Module/Profiles.php:822 ../../include/channel.php:1557 +msgid "Profile Image" msgstr "" -#: ../../addon/hsse/hsse.php:198 ../../include/conversation.php:1447 -msgid "Post as" +#: ../../Zotlabs/Module/Profiles.php:832 ../../include/channel.php:1538 +#: ../../include/nav.php:115 +msgid "Edit Profiles" msgstr "" -#: ../../addon/hsse/hsse.php:200 ../../include/conversation.php:1449 -#: ../../Zotlabs/Lib/ThreadItem.php:826 -msgid "Bold" +#: ../../Zotlabs/Module/Profiles.php:833 ../../Zotlabs/Module/Wiki.php:214 +#: ../../Zotlabs/Module/Manage.php:145 ../../Zotlabs/Module/Chat.php:262 +msgid "Create New" msgstr "" -#: ../../addon/hsse/hsse.php:201 ../../include/conversation.php:1450 -#: ../../Zotlabs/Lib/ThreadItem.php:827 -msgid "Italic" +#: ../../Zotlabs/Module/Import.php:68 ../../Zotlabs/Module/Import_items.php:48 +msgid "Nothing to import." msgstr "" -#: ../../addon/hsse/hsse.php:202 ../../include/conversation.php:1451 -#: ../../Zotlabs/Lib/ThreadItem.php:828 -msgid "Underline" +#: ../../Zotlabs/Module/Import.php:83 ../../Zotlabs/Module/Import.php:99 +#: ../../Zotlabs/Module/Import_items.php:72 +msgid "Unable to download data from old server" msgstr "" -#: ../../addon/hsse/hsse.php:203 ../../include/conversation.php:1452 -#: ../../Zotlabs/Lib/ThreadItem.php:829 -msgid "Quote" +#: ../../Zotlabs/Module/Import.php:106 ../../Zotlabs/Module/Import_items.php:77 +msgid "Imported file is empty." msgstr "" -#: ../../addon/hsse/hsse.php:204 ../../include/conversation.php:1453 -#: ../../Zotlabs/Lib/ThreadItem.php:830 -msgid "Code" +#: ../../Zotlabs/Module/Import.php:162 +#, php-format +msgid "Your service plan only allows %d channels." msgstr "" -#: ../../addon/hsse/hsse.php:205 ../../include/conversation.php:1454 -#: ../../Zotlabs/Lib/ThreadItem.php:832 -msgid "Attach/Upload file" +#: ../../Zotlabs/Module/Import.php:189 +msgid "No channel. Import failed." msgstr "" -#: ../../addon/hsse/hsse.php:208 ../../include/conversation.php:1457 -#: ../../Zotlabs/Module/Wiki.php:400 -msgid "Embed an image from your albums" +#: ../../Zotlabs/Module/Import.php:593 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:142 +msgid "Import completed." msgstr "" -#: ../../addon/hsse/hsse.php:209 ../../addon/hsse/hsse.php:258 -#: ../../include/conversation.php:1458 ../../include/conversation.php:1511 -#: ../../Zotlabs/Module/Article_edit.php:130 -#: ../../Zotlabs/Module/Fbrowser.php:66 ../../Zotlabs/Module/Fbrowser.php:88 -#: ../../Zotlabs/Module/Card_edit.php:131 ../../Zotlabs/Module/Oauth.php:112 -#: ../../Zotlabs/Module/Oauth.php:138 ../../Zotlabs/Module/Editwebpage.php:169 -#: ../../Zotlabs/Module/Cdav.php:1058 ../../Zotlabs/Module/Cdav.php:1390 -#: ../../Zotlabs/Module/Tagrm.php:15 ../../Zotlabs/Module/Tagrm.php:138 -#: ../../Zotlabs/Module/Editpost.php:110 -#: ../../Zotlabs/Module/Admin/Addons.php:427 -#: ../../Zotlabs/Module/Profile_photo.php:507 -#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Filer.php:56 -#: ../../Zotlabs/Module/Editlayout.php:140 -#: ../../Zotlabs/Module/Cover_photo.php:428 -#: ../../Zotlabs/Module/Profiles.php:803 ../../Zotlabs/Module/Oauth2.php:117 -#: ../../Zotlabs/Module/Oauth2.php:145 ../../Zotlabs/Module/Wiki.php:368 -#: ../../Zotlabs/Module/Wiki.php:401 ../../Zotlabs/Module/Connedit.php:933 -#: ../../Zotlabs/Storage/Browser.php:376 -msgid "Cancel" +#: ../../Zotlabs/Module/Import.php:621 +msgid "You must be logged in to use this feature." msgstr "" -#: ../../addon/hsse/hsse.php:210 ../../addon/hsse/hsse.php:257 -#: ../../include/conversation.php:1459 ../../include/conversation.php:1510 -#: ../../Zotlabs/Module/Profile_photo.php:508 -#: ../../Zotlabs/Module/Cover_photo.php:429 ../../Zotlabs/Module/Wiki.php:402 -msgid "OK" +#: ../../Zotlabs/Module/Import.php:626 +msgid "Import Channel" msgstr "" -#: ../../addon/hsse/hsse.php:212 ../../include/conversation.php:1461 -msgid "Toggle voting" +#: ../../Zotlabs/Module/Import.php:627 +msgid "" +"Use this form to import an existing channel from a different server/hub. You " +"may retrieve the channel identity from the old server/hub via the network or " +"provide an export file." msgstr "" -#: ../../addon/hsse/hsse.php:215 ../../include/conversation.php:1468 -msgid "Disable comments" +#: ../../Zotlabs/Module/Import.php:628 +#: ../../Zotlabs/Module/Import_items.php:127 +msgid "File to Upload" msgstr "" -#: ../../addon/hsse/hsse.php:216 ../../include/conversation.php:1469 -msgid "Toggle comments" +#: ../../Zotlabs/Module/Import.php:629 +msgid "Or provide the old server/hub details" msgstr "" -#: ../../addon/hsse/hsse.php:221 ../../include/conversation.php:1474 -#: ../../Zotlabs/Module/Article_edit.php:116 -#: ../../Zotlabs/Module/Card_edit.php:117 -#: ../../Zotlabs/Module/Editblock.php:129 ../../Zotlabs/Module/Photos.php:674 -#: ../../Zotlabs/Module/Photos.php:1044 -msgid "Title (optional)" +#: ../../Zotlabs/Module/Import.php:631 +msgid "Your old identity address (xyz@example.com)" msgstr "" -#: ../../addon/hsse/hsse.php:224 ../../include/conversation.php:1477 -msgid "Categories (optional, comma-separated list)" +#: ../../Zotlabs/Module/Import.php:632 +msgid "Your old login email address" msgstr "" -#: ../../addon/hsse/hsse.php:225 ../../include/conversation.php:1478 -#: ../../Zotlabs/Module/Events.php:487 -msgid "Permission settings" +#: ../../Zotlabs/Module/Import.php:633 +msgid "Your old login password" msgstr "" -#: ../../addon/hsse/hsse.php:247 ../../include/conversation.php:1500 -msgid "Other networks and post services" +#: ../../Zotlabs/Module/Import.php:634 +msgid "Import a few months of posts if possible (limited by available memory" msgstr "" -#: ../../addon/hsse/hsse.php:250 ../../addon/mail/Mod_Mail.php:170 -#: ../../addon/mail/Mod_Mail.php:313 ../../include/conversation.php:1503 -msgid "Set expiration date" +#: ../../Zotlabs/Module/Import.php:636 +msgid "" +"For either option, please choose whether to make this hub your new primary " +"address, or whether your old location should continue this role. You will be " +"able to post from either location, but only one can be marked as the primary " +"location for files, photos, and media." msgstr "" -#: ../../addon/hsse/hsse.php:253 ../../include/conversation.php:1506 -msgid "Set publish date" +#: ../../Zotlabs/Module/Import.php:638 +msgid "Make this hub my primary location" msgstr "" -#: ../../addon/hsse/hsse.php:255 ../../addon/mail/Mod_Mail.php:172 -#: ../../addon/mail/Mod_Mail.php:315 ../../include/conversation.php:1508 -#: ../../Zotlabs/Module/Chat.php:219 ../../Zotlabs/Lib/ThreadItem.php:839 -msgid "Encrypt text" +#: ../../Zotlabs/Module/Import.php:639 +msgid "Move this channel (disable all previous locations)" msgstr "" -#: ../../addon/hsse/Mod_Hsse.php:15 -msgid "WYSIWYG status editor" +#: ../../Zotlabs/Module/Import.php:640 +msgid "Use this channel nickname instead of the one provided" msgstr "" -#: ../../addon/hsse/Mod_Hsse.php:21 ../../addon/hsse/Mod_Hsse.php:26 -msgid "WYSIWYG Status App" +#: ../../Zotlabs/Module/Import.php:640 +msgid "" +"Leave blank to keep your existing channel nickname. You will be randomly " +"assigned a similar nickname if either name is already allocated on this site." msgstr "" -#: ../../addon/hsse/Mod_Hsse.php:34 -msgid "WYSIWYG Status" +#: ../../Zotlabs/Module/Import.php:642 +msgid "" +"This process may take several minutes to complete. Please submit the form " +"only once and leave this page open until finished." msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:133 -msgid "View Larger" +#: ../../Zotlabs/Module/Like.php:93 +msgid "Like/Dislike" msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:156 -msgid "Tile Server URL" +#: ../../Zotlabs/Module/Like.php:98 +msgid "This action is restricted to members." msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:156 +#: ../../Zotlabs/Module/Like.php:99 msgid "" -"A list of public tile servers" +"Please login with your $Projectname ID or register as a new $Projectname member to continue." msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:157 -msgid "Nominatim (reverse geocoding) Server URL" +#: ../../Zotlabs/Module/Like.php:154 ../../Zotlabs/Module/Like.php:180 +#: ../../Zotlabs/Module/Like.php:218 +msgid "Invalid request." msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:157 -msgid "" -"A list of Nominatim servers" +#: ../../Zotlabs/Module/Like.php:166 ../../include/conversation.php:135 +msgid "channel" msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:158 -msgid "Default zoom" +#: ../../Zotlabs/Module/Like.php:195 +msgid "thing" msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:158 -msgid "" -"The default zoom level. (1:world, 18:highest, also depends on tile server)" +#: ../../Zotlabs/Module/Like.php:241 +msgid "Channel unavailable." msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:159 -msgid "Include marker on map" +#: ../../Zotlabs/Module/Like.php:277 +msgid "Previous action reversed." msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:159 -msgid "Include a marker on the map." +#: ../../Zotlabs/Module/Like.php:433 ../../Zotlabs/Module/Tagger.php:71 +#: ../../Zotlabs/Module/Subthread.php:112 ../../Zotlabs/Lib/Activity.php:2971 +#: ../../include/conversation.php:128 ../../include/text.php:2252 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1597 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1895 +#: ../../extend/addon/hzaddons/redphotos/redphotohelper.php:71 +msgid "photo" msgstr "" -#: ../../addon/openstreetmap/openstreetmap.php:171 -#: ../../addon/rendezvous/rendezvous.php:82 ../../addon/twitter/twitter.php:494 -#: ../../addon/msgfooter/msgfooter.php:54 ../../addon/diaspora/diaspora.php:93 -#: ../../addon/piwik/piwik.php:116 ../../addon/logrot/logrot.php:54 -#: ../../addon/xmpp/xmpp.php:54 ../../Zotlabs/Module/Settings/Channel.php:267 -#: ../../Zotlabs/Module/Defperms.php:112 -msgid "Settings updated." +#: ../../Zotlabs/Module/Like.php:433 ../../Zotlabs/Module/Subthread.php:112 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1597 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1895 +msgid "status" msgstr "" -#: ../../addon/ijpost/Mod_Ijpost.php:23 -msgid "Insane Journal Crosspost Connector Settings saved." +#: ../../Zotlabs/Module/Like.php:469 ../../Zotlabs/Lib/Activity.php:3006 +#: ../../include/conversation.php:174 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1537 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1932 +#, php-format +msgid "%1$s likes %2$s's %3$s" msgstr "" -#: ../../addon/ijpost/Mod_Ijpost.php:35 -msgid "Insane Journal Crosspost Connector App" +#: ../../Zotlabs/Module/Like.php:471 ../../Zotlabs/Lib/Activity.php:3008 +#: ../../include/conversation.php:177 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1934 +#, php-format +msgid "%1$s doesn't like %2$s's %3$s" msgstr "" -#: ../../addon/ijpost/Mod_Ijpost.php:36 -msgid "Relay public postings to Insane Journal" +#: ../../Zotlabs/Module/Like.php:473 +#, php-format +msgid "%1$s agrees with %2$s's %3$s" msgstr "" -#: ../../addon/ijpost/Mod_Ijpost.php:53 -msgid "InsaneJournal username" +#: ../../Zotlabs/Module/Like.php:475 +#, php-format +msgid "%1$s doesn't agree with %2$s's %3$s" msgstr "" -#: ../../addon/ijpost/Mod_Ijpost.php:57 -msgid "InsaneJournal password" +#: ../../Zotlabs/Module/Like.php:477 +#, php-format +msgid "%1$s abstains from a decision on %2$s's %3$s" msgstr "" -#: ../../addon/ijpost/Mod_Ijpost.php:61 -msgid "Post to InsaneJournal by default" +#: ../../Zotlabs/Module/Like.php:479 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2184 +#, php-format +msgid "%1$s is attending %2$s's %3$s" msgstr "" -#: ../../addon/ijpost/Mod_Ijpost.php:69 -msgid "Insane Journal Crosspost Connector" +#: ../../Zotlabs/Module/Like.php:481 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2186 +#, php-format +msgid "%1$s is not attending %2$s's %3$s" msgstr "" -#: ../../addon/ijpost/ijpost.php:44 -msgid "Post to Insane Journal" +#: ../../Zotlabs/Module/Like.php:483 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2188 +#, php-format +msgid "%1$s may attend %2$s's %3$s" msgstr "" -#: ../../addon/wholikesme/wholikesme.php:29 -msgid "Who likes me?" +#: ../../Zotlabs/Module/Like.php:592 +msgid "Action completed." msgstr "" -#: ../../addon/qrator/qrator.php:48 -msgid "QR code" -msgstr "" - -#: ../../addon/qrator/qrator.php:63 -msgid "QR Generator" +#: ../../Zotlabs/Module/Like.php:593 +msgid "Thank you." msgstr "" -#: ../../addon/qrator/qrator.php:64 -msgid "Enter some text" +#: ../../Zotlabs/Module/Defperms.php:68 ../../Zotlabs/Module/Connedit.php:89 +msgid "Could not access contact record." msgstr "" -#: ../../addon/pubcrawl/as.php:1187 ../../include/cdav.php:158 -#: ../../include/cdav.php:159 ../../include/cdav.php:167 -#: ../../include/conversation.php:1211 ../../Zotlabs/Widget/Album.php:84 -#: ../../Zotlabs/Widget/Pinned.php:270 ../../Zotlabs/Widget/Portfolio.php:95 -#: ../../Zotlabs/Module/Embedphotos.php:176 ../../Zotlabs/Module/Photos.php:793 -#: ../../Zotlabs/Module/Photos.php:1255 ../../Zotlabs/Lib/Activity.php:1508 -#: ../../Zotlabs/Lib/Apps.php:1112 ../../Zotlabs/Lib/Apps.php:1196 -msgid "Unknown" +#: ../../Zotlabs/Module/Defperms.php:112 +#: ../../Zotlabs/Module/Settings/Channel.php:267 +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:54 +#: ../../extend/addon/hzaddons/piwik/piwik.php:116 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:82 +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:93 +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171 +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:54 +#: ../../extend/addon/hzaddons/twitter/twitter.php:494 +#: ../../extend/addon/hzaddons/logrot/logrot.php:54 +msgid "Settings updated." msgstr "" -#: ../../addon/pubcrawl/as.php:1483 ../../addon/pubcrawl/as.php:1895 -#: ../../addon/pubcrawl/as.php:2103 ../../include/network.php:1736 -#: ../../Zotlabs/Lib/Activity.php:2821 ../../Zotlabs/Lib/Activity.php:3015 -msgid "ActivityPub" +#: ../../Zotlabs/Module/Defperms.php:190 +msgid "Default Permissions App" msgstr "" -#: ../../addon/pubcrawl/as.php:2057 ../../addon/diaspora/Receiver.php:1597 -#: ../../Zotlabs/Module/Like.php:433 ../../Zotlabs/Module/Subthread.php:112 -msgid "status" +#: ../../Zotlabs/Module/Defperms.php:191 +msgid "Set custom default permissions for new connections" msgstr "" -#: ../../addon/pubcrawl/as.php:2094 ../../addon/diaspora/Receiver.php:1537 -#: ../../include/conversation.php:174 ../../Zotlabs/Module/Like.php:469 -#: ../../Zotlabs/Lib/Activity.php:3006 -#, php-format -msgid "%1$s likes %2$s's %3$s" +#: ../../Zotlabs/Module/Defperms.php:255 ../../Zotlabs/Module/Connedit.php:859 +msgid "Connection Default Permissions" msgstr "" -#: ../../addon/pubcrawl/as.php:2096 ../../include/conversation.php:177 -#: ../../Zotlabs/Module/Like.php:471 ../../Zotlabs/Lib/Activity.php:3008 -#, php-format -msgid "%1$s doesn't like %2$s's %3$s" +#: ../../Zotlabs/Module/Defperms.php:256 ../../Zotlabs/Module/Connedit.php:860 +msgid "Apply these permissions automatically" msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:25 -msgid "ActivityPub Protocol Settings updated." +#: ../../Zotlabs/Module/Defperms.php:256 +#: ../../Zotlabs/Module/Settings/Channel.php:472 +msgid "" +"If enabled, connection requests will be approved without your interaction" msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:34 -msgid "" -"The activitypub protocol does not support location independence. Connections " -"you make within that network may be unreachable from alternate channel " -"locations." +#: ../../Zotlabs/Module/Defperms.php:257 ../../Zotlabs/Module/Connedit.php:861 +msgid "Permission role" msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:40 -msgid "Activitypub Protocol App" +#: ../../Zotlabs/Module/Defperms.php:257 +#: ../../Zotlabs/Module/New_channel.php:157 +#: ../../Zotlabs/Module/New_channel.php:164 +#: ../../Zotlabs/Module/Connedit.php:861 +#: ../../Zotlabs/Widget/Notifications.php:182 ../../include/nav.php:324 +msgid "Loading" msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:50 -msgid "Deliver to ActivityPub recipients in privacy groups" +#: ../../Zotlabs/Module/Defperms.php:258 ../../Zotlabs/Module/Connedit.php:862 +msgid "Add permission role" msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:50 +#: ../../Zotlabs/Module/Defperms.php:262 ../../Zotlabs/Module/Connedit.php:875 msgid "" -"May result in a large number of mentions and expose all the members of your " -"privacy group" +"The permissions indicated on this page will be applied to all new " +"connections." msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:54 -msgid "Send multi-media HTML articles" +#: ../../Zotlabs/Module/Defperms.php:263 +msgid "Automatic approval settings" msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:54 -msgid "Not supported by some microblog services such as Mastodon" +#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Connedit.php:895 +#: ../../Zotlabs/Module/Tokens.php:183 ../../Zotlabs/Module/Permcats.php:124 +msgid "inherited" msgstr "" -#: ../../addon/pubcrawl/Mod_Pubcrawl.php:62 -msgid "Activitypub Protocol" +#: ../../Zotlabs/Module/Defperms.php:267 ../../Zotlabs/Module/Connedit.php:900 +#: ../../Zotlabs/Module/Tokens.php:181 ../../Zotlabs/Module/Permcats.php:122 +msgid "My Settings" msgstr "" -#: ../../addon/ldapauth/ldapauth.php:70 -msgid "An account has been created for you." +#: ../../Zotlabs/Module/Defperms.php:270 ../../Zotlabs/Module/Connedit.php:902 +#: ../../Zotlabs/Module/Tokens.php:186 ../../Zotlabs/Module/Permcats.php:127 +msgid "Individual Permissions" msgstr "" -#: ../../addon/ldapauth/ldapauth.php:77 -msgid "Authentication successful but rejected: account creation is disabled." +#: ../../Zotlabs/Module/Defperms.php:271 +msgid "" +"Some individual permissions may have been preset or locked based on your " +"channel type and privacy settings." msgstr "" -#: ../../addon/dwpost/Mod_Dwpost.php:26 -msgid "Dreamwidth Crosspost Connector Settings saved." +#: ../../Zotlabs/Module/Layouts.php:129 ../../Zotlabs/Module/Layouts.php:189 +#: ../../Zotlabs/Module/Editlayout.php:128 +msgid "Layout Name" msgstr "" -#: ../../addon/dwpost/Mod_Dwpost.php:39 -msgid "Dreamwidth Crosspost Connector App" +#: ../../Zotlabs/Module/Layouts.php:132 ../../Zotlabs/Module/Editlayout.php:129 +msgid "Layout Description (Optional)" msgstr "" -#: ../../addon/dwpost/Mod_Dwpost.php:40 -msgid "Relay public posts to Dreamwidth" +#: ../../Zotlabs/Module/Layouts.php:184 ../../include/text.php:2700 +msgid "Layouts" msgstr "" -#: ../../addon/dwpost/Mod_Dwpost.php:53 -msgid "Dreamwidth username" +#: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:348 +#: ../../include/nav.php:174 ../../include/nav.php:320 +#: ../../include/help.php:117 ../../include/help.php:125 +msgid "Help" msgstr "" -#: ../../addon/dwpost/Mod_Dwpost.php:57 -msgid "Dreamwidth password" +#: ../../Zotlabs/Module/Layouts.php:186 +msgid "Comanche page description language help" msgstr "" -#: ../../addon/dwpost/Mod_Dwpost.php:61 -msgid "Post to Dreamwidth by default" +#: ../../Zotlabs/Module/Layouts.php:190 +msgid "Layout Description" msgstr "" -#: ../../addon/dwpost/Mod_Dwpost.php:77 -msgid "Dreamwidth Crosspost Connector" +#: ../../Zotlabs/Module/Layouts.php:195 +msgid "Download PDL file" msgstr "" -#: ../../addon/dwpost/dwpost.php:49 -msgid "Post to Dreamwidth" +#: ../../Zotlabs/Module/Pubstream.php:20 +msgid "Public Stream App" msgstr "" -#: ../../addon/morepokes/morepokes.php:19 -msgid "bitchslap" +#: ../../Zotlabs/Module/Pubstream.php:21 +msgid "The unmoderated public stream of this hub" msgstr "" -#: ../../addon/morepokes/morepokes.php:19 -msgid "bitchslapped" +#: ../../Zotlabs/Module/Pubstream.php:95 ../../Zotlabs/Module/Display.php:76 +#: ../../Zotlabs/Module/Channel.php:224 ../../Zotlabs/Module/Hq.php:125 +#: ../../Zotlabs/Module/Network.php:205 +msgid "Reset form" msgstr "" -#: ../../addon/morepokes/morepokes.php:20 -msgid "shag" +#: ../../Zotlabs/Module/Pubstream.php:105 ../../Zotlabs/Lib/Apps.php:375 +#: ../../Zotlabs/Widget/Notifications.php:162 +msgid "Public Stream" msgstr "" -#: ../../addon/morepokes/morepokes.php:20 -msgid "shagged" +#: ../../Zotlabs/Module/Sse_bs.php:540 ../../Zotlabs/Module/Ping.php:672 +msgid "Private forum" msgstr "" -#: ../../addon/morepokes/morepokes.php:21 -msgid "patent" +#: ../../Zotlabs/Module/Sse_bs.php:540 ../../Zotlabs/Module/Ping.php:672 +msgid "Public forum" msgstr "" -#: ../../addon/morepokes/morepokes.php:21 -msgid "patented" +#: ../../Zotlabs/Module/Group.php:46 +msgid "Privacy group created." msgstr "" -#: ../../addon/morepokes/morepokes.php:22 -msgid "hug" +#: ../../Zotlabs/Module/Group.php:49 +msgid "Could not create privacy group." msgstr "" -#: ../../addon/morepokes/morepokes.php:22 -msgid "hugged" +#: ../../Zotlabs/Module/Group.php:62 ../../Zotlabs/Module/Group.php:214 +#: ../../include/items.php:4491 +msgid "Privacy group not found." msgstr "" -#: ../../addon/morepokes/morepokes.php:23 -msgid "murder" +#: ../../Zotlabs/Module/Group.php:81 +msgid "Privacy group updated." msgstr "" -#: ../../addon/morepokes/morepokes.php:23 -msgid "murdered" +#: ../../Zotlabs/Module/Group.php:107 +msgid "Privacy Groups App" msgstr "" -#: ../../addon/morepokes/morepokes.php:24 -msgid "worship" +#: ../../Zotlabs/Module/Group.php:108 +msgid "Management of privacy groups" msgstr "" -#: ../../addon/morepokes/morepokes.php:24 -msgid "worshipped" +#: ../../Zotlabs/Module/Group.php:142 ../../Zotlabs/Module/Group.php:154 +#: ../../Zotlabs/Lib/Group.php:324 ../../Zotlabs/Lib/Apps.php:364 +#: ../../Zotlabs/Widget/Activity_filter.php:82 ../../include/group.php:321 +#: ../../include/acl_selectors.php:86 ../../include/nav.php:101 +msgid "Privacy Groups" msgstr "" -#: ../../addon/morepokes/morepokes.php:25 -msgid "kiss" +#: ../../Zotlabs/Module/Group.php:143 +msgid "Add Group" msgstr "" -#: ../../addon/morepokes/morepokes.php:25 -msgid "kissed" +#: ../../Zotlabs/Module/Group.php:147 +msgid "Privacy group name" msgstr "" -#: ../../addon/morepokes/morepokes.php:26 -msgid "tempt" +#: ../../Zotlabs/Module/Group.php:148 ../../Zotlabs/Module/Group.php:257 +msgid "Members are visible to other channels" msgstr "" -#: ../../addon/morepokes/morepokes.php:26 -msgid "tempted" +#: ../../Zotlabs/Module/Group.php:183 +msgid "Privacy group removed." msgstr "" -#: ../../addon/morepokes/morepokes.php:27 -msgid "raise eyebrows at" +#: ../../Zotlabs/Module/Group.php:186 +msgid "Unable to remove privacy group." msgstr "" -#: ../../addon/morepokes/morepokes.php:27 -msgid "raised their eyebrows at" +#: ../../Zotlabs/Module/Group.php:252 +#, php-format +msgid "Privacy Group: %s" msgstr "" -#: ../../addon/morepokes/morepokes.php:28 -msgid "insult" +#: ../../Zotlabs/Module/Group.php:254 +msgid "Privacy group name: " msgstr "" -#: ../../addon/morepokes/morepokes.php:28 -msgid "insulted" +#: ../../Zotlabs/Module/Group.php:259 +msgid "Delete Group" msgstr "" -#: ../../addon/morepokes/morepokes.php:29 -msgid "praise" +#: ../../Zotlabs/Module/Group.php:270 +msgid "Group members" msgstr "" -#: ../../addon/morepokes/morepokes.php:29 -msgid "praised" +#: ../../Zotlabs/Module/Group.php:272 +msgid "Not in this group" msgstr "" -#: ../../addon/morepokes/morepokes.php:30 -msgid "be dubious of" +#: ../../Zotlabs/Module/Group.php:304 +msgid "Click a channel to toggle membership" msgstr "" -#: ../../addon/morepokes/morepokes.php:30 -msgid "was dubious of" +#: ../../Zotlabs/Module/Removeme.php:35 +msgid "" +"Channel removals are not allowed within 48 hours of changing the account " +"password." msgstr "" -#: ../../addon/morepokes/morepokes.php:31 -msgid "eat" +#: ../../Zotlabs/Module/Removeme.php:60 +msgid "Remove This Channel" msgstr "" -#: ../../addon/morepokes/morepokes.php:31 -msgid "ate" +#: ../../Zotlabs/Module/Removeme.php:61 ../../Zotlabs/Module/Changeaddr.php:78 +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "WARNING: " msgstr "" -#: ../../addon/morepokes/morepokes.php:32 -msgid "giggle and fawn at" +#: ../../Zotlabs/Module/Removeme.php:61 +msgid "This channel will be completely removed from the network. " msgstr "" -#: ../../addon/morepokes/morepokes.php:32 -msgid "giggled and fawned at" +#: ../../Zotlabs/Module/Removeme.php:61 +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "This action is permanent and can not be undone!" msgstr "" -#: ../../addon/morepokes/morepokes.php:33 -msgid "doubt" +#: ../../Zotlabs/Module/Removeme.php:62 ../../Zotlabs/Module/Changeaddr.php:79 +#: ../../Zotlabs/Module/Removeaccount.php:59 +msgid "Please enter your password for verification:" msgstr "" -#: ../../addon/morepokes/morepokes.php:33 -msgid "doubted" +#: ../../Zotlabs/Module/Removeme.php:64 +#: ../../Zotlabs/Module/Settings/Channel.php:596 +msgid "Remove Channel" msgstr "" -#: ../../addon/morepokes/morepokes.php:34 -msgid "glare" +#: ../../Zotlabs/Module/Appman.php:39 ../../Zotlabs/Module/Appman.php:56 +msgid "App installed." msgstr "" -#: ../../addon/morepokes/morepokes.php:34 -msgid "glared at" +#: ../../Zotlabs/Module/Appman.php:49 +msgid "Malformed app." msgstr "" -#: ../../addon/morepokes/morepokes.php:35 -msgid "fuck" +#: ../../Zotlabs/Module/Appman.php:132 +msgid "Embed code" msgstr "" -#: ../../addon/morepokes/morepokes.php:35 -msgid "fucked" +#: ../../Zotlabs/Module/Appman.php:138 +msgid "Edit App" msgstr "" -#: ../../addon/morepokes/morepokes.php:36 -msgid "bonk" +#: ../../Zotlabs/Module/Appman.php:138 +msgid "Create App" msgstr "" -#: ../../addon/morepokes/morepokes.php:36 -msgid "bonked" +#: ../../Zotlabs/Module/Appman.php:143 +msgid "Name of app" msgstr "" -#: ../../addon/morepokes/morepokes.php:37 -msgid "declare undying love for" +#: ../../Zotlabs/Module/Appman.php:144 +msgid "Location (URL) of app" msgstr "" -#: ../../addon/morepokes/morepokes.php:37 -msgid "declared undying love for" +#: ../../Zotlabs/Module/Appman.php:146 +msgid "Photo icon URL" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:57 -msgid "Errors encountered deleting database table " +#: ../../Zotlabs/Module/Appman.php:146 +msgid "80 x 80 pixels - optional" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:95 ../../addon/twitter/twitter.php:503 -msgid "Submit Settings" +#: ../../Zotlabs/Module/Appman.php:147 +msgid "Categories (optional, comma separated list)" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:96 -msgid "Drop tables when uninstalling?" +#: ../../Zotlabs/Module/Appman.php:148 +msgid "Version ID" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:96 -msgid "" -"If checked, the Rendezvous database tables will be deleted when the plugin " -"is uninstalled." +#: ../../Zotlabs/Module/Appman.php:149 +msgid "Price of app" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:97 -msgid "Mapbox Access Token" +#: ../../Zotlabs/Module/Appman.php:150 +msgid "Location (URL) to purchase app" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:97 +#: ../../Zotlabs/Module/Changeaddr.php:35 msgid "" -"If you enter a Mapbox access token, it will be used to retrieve map tiles " -"from Mapbox instead of the default OpenStreetMap tile server." +"Channel name changes are not allowed within 48 hours of changing the account " +"password." msgstr "" -#: ../../addon/rendezvous/rendezvous.php:162 -msgid "Rendezvous" +#: ../../Zotlabs/Module/Changeaddr.php:46 ../../include/channel.php:225 +#: ../../include/channel.php:706 +msgid "Reserved nickname. Please choose another." msgstr "" -#: ../../addon/rendezvous/rendezvous.php:167 +#: ../../Zotlabs/Module/Changeaddr.php:51 ../../include/channel.php:230 +#: ../../include/channel.php:711 msgid "" -"This identity has been deleted by another member due to inactivity. Please " -"press the \"New identity\" button or refresh the page to register a new " -"identity. You may use the same name." +"Nickname has unsupported characters or is already being used on this site." msgstr "" -#: ../../addon/rendezvous/rendezvous.php:168 -msgid "Welcome to Rendezvous!" +#: ../../Zotlabs/Module/Changeaddr.php:77 +msgid "Change channel nickname/address" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:169 -msgid "" -"Enter your name to join this rendezvous. To begin sharing your location with " -"the other members, tap the GPS control. When your location is discovered, a " -"red dot will appear and others will be able to see you on the map." +#: ../../Zotlabs/Module/Changeaddr.php:78 +msgid "Any/all connections on other networks will be lost!" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:171 -msgid "Let's meet here" +#: ../../Zotlabs/Module/Changeaddr.php:80 +msgid "New channel address" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:172 -#: ../../Zotlabs/Widget/Wiki_page_history.php:22 -#: ../../Zotlabs/Module/Group.php:155 ../../Zotlabs/Module/Oauth.php:113 -#: ../../Zotlabs/Module/Oauth.php:139 ../../Zotlabs/Module/Chat.php:257 -#: ../../Zotlabs/Module/Cdav.php:1372 ../../Zotlabs/Module/Sharedwithme.php:106 -#: ../../Zotlabs/Module/Admin/Channels.php:159 -#: ../../Zotlabs/Module/Oauth2.php:118 ../../Zotlabs/Module/Oauth2.php:146 -#: ../../Zotlabs/Module/Wiki.php:218 ../../Zotlabs/Module/Connedit.php:915 -#: ../../Zotlabs/Lib/NativeWikiPage.php:564 -#: ../../Zotlabs/Storage/Browser.php:370 -msgid "Name" +#: ../../Zotlabs/Module/Changeaddr.php:81 +msgid "Rename Channel" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:173 -#: ../../addon/cart/submodules/hzservices.php:655 -#: ../../addon/cart/submodules/manualcat.php:260 -#: ../../Zotlabs/Module/Cdav.php:1014 ../../Zotlabs/Module/Events.php:481 -#: ../../Zotlabs/Module/Appman.php:145 ../../Zotlabs/Module/Rbmark.php:101 -msgid "Description" +#: ../../Zotlabs/Module/Oauth.php:45 +msgid "Name is required" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:174 -msgid "New marker" +#: ../../Zotlabs/Module/Oauth.php:49 +msgid "Key and Secret are required" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:175 -msgid "Edit marker" +#: ../../Zotlabs/Module/Oauth.php:100 +msgid "OAuth Apps Manager App" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:176 -msgid "New identity" +#: ../../Zotlabs/Module/Oauth.php:101 +msgid "OAuth authentication tokens for mobile and remote apps" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:177 -msgid "Delete marker" +#: ../../Zotlabs/Module/Oauth.php:110 ../../Zotlabs/Module/Oauth.php:136 +#: ../../Zotlabs/Module/Oauth.php:172 ../../Zotlabs/Module/Oauth2.php:143 +#: ../../Zotlabs/Module/Oauth2.php:193 +msgid "Add application" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:178 -msgid "Delete member" +#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth2.php:118 +#: ../../Zotlabs/Module/Oauth2.php:146 +msgid "Name of application" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:179 -msgid "Edit proximity alert" +#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:140 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:596 +#: ../../extend/addon/hzaddons/twitter/twitter.php:505 +msgid "Consumer Key" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:180 -msgid "" -"A proximity alert will be issued when this member is within a certain radius " -"of you.

      Enter a radius in meters (0 to disable):" +#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:115 +#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 +msgid "Automatically generated - change if desired. Max length 20" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:180 -#: ../../addon/rendezvous/rendezvous.php:185 -msgid "distance" +#: ../../Zotlabs/Module/Oauth.php:115 ../../Zotlabs/Module/Oauth.php:141 +#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:595 +#: ../../extend/addon/hzaddons/twitter/twitter.php:506 +msgid "Consumer Secret" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:181 -msgid "Proximity alert distance (meters)" +#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth.php:142 +#: ../../Zotlabs/Module/Oauth2.php:120 ../../Zotlabs/Module/Oauth2.php:148 +msgid "Redirect" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:182 -#: ../../addon/rendezvous/rendezvous.php:184 +#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth2.php:120 +#: ../../Zotlabs/Module/Oauth2.php:148 msgid "" -"A proximity alert will be issued when you are within a certain radius of the " -"marker location.

      Enter a radius in meters (0 to disable):" -msgstr "" - -#: ../../addon/rendezvous/rendezvous.php:183 -msgid "Marker proximity alert" -msgstr "" - -#: ../../addon/rendezvous/rendezvous.php:186 -msgid "Reminder note" +"Redirect URI - leave blank unless your application specifically requires this" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:187 -msgid "" -"Enter a note to be displayed when you are within the specified proximity..." +#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Oauth.php:143 +msgid "Icon url" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:199 -msgid "Add new rendezvous" +#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Sources.php:123 +#: ../../Zotlabs/Module/Sources.php:158 +msgid "Optional" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:200 -msgid "" -"Create a new rendezvous and share the access link with those you wish to " -"invite to the group. Those who open the link become members of the " -"rendezvous. They can view other member locations, add markers to the map, or " -"share their own locations with the group." +#: ../../Zotlabs/Module/Oauth.php:128 +msgid "Application not found." msgstr "" -#: ../../addon/rendezvous/rendezvous.php:232 -msgid "You have no rendezvous. Press the button above to create a rendezvous!" +#: ../../Zotlabs/Module/Oauth.php:171 +msgid "Connected OAuth Apps" msgstr "" -#: ../../addon/rendezvous/rendezvous.php:401 ../../Zotlabs/Module/Setup.php:718 -msgid "Errors encountered creating database tables." +#: ../../Zotlabs/Module/Oauth.php:175 ../../Zotlabs/Module/Oauth2.php:196 +msgid "Client key starts with" msgstr "" -#: ../../addon/startpage/Mod_Startpage.php:50 -msgid "Startpage App" +#: ../../Zotlabs/Module/Oauth.php:176 ../../Zotlabs/Module/Oauth2.php:197 +msgid "No name" msgstr "" -#: ../../addon/startpage/Mod_Startpage.php:51 -msgid "Set a preferred page to load on login from home page" +#: ../../Zotlabs/Module/Oauth.php:177 ../../Zotlabs/Module/Oauth2.php:198 +msgid "Remove authorization" msgstr "" -#: ../../addon/startpage/Mod_Startpage.php:62 -msgid "Page to load after login" +#: ../../Zotlabs/Module/Email_resend.php:12 +#: ../../Zotlabs/Module/Email_validation.php:24 +msgid "Token verification failed." msgstr "" -#: ../../addon/startpage/Mod_Startpage.php:62 -msgid "" -"Examples: "apps", "network?f=&gid=37" (privacy " -"collection), "channel" or "notifications/system" (leave " -"blank for default network page (grid)." +#: ../../Zotlabs/Module/Email_resend.php:30 +msgid "Email verification resent" msgstr "" -#: ../../addon/startpage/Mod_Startpage.php:70 -msgid "Startpage" +#: ../../Zotlabs/Module/Email_resend.php:33 +msgid "Unable to resend email verification message." msgstr "" -#: ../../addon/mail/Mod_Mail.php:39 -msgid "Messages" +#: ../../Zotlabs/Module/Search.php:17 +#: ../../Zotlabs/Module/Viewconnections.php:23 +#: ../../Zotlabs/Module/Display.php:26 ../../Zotlabs/Module/Photos.php:519 +#: ../../Zotlabs/Module/Directory.php:73 ../../Zotlabs/Module/Directory.php:78 +#: ../../Zotlabs/Module/Ratings.php:83 +msgid "Public access denied." msgstr "" -#: ../../addon/mail/Mod_Mail.php:52 -msgid "message" +#: ../../Zotlabs/Module/Search.php:41 ../../Zotlabs/Module/Connections.php:378 +#: ../../Zotlabs/Lib/Apps.php:353 ../../Zotlabs/Widget/Sitesearch.php:31 +#: ../../Zotlabs/Widget/Activity_filter.php:193 ../../include/text.php:1150 +#: ../../include/text.php:1162 ../../include/acl_selectors.php:148 +#: ../../include/nav.php:188 +msgid "Search" msgstr "" -#: ../../addon/mail/Mod_Mail.php:92 -msgid "Message recalled." +#: ../../Zotlabs/Module/Search.php:222 +#, php-format +msgid "Items tagged with: %s" msgstr "" -#: ../../addon/mail/Mod_Mail.php:105 -msgid "Conversation removed." +#: ../../Zotlabs/Module/Search.php:224 +#, php-format +msgid "Search results for: %s" msgstr "" -#: ../../addon/mail/Mod_Mail.php:120 ../../addon/mail/Mod_Mail.php:241 -msgid "Expires YYYY-MM-DD HH:MM" +#: ../../Zotlabs/Module/Moderate.php:67 +msgid "Comment approved" msgstr "" -#: ../../addon/mail/Mod_Mail.php:148 -msgid "Requested channel is not in this network" +#: ../../Zotlabs/Module/Moderate.php:71 +msgid "Comment deleted" msgstr "" -#: ../../addon/mail/Mod_Mail.php:156 -msgid "Send Private Message" +#: ../../Zotlabs/Module/Rpost.php:150 ../../Zotlabs/Module/Editpost.php:109 +msgid "Edit post" msgstr "" -#: ../../addon/mail/Mod_Mail.php:157 ../../addon/mail/Mod_Mail.php:300 -msgid "To:" +#: ../../Zotlabs/Module/Oexchange.php:27 +msgid "Unable to find your hub." msgstr "" -#: ../../addon/mail/Mod_Mail.php:160 ../../addon/mail/Mod_Mail.php:302 -msgid "Subject:" +#: ../../Zotlabs/Module/Oexchange.php:41 +msgid "Post successful." msgstr "" -#: ../../addon/mail/Mod_Mail.php:163 ../../Zotlabs/Module/Invite.php:157 -msgid "Your message:" +#: ../../Zotlabs/Module/Chanview.php:95 ../../Zotlabs/Module/Card_edit.php:44 +#: ../../Zotlabs/Module/Wall_upload.php:31 ../../Zotlabs/Module/Page.php:75 +#: ../../Zotlabs/Module/Block.php:41 ../../Zotlabs/Module/Article_edit.php:44 +#: ../../Zotlabs/Module/Attach.php:21 ../../Zotlabs/Module/Cal.php:31 +#: ../../Zotlabs/Module/Attach_edit.php:52 +msgid "Channel not found." msgstr "" -#: ../../addon/mail/Mod_Mail.php:165 ../../addon/mail/Mod_Mail.php:308 -msgid "Attach file" +#: ../../Zotlabs/Module/Chanview.php:132 +msgid "toggle full screen mode" msgstr "" -#: ../../addon/mail/Mod_Mail.php:167 -msgid "Send" +#: ../../Zotlabs/Module/Tagger.php:50 +msgid "Post not found." msgstr "" -#: ../../addon/mail/Mod_Mail.php:271 -msgid "Delete message" +#: ../../Zotlabs/Module/Tagger.php:79 ../../Zotlabs/Lib/Activity.php:2971 +#: ../../include/conversation.php:158 ../../include/text.php:2258 +#: ../../include/markdown.php:204 ../../include/bbcode.php:523 +msgid "post" msgstr "" -#: ../../addon/mail/Mod_Mail.php:272 -msgid "Delivery report" +#: ../../Zotlabs/Module/Tagger.php:81 ../../include/conversation.php:160 +#: ../../include/text.php:2260 +msgid "comment" msgstr "" -#: ../../addon/mail/Mod_Mail.php:273 -msgid "Recall message" +#: ../../Zotlabs/Module/Tagger.php:121 +#, php-format +msgid "%1$s tagged %2$s's %3$s with %4$s" msgstr "" -#: ../../addon/mail/Mod_Mail.php:275 -msgid "Message has been recalled." +#: ../../Zotlabs/Module/Import_items.php:93 +#, php-format +msgid "Warning: Database versions differ by %1$d updates." msgstr "" -#: ../../addon/mail/Mod_Mail.php:293 -msgid "Delete Conversation" +#: ../../Zotlabs/Module/Import_items.php:108 +msgid "Import completed" msgstr "" -#: ../../addon/mail/Mod_Mail.php:295 -msgid "" -"No secure communications available. You may be able to " -"respond from the sender's profile page." +#: ../../Zotlabs/Module/Import_items.php:125 +msgid "Import Items" msgstr "" -#: ../../addon/mail/Mod_Mail.php:299 -msgid "Send Reply" +#: ../../Zotlabs/Module/Import_items.php:126 +msgid "Use this form to import existing posts and content from an export file." msgstr "" -#: ../../addon/mail/Mod_Mail.php:304 -#, php-format -msgid "Your message for %s (%s):" +#: ../../Zotlabs/Module/Connect.php:65 ../../Zotlabs/Module/Connect.php:118 +msgid "Continue" msgstr "" -#: ../../addon/mail/Mod_Mail.php:384 -msgid "Unable to lookup recipient." +#: ../../Zotlabs/Module/Connect.php:99 +msgid "Premium Channel Setup" msgstr "" -#: ../../addon/mail/Mod_Mail.php:391 -msgid "Unable to communicate with requested channel." +#: ../../Zotlabs/Module/Connect.php:101 +msgid "Enable premium channel connection restrictions" msgstr "" -#: ../../addon/mail/Mod_Mail.php:398 -msgid "Cannot verify requested channel." +#: ../../Zotlabs/Module/Connect.php:102 +msgid "" +"Please enter your restrictions or conditions, such as paypal receipt, usage " +"guidelines, etc." msgstr "" -#: ../../addon/mail/Mod_Mail.php:416 -msgid "Selected channel has private message restrictions. Send failed." +#: ../../Zotlabs/Module/Connect.php:104 ../../Zotlabs/Module/Connect.php:124 +msgid "" +"This channel may require additional steps or acknowledgement of the " +"following conditions prior to connecting:" msgstr "" -#: ../../addon/adultphotoflag/adultphotoflag.php:24 -msgid "Flag Adult Photos" +#: ../../Zotlabs/Module/Connect.php:105 +msgid "" +"Potential connections will then see the following text before proceeding:" msgstr "" -#: ../../addon/adultphotoflag/adultphotoflag.php:25 +#: ../../Zotlabs/Module/Connect.php:106 ../../Zotlabs/Module/Connect.php:127 msgid "" -"Provide photo edit option to hide inappropriate photos from default album " -"view" +"By continuing, I certify that I have complied with any instructions provided " +"on this page." msgstr "" -#: ../../addon/upgrade_info/upgrade_info.php:48 -msgid "Your channel has been upgraded to $Projectname version" +#: ../../Zotlabs/Module/Connect.php:115 +msgid "(No specific instructions have been provided by the channel owner.)" msgstr "" -#: ../../addon/upgrade_info/upgrade_info.php:50 -msgid "Please have a look at the" +#: ../../Zotlabs/Module/Connect.php:123 +msgid "Restricted or Premium Channel" msgstr "" -#: ../../addon/upgrade_info/upgrade_info.php:52 -msgid "git history" +#: ../../Zotlabs/Module/New_channel.php:147 ../../Zotlabs/Module/Manage.php:138 +#, php-format +msgid "You have created %1$.0f of %2$.0f allowed channels." msgstr "" -#: ../../addon/upgrade_info/upgrade_info.php:54 -msgid "change log" +#: ../../Zotlabs/Module/New_channel.php:159 +msgid "Your real name is recommended." msgstr "" -#: ../../addon/upgrade_info/upgrade_info.php:55 -msgid "for further info." +#: ../../Zotlabs/Module/New_channel.php:160 +msgid "" +"Examples: \"Bob Jameson\", \"Lisa and her Horses\", \"Soccer\", \"Aviation " +"Group\"" msgstr "" -#: ../../addon/upgrade_info/upgrade_info.php:60 -msgid "Upgrade Info" +#: ../../Zotlabs/Module/New_channel.php:165 +msgid "" +"This will be used to create a unique network address (like an email address)." msgstr "" -#: ../../addon/upgrade_info/upgrade_info.php:64 -msgid "Do not show this again" +#: ../../Zotlabs/Module/New_channel.php:167 +msgid "Allowed characters are a-z 0-9, - and _" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:65 -msgid "Twitter settings updated." +#: ../../Zotlabs/Module/New_channel.php:175 +msgid "Channel name" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:78 -msgid "Twitter Crosspost Connector App" +#: ../../Zotlabs/Module/New_channel.php:177 +#: ../../Zotlabs/Module/Register.php:263 +msgid "Choose a short nickname" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:79 -msgid "Relay public posts to Twitter" +#: ../../Zotlabs/Module/New_channel.php:178 +#: ../../Zotlabs/Module/Register.php:264 +#: ../../Zotlabs/Module/Settings/Channel.php:537 +msgid "Channel role and privacy" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:103 +#: ../../Zotlabs/Module/New_channel.php:178 msgid "" -"No consumer key pair for Twitter found. Please contact your site " -"administrator." +"Select a channel permission role compatible with your usage needs and " +"privacy requirements." msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:125 -msgid "" -"At this Hubzilla instance the Twitter plugin was enabled but you have not " -"yet connected your account to your Twitter account. To do so click the " -"button below to get a PIN from Twitter which you have to copy into the input " -"box below and submit the form. Only your public posts will " -"be posted to Twitter." +#: ../../Zotlabs/Module/New_channel.php:178 +#: ../../Zotlabs/Module/Register.php:264 +msgid "Read more about channel permission roles" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:127 -msgid "Log in with Twitter" +#: ../../Zotlabs/Module/New_channel.php:181 +msgid "Create a Channel" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:130 -msgid "Copy the PIN from Twitter here" +#: ../../Zotlabs/Module/New_channel.php:182 +msgid "" +"A channel is a unique network identity. It can represent a person (social " +"network profile), a forum (group), a business or celebrity page, a newsfeed, " +"and many other things." msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:152 +#: ../../Zotlabs/Module/New_channel.php:183 msgid "" -"Note: Due your privacy settings (Hide your profile " -"details from unknown viewers?) the link potentially included in public " -"postings relayed to Twitter will lead the visitor to a blank page informing " -"the visitor that the access to your profile has been restricted." +"or import an existing channel from another location." msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:157 -msgid "Twitter post length" +#: ../../Zotlabs/Module/New_channel.php:188 +msgid "Validate" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:157 -msgid "Maximum tweet length" +#: ../../Zotlabs/Module/Apps.php:50 ../../Zotlabs/Widget/Appstore.php:14 +msgid "Available Apps" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:162 -msgid "Send public postings to Twitter by default" +#: ../../Zotlabs/Module/Apps.php:50 +msgid "Installed Apps" +msgstr "" + +#: ../../Zotlabs/Module/Apps.php:53 +msgid "Manage Apps" msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:162 +#: ../../Zotlabs/Module/Apps.php:54 +msgid "Create Custom App" +msgstr "" + +#: ../../Zotlabs/Module/Removeaccount.php:35 msgid "" -"If enabled your public postings will be posted to the associated Twitter " -"account by default" +"Account removals are not allowed within 48 hours of changing the account " +"password." msgstr "" -#: ../../addon/twitter/Mod_Twitter.php:181 -msgid "Twitter Crosspost Connector" +#: ../../Zotlabs/Module/Removeaccount.php:57 +msgid "Remove This Account" msgstr "" -#: ../../addon/twitter/twitter.php:109 -msgid "Post to Twitter" +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "" +"This account and all its channels will be completely removed from the " +"network. " msgstr "" -#: ../../addon/pumpio/pumpio.php:152 -msgid "You are now authenticated to pumpio." +#: ../../Zotlabs/Module/Removeaccount.php:61 +#: ../../Zotlabs/Module/Settings/Account.php:105 +msgid "Remove Account" msgstr "" -#: ../../addon/pumpio/pumpio.php:153 -msgid "return to the featured settings page" +#: ../../Zotlabs/Module/Filestorage.php:14 +#: ../../Zotlabs/Module/Filestorage.php:53 +msgid "Deprecated!" msgstr "" -#: ../../addon/pumpio/pumpio.php:168 -msgid "Post to Pump.io" +#: ../../Zotlabs/Module/Filestorage.php:29 ../../Zotlabs/Module/Display.php:42 +#: ../../Zotlabs/Module/Display.php:429 ../../Zotlabs/Module/Admin.php:62 +#: ../../Zotlabs/Module/Admin/Themes.php:72 +#: ../../Zotlabs/Module/Admin/Addons.php:260 ../../Zotlabs/Module/Thing.php:96 +#: ../../Zotlabs/Module/Viewsrc.php:25 ../../include/items.php:3919 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:284 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:285 +msgid "Item not found." msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:40 -msgid "Pump.io Settings saved." +#: ../../Zotlabs/Module/Filestorage.php:109 +#: ../../Zotlabs/Module/Attach_edit.php:69 +msgid "File not found." msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:53 -msgid "Pump.io Crosspost Connector App" +#: ../../Zotlabs/Module/Filestorage.php:157 +msgid "Permission Denied." msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:54 -msgid "Relay public posts to pump.io" +#: ../../Zotlabs/Module/Filestorage.php:190 +msgid "Edit file permissions" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:73 -msgid "Pump.io servername" +#: ../../Zotlabs/Module/Filestorage.php:195 +#: ../../Zotlabs/Module/Connedit.php:682 ../../Zotlabs/Module/Chat.php:241 +#: ../../Zotlabs/Module/Photos.php:678 ../../Zotlabs/Module/Photos.php:1047 +#: ../../Zotlabs/Module/Thing.php:321 ../../Zotlabs/Module/Thing.php:374 +#: ../../include/acl_selectors.php:153 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:254 +msgid "Permissions" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:73 -msgid "Without \"http://\" or \"https://\"" +#: ../../Zotlabs/Module/Filestorage.php:202 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:261 +msgid "Set/edit permissions" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:77 -msgid "Pump.io username" +#: ../../Zotlabs/Module/Filestorage.php:203 +msgid "Include all files and sub folders" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:77 -msgid "Without the servername" +#: ../../Zotlabs/Module/Filestorage.php:204 +msgid "Return to file list" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:88 -msgid "You are not authenticated to pumpio" +#: ../../Zotlabs/Module/Filestorage.php:206 +#: ../../Zotlabs/Storage/Browser.php:386 +msgid "Copy/paste this code to attach file to a post" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:90 -msgid "(Re-)Authenticate your pump.io connection" +#: ../../Zotlabs/Module/Filestorage.php:207 +#: ../../Zotlabs/Storage/Browser.php:387 +msgid "Copy/paste this URL to link file from a web page" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:94 -msgid "Post to pump.io by default" +#: ../../Zotlabs/Module/Filestorage.php:209 +msgid "Share this file" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:98 -msgid "Should posts be public" +#: ../../Zotlabs/Module/Filestorage.php:210 +msgid "Show URL to this file" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:102 -msgid "Mirror all public posts" +#: ../../Zotlabs/Module/Filestorage.php:211 +#: ../../Zotlabs/Storage/Browser.php:552 +msgid "Show in your contacts shared folder" msgstr "" -#: ../../addon/pumpio/Mod_Pumpio.php:112 -msgid "Pump.io Crosspost Connector" +#: ../../Zotlabs/Module/Card_edit.php:17 ../../Zotlabs/Module/Card_edit.php:33 +#: ../../Zotlabs/Module/Editlayout.php:79 ../../Zotlabs/Module/Editblock.php:79 +#: ../../Zotlabs/Module/Editblock.php:95 ../../Zotlabs/Module/Editpost.php:24 +#: ../../Zotlabs/Module/Editwebpage.php:80 +#: ../../Zotlabs/Module/Article_edit.php:17 +#: ../../Zotlabs/Module/Article_edit.php:33 +msgid "Item not found" msgstr "" -#: ../../addon/gravatar/gravatar.php:123 -msgid "generic profile image" +#: ../../Zotlabs/Module/Card_edit.php:101 +#: ../../Zotlabs/Module/Editblock.php:116 ../../Zotlabs/Module/Chat.php:220 +#: ../../Zotlabs/Module/Editwebpage.php:143 +#: ../../Zotlabs/Module/Article_edit.php:100 +#: ../../include/conversation.php:1341 +#: ../../extend/addon/hzaddons/hsse/hsse.php:95 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:166 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:309 +msgid "Insert web link" msgstr "" -#: ../../addon/gravatar/gravatar.php:124 -msgid "random geometric pattern" +#: ../../Zotlabs/Module/Card_edit.php:117 +#: ../../Zotlabs/Module/Editblock.php:129 ../../Zotlabs/Module/Photos.php:674 +#: ../../Zotlabs/Module/Photos.php:1044 +#: ../../Zotlabs/Module/Article_edit.php:116 +#: ../../include/conversation.php:1474 +#: ../../extend/addon/hzaddons/hsse/hsse.php:221 +msgid "Title (optional)" msgstr "" -#: ../../addon/gravatar/gravatar.php:125 -msgid "monster face" +#: ../../Zotlabs/Module/Card_edit.php:128 +msgid "Edit Card" msgstr "" -#: ../../addon/gravatar/gravatar.php:126 -msgid "computer generated face" +#: ../../Zotlabs/Module/Viewconnections.php:65 +msgid "No connections." msgstr "" -#: ../../addon/gravatar/gravatar.php:127 -msgid "retro arcade style face" +#: ../../Zotlabs/Module/Viewconnections.php:80 +#: ../../Zotlabs/Module/Connections.php:288 ../../include/text.php:1044 +msgid "Accepts" msgstr "" -#: ../../addon/gravatar/gravatar.php:128 -msgid "Hub default profile photo" +#: ../../Zotlabs/Module/Viewconnections.php:83 +#: ../../Zotlabs/Module/Connections.php:291 ../../include/text.php:1047 +msgid "Comments" msgstr "" -#: ../../addon/gravatar/gravatar.php:143 -msgid "Information" +#: ../../Zotlabs/Module/Viewconnections.php:88 +#: ../../Zotlabs/Module/Connections.php:296 ../../include/text.php:1052 +msgid "Stream items" msgstr "" -#: ../../addon/gravatar/gravatar.php:143 -msgid "" -"Libravatar addon is installed, too. Please disable Libravatar addon or this " -"Gravatar addon.
      The Libravatar addon will fall back to Gravatar if " -"nothing was found at Libravatar." +#: ../../Zotlabs/Module/Viewconnections.php:93 +#: ../../Zotlabs/Module/Connections.php:301 ../../include/text.php:1057 +msgid "Wall posts" msgstr "" -#: ../../addon/gravatar/gravatar.php:150 ../../addon/msgfooter/msgfooter.php:46 -#: ../../addon/xmpp/xmpp.php:43 -msgid "Save Settings" +#: ../../Zotlabs/Module/Viewconnections.php:97 +#: ../../Zotlabs/Module/Connections.php:305 ../../include/text.php:1061 +msgid "Nothing" msgstr "" -#: ../../addon/gravatar/gravatar.php:151 -msgid "Default avatar image" +#: ../../Zotlabs/Module/Viewconnections.php:105 +#, php-format +msgid "Visit %s's profile [%s]" msgstr "" -#: ../../addon/gravatar/gravatar.php:151 -msgid "Select default avatar image if none was found at Gravatar. See README" +#: ../../Zotlabs/Module/Viewconnections.php:135 +msgid "View Connections" msgstr "" -#: ../../addon/gravatar/gravatar.php:152 -msgid "Rating of images" +#: ../../Zotlabs/Module/Oauth2.php:54 +msgid "Name and Secret are required" msgstr "" -#: ../../addon/gravatar/gravatar.php:152 -msgid "Select the appropriate avatar rating for your site. See README" +#: ../../Zotlabs/Module/Oauth2.php:106 +msgid "OAuth2 Apps Manager App" msgstr "" -#: ../../addon/gravatar/gravatar.php:165 -msgid "Gravatar settings updated." +#: ../../Zotlabs/Module/Oauth2.php:107 +msgid "OAuth2 authenticatication tokens for mobile and remote apps" msgstr "" -#: ../../addon/msgfooter/msgfooter.php:47 -msgid "text to include in all outgoing posts from this site" +#: ../../Zotlabs/Module/Oauth2.php:115 +msgid "Add OAuth2 application" msgstr "" -#: ../../addon/sendzid/Mod_Sendzid.php:14 -msgid "Send your identity to all websites" +#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:149 +msgid "Grant Types" msgstr "" -#: ../../addon/sendzid/Mod_Sendzid.php:20 -msgid "Sendzid App" +#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:122 +msgid "leave blank unless your application sepcifically requires this" msgstr "" -#: ../../addon/sendzid/Mod_Sendzid.php:32 -msgid "Send ZID" +#: ../../Zotlabs/Module/Oauth2.php:122 ../../Zotlabs/Module/Oauth2.php:150 +msgid "Authorization scope" msgstr "" -#: ../../addon/cart/widgets/catalogitem.php:57 -#: ../../addon/cart/submodules/hzservices.php:658 -#: ../../addon/cart/submodules/manualcat.php:263 -msgid "Price" +#: ../../Zotlabs/Module/Oauth2.php:134 +msgid "OAuth2 Application not found." msgstr "" -#: ../../addon/cart/manual_payments.php:7 -msgid "Error: order mismatch. Please try again." +#: ../../Zotlabs/Module/Oauth2.php:149 ../../Zotlabs/Module/Oauth2.php:150 +msgid "leave blank unless your application specifically requires this" msgstr "" -#: ../../addon/cart/manual_payments.php:61 -msgid "Manual payments are not enabled." +#: ../../Zotlabs/Module/Oauth2.php:192 +msgid "Connected OAuth2 Apps" msgstr "" -#: ../../addon/cart/manual_payments.php:68 -#: ../../addon/cart/submodules/paypalbutton.php:392 -#: ../../addon/cart/submodules/paypalbuttonV2.php:409 -#: ../../addon/cart/cart.php:1578 -msgid "Order not found." +#: ../../Zotlabs/Module/Wiki.php:35 +#: ../../extend/addon/hzaddons/cart/cart.php:1410 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:51 +msgid "Profile Unavailable." msgstr "" -#: ../../addon/cart/manual_payments.php:77 -msgid "Finished" +#: ../../Zotlabs/Module/Wiki.php:52 +msgid "Wiki App" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:53 +msgid "Provide a wiki for your channel" msgstr "" -#: ../../addon/cart/manual_payments.php:93 -#: ../../addon/cart/submodules/paypalbutton.php:456 -#: ../../addon/cart/submodules/paypalbuttonV2.php:478 -#: ../../addon/cart/myshop.php:37 ../../addon/cart/cart.php:1556 #: ../../Zotlabs/Module/Wiki.php:77 +#: ../../extend/addon/hzaddons/cart/cart.php:1556 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:478 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:456 +#: ../../extend/addon/hzaddons/cart/myshop.php:37 +#: ../../extend/addon/hzaddons/cart/manual_payments.php:93 msgid "Invalid channel" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:151 -msgid "Enable Subscription Management Module" +#: ../../Zotlabs/Module/Wiki.php:133 +msgid "Error retrieving wiki" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:223 -msgid "" -"Cannot include subscription items with different terms in the same order." +#: ../../Zotlabs/Module/Wiki.php:140 +msgid "Error creating zip file export folder" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:372 -msgid "Select Subscription to Edit" +#: ../../Zotlabs/Module/Wiki.php:191 +msgid "Error downloading wiki: " msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:380 -msgid "Edit Subscriptions" +#: ../../Zotlabs/Module/Wiki.php:206 ../../Zotlabs/Widget/Wiki_list.php:15 +#: ../../include/nav.php:536 +msgid "Wikis" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:414 -msgid "Subscription SKU" +#: ../../Zotlabs/Module/Wiki.php:212 ../../Zotlabs/Storage/Browser.php:404 +msgid "Download" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:419 -msgid "Catalog Description" +#: ../../Zotlabs/Module/Wiki.php:216 +msgid "Wiki name" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:423 -msgid "Subscription available for purchase." +#: ../../Zotlabs/Module/Wiki.php:217 +msgid "Content type" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:428 -msgid "Maximum active subscriptions to this item per account." +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2116 +#: ../../extend/addon/hzaddons/mdpost/mdpost.php:41 +msgid "Markdown" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:431 -msgid "Subscription price." +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2114 +msgid "BBcode" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:435 -msgid "Quantity" +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2117 +msgid "Text" msgstr "" -#: ../../addon/cart/submodules/subscriptions.php:439 -msgid "Term" +#: ../../Zotlabs/Module/Wiki.php:219 ../../Zotlabs/Storage/Browser.php:378 +msgid "Type" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:63 -msgid "Enable Hubzilla Services Module" +#: ../../Zotlabs/Module/Wiki.php:220 +msgid "Any type" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:162 -#: ../../addon/cart/submodules/manualcat.php:172 -msgid "New Sku" +#: ../../Zotlabs/Module/Wiki.php:227 +msgid "Lock content type" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:197 -#: ../../addon/cart/submodules/manualcat.php:208 -msgid "Cannot save edits to locked item." +#: ../../Zotlabs/Module/Wiki.php:228 +msgid "Create a status post for this wiki" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:246 -#: ../../addon/cart/submodules/hzservices.php:333 -msgid "SKU not found." +#: ../../Zotlabs/Module/Wiki.php:229 +msgid "Edit Wiki Name" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:299 -#: ../../addon/cart/submodules/hzservices.php:303 -msgid "Invalid Activation Directive." +#: ../../Zotlabs/Module/Wiki.php:274 +msgid "Wiki not found" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:374 -#: ../../addon/cart/submodules/hzservices.php:378 -msgid "Invalid Deactivation Directive." +#: ../../Zotlabs/Module/Wiki.php:300 +msgid "Rename page" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:564 -msgid "Add to this privacy group" +#: ../../Zotlabs/Module/Wiki.php:321 +msgid "Error retrieving page content" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:580 -msgid "Set user service class" +#: ../../Zotlabs/Module/Wiki.php:329 ../../Zotlabs/Module/Wiki.php:331 +msgid "New page" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:607 -msgid "You must be using a local account to purchase this service." +#: ../../Zotlabs/Module/Wiki.php:366 +msgid "Revision Comparison" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:647 -#: ../../addon/cart/submodules/manualcat.php:252 -msgid "Changes Locked" +#: ../../Zotlabs/Module/Wiki.php:367 ../../Zotlabs/Lib/NativeWikiPage.php:567 +#: ../../Zotlabs/Widget/Wiki_page_history.php:25 +msgid "Revert" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:651 -#: ../../addon/cart/submodules/manualcat.php:256 -msgid "Item available for purchase." +#: ../../Zotlabs/Module/Wiki.php:374 +msgid "Short description of your changes (optional)" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:661 -#: ../../addon/cart/submodules/manualcat.php:266 -msgid "Photo URL" +#: ../../Zotlabs/Module/Wiki.php:384 +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:134 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:69 +#: ../../extend/addon/hzaddons/dwpost/dwpost.php:134 +#: ../../extend/addon/hzaddons/wppost/wppost.php:173 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:98 +msgid "Source" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:665 -msgid "Add buyer to privacy group" +#: ../../Zotlabs/Module/Wiki.php:394 +msgid "New page name" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:670 -msgid "Add buyer as connection" +#: ../../Zotlabs/Module/Wiki.php:399 +msgid "Embed image from photo albums" msgstr "" -#: ../../addon/cart/submodules/hzservices.php:678 -#: ../../addon/cart/submodules/hzservices.php:720 -msgid "Set Service Class" +#: ../../Zotlabs/Module/Wiki.php:400 ../../include/conversation.php:1457 +#: ../../extend/addon/hzaddons/hsse/hsse.php:208 +msgid "Embed an image from your albums" msgstr "" -#: ../../addon/cart/submodules/orderoptions.php:70 -msgid "Enable Order/Item Options" +#: ../../Zotlabs/Module/Wiki.php:402 ../../Zotlabs/Module/Profile_photo.php:508 +#: ../../Zotlabs/Module/Cover_photo.php:429 ../../include/conversation.php:1459 +#: ../../include/conversation.php:1510 +#: ../../extend/addon/hzaddons/hsse/hsse.php:210 +#: ../../extend/addon/hzaddons/hsse/hsse.php:257 +msgid "OK" msgstr "" -#: ../../addon/cart/submodules/orderoptions.php:333 -#: ../../addon/cart/submodules/orderoptions.php:357 -#: ../../addon/cart/submodules/orderoptions.php:433 -#: ../../addon/cart/submodules/orderoptions.php:457 -msgid "Label" +#: ../../Zotlabs/Module/Wiki.php:403 ../../Zotlabs/Module/Profile_photo.php:509 +#: ../../Zotlabs/Module/Cover_photo.php:430 ../../include/conversation.php:1385 +#: ../../extend/addon/hzaddons/hsse/hsse.php:139 +msgid "Choose images to embed" msgstr "" -#: ../../addon/cart/submodules/orderoptions.php:334 -#: ../../addon/cart/submodules/orderoptions.php:358 -#: ../../addon/cart/submodules/orderoptions.php:434 -#: ../../addon/cart/submodules/orderoptions.php:458 -#: ../../include/datetime.php:211 ../../Zotlabs/Module/Events.php:468 -#: ../../Zotlabs/Module/Events.php:473 ../../Zotlabs/Module/Appman.php:143 -#: ../../Zotlabs/Module/Appman.php:144 ../../Zotlabs/Module/Profiles.php:747 -#: ../../Zotlabs/Module/Profiles.php:751 -msgid "Required" +#: ../../Zotlabs/Module/Wiki.php:404 ../../Zotlabs/Module/Profile_photo.php:510 +#: ../../Zotlabs/Module/Cover_photo.php:431 ../../include/conversation.php:1386 +#: ../../extend/addon/hzaddons/hsse/hsse.php:140 +msgid "Choose an album" msgstr "" -#: ../../addon/cart/submodules/orderoptions.php:336 -#: ../../addon/cart/submodules/orderoptions.php:360 -#: ../../addon/cart/submodules/orderoptions.php:436 -#: ../../addon/cart/submodules/orderoptions.php:460 -msgid "Instructions" +#: ../../Zotlabs/Module/Wiki.php:405 ../../Zotlabs/Module/Profile_photo.php:511 +#: ../../Zotlabs/Module/Cover_photo.php:432 +msgid "Choose a different album" msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:85 -msgid "Enable Paypal Button Module" +#: ../../Zotlabs/Module/Wiki.php:406 ../../Zotlabs/Module/Profile_photo.php:512 +#: ../../Zotlabs/Module/Cover_photo.php:433 ../../include/conversation.php:1388 +#: ../../extend/addon/hzaddons/hsse/hsse.php:142 +msgid "Error getting album list" msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:93 -#: ../../addon/cart/submodules/paypalbuttonV2.php:94 -msgid "Use Production Key" +#: ../../Zotlabs/Module/Wiki.php:407 ../../Zotlabs/Module/Profile_photo.php:513 +#: ../../Zotlabs/Module/Cover_photo.php:434 ../../include/conversation.php:1389 +#: ../../extend/addon/hzaddons/hsse/hsse.php:143 +msgid "Error getting photo link" msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:100 -#: ../../addon/cart/submodules/paypalbuttonV2.php:101 -msgid "Paypal Sandbox Client Key" +#: ../../Zotlabs/Module/Wiki.php:408 ../../Zotlabs/Module/Profile_photo.php:514 +#: ../../Zotlabs/Module/Cover_photo.php:435 ../../include/conversation.php:1390 +#: ../../extend/addon/hzaddons/hsse/hsse.php:144 +msgid "Error getting album" msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:107 -#: ../../addon/cart/submodules/paypalbuttonV2.php:108 -msgid "Paypal Sandbox Secret Key" +#: ../../Zotlabs/Module/Wiki.php:410 +msgid "History" msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:113 -#: ../../addon/cart/submodules/paypalbuttonV2.php:114 -msgid "Paypal Production Client Key" +#: ../../Zotlabs/Module/Wiki.php:488 +msgid "Error creating wiki. Invalid name." msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:120 -#: ../../addon/cart/submodules/paypalbuttonV2.php:121 -msgid "Paypal Production Secret Key" +#: ../../Zotlabs/Module/Wiki.php:495 +msgid "A wiki with this name already exists." msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:252 -#: ../../addon/cart/submodules/paypalbuttonV2.php:264 -msgid "Paypal button payments are not enabled." +#: ../../Zotlabs/Module/Wiki.php:508 +msgid "Wiki created, but error creating Home page." msgstr "" -#: ../../addon/cart/submodules/paypalbutton.php:270 -#: ../../addon/cart/submodules/paypalbuttonV2.php:282 -msgid "" -"Paypal button payments are not properly configured. Please choose another " -"payment option." -msgstr "" - -#: ../../addon/cart/submodules/paypalbuttonV2.php:86 -msgid "Enable Paypal Button Module (API-v2)" +#: ../../Zotlabs/Module/Wiki.php:515 +msgid "Error creating wiki" msgstr "" -#: ../../addon/cart/submodules/manualcat.php:61 -msgid "Enable Manual Cart Module" +#: ../../Zotlabs/Module/Wiki.php:539 +msgid "Error updating wiki. Invalid name." msgstr "" -#: ../../addon/cart/myshop.php:30 -msgid "Access Denied." +#: ../../Zotlabs/Module/Wiki.php:559 +msgid "Error updating wiki" msgstr "" -#: ../../addon/cart/myshop.php:112 ../../addon/cart/cart.php:1446 -msgid "Order Not Found" +#: ../../Zotlabs/Module/Wiki.php:574 +msgid "Wiki delete permission denied." msgstr "" -#: ../../addon/cart/myshop.php:189 ../../addon/cart/myshop.php:223 -#: ../../addon/cart/myshop.php:271 ../../addon/cart/myshop.php:329 -msgid "Invalid Item" +#: ../../Zotlabs/Module/Wiki.php:584 +msgid "Error deleting wiki" msgstr "" -#: ../../addon/cart/Settings/Cart.php:58 -msgid "Enable Test Catalog" +#: ../../Zotlabs/Module/Wiki.php:617 +msgid "New page created" msgstr "" -#: ../../addon/cart/Settings/Cart.php:70 -msgid "Enable Manual Payments" +#: ../../Zotlabs/Module/Wiki.php:739 +msgid "Cannot delete Home" msgstr "" -#: ../../addon/cart/Settings/Cart.php:90 -msgid "Base Merchant Currency" +#: ../../Zotlabs/Module/Wiki.php:803 +msgid "Current Revision" msgstr "" -#: ../../addon/cart/Settings/Cart.php:129 ../../addon/cart/cart.php:1375 -msgid "Cart Settings" +#: ../../Zotlabs/Module/Wiki.php:803 +msgid "Selected Revision" msgstr "" -#: ../../addon/cart/cart.php:252 -msgid "DB Cleanup Failure" +#: ../../Zotlabs/Module/Wiki.php:853 +msgid "You must be authenticated." msgstr "" -#: ../../addon/cart/cart.php:674 -msgid "[cart] Item Added" +#: ../../Zotlabs/Module/Blocks.php:97 ../../Zotlabs/Module/Blocks.php:155 +#: ../../Zotlabs/Module/Editblock.php:113 +msgid "Block Name" msgstr "" -#: ../../addon/cart/cart.php:1063 -msgid "Order already checked out." +#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2698 +msgid "Blocks" msgstr "" -#: ../../addon/cart/cart.php:1368 -msgid "Drop database tables when uninstalling." +#: ../../Zotlabs/Module/Blocks.php:156 +msgid "Block Title" msgstr "" -#: ../../addon/cart/cart.php:1387 ../../addon/cart/cart.php:1390 -msgid "Shop" +#: ../../Zotlabs/Module/Dircensor.php:42 +msgid "Entry censored" msgstr "" -#: ../../addon/cart/cart.php:1410 ../../addon/flashcards/Mod_Flashcards.php:51 -#: ../../Zotlabs/Module/Wiki.php:35 -msgid "Profile Unavailable." +#: ../../Zotlabs/Module/Dircensor.php:45 +msgid "Entry uncensored" msgstr "" -#: ../../addon/cart/cart.php:1507 -msgid "Cart utilities for orders and payments" +#: ../../Zotlabs/Module/Locs.php:27 ../../Zotlabs/Module/Locs.php:66 +msgid "Location not found." msgstr "" -#: ../../addon/cart/cart.php:1545 -msgid "You must be logged into the Grid to shop." +#: ../../Zotlabs/Module/Locs.php:75 +msgid "Location lookup failed." msgstr "" -#: ../../addon/cart/cart.php:1592 -msgid "Access denied." +#: ../../Zotlabs/Module/Locs.php:79 +msgid "" +"Please select another location to become primary before removing the primary " +"location." msgstr "" -#: ../../addon/cart/cart.php:1644 ../../addon/cart/cart.php:1787 -msgid "No Order Found" +#: ../../Zotlabs/Module/Locs.php:108 +msgid "Syncing locations" msgstr "" -#: ../../addon/cart/cart.php:1653 -msgid "An unknown error has occurred Please start again." +#: ../../Zotlabs/Module/Locs.php:117 +msgid "No locations found." msgstr "" -#: ../../addon/cart/cart.php:1796 -msgid "Requirements not met." +#: ../../Zotlabs/Module/Locs.php:127 +msgid "Manage Channel Locations" msgstr "" -#: ../../addon/cart/cart.php:1796 -msgid "Review your order and complete any needed requirements." +#: ../../Zotlabs/Module/Locs.php:130 +#: ../../extend/addon/hzaddons/workflow/workflow.php:285 +msgid "Primary" msgstr "" -#: ../../addon/cart/cart.php:1822 -msgid "Invalid Payment Type. Please start again." +#: ../../Zotlabs/Module/Locs.php:131 ../../Zotlabs/Module/Menu.php:177 +msgid "Drop" msgstr "" -#: ../../addon/cart/cart.php:1829 -msgid "Order not found" +#: ../../Zotlabs/Module/Locs.php:133 +msgid "Sync Now" msgstr "" -#: ../../addon/nofed/Mod_Nofed.php:21 -msgid "nofed Settings saved." +#: ../../Zotlabs/Module/Locs.php:134 +msgid "Please wait several minutes between consecutive operations." msgstr "" -#: ../../addon/nofed/Mod_Nofed.php:33 -msgid "No Federation App" +#: ../../Zotlabs/Module/Locs.php:135 +msgid "" +"When possible, drop a location by logging into that website/hub and removing " +"your channel." msgstr "" -#: ../../addon/nofed/Mod_Nofed.php:34 -msgid "" -"Prevent posting from being federated to anybody. It will exist only on your " -"channel page." +#: ../../Zotlabs/Module/Locs.php:136 +msgid "Use this form to drop the location if the hub is no longer operating." msgstr "" -#: ../../addon/nofed/Mod_Nofed.php:42 -msgid "Federate posts by default" +#: ../../Zotlabs/Module/Chatsvc.php:131 +msgid "Away" msgstr "" -#: ../../addon/nofed/Mod_Nofed.php:50 -msgid "No Federation" +#: ../../Zotlabs/Module/Chatsvc.php:136 +msgid "Online" msgstr "" -#: ../../addon/nofed/nofed.php:47 -msgid "Federate" +#: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:345 +#: ../../include/features.php:369 ../../include/nav.php:444 +msgid "Photos" msgstr "" -#: ../../addon/smileybutton/Mod_Smileybutton.php:35 -msgid "Smileybutton App" +#: ../../Zotlabs/Module/Fbrowser.php:85 ../../Zotlabs/Storage/Browser.php:351 +#: ../../Zotlabs/Lib/Apps.php:340 ../../include/nav.php:452 +msgid "Files" msgstr "" -#: ../../addon/smileybutton/Mod_Smileybutton.php:36 -msgid "Adds a smileybutton to the jot editor" +#: ../../Zotlabs/Module/Connedit.php:120 +msgid "Could not locate selected profile." msgstr "" -#: ../../addon/smileybutton/Mod_Smileybutton.php:44 -msgid "Hide the button and show the smilies directly." +#: ../../Zotlabs/Module/Connedit.php:264 +msgid "Connection updated." msgstr "" -#: ../../addon/smileybutton/Mod_Smileybutton.php:52 -msgid "Smileybutton Settings" +#: ../../Zotlabs/Module/Connedit.php:266 +msgid "Failed to update connection record." msgstr "" -#: ../../addon/redfiles/redfilehelper.php:64 ../../include/attach.php:2099 -msgid "file" +#: ../../Zotlabs/Module/Connedit.php:309 +msgid "is now connected to" msgstr "" -#: ../../addon/redfiles/redfiles.php:119 -msgid "Redmatrix File Storage Import" +#: ../../Zotlabs/Module/Connedit.php:434 +msgid "Could not access address book record." msgstr "" -#: ../../addon/redfiles/redfiles.php:120 -msgid "This will import all your Redmatrix cloud files to this channel." +#: ../../Zotlabs/Module/Connedit.php:482 ../../Zotlabs/Module/Connedit.php:486 +msgid "Refresh failed - channel is currently unavailable." msgstr "" -#: ../../addon/diaspora/diaspora.php:66 -msgid "" -"Please install the statistics addon to be able to configure a diaspora relay" +#: ../../Zotlabs/Module/Connedit.php:501 ../../Zotlabs/Module/Connedit.php:510 +#: ../../Zotlabs/Module/Connedit.php:519 ../../Zotlabs/Module/Connedit.php:528 +#: ../../Zotlabs/Module/Connedit.php:541 +msgid "Unable to set address book parameters." msgstr "" -#: ../../addon/diaspora/diaspora.php:76 -msgid "Diaspora Relay Handle" +#: ../../Zotlabs/Module/Connedit.php:560 +msgid "Connection has been removed." msgstr "" -#: ../../addon/diaspora/diaspora.php:76 -msgid "Address of a diaspora relay. Example: relay@diasporarelay.tld" +#: ../../Zotlabs/Module/Connedit.php:600 ../../Zotlabs/Lib/Apps.php:344 +#: ../../include/conversation.php:1080 ../../include/nav.php:112 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:57 +msgid "View Profile" msgstr "" -#: ../../addon/diaspora/diaspora.php:96 -msgid "Diaspora relay could not be imported" +#: ../../Zotlabs/Module/Connedit.php:603 +#, php-format +msgid "View %s's profile" msgstr "" -#: ../../addon/diaspora/p.php:48 ../../addon/diaspora/util.php:336 -#: ../../addon/diaspora/util.php:349 ../../Zotlabs/Lib/Enotify.php:61 -msgid "$projectname" +#: ../../Zotlabs/Module/Connedit.php:607 +msgid "Refresh Permissions" msgstr "" -#: ../../addon/diaspora/import_diaspora.php:19 -msgid "No username found in import file." +#: ../../Zotlabs/Module/Connedit.php:610 +msgid "Fetch updated permissions" msgstr "" -#: ../../addon/diaspora/import_diaspora.php:44 ../../include/import.php:76 -msgid "Unable to create a unique channel address. Import failed." +#: ../../Zotlabs/Module/Connedit.php:614 +msgid "Refresh Photo" msgstr "" -#: ../../addon/diaspora/import_diaspora.php:142 -#: ../../Zotlabs/Module/Import.php:593 -msgid "Import completed." +#: ../../Zotlabs/Module/Connedit.php:617 +msgid "Fetch updated photo" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:43 -msgid "Diaspora Protocol Settings updated." +#: ../../Zotlabs/Module/Connedit.php:621 ../../include/conversation.php:1090 +msgid "Recent Activity" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:52 -msgid "" -"The diaspora protocol does not support location independence. Connections " -"you make within that network may be unreachable from alternate channel " -"locations." +#: ../../Zotlabs/Module/Connedit.php:624 +msgid "View recent posts and comments" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:58 -msgid "Diaspora Protocol App" +#: ../../Zotlabs/Module/Connedit.php:628 +#: ../../Zotlabs/Module/Admin/Accounts.php:177 +msgid "Unblock" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:75 -msgid "Allow any Diaspora member to comment on your public posts" +#: ../../Zotlabs/Module/Connedit.php:628 +#: ../../Zotlabs/Module/Admin/Accounts.php:176 +msgid "Block" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:79 -msgid "Prevent your hashtags from being redirected to other sites" +#: ../../Zotlabs/Module/Connedit.php:631 +msgid "Block (or Unblock) all communications with this connection" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:83 -msgid "Sign and forward posts and comments with no existing Diaspora signature" +#: ../../Zotlabs/Module/Connedit.php:632 +msgid "This connection is blocked!" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:88 -msgid "Followed hashtags (comma separated, do not include the #)" +#: ../../Zotlabs/Module/Connedit.php:636 +msgid "Unignore" msgstr "" -#: ../../addon/diaspora/Mod_Diaspora.php:97 -msgid "Diaspora Protocol" +#: ../../Zotlabs/Module/Connedit.php:636 +#: ../../Zotlabs/Module/Connections.php:344 +msgid "Ignore" msgstr "" -#: ../../addon/diaspora/Receiver.php:1541 -#, php-format -msgid "%1$s dislikes %2$s's %3$s" +#: ../../Zotlabs/Module/Connedit.php:639 +msgid "Ignore (or Unignore) all inbound communications from this connection" msgstr "" -#: ../../addon/diaspora/Receiver.php:2184 ../../Zotlabs/Module/Like.php:479 -#, php-format -msgid "%1$s is attending %2$s's %3$s" +#: ../../Zotlabs/Module/Connedit.php:640 +msgid "This connection is ignored!" msgstr "" -#: ../../addon/diaspora/Receiver.php:2186 ../../Zotlabs/Module/Like.php:481 -#, php-format -msgid "%1$s is not attending %2$s's %3$s" +#: ../../Zotlabs/Module/Connedit.php:644 +msgid "Unarchive" msgstr "" -#: ../../addon/diaspora/Receiver.php:2188 ../../Zotlabs/Module/Like.php:483 -#, php-format -msgid "%1$s may attend %2$s's %3$s" +#: ../../Zotlabs/Module/Connedit.php:644 +msgid "Archive" msgstr "" -#: ../../addon/piwik/piwik.php:85 +#: ../../Zotlabs/Module/Connedit.php:647 msgid "" -"This website is tracked using the Piwik " -"analytics tool." +"Archive (or Unarchive) this connection - mark channel dead but keep content" msgstr "" -#: ../../addon/piwik/piwik.php:88 -#, php-format -msgid "" -"If you do not want that your visits are logged this way you can " -"set a cookie to prevent Piwik from tracking further visits of the site " -"(opt-out)." +#: ../../Zotlabs/Module/Connedit.php:648 +msgid "This connection is archived!" msgstr "" -#: ../../addon/piwik/piwik.php:96 -msgid "Piwik Base URL" +#: ../../Zotlabs/Module/Connedit.php:652 +msgid "Unhide" msgstr "" -#: ../../addon/piwik/piwik.php:96 -msgid "" -"Absolute path to your Piwik installation. (without protocol (http/s), with " -"trailing slash)" +#: ../../Zotlabs/Module/Connedit.php:652 +msgid "Hide" msgstr "" -#: ../../addon/piwik/piwik.php:97 -msgid "Site ID" +#: ../../Zotlabs/Module/Connedit.php:655 +msgid "Hide or Unhide this connection from your other connections" msgstr "" -#: ../../addon/piwik/piwik.php:98 -msgid "Show opt-out cookie link?" +#: ../../Zotlabs/Module/Connedit.php:656 +msgid "This connection is hidden!" msgstr "" -#: ../../addon/piwik/piwik.php:99 -msgid "Asynchronous tracking" +#: ../../Zotlabs/Module/Connedit.php:663 +msgid "Delete this connection" msgstr "" -#: ../../addon/piwik/piwik.php:100 -msgid "Enable frontend JavaScript error tracking" +#: ../../Zotlabs/Module/Connedit.php:671 +msgid "Fetch Vcard" msgstr "" -#: ../../addon/piwik/piwik.php:100 -msgid "This feature requires Piwik >= 2.2.0" +#: ../../Zotlabs/Module/Connedit.php:674 +msgid "Fetch electronic calling card for this connection" msgstr "" -#: ../../addon/workflow/workflow.php:222 -msgid "Workflow user." +#: ../../Zotlabs/Module/Connedit.php:685 +msgid "Open Individual Permissions section by default" msgstr "" -#: ../../addon/workflow/workflow.php:272 -msgid "This channel" +#: ../../Zotlabs/Module/Connedit.php:708 +msgid "Affinity" msgstr "" -#: ../../addon/workflow/workflow.php:285 ../../Zotlabs/Module/Locs.php:130 -msgid "Primary" +#: ../../Zotlabs/Module/Connedit.php:711 +msgid "Open Set Affinity section by default" msgstr "" -#: ../../addon/workflow/workflow.php:541 ../../addon/workflow/workflow.php:1437 -#: ../../addon/workflow/workflow.php:1456 -msgid "Workflow" +#: ../../Zotlabs/Module/Connedit.php:715 ../../Zotlabs/Widget/Affinity.php:30 +msgid "Me" msgstr "" -#: ../../addon/workflow/workflow.php:1425 -msgid "No Workflows Available" +#: ../../Zotlabs/Module/Connedit.php:716 ../../Zotlabs/Widget/Affinity.php:31 +msgid "Family" msgstr "" -#: ../../addon/workflow/workflow.php:1455 -msgid "Add item to which workflow" +#: ../../Zotlabs/Module/Connedit.php:717 +#: ../../Zotlabs/Module/Settings/Channel.php:71 +#: ../../Zotlabs/Module/Settings/Channel.php:75 +#: ../../Zotlabs/Module/Settings/Channel.php:76 +#: ../../Zotlabs/Module/Settings/Channel.php:79 +#: ../../Zotlabs/Module/Settings/Channel.php:90 +#: ../../Zotlabs/Widget/Affinity.php:32 ../../include/channel.php:505 +#: ../../include/channel.php:506 ../../include/channel.php:513 +#: ../../include/selectors.php:134 +msgid "Friends" msgstr "" -#: ../../addon/workflow/workflow.php:1515 -#: ../../addon/workflow/workflow.php:1634 -msgid "Create Workflow Item" +#: ../../Zotlabs/Module/Connedit.php:718 ../../Zotlabs/Widget/Affinity.php:33 +msgid "Acquaintances" msgstr "" -#: ../../addon/workflow/workflow.php:2596 -msgid "Link" +#: ../../Zotlabs/Module/Connedit.php:719 +#: ../../Zotlabs/Module/Connections.php:97 +#: ../../Zotlabs/Module/Connections.php:111 +#: ../../Zotlabs/Widget/Affinity.php:34 +msgid "All" msgstr "" -#: ../../addon/workflow/workflow.php:2598 -msgid "Web link." +#: ../../Zotlabs/Module/Connedit.php:748 +msgid "Filter" msgstr "" -#: ../../addon/workflow/workflow.php:2617 -#: ../../addon/workflow/workflow.php:2678 ../../Zotlabs/Module/Cdav.php:1374 -#: ../../Zotlabs/Module/Connedit.php:917 -msgid "Title" +#: ../../Zotlabs/Module/Connedit.php:751 +msgid "Open Custom Filter section by default" msgstr "" -#: ../../addon/workflow/workflow.php:2619 -#: ../../addon/workflow/workflow.php:2680 -msgid "Brief description or title" +#: ../../Zotlabs/Module/Connedit.php:788 +msgid "Approve this connection" msgstr "" -#: ../../addon/workflow/workflow.php:2625 ../../Zotlabs/Widget/Notes.php:21 -#: ../../Zotlabs/Lib/Apps.php:370 -msgid "Notes" +#: ../../Zotlabs/Module/Connedit.php:788 +msgid "Accept connection to allow communication" msgstr "" -#: ../../addon/workflow/workflow.php:2627 -#: ../../addon/workflow/workflow.php:2688 -msgid "Notes and Info" +#: ../../Zotlabs/Module/Connedit.php:793 +msgid "Set Affinity" msgstr "" -#: ../../addon/workflow/workflow.php:2686 -msgid "Body" +#: ../../Zotlabs/Module/Connedit.php:796 +msgid "Set Profile" msgstr "" -#: ../../addon/workflow/Settings/Mod_WorkflowSettings.php:101 -msgid "Workflow Settings" +#: ../../Zotlabs/Module/Connedit.php:799 +msgid "Set Affinity & Profile" msgstr "" -#: ../../addon/donate/donate.php:21 -msgid "Project Servers and Resources" +#: ../../Zotlabs/Module/Connedit.php:847 +msgid "This connection is unreachable from this location." msgstr "" -#: ../../addon/donate/donate.php:22 -msgid "Project Creator and Tech Lead" +#: ../../Zotlabs/Module/Connedit.php:848 +msgid "This connection may be unreachable from other channel locations." msgstr "" -#: ../../addon/donate/donate.php:49 -msgid "" -"And the hundreds of other people and organisations who helped make the " -"Hubzilla possible." +#: ../../Zotlabs/Module/Connedit.php:850 +msgid "Location independence is not supported by their network." msgstr "" -#: ../../addon/donate/donate.php:52 +#: ../../Zotlabs/Module/Connedit.php:856 msgid "" -"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving " -"their time and expertise - and often paying out of pocket for services they " -"share with others." +"This connection is unreachable from this location. Location independence is " +"not supported by their network." msgstr "" -#: ../../addon/donate/donate.php:53 -msgid "" -"There is no corporate funding and no ads, and we do not collect and sell " -"your personal information. (We don't control your personal information - " -"you do.)" +#: ../../Zotlabs/Module/Connedit.php:859 ../../include/items.php:4524 +#, php-format +msgid "Connection: %s" msgstr "" -#: ../../addon/donate/donate.php:54 -msgid "" -"Help support our ground-breaking work in decentralisation, web identity, and " -"privacy." +#: ../../Zotlabs/Module/Connedit.php:860 +msgid "Connection requests will be approved without your interaction" msgstr "" -#: ../../addon/donate/donate.php:56 -msgid "" -"Your donations keep servers and services running and also helps us to " -"provide innovative new features and continued development." +#: ../../Zotlabs/Module/Connedit.php:869 +msgid "This connection's primary address is" msgstr "" -#: ../../addon/donate/donate.php:59 -msgid "Donate" +#: ../../Zotlabs/Module/Connedit.php:870 +msgid "Available locations:" msgstr "" -#: ../../addon/donate/donate.php:61 -msgid "" -"Choose a project, developer, or public hub to support with a one-time " -"donation" +#: ../../Zotlabs/Module/Connedit.php:876 +msgid "Connection Tools" msgstr "" -#: ../../addon/donate/donate.php:62 -msgid "Donate Now" +#: ../../Zotlabs/Module/Connedit.php:878 +msgid "Slide to adjust your degree of friendship" msgstr "" -#: ../../addon/donate/donate.php:63 -msgid "" -"Or become a project sponsor (Hubzilla Project only)" +#: ../../Zotlabs/Module/Connedit.php:879 ../../Zotlabs/Module/Rate.php:155 +#: ../../include/js_strings.php:20 +msgid "Rating" msgstr "" -#: ../../addon/donate/donate.php:64 -msgid "" -"Please indicate if you would like your first name or full name (or nothing) " -"to appear in our sponsor listing" +#: ../../Zotlabs/Module/Connedit.php:880 +msgid "Slide to adjust your rating" msgstr "" -#: ../../addon/donate/donate.php:65 -msgid "Sponsor" +#: ../../Zotlabs/Module/Connedit.php:881 ../../Zotlabs/Module/Connedit.php:886 +msgid "Optionally explain your rating" msgstr "" -#: ../../addon/donate/donate.php:68 -msgid "Special thanks to: " +#: ../../Zotlabs/Module/Connedit.php:883 +msgid "Custom Filter" msgstr "" -#: ../../addon/likebanner/likebanner.php:51 -msgid "Your Webbie:" +#: ../../Zotlabs/Module/Connedit.php:884 +msgid "Only import posts with this text" msgstr "" -#: ../../addon/likebanner/likebanner.php:54 -msgid "Fontsize (px):" +#: ../../Zotlabs/Module/Connedit.php:884 ../../Zotlabs/Module/Connedit.php:885 +#: ../../Zotlabs/Module/Admin/Site.php:327 +#: ../../Zotlabs/Module/Admin/Site.php:328 +msgid "" +"words one per line or #tags or /patterns/ or lang=xx, leave blank to import " +"all posts" msgstr "" -#: ../../addon/likebanner/likebanner.php:68 -msgid "Link:" +#: ../../Zotlabs/Module/Connedit.php:885 +msgid "Do not import posts with this text" msgstr "" -#: ../../addon/likebanner/likebanner.php:70 -msgid "Like us on Hubzilla" +#: ../../Zotlabs/Module/Connedit.php:887 +msgid "This information is public!" msgstr "" -#: ../../addon/likebanner/likebanner.php:72 -msgid "Embed:" +#: ../../Zotlabs/Module/Connedit.php:892 +msgid "Connection Pending Approval" msgstr "" -#: ../../addon/opensearch/opensearch.php:26 +#: ../../Zotlabs/Module/Connedit.php:897 #, php-format -msgctxt "opensearch" -msgid "Search %1$s (%2$s)" +msgid "" +"Please choose the profile you would like to display to %s when viewing your " +"profile securely." msgstr "" -#: ../../addon/opensearch/opensearch.php:28 -msgctxt "opensearch" -msgid "$Projectname" +#: ../../Zotlabs/Module/Connedit.php:899 ../../Zotlabs/Module/Tokens.php:180 +msgid "Their Settings" msgstr "" -#: ../../addon/opensearch/opensearch.php:42 ../../Zotlabs/Module/Home.php:72 -#: ../../Zotlabs/Module/Home.php:80 ../../Zotlabs/Lib/Enotify.php:66 -msgid "$Projectname" +#: ../../Zotlabs/Module/Connedit.php:903 ../../Zotlabs/Module/Tokens.php:187 +#: ../../Zotlabs/Module/Permcats.php:128 +msgid "" +"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " +"individual settings. You can not change those settings here." msgstr "" -#: ../../addon/opensearch/opensearch.php:43 -msgid "Search $Projectname" +#: ../../Zotlabs/Module/Connedit.php:904 +msgid "" +"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " +"individual settings. You can change those settings here but they wont have " +"any impact unless the inherited setting changes." msgstr "" -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:22 -msgid "Fuzzloc Settings updated." +#: ../../Zotlabs/Module/Connedit.php:905 +msgid "Last update:" msgstr "" -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:34 -msgid "Fuzzy Location App" +#: ../../Zotlabs/Module/Connedit.php:913 +msgid "Details" msgstr "" -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:35 -msgid "" -"Blur your precise location if your channel uses browser location mapping" +#: ../../Zotlabs/Module/Profile_photo.php:93 +#: ../../Zotlabs/Module/Cover_photo.php:85 +msgid "Image uploaded but image cropping failed." msgstr "" -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:40 -msgid "Minimum offset in meters" +#: ../../Zotlabs/Module/Profile_photo.php:147 +#: ../../Zotlabs/Module/Profile_photo.php:284 +#: ../../include/photo/photo_driver.php:417 +msgid "Profile Photos" msgstr "" -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:44 -msgid "Maximum offset in meters" +#: ../../Zotlabs/Module/Profile_photo.php:166 +#: ../../Zotlabs/Module/Cover_photo.php:212 +msgid "Image resize failed." msgstr "" -#: ../../addon/fuzzloc/Mod_Fuzzloc.php:53 -msgid "Fuzzy Location" +#: ../../Zotlabs/Module/Profile_photo.php:254 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:298 +msgid "" +"Shift-reload the page or clear browser cache if the new photo does not " +"display immediately." msgstr "" -#: ../../addon/hubwall/hubwall.php:19 -msgid "Send email to all members" +#: ../../Zotlabs/Module/Profile_photo.php:261 +#: ../../Zotlabs/Module/Cover_photo.php:241 ../../include/photos.php:196 +msgid "Unable to process image" msgstr "" -#: ../../addon/hubwall/hubwall.php:33 ../../Zotlabs/Lib/Enotify.php:65 -#, php-format -msgid "%s Administrator" +#: ../../Zotlabs/Module/Profile_photo.php:296 +#: ../../Zotlabs/Module/Cover_photo.php:265 +msgid "Image upload failed." msgstr "" -#: ../../addon/hubwall/hubwall.php:50 ../../addon/mailtest/mailtest.php:50 -msgid "No recipients found." +#: ../../Zotlabs/Module/Profile_photo.php:315 +#: ../../Zotlabs/Module/Cover_photo.php:282 +msgid "Unable to process image." msgstr "" -#: ../../addon/hubwall/hubwall.php:73 -#, php-format -msgid "%1$d of %2$d messages sent." +#: ../../Zotlabs/Module/Profile_photo.php:379 +#: ../../Zotlabs/Module/Profile_photo.php:431 +#: ../../Zotlabs/Module/Cover_photo.php:367 +#: ../../Zotlabs/Module/Cover_photo.php:382 +msgid "Photo not available." msgstr "" -#: ../../addon/hubwall/hubwall.php:81 -msgid "Send email to all hub members." +#: ../../Zotlabs/Module/Profile_photo.php:495 +msgid "" +"Your default profile photo is visible to anybody on the internet. Profile " +"photos for alternate profiles will inherit the permissions of the profile" msgstr "" -#: ../../addon/hubwall/hubwall.php:92 ../../addon/mailtest/mailtest.php:96 -msgid "Message subject" +#: ../../Zotlabs/Module/Profile_photo.php:495 +msgid "" +"Your profile photo is visible to anybody on the internet and may be " +"distributed to other websites." msgstr "" -#: ../../addon/hubwall/hubwall.php:93 -msgid "Sender Email address" +#: ../../Zotlabs/Module/Profile_photo.php:497 +#: ../../Zotlabs/Module/Cover_photo.php:420 +msgid "Upload File:" msgstr "" -#: ../../addon/hubwall/hubwall.php:94 -msgid "Test mode (only send to hub administrator)" +#: ../../Zotlabs/Module/Profile_photo.php:498 +#: ../../Zotlabs/Module/Cover_photo.php:421 +msgid "Select a profile:" msgstr "" -#: ../../addon/notifyadmin/notifyadmin.php:34 -msgid "New registration" +#: ../../Zotlabs/Module/Profile_photo.php:499 +msgid "Use Photo for Profile" msgstr "" -#: ../../addon/notifyadmin/notifyadmin.php:40 -#: ../../Zotlabs/Module/Invite.php:90 -#, php-format -msgid "%s : Message delivery failed." +#: ../../Zotlabs/Module/Profile_photo.php:499 +msgid "Change Profile Photo" msgstr "" -#: ../../addon/notifyadmin/notifyadmin.php:42 -#, php-format -msgid "Message sent to %s. New account registration: %s" +#: ../../Zotlabs/Module/Profile_photo.php:500 +msgid "Use" msgstr "" -#: ../../addon/flashcards/Mod_Flashcards.php:218 -msgid "Not allowed." +#: ../../Zotlabs/Module/Profile_photo.php:500 +#: ../../Zotlabs/Module/Photos.php:688 ../../Zotlabs/Module/Cover_photo.php:423 +#: ../../Zotlabs/Module/Embedphotos.php:188 +#: ../../Zotlabs/Storage/Browser.php:540 ../../Zotlabs/Widget/Cdav.php:146 +#: ../../Zotlabs/Widget/Cdav.php:182 ../../Zotlabs/Widget/Portfolio.php:110 +#: ../../Zotlabs/Widget/Album.php:97 +msgid "Upload" msgstr "" -#: ../../addon/flashcards/Mod_Flashcards.php:254 -#: ../../include/acl_selectors.php:153 ../../Zotlabs/Module/Chat.php:241 -#: ../../Zotlabs/Module/Filestorage.php:195 ../../Zotlabs/Module/Photos.php:678 -#: ../../Zotlabs/Module/Photos.php:1047 ../../Zotlabs/Module/Thing.php:321 -#: ../../Zotlabs/Module/Thing.php:374 ../../Zotlabs/Module/Connedit.php:682 -msgid "Permissions" +#: ../../Zotlabs/Module/Profile_photo.php:501 +#: ../../Zotlabs/Module/Photos.php:996 ../../Zotlabs/Module/Tagrm.php:137 +#: ../../Zotlabs/Module/Admin/Addons.php:459 +#: ../../Zotlabs/Module/Cover_photo.php:424 +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:91 +msgid "Remove" msgstr "" -#: ../../addon/flashcards/Mod_Flashcards.php:261 -#: ../../Zotlabs/Module/Filestorage.php:202 -msgid "Set/edit permissions" +#: ../../Zotlabs/Module/Profile_photo.php:505 +#: ../../Zotlabs/Module/Profile_photo.php:506 +#: ../../Zotlabs/Module/Cover_photo.php:426 +#: ../../Zotlabs/Module/Cover_photo.php:427 +msgid "Use a photo from your albums" msgstr "" -#: ../../addon/flashcards/Mod_Flashcards.php:284 -#: ../../addon/flashcards/Mod_Flashcards.php:285 ../../include/items.php:3902 -#: ../../Zotlabs/Module/Filestorage.php:29 -#: ../../Zotlabs/Module/Admin/Themes.php:72 -#: ../../Zotlabs/Module/Admin/Addons.php:260 -#: ../../Zotlabs/Module/Viewsrc.php:25 ../../Zotlabs/Module/Display.php:42 -#: ../../Zotlabs/Module/Display.php:429 ../../Zotlabs/Module/Admin.php:62 -#: ../../Zotlabs/Module/Thing.php:96 -msgid "Item not found." +#: ../../Zotlabs/Module/Profile_photo.php:516 +#: ../../Zotlabs/Module/Cover_photo.php:438 +msgid "Select existing photo" msgstr "" -#: ../../addon/libertree/libertree.php:43 -msgid "Post to Libertree" +#: ../../Zotlabs/Module/Profile_photo.php:535 +#: ../../Zotlabs/Module/Cover_photo.php:455 +msgid "Crop Image" msgstr "" -#: ../../addon/libertree/Mod_Libertree.php:25 -msgid "Libertree Crosspost Connector Settings saved." +#: ../../Zotlabs/Module/Profile_photo.php:536 +#: ../../Zotlabs/Module/Cover_photo.php:456 +msgid "Please adjust the image cropping for optimum viewing." msgstr "" -#: ../../addon/libertree/Mod_Libertree.php:35 -msgid "Libertree Crosspost Connector App" +#: ../../Zotlabs/Module/Profile_photo.php:538 +#: ../../Zotlabs/Module/Cover_photo.php:458 +msgid "Done Editing" msgstr "" -#: ../../addon/libertree/Mod_Libertree.php:36 -msgid "Relay public posts to Libertree" +#: ../../Zotlabs/Module/Sharedwithme.php:105 +msgid "Files: shared with me" msgstr "" -#: ../../addon/libertree/Mod_Libertree.php:51 -msgid "Libertree API token" +#: ../../Zotlabs/Module/Sharedwithme.php:107 +msgid "NEW" msgstr "" -#: ../../addon/libertree/Mod_Libertree.php:55 -msgid "Libertree site URL" +#: ../../Zotlabs/Module/Sharedwithme.php:108 +#: ../../Zotlabs/Storage/Browser.php:379 ../../include/text.php:1562 +msgid "Size" msgstr "" -#: ../../addon/libertree/Mod_Libertree.php:59 -msgid "Post to Libertree by default" +#: ../../Zotlabs/Module/Sharedwithme.php:109 +#: ../../Zotlabs/Storage/Browser.php:380 +msgid "Last Modified" msgstr "" -#: ../../addon/libertree/Mod_Libertree.php:67 -msgid "Libertree Crosspost Connector" +#: ../../Zotlabs/Module/Sharedwithme.php:110 +msgid "Remove all files" msgstr "" -#: ../../addon/randpost/randpost.php:97 -msgid "You're welcome." +#: ../../Zotlabs/Module/Sharedwithme.php:111 +msgid "Remove this file" msgstr "" -#: ../../addon/randpost/randpost.php:98 -msgid "Ah shucks..." +#: ../../Zotlabs/Module/Editlayout.php:137 +msgid "Edit Layout" msgstr "" -#: ../../addon/randpost/randpost.php:99 -msgid "Don't mention it." +#: ../../Zotlabs/Module/Manage.php:145 +msgid "Create a new channel" msgstr "" -#: ../../addon/randpost/randpost.php:100 -msgid "<blush>" +#: ../../Zotlabs/Module/Manage.php:170 ../../Zotlabs/Lib/Apps.php:337 +#: ../../include/nav.php:98 +msgid "Channel Manager" msgstr "" -#: ../../addon/buglink/buglink.php:16 ../../Zotlabs/Lib/Apps.php:328 -msgid "Report Bug" +#: ../../Zotlabs/Module/Manage.php:171 +msgid "Current Channel" msgstr "" -#: ../../addon/totp/Mod_Totp.php:23 -msgid "TOTP Two-Step Verification" -msgstr "" - -#: ../../addon/totp/Mod_Totp.php:24 -msgid "Enter the 2-step verification generated by your authenticator app:" +#: ../../Zotlabs/Module/Manage.php:173 +msgid "Switch to one of your channels by selecting it." msgstr "" -#: ../../addon/totp/Mod_Totp.php:25 -msgid "Success!" +#: ../../Zotlabs/Module/Manage.php:174 +msgid "Default Channel" msgstr "" -#: ../../addon/totp/Mod_Totp.php:26 -msgid "Invalid code, please try again." +#: ../../Zotlabs/Module/Manage.php:175 +msgid "Make Default" msgstr "" -#: ../../addon/totp/Mod_Totp.php:27 -msgid "Too many invalid codes..." +#: ../../Zotlabs/Module/Manage.php:178 +#, php-format +msgid "%d new messages" msgstr "" -#: ../../addon/totp/Mod_Totp.php:28 -msgid "Verify" +#: ../../Zotlabs/Module/Manage.php:179 +#, php-format +msgid "%d new introductions" msgstr "" -#: ../../addon/totp/Settings/Totp.php:90 -msgid "" -"You haven't set a TOTP secret yet.\n" -"Please click the button below to generate one and register this site\n" -"with your preferred authenticator app." +#: ../../Zotlabs/Module/Manage.php:181 +msgid "Delegated Channel" msgstr "" -#: ../../addon/totp/Settings/Totp.php:93 -msgid "Your TOTP secret is" +#: ../../Zotlabs/Module/Follow.php:93 +msgid "Connection added." msgstr "" -#: ../../addon/totp/Settings/Totp.php:94 -msgid "" -"Be sure to save it somewhere in case you lose or replace your mobile " -"device.\n" -"Use your mobile device to scan the QR code below to register this site\n" -"with your preferred authenticator app." +#: ../../Zotlabs/Module/Item.php:450 ../../Zotlabs/Module/Pin.php:35 +msgid "Unable to locate original post." msgstr "" -#: ../../addon/totp/Settings/Totp.php:99 -msgid "Test" +#: ../../Zotlabs/Module/Item.php:736 +msgid "Empty post discarded." msgstr "" -#: ../../addon/totp/Settings/Totp.php:100 -msgid "Generate New Secret" +#: ../../Zotlabs/Module/Item.php:1187 +msgid "Duplicate post suppressed." msgstr "" -#: ../../addon/totp/Settings/Totp.php:101 -msgid "Go" +#: ../../Zotlabs/Module/Item.php:1332 +msgid "System error. Post not saved." msgstr "" -#: ../../addon/totp/Settings/Totp.php:102 -msgid "Enter your password" +#: ../../Zotlabs/Module/Item.php:1366 +msgid "Your comment is awaiting approval." msgstr "" -#: ../../addon/totp/Settings/Totp.php:103 -msgid "enter TOTP code from your device" +#: ../../Zotlabs/Module/Item.php:1496 +msgid "Unable to obtain post information from database." msgstr "" -#: ../../addon/totp/Settings/Totp.php:104 -msgid "Pass!" +#: ../../Zotlabs/Module/Item.php:1503 +#, php-format +msgid "You have reached your limit of %1$.0f top level posts." msgstr "" -#: ../../addon/totp/Settings/Totp.php:105 -msgid "Fail" +#: ../../Zotlabs/Module/Item.php:1510 +#, php-format +msgid "You have reached your limit of %1$.0f webpages." msgstr "" -#: ../../addon/totp/Settings/Totp.php:106 -msgid "Incorrect password, try again." +#: ../../Zotlabs/Module/Rate.php:156 +msgid "Website:" msgstr "" -#: ../../addon/totp/Settings/Totp.php:107 -msgid "Record your new TOTP secret and rescan the QR code above." +#: ../../Zotlabs/Module/Rate.php:159 +#, php-format +msgid "Remote Channel [%s] (not yet known on this site)" msgstr "" -#: ../../addon/totp/Settings/Totp.php:115 -msgid "TOTP Settings" +#: ../../Zotlabs/Module/Rate.php:160 +msgid "Rating (this information is public)" msgstr "" -#: ../../addon/logrot/logrot.php:36 -msgid "Logfile archive directory" +#: ../../Zotlabs/Module/Rate.php:161 +msgid "Optionally explain your rating (this information is public)" msgstr "" -#: ../../addon/logrot/logrot.php:36 -msgid "Directory to store rotated logs" +#: ../../Zotlabs/Module/Page.php:39 ../../Zotlabs/Module/Block.php:29 +msgid "Invalid item." msgstr "" -#: ../../addon/logrot/logrot.php:37 -msgid "Logfile size in bytes before rotating" +#: ../../Zotlabs/Module/Page.php:136 ../../Zotlabs/Module/Display.php:136 +#: ../../Zotlabs/Module/Display.php:153 ../../Zotlabs/Module/Display.php:173 +#: ../../Zotlabs/Module/Display.php:179 ../../Zotlabs/Module/Block.php:77 +#: ../../Zotlabs/Web/Router.php:185 ../../Zotlabs/Lib/NativeWikiPage.php:521 +#: ../../include/help.php:132 +msgid "Page not found." msgstr "" -#: ../../addon/logrot/logrot.php:38 -msgid "Number of logfiles to retain" +#: ../../Zotlabs/Module/Page.php:173 +msgid "" +"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " +"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, " +"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo " +"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse " +"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " +"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." msgstr "" -#: ../../addon/testdrive/testdrive.php:104 -#, php-format -msgid "Your account on %s will expire in a few days." +#: ../../Zotlabs/Module/Xchan.php:10 +msgid "Xchan Lookup" msgstr "" -#: ../../addon/testdrive/testdrive.php:105 -msgid "Your $Productname test account is about to expire." +#: ../../Zotlabs/Module/Xchan.php:13 +msgid "Lookup xchan beginning with (or webbie): " msgstr "" -#: ../../addon/hideaside/Mod_Hideaside.php:23 -#: ../../addon/hideaside/Mod_Hideaside.php:27 -msgid "Hide Aside App" +#: ../../Zotlabs/Module/Xchan.php:41 ../../Zotlabs/Module/Mitem.php:134 +#: ../../Zotlabs/Module/Menu.php:232 +msgid "Not found." msgstr "" -#: ../../addon/hideaside/Mod_Hideaside.php:24 -#: ../../addon/hideaside/Mod_Hideaside.php:28 -msgid "Fade out aside areas after a while when using endless scroll" +#: ../../Zotlabs/Module/Achievements.php:38 +msgid "Some blurb about what to do when you're new here" msgstr "" -#: ../../addon/skeleton/Mod_Skeleton.php:32 -msgid "Skeleton App" +#: ../../Zotlabs/Module/Subthread.php:143 +#, php-format +msgid "%1$s is following %2$s's %3$s" msgstr "" -#: ../../addon/skeleton/Mod_Skeleton.php:33 -msgid "A skeleton for addons, you can copy/paste" +#: ../../Zotlabs/Module/Subthread.php:145 +#, php-format +msgid "%1$s stopped following %2$s's %3$s" msgstr "" -#: ../../addon/skeleton/Mod_Skeleton.php:40 -msgid "Some setting" +#: ../../Zotlabs/Module/Regmod.php:15 +msgid "Please login." msgstr "" -#: ../../addon/skeleton/Mod_Skeleton.php:40 -msgid "A setting" +#: ../../Zotlabs/Module/Editblock.php:138 +msgid "Edit Block" msgstr "" -#: ../../addon/skeleton/Mod_Skeleton.php:48 -msgid "Skeleton Settings" +#: ../../Zotlabs/Module/Impel.php:43 ../../include/bbcode.php:316 +msgid "webpage" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:104 -#: ../../addon/socialauth/Mod_SocialAuth.php:176 -msgid "Network error" +#: ../../Zotlabs/Module/Impel.php:48 ../../include/bbcode.php:322 +msgid "block" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:108 -#: ../../addon/socialauth/Mod_SocialAuth.php:180 -msgid "API error" +#: ../../Zotlabs/Module/Impel.php:53 ../../include/bbcode.php:319 +msgid "layout" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:112 -#: ../../addon/socialauth/Mod_SocialAuth.php:184 -msgid "Unknown issue" +#: ../../Zotlabs/Module/Impel.php:60 ../../include/bbcode.php:325 +msgid "menu" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:168 -msgid "Unable to login using email address " +#: ../../Zotlabs/Module/Impel.php:185 +#, php-format +msgid "%s element installed" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:202 -msgid "Sign in to Hubzilla using a social account" +#: ../../Zotlabs/Module/Impel.php:188 +#, php-format +msgid "%s element installation failed" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:207 -msgid "Social Authentication using your social media account" +#: ../../Zotlabs/Module/Pubsites.php:25 ../../Zotlabs/Widget/Pubsites.php:12 +msgid "Public Hubs" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:211 +#: ../../Zotlabs/Module/Pubsites.php:28 msgid "" -"This app enables one or more social provider sign-in buttons on the login " -"page." +"The listed hubs allow public registration for the $Projectname network. All " +"hubs in the network are interlinked so membership on any of them conveys " +"membership in the network as a whole. Some hubs may require subscription or " +"provide tiered service plans. The hub itself may provide " +"additional details." msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:229 -msgid "Add an identity provider" +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Hub URL" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:256 -msgid "Enable " +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Access Type" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:263 -msgid "Key" +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Registration Policy" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:263 -#: ../../addon/socialauth/Mod_SocialAuth.php:268 -#: ../../addon/socialauth/Mod_SocialAuth.php:284 -#: ../../addon/socialauth/Mod_SocialAuth.php:297 -msgid "Word" +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Stats" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:268 -msgid "Secret" +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Software" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:297 -msgid "Add a custom provider" +#: ../../Zotlabs/Module/Pubsites.php:36 ../../Zotlabs/Module/Ratings.php:97 +#: ../../include/conversation.php:1130 +msgid "Ratings" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:317 -msgid "Remove an identity provider" +#: ../../Zotlabs/Module/Pubsites.php:50 +msgid "Rate" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:327 -msgid "Social authentication" +#: ../../Zotlabs/Module/Chat.php:29 ../../Zotlabs/Module/Channel.php:42 +#: ../../Zotlabs/Module/Ochannel.php:32 +msgid "You must be logged in to see this page." msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:366 -msgid "Error while saving provider settings" +#: ../../Zotlabs/Module/Chat.php:100 +msgid "Chatrooms App" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:382 -msgid "Custom provider already exists" +#: ../../Zotlabs/Module/Chat.php:101 +msgid "Access Controlled Chatrooms" msgstr "" -#: ../../addon/socialauth/Mod_SocialAuth.php:399 -msgid "Social authentication settings saved." +#: ../../Zotlabs/Module/Chat.php:194 +msgid "Room not found" msgstr "" -#: ../../addon/nsfw/nsfw.php:152 -msgid "Possible adult content" +#: ../../Zotlabs/Module/Chat.php:210 +msgid "Leave Room" msgstr "" -#: ../../addon/nsfw/nsfw.php:167 -#, php-format -msgid "%s - view" +#: ../../Zotlabs/Module/Chat.php:211 +msgid "Delete Room" msgstr "" -#: ../../addon/nsfw/Mod_Nsfw.php:22 -msgid "NSFW Settings saved." +#: ../../Zotlabs/Module/Chat.php:212 +msgid "I am away right now" msgstr "" -#: ../../addon/nsfw/Mod_Nsfw.php:33 -msgid "NSFW App" +#: ../../Zotlabs/Module/Chat.php:213 +msgid "I am online" msgstr "" -#: ../../addon/nsfw/Mod_Nsfw.php:34 -msgid "Collapse content that contains predefined words" +#: ../../Zotlabs/Module/Chat.php:215 +msgid "Bookmark this room" msgstr "" -#: ../../addon/nsfw/Mod_Nsfw.php:44 -msgid "" -"This app looks in posts for the words/text you specify below, and collapses " -"any content containing those keywords so it is not displayed at " -"inappropriate times, such as sexual innuendo that may be improper in a work " -"setting. It is polite and recommended to tag any content containing nudity " -"with #NSFW. This filter can also match any other word/text you specify, and " -"can thereby be used as a general purpose content filter." +#: ../../Zotlabs/Module/Chat.php:218 ../../include/conversation.php:1380 +#: ../../extend/addon/hzaddons/hsse/hsse.php:134 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:119 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:240 +msgid "Please enter a link URL:" msgstr "" -#: ../../addon/nsfw/Mod_Nsfw.php:49 -msgid "Comma separated list of keywords to hide" +#: ../../Zotlabs/Module/Chat.php:219 ../../Zotlabs/Lib/ThreadItem.php:839 +#: ../../include/conversation.php:1508 +#: ../../extend/addon/hzaddons/hsse/hsse.php:255 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:172 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:315 +msgid "Encrypt text" msgstr "" -#: ../../addon/nsfw/Mod_Nsfw.php:49 -msgid "Word, /regular-expression/, lang=xx, lang!=xx" +#: ../../Zotlabs/Module/Chat.php:238 +msgid "New Chatroom" msgstr "" -#: ../../addon/nsfw/Mod_Nsfw.php:58 -msgid "NSFW" +#: ../../Zotlabs/Module/Chat.php:239 +msgid "Chatroom name" msgstr "" -#: ../../addon/upload_limits/upload_limits.php:25 -msgid "Show Upload Limits" +#: ../../Zotlabs/Module/Chat.php:240 +msgid "Expiration of chats (minutes)" msgstr "" -#: ../../addon/upload_limits/upload_limits.php:27 -msgid "Hubzilla configured maximum size: " +#: ../../Zotlabs/Module/Chat.php:256 +#, php-format +msgid "%1$s's Chatrooms" msgstr "" -#: ../../addon/upload_limits/upload_limits.php:28 -msgid "PHP upload_max_filesize: " +#: ../../Zotlabs/Module/Chat.php:261 +msgid "No chatrooms available" msgstr "" -#: ../../addon/upload_limits/upload_limits.php:29 -msgid "PHP post_max_size (must be larger than upload_max_filesize): " +#: ../../Zotlabs/Module/Chat.php:265 +msgid "Expiration" msgstr "" -#: ../../addon/tictac/tictac.php:21 -msgid "Three Dimensional Tic-Tac-Toe" +#: ../../Zotlabs/Module/Chat.php:266 +msgid "min" msgstr "" -#: ../../addon/tictac/tictac.php:54 -msgid "3D Tic-Tac-Toe" +#: ../../Zotlabs/Module/Uexport.php:61 +msgid "Channel Export App" msgstr "" -#: ../../addon/tictac/tictac.php:59 -msgid "New game" +#: ../../Zotlabs/Module/Uexport.php:62 +msgid "Export your channel" msgstr "" -#: ../../addon/tictac/tictac.php:60 -msgid "New game with handicap" +#: ../../Zotlabs/Module/Uexport.php:72 ../../Zotlabs/Module/Uexport.php:73 +msgid "Export Channel" msgstr "" -#: ../../addon/tictac/tictac.php:61 +#: ../../Zotlabs/Module/Uexport.php:74 msgid "" -"Three dimensional tic-tac-toe is just like the traditional game except that " -"it is played on multiple levels simultaneously. " +"Export your basic channel information to a file. This acts as a backup of " +"your connections, permissions, profile and basic data, which can be used to " +"import your data to a new server hub, but does not contain your content." msgstr "" -#: ../../addon/tictac/tictac.php:62 -msgid "" -"In this case there are three levels. You win by getting three in a row on " -"any level, as well as up, down, and diagonally across the different levels." +#: ../../Zotlabs/Module/Uexport.php:75 +msgid "Export Content" msgstr "" -#: ../../addon/tictac/tictac.php:64 +#: ../../Zotlabs/Module/Uexport.php:76 msgid "" -"The handicap game disables the center position on the middle level because " -"the player claiming this square often has an unfair advantage." +"Export your channel information and recent content to a JSON backup that can " +"be restored or imported to another server hub. This backs up all of your " +"connections, permissions, profile data and several months of posts. This " +"file may be VERY large. Please be patient - it may take several minutes for " +"this download to begin." msgstr "" -#: ../../addon/tictac/tictac.php:183 -msgid "You go first..." +#: ../../Zotlabs/Module/Uexport.php:78 +msgid "Export your posts from a given year." msgstr "" -#: ../../addon/tictac/tictac.php:188 -msgid "I'm going first this time..." +#: ../../Zotlabs/Module/Uexport.php:80 +msgid "" +"You may also export your posts and conversations for a particular year or " +"month. Adjust the date in your browser location bar to select other dates. " +"If the export fails (possibly due to memory exhaustion on your server hub), " +"please try again selecting a more limited date range." msgstr "" -#: ../../addon/tictac/tictac.php:194 -msgid "You won!" +#: ../../Zotlabs/Module/Uexport.php:81 +#, php-format +msgid "" +"To select all posts for a given year, such as this year, visit %2$s" msgstr "" -#: ../../addon/tictac/tictac.php:200 ../../addon/tictac/tictac.php:225 -msgid "\"Cat\" game!" +#: ../../Zotlabs/Module/Uexport.php:82 +#, php-format +msgid "" +"To select all posts for a given month, such as January of this year, visit " +"%2$s" msgstr "" -#: ../../addon/tictac/tictac.php:223 -msgid "I won!" +#: ../../Zotlabs/Module/Uexport.php:83 +#, php-format +msgid "" +"These content files may be imported or restored by visiting " +"%2$s on any site containing your channel. For best results please import " +"or restore these in date order (oldest first)." msgstr "" -#: ../../addon/gnusoc/gnusoc.php:451 -msgid "Follow" +#: ../../Zotlabs/Module/Lostpass.php:19 +msgid "No valid account found." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:33 +msgid "Password reset request issued. Check your email." msgstr "" -#: ../../addon/gnusoc/gnusoc.php:454 +#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108 #, php-format -msgid "%1$s is now following %2$s" +msgid "Site Member (%s)" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49 +#, php-format +msgid "Password reset requested at %s" msgstr "" -#: ../../addon/gnusoc/Mod_Gnusoc.php:16 +#: ../../Zotlabs/Module/Lostpass.php:68 msgid "" -"The GNU-Social protocol does not support location independence. Connections " -"you make within that network may be unreachable from alternate channel " -"locations." +"Request could not be verified. (You may have previously submitted it.) " +"Password reset failed." msgstr "" -#: ../../addon/gnusoc/Mod_Gnusoc.php:22 -msgid "GNU-Social Protocol App" +#: ../../Zotlabs/Module/Lostpass.php:91 ../../boot.php:1714 +msgid "Password Reset" msgstr "" -#: ../../addon/gnusoc/Mod_Gnusoc.php:34 -msgid "GNU-Social Protocol" +#: ../../Zotlabs/Module/Lostpass.php:92 +msgid "Your password has been reset as requested." msgstr "" -#: ../../addon/mailtest/mailtest.php:19 -msgid "Send test email" +#: ../../Zotlabs/Module/Lostpass.php:93 +msgid "Your new password is" msgstr "" -#: ../../addon/mailtest/mailtest.php:66 -msgid "Mail sent." +#: ../../Zotlabs/Module/Lostpass.php:94 +msgid "Save or copy your new password - and then" msgstr "" -#: ../../addon/mailtest/mailtest.php:68 -msgid "Sending of mail failed." +#: ../../Zotlabs/Module/Lostpass.php:95 +msgid "click here to login" msgstr "" -#: ../../addon/mailtest/mailtest.php:77 -msgid "Mail Test" +#: ../../Zotlabs/Module/Lostpass.php:96 +msgid "" +"Your password may be changed from the Settings page after " +"successful login." msgstr "" -#: ../../addon/ljpost/Mod_Ljpost.php:38 -msgid "Livejournal Crosspost Connector App" +#: ../../Zotlabs/Module/Lostpass.php:117 +#, php-format +msgid "Your password has changed at %s" msgstr "" -#: ../../addon/ljpost/Mod_Ljpost.php:39 -msgid "Relay public posts to Livejournal" +#: ../../Zotlabs/Module/Lostpass.php:130 +msgid "Forgot your Password?" msgstr "" -#: ../../addon/ljpost/Mod_Ljpost.php:55 -msgid "Livejournal username" +#: ../../Zotlabs/Module/Lostpass.php:131 +msgid "" +"Enter your email address and submit to have your password reset. Then check " +"your email for further instructions." msgstr "" -#: ../../addon/ljpost/Mod_Ljpost.php:59 -msgid "Livejournal password" +#: ../../Zotlabs/Module/Lostpass.php:132 +msgid "Email Address" msgstr "" -#: ../../addon/ljpost/Mod_Ljpost.php:63 -msgid "Post to Livejournal by default" +#: ../../Zotlabs/Module/Vote.php:40 +msgid "Poll not found." msgstr "" -#: ../../addon/ljpost/Mod_Ljpost.php:67 -msgid "Send wall-to-wall posts to Livejournal" +#: ../../Zotlabs/Module/Vote.php:71 +msgid "Invalid response." msgstr "" -#: ../../addon/ljpost/Mod_Ljpost.php:79 -msgid "Livejournal Crosspost Connector" +#: ../../Zotlabs/Module/Vote.php:132 +msgid "Response submitted. Updates may not appear instantly." msgstr "" -#: ../../addon/ljpost/ljpost.php:49 -msgid "Post to Livejournal" +#: ../../Zotlabs/Module/Ping.php:337 ../../Zotlabs/Lib/Enotify.php:948 +msgid "sent you a private message" msgstr "" -#: ../../addon/ljpost/ljpost.php:127 -msgid "Posted by" +#: ../../Zotlabs/Module/Ping.php:393 ../../Zotlabs/Lib/Enotify.php:914 +msgid "added your channel" msgstr "" -#: ../../addon/mdpost/mdpost.php:41 ../../include/text.php:2116 -#: ../../Zotlabs/Widget/Wiki_pages.php:38 -#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../Zotlabs/Module/Wiki.php:217 -#: ../../Zotlabs/Module/Wiki.php:371 -msgid "Markdown" +#: ../../Zotlabs/Module/Ping.php:418 ../../Zotlabs/Lib/Enotify.php:986 +msgid "requires approval" msgstr "" -#: ../../addon/mdpost/mdpost.php:42 -msgid "Use markdown for editing posts" +#: ../../Zotlabs/Module/Ping.php:428 ../../Zotlabs/Lib/Enotify.php:957 +msgid "g A l F d" msgstr "" -#: ../../addon/hzfiles/hzfiles.php:81 -msgid "Hubzilla File Storage Import" +#: ../../Zotlabs/Module/Ping.php:446 ../../Zotlabs/Lib/Enotify.php:960 +msgid "[today]" msgstr "" -#: ../../addon/hzfiles/hzfiles.php:82 -msgid "This will import all your cloud files from another server." +#: ../../Zotlabs/Module/Ping.php:456 +msgid "posted an event" msgstr "" -#: ../../addon/hzfiles/hzfiles.php:83 -msgid "Hubzilla Server base URL" +#: ../../Zotlabs/Module/Ping.php:490 ../../Zotlabs/Lib/Enotify.php:829 +#: ../../Zotlabs/Lib/Enotify.php:931 +msgid "shared a file with you" msgstr "" -#: ../../addon/authchoose/Mod_Authchoose.php:22 +#: ../../Zotlabs/Module/Display.php:359 ../../Zotlabs/Module/Channel.php:449 msgid "" -"Allow magic authentication only to websites of your immediate connections" +"You must enable javascript for your browser to be able to view this content." msgstr "" -#: ../../addon/authchoose/Mod_Authchoose.php:28 -#: ../../addon/authchoose/Mod_Authchoose.php:33 -msgid "Authchoose App" +#: ../../Zotlabs/Module/Display.php:377 +msgid "Article" msgstr "" -#: ../../addon/authchoose/Mod_Authchoose.php:39 -msgid "Authchoose" +#: ../../Zotlabs/Module/Display.php:422 +msgid "Item has been removed." msgstr "" -#: ../../addon/pageheader/Mod_Pageheader.php:22 -msgid "pageheader Settings saved." +#: ../../Zotlabs/Module/Admin.php:96 +#: ../../Zotlabs/Module/Admin/Accounts.php:167 +#: ../../Zotlabs/Module/Admin/Accounts.php:180 +#: ../../Zotlabs/Widget/Admin.php:23 +msgid "Accounts" msgstr "" -#: ../../addon/pageheader/Mod_Pageheader.php:34 -msgid "Page Header App" +#: ../../Zotlabs/Module/Admin.php:97 +msgid "Blocked accounts" msgstr "" -#: ../../addon/pageheader/Mod_Pageheader.php:35 -msgid "Inserts a page header" +#: ../../Zotlabs/Module/Admin.php:98 +msgid "Expired accounts" msgstr "" -#: ../../addon/pageheader/Mod_Pageheader.php:43 -msgid "Message to display on every page on this server" +#: ../../Zotlabs/Module/Admin.php:99 +msgid "Expiring accounts" msgstr "" -#: ../../addon/pageheader/Mod_Pageheader.php:51 -msgid "Page Header" +#: ../../Zotlabs/Module/Admin.php:114 +#: ../../Zotlabs/Module/Admin/Channels.php:146 +#: ../../Zotlabs/Widget/Admin.php:24 +msgid "Channels" msgstr "" -#: ../../addon/irc/Mod_Irc.php:23 ../../addon/irc/irc.php:41 -msgid "Popular Channels" +#: ../../Zotlabs/Module/Admin.php:120 +msgid "Message queues" msgstr "" -#: ../../addon/irc/irc.php:37 -msgid "Channels to auto connect" +#: ../../Zotlabs/Module/Admin.php:134 +msgid "Your software should be updated" msgstr "" -#: ../../addon/irc/irc.php:37 ../../addon/irc/irc.php:41 -msgid "Comma separated list" +#: ../../Zotlabs/Module/Admin.php:138 ../../Zotlabs/Module/Admin/Themes.php:122 +#: ../../Zotlabs/Module/Admin/Themes.php:156 +#: ../../Zotlabs/Module/Admin/Security.php:98 +#: ../../Zotlabs/Module/Admin/Accounts.php:166 +#: ../../Zotlabs/Module/Admin/Channels.php:145 +#: ../../Zotlabs/Module/Admin/Logs.php:82 +#: ../../Zotlabs/Module/Admin/Addons.php:342 +#: ../../Zotlabs/Module/Admin/Addons.php:440 +#: ../../Zotlabs/Module/Admin/Site.php:291 +msgid "Administration" msgstr "" -#: ../../addon/irc/irc.php:45 -msgid "IRC Settings" +#: ../../Zotlabs/Module/Admin.php:139 +msgid "Summary" msgstr "" -#: ../../addon/irc/irc.php:54 -msgid "IRC settings saved." +#: ../../Zotlabs/Module/Admin.php:142 +msgid "Registered accounts" msgstr "" -#: ../../addon/irc/irc.php:58 -msgid "IRC Chatroom" +#: ../../Zotlabs/Module/Admin.php:143 +msgid "Pending registrations" msgstr "" -#: ../../addon/xmpp/xmpp.php:44 -msgid "Jabber BOSH host" +#: ../../Zotlabs/Module/Admin.php:144 +msgid "Registered channels" msgstr "" -#: ../../addon/xmpp/xmpp.php:45 -msgid "Use central userbase" +#: ../../Zotlabs/Module/Admin.php:145 +msgid "Active addons" msgstr "" -#: ../../addon/xmpp/xmpp.php:45 -msgid "" -"If enabled, members will automatically login to an ejabberd server that has " -"to be installed on this machine with synchronized credentials via the " -"\"auth_ejabberd.php\" script." +#: ../../Zotlabs/Module/Admin.php:146 +msgid "Version" msgstr "" -#: ../../addon/xmpp/Mod_Xmpp.php:23 -msgid "XMPP settings updated." +#: ../../Zotlabs/Module/Admin.php:147 +msgid "Repository version (master)" msgstr "" -#: ../../addon/xmpp/Mod_Xmpp.php:35 -msgid "XMPP App" +#: ../../Zotlabs/Module/Admin.php:148 +msgid "Repository version (dev)" msgstr "" -#: ../../addon/xmpp/Mod_Xmpp.php:36 -msgid "Embedded XMPP (Jabber) client" +#: ../../Zotlabs/Module/Photos.php:80 +msgid "Page owner information could not be retrieved." msgstr "" -#: ../../addon/xmpp/Mod_Xmpp.php:52 -msgid "Individual credentials" +#: ../../Zotlabs/Module/Photos.php:96 ../../Zotlabs/Module/Photos.php:115 +msgid "Album not found." msgstr "" -#: ../../addon/xmpp/Mod_Xmpp.php:58 -msgid "Jabber BOSH server" +#: ../../Zotlabs/Module/Photos.php:105 +msgid "Delete Album" msgstr "" -#: ../../addon/xmpp/Mod_Xmpp.php:67 -msgid "XMPP Settings" +#: ../../Zotlabs/Module/Photos.php:176 ../../Zotlabs/Module/Photos.php:1059 +msgid "Delete Photo" msgstr "" -#: ../../include/zot.php:775 -msgid "Invalid data packet" +#: ../../Zotlabs/Module/Photos.php:530 +msgid "No photos selected" msgstr "" -#: ../../include/zot.php:802 ../../Zotlabs/Lib/Libzot.php:656 -msgid "Unable to verify channel signature" +#: ../../Zotlabs/Module/Photos.php:579 +msgid "Access to this item is restricted." msgstr "" -#: ../../include/zot.php:2657 ../../Zotlabs/Lib/Libsync.php:740 +#: ../../Zotlabs/Module/Photos.php:622 #, php-format -msgid "Unable to verify site signature for %s" +msgid "%1$.2f MB of %2$.2f MB photo storage used." msgstr "" -#: ../../include/zot.php:4372 -msgid "invalid target signature" +#: ../../Zotlabs/Module/Photos.php:625 +#, php-format +msgid "%1$.2f MB photo storage used." msgstr "" -#: ../../include/text.php:522 -msgid "prev" +#: ../../Zotlabs/Module/Photos.php:667 +msgid "Upload Photos" msgstr "" -#: ../../include/text.php:524 -msgid "first" +#: ../../Zotlabs/Module/Photos.php:671 +msgid "Enter an album name" msgstr "" -#: ../../include/text.php:553 -msgid "last" +#: ../../Zotlabs/Module/Photos.php:672 +msgid "or select an existing album (doubleclick)" msgstr "" -#: ../../include/text.php:556 -msgid "next" +#: ../../Zotlabs/Module/Photos.php:673 +msgid "Create a status post for this upload" msgstr "" -#: ../../include/text.php:574 -msgid "older" +#: ../../Zotlabs/Module/Photos.php:675 +msgid "Description (optional)" msgstr "" -#: ../../include/text.php:576 -msgid "newer" +#: ../../Zotlabs/Module/Photos.php:761 +msgid "Show Newest First" msgstr "" -#: ../../include/text.php:1024 -msgid "No connections" +#: ../../Zotlabs/Module/Photos.php:763 +msgid "Show Oldest First" msgstr "" -#: ../../include/text.php:1036 ../../include/features.php:133 -#: ../../Zotlabs/Module/Connections.php:374 ../../Zotlabs/Lib/Apps.php:333 -msgid "Connections" +#: ../../Zotlabs/Module/Photos.php:787 ../../Zotlabs/Module/Photos.php:1333 +#: ../../Zotlabs/Module/Embedphotos.php:170 +#: ../../Zotlabs/Widget/Portfolio.php:87 ../../Zotlabs/Widget/Album.php:78 +msgid "View Photo" msgstr "" -#: ../../include/text.php:1044 ../../Zotlabs/Module/Viewconnections.php:80 -#: ../../Zotlabs/Module/Connections.php:288 -msgid "Accepts" +#: ../../Zotlabs/Module/Photos.php:793 ../../Zotlabs/Module/Photos.php:1255 +#: ../../Zotlabs/Module/Embedphotos.php:176 ../../Zotlabs/Lib/Apps.php:1112 +#: ../../Zotlabs/Lib/Apps.php:1196 ../../Zotlabs/Lib/Activity.php:1508 +#: ../../Zotlabs/Widget/Portfolio.php:95 ../../Zotlabs/Widget/Pinned.php:270 +#: ../../Zotlabs/Widget/Album.php:84 ../../include/conversation.php:1211 +#: ../../include/cdav.php:158 ../../include/cdav.php:159 +#: ../../include/cdav.php:167 ../../extend/addon/hzaddons/pubcrawl/as.php:1187 +msgid "Unknown" msgstr "" -#: ../../include/text.php:1047 ../../Zotlabs/Module/Viewconnections.php:83 -#: ../../Zotlabs/Module/Connections.php:291 -msgid "Comments" +#: ../../Zotlabs/Module/Photos.php:818 ../../Zotlabs/Module/Embedphotos.php:186 +#: ../../Zotlabs/Widget/Portfolio.php:108 ../../Zotlabs/Widget/Album.php:95 +msgid "Edit Album" msgstr "" -#: ../../include/text.php:1052 ../../Zotlabs/Module/Viewconnections.php:88 -#: ../../Zotlabs/Module/Connections.php:296 -msgid "Stream items" +#: ../../Zotlabs/Module/Photos.php:820 ../../Zotlabs/Module/Photos.php:1364 +msgid "Add Photos" msgstr "" -#: ../../include/text.php:1057 ../../Zotlabs/Module/Viewconnections.php:93 -#: ../../Zotlabs/Module/Connections.php:301 -msgid "Wall posts" +#: ../../Zotlabs/Module/Photos.php:868 +msgid "Permission denied. Access to this item may be restricted." msgstr "" -#: ../../include/text.php:1061 ../../Zotlabs/Module/Viewconnections.php:97 -#: ../../Zotlabs/Module/Connections.php:305 -msgid "Nothing" +#: ../../Zotlabs/Module/Photos.php:870 +msgid "Photo not available" msgstr "" -#: ../../include/text.php:1076 -#, php-format -msgid "View all %s connections" +#: ../../Zotlabs/Module/Photos.php:928 +msgid "Use as profile photo" msgstr "" -#: ../../include/text.php:1139 -#, php-format -msgid "Network: %s" +#: ../../Zotlabs/Module/Photos.php:929 +msgid "Use as cover photo" msgstr "" -#: ../../include/text.php:1150 ../../include/text.php:1162 -#: ../../include/nav.php:188 ../../include/acl_selectors.php:148 -#: ../../Zotlabs/Widget/Sitesearch.php:31 -#: ../../Zotlabs/Widget/Activity_filter.php:193 -#: ../../Zotlabs/Module/Search.php:41 ../../Zotlabs/Module/Connections.php:378 -#: ../../Zotlabs/Lib/Apps.php:353 -msgid "Search" +#: ../../Zotlabs/Module/Photos.php:936 +msgid "Private Photo" msgstr "" -#: ../../include/text.php:1242 ../../include/text.php:1246 -msgid "poke" +#: ../../Zotlabs/Module/Photos.php:951 +msgid "View Full Size" msgstr "" -#: ../../include/text.php:1242 ../../include/text.php:1246 -#: ../../include/conversation.php:267 -msgid "poked" +#: ../../Zotlabs/Module/Photos.php:1033 +msgid "Edit photo" msgstr "" -#: ../../include/text.php:1247 -msgid "ping" +#: ../../Zotlabs/Module/Photos.php:1035 +msgid "Rotate CW (right)" msgstr "" -#: ../../include/text.php:1247 -msgid "pinged" +#: ../../Zotlabs/Module/Photos.php:1036 +msgid "Rotate CCW (left)" msgstr "" -#: ../../include/text.php:1248 -msgid "prod" +#: ../../Zotlabs/Module/Photos.php:1039 +msgid "Move photo to album" msgstr "" -#: ../../include/text.php:1248 -msgid "prodded" +#: ../../Zotlabs/Module/Photos.php:1040 +msgid "Enter a new album name" msgstr "" -#: ../../include/text.php:1249 -msgid "slap" +#: ../../Zotlabs/Module/Photos.php:1041 +msgid "or select an existing one (doubleclick)" msgstr "" -#: ../../include/text.php:1249 -msgid "slapped" +#: ../../Zotlabs/Module/Photos.php:1046 +msgid "Add a Tag" msgstr "" -#: ../../include/text.php:1250 -msgid "finger" +#: ../../Zotlabs/Module/Photos.php:1054 +msgid "Example: @bob, @Barbara_Jensen, @jim@example.com" msgstr "" -#: ../../include/text.php:1250 -msgid "fingered" +#: ../../Zotlabs/Module/Photos.php:1057 +msgid "Flag as adult in album view" msgstr "" -#: ../../include/text.php:1251 -msgid "rebuff" +#: ../../Zotlabs/Module/Photos.php:1076 ../../Zotlabs/Lib/ThreadItem.php:317 +msgid "I like this (toggle)" msgstr "" -#: ../../include/text.php:1251 -msgid "rebuffed" +#: ../../Zotlabs/Module/Photos.php:1077 ../../Zotlabs/Lib/ThreadItem.php:318 +msgid "I don't like this (toggle)" msgstr "" -#: ../../include/text.php:1274 -msgid "happy" +#: ../../Zotlabs/Module/Photos.php:1079 ../../Zotlabs/Lib/ThreadItem.php:501 +#: ../../include/conversation.php:827 +msgid "Please wait" msgstr "" -#: ../../include/text.php:1275 -msgid "sad" +#: ../../Zotlabs/Module/Photos.php:1095 ../../Zotlabs/Module/Photos.php:1213 +#: ../../Zotlabs/Lib/ThreadItem.php:822 +msgid "This is you" msgstr "" -#: ../../include/text.php:1276 -msgid "mellow" +#: ../../Zotlabs/Module/Photos.php:1097 ../../Zotlabs/Module/Photos.php:1215 +#: ../../Zotlabs/Lib/ThreadItem.php:824 ../../include/js_strings.php:6 +msgid "Comment" msgstr "" -#: ../../include/text.php:1277 -msgid "tired" +#: ../../Zotlabs/Module/Photos.php:1113 ../../include/conversation.php:652 +msgctxt "title" +msgid "Likes" msgstr "" -#: ../../include/text.php:1278 -msgid "perky" +#: ../../Zotlabs/Module/Photos.php:1113 ../../include/conversation.php:653 +msgctxt "title" +msgid "Dislikes" msgstr "" -#: ../../include/text.php:1279 -msgid "angry" +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:77 +#: ../../include/conversation.php:654 +msgctxt "title" +msgid "Agree" msgstr "" -#: ../../include/text.php:1280 -msgid "stupefied" +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:78 +#: ../../include/conversation.php:655 +msgctxt "title" +msgid "Disagree" msgstr "" -#: ../../include/text.php:1281 -msgid "puzzled" +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:79 +#: ../../include/conversation.php:656 +msgctxt "title" +msgid "Abstain" msgstr "" -#: ../../include/text.php:1282 -msgid "interested" +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:66 +#: ../../include/conversation.php:657 +msgctxt "title" +msgid "Attending" msgstr "" -#: ../../include/text.php:1283 -msgid "bitter" +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:67 +#: ../../include/conversation.php:658 +msgctxt "title" +msgid "Not attending" msgstr "" -#: ../../include/text.php:1284 -msgid "cheerful" +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:68 +#: ../../include/conversation.php:659 +msgctxt "title" +msgid "Might attend" msgstr "" -#: ../../include/text.php:1285 -msgid "alive" +#: ../../Zotlabs/Module/Photos.php:1132 ../../Zotlabs/Module/Photos.php:1144 +#: ../../Zotlabs/Lib/ThreadItem.php:238 ../../Zotlabs/Lib/ThreadItem.php:250 +msgid "View all" msgstr "" -#: ../../include/text.php:1286 -msgid "annoyed" -msgstr "" +#: ../../Zotlabs/Module/Photos.php:1136 ../../Zotlabs/Lib/ThreadItem.php:242 +#: ../../include/conversation.php:1749 ../../include/channel.php:1781 +#: ../../include/taxonomy.php:668 +msgctxt "noun" +msgid "Like" +msgid_plural "Likes" +msgstr[0] "" +msgstr[1] "" -#: ../../include/text.php:1287 -msgid "anxious" -msgstr "" +#: ../../Zotlabs/Module/Photos.php:1141 ../../Zotlabs/Lib/ThreadItem.php:247 +#: ../../include/conversation.php:1752 +msgctxt "noun" +msgid "Dislike" +msgid_plural "Dislikes" +msgstr[0] "" +msgstr[1] "" -#: ../../include/text.php:1288 -msgid "cranky" +#: ../../Zotlabs/Module/Photos.php:1247 +msgid "Photo Tools" msgstr "" -#: ../../include/text.php:1289 -msgid "disturbed" +#: ../../Zotlabs/Module/Photos.php:1256 +msgid "In This Photo:" msgstr "" -#: ../../include/text.php:1290 -msgid "frustrated" +#: ../../Zotlabs/Module/Photos.php:1261 +msgid "Map" msgstr "" -#: ../../include/text.php:1291 -msgid "depressed" +#: ../../Zotlabs/Module/Photos.php:1269 ../../Zotlabs/Lib/ThreadItem.php:489 +msgctxt "noun" +msgid "Likes" msgstr "" -#: ../../include/text.php:1292 -msgid "motivated" +#: ../../Zotlabs/Module/Photos.php:1270 ../../Zotlabs/Lib/ThreadItem.php:490 +msgctxt "noun" +msgid "Dislikes" msgstr "" -#: ../../include/text.php:1293 -msgid "relaxed" +#: ../../Zotlabs/Module/Photos.php:1275 ../../Zotlabs/Storage/Browser.php:411 +#: ../../Zotlabs/Lib/ThreadItem.php:495 ../../Zotlabs/Widget/Pinned.php:160 +#: ../../include/acl_selectors.php:155 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:233 +msgid "Close" msgstr "" -#: ../../include/text.php:1294 -msgid "surprised" +#: ../../Zotlabs/Module/Photos.php:1348 ../../Zotlabs/Module/Photos.php:1361 +#: ../../Zotlabs/Module/Photos.php:1362 ../../include/photos.php:667 +msgid "Recent Photos" msgstr "" -#: ../../include/text.php:1482 ../../include/js_strings.php:99 -msgid "Monday" +#: ../../Zotlabs/Module/Channel.php:99 ../../Zotlabs/Module/Profile.php:45 +#: ../../Zotlabs/Module/Hcard.php:37 +msgid "Posts and comments" msgstr "" -#: ../../include/text.php:1482 ../../include/js_strings.php:100 -msgid "Tuesday" +#: ../../Zotlabs/Module/Channel.php:106 ../../Zotlabs/Module/Profile.php:52 +#: ../../Zotlabs/Module/Hcard.php:44 +msgid "Only posts" msgstr "" -#: ../../include/text.php:1482 ../../include/js_strings.php:101 -msgid "Wednesday" +#: ../../Zotlabs/Module/Channel.php:174 +msgid "Insufficient permissions. Request redirected to profile page." msgstr "" -#: ../../include/text.php:1482 ../../include/js_strings.php:102 -msgid "Thursday" +#: ../../Zotlabs/Module/Channel.php:189 ../../Zotlabs/Module/Network.php:164 +msgid "Search Results For:" msgstr "" -#: ../../include/text.php:1482 ../../include/js_strings.php:103 -msgid "Friday" +#: ../../Zotlabs/Module/Cards.php:51 +msgid "Cards App" msgstr "" -#: ../../include/text.php:1482 ../../include/js_strings.php:104 -msgid "Saturday" +#: ../../Zotlabs/Module/Cards.php:52 +msgid "Create personal planning cards" msgstr "" -#: ../../include/text.php:1482 ../../include/js_strings.php:98 -msgid "Sunday" +#: ../../Zotlabs/Module/Cards.php:112 +msgid "Add Card" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:74 -msgid "January" +#: ../../Zotlabs/Module/Cards.php:207 ../../Zotlabs/Lib/Apps.php:326 +#: ../../include/nav.php:501 +msgid "Cards" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:75 -msgid "February" +#: ../../Zotlabs/Module/Go.php:21 +msgid "This page is available only to site members" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:76 -msgid "March" +#: ../../Zotlabs/Module/Go.php:27 +msgid "Welcome" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:77 -msgid "April" +#: ../../Zotlabs/Module/Go.php:29 +msgid "What would you like to do?" msgstr "" -#: ../../include/text.php:1486 -msgid "May" +#: ../../Zotlabs/Module/Go.php:31 +msgid "" +"Please bookmark this page if you would like to return to it in the future" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:79 -msgid "June" +#: ../../Zotlabs/Module/Go.php:35 +msgid "Upload a profile photo" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:80 -msgid "July" +#: ../../Zotlabs/Module/Go.php:36 +msgid "Upload a cover photo" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:81 -msgid "August" +#: ../../Zotlabs/Module/Go.php:37 +msgid "Edit your default profile" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:82 -msgid "September" +#: ../../Zotlabs/Module/Go.php:38 ../../Zotlabs/Widget/Newmember.php:41 +msgid "View friend suggestions" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:83 -msgid "October" +#: ../../Zotlabs/Module/Go.php:39 +msgid "View the channel directory" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:84 -msgid "November" +#: ../../Zotlabs/Module/Go.php:40 +msgid "View/edit your channel settings" msgstr "" -#: ../../include/text.php:1486 ../../include/js_strings.php:85 -msgid "December" +#: ../../Zotlabs/Module/Go.php:41 +msgid "View the site or project documentation" msgstr "" -#: ../../include/text.php:1560 -msgid "Unknown Attachment" +#: ../../Zotlabs/Module/Go.php:42 +msgid "Visit your channel homepage" msgstr "" -#: ../../include/text.php:1562 ../../Zotlabs/Module/Sharedwithme.php:108 -#: ../../Zotlabs/Storage/Browser.php:372 -msgid "Size" +#: ../../Zotlabs/Module/Go.php:43 +msgid "" +"View your connections and/or add somebody whose address you already know" msgstr "" -#: ../../include/text.php:1562 ../../include/feedutils.php:873 -msgid "unknown" +#: ../../Zotlabs/Module/Go.php:44 +msgid "" +"View your personal stream (this may be empty until you add some connections)" msgstr "" -#: ../../include/text.php:1598 -msgid "remove category" +#: ../../Zotlabs/Module/Go.php:52 +msgid "View the public stream. Warning: this content is not moderated" msgstr "" -#: ../../include/text.php:1674 -msgid "remove from file" +#: ../../Zotlabs/Module/Connections.php:58 +#: ../../Zotlabs/Module/Connections.php:115 +#: ../../Zotlabs/Module/Connections.php:273 +msgid "Active" msgstr "" -#: ../../include/text.php:1843 ../../include/message.php:13 -msgid "Download binary/encrypted content" +#: ../../Zotlabs/Module/Connections.php:63 +#: ../../Zotlabs/Module/Connections.php:181 +#: ../../Zotlabs/Module/Connections.php:278 +msgid "Blocked" msgstr "" -#: ../../include/text.php:1914 -msgid "Poll has ended." +#: ../../Zotlabs/Module/Connections.php:68 +#: ../../Zotlabs/Module/Connections.php:188 +#: ../../Zotlabs/Module/Connections.php:277 +msgid "Ignored" msgstr "" -#: ../../include/text.php:1917 -#, php-format -msgid "Poll ends: %s" +#: ../../Zotlabs/Module/Connections.php:73 +#: ../../Zotlabs/Module/Connections.php:202 +#: ../../Zotlabs/Module/Connections.php:276 +msgid "Hidden" msgstr "" -#: ../../include/text.php:1922 ../../Zotlabs/Lib/ThreadItem.php:444 -msgid "Vote" +#: ../../Zotlabs/Module/Connections.php:78 +#: ../../Zotlabs/Module/Connections.php:195 +msgid "Archived/Unreachable" msgstr "" -#: ../../include/text.php:2074 ../../Zotlabs/Module/Events.php:669 -msgid "Link to Source" +#: ../../Zotlabs/Module/Connections.php:83 +#: ../../Zotlabs/Module/Connections.php:92 +#: ../../Zotlabs/Module/Notifications.php:50 ../../Zotlabs/Module/Menu.php:180 +msgid "New" msgstr "" -#: ../../include/text.php:2096 ../../include/language.php:424 -msgid "default" +#: ../../Zotlabs/Module/Connections.php:157 +msgid "Active Connections" msgstr "" -#: ../../include/text.php:2104 -msgid "Page layout" +#: ../../Zotlabs/Module/Connections.php:160 +msgid "Show active connections" msgstr "" -#: ../../include/text.php:2104 -msgid "You can create your own with the layouts tool" +#: ../../Zotlabs/Module/Connections.php:164 +#: ../../Zotlabs/Widget/Notifications.php:104 +msgid "New Connections" msgstr "" -#: ../../include/text.php:2114 ../../Zotlabs/Widget/Wiki_pages.php:38 -#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../Zotlabs/Module/Wiki.php:217 -#: ../../Zotlabs/Module/Wiki.php:371 -msgid "BBcode" +#: ../../Zotlabs/Module/Connections.php:167 +msgid "Show pending (new) connections" msgstr "" -#: ../../include/text.php:2115 -msgid "HTML" +#: ../../Zotlabs/Module/Connections.php:184 +msgid "Only show blocked connections" msgstr "" -#: ../../include/text.php:2117 ../../Zotlabs/Widget/Wiki_pages.php:38 -#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../Zotlabs/Module/Wiki.php:217 -msgid "Text" +#: ../../Zotlabs/Module/Connections.php:191 +msgid "Only show ignored connections" msgstr "" -#: ../../include/text.php:2118 -msgid "Comanche Layout" +#: ../../Zotlabs/Module/Connections.php:198 +msgid "Only show archived/unreachable connections" msgstr "" -#: ../../include/text.php:2123 -msgid "PHP" +#: ../../Zotlabs/Module/Connections.php:205 +msgid "Only show hidden connections" msgstr "" -#: ../../include/text.php:2132 -msgid "Page content type" +#: ../../Zotlabs/Module/Connections.php:220 +msgid "Show all connections" msgstr "" -#: ../../include/text.php:2255 ../../include/event.php:1259 -#: ../../include/conversation.php:132 -#: ../../Zotlabs/Module/Channel_calendar.php:219 -#: ../../Zotlabs/Module/Like.php:435 ../../Zotlabs/Module/Tagger.php:75 -#: ../../Zotlabs/Module/Events.php:266 -msgid "event" +#: ../../Zotlabs/Module/Connections.php:274 +msgid "Pending approval" msgstr "" -#: ../../include/text.php:2258 ../../include/conversation.php:158 -#: ../../include/bbcode.php:523 ../../include/markdown.php:204 -#: ../../Zotlabs/Module/Tagger.php:79 ../../Zotlabs/Lib/Activity.php:2971 -msgid "post" +#: ../../Zotlabs/Module/Connections.php:275 +msgid "Archived" msgstr "" -#: ../../include/text.php:2260 ../../include/conversation.php:160 -#: ../../Zotlabs/Module/Tagger.php:81 -msgid "comment" +#: ../../Zotlabs/Module/Connections.php:279 +msgid "Not connected at this location" msgstr "" -#: ../../include/text.php:2265 -msgid "activity" +#: ../../Zotlabs/Module/Connections.php:318 +#, php-format +msgid "%1$s [%2$s]" msgstr "" -#: ../../include/text.php:2268 -msgid "poll" +#: ../../Zotlabs/Module/Connections.php:319 +msgid "Edit connection" msgstr "" -#: ../../include/text.php:2369 -msgid "a-z, 0-9, -, and _ only" +#: ../../Zotlabs/Module/Connections.php:321 +msgid "Delete connection" msgstr "" -#: ../../include/text.php:2695 -msgid "Design Tools" +#: ../../Zotlabs/Module/Connections.php:330 +msgid "Channel address" msgstr "" -#: ../../include/text.php:2698 ../../Zotlabs/Module/Blocks.php:154 -msgid "Blocks" +#: ../../Zotlabs/Module/Connections.php:332 ../../include/features.php:291 +msgid "Network" msgstr "" -#: ../../include/text.php:2699 ../../Zotlabs/Module/Menu.php:171 -msgid "Menus" +#: ../../Zotlabs/Module/Connections.php:335 +msgid "Call" msgstr "" -#: ../../include/text.php:2700 ../../Zotlabs/Module/Layouts.php:184 -msgid "Layouts" +#: ../../Zotlabs/Module/Connections.php:337 +msgid "Status" msgstr "" -#: ../../include/text.php:2701 -msgid "Pages" +#: ../../Zotlabs/Module/Connections.php:339 +msgid "Connected" msgstr "" -#: ../../include/text.php:2713 -msgid "Import" +#: ../../Zotlabs/Module/Connections.php:341 +msgid "Approve connection" msgstr "" -#: ../../include/text.php:2714 -msgid "Import website..." +#: ../../Zotlabs/Module/Connections.php:342 +#: ../../Zotlabs/Module/Admin/Accounts.php:173 +#: ../../include/conversation.php:774 +msgid "Approve" msgstr "" -#: ../../include/text.php:2715 -msgid "Select folder to import" +#: ../../Zotlabs/Module/Connections.php:343 +msgid "Ignore connection" msgstr "" -#: ../../include/text.php:2716 -msgid "Import from a zipped folder:" +#: ../../Zotlabs/Module/Connections.php:345 +msgid "Recent activity" msgstr "" -#: ../../include/text.php:2717 -msgid "Import from cloud files:" +#: ../../Zotlabs/Module/Connections.php:349 ../../Zotlabs/Module/Suggest.php:71 +#: ../../Zotlabs/Module/Directory.php:370 ../../Zotlabs/Widget/Follow.php:32 +#: ../../Zotlabs/Widget/Suggestions.php:46 ../../include/conversation.php:1100 +#: ../../include/channel.php:1618 ../../include/connections.php:110 +msgid "Connect" msgstr "" -#: ../../include/text.php:2718 -msgid "/cloud/channel/path/to/folder" +#: ../../Zotlabs/Module/Connections.php:351 +msgid "Connect at this location" msgstr "" -#: ../../include/text.php:2719 -msgid "Enter path to website files" +#: ../../Zotlabs/Module/Connections.php:374 ../../Zotlabs/Lib/Apps.php:333 +#: ../../include/features.php:133 ../../include/text.php:1036 +msgid "Connections" msgstr "" -#: ../../include/text.php:2720 -msgid "Select folder" +#: ../../Zotlabs/Module/Connections.php:379 +msgid "Search your connections" msgstr "" -#: ../../include/text.php:2721 -msgid "Export website..." +#: ../../Zotlabs/Module/Connections.php:380 +msgid "Connections search" msgstr "" -#: ../../include/text.php:2722 -msgid "Export to a zip file" +#: ../../Zotlabs/Module/Connections.php:381 +#: ../../Zotlabs/Module/Directory.php:433 +#: ../../Zotlabs/Module/Directory.php:438 ../../include/contact_widgets.php:23 +msgid "Find" msgstr "" -#: ../../include/text.php:2723 -msgid "website.zip" +#: ../../Zotlabs/Module/Editpost.php:38 ../../Zotlabs/Module/Editpost.php:43 +msgid "Item is not editable" msgstr "" -#: ../../include/text.php:2724 -msgid "Enter a name for the zip file." +#: ../../Zotlabs/Module/Tagrm.php:48 ../../Zotlabs/Module/Tagrm.php:98 +msgid "Tag removed" msgstr "" -#: ../../include/text.php:2725 -msgid "Export to cloud files" +#: ../../Zotlabs/Module/Tagrm.php:123 +msgid "Remove Item Tag" msgstr "" -#: ../../include/text.php:2726 -msgid "/path/to/export/folder" +#: ../../Zotlabs/Module/Tagrm.php:125 +msgid "Select a tag to remove: " msgstr "" -#: ../../include/text.php:2727 -msgid "Enter a path to a cloud files destination." +#: ../../Zotlabs/Module/Affinity.php:35 +msgid "Affinity Tool settings updated." msgstr "" -#: ../../include/text.php:2728 -msgid "Specify folder" +#: ../../Zotlabs/Module/Affinity.php:47 +msgid "" +"This app presents a slider control in your connection editor and also on " +"your network page. The slider represents your degree of friendship " +"(affinity) with each connection. It allows you to zoom in or out and display " +"conversations from only your closest friends or everybody in your stream." msgstr "" -#: ../../include/opengraph.php:56 -#, php-format -msgid "This is the home page of %s." +#: ../../Zotlabs/Module/Affinity.php:52 +msgid "Affinity Tool App" msgstr "" -#: ../../include/event.php:33 ../../include/event.php:110 -msgid "l F d, Y \\@ g:i A" +#: ../../Zotlabs/Module/Affinity.php:57 +msgid "" +"The numbers below represent the minimum and maximum slider default positions " +"for your network/stream page as a percentage." msgstr "" -#: ../../include/event.php:41 -msgid "Starts:" +#: ../../Zotlabs/Module/Affinity.php:64 +msgid "Default maximum affinity level" msgstr "" -#: ../../include/event.php:51 -msgid "Finishes:" +#: ../../Zotlabs/Module/Affinity.php:64 +msgid "0-99 default 99" msgstr "" -#: ../../include/event.php:63 ../../include/event.php:134 -#: ../../include/channel.php:1633 ../../Zotlabs/Module/Directory.php:352 -msgid "Location:" +#: ../../Zotlabs/Module/Affinity.php:70 +msgid "Default minimum affinity level" msgstr "" -#: ../../include/event.php:110 -msgid "l F d, Y" +#: ../../Zotlabs/Module/Affinity.php:70 +msgid "0-99 - default 0" msgstr "" -#: ../../include/event.php:114 -msgid "Start:" +#: ../../Zotlabs/Module/Affinity.php:76 +msgid "Persistent affinity levels" msgstr "" -#: ../../include/event.php:118 -msgid "End:" +#: ../../Zotlabs/Module/Affinity.php:76 +msgid "" +"If disabled the max and min levels will be reset to default after page reload" msgstr "" -#: ../../include/event.php:1106 -msgid "This event has been added to your calendar." +#: ../../Zotlabs/Module/Affinity.php:84 +msgid "Affinity Tool Settings" msgstr "" -#: ../../include/event.php:1337 -msgid "Not specified" +#: ../../Zotlabs/Module/Common.php:14 +msgid "No channel." msgstr "" -#: ../../include/event.php:1338 -msgid "Needs Action" +#: ../../Zotlabs/Module/Common.php:45 +msgid "No connections in common." msgstr "" -#: ../../include/event.php:1339 -msgid "Completed" +#: ../../Zotlabs/Module/Common.php:65 +msgid "View Common Connections" msgstr "" -#: ../../include/event.php:1340 -msgid "In Process" +#: ../../Zotlabs/Module/Share.php:104 ../../Zotlabs/Lib/Activity.php:2133 +#, php-format +msgid "🔁 Repeated %1$s's %2$s" msgstr "" -#: ../../include/event.php:1341 -msgid "Cancelled" +#: ../../Zotlabs/Module/Share.php:120 +msgid "Post repeated" msgstr "" -#: ../../include/event.php:1422 ../../include/connections.php:734 -#: ../../Zotlabs/Module/Cdav.php:1381 ../../Zotlabs/Module/Profiles.php:794 -#: ../../Zotlabs/Module/Connedit.php:924 -msgid "Mobile" +#: ../../Zotlabs/Module/Editwebpage.php:139 +msgid "Page link" msgstr "" -#: ../../include/event.php:1423 ../../include/connections.php:735 -#: ../../Zotlabs/Module/Cdav.php:1382 ../../Zotlabs/Module/Profiles.php:795 -#: ../../Zotlabs/Module/Connedit.php:925 -msgid "Home" +#: ../../Zotlabs/Module/Editwebpage.php:166 +msgid "Edit Webpage" msgstr "" -#: ../../include/event.php:1424 ../../include/connections.php:736 -msgid "Home, Voice" +#: ../../Zotlabs/Module/Profile.php:93 +msgid "vcard" msgstr "" -#: ../../include/event.php:1425 ../../include/connections.php:737 -msgid "Home, Fax" +#: ../../Zotlabs/Module/Article_edit.php:127 +msgid "Edit Article" msgstr "" -#: ../../include/event.php:1426 ../../include/connections.php:738 -#: ../../Zotlabs/Module/Cdav.php:1383 ../../Zotlabs/Module/Profiles.php:796 -#: ../../Zotlabs/Module/Connedit.php:926 -msgid "Work" +#: ../../Zotlabs/Module/Rmagic.php:46 +msgid "Authentication failed." msgstr "" -#: ../../include/event.php:1427 ../../include/connections.php:739 -msgid "Work, Voice" +#: ../../Zotlabs/Module/Rmagic.php:96 ../../include/channel.php:2597 +#: ../../boot.php:1706 +msgid "Remote Authentication" msgstr "" -#: ../../include/event.php:1428 ../../include/connections.php:740 -msgid "Work, Fax" +#: ../../Zotlabs/Module/Rmagic.php:97 ../../include/channel.php:2598 +msgid "Enter your channel address (e.g. channel@example.com)" msgstr "" -#: ../../include/event.php:1429 ../../include/event.php:1436 -#: ../../include/selectors.php:60 ../../include/selectors.php:77 -#: ../../include/selectors.php:115 ../../include/selectors.php:151 -#: ../../include/connections.php:741 ../../include/connections.php:748 -#: ../../Zotlabs/Module/Cdav.php:1384 ../../Zotlabs/Module/Profiles.php:797 -#: ../../Zotlabs/Module/Connedit.php:927 -#: ../../Zotlabs/Access/PermissionRoles.php:310 -msgid "Other" +#: ../../Zotlabs/Module/Rmagic.php:98 ../../include/channel.php:2599 +msgid "Authenticate" msgstr "" -#: ../../include/features.php:55 ../../Zotlabs/Module/Admin/Features.php:55 -#: ../../Zotlabs/Module/Admin/Features.php:56 -#: ../../Zotlabs/Module/Settings/Features.php:38 -msgid "Off" +#: ../../Zotlabs/Module/Attach.php:67 +msgid "Item not available." msgstr "" -#: ../../include/features.php:55 ../../Zotlabs/Module/Admin/Features.php:55 -#: ../../Zotlabs/Module/Admin/Features.php:56 -#: ../../Zotlabs/Module/Settings/Features.php:38 -msgid "On" +#: ../../Zotlabs/Module/Pconfig.php:32 ../../Zotlabs/Module/Pconfig.php:68 +msgid "This setting requires special processing and editing has been blocked." msgstr "" -#: ../../include/features.php:82 ../../include/nav.php:463 -#: ../../include/nav.php:466 ../../Zotlabs/Lib/Apps.php:346 -msgid "Calendar" +#: ../../Zotlabs/Module/Pconfig.php:57 +msgid "Configuration Editor" msgstr "" -#: ../../include/features.php:86 -msgid "Start calendar week on Monday" +#: ../../Zotlabs/Module/Pconfig.php:58 +msgid "" +"Warning: Changing some settings could render your channel inoperable. Please " +"leave this page unless you are comfortable with and knowledgeable about how " +"to correctly use this feature." msgstr "" -#: ../../include/features.php:87 -msgid "Default is Sunday" -msgstr "" - -#: ../../include/features.php:94 -msgid "Event Timezone Selection" +#: ../../Zotlabs/Module/Randprof.php:29 +msgid "Random Channel App" msgstr "" -#: ../../include/features.php:95 -msgid "Allow event creation in timezones other than your own." +#: ../../Zotlabs/Module/Randprof.php:30 +msgid "Visit a random channel in the $Projectname network" msgstr "" -#: ../../include/features.php:104 ../../Zotlabs/Lib/Apps.php:343 -msgid "Channel Home" +#: ../../Zotlabs/Module/Admin/Themes.php:26 +msgid "Theme settings updated." msgstr "" -#: ../../include/features.php:108 -msgid "Search by Date" +#: ../../Zotlabs/Module/Admin/Themes.php:61 +msgid "No themes found." msgstr "" -#: ../../include/features.php:109 -msgid "Ability to select posts by date ranges" +#: ../../Zotlabs/Module/Admin/Themes.php:95 +#: ../../Zotlabs/Module/Admin/Addons.php:311 +msgid "Disable" msgstr "" -#: ../../include/features.php:116 -msgid "Tag Cloud" +#: ../../Zotlabs/Module/Admin/Themes.php:97 +#: ../../Zotlabs/Module/Admin/Addons.php:314 +msgid "Enable" msgstr "" -#: ../../include/features.php:117 -msgid "Provide a personal tag cloud on your channel page" +#: ../../Zotlabs/Module/Admin/Themes.php:116 +msgid "Screenshot" msgstr "" -#: ../../include/features.php:124 ../../include/features.php:359 -msgid "Use blog/list mode" +#: ../../Zotlabs/Module/Admin/Themes.php:123 +#: ../../Zotlabs/Module/Admin/Themes.php:157 ../../Zotlabs/Widget/Admin.php:28 +msgid "Themes" msgstr "" -#: ../../include/features.php:125 ../../include/features.php:360 -msgid "Comments will be displayed separately" +#: ../../Zotlabs/Module/Admin/Themes.php:124 +#: ../../Zotlabs/Module/Admin/Addons.php:344 +msgid "Toggle" msgstr "" -#: ../../include/features.php:137 -msgid "Connection Filtering" +#: ../../Zotlabs/Module/Admin/Themes.php:125 +#: ../../Zotlabs/Module/Admin/Addons.php:345 ../../Zotlabs/Lib/Apps.php:339 +#: ../../Zotlabs/Widget/Settings_menu.php:61 +#: ../../Zotlabs/Widget/Newmember.php:53 ../../include/nav.php:103 +msgid "Settings" msgstr "" -#: ../../include/features.php:138 -msgid "Filter incoming posts from connections based on keywords/content" +#: ../../Zotlabs/Module/Admin/Themes.php:134 +#: ../../Zotlabs/Module/Admin/Addons.php:352 +msgid "Author: " msgstr "" -#: ../../include/features.php:146 -msgid "Conversation" +#: ../../Zotlabs/Module/Admin/Themes.php:135 +#: ../../Zotlabs/Module/Admin/Addons.php:353 +msgid "Maintainer: " msgstr "" -#: ../../include/features.php:158 -msgid "Emoji Reactions" +#: ../../Zotlabs/Module/Admin/Themes.php:162 +msgid "[Experimental]" msgstr "" -#: ../../include/features.php:159 -msgid "Add emoji reaction ability to posts" +#: ../../Zotlabs/Module/Admin/Themes.php:163 +msgid "[Unsupported]" msgstr "" -#: ../../include/features.php:166 -msgid "Dislike Posts" +#: ../../Zotlabs/Module/Admin/Security.php:89 +msgid "" +"By default, unfiltered HTML is allowed in embedded media. This is inherently " +"insecure." msgstr "" -#: ../../include/features.php:167 -msgid "Ability to dislike posts/comments" +#: ../../Zotlabs/Module/Admin/Security.php:92 +msgid "" +"The recommended setting is to only allow unfiltered HTML from the following " +"sites:" msgstr "" -#: ../../include/features.php:174 -msgid "Star Posts" +#: ../../Zotlabs/Module/Admin/Security.php:93 +msgid "" +"https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/" +"
      https://vimeo.com/
      https://soundcloud.com/
      " msgstr "" -#: ../../include/features.php:175 -msgid "Ability to mark special posts with a star indicator" +#: ../../Zotlabs/Module/Admin/Security.php:94 +msgid "" +"All other embedded content will be filtered, unless " +"embedded content from that site is explicitly blocked." msgstr "" -#: ../../include/features.php:182 -msgid "Reply on comment" +#: ../../Zotlabs/Module/Admin/Security.php:99 ../../Zotlabs/Widget/Admin.php:25 +msgid "Security" msgstr "" -#: ../../include/features.php:183 -msgid "Ability to reply on selected comment" +#: ../../Zotlabs/Module/Admin/Security.php:101 +msgid "Block public" msgstr "" -#: ../../include/features.php:192 ../../Zotlabs/Lib/Apps.php:347 -msgid "Directory" +#: ../../Zotlabs/Module/Admin/Security.php:101 +msgid "" +"Check to block public access to all otherwise public personal pages on this " +"site unless you are currently authenticated." msgstr "" -#: ../../include/features.php:196 -msgid "Advanced Directory Search" +#: ../../Zotlabs/Module/Admin/Security.php:102 +msgid "Provide a cloud root directory" msgstr "" -#: ../../include/features.php:197 -msgid "Allows creation of complex directory search queries" +#: ../../Zotlabs/Module/Admin/Security.php:102 +msgid "" +"The cloud root directory lists all channel names which provide public files" msgstr "" -#: ../../include/features.php:206 -msgid "Editor" +#: ../../Zotlabs/Module/Admin/Security.php:103 +msgid "Show total disk space available to cloud uploads" msgstr "" -#: ../../include/features.php:210 -msgid "Post Categories" +#: ../../Zotlabs/Module/Admin/Security.php:104 +msgid "Set \"Transport Security\" HTTP header" msgstr "" -#: ../../include/features.php:211 -msgid "Add categories to your posts" +#: ../../Zotlabs/Module/Admin/Security.php:105 +msgid "Set \"Content Security Policy\" HTTP header" msgstr "" -#: ../../include/features.php:219 -msgid "Large Photos" +#: ../../Zotlabs/Module/Admin/Security.php:106 +msgid "Allowed email domains" msgstr "" -#: ../../include/features.php:220 +#: ../../Zotlabs/Module/Admin/Security.php:106 msgid "" -"Include large (1024px) photo thumbnails in posts. If not enabled, use small " -"(640px) photo thumbnails" +"Comma separated list of domains which are allowed in email addresses for " +"registrations to this site. Wildcards are accepted. Empty to allow any " +"domains" msgstr "" -#: ../../include/features.php:227 -msgid "Even More Encryption" +#: ../../Zotlabs/Module/Admin/Security.php:107 +msgid "Not allowed email domains" msgstr "" -#: ../../include/features.php:228 +#: ../../Zotlabs/Module/Admin/Security.php:107 msgid "" -"Allow optional encryption of content end-to-end with a shared secret key" +"Comma separated list of domains which are not allowed in email addresses for " +"registrations to this site. Wildcards are accepted. Empty to allow any " +"domains, unless allowed domains have been defined." msgstr "" -#: ../../include/features.php:235 -msgid "Disable Comments" +#: ../../Zotlabs/Module/Admin/Security.php:108 +msgid "Allow communications only from these sites" msgstr "" -#: ../../include/features.php:236 -msgid "Provide the option to disable comments for a post" +#: ../../Zotlabs/Module/Admin/Security.php:108 +msgid "" +"One site per line. Leave empty to allow communication from anywhere by " +"default" msgstr "" -#: ../../include/features.php:243 -msgid "Delayed Posting" +#: ../../Zotlabs/Module/Admin/Security.php:109 +msgid "Block communications from these sites" msgstr "" -#: ../../include/features.php:244 -msgid "Allow posts to be published at a later date" +#: ../../Zotlabs/Module/Admin/Security.php:110 +msgid "Allow communications only from these channels" msgstr "" -#: ../../include/features.php:251 -msgid "Content Expiration" +#: ../../Zotlabs/Module/Admin/Security.php:110 +msgid "" +"One channel (hash) per line. Leave empty to allow from any channel by default" msgstr "" -#: ../../include/features.php:252 -msgid "Remove posts/comments and/or private messages at a future time" +#: ../../Zotlabs/Module/Admin/Security.php:111 +msgid "Block communications from these channels" msgstr "" -#: ../../include/features.php:259 -msgid "Suppress Duplicate Posts/Comments" +#: ../../Zotlabs/Module/Admin/Security.php:112 +msgid "Only allow embeds from secure (SSL) websites and links." msgstr "" -#: ../../include/features.php:260 -msgid "" -"Prevent posts with identical content to be published with less than two " -"minutes in between submissions." +#: ../../Zotlabs/Module/Admin/Security.php:113 +msgid "Allow unfiltered embedded HTML content only from these domains" msgstr "" -#: ../../include/features.php:267 -msgid "Auto-save drafts of posts and comments" +#: ../../Zotlabs/Module/Admin/Security.php:113 +msgid "One site per line. By default embedded content is filtered." msgstr "" -#: ../../include/features.php:268 -msgid "" -"Automatically saves post and comment drafts in local browser storage to help " -"prevent accidental loss of compositions" +#: ../../Zotlabs/Module/Admin/Security.php:114 +msgid "Block embedded HTML from these domains" msgstr "" -#: ../../include/features.php:277 -msgid "Manage" +#: ../../Zotlabs/Module/Admin/Security.php:115 +msgid "Allow SVG thumbnails in file browser" msgstr "" -#: ../../include/features.php:281 -msgid "Navigation Channel Select" +#: ../../Zotlabs/Module/Admin/Security.php:115 +msgid "WARNING: SVG images may contain malicious code." msgstr "" -#: ../../include/features.php:282 -msgid "Change channels directly from within the navigation dropdown menu" +#: ../../Zotlabs/Module/Admin/Security.php:116 +msgid "Allow embedded (inline) PDF files" msgstr "" -#: ../../include/features.php:291 ../../Zotlabs/Module/Connections.php:332 -msgid "Network" -msgstr "" +#: ../../Zotlabs/Module/Admin/Accounts.php:37 +#, php-format +msgid "%s account blocked/unblocked" +msgid_plural "%s account blocked/unblocked" +msgstr[0] "" +msgstr[1] "" -#: ../../include/features.php:295 -msgid "Events Filter" -msgstr "" +#: ../../Zotlabs/Module/Admin/Accounts.php:44 +#, php-format +msgid "%s account deleted" +msgid_plural "%s accounts deleted" +msgstr[0] "" +msgstr[1] "" -#: ../../include/features.php:296 -msgid "Ability to display only events" +#: ../../Zotlabs/Module/Admin/Accounts.php:80 +msgid "Account not found" msgstr "" -#: ../../include/features.php:303 -msgid "Polls Filter" +#: ../../Zotlabs/Module/Admin/Accounts.php:91 ../../include/channel.php:2757 +#, php-format +msgid "Account '%s' deleted" msgstr "" -#: ../../include/features.php:304 -msgid "Ability to display only polls" +#: ../../Zotlabs/Module/Admin/Accounts.php:99 +#, php-format +msgid "Account '%s' blocked" msgstr "" -#: ../../include/features.php:311 ../../Zotlabs/Widget/Savedsearch.php:83 -msgid "Saved Searches" +#: ../../Zotlabs/Module/Admin/Accounts.php:107 +#, php-format +msgid "Account '%s' unblocked" msgstr "" -#: ../../include/features.php:312 -msgid "Save search terms for re-use" +#: ../../Zotlabs/Module/Admin/Accounts.php:169 +#: ../../Zotlabs/Module/Admin/Channels.php:148 +msgid "select all" msgstr "" -#: ../../include/features.php:319 ../../include/contact_widgets.php:53 -#: ../../Zotlabs/Widget/Activity_filter.php:179 -#: ../../Zotlabs/Widget/Filer.php:28 -msgid "Saved Folders" +#: ../../Zotlabs/Module/Admin/Accounts.php:170 +msgid "Registrations waiting for confirm" msgstr "" -#: ../../include/features.php:320 -msgid "Ability to file posts under folders" +#: ../../Zotlabs/Module/Admin/Accounts.php:171 +msgid "Request date" msgstr "" -#: ../../include/features.php:327 -msgid "Alternate Stream Order" +#: ../../Zotlabs/Module/Admin/Accounts.php:172 +msgid "No registrations." msgstr "" -#: ../../include/features.php:328 -msgid "" -"Ability to order the stream by last post date, last comment date or " -"unthreaded activities" +#: ../../Zotlabs/Module/Admin/Accounts.php:182 +msgid "ID" msgstr "" -#: ../../include/features.php:335 -msgid "Contact Filter" +#: ../../Zotlabs/Module/Admin/Accounts.php:184 +msgid "All Channels" msgstr "" -#: ../../include/features.php:336 -msgid "Ability to display only posts of a selected contact" +#: ../../Zotlabs/Module/Admin/Accounts.php:185 +msgid "Register date" msgstr "" -#: ../../include/features.php:343 -msgid "Forum Filter" +#: ../../Zotlabs/Module/Admin/Accounts.php:186 +msgid "Last login" msgstr "" -#: ../../include/features.php:344 -msgid "Ability to display only posts of a specific forum" +#: ../../Zotlabs/Module/Admin/Accounts.php:187 +msgid "Expires" msgstr "" -#: ../../include/features.php:351 -msgid "Personal Posts Filter" +#: ../../Zotlabs/Module/Admin/Accounts.php:188 +msgid "Service Class" msgstr "" -#: ../../include/features.php:352 -msgid "Ability to display only posts that you've interacted on" +#: ../../Zotlabs/Module/Admin/Accounts.php:190 +msgid "" +"Selected accounts will be deleted!\\n\\nEverything these accounts had posted " +"on this site will be permanently deleted!\\n\\nAre you sure?" msgstr "" -#: ../../include/features.php:369 ../../include/nav.php:444 -#: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:345 -msgid "Photos" +#: ../../Zotlabs/Module/Admin/Accounts.php:191 +msgid "" +"The account {0} will be deleted!\\n\\nEverything this account has posted on " +"this site will be permanently deleted!\\n\\nAre you sure?" msgstr "" -#: ../../include/features.php:373 -msgid "Photo Location" +#: ../../Zotlabs/Module/Admin/Features.php:55 +#: ../../Zotlabs/Module/Admin/Features.php:56 +#: ../../Zotlabs/Module/Settings/Features.php:38 ../../include/features.php:55 +msgid "Off" msgstr "" -#: ../../include/features.php:374 -msgid "If location data is available on uploaded photos, link this to a map." +#: ../../Zotlabs/Module/Admin/Features.php:55 +#: ../../Zotlabs/Module/Admin/Features.php:56 +#: ../../Zotlabs/Module/Settings/Features.php:38 ../../include/features.php:55 +msgid "On" msgstr "" -#: ../../include/features.php:383 ../../Zotlabs/Lib/Apps.php:363 -msgid "Profiles" +#: ../../Zotlabs/Module/Admin/Features.php:56 +#, php-format +msgid "Lock feature %s" msgstr "" -#: ../../include/features.php:387 -msgid "Advanced Profiles" +#: ../../Zotlabs/Module/Admin/Features.php:64 +msgid "Manage Additional Features" msgstr "" -#: ../../include/features.php:388 -msgid "Additional profile sections and selections" +#: ../../Zotlabs/Module/Admin/Queue.php:35 +msgid "Queue Statistics" msgstr "" -#: ../../include/features.php:395 -msgid "Profile Import/Export" +#: ../../Zotlabs/Module/Admin/Queue.php:36 +msgid "Total Entries" msgstr "" -#: ../../include/features.php:396 -msgid "Save and load profile details across sites/channels" +#: ../../Zotlabs/Module/Admin/Queue.php:37 +msgid "Priority" msgstr "" -#: ../../include/features.php:403 -msgid "Multiple Profiles" +#: ../../Zotlabs/Module/Admin/Queue.php:38 +msgid "Destination URL" msgstr "" -#: ../../include/features.php:404 -msgid "Ability to create multiple profiles" +#: ../../Zotlabs/Module/Admin/Queue.php:39 +msgid "Mark hub permanently offline" msgstr "" -#: ../../include/security.php:609 -msgid "" -"The form security token was not correct. This probably happened because the " -"form has been opened for too long (>3 hours) before submitting it." +#: ../../Zotlabs/Module/Admin/Queue.php:40 +msgid "Empty queue for this hub" msgstr "" -#: ../../include/js_strings.php:5 -msgid "Delete this item?" +#: ../../Zotlabs/Module/Admin/Queue.php:41 +msgid "Last known contact" msgstr "" -#: ../../include/js_strings.php:6 ../../Zotlabs/Module/Photos.php:1097 -#: ../../Zotlabs/Module/Photos.php:1215 ../../Zotlabs/Lib/ThreadItem.php:824 -msgid "Comment" +#: ../../Zotlabs/Module/Admin/Dbsync.php:19 +#: ../../Zotlabs/Module/Admin/Dbsync.php:59 +msgid "Update has been marked successful" msgstr "" -#: ../../include/js_strings.php:7 ../../Zotlabs/Lib/ThreadItem.php:533 +#: ../../Zotlabs/Module/Admin/Dbsync.php:32 #, php-format -msgid "%s show all" +msgid "Verification of update %s failed. Check system logs." msgstr "" -#: ../../include/js_strings.php:8 +#: ../../Zotlabs/Module/Admin/Dbsync.php:35 +#: ../../Zotlabs/Module/Admin/Dbsync.php:74 #, php-format -msgid "%s show less" +msgid "Update %s was successfully applied." msgstr "" -#: ../../include/js_strings.php:9 +#: ../../Zotlabs/Module/Admin/Dbsync.php:39 #, php-format -msgid "%s expand" +msgid "Verifying update %s did not return a status. Unknown if it succeeded." msgstr "" -#: ../../include/js_strings.php:10 +#: ../../Zotlabs/Module/Admin/Dbsync.php:42 #, php-format -msgid "%s collapse" +msgid "Update %s does not contain a verification function." msgstr "" -#: ../../include/js_strings.php:11 -msgid "Password too short" +#: ../../Zotlabs/Module/Admin/Dbsync.php:46 +#: ../../Zotlabs/Module/Admin/Dbsync.php:81 +#, php-format +msgid "Update function %s could not be found." msgstr "" -#: ../../include/js_strings.php:12 -msgid "Passwords do not match" +#: ../../Zotlabs/Module/Admin/Dbsync.php:71 +#, php-format +msgid "Executing update procedure %s failed. Check system logs." msgstr "" -#: ../../include/js_strings.php:13 -msgid "everybody" +#: ../../Zotlabs/Module/Admin/Dbsync.php:78 +#, php-format +msgid "" +"Update %s did not return a status. It cannot be determined if it was " +"successful." msgstr "" -#: ../../include/js_strings.php:14 -msgid "Secret Passphrase" +#: ../../Zotlabs/Module/Admin/Dbsync.php:99 +msgid "Failed Updates" msgstr "" -#: ../../include/js_strings.php:15 -msgid "Passphrase hint" +#: ../../Zotlabs/Module/Admin/Dbsync.php:101 +msgid "Mark success (if update was manually applied)" msgstr "" -#: ../../include/js_strings.php:16 -msgid "Notice: Permissions have changed but have not yet been submitted." +#: ../../Zotlabs/Module/Admin/Dbsync.php:102 +msgid "Attempt to verify this update if a verification procedure exists" msgstr "" -#: ../../include/js_strings.php:17 -msgid "close all" +#: ../../Zotlabs/Module/Admin/Dbsync.php:103 +msgid "Attempt to execute this update step automatically" msgstr "" -#: ../../include/js_strings.php:18 -msgid "Nothing new here" +#: ../../Zotlabs/Module/Admin/Dbsync.php:108 +msgid "No failed updates." msgstr "" -#: ../../include/js_strings.php:19 -msgid "Rate This Channel (this is public)" +#: ../../Zotlabs/Module/Admin/Channels.php:31 +#, php-format +msgid "%s channel censored/uncensored" +msgid_plural "%s channels censored/uncensored" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Channels.php:40 +#, php-format +msgid "%s channel code allowed/disallowed" +msgid_plural "%s channels code allowed/disallowed" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Channels.php:46 +#, php-format +msgid "%s channel deleted" +msgid_plural "%s channels deleted" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Channels.php:65 +msgid "Channel not found" msgstr "" -#: ../../include/js_strings.php:20 ../../Zotlabs/Module/Rate.php:155 -#: ../../Zotlabs/Module/Connedit.php:879 -msgid "Rating" +#: ../../Zotlabs/Module/Admin/Channels.php:75 +#, php-format +msgid "Channel '%s' deleted" msgstr "" -#: ../../include/js_strings.php:21 -msgid "Describe (optional)" +#: ../../Zotlabs/Module/Admin/Channels.php:87 +#, php-format +msgid "Channel '%s' censored" msgstr "" -#: ../../include/js_strings.php:23 -msgid "Please enter a link URL" +#: ../../Zotlabs/Module/Admin/Channels.php:87 +#, php-format +msgid "Channel '%s' uncensored" msgstr "" -#: ../../include/js_strings.php:24 -msgid "Unsaved changes. Are you sure you wish to leave this page?" +#: ../../Zotlabs/Module/Admin/Channels.php:98 +#, php-format +msgid "Channel '%s' code allowed" msgstr "" -#: ../../include/js_strings.php:25 ../../Zotlabs/Module/Pubsites.php:52 -#: ../../Zotlabs/Module/Cdav.php:1015 ../../Zotlabs/Module/Events.php:483 -#: ../../Zotlabs/Module/Profiles.php:511 ../../Zotlabs/Module/Profiles.php:736 -#: ../../Zotlabs/Module/Locs.php:128 -msgid "Location" +#: ../../Zotlabs/Module/Admin/Channels.php:98 +#, php-format +msgid "Channel '%s' code disallowed" msgstr "" -#: ../../include/js_strings.php:26 -msgid "lovely" +#: ../../Zotlabs/Module/Admin/Channels.php:150 +#: ../../Zotlabs/Module/Directory.php:362 +msgid "Censor" msgstr "" -#: ../../include/js_strings.php:27 -msgid "wonderful" +#: ../../Zotlabs/Module/Admin/Channels.php:151 +#: ../../Zotlabs/Module/Directory.php:362 +msgid "Uncensor" msgstr "" -#: ../../include/js_strings.php:28 -msgid "fantastic" +#: ../../Zotlabs/Module/Admin/Channels.php:152 +msgid "Allow Code" msgstr "" -#: ../../include/js_strings.php:29 -msgid "great" +#: ../../Zotlabs/Module/Admin/Channels.php:153 +msgid "Disallow Code" msgstr "" -#: ../../include/js_strings.php:30 -msgid "" -"Your chosen nickname was either already taken or not valid. Please use our " -"suggestion (" +#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:421 +msgid "Channel" msgstr "" -#: ../../include/js_strings.php:31 -msgid ") or enter a new one." +#: ../../Zotlabs/Module/Admin/Channels.php:158 +msgid "UID" msgstr "" -#: ../../include/js_strings.php:32 -msgid "Thank you, this nickname is valid." +#: ../../Zotlabs/Module/Admin/Channels.php:162 +msgid "" +"Selected channels will be deleted!\\n\\nEverything that was posted in these " +"channels on this site will be permanently deleted!\\n\\nAre you sure?" msgstr "" -#: ../../include/js_strings.php:33 -msgid "A channel name is required." +#: ../../Zotlabs/Module/Admin/Channels.php:163 +msgid "" +"The channel {0} will be deleted!\\n\\nEverything that was posted in this " +"channel on this site will be permanently deleted!\\n\\nAre you sure?" msgstr "" -#: ../../include/js_strings.php:34 -msgid "This is a " +#: ../../Zotlabs/Module/Admin/Logs.php:28 +msgid "Log settings updated." msgstr "" -#: ../../include/js_strings.php:35 -msgid " channel name" +#: ../../Zotlabs/Module/Admin/Logs.php:83 ../../Zotlabs/Widget/Admin.php:48 +#: ../../Zotlabs/Widget/Admin.php:58 +msgid "Logs" msgstr "" -#: ../../include/js_strings.php:36 -msgid "Back to reply" +#: ../../Zotlabs/Module/Admin/Logs.php:85 +msgid "Clear" msgstr "" -#: ../../include/js_strings.php:37 -msgid "Pinned" +#: ../../Zotlabs/Module/Admin/Logs.php:91 +msgid "Debugging" msgstr "" -#: ../../include/js_strings.php:38 ../../Zotlabs/Lib/ThreadItem.php:471 -msgid "Pin to the top" +#: ../../Zotlabs/Module/Admin/Logs.php:92 +msgid "Log file" msgstr "" -#: ../../include/js_strings.php:39 ../../Zotlabs/Widget/Pinned.php:157 -#: ../../Zotlabs/Lib/ThreadItem.php:471 -msgid "Unpin from the top" +#: ../../Zotlabs/Module/Admin/Logs.php:92 +msgid "" +"Must be writable by web server. Relative to your top-level webserver " +"directory." msgstr "" -#: ../../include/js_strings.php:45 -#, php-format -msgid "%d minutes" -msgid_plural "%d minutes" -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Admin/Logs.php:93 +msgid "Log level" +msgstr "" -#: ../../include/js_strings.php:46 -#, php-format -msgid "about %d hours" -msgid_plural "about %d hours" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/js_strings.php:47 -#, php-format -msgid "%d days" -msgid_plural "%d days" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/js_strings.php:48 -#, php-format -msgid "%d months" -msgid_plural "%d months" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/js_strings.php:49 +#: ../../Zotlabs/Module/Admin/Account_edit.php:29 #, php-format -msgid "%d years" -msgid_plural "%d years" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/js_strings.php:54 -msgid "timeago.prefixAgo" +msgid "Password changed for account %d." msgstr "" -#: ../../include/js_strings.php:55 -msgid "timeago.prefixFromNow" +#: ../../Zotlabs/Module/Admin/Account_edit.php:46 +msgid "Account settings updated." msgstr "" -#: ../../include/js_strings.php:56 -msgid "timeago.suffixAgo" +#: ../../Zotlabs/Module/Admin/Account_edit.php:61 +msgid "Account not found." msgstr "" -#: ../../include/js_strings.php:57 -msgid "timeago.suffixFromNow" +#: ../../Zotlabs/Module/Admin/Account_edit.php:68 +msgid "Account Edit" msgstr "" -#: ../../include/js_strings.php:60 -msgid "less than a minute" +#: ../../Zotlabs/Module/Admin/Account_edit.php:69 +msgid "New Password" msgstr "" -#: ../../include/js_strings.php:61 -msgid "about a minute" +#: ../../Zotlabs/Module/Admin/Account_edit.php:70 +msgid "New Password again" msgstr "" -#: ../../include/js_strings.php:63 -msgid "about an hour" +#: ../../Zotlabs/Module/Admin/Account_edit.php:71 +msgid "Account language (for emails)" msgstr "" -#: ../../include/js_strings.php:65 -msgid "a day" +#: ../../Zotlabs/Module/Admin/Account_edit.php:72 +msgid "Service class" msgstr "" -#: ../../include/js_strings.php:67 -msgid "about a month" +#: ../../Zotlabs/Module/Admin/Addons.php:290 +#, php-format +msgid "Plugin %s disabled." msgstr "" -#: ../../include/js_strings.php:69 -msgid "about a year" +#: ../../Zotlabs/Module/Admin/Addons.php:295 +#, php-format +msgid "Plugin %s enabled." msgstr "" -#: ../../include/js_strings.php:71 -msgid " " +#: ../../Zotlabs/Module/Admin/Addons.php:343 +#: ../../Zotlabs/Module/Admin/Addons.php:441 ../../Zotlabs/Widget/Admin.php:27 +msgid "Addons" msgstr "" -#: ../../include/js_strings.php:72 -msgid "timeago.numbers" +#: ../../Zotlabs/Module/Admin/Addons.php:354 +msgid "Minimum project version: " msgstr "" -#: ../../include/js_strings.php:78 -msgctxt "long" -msgid "May" +#: ../../Zotlabs/Module/Admin/Addons.php:355 +msgid "Maximum project version: " msgstr "" -#: ../../include/js_strings.php:86 -msgid "Jan" +#: ../../Zotlabs/Module/Admin/Addons.php:356 +msgid "Minimum PHP version: " msgstr "" -#: ../../include/js_strings.php:87 -msgid "Feb" +#: ../../Zotlabs/Module/Admin/Addons.php:357 +msgid "Compatible Server Roles: " msgstr "" -#: ../../include/js_strings.php:88 -msgid "Mar" +#: ../../Zotlabs/Module/Admin/Addons.php:358 +msgid "Requires: " msgstr "" -#: ../../include/js_strings.php:89 -msgid "Apr" +#: ../../Zotlabs/Module/Admin/Addons.php:359 +#: ../../Zotlabs/Module/Admin/Addons.php:446 +msgid "Disabled - version incompatibility" msgstr "" -#: ../../include/js_strings.php:90 -msgctxt "short" -msgid "May" +#: ../../Zotlabs/Module/Admin/Addons.php:415 +msgid "Enter the public git repository URL of the addon repo." msgstr "" -#: ../../include/js_strings.php:91 -msgid "Jun" +#: ../../Zotlabs/Module/Admin/Addons.php:416 +msgid "Addon repo git URL" msgstr "" -#: ../../include/js_strings.php:92 -msgid "Jul" +#: ../../Zotlabs/Module/Admin/Addons.php:417 +msgid "Custom repo name" msgstr "" -#: ../../include/js_strings.php:93 -msgid "Aug" +#: ../../Zotlabs/Module/Admin/Addons.php:417 +msgid "(optional)" msgstr "" -#: ../../include/js_strings.php:94 -msgid "Sep" +#: ../../Zotlabs/Module/Admin/Addons.php:418 +msgid "Download Addon Repo" msgstr "" -#: ../../include/js_strings.php:95 -msgid "Oct" +#: ../../Zotlabs/Module/Admin/Addons.php:425 +msgid "Install new repo" msgstr "" -#: ../../include/js_strings.php:96 -msgid "Nov" +#: ../../Zotlabs/Module/Admin/Addons.php:426 ../../Zotlabs/Lib/Apps.php:536 +msgid "Install" msgstr "" -#: ../../include/js_strings.php:97 -msgid "Dec" +#: ../../Zotlabs/Module/Admin/Addons.php:449 +msgid "Manage Repos" msgstr "" -#: ../../include/js_strings.php:105 -msgid "Sun" +#: ../../Zotlabs/Module/Admin/Addons.php:450 +msgid "Installed Addon Repositories" msgstr "" -#: ../../include/js_strings.php:106 -msgid "Mon" +#: ../../Zotlabs/Module/Admin/Addons.php:451 +msgid "Install a New Addon Repository" msgstr "" -#: ../../include/js_strings.php:107 -msgid "Tue" +#: ../../Zotlabs/Module/Admin/Addons.php:458 +msgid "Switch branch" msgstr "" -#: ../../include/js_strings.php:108 -msgid "Wed" +#: ../../Zotlabs/Module/Admin/Site.php:165 +msgid "Site settings updated." msgstr "" -#: ../../include/js_strings.php:109 -msgid "Thu" +#: ../../Zotlabs/Module/Admin/Site.php:191 ../../include/text.php:3381 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:335 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:359 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:435 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:459 +#: ../../view/theme/redbasic/php/config.php:15 +msgid "Default" msgstr "" -#: ../../include/js_strings.php:110 -msgid "Fri" +#: ../../Zotlabs/Module/Admin/Site.php:202 +#: ../../Zotlabs/Module/Settings/Display.php:118 +#, php-format +msgid "%s - (Incompatible)" msgstr "" -#: ../../include/js_strings.php:111 -msgid "Sat" +#: ../../Zotlabs/Module/Admin/Site.php:209 +msgid "mobile" msgstr "" -#: ../../include/js_strings.php:112 -msgctxt "calendar" -msgid "today" +#: ../../Zotlabs/Module/Admin/Site.php:211 +msgid "experimental" msgstr "" -#: ../../include/js_strings.php:113 -msgctxt "calendar" -msgid "month" +#: ../../Zotlabs/Module/Admin/Site.php:213 +msgid "unsupported" msgstr "" -#: ../../include/js_strings.php:114 -msgctxt "calendar" -msgid "week" +#: ../../Zotlabs/Module/Admin/Site.php:260 +msgid "Yes - with approval" msgstr "" -#: ../../include/js_strings.php:115 -msgctxt "calendar" -msgid "day" +#: ../../Zotlabs/Module/Admin/Site.php:266 +msgid "My site is not a public server" msgstr "" -#: ../../include/js_strings.php:116 -msgctxt "calendar" -msgid "All day" +#: ../../Zotlabs/Module/Admin/Site.php:267 +msgid "My site has paid access only" msgstr "" -#: ../../include/js_strings.php:119 -msgid "Please stand by while your download is being prepared." +#: ../../Zotlabs/Module/Admin/Site.php:268 +msgid "My site has free access only" msgstr "" -#: ../../include/help.php:80 -msgid "Help:" +#: ../../Zotlabs/Module/Admin/Site.php:269 +msgid "My site offers free accounts with optional paid upgrades" msgstr "" -#: ../../include/help.php:117 ../../include/help.php:125 -#: ../../include/nav.php:174 ../../include/nav.php:320 -#: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:348 -msgid "Help" +#: ../../Zotlabs/Module/Admin/Site.php:283 +msgid "Default permission role for new accounts" msgstr "" -#: ../../include/help.php:129 -msgid "Not Found" +#: ../../Zotlabs/Module/Admin/Site.php:283 +msgid "" +"This role will be used for the first channel created after registration." msgstr "" -#: ../../include/help.php:132 ../../Zotlabs/Module/Display.php:136 -#: ../../Zotlabs/Module/Display.php:153 ../../Zotlabs/Module/Display.php:173 -#: ../../Zotlabs/Module/Display.php:179 ../../Zotlabs/Module/Page.php:136 -#: ../../Zotlabs/Module/Block.php:77 ../../Zotlabs/Lib/NativeWikiPage.php:521 -#: ../../Zotlabs/Web/Router.php:185 -msgid "Page not found." +#: ../../Zotlabs/Module/Admin/Site.php:292 ../../Zotlabs/Widget/Admin.php:22 +msgid "Site" msgstr "" -#: ../../include/photos.php:151 -#, php-format -msgid "Image exceeds website size limit of %lu bytes" +#: ../../Zotlabs/Module/Admin/Site.php:294 +#: ../../Zotlabs/Module/Register.php:277 +msgid "Registration" msgstr "" -#: ../../include/photos.php:162 -msgid "Image file is empty." +#: ../../Zotlabs/Module/Admin/Site.php:295 +msgid "File upload" msgstr "" -#: ../../include/photos.php:196 ../../Zotlabs/Module/Profile_photo.php:261 -#: ../../Zotlabs/Module/Cover_photo.php:241 -msgid "Unable to process image" +#: ../../Zotlabs/Module/Admin/Site.php:296 +msgid "Policies" msgstr "" -#: ../../include/photos.php:324 -msgid "Photo storage failed." +#: ../../Zotlabs/Module/Admin/Site.php:297 ../../include/contact_widgets.php:16 +#: ../../include/acl_selectors.php:144 +msgid "Advanced" msgstr "" -#: ../../include/photos.php:373 -msgid "a new photo" +#: ../../Zotlabs/Module/Admin/Site.php:301 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:593 +msgid "Site name" msgstr "" -#: ../../include/photos.php:377 -#, php-format -msgctxt "photo_upload" -msgid "%1$s posted %2$s to %3$s" +#: ../../Zotlabs/Module/Admin/Site.php:303 +msgid "Banner/Logo" msgstr "" -#: ../../include/photos.php:666 ../../include/nav.php:447 -msgid "Photo Albums" +#: ../../Zotlabs/Module/Admin/Site.php:303 +msgid "Unfiltered HTML/CSS/JS is allowed" msgstr "" -#: ../../include/photos.php:667 ../../Zotlabs/Module/Photos.php:1348 -#: ../../Zotlabs/Module/Photos.php:1361 ../../Zotlabs/Module/Photos.php:1362 -msgid "Recent Photos" +#: ../../Zotlabs/Module/Admin/Site.php:304 +msgid "Administrator Information" msgstr "" -#: ../../include/photos.php:671 -msgid "Upload New Photos" +#: ../../Zotlabs/Module/Admin/Site.php:304 +msgid "" +"Contact information for site administrators. Displayed on siteinfo page. " +"BBCode can be used here" msgstr "" -#: ../../include/network.php:1731 ../../include/network.php:1732 -msgid "Friendica" +#: ../../Zotlabs/Module/Admin/Site.php:305 ../../Zotlabs/Module/Siteinfo.php:24 +msgid "Site Information" msgstr "" -#: ../../include/network.php:1733 -msgid "OStatus" +#: ../../Zotlabs/Module/Admin/Site.php:305 +msgid "" +"Publicly visible description of this site. Displayed on siteinfo page. " +"BBCode can be used here" msgstr "" -#: ../../include/network.php:1734 -msgid "GNU-Social" +#: ../../Zotlabs/Module/Admin/Site.php:306 +msgid "System language" msgstr "" -#: ../../include/network.php:1735 -msgid "RSS/Atom" +#: ../../Zotlabs/Module/Admin/Site.php:307 +msgid "System theme" msgstr "" -#: ../../include/network.php:1738 -msgid "Diaspora" +#: ../../Zotlabs/Module/Admin/Site.php:307 +msgid "" +"Default system theme - may be over-ridden by user profiles - change theme settings" msgstr "" -#: ../../include/network.php:1739 -msgid "Facebook" +#: ../../Zotlabs/Module/Admin/Site.php:310 +msgid "Allow Feeds as Connections" msgstr "" -#: ../../include/network.php:1740 -msgid "Zot" +#: ../../Zotlabs/Module/Admin/Site.php:310 +msgid "(Heavy system resource usage)" msgstr "" -#: ../../include/network.php:1741 -msgid "LinkedIn" +#: ../../Zotlabs/Module/Admin/Site.php:311 +msgid "Maximum image size" msgstr "" -#: ../../include/network.php:1742 -msgid "XMPP/IM" +#: ../../Zotlabs/Module/Admin/Site.php:311 +msgid "" +"Maximum size in bytes of uploaded images. Default is 0, which means no " +"limits." msgstr "" -#: ../../include/network.php:1743 -msgid "MySpace" +#: ../../Zotlabs/Module/Admin/Site.php:312 +msgid "Does this site allow new member registration?" msgstr "" -#: ../../include/activities.php:42 -msgid " and " +#: ../../Zotlabs/Module/Admin/Site.php:313 +msgid "Invitation only" msgstr "" -#: ../../include/activities.php:50 -msgid "public profile" +#: ../../Zotlabs/Module/Admin/Site.php:313 +msgid "" +"Only allow new member registrations with an invitation code. Above register " +"policy must be set to Yes." msgstr "" -#: ../../include/activities.php:59 -#, php-format -msgid "%1$s changed %2$s to “%3$s”" +#: ../../Zotlabs/Module/Admin/Site.php:314 +msgid "Minimum age" msgstr "" -#: ../../include/activities.php:60 -#, php-format -msgid "Visit %1$s's %2$s" +#: ../../Zotlabs/Module/Admin/Site.php:314 +msgid "Minimum age (in years) for who may register on this site." msgstr "" -#: ../../include/activities.php:63 -#, php-format -msgid "%1$s has an updated %2$s, changing %3$s." +#: ../../Zotlabs/Module/Admin/Site.php:315 +msgid "Which best describes the types of account offered by this hub?" msgstr "" -#: ../../include/contact_widgets.php:11 -#, php-format -msgid "%d invitation available" -msgid_plural "%d invitations available" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/contact_widgets.php:16 ../../include/acl_selectors.php:144 -#: ../../Zotlabs/Module/Admin/Site.php:297 -msgid "Advanced" +#: ../../Zotlabs/Module/Admin/Site.php:315 +msgid "This is displayed on the public server site list." msgstr "" -#: ../../include/contact_widgets.php:19 -msgid "Find Channels" +#: ../../Zotlabs/Module/Admin/Site.php:316 +msgid "Register text" msgstr "" -#: ../../include/contact_widgets.php:20 -msgid "Enter name or interest" +#: ../../Zotlabs/Module/Admin/Site.php:316 +msgid "Will be displayed prominently on the registration page." msgstr "" -#: ../../include/contact_widgets.php:21 -msgid "Connect/Follow" +#: ../../Zotlabs/Module/Admin/Site.php:318 +msgid "Site homepage to show visitors (default: login box)" msgstr "" -#: ../../include/contact_widgets.php:22 -msgid "Examples: Robert Morgenstein, Fishing" +#: ../../Zotlabs/Module/Admin/Site.php:318 +msgid "" +"example: 'pubstream' to show public stream, 'page/sys/home' to show a system " +"webpage called 'home' or 'include:home.html' to include a file." msgstr "" -#: ../../include/contact_widgets.php:23 ../../Zotlabs/Module/Directory.php:431 -#: ../../Zotlabs/Module/Directory.php:436 -#: ../../Zotlabs/Module/Connections.php:381 -msgid "Find" +#: ../../Zotlabs/Module/Admin/Site.php:319 +msgid "Preserve site homepage URL" msgstr "" -#: ../../include/contact_widgets.php:24 ../../Zotlabs/Module/Directory.php:435 -#: ../../Zotlabs/Module/Suggest.php:79 -msgid "Channel Suggestions" +#: ../../Zotlabs/Module/Admin/Site.php:319 +msgid "" +"Present the site homepage in a frame at the original location instead of " +"redirecting" msgstr "" -#: ../../include/contact_widgets.php:26 -msgid "Random Profile" +#: ../../Zotlabs/Module/Admin/Site.php:320 +msgid "Accounts abandoned after x days" msgstr "" -#: ../../include/contact_widgets.php:27 -msgid "Invite Friends" +#: ../../Zotlabs/Module/Admin/Site.php:320 +msgid "" +"Will not waste system resources polling external sites for abandonded " +"accounts. Enter 0 for no time limit." msgstr "" -#: ../../include/contact_widgets.php:29 -msgid "Advanced example: name=fred and country=iceland" +#: ../../Zotlabs/Module/Admin/Site.php:321 +msgid "Allowed friend domains" msgstr "" -#: ../../include/contact_widgets.php:56 ../../include/contact_widgets.php:111 -#: ../../include/contact_widgets.php:155 ../../include/contact_widgets.php:200 -#: ../../include/contact_widgets.php:235 -#: ../../Zotlabs/Widget/Appcategories.php:46 ../../Zotlabs/Widget/Filer.php:31 -msgid "Everything" +#: ../../Zotlabs/Module/Admin/Site.php:321 +msgid "" +"Comma separated list of domains which are allowed to establish friendships " +"with this site. Wildcards are accepted. Empty to allow any domains" msgstr "" -#: ../../include/contact_widgets.php:108 ../../include/contact_widgets.php:152 -#: ../../include/contact_widgets.php:197 ../../include/contact_widgets.php:232 -#: ../../include/taxonomy.php:418 ../../include/taxonomy.php:500 -#: ../../include/taxonomy.php:520 ../../include/taxonomy.php:541 -#: ../../Zotlabs/Widget/Appcategories.php:43 ../../Zotlabs/Module/Cdav.php:1070 -#: ../../Zotlabs/Storage/Browser.php:293 ../../Zotlabs/Storage/Browser.php:381 -#: ../../Zotlabs/Storage/Browser.php:396 -msgid "Categories" +#: ../../Zotlabs/Module/Admin/Site.php:322 +msgid "Verify Email Addresses" msgstr "" -#: ../../include/contact_widgets.php:265 -msgid "Common Connections" +#: ../../Zotlabs/Module/Admin/Site.php:322 +msgid "" +"Check to verify email addresses used in account registration (recommended)." msgstr "" -#: ../../include/contact_widgets.php:269 -#, php-format -msgid "View all %d common connections" +#: ../../Zotlabs/Module/Admin/Site.php:323 +msgid "Force publish" msgstr "" -#: ../../include/language.php:437 -msgid "Select an alternate language" +#: ../../Zotlabs/Module/Admin/Site.php:323 +msgid "" +"Check to force all profiles on this site to be listed in the site directory." msgstr "" -#: ../../include/import.php:29 -msgid "Unable to import a removed channel." +#: ../../Zotlabs/Module/Admin/Site.php:324 +msgid "Import Public Streams" msgstr "" -#: ../../include/import.php:55 +#: ../../Zotlabs/Module/Admin/Site.php:324 msgid "" -"Cannot create a duplicate channel identifier on this system. Import failed." +"Import and allow access to public content pulled from other sites. Warning: " +"this content is unmoderated." msgstr "" -#: ../../include/import.php:121 -msgid "Cloned channel not found. Import failed." +#: ../../Zotlabs/Module/Admin/Site.php:325 +msgid "Site only Public Streams" msgstr "" -#: ../../include/nav.php:92 -msgid "Remote authentication" +#: ../../Zotlabs/Module/Admin/Site.php:325 +msgid "" +"Allow access to public content originating only from this site if Imported " +"Public Streams are disabled." msgstr "" -#: ../../include/nav.php:92 -msgid "Click to authenticate to your home hub" +#: ../../Zotlabs/Module/Admin/Site.php:326 +msgid "Allow anybody on the internet to access the Public streams" msgstr "" -#: ../../include/nav.php:98 ../../Zotlabs/Module/Manage.php:170 -#: ../../Zotlabs/Lib/Apps.php:337 -msgid "Channel Manager" +#: ../../Zotlabs/Module/Admin/Site.php:326 +msgid "" +"Disable to require authentication before viewing. Warning: this content is " +"unmoderated." msgstr "" -#: ../../include/nav.php:98 -msgid "Manage your channels" +#: ../../Zotlabs/Module/Admin/Site.php:327 +msgid "Only import Public stream posts with this text" msgstr "" -#: ../../include/nav.php:101 ../../include/group.php:321 -#: ../../include/acl_selectors.php:86 -#: ../../Zotlabs/Widget/Activity_filter.php:82 -#: ../../Zotlabs/Module/Group.php:142 ../../Zotlabs/Module/Group.php:154 -#: ../../Zotlabs/Lib/Group.php:324 ../../Zotlabs/Lib/Apps.php:364 -msgid "Privacy Groups" +#: ../../Zotlabs/Module/Admin/Site.php:328 +msgid "Do not import Public stream posts with this text" msgstr "" -#: ../../include/nav.php:101 -msgid "Manage your privacy groups" +#: ../../Zotlabs/Module/Admin/Site.php:331 +msgid "Login on Homepage" msgstr "" -#: ../../include/nav.php:103 ../../Zotlabs/Widget/Settings_menu.php:61 -#: ../../Zotlabs/Widget/Newmember.php:53 -#: ../../Zotlabs/Module/Admin/Themes.php:125 -#: ../../Zotlabs/Module/Admin/Addons.php:345 ../../Zotlabs/Lib/Apps.php:339 -msgid "Settings" +#: ../../Zotlabs/Module/Admin/Site.php:331 +msgid "" +"Present a login box to visitors on the home page if no other content has " +"been configured." msgstr "" -#: ../../include/nav.php:103 -msgid "Account/Channel Settings" +#: ../../Zotlabs/Module/Admin/Site.php:332 +msgid "Enable context help" msgstr "" -#: ../../include/nav.php:109 ../../include/nav.php:138 -#: ../../include/nav.php:157 ../../boot.php:1698 -msgid "Logout" +#: ../../Zotlabs/Module/Admin/Site.php:332 +msgid "" +"Display contextual help for the current page when the help button is pressed." msgstr "" -#: ../../include/nav.php:109 ../../include/nav.php:138 -msgid "End this session" +#: ../../Zotlabs/Module/Admin/Site.php:334 +msgid "Reply-to email address for system generated email." msgstr "" -#: ../../include/nav.php:112 -msgid "Your profile page" +#: ../../Zotlabs/Module/Admin/Site.php:335 +msgid "Sender (From) email address for system generated email." msgstr "" -#: ../../include/nav.php:115 ../../include/channel.php:1538 -#: ../../Zotlabs/Module/Profiles.php:832 -msgid "Edit Profiles" +#: ../../Zotlabs/Module/Admin/Site.php:336 +msgid "Name of email sender for system generated email." msgstr "" -#: ../../include/nav.php:115 -msgid "Manage/Edit profiles" +#: ../../Zotlabs/Module/Admin/Site.php:338 +msgid "Directory Server URL" msgstr "" -#: ../../include/nav.php:117 ../../Zotlabs/Widget/Newmember.php:35 -msgid "Edit your profile" +#: ../../Zotlabs/Module/Admin/Site.php:338 +msgid "Default directory server" msgstr "" -#: ../../include/nav.php:124 ../../include/nav.php:128 -#: ../../Zotlabs/Lib/Apps.php:336 ../../boot.php:1699 -msgid "Login" +#: ../../Zotlabs/Module/Admin/Site.php:340 +msgid "Enable SSE Notifications" msgstr "" -#: ../../include/nav.php:124 ../../include/nav.php:128 -msgid "Sign in" +#: ../../Zotlabs/Module/Admin/Site.php:340 +msgid "" +"If disabled, traditional polling will be used. Warning: this setting might " +"not be suited for shared hosting" msgstr "" -#: ../../include/nav.php:155 -msgid "Take me home" +#: ../../Zotlabs/Module/Admin/Site.php:342 +msgid "Proxy user" msgstr "" -#: ../../include/nav.php:157 -msgid "Log me out of this site" +#: ../../Zotlabs/Module/Admin/Site.php:343 +msgid "Proxy URL" msgstr "" -#: ../../include/nav.php:162 ../../Zotlabs/Module/Register.php:293 -#: ../../boot.php:1679 -msgid "Register" +#: ../../Zotlabs/Module/Admin/Site.php:344 +msgid "Network timeout" msgstr "" -#: ../../include/nav.php:162 -msgid "Create an account" +#: ../../Zotlabs/Module/Admin/Site.php:344 +msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." msgstr "" -#: ../../include/nav.php:174 -msgid "Help and documentation" +#: ../../Zotlabs/Module/Admin/Site.php:345 +msgid "Delivery interval" msgstr "" -#: ../../include/nav.php:188 -msgid "Search site @name, !forum, #tag, ?docs, content" +#: ../../Zotlabs/Module/Admin/Site.php:345 +msgid "" +"Delay background delivery processes by this many seconds to reduce system " +"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 " +"for large dedicated servers." msgstr "" -#: ../../include/nav.php:194 ../../Zotlabs/Widget/Admin.php:55 -msgid "Admin" -msgstr "" - -#: ../../include/nav.php:194 -msgid "Site Setup and Configuration" +#: ../../Zotlabs/Module/Admin/Site.php:346 +msgid "Deliveries per process" msgstr "" -#: ../../include/nav.php:324 ../../Zotlabs/Widget/Notifications.php:182 -#: ../../Zotlabs/Module/New_channel.php:157 -#: ../../Zotlabs/Module/New_channel.php:164 -#: ../../Zotlabs/Module/Defperms.php:257 ../../Zotlabs/Module/Connedit.php:861 -msgid "Loading" +#: ../../Zotlabs/Module/Admin/Site.php:346 +msgid "" +"Number of deliveries to attempt in a single operating system process. Adjust " +"if necessary to tune system performance. Recommend: 1-5." msgstr "" -#: ../../include/nav.php:330 -msgid "@name, !forum, #tag, ?doc, content" +#: ../../Zotlabs/Module/Admin/Site.php:347 +msgid "Queue Threshold" msgstr "" -#: ../../include/nav.php:331 -msgid "Please wait..." +#: ../../Zotlabs/Module/Admin/Site.php:347 +msgid "" +"Always defer immediate delivery if queue contains more than this number of " +"entries." msgstr "" -#: ../../include/nav.php:337 -msgid "Add Apps" +#: ../../Zotlabs/Module/Admin/Site.php:348 +msgid "Poll interval" msgstr "" -#: ../../include/nav.php:338 -msgid "Arrange Apps" +#: ../../Zotlabs/Module/Admin/Site.php:348 +msgid "" +"Delay background polling processes by this many seconds to reduce system " +"load. If 0, use delivery interval." msgstr "" -#: ../../include/nav.php:339 -msgid "Toggle System Apps" +#: ../../Zotlabs/Module/Admin/Site.php:349 +msgid "Path to ImageMagick convert program" msgstr "" -#: ../../include/nav.php:421 ../../Zotlabs/Module/Admin/Channels.php:154 -msgid "Channel" +#: ../../Zotlabs/Module/Admin/Site.php:349 +msgid "" +"If set, use this program to generate photo thumbnails for huge images ( > " +"4000 pixels in either dimension), otherwise memory exhaustion may occur. " +"Example: /usr/bin/convert" msgstr "" -#: ../../include/nav.php:424 -msgid "Status Messages and Posts" +#: ../../Zotlabs/Module/Admin/Site.php:350 +msgid "Maximum Load Average" msgstr "" -#: ../../include/nav.php:434 ../../Zotlabs/Module/Help.php:83 -msgid "About" +#: ../../Zotlabs/Module/Admin/Site.php:350 +msgid "" +"Maximum system load before delivery and poll processes are deferred - " +"default 50." msgstr "" -#: ../../include/nav.php:437 -msgid "Profile Details" +#: ../../Zotlabs/Module/Admin/Site.php:351 +msgid "Expiration period in days for imported (grid/network) content" msgstr "" -#: ../../include/nav.php:452 ../../Zotlabs/Module/Fbrowser.php:85 -#: ../../Zotlabs/Lib/Apps.php:340 ../../Zotlabs/Storage/Browser.php:344 -msgid "Files" +#: ../../Zotlabs/Module/Admin/Site.php:351 +msgid "0 for no expiration of imported content" msgstr "" -#: ../../include/nav.php:455 -msgid "Files and Storage" +#: ../../Zotlabs/Module/Admin/Site.php:352 +msgid "" +"Do not expire any posts which have comments less than this many days ago" msgstr "" -#: ../../include/nav.php:477 ../../include/nav.php:480 -#: ../../Zotlabs/Widget/Chatroom_list.php:16 ../../Zotlabs/Lib/Apps.php:330 -msgid "Chatrooms" +#: ../../Zotlabs/Module/Admin/Site.php:354 +msgid "" +"Public servers: Optional landing (marketing) webpage for new registrants" msgstr "" -#: ../../include/nav.php:490 ../../Zotlabs/Lib/Apps.php:329 -msgid "Bookmarks" +#: ../../Zotlabs/Module/Admin/Site.php:354 +#, php-format +msgid "Create this page first. Default is %s/register" msgstr "" -#: ../../include/nav.php:493 -msgid "Saved Bookmarks" +#: ../../Zotlabs/Module/Admin/Site.php:355 +msgid "Page to display after creating a new channel" msgstr "" -#: ../../include/nav.php:501 ../../Zotlabs/Module/Cards.php:207 -#: ../../Zotlabs/Lib/Apps.php:326 -msgid "Cards" +#: ../../Zotlabs/Module/Admin/Site.php:355 +msgid "Default: profiles" msgstr "" -#: ../../include/nav.php:504 -msgid "View Cards" +#: ../../Zotlabs/Module/Admin/Site.php:357 +msgid "Optional: site location" msgstr "" -#: ../../include/nav.php:512 ../../Zotlabs/Module/Articles.php:226 -#: ../../Zotlabs/Lib/Apps.php:325 -msgid "Articles" +#: ../../Zotlabs/Module/Admin/Site.php:357 +msgid "Region or country" msgstr "" -#: ../../include/nav.php:515 -msgid "View Articles" +#: ../../Zotlabs/Module/Admin/Profs.php:89 +msgid "New Profile Field" msgstr "" -#: ../../include/nav.php:524 ../../Zotlabs/Module/Webpages.php:252 -#: ../../Zotlabs/Lib/Apps.php:341 -msgid "Webpages" +#: ../../Zotlabs/Module/Admin/Profs.php:90 +#: ../../Zotlabs/Module/Admin/Profs.php:110 +msgid "Field nickname" msgstr "" -#: ../../include/nav.php:527 -msgid "View Webpages" +#: ../../Zotlabs/Module/Admin/Profs.php:90 +#: ../../Zotlabs/Module/Admin/Profs.php:110 +msgid "System name of field" msgstr "" -#: ../../include/nav.php:536 ../../Zotlabs/Widget/Wiki_list.php:15 -#: ../../Zotlabs/Module/Wiki.php:206 -msgid "Wikis" +#: ../../Zotlabs/Module/Admin/Profs.php:91 +#: ../../Zotlabs/Module/Admin/Profs.php:111 +msgid "Input type" msgstr "" -#: ../../include/nav.php:539 ../../Zotlabs/Lib/Apps.php:342 -msgid "Wiki" +#: ../../Zotlabs/Module/Admin/Profs.php:92 +#: ../../Zotlabs/Module/Admin/Profs.php:112 +msgid "Field Name" msgstr "" -#: ../../include/auth.php:194 -msgid "Delegation session ended." +#: ../../Zotlabs/Module/Admin/Profs.php:92 +#: ../../Zotlabs/Module/Admin/Profs.php:112 +msgid "Label on profile pages" msgstr "" -#: ../../include/auth.php:198 -msgid "Logged out." +#: ../../Zotlabs/Module/Admin/Profs.php:93 +#: ../../Zotlabs/Module/Admin/Profs.php:113 +msgid "Help text" msgstr "" -#: ../../include/auth.php:294 -msgid "Email validation is incomplete. Please check your email." +#: ../../Zotlabs/Module/Admin/Profs.php:93 +#: ../../Zotlabs/Module/Admin/Profs.php:113 +msgid "Additional info (optional)" msgstr "" -#: ../../include/auth.php:310 -msgid "Failed authentication" +#: ../../Zotlabs/Module/Admin/Profs.php:103 +msgid "Field definition not found" msgstr "" -#: ../../include/datetime.php:58 ../../Zotlabs/Widget/Newmember.php:51 -#: ../../Zotlabs/Module/Profiles.php:738 -msgid "Miscellaneous" +#: ../../Zotlabs/Module/Admin/Profs.php:109 +msgid "Edit Profile Field" msgstr "" -#: ../../include/datetime.php:140 -msgid "Birthday" +#: ../../Zotlabs/Module/Admin/Profs.php:168 ../../Zotlabs/Widget/Admin.php:30 +msgid "Profile Fields" msgstr "" -#: ../../include/datetime.php:140 -msgid "Age: " +#: ../../Zotlabs/Module/Admin/Profs.php:169 +msgid "Basic Profile Fields" msgstr "" -#: ../../include/datetime.php:140 -msgid "YYYY-MM-DD or MM-DD" +#: ../../Zotlabs/Module/Admin/Profs.php:170 +msgid "Advanced Profile Fields" msgstr "" -#: ../../include/datetime.php:238 ../../boot.php:2703 -msgid "never" +#: ../../Zotlabs/Module/Admin/Profs.php:170 +msgid "(In addition to basic fields)" msgstr "" -#: ../../include/datetime.php:244 -msgid "less than a second ago" +#: ../../Zotlabs/Module/Admin/Profs.php:172 +msgid "All available fields" msgstr "" -#: ../../include/datetime.php:262 -#, php-format -msgctxt "e.g. 22 hours ago, 1 minute ago" -msgid "%1$d %2$s ago" +#: ../../Zotlabs/Module/Admin/Profs.php:173 +msgid "Custom Fields" msgstr "" -#: ../../include/datetime.php:273 -msgctxt "relative_date" -msgid "year" -msgid_plural "years" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/datetime.php:276 -msgctxt "relative_date" -msgid "month" -msgid_plural "months" -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Admin/Profs.php:177 +msgid "Create Custom Field" +msgstr "" -#: ../../include/datetime.php:279 -msgctxt "relative_date" -msgid "week" -msgid_plural "weeks" -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Notify.php:61 ../../Zotlabs/Module/Notifications.php:55 +msgid "No more system notifications." +msgstr "" -#: ../../include/datetime.php:282 -msgctxt "relative_date" -msgid "day" -msgid_plural "days" -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Notify.php:65 ../../Zotlabs/Module/Notifications.php:59 +msgid "System Notifications" +msgstr "" -#: ../../include/datetime.php:285 -msgctxt "relative_date" -msgid "hour" -msgid_plural "hours" -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Cal.php:64 +msgid "Permissions denied." +msgstr "" -#: ../../include/datetime.php:288 -msgctxt "relative_date" -msgid "minute" -msgid_plural "minutes" -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Thing.php:122 +msgid "Thing updated" +msgstr "" -#: ../../include/datetime.php:291 -msgctxt "relative_date" -msgid "second" -msgid_plural "seconds" -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Thing.php:174 +msgid "Object store: failed" +msgstr "" -#: ../../include/datetime.php:520 -#, php-format -msgid "%1$s's birthday" +#: ../../Zotlabs/Module/Thing.php:178 +msgid "Thing added" msgstr "" -#: ../../include/datetime.php:521 +#: ../../Zotlabs/Module/Thing.php:204 #, php-format -msgid "Happy Birthday %1$s" +msgid "OBJ: %1$s %2$s %3$s" msgstr "" -#: ../../include/cdav.php:157 -msgid "INVALID EVENT DISMISSED!" +#: ../../Zotlabs/Module/Thing.php:267 +msgid "Show Thing" msgstr "" -#: ../../include/cdav.php:158 -msgid "Summary: " +#: ../../Zotlabs/Module/Thing.php:274 +msgid "item not found." msgstr "" -#: ../../include/cdav.php:159 -msgid "Date: " +#: ../../Zotlabs/Module/Thing.php:307 +msgid "Edit Thing" msgstr "" -#: ../../include/cdav.php:160 ../../include/cdav.php:168 -msgid "Reason: " +#: ../../Zotlabs/Module/Thing.php:309 ../../Zotlabs/Module/Thing.php:366 +msgid "Select a profile" msgstr "" -#: ../../include/cdav.php:166 -msgid "INVALID CARD DISMISSED!" +#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 +msgid "Post an activity" msgstr "" -#: ../../include/cdav.php:167 -msgid "Name: " +#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 +msgid "Only sends to viewers of the applicable profile" msgstr "" -#: ../../include/follow.php:37 ../../Zotlabs/Lib/Connect.php:46 -#: ../../Zotlabs/Lib/Connect.php:143 -msgid "Channel is blocked on this site." +#: ../../Zotlabs/Module/Thing.php:315 ../../Zotlabs/Module/Thing.php:371 +msgid "Name of thing e.g. something" msgstr "" -#: ../../include/follow.php:42 ../../Zotlabs/Lib/Connect.php:51 -msgid "Channel location missing." +#: ../../Zotlabs/Module/Thing.php:317 ../../Zotlabs/Module/Thing.php:372 +msgid "URL of thing (optional)" msgstr "" -#: ../../include/follow.php:84 -msgid "Response from remote channel was incomplete." +#: ../../Zotlabs/Module/Thing.php:319 ../../Zotlabs/Module/Thing.php:373 +msgid "URL for photo of thing (optional)" msgstr "" -#: ../../include/follow.php:96 -msgid "Premium channel - please visit:" +#: ../../Zotlabs/Module/Thing.php:364 +msgid "Add Thing to your Profile" msgstr "" -#: ../../include/follow.php:110 -msgid "Channel was deleted and no longer exists." +#: ../../Zotlabs/Module/Suggest.php:40 +msgid "Suggest Channels App" msgstr "" -#: ../../include/follow.php:166 ../../Zotlabs/Lib/Connect.php:103 -msgid "Remote channel or protocol unavailable." +#: ../../Zotlabs/Module/Suggest.php:41 +msgid "" +"Suggestions for channels in the $Projectname network you might be interested " +"in" msgstr "" -#: ../../include/follow.php:190 ../../Zotlabs/Lib/Connect.php:137 -msgid "Channel discovery failed." +#: ../../Zotlabs/Module/Suggest.php:54 +msgid "" +"No suggestions available. If this is a new site, please try again in 24 " +"hours." msgstr "" -#: ../../include/follow.php:202 ../../Zotlabs/Lib/Connect.php:155 -msgid "Protocol disabled." +#: ../../Zotlabs/Module/Suggest.php:73 ../../Zotlabs/Widget/Suggestions.php:48 +msgid "Ignore/Hide" msgstr "" -#: ../../include/follow.php:213 ../../Zotlabs/Lib/Connect.php:167 -msgid "Cannot connect to yourself." +#: ../../Zotlabs/Module/Suggest.php:79 ../../Zotlabs/Module/Directory.php:437 +#: ../../include/contact_widgets.php:24 +msgid "Channel Suggestions" msgstr "" -#: ../../include/conversation.php:135 ../../Zotlabs/Module/Like.php:166 -msgid "channel" +#: ../../Zotlabs/Module/Email_validation.php:36 +msgid "Email Verification Required" msgstr "" -#: ../../include/conversation.php:183 +#: ../../Zotlabs/Module/Email_validation.php:37 #, php-format -msgid "likes %1$s's %2$s" +msgid "" +"A verification token was sent to your email address [%s]. Enter that token " +"here to complete the account verification step. Please allow a few minutes " +"for delivery, and check your spam folder if you do not see the message." msgstr "" -#: ../../include/conversation.php:186 -#, php-format -msgid "doesn't like %1$s's %2$s" +#: ../../Zotlabs/Module/Email_validation.php:38 +msgid "Resend Email" msgstr "" -#: ../../include/conversation.php:226 ../../include/conversation.php:228 -#, php-format -msgid "%1$s is now connected with %2$s" +#: ../../Zotlabs/Module/Email_validation.php:41 +msgid "Validation token" msgstr "" -#: ../../include/conversation.php:263 -#, php-format -msgid "%1$s poked %2$s" +#: ../../Zotlabs/Module/Notes.php:57 +msgid "Notes App" +msgstr "" + +#: ../../Zotlabs/Module/Notes.php:58 +msgid "A simple notes app with a widget (note: notes are not encrypted)" msgstr "" -#: ../../include/conversation.php:286 ../../Zotlabs/Module/Mood.php:76 +#: ../../Zotlabs/Module/Tokens.php:39 #, php-format -msgctxt "mood" -msgid "%1$s is %2$s" +msgid "This channel is limited to %d tokens" msgstr "" -#: ../../include/conversation.php:516 ../../Zotlabs/Lib/ThreadItem.php:500 -msgid "This is an unsaved preview" +#: ../../Zotlabs/Module/Tokens.php:45 +msgid "Name and Password are required." msgstr "" -#: ../../include/conversation.php:652 ../../Zotlabs/Module/Photos.php:1113 -msgctxt "title" -msgid "Likes" +#: ../../Zotlabs/Module/Tokens.php:85 +msgid "Token saved." msgstr "" -#: ../../include/conversation.php:653 ../../Zotlabs/Module/Photos.php:1113 -msgctxt "title" -msgid "Dislikes" +#: ../../Zotlabs/Module/Tokens.php:99 +msgid "Guest Access App" msgstr "" -#: ../../include/conversation.php:654 ../../Zotlabs/Widget/Pinned.php:77 -#: ../../Zotlabs/Module/Photos.php:1114 -msgctxt "title" -msgid "Agree" +#: ../../Zotlabs/Module/Tokens.php:100 +msgid "Create access tokens so that non-members can access private content" msgstr "" -#: ../../include/conversation.php:655 ../../Zotlabs/Widget/Pinned.php:78 -#: ../../Zotlabs/Module/Photos.php:1114 -msgctxt "title" -msgid "Disagree" +#: ../../Zotlabs/Module/Tokens.php:133 +msgid "" +"Use this form to create temporary access identifiers to share things with " +"non-members. These identities may be used in Access Control Lists and " +"visitors may login using these credentials to access private content." msgstr "" -#: ../../include/conversation.php:656 ../../Zotlabs/Widget/Pinned.php:79 -#: ../../Zotlabs/Module/Photos.php:1114 -msgctxt "title" -msgid "Abstain" +#: ../../Zotlabs/Module/Tokens.php:135 +msgid "" +"You may also provide dropbox style access links to friends and " +"associates by adding the Login Password to any specific site URL as shown. " +"Examples:" msgstr "" -#: ../../include/conversation.php:657 ../../Zotlabs/Widget/Pinned.php:66 -#: ../../Zotlabs/Module/Photos.php:1115 -msgctxt "title" -msgid "Attending" +#: ../../Zotlabs/Module/Tokens.php:170 +msgid "Guest Access Tokens" msgstr "" -#: ../../include/conversation.php:658 ../../Zotlabs/Widget/Pinned.php:67 -#: ../../Zotlabs/Module/Photos.php:1115 -msgctxt "title" -msgid "Not attending" +#: ../../Zotlabs/Module/Tokens.php:177 +msgid "Login Name" msgstr "" -#: ../../include/conversation.php:659 ../../Zotlabs/Widget/Pinned.php:68 -#: ../../Zotlabs/Module/Photos.php:1115 -msgctxt "title" -msgid "Might attend" +#: ../../Zotlabs/Module/Tokens.php:178 +msgid "Login Password" msgstr "" -#: ../../include/conversation.php:729 ../../Zotlabs/Lib/ThreadItem.php:180 -msgid "Select" +#: ../../Zotlabs/Module/Tokens.php:179 +msgid "Expires (yyyy-mm-dd)" msgstr "" -#: ../../include/conversation.php:730 ../../include/conversation.php:775 -#: ../../Zotlabs/Module/Article_edit.php:128 -#: ../../Zotlabs/Module/Card_edit.php:129 ../../Zotlabs/Module/Oauth.php:174 -#: ../../Zotlabs/Module/Editwebpage.php:167 ../../Zotlabs/Module/Cdav.php:1056 -#: ../../Zotlabs/Module/Cdav.php:1389 ../../Zotlabs/Module/Webpages.php:257 -#: ../../Zotlabs/Module/Admin/Accounts.php:175 -#: ../../Zotlabs/Module/Admin/Channels.php:149 -#: ../../Zotlabs/Module/Admin/Profs.php:176 ../../Zotlabs/Module/Blocks.php:162 -#: ../../Zotlabs/Module/Editblock.php:139 -#: ../../Zotlabs/Module/Editlayout.php:138 -#: ../../Zotlabs/Module/Connections.php:328 -#: ../../Zotlabs/Module/Photos.php:1179 ../../Zotlabs/Module/Profiles.php:802 -#: ../../Zotlabs/Module/Oauth2.php:195 ../../Zotlabs/Module/Thing.php:269 -#: ../../Zotlabs/Module/Connedit.php:660 ../../Zotlabs/Module/Connedit.php:932 -#: ../../Zotlabs/Lib/Apps.php:558 ../../Zotlabs/Lib/ThreadItem.php:170 -#: ../../Zotlabs/Storage/Browser.php:377 -msgid "Delete" +#: ../../Zotlabs/Module/Apporder.php:47 +msgid "Change Order of Pinned Navbar Apps" msgstr "" -#: ../../include/conversation.php:734 ../../Zotlabs/Lib/ThreadItem.php:273 -msgid "Toggle Star Status" +#: ../../Zotlabs/Module/Apporder.php:47 +msgid "Change Order of App Tray Apps" msgstr "" -#: ../../include/conversation.php:739 ../../Zotlabs/Lib/ThreadItem.php:103 -msgid "Private Message" +#: ../../Zotlabs/Module/Apporder.php:48 +msgid "" +"Use arrows to move the corresponding app left (top) or right (bottom) in the " +"navbar" msgstr "" -#: ../../include/conversation.php:746 ../../Zotlabs/Widget/Pinned.php:88 -#: ../../Zotlabs/Lib/ThreadItem.php:284 -msgid "Message signature validated" +#: ../../Zotlabs/Module/Apporder.php:48 +msgid "Use arrows to move the corresponding app up or down in the app tray" msgstr "" -#: ../../include/conversation.php:747 ../../Zotlabs/Widget/Pinned.php:89 -#: ../../Zotlabs/Lib/ThreadItem.php:285 -msgid "Message signature incorrect" +#: ../../Zotlabs/Module/Notifications.php:60 +#: ../../Zotlabs/Lib/ThreadItem.php:482 +msgid "Mark all seen" msgstr "" -#: ../../include/conversation.php:774 -#: ../../Zotlabs/Module/Admin/Accounts.php:173 -#: ../../Zotlabs/Module/Connections.php:342 -msgid "Approve" +#: ../../Zotlabs/Module/Home.php:72 ../../Zotlabs/Module/Home.php:80 +#: ../../Zotlabs/Lib/Enotify.php:66 +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:42 +msgid "$Projectname" msgstr "" -#: ../../include/conversation.php:779 +#: ../../Zotlabs/Module/Home.php:90 #, php-format -msgid "View %s's profile @ %s" +msgid "Welcome to %s" msgstr "" -#: ../../include/conversation.php:799 -msgid "Categories:" +#: ../../Zotlabs/Module/Articles.php:52 +msgid "Articles App" msgstr "" -#: ../../include/conversation.php:800 -msgid "Filed under:" +#: ../../Zotlabs/Module/Articles.php:53 +msgid "Create interactive articles" msgstr "" -#: ../../include/conversation.php:806 ../../Zotlabs/Widget/Pinned.php:133 -#: ../../Zotlabs/Lib/ThreadItem.php:429 -#, php-format -msgid "from %s" +#: ../../Zotlabs/Module/Articles.php:116 +msgid "Add Article" msgstr "" -#: ../../include/conversation.php:809 ../../Zotlabs/Widget/Pinned.php:136 -#: ../../Zotlabs/Lib/ThreadItem.php:432 -#, php-format -msgid "last edited: %s" +#: ../../Zotlabs/Module/Articles.php:226 ../../Zotlabs/Lib/Apps.php:325 +#: ../../include/nav.php:512 +msgid "Articles" msgstr "" -#: ../../include/conversation.php:810 ../../Zotlabs/Widget/Pinned.php:137 -#: ../../Zotlabs/Lib/ThreadItem.php:433 -#, php-format -msgid "Expires: %s" +#: ../../Zotlabs/Module/Setup.php:167 +msgid "$Projectname Server - Setup" msgstr "" -#: ../../include/conversation.php:825 -msgid "View in context" +#: ../../Zotlabs/Module/Setup.php:171 +msgid "Could not connect to database." msgstr "" -#: ../../include/conversation.php:827 ../../Zotlabs/Module/Photos.php:1079 -#: ../../Zotlabs/Lib/ThreadItem.php:501 -msgid "Please wait" +#: ../../Zotlabs/Module/Setup.php:175 +msgid "" +"Could not connect to specified site URL. Possible SSL certificate or DNS " +"issue." msgstr "" -#: ../../include/conversation.php:928 -msgid "remove" +#: ../../Zotlabs/Module/Setup.php:182 +msgid "Could not create table." msgstr "" -#: ../../include/conversation.php:932 -msgid "Loading..." +#: ../../Zotlabs/Module/Setup.php:188 +msgid "Your site database has been installed." msgstr "" -#: ../../include/conversation.php:933 ../../Zotlabs/Lib/ThreadItem.php:301 -msgid "Conversation Tools" +#: ../../Zotlabs/Module/Setup.php:194 +msgid "" +"You may need to import the file \"install/schema_xxx.sql\" manually using a " +"database client." msgstr "" -#: ../../include/conversation.php:934 -msgid "Delete Selected Items" +#: ../../Zotlabs/Module/Setup.php:195 ../../Zotlabs/Module/Setup.php:259 +#: ../../Zotlabs/Module/Setup.php:766 +msgid "Please see the file \"install/INSTALL.txt\"." msgstr "" -#: ../../include/conversation.php:977 -msgid "View Source" +#: ../../Zotlabs/Module/Setup.php:256 +msgid "System check" msgstr "" -#: ../../include/conversation.php:987 -msgid "Follow Thread" +#: ../../Zotlabs/Module/Setup.php:261 +msgid "Check again" msgstr "" -#: ../../include/conversation.php:996 -msgid "Unfollow Thread" +#: ../../Zotlabs/Module/Setup.php:282 +msgid "Database connection" msgstr "" -#: ../../include/conversation.php:1090 ../../Zotlabs/Module/Connedit.php:621 -msgid "Recent Activity" +#: ../../Zotlabs/Module/Setup.php:283 +msgid "" +"In order to install $Projectname we need to know how to connect to your " +"database." msgstr "" -#: ../../include/conversation.php:1100 ../../include/connections.php:110 -#: ../../include/channel.php:1618 ../../Zotlabs/Widget/Suggestions.php:46 -#: ../../Zotlabs/Widget/Follow.php:32 ../../Zotlabs/Module/Directory.php:368 -#: ../../Zotlabs/Module/Connections.php:349 ../../Zotlabs/Module/Suggest.php:71 -msgid "Connect" +#: ../../Zotlabs/Module/Setup.php:284 +msgid "" +"Please contact your hosting provider or site administrator if you have " +"questions about these settings." msgstr "" -#: ../../include/conversation.php:1110 -msgid "Edit Connection" +#: ../../Zotlabs/Module/Setup.php:285 +msgid "" +"The database you specify below should already exist. If it does not, please " +"create it before continuing." msgstr "" -#: ../../include/conversation.php:1120 -msgid "Message" +#: ../../Zotlabs/Module/Setup.php:289 +msgid "Database Server Name" msgstr "" -#: ../../include/conversation.php:1130 ../../Zotlabs/Module/Pubsites.php:35 -#: ../../Zotlabs/Module/Ratings.php:97 -msgid "Ratings" +#: ../../Zotlabs/Module/Setup.php:289 +msgid "Default is 127.0.0.1" msgstr "" -#: ../../include/conversation.php:1140 ../../Zotlabs/Module/Poke.php:199 -#: ../../Zotlabs/Lib/Apps.php:351 -msgid "Poke" +#: ../../Zotlabs/Module/Setup.php:290 +msgid "Database Port" msgstr "" -#: ../../include/conversation.php:1262 -#, php-format -msgid "%s likes this." +#: ../../Zotlabs/Module/Setup.php:290 +msgid "Communication port number - use 0 for default" msgstr "" -#: ../../include/conversation.php:1262 -#, php-format -msgid "%s doesn't like this." +#: ../../Zotlabs/Module/Setup.php:291 +msgid "Database Login Name" msgstr "" -#: ../../include/conversation.php:1266 -#, php-format -msgid "%2$d people like this." -msgid_plural "%2$d people like this." -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Setup.php:292 +msgid "Database Login Password" +msgstr "" -#: ../../include/conversation.php:1268 -#, php-format -msgid "%2$d people don't like this." -msgid_plural "%2$d people don't like this." -msgstr[0] "" -msgstr[1] "" +#: ../../Zotlabs/Module/Setup.php:293 +msgid "Database Name" +msgstr "" -#: ../../include/conversation.php:1274 -msgid "and" +#: ../../Zotlabs/Module/Setup.php:294 +msgid "Database Type" msgstr "" -#: ../../include/conversation.php:1277 -#, php-format -msgid ", and %d other people" -msgid_plural ", and %d other people" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1278 -#, php-format -msgid "%s like this." -msgstr "" - -#: ../../include/conversation.php:1278 -#, php-format -msgid "%s don't like this." +#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 +msgid "Site administrator email address" msgstr "" -#: ../../include/conversation.php:1462 -msgid "Toggle poll" +#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 +msgid "" +"Your account email address must match this in order to use the web admin " +"panel." msgstr "" -#: ../../include/conversation.php:1463 -msgid "Option" +#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 +msgid "Website URL" msgstr "" -#: ../../include/conversation.php:1464 -msgid "Add option" +#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 +msgid "Please use SSL (https) URL if available." msgstr "" -#: ../../include/conversation.php:1465 -msgid "Minutes" +#: ../../Zotlabs/Module/Setup.php:298 ../../Zotlabs/Module/Setup.php:340 +msgid "Please select a default timezone for your website" msgstr "" -#: ../../include/conversation.php:1465 -msgid "Hours" +#: ../../Zotlabs/Module/Setup.php:325 +msgid "Site settings" msgstr "" -#: ../../include/conversation.php:1465 -msgid "Days" +#: ../../Zotlabs/Module/Setup.php:379 +msgid "PHP version 7.1 or greater is required." msgstr "" -#: ../../include/conversation.php:1466 -msgid "Allow multiple answers" +#: ../../Zotlabs/Module/Setup.php:380 +msgid "PHP version" msgstr "" -#: ../../include/conversation.php:1749 ../../include/taxonomy.php:668 -#: ../../include/channel.php:1781 ../../Zotlabs/Module/Photos.php:1136 -#: ../../Zotlabs/Lib/ThreadItem.php:242 -msgctxt "noun" -msgid "Like" -msgid_plural "Likes" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1752 ../../Zotlabs/Module/Photos.php:1141 -#: ../../Zotlabs/Lib/ThreadItem.php:247 -msgctxt "noun" -msgid "Dislike" -msgid_plural "Dislikes" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1755 -msgctxt "noun" -msgid "Attending" -msgid_plural "Attending" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1758 -msgctxt "noun" -msgid "Not Attending" -msgid_plural "Not Attending" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1761 -msgctxt "noun" -msgid "Undecided" -msgid_plural "Undecided" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1764 -msgctxt "noun" -msgid "Agree" -msgid_plural "Agrees" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1767 -msgctxt "noun" -msgid "Disagree" -msgid_plural "Disagrees" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/conversation.php:1770 -msgctxt "noun" -msgid "Abstain" -msgid_plural "Abstains" -msgstr[0] "" -msgstr[1] "" - -#: ../../include/selectors.php:18 -msgid "Profile to assign new connections" +#: ../../Zotlabs/Module/Setup.php:396 +msgid "Could not find a command line version of PHP in the web server PATH." msgstr "" -#: ../../include/selectors.php:41 -msgid "Frequently" +#: ../../Zotlabs/Module/Setup.php:397 +msgid "" +"If you don't have a command line version of PHP installed on server, you " +"will not be able to run background polling via cron." msgstr "" -#: ../../include/selectors.php:42 -msgid "Hourly" +#: ../../Zotlabs/Module/Setup.php:401 +msgid "PHP executable path" msgstr "" -#: ../../include/selectors.php:43 -msgid "Twice daily" +#: ../../Zotlabs/Module/Setup.php:401 +msgid "" +"Enter full path to php executable. You can leave this blank to continue the " +"installation." msgstr "" -#: ../../include/selectors.php:44 -msgid "Daily" +#: ../../Zotlabs/Module/Setup.php:406 +msgid "Command line PHP" msgstr "" -#: ../../include/selectors.php:45 -msgid "Weekly" +#: ../../Zotlabs/Module/Setup.php:416 +msgid "" +"Unable to check command line PHP, as shell_exec() is disabled. This is " +"required." msgstr "" -#: ../../include/selectors.php:46 -msgid "Monthly" +#: ../../Zotlabs/Module/Setup.php:420 +msgid "" +"The command line version of PHP on your system does not have " +"\"register_argc_argv\" enabled." msgstr "" -#: ../../include/selectors.php:60 -msgid "Currently Male" +#: ../../Zotlabs/Module/Setup.php:421 +msgid "This is required for message delivery to work." msgstr "" -#: ../../include/selectors.php:60 -msgid "Currently Female" +#: ../../Zotlabs/Module/Setup.php:424 +msgid "PHP register_argc_argv" msgstr "" -#: ../../include/selectors.php:60 -msgid "Mostly Male" +#: ../../Zotlabs/Module/Setup.php:444 +msgid "" +"This is not sufficient to upload larger images or files. You should be able " +"to upload at least 4 MB at once." msgstr "" -#: ../../include/selectors.php:60 -msgid "Mostly Female" +#: ../../Zotlabs/Module/Setup.php:446 +#, php-format +msgid "" +"Your max allowed total upload size is set to %s. Maximum size of one file to " +"upload is set to %s. You are allowed to upload up to %d files at once." msgstr "" -#: ../../include/selectors.php:60 -msgid "Transgender" +#: ../../Zotlabs/Module/Setup.php:452 +msgid "You can adjust these settings in the server php.ini file." msgstr "" -#: ../../include/selectors.php:60 -msgid "Intersex" +#: ../../Zotlabs/Module/Setup.php:454 +msgid "PHP upload limits" msgstr "" -#: ../../include/selectors.php:60 -msgid "Transsexual" +#: ../../Zotlabs/Module/Setup.php:477 +msgid "" +"Error: the \"openssl_pkey_new\" function on this system is not able to " +"generate encryption keys" msgstr "" -#: ../../include/selectors.php:60 -msgid "Hermaphrodite" +#: ../../Zotlabs/Module/Setup.php:478 +msgid "" +"If running under Windows, please see \"http://www.php.net/manual/en/openssl." +"installation.php\"." msgstr "" -#: ../../include/selectors.php:60 ../../include/channel.php:1726 -msgid "Neuter" +#: ../../Zotlabs/Module/Setup.php:481 +msgid "Generate encryption keys" msgstr "" -#: ../../include/selectors.php:60 ../../include/channel.php:1728 -msgid "Non-specific" +#: ../../Zotlabs/Module/Setup.php:498 +msgid "libCurl PHP module" msgstr "" -#: ../../include/selectors.php:60 -msgid "Undecided" +#: ../../Zotlabs/Module/Setup.php:499 +msgid "GD graphics PHP module" msgstr "" -#: ../../include/selectors.php:96 ../../include/selectors.php:115 -msgid "Males" +#: ../../Zotlabs/Module/Setup.php:500 +msgid "OpenSSL PHP module" msgstr "" -#: ../../include/selectors.php:96 ../../include/selectors.php:115 -msgid "Females" +#: ../../Zotlabs/Module/Setup.php:501 +msgid "PDO database PHP module" msgstr "" -#: ../../include/selectors.php:96 -msgid "Gay" +#: ../../Zotlabs/Module/Setup.php:502 +msgid "mb_string PHP module" msgstr "" -#: ../../include/selectors.php:96 -msgid "Lesbian" +#: ../../Zotlabs/Module/Setup.php:503 +msgid "xml PHP module" msgstr "" -#: ../../include/selectors.php:96 -msgid "No Preference" +#: ../../Zotlabs/Module/Setup.php:504 +msgid "zip PHP module" msgstr "" -#: ../../include/selectors.php:96 -msgid "Bisexual" +#: ../../Zotlabs/Module/Setup.php:508 ../../Zotlabs/Module/Setup.php:510 +msgid "Apache mod_rewrite module" msgstr "" -#: ../../include/selectors.php:96 -msgid "Autosexual" +#: ../../Zotlabs/Module/Setup.php:508 +msgid "" +"Error: Apache webserver mod-rewrite module is required but not installed." msgstr "" -#: ../../include/selectors.php:96 -msgid "Abstinent" +#: ../../Zotlabs/Module/Setup.php:514 ../../Zotlabs/Module/Setup.php:517 +msgid "exec" msgstr "" -#: ../../include/selectors.php:96 -msgid "Virgin" +#: ../../Zotlabs/Module/Setup.php:514 +msgid "" +"Error: exec is required but is either not installed or has been disabled in " +"php.ini" msgstr "" -#: ../../include/selectors.php:96 -msgid "Deviant" +#: ../../Zotlabs/Module/Setup.php:520 ../../Zotlabs/Module/Setup.php:523 +msgid "shell_exec" msgstr "" -#: ../../include/selectors.php:96 -msgid "Fetish" +#: ../../Zotlabs/Module/Setup.php:520 +msgid "" +"Error: shell_exec is required but is either not installed or has been " +"disabled in php.ini" msgstr "" -#: ../../include/selectors.php:96 -msgid "Oodles" +#: ../../Zotlabs/Module/Setup.php:528 +msgid "Error: libCURL PHP module required but not installed." msgstr "" -#: ../../include/selectors.php:96 -msgid "Nonsexual" +#: ../../Zotlabs/Module/Setup.php:532 +msgid "" +"Error: GD PHP module with JPEG support or ImageMagick graphics library " +"required but not installed." msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "Single" +#: ../../Zotlabs/Module/Setup.php:536 +msgid "Error: openssl PHP module required but not installed." msgstr "" -#: ../../include/selectors.php:134 -msgid "Lonely" +#: ../../Zotlabs/Module/Setup.php:542 +msgid "" +"Error: PDO database PHP module missing a driver for either mysql or pgsql." msgstr "" -#: ../../include/selectors.php:134 -msgid "Available" +#: ../../Zotlabs/Module/Setup.php:547 +msgid "Error: PDO database PHP module required but not installed." msgstr "" -#: ../../include/selectors.php:134 -msgid "Unavailable" +#: ../../Zotlabs/Module/Setup.php:551 +msgid "Error: mb_string PHP module required but not installed." msgstr "" -#: ../../include/selectors.php:134 -msgid "Has crush" +#: ../../Zotlabs/Module/Setup.php:555 +msgid "Error: xml PHP module required for DAV but not installed." msgstr "" -#: ../../include/selectors.php:134 -msgid "Infatuated" +#: ../../Zotlabs/Module/Setup.php:559 +msgid "Error: zip PHP module required but not installed." msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "Dating" +#: ../../Zotlabs/Module/Setup.php:578 ../../Zotlabs/Module/Setup.php:587 +msgid ".htconfig.php is writable" msgstr "" -#: ../../include/selectors.php:134 -msgid "Unfaithful" +#: ../../Zotlabs/Module/Setup.php:583 +msgid "" +"The web installer needs to be able to create a file called \".htconfig.php\" " +"in the top folder of your web server and it is unable to do so." msgstr "" -#: ../../include/selectors.php:134 -msgid "Sex Addict" +#: ../../Zotlabs/Module/Setup.php:584 +msgid "" +"This is most often a permission setting, as the web server may not be able " +"to write files in your folder - even if you can." msgstr "" -#: ../../include/selectors.php:134 ../../include/channel.php:505 -#: ../../include/channel.php:506 ../../include/channel.php:513 -#: ../../Zotlabs/Widget/Affinity.php:32 -#: ../../Zotlabs/Module/Settings/Channel.php:71 -#: ../../Zotlabs/Module/Settings/Channel.php:75 -#: ../../Zotlabs/Module/Settings/Channel.php:76 -#: ../../Zotlabs/Module/Settings/Channel.php:79 -#: ../../Zotlabs/Module/Settings/Channel.php:90 -#: ../../Zotlabs/Module/Connedit.php:717 -msgid "Friends" +#: ../../Zotlabs/Module/Setup.php:585 +msgid "Please see install/INSTALL.txt for additional information." msgstr "" -#: ../../include/selectors.php:134 -msgid "Friends/Benefits" +#: ../../Zotlabs/Module/Setup.php:601 +msgid "" +"This software uses the Smarty3 template engine to render its web views. " +"Smarty3 compiles templates to PHP to speed up rendering." msgstr "" -#: ../../include/selectors.php:134 -msgid "Casual" +#: ../../Zotlabs/Module/Setup.php:602 +#, php-format +msgid "" +"In order to store these compiled templates, the web server needs to have " +"write access to the directory %s under the top level web folder." msgstr "" -#: ../../include/selectors.php:134 -msgid "Engaged" +#: ../../Zotlabs/Module/Setup.php:603 ../../Zotlabs/Module/Setup.php:624 +msgid "" +"Please ensure that the user that your web server runs as (e.g. www-data) has " +"write access to this folder." msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "Married" +#: ../../Zotlabs/Module/Setup.php:604 +#, php-format +msgid "" +"Note: as a security measure, you should give the web server write access to " +"%s only--not the template files (.tpl) that it contains." msgstr "" -#: ../../include/selectors.php:134 -msgid "Imaginarily married" +#: ../../Zotlabs/Module/Setup.php:607 +#, php-format +msgid "%s is writable" msgstr "" -#: ../../include/selectors.php:134 -msgid "Partners" +#: ../../Zotlabs/Module/Setup.php:623 +msgid "" +"This software uses the store directory to save uploaded files. The web " +"server needs to have write access to the store directory under the top level " +"web folder" msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "Cohabiting" +#: ../../Zotlabs/Module/Setup.php:627 +msgid "store is writable" msgstr "" -#: ../../include/selectors.php:134 -msgid "Common law" +#: ../../Zotlabs/Module/Setup.php:659 +msgid "" +"SSL certificate cannot be validated. Fix certificate or disable https access " +"to this site." msgstr "" -#: ../../include/selectors.php:134 -msgid "Happy" +#: ../../Zotlabs/Module/Setup.php:660 +msgid "" +"If you have https access to your website or allow connections to TCP port " +"443 (the https: port), you MUST use a browser-valid certificate. You MUST " +"NOT use self-signed certificates!" msgstr "" -#: ../../include/selectors.php:134 -msgid "Not looking" +#: ../../Zotlabs/Module/Setup.php:661 +msgid "" +"This restriction is incorporated because public posts from you may for " +"example contain references to images on your own hub." msgstr "" -#: ../../include/selectors.php:134 -msgid "Swinger" +#: ../../Zotlabs/Module/Setup.php:662 +msgid "" +"If your certificate is not recognized, members of other sites (who may " +"themselves have valid certificates) will get a warning message on their own " +"site complaining about security issues." msgstr "" -#: ../../include/selectors.php:134 -msgid "Betrayed" +#: ../../Zotlabs/Module/Setup.php:663 +msgid "" +"This can cause usability issues elsewhere (not just on your own site) so we " +"must insist on this requirement." msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "Separated" +#: ../../Zotlabs/Module/Setup.php:664 +msgid "" +"Providers are available that issue free certificates which are browser-valid." msgstr "" -#: ../../include/selectors.php:134 -msgid "Unstable" +#: ../../Zotlabs/Module/Setup.php:665 +msgid "" +"If you are confident that the certificate is valid and signed by a trusted " +"authority, check to see if you have failed to install an intermediate cert. " +"These are not normally required by browsers, but are required for server-to-" +"server communications." msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "Divorced" +#: ../../Zotlabs/Module/Setup.php:667 +msgid "SSL certificate validation" msgstr "" -#: ../../include/selectors.php:134 -msgid "Imaginarily divorced" +#: ../../Zotlabs/Module/Setup.php:673 +msgid "" +"Url rewrite in .htaccess is not working. Check your server configuration." +"Test: " msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "Widowed" +#: ../../Zotlabs/Module/Setup.php:676 +msgid "Url rewrite is working" msgstr "" -#: ../../include/selectors.php:134 -msgid "Uncertain" +#: ../../Zotlabs/Module/Setup.php:689 +msgid "" +"The database configuration file \".htconfig.php\" could not be written. " +"Please use the enclosed text to create a configuration file in your web " +"server root." msgstr "" -#: ../../include/selectors.php:134 ../../include/selectors.php:151 -msgid "It's complicated" +#: ../../Zotlabs/Module/Setup.php:718 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:401 +msgid "Errors encountered creating database tables." msgstr "" -#: ../../include/selectors.php:134 -msgid "Don't care" +#: ../../Zotlabs/Module/Setup.php:764 +msgid "

      What next?

      " msgstr "" -#: ../../include/selectors.php:134 -msgid "Ask me" +#: ../../Zotlabs/Module/Setup.php:765 +msgid "" +"IMPORTANT: You will need to [manually] setup a scheduled task for the poller." msgstr "" -#: ../../include/connections.php:134 -msgid "New window" +#: ../../Zotlabs/Module/Directory.php:122 +msgid "No default suggestions were found." msgstr "" -#: ../../include/connections.php:135 -msgid "Open the selected location in a different window or browser tab" -msgstr "" +#: ../../Zotlabs/Module/Directory.php:282 +#, php-format +msgid "%d rating" +msgid_plural "%d ratings" +msgstr[0] "" +msgstr[1] "" -#: ../../include/group.php:23 ../../Zotlabs/Lib/Group.php:28 -msgid "" -"A deleted group with this name was revived. Existing item permissions " -"may apply to this group and any future members. If this is " -"not what you intended, please create another group with a different name." +#: ../../Zotlabs/Module/Directory.php:293 +msgid "Gender: " msgstr "" -#: ../../include/group.php:265 ../../Zotlabs/Lib/Group.php:270 -msgid "Add new connections to this privacy group" +#: ../../Zotlabs/Module/Directory.php:295 +msgid "Status: " msgstr "" -#: ../../include/group.php:299 ../../Zotlabs/Lib/AccessList.php:311 -#: ../../Zotlabs/Lib/Group.php:302 -msgid "edit" +#: ../../Zotlabs/Module/Directory.php:297 +msgid "Homepage: " msgstr "" -#: ../../include/group.php:322 ../../Zotlabs/Lib/Group.php:325 -msgid "Edit group" +#: ../../Zotlabs/Module/Directory.php:349 ../../include/channel.php:1806 +msgid "Age:" msgstr "" -#: ../../include/group.php:323 ../../Zotlabs/Lib/Group.php:326 -msgid "Add privacy group" +#: ../../Zotlabs/Module/Directory.php:354 ../../include/channel.php:1633 +#: ../../include/event.php:63 ../../include/event.php:134 +msgid "Location:" msgstr "" -#: ../../include/group.php:324 ../../Zotlabs/Lib/Group.php:327 -msgid "Channels not in any privacy group" +#: ../../Zotlabs/Module/Directory.php:360 +msgid "Description:" msgstr "" -#: ../../include/group.php:326 ../../Zotlabs/Widget/Savedsearch.php:84 -#: ../../Zotlabs/Lib/AccessList.php:336 ../../Zotlabs/Lib/Group.php:329 -msgid "add" +#: ../../Zotlabs/Module/Directory.php:367 ../../include/channel.php:1835 +msgid "Hometown:" msgstr "" -#: ../../include/taxonomy.php:323 -msgid "Trending" +#: ../../Zotlabs/Module/Directory.php:369 ../../include/channel.php:1841 +msgid "About:" msgstr "" -#: ../../include/taxonomy.php:323 ../../include/taxonomy.php:458 -#: ../../include/taxonomy.php:479 ../../Zotlabs/Widget/Tagcloud.php:22 -msgid "Tags" +#: ../../Zotlabs/Module/Directory.php:371 +msgid "Public Forum:" msgstr "" -#: ../../include/taxonomy.php:559 -msgid "Keywords" +#: ../../Zotlabs/Module/Directory.php:374 +msgid "Keywords: " msgstr "" -#: ../../include/taxonomy.php:580 -msgid "have" +#: ../../Zotlabs/Module/Directory.php:377 +msgid "Don't suggest" msgstr "" -#: ../../include/taxonomy.php:580 -msgid "has" +#: ../../Zotlabs/Module/Directory.php:379 +msgid "Common connections (estimated):" msgstr "" -#: ../../include/taxonomy.php:581 -msgid "want" +#: ../../Zotlabs/Module/Directory.php:428 +msgid "Global Directory" msgstr "" -#: ../../include/taxonomy.php:581 -msgid "wants" +#: ../../Zotlabs/Module/Directory.php:428 +msgid "Local Directory" msgstr "" -#: ../../include/taxonomy.php:582 ../../Zotlabs/Lib/ThreadItem.php:317 -msgid "like" +#: ../../Zotlabs/Module/Directory.php:434 +msgid "Finding:" msgstr "" -#: ../../include/taxonomy.php:582 -msgid "likes" +#: ../../Zotlabs/Module/Directory.php:439 +msgid "next page" msgstr "" -#: ../../include/taxonomy.php:583 ../../Zotlabs/Lib/ThreadItem.php:318 -msgid "dislike" +#: ../../Zotlabs/Module/Directory.php:439 +msgid "previous page" msgstr "" -#: ../../include/taxonomy.php:583 -msgid "dislikes" +#: ../../Zotlabs/Module/Directory.php:440 +msgid "Sort options" msgstr "" -#: ../../include/items.php:999 ../../include/items.php:1059 -msgid "(Unknown)" +#: ../../Zotlabs/Module/Directory.php:441 +msgid "Alphabetic" msgstr "" -#: ../../include/items.php:1247 -msgid "Visible to anybody on the internet." +#: ../../Zotlabs/Module/Directory.php:442 +msgid "Reverse Alphabetic" msgstr "" -#: ../../include/items.php:1249 -msgid "Visible to you only." +#: ../../Zotlabs/Module/Directory.php:443 +msgid "Newest to Oldest" msgstr "" -#: ../../include/items.php:1251 -msgid "Visible to anybody in this network." +#: ../../Zotlabs/Module/Directory.php:444 +msgid "Oldest to Newest" msgstr "" -#: ../../include/items.php:1253 -msgid "Visible to anybody authenticated." +#: ../../Zotlabs/Module/Directory.php:461 +msgid "No entries (some entries may be hidden)." msgstr "" -#: ../../include/items.php:1255 -#, php-format -msgid "Visible to anybody on %s." +#: ../../Zotlabs/Module/Mitem.php:31 ../../Zotlabs/Module/Menu.php:209 +msgid "Menu not found." msgstr "" -#: ../../include/items.php:1257 -msgid "Visible to all connections." +#: ../../Zotlabs/Module/Mitem.php:63 +msgid "Unable to create element." msgstr "" -#: ../../include/items.php:1259 -msgid "Visible to approved connections." +#: ../../Zotlabs/Module/Mitem.php:87 +msgid "Unable to update menu element." msgstr "" -#: ../../include/items.php:1261 -msgid "Visible to specific connections." +#: ../../Zotlabs/Module/Mitem.php:103 +msgid "Unable to add menu element." msgstr "" -#: ../../include/items.php:4474 ../../Zotlabs/Module/Group.php:62 -#: ../../Zotlabs/Module/Group.php:214 -msgid "Privacy group not found." +#: ../../Zotlabs/Module/Mitem.php:167 ../../Zotlabs/Module/Mitem.php:246 +msgid "Menu Item Permissions" msgstr "" -#: ../../include/items.php:4490 -msgid "Privacy group is empty." +#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247 +#: ../../Zotlabs/Module/Settings/Channel.php:528 +msgid "(click to open/close)" msgstr "" -#: ../../include/items.php:4497 -#, php-format -msgid "Privacy group: %s" +#: ../../Zotlabs/Module/Mitem.php:174 ../../Zotlabs/Module/Mitem.php:191 +msgid "Link Name" msgstr "" -#: ../../include/items.php:4507 ../../Zotlabs/Module/Connedit.php:859 -#, php-format -msgid "Connection: %s" +#: ../../Zotlabs/Module/Mitem.php:175 ../../Zotlabs/Module/Mitem.php:255 +msgid "Link or Submenu Target" msgstr "" -#: ../../include/items.php:4509 -msgid "Connection not found." +#: ../../Zotlabs/Module/Mitem.php:175 +msgid "Enter URL of the link or select a menu name to create a submenu" msgstr "" -#: ../../include/items.php:4843 ../../Zotlabs/Module/Cover_photo.php:297 -msgid "female" +#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:256 +msgid "Use magic-auth if available" msgstr "" -#: ../../include/items.php:4844 ../../Zotlabs/Module/Cover_photo.php:298 -#, php-format -msgid "%1$s updated her %2$s" +#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:257 +msgid "Open link in new window" msgstr "" -#: ../../include/items.php:4845 ../../Zotlabs/Module/Cover_photo.php:299 -msgid "male" +#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 +msgid "Order in list" msgstr "" -#: ../../include/items.php:4846 ../../Zotlabs/Module/Cover_photo.php:300 -#, php-format -msgid "%1$s updated his %2$s" +#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 +msgid "Higher numbers will sink to bottom of listing" msgstr "" -#: ../../include/items.php:4848 ../../Zotlabs/Module/Cover_photo.php:302 -#, php-format -msgid "%1$s updated their %2$s" +#: ../../Zotlabs/Module/Mitem.php:179 +msgid "Submit and finish" msgstr "" -#: ../../include/items.php:4850 -msgid "profile photo" +#: ../../Zotlabs/Module/Mitem.php:180 +msgid "Submit and continue" msgstr "" -#: ../../include/items.php:5042 -#, php-format -msgid "[Edited %s]" +#: ../../Zotlabs/Module/Mitem.php:189 +msgid "Menu:" msgstr "" -#: ../../include/items.php:5042 -msgctxt "edit_activity" -msgid "Post" +#: ../../Zotlabs/Module/Mitem.php:192 +msgid "Link Target" msgstr "" -#: ../../include/items.php:5042 -msgctxt "edit_activity" -msgid "Comment" +#: ../../Zotlabs/Module/Mitem.php:195 +msgid "Edit menu" msgstr "" -#: ../../include/account.php:36 -msgid "Not a valid email address" +#: ../../Zotlabs/Module/Mitem.php:198 +msgid "Edit element" msgstr "" -#: ../../include/account.php:38 -msgid "Your email domain is not among those allowed on this site" +#: ../../Zotlabs/Module/Mitem.php:199 +msgid "Drop element" msgstr "" -#: ../../include/account.php:44 -msgid "Your email address is already registered at this site." +#: ../../Zotlabs/Module/Mitem.php:200 +msgid "New element" msgstr "" -#: ../../include/account.php:76 -msgid "An invitation is required." +#: ../../Zotlabs/Module/Mitem.php:201 +msgid "Edit this menu container" msgstr "" -#: ../../include/account.php:80 -msgid "Invitation could not be verified." +#: ../../Zotlabs/Module/Mitem.php:202 +msgid "Add menu element" msgstr "" -#: ../../include/account.php:156 -msgid "Please enter the required information." +#: ../../Zotlabs/Module/Mitem.php:203 +msgid "Delete this menu item" msgstr "" -#: ../../include/account.php:223 -msgid "Failed to store account information." +#: ../../Zotlabs/Module/Mitem.php:204 +msgid "Edit this menu item" msgstr "" -#: ../../include/account.php:311 -#, php-format -msgid "Registration confirmation for %s" +#: ../../Zotlabs/Module/Mitem.php:222 +msgid "Menu item not found." msgstr "" -#: ../../include/account.php:380 -#, php-format -msgid "Registration request at %s" +#: ../../Zotlabs/Module/Mitem.php:235 +msgid "Menu item deleted." msgstr "" -#: ../../include/account.php:402 -msgid "your registration password" +#: ../../Zotlabs/Module/Mitem.php:237 +msgid "Menu item could not be deleted." msgstr "" -#: ../../include/account.php:408 ../../include/account.php:471 -#, php-format -msgid "Registration details for %s" +#: ../../Zotlabs/Module/Mitem.php:244 +msgid "Edit Menu Element" msgstr "" -#: ../../include/account.php:482 -msgid "Account approved." +#: ../../Zotlabs/Module/Mitem.php:254 +msgid "Link text" msgstr "" -#: ../../include/account.php:522 +#: ../../Zotlabs/Module/Mood.php:76 ../../include/conversation.php:286 #, php-format -msgid "Registration revoked for %s" -msgstr "" - -#: ../../include/account.php:805 ../../include/account.php:807 -msgid "Click here to upgrade." +msgctxt "mood" +msgid "%1$s is %2$s" msgstr "" -#: ../../include/account.php:813 -msgid "This action exceeds the limits set by your subscription plan." +#: ../../Zotlabs/Module/Mood.php:134 +msgid "Mood App" msgstr "" -#: ../../include/account.php:818 -msgid "This action is not available under your subscription plan." +#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Module/Mood.php:155 +msgid "Set your current mood and tell your friends" msgstr "" -#: ../../include/photo/photo_driver.php:417 -#: ../../Zotlabs/Module/Profile_photo.php:147 -#: ../../Zotlabs/Module/Profile_photo.php:284 -msgid "Profile Photos" +#: ../../Zotlabs/Module/Mood.php:154 ../../Zotlabs/Lib/Apps.php:350 +msgid "Mood" msgstr "" -#: ../../include/attach.php:273 ../../include/attach.php:324 -#: ../../include/attach.php:419 -msgid "Item was not found." +#: ../../Zotlabs/Module/Permcats.php:29 +msgid "Permission category name is required." msgstr "" -#: ../../include/attach.php:290 -msgid "Unknown error." +#: ../../Zotlabs/Module/Permcats.php:48 +msgid "Permission category saved." msgstr "" -#: ../../include/attach.php:612 -msgid "No source file." +#: ../../Zotlabs/Module/Permcats.php:63 +msgid "Permission Categories App" msgstr "" -#: ../../include/attach.php:634 -msgid "Cannot locate file to replace" +#: ../../Zotlabs/Module/Permcats.php:64 +msgid "Create custom connection permission limits" msgstr "" -#: ../../include/attach.php:653 -msgid "Cannot locate file to revise/update" +#: ../../Zotlabs/Module/Permcats.php:80 +msgid "" +"Use this form to create permission rules for various classes of people or " +"connections." msgstr "" -#: ../../include/attach.php:795 -#, php-format -msgid "File exceeds size limit of %d" +#: ../../Zotlabs/Module/Permcats.php:113 ../../Zotlabs/Lib/Apps.php:374 +msgid "Permission Categories" msgstr "" -#: ../../include/attach.php:816 -#, php-format -msgid "You have reached your limit of %1$.0f Mbytes attachment storage." +#: ../../Zotlabs/Module/Permcats.php:121 +msgid "Permission category name" msgstr "" -#: ../../include/attach.php:1004 -msgid "File upload failed. Possible system limit or action terminated." +#: ../../Zotlabs/Module/Ratings.php:70 +msgid "No ratings" msgstr "" -#: ../../include/attach.php:1033 -msgid "Stored file could not be verified. Upload failed." +#: ../../Zotlabs/Module/Ratings.php:98 +msgid "Rating: " msgstr "" -#: ../../include/attach.php:1105 ../../include/attach.php:1121 -msgid "Path not available." +#: ../../Zotlabs/Module/Ratings.php:99 +msgid "Website: " msgstr "" -#: ../../include/attach.php:1169 ../../include/attach.php:1332 -msgid "Empty pathname" +#: ../../Zotlabs/Module/Ratings.php:101 +msgid "Description: " msgstr "" -#: ../../include/attach.php:1195 -msgid "duplicate filename or path" +#: ../../Zotlabs/Module/Register.php:52 +msgid "Maximum daily site registrations exceeded. Please try again tomorrow." msgstr "" -#: ../../include/attach.php:1220 -msgid "Path not found." +#: ../../Zotlabs/Module/Register.php:58 +msgid "" +"Please indicate acceptance of the Terms of Service. Registration failed." msgstr "" -#: ../../include/attach.php:1288 -msgid "mkdir failed." +#: ../../Zotlabs/Module/Register.php:92 +msgid "Passwords do not match." msgstr "" -#: ../../include/attach.php:1292 -msgid "database storage failed." +#: ../../Zotlabs/Module/Register.php:135 +msgid "Registration successful. Continue to create your first channel..." msgstr "" -#: ../../include/attach.php:1338 -msgid "Empty path" +#: ../../Zotlabs/Module/Register.php:138 +msgid "" +"Registration successful. Please check your email for validation instructions." msgstr "" -#: ../../include/attach.php:2099 -#, php-format -msgid "%s shared a %s with you" +#: ../../Zotlabs/Module/Register.php:145 +msgid "Your registration is pending approval by the site owner." msgstr "" -#: ../../include/bookmarks.php:34 -#, php-format -msgid "%1$s's bookmarks" +#: ../../Zotlabs/Module/Register.php:148 +msgid "Your registration can not be processed." msgstr "" -#: ../../include/menu.php:120 ../../include/channel.php:1538 -#: ../../include/channel.php:1542 ../../Zotlabs/Widget/Cdav.php:138 -#: ../../Zotlabs/Widget/Cdav.php:175 ../../Zotlabs/Module/Article_edit.php:98 -#: ../../Zotlabs/Module/Group.php:253 ../../Zotlabs/Module/Card_edit.php:99 -#: ../../Zotlabs/Module/Oauth.php:173 ../../Zotlabs/Module/Editwebpage.php:142 -#: ../../Zotlabs/Module/Webpages.php:255 -#: ../../Zotlabs/Module/Admin/Profs.php:175 ../../Zotlabs/Module/Blocks.php:160 -#: ../../Zotlabs/Module/Editblock.php:114 -#: ../../Zotlabs/Module/Editlayout.php:114 -#: ../../Zotlabs/Module/Connections.php:320 -#: ../../Zotlabs/Module/Connections.php:362 -#: ../../Zotlabs/Module/Connections.php:382 ../../Zotlabs/Module/Menu.php:176 -#: ../../Zotlabs/Module/Oauth2.php:194 ../../Zotlabs/Module/Thing.php:268 -#: ../../Zotlabs/Module/Wiki.php:211 ../../Zotlabs/Module/Wiki.php:384 -#: ../../Zotlabs/Module/Layouts.php:193 ../../Zotlabs/Lib/Apps.php:557 -#: ../../Zotlabs/Lib/ThreadItem.php:148 -msgid "Edit" +#: ../../Zotlabs/Module/Register.php:195 +msgid "Registration on this hub is disabled." msgstr "" -#: ../../include/bbcode.php:221 ../../include/bbcode.php:896 -#: ../../include/bbcode.php:1486 ../../include/bbcode.php:1494 -msgid "Image/photo" +#: ../../Zotlabs/Module/Register.php:204 +msgid "Registration on this hub is by approval only." msgstr "" -#: ../../include/bbcode.php:268 ../../include/bbcode.php:1511 -msgid "Encrypted content" +#: ../../Zotlabs/Module/Register.php:205 ../../Zotlabs/Module/Register.php:214 +msgid "Register at another affiliated hub." msgstr "" -#: ../../include/bbcode.php:302 -#, php-format -msgid "Install %1$s element %2$s" +#: ../../Zotlabs/Module/Register.php:213 +msgid "Registration on this hub is by invitation only." msgstr "" -#: ../../include/bbcode.php:306 -#, php-format +#: ../../Zotlabs/Module/Register.php:224 msgid "" -"This post contains an installable %s element, however you lack permissions " -"to install it on this site." +"This site has exceeded the number of allowed daily account registrations. " +"Please try again tomorrow." msgstr "" -#: ../../include/bbcode.php:316 ../../Zotlabs/Module/Impel.php:43 -msgid "webpage" +#: ../../Zotlabs/Module/Register.php:239 ../../Zotlabs/Module/Siteinfo.php:28 +msgid "Terms of Service" msgstr "" -#: ../../include/bbcode.php:319 ../../Zotlabs/Module/Impel.php:53 -msgid "layout" +#: ../../Zotlabs/Module/Register.php:245 +#, php-format +msgid "I accept the %s for this website" msgstr "" -#: ../../include/bbcode.php:322 ../../Zotlabs/Module/Impel.php:48 -msgid "block" +#: ../../Zotlabs/Module/Register.php:252 +#, php-format +msgid "I am over %s years of age and accept the %s for this website" msgstr "" -#: ../../include/bbcode.php:325 ../../Zotlabs/Module/Impel.php:60 -msgid "menu" +#: ../../Zotlabs/Module/Register.php:257 +msgid "Your email address" msgstr "" -#: ../../include/bbcode.php:519 -msgid "card" +#: ../../Zotlabs/Module/Register.php:258 +msgid "Choose a password" msgstr "" -#: ../../include/bbcode.php:521 -msgid "article" +#: ../../Zotlabs/Module/Register.php:259 +msgid "Please re-enter your password" msgstr "" -#: ../../include/bbcode.php:527 ../../include/markdown.php:202 -#, php-format -msgid "%1$s wrote the following %2$s %3$s" +#: ../../Zotlabs/Module/Register.php:260 +msgid "Please enter your invitation code" msgstr "" -#: ../../include/bbcode.php:604 ../../include/bbcode.php:612 -msgid "Click to open/close" +#: ../../Zotlabs/Module/Register.php:261 +msgid "Your Name" msgstr "" -#: ../../include/bbcode.php:612 ../../include/markdown.php:251 -msgid "spoiler" +#: ../../Zotlabs/Module/Register.php:261 +msgid "Real names are preferred." msgstr "" -#: ../../include/bbcode.php:625 -msgid "View article" +#: ../../Zotlabs/Module/Register.php:263 +#, php-format +msgid "" +"Your nickname will be used to create an easy to remember channel address e." +"g. nickname%s" msgstr "" -#: ../../include/bbcode.php:625 -msgid "View summary" +#: ../../Zotlabs/Module/Register.php:264 +msgid "" +"Select a channel permission role for your usage needs and privacy " +"requirements." msgstr "" -#: ../../include/bbcode.php:1018 ../../include/bbcode.php:1190 -#: ../../Zotlabs/Lib/NativeWikiPage.php:606 -msgid "Different viewers will see this text differently" +#: ../../Zotlabs/Module/Register.php:265 +msgid "no" msgstr "" -#: ../../include/bbcode.php:1474 -msgid "$1 wrote:" +#: ../../Zotlabs/Module/Register.php:265 +msgid "yes" msgstr "" -#: ../../include/channel.php:46 -msgid "Unable to obtain identity information from database" +#: ../../Zotlabs/Module/Register.php:293 ../../include/nav.php:162 +#: ../../boot.php:1685 +msgid "Register" msgstr "" -#: ../../include/channel.php:79 -msgid "Empty name" +#: ../../Zotlabs/Module/Register.php:294 +msgid "" +"This site requires email verification. After completing this form, please " +"check your email for further instructions." msgstr "" -#: ../../include/channel.php:82 -msgid "Name too long" +#: ../../Zotlabs/Module/Acl.php:123 ../../Zotlabs/Module/Lockview.php:117 +#: ../../Zotlabs/Module/Lockview.php:153 +msgctxt "acl" +msgid "Profile" msgstr "" -#: ../../include/channel.php:199 -msgid "No account identifier" +#: ../../Zotlabs/Module/Acl.php:370 +msgid "network" msgstr "" -#: ../../include/channel.php:211 -msgid "Nickname is required." +#: ../../Zotlabs/Module/Settings/Featured.php:25 +msgid "No feature settings configured" msgstr "" -#: ../../include/channel.php:225 ../../include/channel.php:706 -#: ../../Zotlabs/Module/Changeaddr.php:46 -msgid "Reserved nickname. Please choose another." +#: ../../Zotlabs/Module/Settings/Featured.php:34 +msgid "Addon Settings" msgstr "" -#: ../../include/channel.php:230 ../../include/channel.php:711 -#: ../../Zotlabs/Module/Changeaddr.php:51 -msgid "" -"Nickname has unsupported characters or is already being used on this site." +#: ../../Zotlabs/Module/Settings/Featured.php:35 +msgid "Please save/submit changes to any panel before opening another." msgstr "" -#: ../../include/channel.php:294 -msgid "Unable to retrieve created identity" +#: ../../Zotlabs/Module/Settings/Account.php:19 +msgid "Not valid email." msgstr "" -#: ../../include/channel.php:441 -msgid "Default Profile" +#: ../../Zotlabs/Module/Settings/Account.php:22 +msgid "Protected email address. Cannot change to that email." msgstr "" -#: ../../include/channel.php:639 ../../include/channel.php:728 -msgid "Unable to retrieve modified identity" +#: ../../Zotlabs/Module/Settings/Account.php:31 +msgid "System failure storing new email. Please try again." msgstr "" -#: ../../include/channel.php:1385 -msgid "Requested channel is not available." +#: ../../Zotlabs/Module/Settings/Account.php:48 +msgid "Password verification failed." msgstr "" -#: ../../include/channel.php:1531 ../../Zotlabs/Module/Profiles.php:730 -msgid "Change profile photo" +#: ../../Zotlabs/Module/Settings/Account.php:55 +msgid "Passwords do not match. Password unchanged." msgstr "" -#: ../../include/channel.php:1539 -msgid "Create New Profile" +#: ../../Zotlabs/Module/Settings/Account.php:59 +msgid "Empty passwords are not allowed. Password unchanged." msgstr "" -#: ../../include/channel.php:1557 ../../Zotlabs/Module/Profiles.php:822 -msgid "Profile Image" +#: ../../Zotlabs/Module/Settings/Account.php:73 +msgid "Password changed." msgstr "" -#: ../../include/channel.php:1560 -msgid "Visible to everybody" +#: ../../Zotlabs/Module/Settings/Account.php:75 +msgid "Password update failed. Please try again." msgstr "" -#: ../../include/channel.php:1561 ../../Zotlabs/Module/Profiles.php:727 -#: ../../Zotlabs/Module/Profiles.php:826 -msgid "Edit visibility" +#: ../../Zotlabs/Module/Settings/Account.php:99 +msgid "Account Settings" msgstr "" -#: ../../include/channel.php:1637 ../../include/channel.php:1765 -msgid "Gender:" +#: ../../Zotlabs/Module/Settings/Account.php:100 +msgid "Current Password" msgstr "" -#: ../../include/channel.php:1638 ../../include/channel.php:1809 -msgid "Status:" +#: ../../Zotlabs/Module/Settings/Account.php:101 +msgid "Enter New Password" msgstr "" -#: ../../include/channel.php:1639 ../../include/channel.php:1833 -msgid "Homepage:" +#: ../../Zotlabs/Module/Settings/Account.php:102 +msgid "Confirm New Password" msgstr "" -#: ../../include/channel.php:1640 -msgid "Online Now" +#: ../../Zotlabs/Module/Settings/Account.php:102 +msgid "Leave password fields blank unless changing" msgstr "" -#: ../../include/channel.php:1693 -msgid "Change your profile photo" +#: ../../Zotlabs/Module/Settings/Account.php:104 +#: ../../Zotlabs/Module/Settings/Channel.php:502 +msgid "Email Address:" msgstr "" -#: ../../include/channel.php:1724 -msgid "Trans" +#: ../../Zotlabs/Module/Settings/Account.php:106 +msgid "Remove this account including all its channels" msgstr "" -#: ../../include/channel.php:1763 ../../Zotlabs/Module/Settings/Channel.php:501 -msgid "Full Name:" +#: ../../Zotlabs/Module/Settings/Events.php:40 +msgid "Events Settings" msgstr "" -#: ../../include/channel.php:1770 -msgid "Like this channel" +#: ../../Zotlabs/Module/Settings/Profiles.php:49 +msgid "Profiles Settings" msgstr "" -#: ../../include/channel.php:1794 -msgid "j F, Y" +#: ../../Zotlabs/Module/Settings/Editor.php:40 +msgid "Editor Settings" msgstr "" -#: ../../include/channel.php:1795 -msgid "j F" +#: ../../Zotlabs/Module/Settings/Features.php:45 +msgid "Additional Features" msgstr "" -#: ../../include/channel.php:1802 -msgid "Birthday:" +#: ../../Zotlabs/Module/Settings/Manage.php:41 +msgid "Channel Manager Settings" msgstr "" -#: ../../include/channel.php:1806 ../../Zotlabs/Module/Directory.php:347 -msgid "Age:" +#: ../../Zotlabs/Module/Settings/Display.php:127 +#, php-format +msgid "%s - (Experimental)" msgstr "" -#: ../../include/channel.php:1815 -#, php-format -msgid "for %1$d %2$s" +#: ../../Zotlabs/Module/Settings/Display.php:183 +msgid "Display Settings" msgstr "" -#: ../../include/channel.php:1827 -msgid "Tags:" +#: ../../Zotlabs/Module/Settings/Display.php:184 +msgid "Theme Settings" msgstr "" -#: ../../include/channel.php:1831 -msgid "Sexual Preference:" +#: ../../Zotlabs/Module/Settings/Display.php:185 +msgid "Custom Theme Settings" msgstr "" -#: ../../include/channel.php:1835 ../../Zotlabs/Module/Directory.php:365 -msgid "Hometown:" +#: ../../Zotlabs/Module/Settings/Display.php:186 +msgid "Content Settings" msgstr "" -#: ../../include/channel.php:1837 -msgid "Political Views:" +#: ../../Zotlabs/Module/Settings/Display.php:192 +msgid "Display Theme:" msgstr "" -#: ../../include/channel.php:1839 -msgid "Religion:" +#: ../../Zotlabs/Module/Settings/Display.php:193 +msgid "Select scheme" msgstr "" -#: ../../include/channel.php:1841 ../../Zotlabs/Module/Directory.php:367 -msgid "About:" +#: ../../Zotlabs/Module/Settings/Display.php:195 +msgid "Preload images before rendering the page" msgstr "" -#: ../../include/channel.php:1843 -msgid "Hobbies/Interests:" +#: ../../Zotlabs/Module/Settings/Display.php:195 +msgid "" +"The subjective page load time will be longer but the page will be ready when " +"displayed" msgstr "" -#: ../../include/channel.php:1845 -msgid "Likes:" +#: ../../Zotlabs/Module/Settings/Display.php:196 +msgid "Enable user zoom on mobile devices" msgstr "" -#: ../../include/channel.php:1847 -msgid "Dislikes:" +#: ../../Zotlabs/Module/Settings/Display.php:197 +msgid "Update browser every xx seconds" msgstr "" -#: ../../include/channel.php:1849 -msgid "Contact information and Social Networks:" +#: ../../Zotlabs/Module/Settings/Display.php:197 +msgid "Minimum of 10 seconds, no maximum" msgstr "" -#: ../../include/channel.php:1851 -msgid "My other channels:" +#: ../../Zotlabs/Module/Settings/Display.php:198 +msgid "Maximum number of conversations to load at any time:" msgstr "" -#: ../../include/channel.php:1853 -msgid "Musical interests:" +#: ../../Zotlabs/Module/Settings/Display.php:198 +msgid "Maximum of 30 items" msgstr "" -#: ../../include/channel.php:1855 -msgid "Books, literature:" +#: ../../Zotlabs/Module/Settings/Display.php:199 +msgid "Show emoticons (smilies) as images" msgstr "" -#: ../../include/channel.php:1857 -msgid "Television:" +#: ../../Zotlabs/Module/Settings/Display.php:200 +msgid "Provide channel menu in navigation bar" msgstr "" -#: ../../include/channel.php:1859 -msgid "Film/dance/culture/entertainment:" +#: ../../Zotlabs/Module/Settings/Display.php:200 +msgid "Default: channel menu located in app menu" msgstr "" -#: ../../include/channel.php:1861 -msgid "Love/Romance:" +#: ../../Zotlabs/Module/Settings/Display.php:201 +msgid "Link post titles to source" msgstr "" -#: ../../include/channel.php:1863 -msgid "Work/employment:" +#: ../../Zotlabs/Module/Settings/Display.php:203 +#: ../../Zotlabs/Widget/Newmember.php:75 +msgid "New Member Links" msgstr "" -#: ../../include/channel.php:1865 -msgid "School/education:" +#: ../../Zotlabs/Module/Settings/Display.php:203 +msgid "Display new member quick links menu" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Photos.php:40 +msgid "Photos Settings" msgstr "" -#: ../../include/channel.php:1886 ../../Zotlabs/Module/Profperm.php:113 -#: ../../Zotlabs/Lib/Apps.php:362 -msgid "Profile" +#: ../../Zotlabs/Module/Settings/Channel.php:329 +msgid "Nobody except yourself" msgstr "" -#: ../../include/channel.php:1888 -msgid "Like this thing" +#: ../../Zotlabs/Module/Settings/Channel.php:330 +msgid "Only those you specifically allow" msgstr "" -#: ../../include/channel.php:1889 ../../Zotlabs/Module/Events.php:699 -msgid "Export" +#: ../../Zotlabs/Module/Settings/Channel.php:331 +msgid "Approved connections" msgstr "" -#: ../../include/channel.php:2328 ../../Zotlabs/Module/Cover_photo.php:304 -msgid "cover photo" +#: ../../Zotlabs/Module/Settings/Channel.php:332 +msgid "Any connections" msgstr "" -#: ../../include/channel.php:2597 ../../Zotlabs/Module/Rmagic.php:96 -#: ../../boot.php:1700 -msgid "Remote Authentication" +#: ../../Zotlabs/Module/Settings/Channel.php:333 +msgid "Anybody on this website" msgstr "" -#: ../../include/channel.php:2598 ../../Zotlabs/Module/Rmagic.php:97 -msgid "Enter your channel address (e.g. channel@example.com)" +#: ../../Zotlabs/Module/Settings/Channel.php:334 +msgid "Anybody in this network" msgstr "" -#: ../../include/channel.php:2599 ../../Zotlabs/Module/Rmagic.php:98 -msgid "Authenticate" +#: ../../Zotlabs/Module/Settings/Channel.php:335 +msgid "Anybody authenticated" msgstr "" -#: ../../include/channel.php:2757 ../../Zotlabs/Module/Admin/Accounts.php:91 -#, php-format -msgid "Account '%s' deleted" +#: ../../Zotlabs/Module/Settings/Channel.php:336 +msgid "Anybody on the internet" msgstr "" -#: ../../include/acl_selectors.php:33 -#: ../../Zotlabs/Lib/PermissionDescription.php:34 -msgid "Visible to your default audience" +#: ../../Zotlabs/Module/Settings/Channel.php:411 +msgid "Publish your default profile in the network directory" msgstr "" -#: ../../include/acl_selectors.php:99 -msgid "Profile-Based Privacy Groups" +#: ../../Zotlabs/Module/Settings/Channel.php:416 +msgid "Allow us to suggest you as a potential friend to new members?" msgstr "" -#: ../../include/acl_selectors.php:118 -msgid "Private Forum" +#: ../../Zotlabs/Module/Settings/Channel.php:420 +msgid "or" msgstr "" -#: ../../include/acl_selectors.php:124 ../../Zotlabs/Widget/Forums.php:100 -#: ../../Zotlabs/Widget/Activity_filter.php:115 -#: ../../Zotlabs/Widget/Notifications.php:139 -#: ../../Zotlabs/Widget/Notifications.php:140 -msgid "Forums" +#: ../../Zotlabs/Module/Settings/Channel.php:429 +msgid "Your channel address is" msgstr "" -#: ../../include/acl_selectors.php:135 -#: ../../Zotlabs/Lib/PermissionDescription.php:107 -msgid "Only me" +#: ../../Zotlabs/Module/Settings/Channel.php:432 +msgid "Your files/photos are accessible via WebDAV at" msgstr "" -#: ../../include/acl_selectors.php:142 -msgid "Share with" +#: ../../Zotlabs/Module/Settings/Channel.php:472 +msgid "Automatic membership approval" msgstr "" -#: ../../include/acl_selectors.php:143 -msgid "Custom selection" +#: ../../Zotlabs/Module/Settings/Channel.php:493 +msgid "Channel Settings" msgstr "" -#: ../../include/acl_selectors.php:145 -msgid "" -"Select \"Allow\" to allow viewing. \"Don't allow\" lets you override and " -"limit the scope of \"Allow\"." +#: ../../Zotlabs/Module/Settings/Channel.php:500 +msgid "Basic Settings" msgstr "" -#: ../../include/acl_selectors.php:146 ../../Zotlabs/Module/Authorize.php:32 -msgid "Allow" +#: ../../Zotlabs/Module/Settings/Channel.php:501 ../../include/channel.php:1763 +msgid "Full Name:" msgstr "" -#: ../../include/acl_selectors.php:147 -msgid "Don't allow" +#: ../../Zotlabs/Module/Settings/Channel.php:503 +msgid "Your Timezone:" msgstr "" -#: ../../include/acl_selectors.php:180 -#, php-format -msgid "" -"Post permissions %s cannot be changed %s after a post is shared.
      These " -"permissions set who is allowed to view the post." +#: ../../Zotlabs/Module/Settings/Channel.php:504 +msgid "Default Post Location:" msgstr "" -#: ../../include/oembed.php:153 -msgid "View PDF" +#: ../../Zotlabs/Module/Settings/Channel.php:504 +msgid "Geographical location to display on your posts" msgstr "" -#: ../../include/oembed.php:357 -msgid " by " +#: ../../Zotlabs/Module/Settings/Channel.php:505 +msgid "Use Browser Location:" msgstr "" -#: ../../include/oembed.php:358 -msgid " on " +#: ../../Zotlabs/Module/Settings/Channel.php:507 +msgid "Adult Content" msgstr "" -#: ../../include/oembed.php:387 -msgid "Embedded content" +#: ../../Zotlabs/Module/Settings/Channel.php:507 +msgid "" +"This channel frequently or regularly publishes adult content. (Please tag " +"any adult material and/or nudity with #NSFW)" msgstr "" -#: ../../include/oembed.php:396 -msgid "Embedding disabled" +#: ../../Zotlabs/Module/Settings/Channel.php:509 +msgid "Security and Privacy Settings" msgstr "" -#: ../../include/dir_fns.php:140 ../../Zotlabs/Lib/Libzotdir.php:162 -msgid "Directory Options" +#: ../../Zotlabs/Module/Settings/Channel.php:511 +msgid "Your permissions are already configured. Click to view/adjust" msgstr "" -#: ../../include/dir_fns.php:142 ../../Zotlabs/Lib/Libzotdir.php:164 -msgid "Safe Mode" +#: ../../Zotlabs/Module/Settings/Channel.php:513 +msgid "Hide my online presence" msgstr "" -#: ../../include/dir_fns.php:143 ../../Zotlabs/Lib/Libzotdir.php:165 -msgid "Public Forums Only" +#: ../../Zotlabs/Module/Settings/Channel.php:513 +msgid "Prevents displaying in your profile that you are online" msgstr "" -#: ../../include/dir_fns.php:144 ../../Zotlabs/Lib/Libzotdir.php:167 -msgid "This Website Only" +#: ../../Zotlabs/Module/Settings/Channel.php:515 +msgid "Simple Privacy Settings:" msgstr "" -#: ../../include/zid.php:360 -#, php-format -msgid "OpenWebAuth: %1$s welcomes %2$s" +#: ../../Zotlabs/Module/Settings/Channel.php:516 +msgid "" +"Very Public - extremely permissive (should be used with caution)" msgstr "" -#: ../../include/message.php:41 -msgid "Unable to determine sender." +#: ../../Zotlabs/Module/Settings/Channel.php:517 +msgid "" +"Typical - default public, privacy when desired (similar to social " +"network permissions but with improved privacy)" msgstr "" -#: ../../include/message.php:80 -msgid "No recipient provided." +#: ../../Zotlabs/Module/Settings/Channel.php:518 +msgid "Private - default private, never open or public" msgstr "" -#: ../../include/message.php:85 -msgid "[no subject]" +#: ../../Zotlabs/Module/Settings/Channel.php:519 +msgid "Blocked - default blocked to/from everybody" msgstr "" -#: ../../include/message.php:214 -msgid "Stored post could not be verified." +#: ../../Zotlabs/Module/Settings/Channel.php:521 +msgid "Allow others to tag your posts" msgstr "" -#: ../../Zotlabs/Widget/Activity_order.php:90 -msgid "Commented Date" +#: ../../Zotlabs/Module/Settings/Channel.php:521 +msgid "" +"Often used by the community to retro-actively flag inappropriate content" msgstr "" -#: ../../Zotlabs/Widget/Activity_order.php:94 -msgid "Order by last commented date" +#: ../../Zotlabs/Module/Settings/Channel.php:523 +msgid "Channel Permission Limits" msgstr "" -#: ../../Zotlabs/Widget/Activity_order.php:97 -msgid "Posted Date" +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "Expire other channel content after this many days" msgstr "" -#: ../../Zotlabs/Widget/Activity_order.php:101 -msgid "Order by last posted date" +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "0 or blank to use the website limit." msgstr "" -#: ../../Zotlabs/Widget/Activity_order.php:104 -msgid "Date Unthreaded" +#: ../../Zotlabs/Module/Settings/Channel.php:525 +#, php-format +msgid "This website expires after %d days." msgstr "" -#: ../../Zotlabs/Widget/Activity_order.php:108 -msgid "Order unthreaded by date" +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "This website does not expire imported content." msgstr "" -#: ../../Zotlabs/Widget/Activity_order.php:123 -msgid "Stream Order" +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "The website limit takes precedence if lower than your limit." msgstr "" -#: ../../Zotlabs/Widget/Archive.php:43 -msgid "Archives" +#: ../../Zotlabs/Module/Settings/Channel.php:526 +msgid "Maximum Friend Requests/Day:" msgstr "" -#: ../../Zotlabs/Widget/Wiki_pages.php:34 -#: ../../Zotlabs/Widget/Wiki_pages.php:91 -msgid "Add new page" +#: ../../Zotlabs/Module/Settings/Channel.php:526 +msgid "May reduce spam activity" msgstr "" -#: ../../Zotlabs/Widget/Wiki_pages.php:41 -#: ../../Zotlabs/Widget/Wiki_pages.php:98 ../../Zotlabs/Module/Dreport.php:166 -msgid "Options" +#: ../../Zotlabs/Module/Settings/Channel.php:527 +msgid "Default Privacy Group" msgstr "" -#: ../../Zotlabs/Widget/Wiki_pages.php:85 -msgid "Wiki Pages" +#: ../../Zotlabs/Module/Settings/Channel.php:529 +msgid "Use my default audience setting for the type of object published" msgstr "" -#: ../../Zotlabs/Widget/Wiki_pages.php:96 -msgid "Page name" +#: ../../Zotlabs/Module/Settings/Channel.php:538 +msgid "Default permissions category" msgstr "" -#: ../../Zotlabs/Widget/Album.php:78 ../../Zotlabs/Widget/Portfolio.php:87 -#: ../../Zotlabs/Module/Embedphotos.php:170 ../../Zotlabs/Module/Photos.php:787 -#: ../../Zotlabs/Module/Photos.php:1333 -msgid "View Photo" +#: ../../Zotlabs/Module/Settings/Channel.php:544 +msgid "Maximum private messages per day from unknown people:" msgstr "" -#: ../../Zotlabs/Widget/Album.php:95 ../../Zotlabs/Widget/Portfolio.php:108 -#: ../../Zotlabs/Module/Embedphotos.php:186 ../../Zotlabs/Module/Photos.php:818 -msgid "Edit Album" +#: ../../Zotlabs/Module/Settings/Channel.php:544 +msgid "Useful to reduce spamming" msgstr "" -#: ../../Zotlabs/Widget/Album.php:97 ../../Zotlabs/Widget/Cdav.php:146 -#: ../../Zotlabs/Widget/Cdav.php:182 ../../Zotlabs/Widget/Portfolio.php:110 -#: ../../Zotlabs/Module/Embedphotos.php:188 -#: ../../Zotlabs/Module/Profile_photo.php:500 -#: ../../Zotlabs/Module/Cover_photo.php:423 ../../Zotlabs/Module/Photos.php:688 -#: ../../Zotlabs/Storage/Browser.php:533 -msgid "Upload" +#: ../../Zotlabs/Module/Settings/Channel.php:547 +#: ../../Zotlabs/Lib/Enotify.php:68 +msgid "Notification Settings" msgstr "" -#: ../../Zotlabs/Widget/Tasklist.php:23 -msgid "Tasks" +#: ../../Zotlabs/Module/Settings/Channel.php:548 +msgid "By default post a status message when:" msgstr "" -#: ../../Zotlabs/Widget/Pubsites.php:12 ../../Zotlabs/Module/Pubsites.php:24 -msgid "Public Hubs" +#: ../../Zotlabs/Module/Settings/Channel.php:549 +msgid "accepting a friend request" msgstr "" -#: ../../Zotlabs/Widget/Conversations.php:17 -msgid "Received Messages" +#: ../../Zotlabs/Module/Settings/Channel.php:550 +msgid "joining a forum/community" msgstr "" -#: ../../Zotlabs/Widget/Conversations.php:21 -msgid "Sent Messages" +#: ../../Zotlabs/Module/Settings/Channel.php:551 +msgid "making an interesting profile change" msgstr "" -#: ../../Zotlabs/Widget/Conversations.php:25 -msgid "Conversations" +#: ../../Zotlabs/Module/Settings/Channel.php:552 +msgid "Send a notification email when:" msgstr "" -#: ../../Zotlabs/Widget/Conversations.php:37 -msgid "No messages." +#: ../../Zotlabs/Module/Settings/Channel.php:553 +msgid "You receive a connection request" msgstr "" -#: ../../Zotlabs/Widget/Conversations.php:57 -msgid "Delete conversation" +#: ../../Zotlabs/Module/Settings/Channel.php:554 +msgid "Your connections are confirmed" msgstr "" -#: ../../Zotlabs/Widget/Chatroom_members.php:11 -msgid "Chat Members" +#: ../../Zotlabs/Module/Settings/Channel.php:555 +msgid "Someone writes on your profile wall" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:70 ../../Zotlabs/Lib/ThreadItem.php:205 -msgid "I will attend" +#: ../../Zotlabs/Module/Settings/Channel.php:556 +msgid "Someone writes a followup comment" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:70 ../../Zotlabs/Lib/ThreadItem.php:205 -msgid "I will not attend" +#: ../../Zotlabs/Module/Settings/Channel.php:557 +msgid "You receive a private message" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:70 ../../Zotlabs/Lib/ThreadItem.php:205 -msgid "I might attend" +#: ../../Zotlabs/Module/Settings/Channel.php:558 +msgid "You receive a friend suggestion" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:81 ../../Zotlabs/Lib/ThreadItem.php:219 -msgid "I agree" +#: ../../Zotlabs/Module/Settings/Channel.php:559 +msgid "You are tagged in a post" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:81 ../../Zotlabs/Lib/ThreadItem.php:219 -msgid "I disagree" +#: ../../Zotlabs/Module/Settings/Channel.php:560 +msgid "You are poked/prodded/etc. in a post" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:81 ../../Zotlabs/Lib/ThreadItem.php:219 -msgid "I abstain" +#: ../../Zotlabs/Module/Settings/Channel.php:562 +msgid "Someone likes your post/comment" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:99 ../../Zotlabs/Lib/ThreadItem.php:329 -msgid "Share This" +#: ../../Zotlabs/Module/Settings/Channel.php:565 +msgid "Show visual notifications including:" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:99 ../../Zotlabs/Lib/ThreadItem.php:329 -msgid "share" +#: ../../Zotlabs/Module/Settings/Channel.php:567 +msgid "Unseen stream activity" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:123 ../../Zotlabs/Widget/Pinned.php:124 -#, php-format -msgid "View %s's profile - %s" +#: ../../Zotlabs/Module/Settings/Channel.php:568 +msgid "Unseen channel activity" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:128 ../../Zotlabs/Lib/ThreadItem.php:413 -msgid "via" +#: ../../Zotlabs/Module/Settings/Channel.php:569 +msgid "Unseen private messages" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:143 ../../Zotlabs/Lib/ThreadItem.php:443 -msgid "Attendance Options" +#: ../../Zotlabs/Module/Settings/Channel.php:569 +#: ../../Zotlabs/Module/Settings/Channel.php:574 +#: ../../Zotlabs/Module/Settings/Channel.php:575 +#: ../../Zotlabs/Module/Settings/Channel.php:576 +msgid "Recommended" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:144 ../../Zotlabs/Lib/ThreadItem.php:445 -msgid "Voting Options" +#: ../../Zotlabs/Module/Settings/Channel.php:570 +msgid "Upcoming events" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:156 ../../Zotlabs/Lib/ThreadItem.php:469 -msgid "Pinned post" +#: ../../Zotlabs/Module/Settings/Channel.php:571 +msgid "Events today" msgstr "" -#: ../../Zotlabs/Widget/Pinned.php:158 -msgid "Don't show" +#: ../../Zotlabs/Module/Settings/Channel.php:572 +msgid "Upcoming birthdays" msgstr "" -#: ../../Zotlabs/Widget/Activity.php:50 -msgctxt "widget" -msgid "Activity" +#: ../../Zotlabs/Module/Settings/Channel.php:572 +msgid "Not available in all themes" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:37 -msgid "Select Channel" +#: ../../Zotlabs/Module/Settings/Channel.php:573 +msgid "System (personal) notifications" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:42 -msgid "Read-write" +#: ../../Zotlabs/Module/Settings/Channel.php:574 +msgid "System info messages" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:43 -msgid "Read-only" +#: ../../Zotlabs/Module/Settings/Channel.php:575 +msgid "System critical alerts" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:127 -msgid "Channel Calendar" +#: ../../Zotlabs/Module/Settings/Channel.php:576 +msgid "New connections" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:129 ../../Zotlabs/Widget/Cdav.php:143 -#: ../../Zotlabs/Module/Cdav.php:1055 -msgid "CalDAV Calendars" +#: ../../Zotlabs/Module/Settings/Channel.php:577 +msgid "System Registrations" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:131 -msgid "Shared CalDAV Calendars" +#: ../../Zotlabs/Module/Settings/Channel.php:578 +msgid "Unseen shared files" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:135 -msgid "Share this calendar" +#: ../../Zotlabs/Module/Settings/Channel.php:579 +msgid "Unseen public stream activity" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:137 -msgid "Calendar name and color" +#: ../../Zotlabs/Module/Settings/Channel.php:580 +msgid "Unseen likes and dislikes" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:139 -msgid "Create new CalDAV calendar" +#: ../../Zotlabs/Module/Settings/Channel.php:581 +msgid "Unseen forum posts" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:140 ../../Zotlabs/Widget/Cdav.php:178 -#: ../../Zotlabs/Module/Cdav.php:1059 ../../Zotlabs/Module/Cdav.php:1387 -#: ../../Zotlabs/Module/Webpages.php:254 -#: ../../Zotlabs/Module/New_channel.php:189 ../../Zotlabs/Module/Cards.php:113 -#: ../../Zotlabs/Module/Blocks.php:159 ../../Zotlabs/Module/Profiles.php:800 -#: ../../Zotlabs/Module/Articles.php:117 ../../Zotlabs/Module/Menu.php:182 -#: ../../Zotlabs/Module/Connedit.php:930 ../../Zotlabs/Module/Layouts.php:185 -#: ../../Zotlabs/Storage/Browser.php:358 ../../Zotlabs/Storage/Browser.php:531 -msgid "Create" +#: ../../Zotlabs/Module/Settings/Channel.php:582 +msgid "Email notification hub (hostname)" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:141 -msgid "Calendar Name" +#: ../../Zotlabs/Module/Settings/Channel.php:582 +#, php-format +msgid "" +"If your channel is mirrored to multiple hubs, set this to your preferred " +"location. This will prevent duplicate email notifications. Example: %s" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:142 -msgid "Calendar Tools" +#: ../../Zotlabs/Module/Settings/Channel.php:583 +msgid "Show new wall posts, private messages and connections under Notices" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:143 ../../Zotlabs/Module/Cdav.php:1055 -msgid "Channel Calendars" +#: ../../Zotlabs/Module/Settings/Channel.php:585 +msgid "Notify me of events this many days in advance" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:144 -msgid "Import calendar" +#: ../../Zotlabs/Module/Settings/Channel.php:585 +msgid "Must be greater than 0" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:145 -msgid "Select a calendar to import to" +#: ../../Zotlabs/Module/Settings/Channel.php:590 +msgid "Advanced Account/Page Type Settings" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:172 -msgid "Addressbooks" +#: ../../Zotlabs/Module/Settings/Channel.php:591 +msgid "Change the behaviour of this account for special situations" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:174 -msgid "Addressbook name" +#: ../../Zotlabs/Module/Settings/Channel.php:593 +msgid "Miscellaneous Settings" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:176 -msgid "Create new addressbook" +#: ../../Zotlabs/Module/Settings/Channel.php:594 +msgid "Default photo upload folder" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:177 -msgid "Addressbook Name" +#: ../../Zotlabs/Module/Settings/Channel.php:594 +#: ../../Zotlabs/Module/Settings/Channel.php:595 +msgid "%Y - current year, %m - current month" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:179 -msgid "Addressbook Tools" +#: ../../Zotlabs/Module/Settings/Channel.php:595 +msgid "Default file upload folder" msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:180 -msgid "Import addressbook" +#: ../../Zotlabs/Module/Settings/Channel.php:597 +msgid "Remove this channel." msgstr "" -#: ../../Zotlabs/Widget/Cdav.php:181 -msgid "Select an addressbook to import to" +#: ../../Zotlabs/Module/Settings/Connections.php:40 +msgid "Connections Settings" msgstr "" -#: ../../Zotlabs/Widget/Savedsearch.php:75 -msgid "Remove term" +#: ../../Zotlabs/Module/Settings/Calendar.php:40 +msgid "Calendar Settings" msgstr "" -#: ../../Zotlabs/Widget/Suggestedchats.php:32 -msgid "Suggested Chatrooms" +#: ../../Zotlabs/Module/Settings/Directory.php:40 +msgid "Directory Settings" msgstr "" -#: ../../Zotlabs/Widget/Settings_menu.php:32 -msgid "Account settings" +#: ../../Zotlabs/Module/Settings/Channel_home.php:46 +#: ../../Zotlabs/Module/Settings/Network.php:42 +msgid "Max height of content (in pixels)" msgstr "" -#: ../../Zotlabs/Widget/Settings_menu.php:38 -msgid "Channel settings" +#: ../../Zotlabs/Module/Settings/Channel_home.php:48 +#: ../../Zotlabs/Module/Settings/Network.php:44 +msgid "Click to expand content exceeding this height" msgstr "" -#: ../../Zotlabs/Widget/Settings_menu.php:46 -msgid "Display settings" +#: ../../Zotlabs/Module/Settings/Channel_home.php:61 +msgid "Personal menu to display in your channel pages" msgstr "" -#: ../../Zotlabs/Widget/Settings_menu.php:53 -msgid "Manage locations" +#: ../../Zotlabs/Module/Settings/Channel_home.php:88 +msgid "Channel Home Settings" msgstr "" -#: ../../Zotlabs/Widget/Chatroom_list.php:20 -msgid "Overview" +#: ../../Zotlabs/Module/Settings/Network.php:59 +msgid "Stream Settings" msgstr "" -#: ../../Zotlabs/Widget/Suggestions.php:48 ../../Zotlabs/Module/Suggest.php:73 -msgid "Ignore/Hide" +#: ../../Zotlabs/Module/Settings/Conversation.php:23 +msgid "Settings saved." msgstr "" -#: ../../Zotlabs/Widget/Suggestions.php:53 -msgid "Suggestions" +#: ../../Zotlabs/Module/Settings/Conversation.php:25 +msgid "Settings saved. Reload page please." msgstr "" -#: ../../Zotlabs/Widget/Suggestions.php:54 -msgid "See more..." +#: ../../Zotlabs/Module/Settings/Conversation.php:47 +msgid "Conversation Settings" msgstr "" -#: ../../Zotlabs/Widget/Bookmarkedchats.php:24 -msgid "Bookmarked Chatrooms" +#: ../../Zotlabs/Module/Probe.php:18 +msgid "Remote Diagnostics App" msgstr "" -#: ../../Zotlabs/Widget/Wiki_page_history.php:23 -#: ../../Zotlabs/Lib/NativeWikiPage.php:565 -msgctxt "wiki_history" -msgid "Message" +#: ../../Zotlabs/Module/Probe.php:19 +msgid "Perform diagnostics on remote channels" msgstr "" -#: ../../Zotlabs/Widget/Wiki_page_history.php:24 -#: ../../Zotlabs/Lib/NativeWikiPage.php:566 -msgid "Date" +#: ../../Zotlabs/Module/Invite.php:37 +msgid "Total invitation limit exceeded." msgstr "" -#: ../../Zotlabs/Widget/Wiki_page_history.php:25 -#: ../../Zotlabs/Module/Wiki.php:367 ../../Zotlabs/Lib/NativeWikiPage.php:567 -msgid "Revert" +#: ../../Zotlabs/Module/Invite.php:61 +#, php-format +msgid "%s : Not a valid email address." msgstr "" -#: ../../Zotlabs/Widget/Wiki_page_history.php:26 -#: ../../Zotlabs/Lib/NativeWikiPage.php:568 -msgid "Compare" +#: ../../Zotlabs/Module/Invite.php:75 +msgid "Please join us on $Projectname" msgstr "" -#: ../../Zotlabs/Widget/Hq_controls.php:14 -msgid "HQ Control Panel" +#: ../../Zotlabs/Module/Invite.php:85 +msgid "Invitation limit exceeded. Please contact your site administrator." msgstr "" -#: ../../Zotlabs/Widget/Hq_controls.php:17 -msgid "Create a new post" +#: ../../Zotlabs/Module/Invite.php:90 +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:40 +#, php-format +msgid "%s : Message delivery failed." msgstr "" -#: ../../Zotlabs/Widget/Mailmenu.php:13 -msgid "Private Mail Menu" +#: ../../Zotlabs/Module/Invite.php:94 +#, php-format +msgid "%d message sent." +msgid_plural "%d messages sent." +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Invite.php:110 +msgid "Invite App" msgstr "" -#: ../../Zotlabs/Widget/Mailmenu.php:15 -msgid "Combined View" +#: ../../Zotlabs/Module/Invite.php:111 +msgid "Send email invitations to join this network" msgstr "" -#: ../../Zotlabs/Widget/Mailmenu.php:20 -msgid "Inbox" +#: ../../Zotlabs/Module/Invite.php:124 +msgid "You have no more invitations available" msgstr "" -#: ../../Zotlabs/Widget/Mailmenu.php:25 -msgid "Outbox" +#: ../../Zotlabs/Module/Invite.php:155 +msgid "Send invitations" msgstr "" -#: ../../Zotlabs/Widget/Mailmenu.php:30 -msgid "New Message" +#: ../../Zotlabs/Module/Invite.php:156 +msgid "Enter email addresses, one per line:" msgstr "" -#: ../../Zotlabs/Widget/Photo.php:48 ../../Zotlabs/Widget/Photo_rand.php:58 -msgid "photo/image" +#: ../../Zotlabs/Module/Invite.php:157 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:163 +msgid "Your message:" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:22 ../../Zotlabs/Module/Admin/Site.php:292 -msgid "Site" +#: ../../Zotlabs/Module/Invite.php:158 +msgid "Please join my community on $Projectname." msgstr "" -#: ../../Zotlabs/Widget/Admin.php:23 -#: ../../Zotlabs/Module/Admin/Accounts.php:167 -#: ../../Zotlabs/Module/Admin/Accounts.php:180 -#: ../../Zotlabs/Module/Admin.php:96 -msgid "Accounts" +#: ../../Zotlabs/Module/Invite.php:160 +msgid "You will need to supply this invitation code:" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:23 ../../Zotlabs/Widget/Admin.php:60 -msgid "Member registrations waiting for confirmation" +#: ../../Zotlabs/Module/Invite.php:161 +msgid "1. Register at any $Projectname location (they are all inter-connected)" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:24 -#: ../../Zotlabs/Module/Admin/Channels.php:146 -#: ../../Zotlabs/Module/Admin.php:114 -msgid "Channels" +#: ../../Zotlabs/Module/Invite.php:163 +msgid "2. Enter my $Projectname network address into the site searchbar." msgstr "" -#: ../../Zotlabs/Widget/Admin.php:25 ../../Zotlabs/Module/Admin/Security.php:99 -msgid "Security" +#: ../../Zotlabs/Module/Invite.php:164 +msgid "or visit" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:26 ../../Zotlabs/Lib/Apps.php:358 -msgid "Features" +#: ../../Zotlabs/Module/Invite.php:166 +msgid "3. Click [Connect]" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:27 ../../Zotlabs/Module/Admin/Addons.php:343 -#: ../../Zotlabs/Module/Admin/Addons.php:441 -msgid "Addons" +#: ../../Zotlabs/Module/Siteinfo.php:21 +msgid "About this site" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:28 ../../Zotlabs/Module/Admin/Themes.php:123 -#: ../../Zotlabs/Module/Admin/Themes.php:157 -msgid "Themes" +#: ../../Zotlabs/Module/Siteinfo.php:22 +msgid "Site Name" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:29 -msgid "Inspect queue" +#: ../../Zotlabs/Module/Siteinfo.php:26 +msgid "Administrator" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:30 ../../Zotlabs/Module/Admin/Profs.php:168 -msgid "Profile Fields" +#: ../../Zotlabs/Module/Siteinfo.php:29 +msgid "Software and Project information" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:31 -msgid "DB updates" +#: ../../Zotlabs/Module/Siteinfo.php:30 +msgid "This site is powered by $Projectname" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:48 ../../Zotlabs/Widget/Admin.php:58 -#: ../../Zotlabs/Module/Admin/Logs.php:83 -msgid "Logs" +#: ../../Zotlabs/Module/Siteinfo.php:31 +msgid "" +"Federated and decentralised networking and identity services provided by Zot" msgstr "" -#: ../../Zotlabs/Widget/Admin.php:56 -msgid "Addon Features" +#: ../../Zotlabs/Module/Siteinfo.php:34 +msgid "Additional federated transport protocols:" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:33 -msgid "Direct Messages" +#: ../../Zotlabs/Module/Siteinfo.php:36 +#, php-format +msgid "Version %s" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:37 -msgid "Show direct (private) messages" +#: ../../Zotlabs/Module/Siteinfo.php:37 +msgid "Project homepage" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:42 -msgid "Events" +#: ../../Zotlabs/Module/Siteinfo.php:38 +msgid "Developer homepage" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:46 -msgid "Show posts that include events" +#: ../../Zotlabs/Module/Service_limits.php:23 +msgid "No service class restrictions found." msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:52 -msgid "Polls" +#: ../../Zotlabs/Module/Rbmark.php:94 +msgid "Select a bookmark folder" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:56 -msgid "Show posts that include polls" +#: ../../Zotlabs/Module/Rbmark.php:99 +msgid "Save Bookmark" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:77 -#, php-format -msgid "Show posts related to the %s privacy group" +#: ../../Zotlabs/Module/Rbmark.php:100 +msgid "URL of bookmark" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:86 -msgid "Show my privacy groups" +#: ../../Zotlabs/Module/Rbmark.php:105 +msgid "Or enter new bookmark folder name" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:108 -msgid "Show posts to this forum" +#: ../../Zotlabs/Module/Lang.php:17 +msgid "Language App" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:119 -msgid "Show forums" +#: ../../Zotlabs/Module/Lang.php:18 +msgid "Change UI language" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:133 -msgid "Starred Posts" +#: ../../Zotlabs/Module/Hq.php:131 +msgid "Welcome to Hubzilla!" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:137 -msgid "Show posts that I have starred" +#: ../../Zotlabs/Module/Hq.php:131 +msgid "You have got no unseen posts..." msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:148 -msgid "Personal Posts" +#: ../../Zotlabs/Module/Cover_photo.php:196 +#: ../../Zotlabs/Module/Cover_photo.php:254 +msgid "Cover Photos" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:152 -msgid "Show posts that mention or involve me" +#: ../../Zotlabs/Module/Cover_photo.php:297 ../../include/items.php:4860 +msgid "female" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:173 +#: ../../Zotlabs/Module/Cover_photo.php:298 ../../include/items.php:4861 #, php-format -msgid "Show posts that I have filed to %s" +msgid "%1$s updated her %2$s" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:183 -msgid "Show filed post categories" +#: ../../Zotlabs/Module/Cover_photo.php:299 ../../include/items.php:4862 +msgid "male" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:197 -msgid "Panel search" +#: ../../Zotlabs/Module/Cover_photo.php:300 ../../include/items.php:4863 +#, php-format +msgid "%1$s updated his %2$s" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:207 -msgid "Filter by name" +#: ../../Zotlabs/Module/Cover_photo.php:302 ../../include/items.php:4865 +#, php-format +msgid "%1$s updated their %2$s" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:222 -msgid "Remove active filter" +#: ../../Zotlabs/Module/Cover_photo.php:304 ../../include/channel.php:2328 +msgid "cover photo" msgstr "" -#: ../../Zotlabs/Widget/Activity_filter.php:238 -msgid "Stream Filters" +#: ../../Zotlabs/Module/Cover_photo.php:418 +msgid "Your cover photo may be visible to anybody on the internet" msgstr "" -#: ../../Zotlabs/Widget/Appstore.php:11 -msgid "App Collections" +#: ../../Zotlabs/Module/Cover_photo.php:422 +msgid "Change Cover Photo" msgstr "" -#: ../../Zotlabs/Widget/Appstore.php:13 -msgid "Installed apps" +#: ../../Zotlabs/Module/Menu.php:68 +msgid "Unable to update menu." msgstr "" -#: ../../Zotlabs/Widget/Appstore.php:14 ../../Zotlabs/Module/Apps.php:50 -msgid "Available Apps" +#: ../../Zotlabs/Module/Menu.php:79 +msgid "Unable to create menu." msgstr "" -#: ../../Zotlabs/Widget/Eventstools.php:13 -msgid "Events Tools" +#: ../../Zotlabs/Module/Menu.php:161 ../../Zotlabs/Module/Menu.php:174 +msgid "Menu Name" msgstr "" -#: ../../Zotlabs/Widget/Eventstools.php:14 -msgid "Export Calendar" +#: ../../Zotlabs/Module/Menu.php:161 +msgid "Unique name (not visible on webpage) - required" msgstr "" -#: ../../Zotlabs/Widget/Eventstools.php:15 -msgid "Import Calendar" +#: ../../Zotlabs/Module/Menu.php:162 ../../Zotlabs/Module/Menu.php:175 +msgid "Menu Title" msgstr "" -#: ../../Zotlabs/Widget/Rating.php:51 -msgid "Rating Tools" +#: ../../Zotlabs/Module/Menu.php:162 +msgid "Visible on webpage - leave empty for no title" msgstr "" -#: ../../Zotlabs/Widget/Rating.php:55 ../../Zotlabs/Widget/Rating.php:57 -msgid "Rate Me" +#: ../../Zotlabs/Module/Menu.php:163 +msgid "Allow Bookmarks" msgstr "" -#: ../../Zotlabs/Widget/Rating.php:60 -msgid "View Ratings" +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +msgid "Menu may be used to store saved bookmarks" msgstr "" -#: ../../Zotlabs/Widget/Cover_photo.php:65 -msgid "Click to show more" +#: ../../Zotlabs/Module/Menu.php:164 ../../Zotlabs/Module/Menu.php:225 +msgid "Submit and proceed" msgstr "" -#: ../../Zotlabs/Widget/Follow.php:22 -#, php-format -msgid "You have %1$.0f of %2$.0f allowed connections." +#: ../../Zotlabs/Module/Menu.php:171 ../../include/text.php:2699 +msgid "Menus" msgstr "" -#: ../../Zotlabs/Widget/Follow.php:29 -msgid "Add New Connection" +#: ../../Zotlabs/Module/Menu.php:181 +msgid "Bookmarks allowed" msgstr "" -#: ../../Zotlabs/Widget/Follow.php:30 -msgid "Enter channel address" +#: ../../Zotlabs/Module/Menu.php:183 +msgid "Delete this menu" msgstr "" -#: ../../Zotlabs/Widget/Follow.php:31 -msgid "Examples: bob@example.com, https://example.com/barbara" +#: ../../Zotlabs/Module/Menu.php:184 ../../Zotlabs/Module/Menu.php:219 +msgid "Edit menu contents" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:31 -msgid "Profile Creation" +#: ../../Zotlabs/Module/Menu.php:185 +msgid "Edit this menu" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:33 -msgid "Upload profile photo" +#: ../../Zotlabs/Module/Menu.php:201 +msgid "Menu could not be deleted." msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:34 -msgid "Upload cover photo" +#: ../../Zotlabs/Module/Menu.php:214 +msgid "Edit Menu" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:38 -msgid "Find and Connect with others" +#: ../../Zotlabs/Module/Menu.php:218 +msgid "Add or remove entries to this menu" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:40 -msgid "View the directory" +#: ../../Zotlabs/Module/Menu.php:220 +msgid "Menu name" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:41 ../../Zotlabs/Module/Go.php:38 -msgid "View friend suggestions" +#: ../../Zotlabs/Module/Menu.php:220 +msgid "Must be unique, only seen by you" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:42 -msgid "Manage your connections" +#: ../../Zotlabs/Module/Menu.php:221 +msgid "Menu title" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:45 -msgid "Communicate" +#: ../../Zotlabs/Module/Menu.php:221 +msgid "Menu title as seen by others" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:47 -msgid "View your channel homepage" +#: ../../Zotlabs/Module/Menu.php:222 +msgid "Allow bookmarks" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:48 -msgid "View your network stream" +#: ../../Zotlabs/Module/Sources.php:41 +msgid "Failed to create source. No channel selected." msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:54 -msgid "Documentation" +#: ../../Zotlabs/Module/Sources.php:57 +msgid "Source created." msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:57 -msgid "Missing Features?" +#: ../../Zotlabs/Module/Sources.php:70 +msgid "Source updated." msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:59 -msgid "Pin apps to navigation bar" +#: ../../Zotlabs/Module/Sources.php:88 +msgid "Sources App" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:60 -msgid "Install more apps" +#: ../../Zotlabs/Module/Sources.php:89 +msgid "Automatically import channel content from other channels or feeds" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:71 -msgid "View public stream" +#: ../../Zotlabs/Module/Sources.php:101 +msgid "*" msgstr "" -#: ../../Zotlabs/Widget/Newmember.php:75 -#: ../../Zotlabs/Module/Settings/Display.php:203 -msgid "New Member Links" +#: ../../Zotlabs/Module/Sources.php:107 ../../Zotlabs/Lib/Apps.php:368 +msgid "Channel Sources" msgstr "" -#: ../../Zotlabs/Widget/Affinity.php:30 ../../Zotlabs/Module/Connedit.php:715 -msgid "Me" +#: ../../Zotlabs/Module/Sources.php:108 +msgid "Manage remote sources of content for your channel." msgstr "" -#: ../../Zotlabs/Widget/Affinity.php:31 ../../Zotlabs/Module/Connedit.php:716 -msgid "Family" +#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:119 +msgid "New Source" msgstr "" -#: ../../Zotlabs/Widget/Affinity.php:33 ../../Zotlabs/Module/Connedit.php:718 -msgid "Acquaintances" +#: ../../Zotlabs/Module/Sources.php:120 ../../Zotlabs/Module/Sources.php:154 +msgid "" +"Import all or selected content from the following channel into this channel " +"and distribute it according to your channel settings." msgstr "" -#: ../../Zotlabs/Widget/Affinity.php:34 ../../Zotlabs/Module/Connections.php:97 -#: ../../Zotlabs/Module/Connections.php:111 -#: ../../Zotlabs/Module/Connedit.php:719 -msgid "All" +#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 +msgid "Only import content with these words (one per line)" msgstr "" -#: ../../Zotlabs/Widget/Affinity.php:54 -msgid "Refresh" +#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 +msgid "Leave blank to import all public content" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:16 -msgid "New Network Activity" +#: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:161 +msgid "Channel Name" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:17 -msgid "New Network Activity Notifications" +#: ../../Zotlabs/Module/Sources.php:123 ../../Zotlabs/Module/Sources.php:158 +msgid "" +"Add the following categories to posts imported from this source (comma " +"separated)" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:20 -msgid "View your network activity" +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +msgid "Resend posts with this channel as author" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +msgid "Copyrights may apply" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:23 -#: ../../Zotlabs/Widget/Notifications.php:62 -msgid "Mark all notifications read" +#: ../../Zotlabs/Module/Sources.php:144 ../../Zotlabs/Module/Sources.php:174 +msgid "Source not found." msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:26 -#: ../../Zotlabs/Widget/Notifications.php:46 -#: ../../Zotlabs/Widget/Notifications.php:65 -#: ../../Zotlabs/Widget/Notifications.php:172 -msgid "Show new posts only" +#: ../../Zotlabs/Module/Sources.php:151 +msgid "Edit Source" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:27 -#: ../../Zotlabs/Widget/Notifications.php:47 -#: ../../Zotlabs/Widget/Notifications.php:66 -#: ../../Zotlabs/Widget/Notifications.php:142 -#: ../../Zotlabs/Widget/Notifications.php:173 -msgid "Filter by name or address" +#: ../../Zotlabs/Module/Sources.php:152 +msgid "Delete Source" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:36 -msgid "New Home Activity" +#: ../../Zotlabs/Module/Sources.php:182 +msgid "Source removed" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:37 -msgid "New Home Activity Notifications" +#: ../../Zotlabs/Module/Sources.php:184 +msgid "Unable to remove source." msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:40 -msgid "View your home activity" +#: ../../Zotlabs/Module/Poke.php:165 +msgid "Poke App" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:43 -#: ../../Zotlabs/Widget/Notifications.php:169 -msgid "Mark all notifications seen" +#: ../../Zotlabs/Module/Poke.php:166 +msgid "Poke somebody in your addressbook" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:55 -msgid "New Direct Messages" +#: ../../Zotlabs/Module/Poke.php:199 ../../Zotlabs/Lib/Apps.php:351 +#: ../../include/conversation.php:1140 +msgid "Poke" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:56 -msgid "New Direct Messages Notifications" +#: ../../Zotlabs/Module/Poke.php:200 +msgid "Poke somebody" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:59 -msgid "View your direct messages" +#: ../../Zotlabs/Module/Poke.php:203 +msgid "Poke/Prod" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:74 -msgid "New Mails" +#: ../../Zotlabs/Module/Poke.php:204 +msgid "Poke, prod or do other things to somebody" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:75 -msgid "New Mails Notifications" +#: ../../Zotlabs/Module/Poke.php:211 +msgid "Recipient" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:78 -msgid "View your private mails" +#: ../../Zotlabs/Module/Poke.php:212 +msgid "Choose what you wish to do to recipient" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:81 -msgid "Mark all messages seen" +#: ../../Zotlabs/Module/Poke.php:215 ../../Zotlabs/Module/Poke.php:216 +msgid "Make this post private" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:89 -msgid "New Events" +#: ../../Zotlabs/Module/Network.php:105 +msgid "No such group" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:90 -msgid "New Events Notifications" +#: ../../Zotlabs/Module/Network.php:152 +msgid "No such channel" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:93 -msgid "View events" +#: ../../Zotlabs/Module/Network.php:239 +msgid "Privacy group is empty" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:96 -msgid "Mark all events seen" +#: ../../Zotlabs/Module/Network.php:249 +msgid "Privacy group: " msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:104 -#: ../../Zotlabs/Module/Connections.php:164 -msgid "New Connections" +#: ../../Zotlabs/Module/Network.php:322 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:29 +msgid "Invalid channel." msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:105 -msgid "New Connections Notifications" +#: ../../Zotlabs/Module/Attach_edit.php:118 +msgid "Can not copy folder into itself." msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:108 -msgid "View all connections" +#: ../../Zotlabs/Module/Attach_edit.php:131 +#, php-format +msgid "Can not move folder \"%s\" into itself." msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:116 -msgid "New Files" +#: ../../Zotlabs/Module/Viewsrc.php:43 +msgid "item" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:117 -msgid "New Files Notifications" +#: ../../Zotlabs/Module/Lockview.php:75 +msgid "Remote privacy information not available." msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:124 -#: ../../Zotlabs/Widget/Notifications.php:125 -msgid "Notices" +#: ../../Zotlabs/Module/Lockview.php:96 +msgid "Visible to:" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:128 -msgid "View all notices" +#: ../../Zotlabs/Storage/Browser.php:292 +msgid "Change filename to" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:131 -msgid "Mark all notices seen" +#: ../../Zotlabs/Storage/Browser.php:309 ../../Zotlabs/Storage/Browser.php:390 +msgid "Select a target location" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:152 -msgid "New Registrations" +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:391 +msgid "Copy to target location" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:153 -msgid "New Registrations Notifications" +#: ../../Zotlabs/Storage/Browser.php:311 ../../Zotlabs/Storage/Browser.php:389 +msgid "Set permissions for all files and sub folders" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:162 -#: ../../Zotlabs/Module/Pubstream.php:105 ../../Zotlabs/Lib/Apps.php:375 -msgid "Public Stream" +#: ../../Zotlabs/Storage/Browser.php:312 +msgid "Notify your contacts about this file" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:163 -msgid "Public Stream Notifications" +#: ../../Zotlabs/Storage/Browser.php:351 +msgid "File category" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:166 -msgid "View the public stream" +#: ../../Zotlabs/Storage/Browser.php:362 +msgid "Total" msgstr "" -#: ../../Zotlabs/Widget/Notifications.php:181 -msgid "Sorry, you have got no notifications at the moment" +#: ../../Zotlabs/Storage/Browser.php:364 +msgid "Shared" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:39 -#, php-format -msgid "This channel is limited to %d tokens" +#: ../../Zotlabs/Storage/Browser.php:366 +msgid "Add Files" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:45 -msgid "Name and Password are required." +#: ../../Zotlabs/Storage/Browser.php:369 ../../Zotlabs/Lib/ThreadItem.php:174 +msgid "Admin Delete" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:85 -msgid "Token saved." +#: ../../Zotlabs/Storage/Browser.php:381 +msgid "parent" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:99 -msgid "Guest Access App" +#: ../../Zotlabs/Storage/Browser.php:399 +msgid "Select All" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:100 -msgid "Create access tokens so that non-members can access private content" +#: ../../Zotlabs/Storage/Browser.php:400 +msgid "Bulk Actions" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:133 -msgid "" -"Use this form to create temporary access identifiers to share things with " -"non-members. These identities may be used in Access Control Lists and " -"visitors may login using these credentials to access private content." +#: ../../Zotlabs/Storage/Browser.php:401 +msgid "Adjust Permissions" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:135 -msgid "" -"You may also provide dropbox style access links to friends and " -"associates by adding the Login Password to any specific site URL as shown. " -"Examples:" +#: ../../Zotlabs/Storage/Browser.php:402 +msgid "Move or Copy" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:170 -msgid "Guest Access Tokens" +#: ../../Zotlabs/Storage/Browser.php:405 +msgid "Info" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:177 -msgid "Login Name" +#: ../../Zotlabs/Storage/Browser.php:406 +msgid "Rename" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:178 -msgid "Login Password" +#: ../../Zotlabs/Storage/Browser.php:407 ../../Zotlabs/Lib/Apps.php:360 +msgid "Post" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:179 -msgid "Expires (yyyy-mm-dd)" +#: ../../Zotlabs/Storage/Browser.php:408 +msgid "Attachment BBcode" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:180 ../../Zotlabs/Module/Connedit.php:899 -msgid "Their Settings" +#: ../../Zotlabs/Storage/Browser.php:409 +msgid "Embed BBcode" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:181 ../../Zotlabs/Module/Permcats.php:122 -#: ../../Zotlabs/Module/Defperms.php:267 ../../Zotlabs/Module/Connedit.php:900 -msgid "My Settings" +#: ../../Zotlabs/Storage/Browser.php:410 +msgid "Link BBcode" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:183 ../../Zotlabs/Module/Permcats.php:124 -#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Connedit.php:895 -msgid "inherited" +#: ../../Zotlabs/Storage/Browser.php:480 +#, php-format +msgid "You are using %1$s of your available file storage." msgstr "" -#: ../../Zotlabs/Module/Tokens.php:186 ../../Zotlabs/Module/Permcats.php:127 -#: ../../Zotlabs/Module/Defperms.php:270 ../../Zotlabs/Module/Connedit.php:902 -msgid "Individual Permissions" +#: ../../Zotlabs/Storage/Browser.php:485 +#, php-format +msgid "You are using %1$s of %2$s available file storage. (%3$s%)" msgstr "" -#: ../../Zotlabs/Module/Tokens.php:187 ../../Zotlabs/Module/Permcats.php:128 -#: ../../Zotlabs/Module/Connedit.php:903 -msgid "" -"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " -"individual settings. You can not change those settings here." +#: ../../Zotlabs/Storage/Browser.php:496 +msgid "WARNING:" msgstr "" -#: ../../Zotlabs/Module/Article_edit.php:17 -#: ../../Zotlabs/Module/Article_edit.php:33 -#: ../../Zotlabs/Module/Card_edit.php:17 ../../Zotlabs/Module/Card_edit.php:33 -#: ../../Zotlabs/Module/Editwebpage.php:80 ../../Zotlabs/Module/Editpost.php:24 -#: ../../Zotlabs/Module/Editblock.php:79 ../../Zotlabs/Module/Editblock.php:95 -#: ../../Zotlabs/Module/Editlayout.php:79 -msgid "Item not found" +#: ../../Zotlabs/Storage/Browser.php:537 +msgid "Create new folder" msgstr "" -#: ../../Zotlabs/Module/Article_edit.php:44 -#: ../../Zotlabs/Module/Attach_edit.php:52 -#: ../../Zotlabs/Module/Wall_upload.php:31 -#: ../../Zotlabs/Module/Card_edit.php:44 ../../Zotlabs/Module/Chanview.php:95 -#: ../../Zotlabs/Module/Cal.php:31 ../../Zotlabs/Module/Attach.php:21 -#: ../../Zotlabs/Module/Page.php:75 ../../Zotlabs/Module/Block.php:41 -msgid "Channel not found." +#: ../../Zotlabs/Storage/Browser.php:539 +msgid "Upload file" msgstr "" -#: ../../Zotlabs/Module/Article_edit.php:127 -msgid "Edit Article" +#: ../../Zotlabs/Storage/Browser.php:551 +msgid "Drop files here to immediately upload" msgstr "" -#: ../../Zotlabs/Module/Attach_edit.php:69 -#: ../../Zotlabs/Module/Filestorage.php:109 -msgid "File not found." +#: ../../Zotlabs/Storage/Browser.php:554 +msgid "" +"You can select files via the upload button or drop them right here or into " +"an existing folder." msgstr "" -#: ../../Zotlabs/Module/Attach_edit.php:118 -msgid "Can not copy folder into itself." +#: ../../Zotlabs/Zot/Auth.php:152 +msgid "" +"Remote authentication blocked. You are logged into this site locally. Please " +"logout and retry." msgstr "" -#: ../../Zotlabs/Module/Attach_edit.php:131 +#: ../../Zotlabs/Zot/Auth.php:264 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:76 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:178 #, php-format -msgid "Can not move folder \"%s\" into itself." +msgid "Welcome %s. Remote authentication successful." msgstr "" -#: ../../Zotlabs/Module/Network.php:105 -msgid "No such group" +#: ../../Zotlabs/Lib/Group.php:28 ../../include/group.php:23 +msgid "" +"A deleted group with this name was revived. Existing item permissions " +"may apply to this group and any future members. If this is " +"not what you intended, please create another group with a different name." msgstr "" -#: ../../Zotlabs/Module/Network.php:152 -msgid "No such channel" +#: ../../Zotlabs/Lib/Group.php:270 ../../include/group.php:265 +msgid "Add new connections to this privacy group" msgstr "" -#: ../../Zotlabs/Module/Network.php:164 ../../Zotlabs/Module/Channel.php:189 -msgid "Search Results For:" +#: ../../Zotlabs/Lib/Group.php:302 ../../Zotlabs/Lib/AccessList.php:311 +#: ../../include/group.php:299 +msgid "edit" msgstr "" -#: ../../Zotlabs/Module/Network.php:205 ../../Zotlabs/Module/Channel.php:224 -#: ../../Zotlabs/Module/Hq.php:125 ../../Zotlabs/Module/Pubstream.php:95 -#: ../../Zotlabs/Module/Display.php:76 -msgid "Reset form" +#: ../../Zotlabs/Lib/Group.php:325 ../../include/group.php:322 +msgid "Edit group" msgstr "" -#: ../../Zotlabs/Module/Network.php:239 -msgid "Privacy group is empty" +#: ../../Zotlabs/Lib/Group.php:326 ../../include/group.php:323 +msgid "Add privacy group" msgstr "" -#: ../../Zotlabs/Module/Network.php:249 -msgid "Privacy group: " +#: ../../Zotlabs/Lib/Group.php:327 ../../include/group.php:324 +msgid "Channels not in any privacy group" msgstr "" -#: ../../Zotlabs/Module/Import_items.php:48 ../../Zotlabs/Module/Import.php:68 -msgid "Nothing to import." +#: ../../Zotlabs/Lib/Group.php:329 ../../Zotlabs/Lib/AccessList.php:336 +#: ../../Zotlabs/Widget/Savedsearch.php:84 ../../include/group.php:326 +msgid "add" msgstr "" -#: ../../Zotlabs/Module/Import_items.php:72 ../../Zotlabs/Module/Import.php:83 -#: ../../Zotlabs/Module/Import.php:99 -msgid "Unable to download data from old server" +#: ../../Zotlabs/Lib/Connect.php:46 ../../Zotlabs/Lib/Connect.php:143 +#: ../../include/follow.php:37 +msgid "Channel is blocked on this site." msgstr "" -#: ../../Zotlabs/Module/Import_items.php:77 ../../Zotlabs/Module/Import.php:106 -msgid "Imported file is empty." +#: ../../Zotlabs/Lib/Connect.php:51 ../../include/follow.php:42 +msgid "Channel location missing." msgstr "" -#: ../../Zotlabs/Module/Import_items.php:93 -#, php-format -msgid "Warning: Database versions differ by %1$d updates." +#: ../../Zotlabs/Lib/Connect.php:103 ../../include/follow.php:166 +msgid "Remote channel or protocol unavailable." msgstr "" -#: ../../Zotlabs/Module/Import_items.php:108 -msgid "Import completed" +#: ../../Zotlabs/Lib/Connect.php:137 ../../include/follow.php:190 +msgid "Channel discovery failed." msgstr "" -#: ../../Zotlabs/Module/Import_items.php:125 -msgid "Import Items" +#: ../../Zotlabs/Lib/Connect.php:155 ../../include/follow.php:202 +msgid "Protocol disabled." msgstr "" -#: ../../Zotlabs/Module/Import_items.php:126 -msgid "Use this form to import existing posts and content from an export file." +#: ../../Zotlabs/Lib/Connect.php:167 ../../include/follow.php:213 +msgid "Cannot connect to yourself." msgstr "" -#: ../../Zotlabs/Module/Import_items.php:127 -#: ../../Zotlabs/Module/Import.php:628 -msgid "File to Upload" +#: ../../Zotlabs/Lib/Connect.php:271 +msgid "error saving data" msgstr "" -#: ../../Zotlabs/Module/Import.php:162 -#, php-format -msgid "Your service plan only allows %d channels." +#: ../../Zotlabs/Lib/Apps.php:323 +msgid "Apps" msgstr "" -#: ../../Zotlabs/Module/Import.php:189 -msgid "No channel. Import failed." +#: ../../Zotlabs/Lib/Apps.php:324 +msgid "Affinity Tool" msgstr "" -#: ../../Zotlabs/Module/Import.php:621 -msgid "You must be logged in to use this feature." +#: ../../Zotlabs/Lib/Apps.php:327 +msgid "Site Admin" msgstr "" -#: ../../Zotlabs/Module/Import.php:626 -msgid "Import Channel" +#: ../../Zotlabs/Lib/Apps.php:328 +#: ../../extend/addon/hzaddons/buglink/buglink.php:16 +msgid "Report Bug" msgstr "" -#: ../../Zotlabs/Module/Import.php:627 -msgid "" -"Use this form to import an existing channel from a different server/hub. You " -"may retrieve the channel identity from the old server/hub via the network or " -"provide an export file." +#: ../../Zotlabs/Lib/Apps.php:329 ../../include/nav.php:490 +msgid "Bookmarks" msgstr "" -#: ../../Zotlabs/Module/Import.php:629 -msgid "Or provide the old server/hub details" +#: ../../Zotlabs/Lib/Apps.php:330 ../../Zotlabs/Widget/Chatroom_list.php:16 +#: ../../include/nav.php:477 ../../include/nav.php:480 +msgid "Chatrooms" msgstr "" -#: ../../Zotlabs/Module/Import.php:631 -msgid "Your old identity address (xyz@example.com)" +#: ../../Zotlabs/Lib/Apps.php:331 +msgid "Content Filter" msgstr "" -#: ../../Zotlabs/Module/Import.php:632 -msgid "Your old login email address" +#: ../../Zotlabs/Lib/Apps.php:332 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:135 +msgid "Content Import" msgstr "" -#: ../../Zotlabs/Module/Import.php:633 -msgid "Your old login password" +#: ../../Zotlabs/Lib/Apps.php:334 +msgid "Remote Diagnostics" msgstr "" -#: ../../Zotlabs/Module/Import.php:634 -msgid "Import a few months of posts if possible (limited by available memory" +#: ../../Zotlabs/Lib/Apps.php:335 +msgid "Suggest Channels" msgstr "" -#: ../../Zotlabs/Module/Import.php:636 -msgid "" -"For either option, please choose whether to make this hub your new primary " -"address, or whether your old location should continue this role. You will be " -"able to post from either location, but only one can be marked as the primary " -"location for files, photos, and media." +#: ../../Zotlabs/Lib/Apps.php:336 ../../include/nav.php:124 +#: ../../include/nav.php:128 ../../boot.php:1705 +msgid "Login" msgstr "" -#: ../../Zotlabs/Module/Import.php:638 -msgid "Make this hub my primary location" +#: ../../Zotlabs/Lib/Apps.php:338 +msgid "Stream" msgstr "" -#: ../../Zotlabs/Module/Import.php:639 -msgid "Move this channel (disable all previous locations)" +#: ../../Zotlabs/Lib/Apps.php:342 ../../include/nav.php:539 +msgid "Wiki" msgstr "" -#: ../../Zotlabs/Module/Import.php:640 -msgid "Use this channel nickname instead of the one provided" +#: ../../Zotlabs/Lib/Apps.php:343 ../../include/features.php:104 +msgid "Channel Home" msgstr "" -#: ../../Zotlabs/Module/Import.php:640 -msgid "" -"Leave blank to keep your existing channel nickname. You will be randomly " -"assigned a similar nickname if either name is already allocated on this site." +#: ../../Zotlabs/Lib/Apps.php:346 ../../include/features.php:82 +#: ../../include/nav.php:463 ../../include/nav.php:466 +msgid "Calendar" msgstr "" -#: ../../Zotlabs/Module/Import.php:642 -msgid "" -"This process may take several minutes to complete. Please submit the form " -"only once and leave this page open until finished." +#: ../../Zotlabs/Lib/Apps.php:347 ../../include/features.php:192 +msgid "Directory" msgstr "" -#: ../../Zotlabs/Module/Ochannel.php:32 ../../Zotlabs/Module/Channel.php:42 -#: ../../Zotlabs/Module/Chat.php:29 -msgid "You must be logged in to see this page." +#: ../../Zotlabs/Lib/Apps.php:349 +msgid "Mail" msgstr "" -#: ../../Zotlabs/Module/Z6trans.php:19 -msgid "Update to Hubzilla 5.0 step 2" +#: ../../Zotlabs/Lib/Apps.php:352 +msgid "Chat" msgstr "" -#: ../../Zotlabs/Module/Z6trans.php:21 -msgid "To complete the update please run" +#: ../../Zotlabs/Lib/Apps.php:354 +msgid "Probe" msgstr "" -#: ../../Zotlabs/Module/Z6trans.php:23 -msgid "php util/z6convert.php" +#: ../../Zotlabs/Lib/Apps.php:355 +msgid "Suggest" msgstr "" -#: ../../Zotlabs/Module/Z6trans.php:25 -msgid "from the terminal." +#: ../../Zotlabs/Lib/Apps.php:356 +msgid "Random Channel" msgstr "" -#: ../../Zotlabs/Module/Register.php:52 -msgid "Maximum daily site registrations exceeded. Please try again tomorrow." +#: ../../Zotlabs/Lib/Apps.php:357 +msgid "Invite" msgstr "" -#: ../../Zotlabs/Module/Register.php:58 -msgid "" -"Please indicate acceptance of the Terms of Service. Registration failed." +#: ../../Zotlabs/Lib/Apps.php:358 ../../Zotlabs/Widget/Admin.php:26 +msgid "Features" msgstr "" -#: ../../Zotlabs/Module/Register.php:92 -msgid "Passwords do not match." +#: ../../Zotlabs/Lib/Apps.php:359 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:69 +msgid "Language" msgstr "" -#: ../../Zotlabs/Module/Register.php:135 -msgid "Registration successful. Continue to create your first channel..." +#: ../../Zotlabs/Lib/Apps.php:361 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:58 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:59 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:60 +msgid "Profile Photo" msgstr "" -#: ../../Zotlabs/Module/Register.php:138 -msgid "" -"Registration successful. Please check your email for validation instructions." +#: ../../Zotlabs/Lib/Apps.php:363 ../../include/features.php:383 +msgid "Profiles" msgstr "" -#: ../../Zotlabs/Module/Register.php:145 -msgid "Your registration is pending approval by the site owner." +#: ../../Zotlabs/Lib/Apps.php:365 +msgid "Notifications" msgstr "" -#: ../../Zotlabs/Module/Register.php:148 -msgid "Your registration can not be processed." +#: ../../Zotlabs/Lib/Apps.php:366 +msgid "Order Apps" msgstr "" -#: ../../Zotlabs/Module/Register.php:195 -msgid "Registration on this hub is disabled." +#: ../../Zotlabs/Lib/Apps.php:367 +msgid "CardDAV" msgstr "" -#: ../../Zotlabs/Module/Register.php:204 -msgid "Registration on this hub is by approval only." +#: ../../Zotlabs/Lib/Apps.php:369 +msgid "Guest Access" msgstr "" -#: ../../Zotlabs/Module/Register.php:205 ../../Zotlabs/Module/Register.php:214 -msgid "Register at another affiliated hub." +#: ../../Zotlabs/Lib/Apps.php:370 ../../Zotlabs/Widget/Notes.php:21 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2625 +msgid "Notes" msgstr "" -#: ../../Zotlabs/Module/Register.php:213 -msgid "Registration on this hub is by invitation only." +#: ../../Zotlabs/Lib/Apps.php:371 +msgid "OAuth Apps Manager" msgstr "" -#: ../../Zotlabs/Module/Register.php:224 -msgid "" -"This site has exceeded the number of allowed daily account registrations. " -"Please try again tomorrow." +#: ../../Zotlabs/Lib/Apps.php:372 +msgid "OAuth2 Apps Manager" msgstr "" -#: ../../Zotlabs/Module/Register.php:239 ../../Zotlabs/Module/Siteinfo.php:28 -msgid "Terms of Service" +#: ../../Zotlabs/Lib/Apps.php:373 +msgid "PDL Editor" msgstr "" -#: ../../Zotlabs/Module/Register.php:245 -#, php-format -msgid "I accept the %s for this website" +#: ../../Zotlabs/Lib/Apps.php:376 +msgid "My Chatrooms" msgstr "" -#: ../../Zotlabs/Module/Register.php:252 -#, php-format -msgid "I am over %s years of age and accept the %s for this website" +#: ../../Zotlabs/Lib/Apps.php:377 +msgid "Channel Export" msgstr "" -#: ../../Zotlabs/Module/Register.php:257 -msgid "Your email address" +#: ../../Zotlabs/Lib/Apps.php:554 +msgid "Purchase" msgstr "" -#: ../../Zotlabs/Module/Register.php:258 -msgid "Choose a password" +#: ../../Zotlabs/Lib/Apps.php:559 +msgid "Undelete" msgstr "" -#: ../../Zotlabs/Module/Register.php:259 -msgid "Please re-enter your password" +#: ../../Zotlabs/Lib/Apps.php:569 +msgid "Add to app-tray" msgstr "" -#: ../../Zotlabs/Module/Register.php:260 -msgid "Please enter your invitation code" +#: ../../Zotlabs/Lib/Apps.php:570 +msgid "Remove from app-tray" msgstr "" -#: ../../Zotlabs/Module/Register.php:261 -msgid "Your Name" +#: ../../Zotlabs/Lib/Apps.php:571 +msgid "Pin to navbar" msgstr "" -#: ../../Zotlabs/Module/Register.php:261 -msgid "Real names are preferred." +#: ../../Zotlabs/Lib/Apps.php:572 +msgid "Unpin from navbar" msgstr "" -#: ../../Zotlabs/Module/Register.php:263 -#: ../../Zotlabs/Module/New_channel.php:177 -msgid "Choose a short nickname" +#: ../../Zotlabs/Lib/DB_Upgrade.php:67 +msgid "Source code of failed update: " msgstr "" -#: ../../Zotlabs/Module/Register.php:263 +#: ../../Zotlabs/Lib/DB_Upgrade.php:88 #, php-format -msgid "" -"Your nickname will be used to create an easy to remember channel address e." -"g. nickname%s" +msgid "Update Error at %s" msgstr "" -#: ../../Zotlabs/Module/Register.php:264 -#: ../../Zotlabs/Module/New_channel.php:178 -#: ../../Zotlabs/Module/Settings/Channel.php:537 -msgid "Channel role and privacy" +#: ../../Zotlabs/Lib/DB_Upgrade.php:94 +#, php-format +msgid "Update %s failed. See error logs." msgstr "" -#: ../../Zotlabs/Module/Register.php:264 +#: ../../Zotlabs/Lib/AccessList.php:28 msgid "" -"Select a channel permission role for your usage needs and privacy " -"requirements." +"A deleted list with this name was revived. Existing item permissions " +"may apply to this list and any future members. If this is " +"not what you intended, please create another list with a different name." msgstr "" -#: ../../Zotlabs/Module/Register.php:264 -#: ../../Zotlabs/Module/New_channel.php:178 -msgid "Read more about channel permission roles" +#: ../../Zotlabs/Lib/AccessList.php:286 +msgid "Add new connections to this access list" msgstr "" -#: ../../Zotlabs/Module/Register.php:265 -msgid "no" +#: ../../Zotlabs/Lib/AccessList.php:331 +msgid "Lists" msgstr "" -#: ../../Zotlabs/Module/Register.php:265 -msgid "yes" +#: ../../Zotlabs/Lib/AccessList.php:332 +msgid "Edit list" msgstr "" -#: ../../Zotlabs/Module/Register.php:277 -#: ../../Zotlabs/Module/Admin/Site.php:294 -msgid "Registration" +#: ../../Zotlabs/Lib/AccessList.php:333 +msgid "Create new list" msgstr "" -#: ../../Zotlabs/Module/Register.php:294 -msgid "" -"This site requires email verification. After completing this form, please " -"check your email for further instructions." +#: ../../Zotlabs/Lib/AccessList.php:334 +msgid "Channels not in any access list" msgstr "" -#: ../../Zotlabs/Module/Search.php:17 -#: ../../Zotlabs/Module/Viewconnections.php:23 -#: ../../Zotlabs/Module/Ratings.php:83 ../../Zotlabs/Module/Display.php:26 -#: ../../Zotlabs/Module/Directory.php:71 ../../Zotlabs/Module/Directory.php:76 -#: ../../Zotlabs/Module/Photos.php:519 -msgid "Public access denied." +#: ../../Zotlabs/Lib/Chatroom.php:25 +msgid "Missing room name" msgstr "" -#: ../../Zotlabs/Module/Search.php:222 -#, php-format -msgid "Items tagged with: %s" +#: ../../Zotlabs/Lib/Chatroom.php:34 +msgid "Duplicate room name" msgstr "" -#: ../../Zotlabs/Module/Search.php:224 -#, php-format -msgid "Search results for: %s" +#: ../../Zotlabs/Lib/Chatroom.php:84 ../../Zotlabs/Lib/Chatroom.php:92 +msgid "Invalid room specifier." msgstr "" -#: ../../Zotlabs/Module/Setup.php:167 -msgid "$Projectname Server - Setup" +#: ../../Zotlabs/Lib/Chatroom.php:124 +msgid "Room not found." msgstr "" -#: ../../Zotlabs/Module/Setup.php:171 -msgid "Could not connect to database." +#: ../../Zotlabs/Lib/Chatroom.php:145 +msgid "Room is full" msgstr "" -#: ../../Zotlabs/Module/Setup.php:175 -msgid "" -"Could not connect to specified site URL. Possible SSL certificate or DNS " -"issue." +#: ../../Zotlabs/Lib/Techlevels.php:10 +msgid "0. Beginner/Basic" msgstr "" -#: ../../Zotlabs/Module/Setup.php:182 -msgid "Could not create table." +#: ../../Zotlabs/Lib/Techlevels.php:11 +msgid "1. Novice - not skilled but willing to learn" msgstr "" -#: ../../Zotlabs/Module/Setup.php:188 -msgid "Your site database has been installed." +#: ../../Zotlabs/Lib/Techlevels.php:12 +msgid "2. Intermediate - somewhat comfortable" msgstr "" -#: ../../Zotlabs/Module/Setup.php:194 -msgid "" -"You may need to import the file \"install/schema_xxx.sql\" manually using a " -"database client." +#: ../../Zotlabs/Lib/Techlevels.php:13 +msgid "3. Advanced - very comfortable" msgstr "" -#: ../../Zotlabs/Module/Setup.php:195 ../../Zotlabs/Module/Setup.php:259 -#: ../../Zotlabs/Module/Setup.php:766 -msgid "Please see the file \"install/INSTALL.txt\"." +#: ../../Zotlabs/Lib/Techlevels.php:14 +msgid "4. Expert - I can write computer code" msgstr "" -#: ../../Zotlabs/Module/Setup.php:256 -msgid "System check" +#: ../../Zotlabs/Lib/Techlevels.php:15 +msgid "5. Wizard - I probably know more than you do" msgstr "" -#: ../../Zotlabs/Module/Setup.php:260 ../../Zotlabs/Module/Cdav.php:1036 -#: ../../Zotlabs/Module/Events.php:698 ../../Zotlabs/Module/Events.php:707 -#: ../../Zotlabs/Module/Cal.php:206 ../../Zotlabs/Module/Photos.php:956 -msgid "Next" +#: ../../Zotlabs/Lib/Enotify.php:60 +msgid "$Projectname Notification" msgstr "" -#: ../../Zotlabs/Module/Setup.php:261 -msgid "Check again" +#: ../../Zotlabs/Lib/Enotify.php:61 +#: ../../extend/addon/hzaddons/diaspora/util.php:336 +#: ../../extend/addon/hzaddons/diaspora/util.php:349 +#: ../../extend/addon/hzaddons/diaspora/p.php:48 +msgid "$projectname" msgstr "" -#: ../../Zotlabs/Module/Setup.php:282 -msgid "Database connection" +#: ../../Zotlabs/Lib/Enotify.php:63 +msgid "Thank You," msgstr "" -#: ../../Zotlabs/Module/Setup.php:283 -msgid "" -"In order to install $Projectname we need to know how to connect to your " -"database." +#: ../../Zotlabs/Lib/Enotify.php:65 +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:33 +#, php-format +msgid "%s Administrator" msgstr "" -#: ../../Zotlabs/Module/Setup.php:284 -msgid "" -"Please contact your hosting provider or site administrator if you have " -"questions about these settings." +#: ../../Zotlabs/Lib/Enotify.php:66 +#, php-format +msgid "This email was sent by %1$s at %2$s." msgstr "" -#: ../../Zotlabs/Module/Setup.php:285 +#: ../../Zotlabs/Lib/Enotify.php:67 +#, php-format msgid "" -"The database you specify below should already exist. If it does not, please " -"create it before continuing." +"To stop receiving these messages, please adjust your Notification Settings " +"at %s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:289 -msgid "Database Server Name" +#: ../../Zotlabs/Lib/Enotify.php:68 +#, php-format +msgid "To stop receiving these messages, please adjust your %s." msgstr "" -#: ../../Zotlabs/Module/Setup.php:289 -msgid "Default is 127.0.0.1" +#: ../../Zotlabs/Lib/Enotify.php:123 +#, php-format +msgid "%s " msgstr "" -#: ../../Zotlabs/Module/Setup.php:290 -msgid "Database Port" +#: ../../Zotlabs/Lib/Enotify.php:127 +#, php-format +msgid "[$Projectname:Notify] New mail received at %s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:290 -msgid "Communication port number - use 0 for default" +#: ../../Zotlabs/Lib/Enotify.php:129 +#, php-format +msgid "%1$s sent you a new private message at %2$s." msgstr "" -#: ../../Zotlabs/Module/Setup.php:291 -msgid "Database Login Name" +#: ../../Zotlabs/Lib/Enotify.php:130 +#, php-format +msgid "%1$s sent you %2$s." msgstr "" -#: ../../Zotlabs/Module/Setup.php:292 -msgid "Database Login Password" +#: ../../Zotlabs/Lib/Enotify.php:130 +msgid "a private message" msgstr "" -#: ../../Zotlabs/Module/Setup.php:293 -msgid "Database Name" +#: ../../Zotlabs/Lib/Enotify.php:131 +#, php-format +msgid "Please visit %s to view and/or reply to your private messages." msgstr "" -#: ../../Zotlabs/Module/Setup.php:294 -msgid "Database Type" +#: ../../Zotlabs/Lib/Enotify.php:144 +msgid "commented on" msgstr "" -#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 -msgid "Site administrator email address" +#: ../../Zotlabs/Lib/Enotify.php:157 +msgid "liked" msgstr "" -#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 -msgid "" -"Your account email address must match this in order to use the web admin " -"panel." +#: ../../Zotlabs/Lib/Enotify.php:160 +msgid "disliked" msgstr "" -#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 -msgid "Website URL" +#: ../../Zotlabs/Lib/Enotify.php:165 +msgid "voted on" msgstr "" -#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 -msgid "Please use SSL (https) URL if available." +#: ../../Zotlabs/Lib/Enotify.php:208 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]a %4$s[/zrl]" msgstr "" -#: ../../Zotlabs/Module/Setup.php:298 ../../Zotlabs/Module/Setup.php:340 -msgid "Please select a default timezone for your website" +#: ../../Zotlabs/Lib/Enotify.php:216 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]%4$s's %5$s[/zrl]" msgstr "" -#: ../../Zotlabs/Module/Setup.php:325 -msgid "Site settings" +#: ../../Zotlabs/Lib/Enotify.php:225 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]your %4$s[/zrl]" msgstr "" -#: ../../Zotlabs/Module/Setup.php:379 -msgid "PHP version 7.1 or greater is required." +#: ../../Zotlabs/Lib/Enotify.php:237 +#, php-format +msgid "[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:380 -msgid "PHP version" +#: ../../Zotlabs/Lib/Enotify.php:239 +#, php-format +msgid "[$Projectname:Notify] Comment to conversation #%1$d by %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:396 -msgid "Could not find a command line version of PHP in the web server PATH." +#: ../../Zotlabs/Lib/Enotify.php:240 +#, php-format +msgid "%1$s commented on an item/conversation you have been following." msgstr "" -#: ../../Zotlabs/Module/Setup.php:397 -msgid "" -"If you don't have a command line version of PHP installed on server, you " -"will not be able to run background polling via cron." +#: ../../Zotlabs/Lib/Enotify.php:243 ../../Zotlabs/Lib/Enotify.php:324 +#: ../../Zotlabs/Lib/Enotify.php:340 ../../Zotlabs/Lib/Enotify.php:365 +#: ../../Zotlabs/Lib/Enotify.php:382 ../../Zotlabs/Lib/Enotify.php:395 +#, php-format +msgid "Please visit %s to view and/or reply to the conversation." msgstr "" -#: ../../Zotlabs/Module/Setup.php:401 -msgid "PHP executable path" +#: ../../Zotlabs/Lib/Enotify.php:247 ../../Zotlabs/Lib/Enotify.php:248 +#, php-format +msgid "Please visit %s to approve or reject this comment." msgstr "" -#: ../../Zotlabs/Module/Setup.php:401 -msgid "" -"Enter full path to php executable. You can leave this blank to continue the " -"installation." +#: ../../Zotlabs/Lib/Enotify.php:306 +#, php-format +msgid "%1$s liked [zrl=%2$s]your %3$s[/zrl]" msgstr "" -#: ../../Zotlabs/Module/Setup.php:406 -msgid "Command line PHP" +#: ../../Zotlabs/Lib/Enotify.php:320 +#, php-format +msgid "[$Projectname:Notify] Like received to conversation #%1$d by %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:416 -msgid "" -"Unable to check command line PHP, as shell_exec() is disabled. This is " -"required." +#: ../../Zotlabs/Lib/Enotify.php:321 +#, php-format +msgid "%1$s liked an item/conversation you created." msgstr "" -#: ../../Zotlabs/Module/Setup.php:420 -msgid "" -"The command line version of PHP on your system does not have " -"\"register_argc_argv\" enabled." +#: ../../Zotlabs/Lib/Enotify.php:332 +#, php-format +msgid "[$Projectname:Notify] %s posted to your profile wall" msgstr "" -#: ../../Zotlabs/Module/Setup.php:421 -msgid "This is required for message delivery to work." +#: ../../Zotlabs/Lib/Enotify.php:334 +#, php-format +msgid "%1$s posted to your profile wall at %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:424 -msgid "PHP register_argc_argv" +#: ../../Zotlabs/Lib/Enotify.php:336 +#, php-format +msgid "%1$s posted to [zrl=%2$s]your wall[/zrl]" msgstr "" -#: ../../Zotlabs/Module/Setup.php:444 -msgid "" -"This is not sufficient to upload larger images or files. You should be able " -"to upload at least 4 MB at once." +#: ../../Zotlabs/Lib/Enotify.php:359 +#, php-format +msgid "[$Projectname:Notify] %s tagged you" msgstr "" -#: ../../Zotlabs/Module/Setup.php:446 +#: ../../Zotlabs/Lib/Enotify.php:360 #, php-format -msgid "" -"Your max allowed total upload size is set to %s. Maximum size of one file to " -"upload is set to %s. You are allowed to upload up to %d files at once." +msgid "%1$s tagged you at %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:452 -msgid "You can adjust these settings in the server php.ini file." +#: ../../Zotlabs/Lib/Enotify.php:361 +#, php-format +msgid "%1$s [zrl=%2$s]tagged you[/zrl]." msgstr "" -#: ../../Zotlabs/Module/Setup.php:454 -msgid "PHP upload limits" +#: ../../Zotlabs/Lib/Enotify.php:372 +#, php-format +msgid "[$Projectname:Notify] %1$s poked you" msgstr "" -#: ../../Zotlabs/Module/Setup.php:477 -msgid "" -"Error: the \"openssl_pkey_new\" function on this system is not able to " -"generate encryption keys" +#: ../../Zotlabs/Lib/Enotify.php:373 +#, php-format +msgid "%1$s poked you at %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:478 -msgid "" -"If running under Windows, please see \"http://www.php.net/manual/en/openssl." -"installation.php\"." +#: ../../Zotlabs/Lib/Enotify.php:374 +#, php-format +msgid "%1$s [zrl=%2$s]poked you[/zrl]." msgstr "" -#: ../../Zotlabs/Module/Setup.php:481 -msgid "Generate encryption keys" +#: ../../Zotlabs/Lib/Enotify.php:389 +#, php-format +msgid "[$Projectname:Notify] %s tagged your post" msgstr "" -#: ../../Zotlabs/Module/Setup.php:498 -msgid "libCurl PHP module" +#: ../../Zotlabs/Lib/Enotify.php:390 +#, php-format +msgid "%1$s tagged your post at %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:499 -msgid "GD graphics PHP module" +#: ../../Zotlabs/Lib/Enotify.php:391 +#, php-format +msgid "%1$s tagged [zrl=%2$s]your post[/zrl]" msgstr "" -#: ../../Zotlabs/Module/Setup.php:500 -msgid "OpenSSL PHP module" +#: ../../Zotlabs/Lib/Enotify.php:402 +msgid "[$Projectname:Notify] Introduction received" msgstr "" -#: ../../Zotlabs/Module/Setup.php:501 -msgid "PDO database PHP module" +#: ../../Zotlabs/Lib/Enotify.php:403 +#, php-format +msgid "You've received an new connection request from '%1$s' at %2$s" msgstr "" - -#: ../../Zotlabs/Module/Setup.php:502 -msgid "mb_string PHP module" + +#: ../../Zotlabs/Lib/Enotify.php:404 +#, php-format +msgid "You've received [zrl=%1$s]a new connection request[/zrl] from %2$s." msgstr "" -#: ../../Zotlabs/Module/Setup.php:503 -msgid "xml PHP module" +#: ../../Zotlabs/Lib/Enotify.php:407 ../../Zotlabs/Lib/Enotify.php:425 +#, php-format +msgid "You may visit their profile at %s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:504 -msgid "zip PHP module" +#: ../../Zotlabs/Lib/Enotify.php:409 +#, php-format +msgid "Please visit %s to approve or reject the connection request." msgstr "" -#: ../../Zotlabs/Module/Setup.php:508 ../../Zotlabs/Module/Setup.php:510 -msgid "Apache mod_rewrite module" +#: ../../Zotlabs/Lib/Enotify.php:416 +msgid "[$Projectname:Notify] Friend suggestion received" msgstr "" -#: ../../Zotlabs/Module/Setup.php:508 -msgid "" -"Error: Apache webserver mod-rewrite module is required but not installed." +#: ../../Zotlabs/Lib/Enotify.php:417 +#, php-format +msgid "You've received a friend suggestion from '%1$s' at %2$s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:514 ../../Zotlabs/Module/Setup.php:517 -msgid "exec" +#: ../../Zotlabs/Lib/Enotify.php:418 +#, php-format +msgid "You've received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s." msgstr "" -#: ../../Zotlabs/Module/Setup.php:514 -msgid "" -"Error: exec is required but is either not installed or has been disabled in " -"php.ini" +#: ../../Zotlabs/Lib/Enotify.php:423 +msgid "Name:" msgstr "" -#: ../../Zotlabs/Module/Setup.php:520 ../../Zotlabs/Module/Setup.php:523 -msgid "shell_exec" +#: ../../Zotlabs/Lib/Enotify.php:424 +msgid "Photo:" msgstr "" -#: ../../Zotlabs/Module/Setup.php:520 -msgid "" -"Error: shell_exec is required but is either not installed or has been " -"disabled in php.ini" +#: ../../Zotlabs/Lib/Enotify.php:427 +#, php-format +msgid "Please visit %s to approve or reject the suggestion." msgstr "" -#: ../../Zotlabs/Module/Setup.php:528 -msgid "Error: libCURL PHP module required but not installed." +#: ../../Zotlabs/Lib/Enotify.php:652 +msgid "[$Projectname:Notify]" msgstr "" -#: ../../Zotlabs/Module/Setup.php:532 -msgid "" -"Error: GD PHP module with JPEG support or ImageMagick graphics library " -"required but not installed." +#: ../../Zotlabs/Lib/Enotify.php:820 +msgid "created a new poll" msgstr "" -#: ../../Zotlabs/Module/Setup.php:536 -msgid "Error: openssl PHP module required but not installed." +#: ../../Zotlabs/Lib/Enotify.php:820 +msgid "created a new post" msgstr "" -#: ../../Zotlabs/Module/Setup.php:542 -msgid "" -"Error: PDO database PHP module missing a driver for either mysql or pgsql." +#: ../../Zotlabs/Lib/Enotify.php:821 +#, php-format +msgid "voted on %s's poll" msgstr "" -#: ../../Zotlabs/Module/Setup.php:547 -msgid "Error: PDO database PHP module required but not installed." +#: ../../Zotlabs/Lib/Enotify.php:821 +#, php-format +msgid "commented on %s's post" msgstr "" -#: ../../Zotlabs/Module/Setup.php:551 -msgid "Error: mb_string PHP module required but not installed." +#: ../../Zotlabs/Lib/Enotify.php:825 +#, php-format +msgid "repeated %s's post" msgstr "" -#: ../../Zotlabs/Module/Setup.php:555 -msgid "Error: xml PHP module required for DAV but not installed." +#: ../../Zotlabs/Lib/Enotify.php:837 +#, php-format +msgid "edited a post dated %s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:559 -msgid "Error: zip PHP module required but not installed." +#: ../../Zotlabs/Lib/Enotify.php:841 +#, php-format +msgid "edited a comment dated %s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:578 ../../Zotlabs/Module/Setup.php:587 -msgid ".htconfig.php is writable" +#: ../../Zotlabs/Lib/Enotify.php:970 +msgid "created an event" msgstr "" -#: ../../Zotlabs/Module/Setup.php:583 -msgid "" -"The web installer needs to be able to create a file called \".htconfig.php\" " -"in the top folder of your web server and it is unable to do so." +#: ../../Zotlabs/Lib/Libsync.php:740 ../../include/zot.php:2657 +#, php-format +msgid "Unable to verify site signature for %s" msgstr "" -#: ../../Zotlabs/Module/Setup.php:584 -msgid "" -"This is most often a permission setting, as the web server may not be able " -"to write files in your folder - even if you can." +#: ../../Zotlabs/Lib/NativeWikiPage.php:42 +#: ../../Zotlabs/Lib/NativeWikiPage.php:94 +msgid "(No Title)" msgstr "" -#: ../../Zotlabs/Module/Setup.php:585 -msgid "Please see install/INSTALL.txt for additional information." +#: ../../Zotlabs/Lib/NativeWikiPage.php:109 +msgid "Wiki page create failed." msgstr "" -#: ../../Zotlabs/Module/Setup.php:601 -msgid "" -"This software uses the Smarty3 template engine to render its web views. " -"Smarty3 compiles templates to PHP to speed up rendering." +#: ../../Zotlabs/Lib/NativeWikiPage.php:122 +msgid "Wiki not found." msgstr "" -#: ../../Zotlabs/Module/Setup.php:602 -#, php-format -msgid "" -"In order to store these compiled templates, the web server needs to have " -"write access to the directory %s under the top level web folder." +#: ../../Zotlabs/Lib/NativeWikiPage.php:133 +msgid "Destination name already exists" msgstr "" -#: ../../Zotlabs/Module/Setup.php:603 ../../Zotlabs/Module/Setup.php:624 -msgid "" -"Please ensure that the user that your web server runs as (e.g. www-data) has " -"write access to this folder." +#: ../../Zotlabs/Lib/NativeWikiPage.php:166 +#: ../../Zotlabs/Lib/NativeWikiPage.php:362 +msgid "Page not found" msgstr "" -#: ../../Zotlabs/Module/Setup.php:604 -#, php-format -msgid "" -"Note: as a security measure, you should give the web server write access to " -"%s only--not the template files (.tpl) that it contains." +#: ../../Zotlabs/Lib/NativeWikiPage.php:197 +msgid "Error reading page content" msgstr "" -#: ../../Zotlabs/Module/Setup.php:607 -#, php-format -msgid "%s is writable" +#: ../../Zotlabs/Lib/NativeWikiPage.php:353 +#: ../../Zotlabs/Lib/NativeWikiPage.php:402 +#: ../../Zotlabs/Lib/NativeWikiPage.php:469 +#: ../../Zotlabs/Lib/NativeWikiPage.php:510 +msgid "Error reading wiki" msgstr "" -#: ../../Zotlabs/Module/Setup.php:623 -msgid "" -"This software uses the store directory to save uploaded files. The web " -"server needs to have write access to the store directory under the top level " -"web folder" +#: ../../Zotlabs/Lib/NativeWikiPage.php:390 +msgid "Page update failed." msgstr "" -#: ../../Zotlabs/Module/Setup.php:627 -msgid "store is writable" +#: ../../Zotlabs/Lib/NativeWikiPage.php:424 +msgid "Nothing deleted" msgstr "" -#: ../../Zotlabs/Module/Setup.php:659 -msgid "" -"SSL certificate cannot be validated. Fix certificate or disable https access " -"to this site." +#: ../../Zotlabs/Lib/NativeWikiPage.php:490 +msgid "Compare: object not found." msgstr "" -#: ../../Zotlabs/Module/Setup.php:660 -msgid "" -"If you have https access to your website or allow connections to TCP port " -"443 (the https: port), you MUST use a browser-valid certificate. You MUST " -"NOT use self-signed certificates!" +#: ../../Zotlabs/Lib/NativeWikiPage.php:496 +msgid "Page updated" msgstr "" -#: ../../Zotlabs/Module/Setup.php:661 -msgid "" -"This restriction is incorporated because public posts from you may for " -"example contain references to images on your own hub." +#: ../../Zotlabs/Lib/NativeWikiPage.php:499 +msgid "Untitled" msgstr "" -#: ../../Zotlabs/Module/Setup.php:662 -msgid "" -"If your certificate is not recognized, members of other sites (who may " -"themselves have valid certificates) will get a warning message on their own " -"site complaining about security issues." +#: ../../Zotlabs/Lib/NativeWikiPage.php:505 +msgid "Wiki resource_id required for git commit" msgstr "" -#: ../../Zotlabs/Module/Setup.php:663 -msgid "" -"This can cause usability issues elsewhere (not just on your own site) so we " -"must insist on this requirement." +#: ../../Zotlabs/Lib/NativeWikiPage.php:565 +#: ../../Zotlabs/Widget/Wiki_page_history.php:23 +msgctxt "wiki_history" +msgid "Message" msgstr "" -#: ../../Zotlabs/Module/Setup.php:664 -msgid "" -"Providers are available that issue free certificates which are browser-valid." +#: ../../Zotlabs/Lib/NativeWikiPage.php:566 +#: ../../Zotlabs/Widget/Wiki_page_history.php:24 +msgid "Date" msgstr "" -#: ../../Zotlabs/Module/Setup.php:665 -msgid "" -"If you are confident that the certificate is valid and signed by a trusted " -"authority, check to see if you have failed to install an intermediate cert. " -"These are not normally required by browsers, but are required for server-to-" -"server communications." +#: ../../Zotlabs/Lib/NativeWikiPage.php:568 +#: ../../Zotlabs/Widget/Wiki_page_history.php:26 +msgid "Compare" msgstr "" -#: ../../Zotlabs/Module/Setup.php:667 -msgid "SSL certificate validation" +#: ../../Zotlabs/Lib/NativeWikiPage.php:606 ../../include/bbcode.php:1018 +#: ../../include/bbcode.php:1190 +msgid "Different viewers will see this text differently" msgstr "" -#: ../../Zotlabs/Module/Setup.php:673 -msgid "" -"Url rewrite in .htaccess is not working. Check your server configuration." -"Test: " +#: ../../Zotlabs/Lib/ThreadItem.php:103 ../../include/conversation.php:739 +msgid "Private Message" msgstr "" -#: ../../Zotlabs/Module/Setup.php:676 -msgid "Url rewrite is working" +#: ../../Zotlabs/Lib/ThreadItem.php:130 +msgid "Privacy conflict. Discretion advised." msgstr "" -#: ../../Zotlabs/Module/Setup.php:689 -msgid "" -"The database configuration file \".htconfig.php\" could not be written. " -"Please use the enclosed text to create a configuration file in your web " -"server root." +#: ../../Zotlabs/Lib/ThreadItem.php:180 ../../include/conversation.php:729 +msgid "Select" msgstr "" -#: ../../Zotlabs/Module/Setup.php:764 -msgid "

      What next?

      " +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I will attend" msgstr "" -#: ../../Zotlabs/Module/Setup.php:765 -msgid "" -"IMPORTANT: You will need to [manually] setup a scheduled task for the poller." +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I will not attend" msgstr "" -#: ../../Zotlabs/Module/Viewconnections.php:65 -msgid "No connections." +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I might attend" msgstr "" -#: ../../Zotlabs/Module/Viewconnections.php:105 -#, php-format -msgid "Visit %s's profile [%s]" +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I agree" msgstr "" -#: ../../Zotlabs/Module/Viewconnections.php:135 -msgid "View Connections" +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I disagree" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:27 -msgid "" -"The listed hubs allow public registration for the $Projectname network. All " -"hubs in the network are interlinked so membership on any of them conveys " -"membership in the network as a whole. Some hubs may require subscription or " -"provide tiered service plans. The hub itself may provide " -"additional details." +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I abstain" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:33 -msgid "Hub URL" +#: ../../Zotlabs/Lib/ThreadItem.php:273 ../../include/conversation.php:734 +msgid "Toggle Star Status" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:33 -msgid "Access Type" +#: ../../Zotlabs/Lib/ThreadItem.php:284 ../../Zotlabs/Widget/Pinned.php:88 +#: ../../include/conversation.php:746 +msgid "Message signature validated" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:33 -msgid "Registration Policy" +#: ../../Zotlabs/Lib/ThreadItem.php:285 ../../Zotlabs/Widget/Pinned.php:89 +#: ../../include/conversation.php:747 +msgid "Message signature incorrect" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:33 -msgid "Stats" +#: ../../Zotlabs/Lib/ThreadItem.php:301 ../../include/conversation.php:933 +msgid "Conversation Tools" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:33 -msgid "Software" +#: ../../Zotlabs/Lib/ThreadItem.php:317 ../../include/taxonomy.php:582 +msgid "like" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:49 -msgid "Rate" +#: ../../Zotlabs/Lib/ThreadItem.php:318 ../../include/taxonomy.php:583 +msgid "dislike" msgstr "" -#: ../../Zotlabs/Module/Pubsites.php:60 ../../Zotlabs/Module/Webpages.php:261 -#: ../../Zotlabs/Module/Events.php:702 ../../Zotlabs/Module/Blocks.php:166 -#: ../../Zotlabs/Module/Wiki.php:213 ../../Zotlabs/Module/Wiki.php:409 -#: ../../Zotlabs/Module/Layouts.php:198 -msgid "View" +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "Reply on this comment" msgstr "" -#: ../../Zotlabs/Module/Channel.php:99 ../../Zotlabs/Module/Hcard.php:37 -#: ../../Zotlabs/Module/Profile.php:45 -msgid "Posts and comments" +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "reply" msgstr "" -#: ../../Zotlabs/Module/Channel.php:106 ../../Zotlabs/Module/Hcard.php:44 -#: ../../Zotlabs/Module/Profile.php:52 -msgid "Only posts" +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "Reply to" msgstr "" -#: ../../Zotlabs/Module/Channel.php:174 -msgid "Insufficient permissions. Request redirected to profile page." +#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Widget/Pinned.php:99 +msgid "Share This" msgstr "" -#: ../../Zotlabs/Module/Channel.php:449 ../../Zotlabs/Module/Display.php:359 -msgid "" -"You must enable javascript for your browser to be able to view this content." +#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Widget/Pinned.php:99 +msgid "share" msgstr "" -#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63 -msgid "Invalid profile identifier." +#: ../../Zotlabs/Lib/ThreadItem.php:339 +msgid "Delivery Report" msgstr "" -#: ../../Zotlabs/Module/Profperm.php:111 -msgid "Profile Visibility Editor" +#: ../../Zotlabs/Lib/ThreadItem.php:358 +#, php-format +msgid "%d comment" +msgid_plural "%d comments" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Lib/ThreadItem.php:359 +#, php-format +msgid "%d unseen" msgstr "" -#: ../../Zotlabs/Module/Profperm.php:115 -msgid "Click on a contact to add or remove." +#: ../../Zotlabs/Lib/ThreadItem.php:412 +msgid "to" msgstr "" -#: ../../Zotlabs/Module/Profperm.php:124 -msgid "Visible To" +#: ../../Zotlabs/Lib/ThreadItem.php:413 ../../Zotlabs/Widget/Pinned.php:128 +msgid "via" msgstr "" -#: ../../Zotlabs/Module/Profperm.php:140 -#: ../../Zotlabs/Module/Connections.php:217 -msgid "All Connections" +#: ../../Zotlabs/Lib/ThreadItem.php:414 +msgid "Wall-to-Wall" msgstr "" -#: ../../Zotlabs/Module/Group.php:46 -msgid "Privacy group created." +#: ../../Zotlabs/Lib/ThreadItem.php:415 +msgid "via Wall-To-Wall:" msgstr "" -#: ../../Zotlabs/Module/Group.php:49 -msgid "Could not create privacy group." +#: ../../Zotlabs/Lib/ThreadItem.php:429 ../../Zotlabs/Widget/Pinned.php:133 +#: ../../include/conversation.php:806 +#, php-format +msgid "from %s" msgstr "" -#: ../../Zotlabs/Module/Group.php:81 -msgid "Privacy group updated." +#: ../../Zotlabs/Lib/ThreadItem.php:432 ../../Zotlabs/Widget/Pinned.php:136 +#: ../../include/conversation.php:809 +#, php-format +msgid "last edited: %s" msgstr "" -#: ../../Zotlabs/Module/Group.php:107 -msgid "Privacy Groups App" +#: ../../Zotlabs/Lib/ThreadItem.php:433 ../../Zotlabs/Widget/Pinned.php:137 +#: ../../include/conversation.php:810 +#, php-format +msgid "Expires: %s" msgstr "" -#: ../../Zotlabs/Module/Group.php:108 -msgid "Management of privacy groups" +#: ../../Zotlabs/Lib/ThreadItem.php:442 +msgid "Attend" msgstr "" -#: ../../Zotlabs/Module/Group.php:143 -msgid "Add Group" +#: ../../Zotlabs/Lib/ThreadItem.php:443 ../../Zotlabs/Widget/Pinned.php:143 +msgid "Attendance Options" msgstr "" -#: ../../Zotlabs/Module/Group.php:147 -msgid "Privacy group name" +#: ../../Zotlabs/Lib/ThreadItem.php:444 ../../include/text.php:1922 +msgid "Vote" msgstr "" -#: ../../Zotlabs/Module/Group.php:148 ../../Zotlabs/Module/Group.php:257 -msgid "Members are visible to other channels" +#: ../../Zotlabs/Lib/ThreadItem.php:445 ../../Zotlabs/Widget/Pinned.php:144 +msgid "Voting Options" msgstr "" -#: ../../Zotlabs/Module/Group.php:156 ../../Zotlabs/Module/Help.php:84 -msgid "Members" +#: ../../Zotlabs/Lib/ThreadItem.php:460 +msgid "Go to previous comment" msgstr "" -#: ../../Zotlabs/Module/Group.php:183 -msgid "Privacy group removed." +#: ../../Zotlabs/Lib/ThreadItem.php:469 ../../Zotlabs/Widget/Pinned.php:156 +msgid "Pinned post" msgstr "" -#: ../../Zotlabs/Module/Group.php:186 -msgid "Unable to remove privacy group." +#: ../../Zotlabs/Lib/ThreadItem.php:471 ../../Zotlabs/Widget/Pinned.php:157 +#: ../../include/js_strings.php:39 +msgid "Unpin from the top" msgstr "" -#: ../../Zotlabs/Module/Group.php:252 -#, php-format -msgid "Privacy Group: %s" +#: ../../Zotlabs/Lib/ThreadItem.php:471 ../../include/js_strings.php:38 +msgid "Pin to the top" msgstr "" -#: ../../Zotlabs/Module/Group.php:254 -msgid "Privacy group name: " +#: ../../Zotlabs/Lib/ThreadItem.php:472 +#: ../../extend/addon/hzaddons/bookmarker/bookmarker.php:38 +msgid "Save Bookmarks" msgstr "" -#: ../../Zotlabs/Module/Group.php:259 -msgid "Delete Group" +#: ../../Zotlabs/Lib/ThreadItem.php:473 +msgid "Add to Calendar" msgstr "" -#: ../../Zotlabs/Module/Group.php:270 -msgid "Group members" +#: ../../Zotlabs/Lib/ThreadItem.php:500 ../../include/conversation.php:516 +msgid "This is an unsaved preview" msgstr "" -#: ../../Zotlabs/Module/Group.php:272 -msgid "Not in this group" +#: ../../Zotlabs/Lib/ThreadItem.php:533 ../../include/js_strings.php:7 +#, php-format +msgid "%s show all" msgstr "" -#: ../../Zotlabs/Module/Group.php:304 -msgid "Click a channel to toggle membership" +#: ../../Zotlabs/Lib/ThreadItem.php:826 ../../include/conversation.php:1449 +#: ../../extend/addon/hzaddons/hsse/hsse.php:200 +msgid "Bold" msgstr "" -#: ../../Zotlabs/Module/Card_edit.php:128 -msgid "Edit Card" +#: ../../Zotlabs/Lib/ThreadItem.php:827 ../../include/conversation.php:1450 +#: ../../extend/addon/hzaddons/hsse/hsse.php:201 +msgid "Italic" msgstr "" -#: ../../Zotlabs/Module/Go.php:21 -msgid "This page is available only to site members" +#: ../../Zotlabs/Lib/ThreadItem.php:828 ../../include/conversation.php:1451 +#: ../../extend/addon/hzaddons/hsse/hsse.php:202 +msgid "Underline" msgstr "" -#: ../../Zotlabs/Module/Go.php:27 -msgid "Welcome" +#: ../../Zotlabs/Lib/ThreadItem.php:829 ../../include/conversation.php:1452 +#: ../../extend/addon/hzaddons/hsse/hsse.php:203 +msgid "Quote" msgstr "" -#: ../../Zotlabs/Module/Go.php:29 -msgid "What would you like to do?" +#: ../../Zotlabs/Lib/ThreadItem.php:830 ../../include/conversation.php:1453 +#: ../../extend/addon/hzaddons/hsse/hsse.php:204 +msgid "Code" msgstr "" -#: ../../Zotlabs/Module/Go.php:31 -msgid "" -"Please bookmark this page if you would like to return to it in the future" +#: ../../Zotlabs/Lib/ThreadItem.php:831 +msgid "Image" msgstr "" -#: ../../Zotlabs/Module/Go.php:35 -msgid "Upload a profile photo" +#: ../../Zotlabs/Lib/ThreadItem.php:832 ../../include/conversation.php:1454 +#: ../../extend/addon/hzaddons/hsse/hsse.php:205 +msgid "Attach/Upload file" msgstr "" -#: ../../Zotlabs/Module/Go.php:36 -msgid "Upload a cover photo" +#: ../../Zotlabs/Lib/ThreadItem.php:833 +msgid "Insert Link" msgstr "" -#: ../../Zotlabs/Module/Go.php:37 -msgid "Edit your default profile" +#: ../../Zotlabs/Lib/ThreadItem.php:834 +msgid "Video" msgstr "" -#: ../../Zotlabs/Module/Go.php:39 -msgid "View the channel directory" +#: ../../Zotlabs/Lib/ThreadItem.php:844 +msgid "Your full name (required)" msgstr "" -#: ../../Zotlabs/Module/Go.php:40 -msgid "View/edit your channel settings" +#: ../../Zotlabs/Lib/ThreadItem.php:845 +msgid "Your email address (required)" msgstr "" -#: ../../Zotlabs/Module/Go.php:41 -msgid "View the site or project documentation" +#: ../../Zotlabs/Lib/ThreadItem.php:846 +msgid "Your website URL (optional)" msgstr "" -#: ../../Zotlabs/Module/Go.php:42 -msgid "Visit your channel homepage" +#: ../../Zotlabs/Lib/Activity.php:2110 +#, php-format +msgid "Likes %1$s's %2$s" msgstr "" -#: ../../Zotlabs/Module/Go.php:43 -msgid "" -"View your connections and/or add somebody whose address you already know" +#: ../../Zotlabs/Lib/Activity.php:2113 +#, php-format +msgid "Doesn't like %1$s's %2$s" msgstr "" -#: ../../Zotlabs/Module/Go.php:44 -msgid "" -"View your personal stream (this may be empty until you add some connections)" +#: ../../Zotlabs/Lib/Activity.php:2119 +#, php-format +msgid "Will attend %s's event" msgstr "" -#: ../../Zotlabs/Module/Go.php:52 -msgid "View the public stream. Warning: this content is not moderated" +#: ../../Zotlabs/Lib/Activity.php:2122 +#, php-format +msgid "Will not attend %s's event" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:45 -msgid "Name is required" +#: ../../Zotlabs/Lib/Activity.php:2125 +#, php-format +msgid "May attend %s's event" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:49 -msgid "Key and Secret are required" +#: ../../Zotlabs/Lib/Activity.php:2128 +#, php-format +msgid "May not attend %s's event" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:53 ../../Zotlabs/Module/Oauth.php:137 -#: ../../Zotlabs/Module/Cdav.php:1053 ../../Zotlabs/Module/Cdav.php:1388 -#: ../../Zotlabs/Module/Admin/Addons.php:457 -#: ../../Zotlabs/Module/Profiles.php:801 ../../Zotlabs/Module/Oauth2.php:58 -#: ../../Zotlabs/Module/Oauth2.php:144 ../../Zotlabs/Module/Connedit.php:931 -#: ../../Zotlabs/Lib/Apps.php:536 -msgid "Update" +#: ../../Zotlabs/Lib/Activity.php:2821 ../../Zotlabs/Lib/Activity.php:3015 +#: ../../include/network.php:1736 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1479 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1733 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1941 +msgid "ActivityPub" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:100 -msgid "OAuth Apps Manager App" +#: ../../Zotlabs/Lib/NativeWiki.php:145 +msgid "Wiki updated successfully" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:101 -msgid "OAuth authentication tokens for mobile and remote apps" +#: ../../Zotlabs/Lib/NativeWiki.php:199 +msgid "Wiki files deleted successfully" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:110 ../../Zotlabs/Module/Oauth.php:136 -#: ../../Zotlabs/Module/Oauth.php:172 ../../Zotlabs/Module/Oauth2.php:143 -#: ../../Zotlabs/Module/Oauth2.php:193 -msgid "Add application" +#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../include/dir_fns.php:141 +msgid "Directory Options" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth2.php:118 -#: ../../Zotlabs/Module/Oauth2.php:146 -msgid "Name of application" +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../include/dir_fns.php:143 +msgid "Safe Mode" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:115 -#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 -msgid "Automatically generated - change if desired. Max length 20" +#: ../../Zotlabs/Lib/Libzotdir.php:166 ../../include/dir_fns.php:144 +msgid "Public Forums Only" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth.php:142 -#: ../../Zotlabs/Module/Oauth2.php:120 ../../Zotlabs/Module/Oauth2.php:148 -msgid "Redirect" +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/dir_fns.php:145 +msgid "This Website Only" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth2.php:120 -#: ../../Zotlabs/Module/Oauth2.php:148 -msgid "" -"Redirect URI - leave blank unless your application specifically requires this" +#: ../../Zotlabs/Lib/Permcat.php:82 +msgctxt "permcat" +msgid "default" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Oauth.php:143 -msgid "Icon url" +#: ../../Zotlabs/Lib/Permcat.php:133 +msgctxt "permcat" +msgid "follower" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Sources.php:123 -#: ../../Zotlabs/Module/Sources.php:158 -msgid "Optional" +#: ../../Zotlabs/Lib/Permcat.php:137 +msgctxt "permcat" +msgid "contributor" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:128 -msgid "Application not found." +#: ../../Zotlabs/Lib/Permcat.php:141 +msgctxt "permcat" +msgid "publisher" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:171 -msgid "Connected OAuth Apps" +#: ../../Zotlabs/Lib/Libzot.php:656 ../../include/zot.php:802 +msgid "Unable to verify channel signature" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:175 ../../Zotlabs/Module/Oauth2.php:196 -msgid "Client key starts with" +#: ../../Zotlabs/Lib/PermissionDescription.php:34 +#: ../../include/acl_selectors.php:33 +msgid "Visible to your default audience" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:176 ../../Zotlabs/Module/Oauth2.php:197 -msgid "No name" +#: ../../Zotlabs/Lib/PermissionDescription.php:107 +#: ../../include/acl_selectors.php:135 +msgid "Only me" msgstr "" -#: ../../Zotlabs/Module/Oauth.php:177 ../../Zotlabs/Module/Oauth2.php:198 -msgid "Remove authorization" +#: ../../Zotlabs/Lib/PermissionDescription.php:108 +msgid "Public" msgstr "" -#: ../../Zotlabs/Module/Editwebpage.php:139 -msgid "Page link" +#: ../../Zotlabs/Lib/PermissionDescription.php:109 +msgid "Anybody in the $Projectname network" msgstr "" -#: ../../Zotlabs/Module/Editwebpage.php:166 -msgid "Edit Webpage" +#: ../../Zotlabs/Lib/PermissionDescription.php:110 +#, php-format +msgid "Any account on %s" msgstr "" -#: ../../Zotlabs/Module/Dirsearch.php:28 ../../Zotlabs/Module/Regdir.php:52 -msgid "This site is not a directory server" +#: ../../Zotlabs/Lib/PermissionDescription.php:111 +msgid "Any of my connections" msgstr "" -#: ../../Zotlabs/Module/Dirsearch.php:37 -msgid "This directory server requires an access token" +#: ../../Zotlabs/Lib/PermissionDescription.php:112 +msgid "Only connections I specifically allow" msgstr "" -#: ../../Zotlabs/Module/Hq.php:131 -msgid "Welcome to Hubzilla!" +#: ../../Zotlabs/Lib/PermissionDescription.php:113 +msgid "Anybody authenticated (could include visitors from other networks)" msgstr "" -#: ../../Zotlabs/Module/Hq.php:131 -msgid "You have got no unseen posts..." +#: ../../Zotlabs/Lib/PermissionDescription.php:114 +msgid "Any connections including those who haven't yet been approved" msgstr "" -#: ../../Zotlabs/Module/Pin.php:35 ../../Zotlabs/Module/Item.php:450 -msgid "Unable to locate original post." +#: ../../Zotlabs/Lib/PermissionDescription.php:150 +msgid "" +"This is your default setting for the audience of your normal stream, and " +"posts." msgstr "" -#: ../../Zotlabs/Module/Chat.php:100 -msgid "Chatrooms App" +#: ../../Zotlabs/Lib/PermissionDescription.php:151 +msgid "" +"This is your default setting for who can view your default channel profile" msgstr "" -#: ../../Zotlabs/Module/Chat.php:101 -msgid "Access Controlled Chatrooms" +#: ../../Zotlabs/Lib/PermissionDescription.php:152 +msgid "This is your default setting for who can view your connections" msgstr "" -#: ../../Zotlabs/Module/Chat.php:194 -msgid "Room not found" +#: ../../Zotlabs/Lib/PermissionDescription.php:153 +msgid "" +"This is your default setting for who can view your file storage and photos" msgstr "" -#: ../../Zotlabs/Module/Chat.php:210 -msgid "Leave Room" +#: ../../Zotlabs/Lib/PermissionDescription.php:154 +msgid "This is your default setting for the audience of your webpages" msgstr "" -#: ../../Zotlabs/Module/Chat.php:211 -msgid "Delete Room" +#: ../../Zotlabs/Widget/Appcategories.php:46 ../../Zotlabs/Widget/Filer.php:31 +#: ../../include/contact_widgets.php:56 ../../include/contact_widgets.php:111 +#: ../../include/contact_widgets.php:155 ../../include/contact_widgets.php:200 +#: ../../include/contact_widgets.php:235 +msgid "Everything" msgstr "" -#: ../../Zotlabs/Module/Chat.php:212 -msgid "I am away right now" +#: ../../Zotlabs/Widget/Cdav.php:37 +msgid "Select Channel" msgstr "" -#: ../../Zotlabs/Module/Chat.php:213 -msgid "I am online" +#: ../../Zotlabs/Widget/Cdav.php:42 +msgid "Read-write" msgstr "" -#: ../../Zotlabs/Module/Chat.php:215 -msgid "Bookmark this room" +#: ../../Zotlabs/Widget/Cdav.php:43 +msgid "Read-only" msgstr "" -#: ../../Zotlabs/Module/Chat.php:238 -msgid "New Chatroom" +#: ../../Zotlabs/Widget/Cdav.php:127 +msgid "Channel Calendar" msgstr "" -#: ../../Zotlabs/Module/Chat.php:239 -msgid "Chatroom name" +#: ../../Zotlabs/Widget/Cdav.php:131 +msgid "Shared CalDAV Calendars" msgstr "" -#: ../../Zotlabs/Module/Chat.php:240 -msgid "Expiration of chats (minutes)" +#: ../../Zotlabs/Widget/Cdav.php:135 +msgid "Share this calendar" msgstr "" -#: ../../Zotlabs/Module/Chat.php:256 -#, php-format -msgid "%1$s's Chatrooms" +#: ../../Zotlabs/Widget/Cdav.php:137 +msgid "Calendar name and color" msgstr "" -#: ../../Zotlabs/Module/Chat.php:261 -msgid "No chatrooms available" +#: ../../Zotlabs/Widget/Cdav.php:139 +msgid "Create new CalDAV calendar" msgstr "" -#: ../../Zotlabs/Module/Chat.php:262 ../../Zotlabs/Module/Manage.php:145 -#: ../../Zotlabs/Module/Profiles.php:833 ../../Zotlabs/Module/Wiki.php:214 -msgid "Create New" +#: ../../Zotlabs/Widget/Cdav.php:141 +msgid "Calendar Name" msgstr "" -#: ../../Zotlabs/Module/Chat.php:265 -msgid "Expiration" +#: ../../Zotlabs/Widget/Cdav.php:142 +msgid "Calendar Tools" msgstr "" -#: ../../Zotlabs/Module/Chat.php:266 -msgid "min" +#: ../../Zotlabs/Widget/Cdav.php:144 +msgid "Import calendar" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:57 -#: ../../Zotlabs/Module/Events.php:113 -msgid "Event can not end before it has started." +#: ../../Zotlabs/Widget/Cdav.php:145 +msgid "Select a calendar to import to" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:59 -#: ../../Zotlabs/Module/Channel_calendar.php:67 -#: ../../Zotlabs/Module/Channel_calendar.php:84 -#: ../../Zotlabs/Module/Events.php:115 ../../Zotlabs/Module/Events.php:124 -#: ../../Zotlabs/Module/Events.php:146 -msgid "Unable to generate preview." +#: ../../Zotlabs/Widget/Cdav.php:172 +msgid "Addressbooks" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:65 -#: ../../Zotlabs/Module/Events.php:122 -msgid "Event title and start time are required." +#: ../../Zotlabs/Widget/Cdav.php:174 +msgid "Addressbook name" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:82 -#: ../../Zotlabs/Module/Channel_calendar.php:224 -#: ../../Zotlabs/Module/Events.php:144 ../../Zotlabs/Module/Events.php:271 -msgid "Event not found." +#: ../../Zotlabs/Widget/Cdav.php:176 +msgid "Create new addressbook" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:371 -#: ../../Zotlabs/Module/Events.php:641 -msgid "Edit event" +#: ../../Zotlabs/Widget/Cdav.php:177 +msgid "Addressbook Name" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:373 -#: ../../Zotlabs/Module/Events.php:643 -msgid "Delete event" +#: ../../Zotlabs/Widget/Cdav.php:179 +msgid "Addressbook Tools" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:393 -#: ../../Zotlabs/Module/Cdav.php:943 ../../Zotlabs/Module/Cal.php:167 -msgid "Link to source" +#: ../../Zotlabs/Widget/Cdav.php:180 +msgid "Import addressbook" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:407 -#: ../../Zotlabs/Module/Events.php:677 -msgid "calendar" +#: ../../Zotlabs/Widget/Cdav.php:181 +msgid "Select an addressbook to import to" msgstr "" -#: ../../Zotlabs/Module/Channel_calendar.php:494 -#: ../../Zotlabs/Module/Events.php:742 -msgid "Failed to remove event" +#: ../../Zotlabs/Widget/Filer.php:28 +#: ../../Zotlabs/Widget/Activity_filter.php:179 +#: ../../include/contact_widgets.php:53 ../../include/features.php:319 +msgid "Saved Folders" msgstr "" -#: ../../Zotlabs/Module/Like.php:93 -msgid "Like/Dislike" +#: ../../Zotlabs/Widget/Tagcloud.php:22 ../../include/taxonomy.php:323 +#: ../../include/taxonomy.php:458 ../../include/taxonomy.php:479 +msgid "Tags" msgstr "" -#: ../../Zotlabs/Module/Like.php:98 -msgid "This action is restricted to members." +#: ../../Zotlabs/Widget/Archive.php:43 +msgid "Archives" msgstr "" -#: ../../Zotlabs/Module/Like.php:99 -msgid "" -"Please login with your $Projectname ID or register as a new $Projectname member to continue." +#: ../../Zotlabs/Widget/Chatroom_members.php:11 +msgid "Chat Members" msgstr "" -#: ../../Zotlabs/Module/Like.php:154 ../../Zotlabs/Module/Like.php:180 -#: ../../Zotlabs/Module/Like.php:218 -msgid "Invalid request." +#: ../../Zotlabs/Widget/Rating.php:51 +msgid "Rating Tools" msgstr "" -#: ../../Zotlabs/Module/Like.php:195 -msgid "thing" +#: ../../Zotlabs/Widget/Rating.php:55 ../../Zotlabs/Widget/Rating.php:57 +msgid "Rate Me" msgstr "" -#: ../../Zotlabs/Module/Like.php:241 -msgid "Channel unavailable." +#: ../../Zotlabs/Widget/Rating.php:60 +msgid "View Ratings" msgstr "" -#: ../../Zotlabs/Module/Like.php:277 -msgid "Previous action reversed." +#: ../../Zotlabs/Widget/Wiki_pages.php:34 +#: ../../Zotlabs/Widget/Wiki_pages.php:91 +msgid "Add new page" msgstr "" -#: ../../Zotlabs/Module/Like.php:473 -#, php-format -msgid "%1$s agrees with %2$s's %3$s" +#: ../../Zotlabs/Widget/Wiki_pages.php:85 +msgid "Wiki Pages" msgstr "" -#: ../../Zotlabs/Module/Like.php:475 -#, php-format -msgid "%1$s doesn't agree with %2$s's %3$s" +#: ../../Zotlabs/Widget/Wiki_pages.php:96 +msgid "Page name" msgstr "" -#: ../../Zotlabs/Module/Like.php:477 -#, php-format -msgid "%1$s abstains from a decision on %2$s's %3$s" +#: ../../Zotlabs/Widget/Bookmarkedchats.php:24 +msgid "Bookmarked Chatrooms" msgstr "" -#: ../../Zotlabs/Module/Like.php:592 -msgid "Action completed." +#: ../../Zotlabs/Widget/Photo.php:48 ../../Zotlabs/Widget/Photo_rand.php:58 +msgid "photo/image" msgstr "" -#: ../../Zotlabs/Module/Like.php:593 -msgid "Thank you." +#: ../../Zotlabs/Widget/Forums.php:100 +#: ../../Zotlabs/Widget/Activity_filter.php:115 +#: ../../Zotlabs/Widget/Notifications.php:139 +#: ../../Zotlabs/Widget/Notifications.php:140 +#: ../../include/acl_selectors.php:124 +msgid "Forums" msgstr "" -#: ../../Zotlabs/Module/Poke.php:165 -msgid "Poke App" +#: ../../Zotlabs/Widget/Savedsearch.php:75 +msgid "Remove term" msgstr "" -#: ../../Zotlabs/Module/Poke.php:166 -msgid "Poke somebody in your addressbook" +#: ../../Zotlabs/Widget/Savedsearch.php:83 ../../include/features.php:311 +msgid "Saved Searches" msgstr "" -#: ../../Zotlabs/Module/Poke.php:200 -msgid "Poke somebody" +#: ../../Zotlabs/Widget/Follow.php:22 +#, php-format +msgid "You have %1$.0f of %2$.0f allowed connections." msgstr "" -#: ../../Zotlabs/Module/Poke.php:203 -msgid "Poke/Prod" +#: ../../Zotlabs/Widget/Follow.php:29 +msgid "Add New Connection" msgstr "" -#: ../../Zotlabs/Module/Poke.php:204 -msgid "Poke, prod or do other things to somebody" +#: ../../Zotlabs/Widget/Follow.php:30 +msgid "Enter channel address" msgstr "" -#: ../../Zotlabs/Module/Poke.php:211 -msgid "Recipient" +#: ../../Zotlabs/Widget/Follow.php:31 +msgid "Examples: bob@example.com, https://example.com/barbara" msgstr "" -#: ../../Zotlabs/Module/Poke.php:212 -msgid "Choose what you wish to do to recipient" +#: ../../Zotlabs/Widget/Suggestions.php:53 +msgid "Suggestions" msgstr "" -#: ../../Zotlabs/Module/Poke.php:215 ../../Zotlabs/Module/Poke.php:216 -msgid "Make this post private" +#: ../../Zotlabs/Widget/Suggestions.php:54 +msgid "See more..." msgstr "" -#: ../../Zotlabs/Module/Cdav.php:818 ../../Zotlabs/Module/Events.php:28 -msgid "Calendar entries imported." +#: ../../Zotlabs/Widget/Tasklist.php:23 +msgid "Tasks" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:820 ../../Zotlabs/Module/Events.php:30 -msgid "No calendar entries found." +#: ../../Zotlabs/Widget/Admin.php:23 ../../Zotlabs/Widget/Admin.php:60 +msgid "Member registrations waiting for confirmation" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:876 -msgid "CardDAV App" +#: ../../Zotlabs/Widget/Admin.php:29 +msgid "Inspect queue" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:877 -msgid "CalDAV capable addressbook" +#: ../../Zotlabs/Widget/Admin.php:31 +msgid "DB updates" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1009 ../../Zotlabs/Module/Events.php:468 -msgid "Event title" +#: ../../Zotlabs/Widget/Admin.php:55 ../../include/nav.php:194 +msgid "Admin" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1010 ../../Zotlabs/Module/Events.php:474 -msgid "Start date and time" +#: ../../Zotlabs/Widget/Admin.php:56 +msgid "Addon Features" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1011 -msgid "End date and time" +#: ../../Zotlabs/Widget/Chatroom_list.php:20 +msgid "Overview" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1012 ../../Zotlabs/Module/Events.php:497 -msgid "Timezone:" +#: ../../Zotlabs/Widget/Appstore.php:11 +msgid "App Collections" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1035 ../../Zotlabs/Module/Events.php:697 -#: ../../Zotlabs/Module/Events.php:706 ../../Zotlabs/Module/Cal.php:205 -#: ../../Zotlabs/Module/Photos.php:947 -msgid "Previous" +#: ../../Zotlabs/Widget/Appstore.php:13 +msgid "Installed apps" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1037 ../../Zotlabs/Module/Events.php:708 -#: ../../Zotlabs/Module/Cal.php:207 -msgid "Today" +#: ../../Zotlabs/Widget/Activity_order.php:90 +msgid "Commented Date" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1038 ../../Zotlabs/Module/Events.php:703 -msgid "Month" +#: ../../Zotlabs/Widget/Activity_order.php:94 +msgid "Order by last commented date" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1039 ../../Zotlabs/Module/Events.php:704 -msgid "Week" +#: ../../Zotlabs/Widget/Activity_order.php:97 +msgid "Posted Date" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1040 ../../Zotlabs/Module/Events.php:705 -msgid "Day" +#: ../../Zotlabs/Widget/Activity_order.php:101 +msgid "Order by last posted date" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1041 -msgid "List month" +#: ../../Zotlabs/Widget/Activity_order.php:104 +msgid "Date Unthreaded" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1042 -msgid "List week" +#: ../../Zotlabs/Widget/Activity_order.php:108 +msgid "Order unthreaded by date" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1043 -msgid "List day" +#: ../../Zotlabs/Widget/Activity_order.php:123 +msgid "Stream Order" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1051 -msgid "More" +#: ../../Zotlabs/Widget/Mailmenu.php:13 +msgid "Private Mail Menu" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1052 -msgid "Less" +#: ../../Zotlabs/Widget/Mailmenu.php:15 +msgid "Combined View" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1054 -msgid "Select calendar" +#: ../../Zotlabs/Widget/Mailmenu.php:20 +msgid "Inbox" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1057 -msgid "Delete all" +#: ../../Zotlabs/Widget/Mailmenu.php:25 +msgid "Outbox" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1060 -msgid "Sorry! Editing of recurrent events is not yet implemented." +#: ../../Zotlabs/Widget/Mailmenu.php:30 +msgid "New Message" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1373 ../../Zotlabs/Module/Connedit.php:916 -msgid "Organisation" +#: ../../Zotlabs/Widget/Affinity.php:54 +msgid "Refresh" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1375 ../../Zotlabs/Module/Profiles.php:788 -#: ../../Zotlabs/Module/Connedit.php:918 -msgid "Phone" +#: ../../Zotlabs/Widget/Hq_controls.php:14 +msgid "HQ Control Panel" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1377 ../../Zotlabs/Module/Profiles.php:790 -#: ../../Zotlabs/Module/Connedit.php:920 -msgid "Instant messenger" +#: ../../Zotlabs/Widget/Hq_controls.php:17 +msgid "Create a new post" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1378 ../../Zotlabs/Module/Profiles.php:791 -#: ../../Zotlabs/Module/Connedit.php:921 -msgid "Website" +#: ../../Zotlabs/Widget/Eventstools.php:13 +msgid "Events Tools" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1379 -#: ../../Zotlabs/Module/Admin/Channels.php:160 -#: ../../Zotlabs/Module/Profiles.php:504 ../../Zotlabs/Module/Profiles.php:792 -#: ../../Zotlabs/Module/Connedit.php:922 ../../Zotlabs/Module/Locs.php:129 -msgid "Address" +#: ../../Zotlabs/Widget/Eventstools.php:14 +msgid "Export Calendar" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1380 ../../Zotlabs/Module/Profiles.php:793 -#: ../../Zotlabs/Module/Connedit.php:923 -msgid "Note" +#: ../../Zotlabs/Widget/Eventstools.php:15 +msgid "Import Calendar" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1385 ../../Zotlabs/Module/Profiles.php:798 -#: ../../Zotlabs/Module/Connedit.php:928 -msgid "Add Contact" +#: ../../Zotlabs/Widget/Activity_filter.php:33 +msgid "Direct Messages" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1386 ../../Zotlabs/Module/Profiles.php:799 -#: ../../Zotlabs/Module/Connedit.php:929 -msgid "Add Field" +#: ../../Zotlabs/Widget/Activity_filter.php:37 +msgid "Show direct (private) messages" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1391 ../../Zotlabs/Module/Connedit.php:934 -msgid "P.O. Box" +#: ../../Zotlabs/Widget/Activity_filter.php:42 +msgid "Events" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1392 ../../Zotlabs/Module/Connedit.php:935 -msgid "Additional" +#: ../../Zotlabs/Widget/Activity_filter.php:46 +msgid "Show posts that include events" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1393 ../../Zotlabs/Module/Connedit.php:936 -msgid "Street" +#: ../../Zotlabs/Widget/Activity_filter.php:52 +msgid "Polls" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1394 ../../Zotlabs/Module/Connedit.php:937 -msgid "Locality" +#: ../../Zotlabs/Widget/Activity_filter.php:56 +msgid "Show posts that include polls" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1395 ../../Zotlabs/Module/Connedit.php:938 -msgid "Region" +#: ../../Zotlabs/Widget/Activity_filter.php:77 +#, php-format +msgid "Show posts related to the %s privacy group" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1396 ../../Zotlabs/Module/Connedit.php:939 -msgid "ZIP Code" +#: ../../Zotlabs/Widget/Activity_filter.php:86 +msgid "Show my privacy groups" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1397 ../../Zotlabs/Module/Profiles.php:759 -#: ../../Zotlabs/Module/Connedit.php:940 -msgid "Country" +#: ../../Zotlabs/Widget/Activity_filter.php:108 +msgid "Show posts to this forum" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1456 -msgid "Default Calendar" +#: ../../Zotlabs/Widget/Activity_filter.php:119 +msgid "Show forums" msgstr "" -#: ../../Zotlabs/Module/Cdav.php:1467 -msgid "Default Addressbook" +#: ../../Zotlabs/Widget/Activity_filter.php:133 +msgid "Starred Posts" msgstr "" -#: ../../Zotlabs/Module/Lockview.php:75 -msgid "Remote privacy information not available." +#: ../../Zotlabs/Widget/Activity_filter.php:137 +msgid "Show posts that I have starred" msgstr "" -#: ../../Zotlabs/Module/Lockview.php:96 -msgid "Visible to:" +#: ../../Zotlabs/Widget/Activity_filter.php:148 +msgid "Personal Posts" msgstr "" -#: ../../Zotlabs/Module/Lockview.php:117 ../../Zotlabs/Module/Lockview.php:153 -#: ../../Zotlabs/Module/Acl.php:121 -msgctxt "acl" -msgid "Profile" +#: ../../Zotlabs/Widget/Activity_filter.php:152 +msgid "Show posts that mention or involve me" msgstr "" -#: ../../Zotlabs/Module/Item.php:736 -msgid "Empty post discarded." +#: ../../Zotlabs/Widget/Activity_filter.php:173 +#, php-format +msgid "Show posts that I have filed to %s" msgstr "" -#: ../../Zotlabs/Module/Item.php:1187 -msgid "Duplicate post suppressed." +#: ../../Zotlabs/Widget/Activity_filter.php:183 +msgid "Show filed post categories" msgstr "" -#: ../../Zotlabs/Module/Item.php:1332 -msgid "System error. Post not saved." +#: ../../Zotlabs/Widget/Activity_filter.php:197 +msgid "Panel search" msgstr "" -#: ../../Zotlabs/Module/Item.php:1366 -msgid "Your comment is awaiting approval." +#: ../../Zotlabs/Widget/Activity_filter.php:207 +msgid "Filter by name" msgstr "" -#: ../../Zotlabs/Module/Item.php:1496 -msgid "Unable to obtain post information from database." +#: ../../Zotlabs/Widget/Activity_filter.php:222 +msgid "Remove active filter" msgstr "" -#: ../../Zotlabs/Module/Item.php:1503 -#, php-format -msgid "You have reached your limit of %1$.0f top level posts." +#: ../../Zotlabs/Widget/Activity_filter.php:238 +msgid "Stream Filters" msgstr "" -#: ../../Zotlabs/Module/Item.php:1510 -#, php-format -msgid "You have reached your limit of %1$.0f webpages." +#: ../../Zotlabs/Widget/Activity.php:50 +msgctxt "widget" +msgid "Activity" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:31 ../../Zotlabs/Module/Menu.php:209 -msgid "Menu not found." +#: ../../Zotlabs/Widget/Notifications.php:16 +msgid "New Network Activity" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:63 -msgid "Unable to create element." +#: ../../Zotlabs/Widget/Notifications.php:17 +msgid "New Network Activity Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:87 -msgid "Unable to update menu element." +#: ../../Zotlabs/Widget/Notifications.php:20 +msgid "View your network activity" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:103 -msgid "Unable to add menu element." +#: ../../Zotlabs/Widget/Notifications.php:23 +#: ../../Zotlabs/Widget/Notifications.php:62 +msgid "Mark all notifications read" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:134 ../../Zotlabs/Module/Xchan.php:41 -#: ../../Zotlabs/Module/Menu.php:232 -msgid "Not found." +#: ../../Zotlabs/Widget/Notifications.php:26 +#: ../../Zotlabs/Widget/Notifications.php:46 +#: ../../Zotlabs/Widget/Notifications.php:65 +#: ../../Zotlabs/Widget/Notifications.php:172 +msgid "Show new posts only" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:167 ../../Zotlabs/Module/Mitem.php:246 -msgid "Menu Item Permissions" +#: ../../Zotlabs/Widget/Notifications.php:27 +#: ../../Zotlabs/Widget/Notifications.php:47 +#: ../../Zotlabs/Widget/Notifications.php:66 +#: ../../Zotlabs/Widget/Notifications.php:142 +#: ../../Zotlabs/Widget/Notifications.php:173 +msgid "Filter by name or address" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247 -#: ../../Zotlabs/Module/Settings/Channel.php:528 -msgid "(click to open/close)" +#: ../../Zotlabs/Widget/Notifications.php:36 +msgid "New Home Activity" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:174 ../../Zotlabs/Module/Mitem.php:191 -msgid "Link Name" +#: ../../Zotlabs/Widget/Notifications.php:37 +msgid "New Home Activity Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:175 ../../Zotlabs/Module/Mitem.php:255 -msgid "Link or Submenu Target" +#: ../../Zotlabs/Widget/Notifications.php:40 +msgid "View your home activity" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:175 -msgid "Enter URL of the link or select a menu name to create a submenu" +#: ../../Zotlabs/Widget/Notifications.php:43 +#: ../../Zotlabs/Widget/Notifications.php:169 +msgid "Mark all notifications seen" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:256 -msgid "Use magic-auth if available" +#: ../../Zotlabs/Widget/Notifications.php:55 +msgid "New Direct Messages" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:257 -msgid "Open link in new window" +#: ../../Zotlabs/Widget/Notifications.php:56 +msgid "New Direct Messages Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 -msgid "Order in list" +#: ../../Zotlabs/Widget/Notifications.php:59 +msgid "View your direct messages" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 -msgid "Higher numbers will sink to bottom of listing" +#: ../../Zotlabs/Widget/Notifications.php:74 +msgid "New Mails" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:179 -msgid "Submit and finish" +#: ../../Zotlabs/Widget/Notifications.php:75 +msgid "New Mails Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:180 -msgid "Submit and continue" +#: ../../Zotlabs/Widget/Notifications.php:78 +msgid "View your private mails" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:189 -msgid "Menu:" +#: ../../Zotlabs/Widget/Notifications.php:81 +msgid "Mark all messages seen" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:192 -msgid "Link Target" +#: ../../Zotlabs/Widget/Notifications.php:89 +msgid "New Events" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:195 -msgid "Edit menu" +#: ../../Zotlabs/Widget/Notifications.php:90 +msgid "New Events Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:198 -msgid "Edit element" +#: ../../Zotlabs/Widget/Notifications.php:93 +msgid "View events" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:199 -msgid "Drop element" +#: ../../Zotlabs/Widget/Notifications.php:96 +msgid "Mark all events seen" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:200 -msgid "New element" +#: ../../Zotlabs/Widget/Notifications.php:105 +msgid "New Connections Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:201 -msgid "Edit this menu container" +#: ../../Zotlabs/Widget/Notifications.php:108 +msgid "View all connections" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:202 -msgid "Add menu element" +#: ../../Zotlabs/Widget/Notifications.php:116 +msgid "New Files" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:203 -msgid "Delete this menu item" +#: ../../Zotlabs/Widget/Notifications.php:117 +msgid "New Files Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:204 -msgid "Edit this menu item" +#: ../../Zotlabs/Widget/Notifications.php:124 +#: ../../Zotlabs/Widget/Notifications.php:125 +msgid "Notices" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:222 -msgid "Menu item not found." +#: ../../Zotlabs/Widget/Notifications.php:128 +msgid "View all notices" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:235 -msgid "Menu item deleted." +#: ../../Zotlabs/Widget/Notifications.php:131 +msgid "Mark all notices seen" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:237 -msgid "Menu item could not be deleted." +#: ../../Zotlabs/Widget/Notifications.php:152 +msgid "New Registrations" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:244 -msgid "Edit Menu Element" +#: ../../Zotlabs/Widget/Notifications.php:153 +msgid "New Registrations Notifications" msgstr "" -#: ../../Zotlabs/Module/Mitem.php:254 -msgid "Link text" +#: ../../Zotlabs/Widget/Notifications.php:163 +msgid "Public Stream Notifications" msgstr "" -#: ../../Zotlabs/Module/Profile.php:93 -msgid "vcard" +#: ../../Zotlabs/Widget/Notifications.php:166 +msgid "View the public stream" msgstr "" -#: ../../Zotlabs/Module/Sharedwithme.php:105 -msgid "Files: shared with me" +#: ../../Zotlabs/Widget/Notifications.php:181 +msgid "Sorry, you have got no notifications at the moment" msgstr "" -#: ../../Zotlabs/Module/Sharedwithme.php:107 -msgid "NEW" +#: ../../Zotlabs/Widget/Pinned.php:123 ../../Zotlabs/Widget/Pinned.php:124 +#, php-format +msgid "View %s's profile - %s" msgstr "" -#: ../../Zotlabs/Module/Sharedwithme.php:109 -#: ../../Zotlabs/Storage/Browser.php:373 -msgid "Last Modified" +#: ../../Zotlabs/Widget/Pinned.php:158 +msgid "Don't show" msgstr "" -#: ../../Zotlabs/Module/Sharedwithme.php:110 -msgid "Remove all files" +#: ../../Zotlabs/Widget/Settings_menu.php:32 +msgid "Account settings" msgstr "" -#: ../../Zotlabs/Module/Sharedwithme.php:111 -msgid "Remove this file" +#: ../../Zotlabs/Widget/Settings_menu.php:38 +msgid "Channel settings" msgstr "" -#: ../../Zotlabs/Module/Help.php:23 -msgid "Documentation Search" +#: ../../Zotlabs/Widget/Settings_menu.php:46 +msgid "Display settings" msgstr "" -#: ../../Zotlabs/Module/Help.php:85 -msgid "Administrators" +#: ../../Zotlabs/Widget/Settings_menu.php:53 +msgid "Manage locations" msgstr "" -#: ../../Zotlabs/Module/Help.php:86 -msgid "Developers" +#: ../../Zotlabs/Widget/Suggestedchats.php:32 +msgid "Suggested Chatrooms" msgstr "" -#: ../../Zotlabs/Module/Help.php:87 -msgid "Tutorials" +#: ../../Zotlabs/Widget/Conversations.php:17 +msgid "Received Messages" msgstr "" -#: ../../Zotlabs/Module/Help.php:98 -msgid "$Projectname Documentation" +#: ../../Zotlabs/Widget/Conversations.php:21 +msgid "Sent Messages" msgstr "" -#: ../../Zotlabs/Module/Help.php:99 -msgid "Contents" +#: ../../Zotlabs/Widget/Conversations.php:25 +msgid "Conversations" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:48 -msgid "Webpages App" +#: ../../Zotlabs/Widget/Conversations.php:37 +msgid "No messages." msgstr "" -#: ../../Zotlabs/Module/Webpages.php:49 -msgid "Provide managed web pages on your channel" +#: ../../Zotlabs/Widget/Conversations.php:57 +msgid "Delete conversation" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:69 -msgid "Import Webpage Elements" +#: ../../Zotlabs/Widget/Newmember.php:31 +msgid "Profile Creation" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:70 -msgid "Import selected" +#: ../../Zotlabs/Widget/Newmember.php:33 +msgid "Upload profile photo" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:93 -msgid "Export Webpage Elements" +#: ../../Zotlabs/Widget/Newmember.php:34 +msgid "Upload cover photo" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:94 -msgid "Export selected" +#: ../../Zotlabs/Widget/Newmember.php:35 ../../include/nav.php:117 +msgid "Edit your profile" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:263 -msgid "Actions" +#: ../../Zotlabs/Widget/Newmember.php:38 +msgid "Find and Connect with others" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:264 -msgid "Page Link" +#: ../../Zotlabs/Widget/Newmember.php:40 +msgid "View the directory" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:265 -msgid "Page Title" +#: ../../Zotlabs/Widget/Newmember.php:42 +msgid "Manage your connections" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:266 ../../Zotlabs/Module/Blocks.php:157 -#: ../../Zotlabs/Module/Menu.php:178 ../../Zotlabs/Module/Layouts.php:191 -msgid "Created" +#: ../../Zotlabs/Widget/Newmember.php:45 +msgid "Communicate" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:267 ../../Zotlabs/Module/Blocks.php:158 -#: ../../Zotlabs/Module/Menu.php:179 ../../Zotlabs/Module/Layouts.php:192 -msgid "Edited" +#: ../../Zotlabs/Widget/Newmember.php:47 +msgid "View your channel homepage" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:295 -msgid "Invalid file type." +#: ../../Zotlabs/Widget/Newmember.php:48 +msgid "View your network stream" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:307 -msgid "Error opening zip file" +#: ../../Zotlabs/Widget/Newmember.php:54 +msgid "Documentation" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:318 -msgid "Invalid folder path." +#: ../../Zotlabs/Widget/Newmember.php:57 +msgid "Missing Features?" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:345 -msgid "No webpage elements detected." +#: ../../Zotlabs/Widget/Newmember.php:59 +msgid "Pin apps to navigation bar" msgstr "" -#: ../../Zotlabs/Module/Webpages.php:420 -msgid "Import complete." +#: ../../Zotlabs/Widget/Newmember.php:60 +msgid "Install more apps" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:14 -#: ../../Zotlabs/Module/Filestorage.php:53 -msgid "Deprecated!" +#: ../../Zotlabs/Widget/Newmember.php:71 +msgid "View public stream" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:157 -msgid "Permission Denied." +#: ../../Zotlabs/Widget/Cover_photo.php:65 +msgid "Click to show more" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:190 -msgid "Edit file permissions" +#: ../../util/nconfig.php:34 +msgid "Source channel not found." msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:203 -msgid "Include all files and sub folders" -msgstr "" +#: ../../include/contact_widgets.php:11 +#, php-format +msgid "%d invitation available" +msgid_plural "%d invitations available" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Filestorage.php:204 -msgid "Return to file list" +#: ../../include/contact_widgets.php:19 +msgid "Find Channels" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:206 -#: ../../Zotlabs/Storage/Browser.php:379 -msgid "Copy/paste this code to attach file to a post" +#: ../../include/contact_widgets.php:20 +msgid "Enter name or interest" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:207 -#: ../../Zotlabs/Storage/Browser.php:380 -msgid "Copy/paste this URL to link file from a web page" +#: ../../include/contact_widgets.php:21 +msgid "Connect/Follow" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:209 -msgid "Share this file" +#: ../../include/contact_widgets.php:22 +msgid "Examples: Robert Morgenstein, Fishing" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:210 -msgid "Show URL to this file" +#: ../../include/contact_widgets.php:26 +msgid "Random Profile" msgstr "" -#: ../../Zotlabs/Module/Filestorage.php:211 -#: ../../Zotlabs/Storage/Browser.php:545 -msgid "Show in your contacts shared folder" +#: ../../include/contact_widgets.php:27 +msgid "Invite Friends" msgstr "" -#: ../../Zotlabs/Module/Tagrm.php:48 ../../Zotlabs/Module/Tagrm.php:98 -msgid "Tag removed" +#: ../../include/contact_widgets.php:29 +msgid "Advanced example: name=fred and country=iceland" msgstr "" -#: ../../Zotlabs/Module/Tagrm.php:123 -msgid "Remove Item Tag" +#: ../../include/contact_widgets.php:265 +msgid "Common Connections" msgstr "" -#: ../../Zotlabs/Module/Tagrm.php:125 -msgid "Select a tag to remove: " +#: ../../include/contact_widgets.php:269 +#, php-format +msgid "View all %d common connections" msgstr "" -#: ../../Zotlabs/Module/Connect.php:65 ../../Zotlabs/Module/Connect.php:118 -msgid "Continue" +#: ../../include/conversation.php:183 +#, php-format +msgid "likes %1$s's %2$s" msgstr "" -#: ../../Zotlabs/Module/Connect.php:99 -msgid "Premium Channel Setup" +#: ../../include/conversation.php:186 +#, php-format +msgid "doesn't like %1$s's %2$s" msgstr "" -#: ../../Zotlabs/Module/Connect.php:101 -msgid "Enable premium channel connection restrictions" +#: ../../include/conversation.php:226 ../../include/conversation.php:228 +#, php-format +msgid "%1$s is now connected with %2$s" msgstr "" -#: ../../Zotlabs/Module/Connect.php:102 -msgid "" -"Please enter your restrictions or conditions, such as paypal receipt, usage " -"guidelines, etc." +#: ../../include/conversation.php:263 +#, php-format +msgid "%1$s poked %2$s" msgstr "" -#: ../../Zotlabs/Module/Connect.php:104 ../../Zotlabs/Module/Connect.php:124 -msgid "" -"This channel may require additional steps or acknowledgement of the " -"following conditions prior to connecting:" +#: ../../include/conversation.php:267 ../../include/text.php:1242 +#: ../../include/text.php:1246 +msgid "poked" msgstr "" -#: ../../Zotlabs/Module/Connect.php:105 -msgid "" -"Potential connections will then see the following text before proceeding:" +#: ../../include/conversation.php:779 +#, php-format +msgid "View %s's profile @ %s" msgstr "" -#: ../../Zotlabs/Module/Connect.php:106 ../../Zotlabs/Module/Connect.php:127 -msgid "" -"By continuing, I certify that I have complied with any instructions provided " -"on this page." +#: ../../include/conversation.php:799 +msgid "Categories:" msgstr "" -#: ../../Zotlabs/Module/Connect.php:115 -msgid "(No specific instructions have been provided by the channel owner.)" +#: ../../include/conversation.php:800 +msgid "Filed under:" msgstr "" -#: ../../Zotlabs/Module/Connect.php:123 -msgid "Restricted or Premium Channel" +#: ../../include/conversation.php:825 +msgid "View in context" msgstr "" -#: ../../Zotlabs/Module/Cloud.php:120 -msgid "Not found" +#: ../../include/conversation.php:928 +msgid "remove" msgstr "" -#: ../../Zotlabs/Module/Cloud.php:126 -msgid "Please refresh page" +#: ../../include/conversation.php:932 +msgid "Loading..." msgstr "" -#: ../../Zotlabs/Module/Cloud.php:129 -msgid "Unknown error" +#: ../../include/conversation.php:934 +msgid "Delete Selected Items" msgstr "" -#: ../../Zotlabs/Module/Share.php:104 ../../Zotlabs/Lib/Activity.php:2133 -#, php-format -msgid "🔁 Repeated %1$s's %2$s" +#: ../../include/conversation.php:977 +msgid "View Source" msgstr "" -#: ../../Zotlabs/Module/Share.php:120 -msgid "Post repeated" +#: ../../include/conversation.php:987 +msgid "Follow Thread" msgstr "" -#: ../../Zotlabs/Module/Acl.php:368 -msgid "network" +#: ../../include/conversation.php:996 +msgid "Unfollow Thread" msgstr "" -#: ../../Zotlabs/Module/Editpost.php:38 ../../Zotlabs/Module/Editpost.php:43 -msgid "Item is not editable" +#: ../../include/conversation.php:1110 +msgid "Edit Connection" msgstr "" -#: ../../Zotlabs/Module/Editpost.php:109 ../../Zotlabs/Module/Rpost.php:150 -msgid "Edit post" +#: ../../include/conversation.php:1120 +msgid "Message" msgstr "" -#: ../../Zotlabs/Module/Tagger.php:50 -msgid "Post not found." +#: ../../include/conversation.php:1262 +#, php-format +msgid "%s likes this." msgstr "" -#: ../../Zotlabs/Module/Tagger.php:121 +#: ../../include/conversation.php:1262 #, php-format -msgid "%1$s tagged %2$s's %3$s with %4$s" +msgid "%s doesn't like this." msgstr "" -#: ../../Zotlabs/Module/Authorize.php:17 -msgid "Unknown App" -msgstr "" +#: ../../include/conversation.php:1266 +#, php-format +msgid "%2$d people like this." +msgid_plural "%2$d people like this." +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Authorize.php:29 -msgid "Authorize" +#: ../../include/conversation.php:1268 +#, php-format +msgid "%2$d people don't like this." +msgid_plural "%2$d people don't like this." +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1274 +msgid "and" msgstr "" -#: ../../Zotlabs/Module/Authorize.php:30 +#: ../../include/conversation.php:1277 #, php-format -msgid "Do you authorize the app %s to access your channel data?" -msgstr "" +msgid ", and %d other people" +msgid_plural ", and %d other people" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Authorize.php:33 -#: ../../Zotlabs/Module/Admin/Accounts.php:174 -msgid "Deny" +#: ../../include/conversation.php:1278 +#, php-format +msgid "%s like this." msgstr "" -#: ../../Zotlabs/Module/Admin/Queue.php:35 -msgid "Queue Statistics" +#: ../../include/conversation.php:1278 +#, php-format +msgid "%s don't like this." msgstr "" -#: ../../Zotlabs/Module/Admin/Queue.php:36 -msgid "Total Entries" +#: ../../include/conversation.php:1328 +#: ../../extend/addon/hzaddons/hsse/hsse.php:82 +msgid "Set your location" msgstr "" -#: ../../Zotlabs/Module/Admin/Queue.php:37 -msgid "Priority" +#: ../../include/conversation.php:1329 +#: ../../extend/addon/hzaddons/hsse/hsse.php:83 +msgid "Clear browser location" msgstr "" -#: ../../Zotlabs/Module/Admin/Queue.php:38 -msgid "Destination URL" +#: ../../include/conversation.php:1345 +#: ../../extend/addon/hzaddons/hsse/hsse.php:99 +msgid "Embed (existing) photo from your photo albums" msgstr "" -#: ../../Zotlabs/Module/Admin/Queue.php:39 -msgid "Mark hub permanently offline" +#: ../../include/conversation.php:1381 +#: ../../extend/addon/hzaddons/hsse/hsse.php:135 +msgid "Tag term:" msgstr "" -#: ../../Zotlabs/Module/Admin/Queue.php:40 -msgid "Empty queue for this hub" +#: ../../include/conversation.php:1382 +#: ../../extend/addon/hzaddons/hsse/hsse.php:136 +msgid "Where are you right now?" msgstr "" -#: ../../Zotlabs/Module/Admin/Queue.php:41 -msgid "Last known contact" +#: ../../include/conversation.php:1387 +#: ../../extend/addon/hzaddons/hsse/hsse.php:141 +msgid "Choose a different album..." msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:26 -msgid "Theme settings updated." +#: ../../include/conversation.php:1391 +#: ../../extend/addon/hzaddons/hsse/hsse.php:145 +msgid "Comments enabled" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:61 -msgid "No themes found." +#: ../../include/conversation.php:1392 +#: ../../extend/addon/hzaddons/hsse/hsse.php:146 +msgid "Comments disabled" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:95 -#: ../../Zotlabs/Module/Admin/Addons.php:311 -msgid "Disable" +#: ../../include/conversation.php:1444 +#: ../../extend/addon/hzaddons/hsse/hsse.php:195 +msgid "Page link name" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:97 -#: ../../Zotlabs/Module/Admin/Addons.php:314 -msgid "Enable" +#: ../../include/conversation.php:1447 +#: ../../extend/addon/hzaddons/hsse/hsse.php:198 +msgid "Post as" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:116 -msgid "Screenshot" +#: ../../include/conversation.php:1461 +#: ../../extend/addon/hzaddons/hsse/hsse.php:212 +msgid "Toggle voting" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:122 -#: ../../Zotlabs/Module/Admin/Themes.php:156 -#: ../../Zotlabs/Module/Admin/Security.php:98 -#: ../../Zotlabs/Module/Admin/Accounts.php:166 -#: ../../Zotlabs/Module/Admin/Site.php:291 -#: ../../Zotlabs/Module/Admin/Logs.php:82 -#: ../../Zotlabs/Module/Admin/Channels.php:145 -#: ../../Zotlabs/Module/Admin/Addons.php:342 -#: ../../Zotlabs/Module/Admin/Addons.php:440 ../../Zotlabs/Module/Admin.php:138 -msgid "Administration" +#: ../../include/conversation.php:1462 +msgid "Toggle poll" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:124 -#: ../../Zotlabs/Module/Admin/Addons.php:344 -msgid "Toggle" +#: ../../include/conversation.php:1463 +msgid "Option" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:134 -#: ../../Zotlabs/Module/Admin/Addons.php:352 -msgid "Author: " +#: ../../include/conversation.php:1464 +msgid "Add option" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:135 -#: ../../Zotlabs/Module/Admin/Addons.php:353 -msgid "Maintainer: " +#: ../../include/conversation.php:1465 +msgid "Minutes" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:162 -msgid "[Experimental]" +#: ../../include/conversation.php:1465 +msgid "Hours" msgstr "" -#: ../../Zotlabs/Module/Admin/Themes.php:163 -msgid "[Unsupported]" +#: ../../include/conversation.php:1465 +msgid "Days" msgstr "" -#: ../../Zotlabs/Module/Admin/Features.php:56 -#, php-format -msgid "Lock feature %s" +#: ../../include/conversation.php:1466 +msgid "Allow multiple answers" msgstr "" -#: ../../Zotlabs/Module/Admin/Features.php:64 -msgid "Manage Additional Features" +#: ../../include/conversation.php:1468 +#: ../../extend/addon/hzaddons/hsse/hsse.php:215 +msgid "Disable comments" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:89 -msgid "" -"By default, unfiltered HTML is allowed in embedded media. This is inherently " -"insecure." +#: ../../include/conversation.php:1469 +#: ../../extend/addon/hzaddons/hsse/hsse.php:216 +msgid "Toggle comments" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:92 -msgid "" -"The recommended setting is to only allow unfiltered HTML from the following " -"sites:" +#: ../../include/conversation.php:1477 +#: ../../extend/addon/hzaddons/hsse/hsse.php:224 +msgid "Categories (optional, comma-separated list)" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:93 -msgid "" -"https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/" -"
      https://vimeo.com/
      https://soundcloud.com/
      " +#: ../../include/conversation.php:1500 +#: ../../extend/addon/hzaddons/hsse/hsse.php:247 +msgid "Other networks and post services" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:94 -msgid "" -"All other embedded content will be filtered, unless " -"embedded content from that site is explicitly blocked." +#: ../../include/conversation.php:1503 +#: ../../extend/addon/hzaddons/hsse/hsse.php:250 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:170 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:313 +msgid "Set expiration date" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:101 -msgid "Block public" +#: ../../include/conversation.php:1506 +#: ../../extend/addon/hzaddons/hsse/hsse.php:253 +msgid "Set publish date" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:101 -msgid "" -"Check to block public access to all otherwise public personal pages on this " -"site unless you are currently authenticated." -msgstr "" +#: ../../include/conversation.php:1755 +msgctxt "noun" +msgid "Attending" +msgid_plural "Attending" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Admin/Security.php:102 -msgid "Provide a cloud root directory" +#: ../../include/conversation.php:1758 +msgctxt "noun" +msgid "Not Attending" +msgid_plural "Not Attending" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1761 +msgctxt "noun" +msgid "Undecided" +msgid_plural "Undecided" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1764 +msgctxt "noun" +msgid "Agree" +msgid_plural "Agrees" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1767 +msgctxt "noun" +msgid "Disagree" +msgid_plural "Disagrees" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1770 +msgctxt "noun" +msgid "Abstain" +msgid_plural "Abstains" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/channel.php:46 +msgid "Unable to obtain identity information from database" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:102 -msgid "" -"The cloud root directory lists all channel names which provide public files" +#: ../../include/channel.php:79 +msgid "Empty name" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:103 -msgid "Show total disk space available to cloud uploads" +#: ../../include/channel.php:82 +msgid "Name too long" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:104 -msgid "Set \"Transport Security\" HTTP header" +#: ../../include/channel.php:199 +msgid "No account identifier" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:105 -msgid "Set \"Content Security Policy\" HTTP header" +#: ../../include/channel.php:211 +msgid "Nickname is required." msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:106 -msgid "Allowed email domains" +#: ../../include/channel.php:294 +msgid "Unable to retrieve created identity" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:106 -msgid "" -"Comma separated list of domains which are allowed in email addresses for " -"registrations to this site. Wildcards are accepted. Empty to allow any " -"domains" +#: ../../include/channel.php:441 +msgid "Default Profile" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:107 -msgid "Not allowed email domains" +#: ../../include/channel.php:639 ../../include/channel.php:728 +msgid "Unable to retrieve modified identity" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:107 -msgid "" -"Comma separated list of domains which are not allowed in email addresses for " -"registrations to this site. Wildcards are accepted. Empty to allow any " -"domains, unless allowed domains have been defined." +#: ../../include/channel.php:1385 +msgid "Requested channel is not available." msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:108 -msgid "Allow communications only from these sites" +#: ../../include/channel.php:1539 +msgid "Create New Profile" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:108 -msgid "" -"One site per line. Leave empty to allow communication from anywhere by " -"default" +#: ../../include/channel.php:1542 ../../include/nav.php:117 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:58 +msgid "Edit Profile" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:109 -msgid "Block communications from these sites" +#: ../../include/channel.php:1560 +msgid "Visible to everybody" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:110 -msgid "Allow communications only from these channels" +#: ../../include/channel.php:1637 ../../include/channel.php:1765 +msgid "Gender:" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:110 -msgid "" -"One channel (hash) per line. Leave empty to allow from any channel by default" +#: ../../include/channel.php:1638 ../../include/channel.php:1809 +msgid "Status:" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:111 -msgid "Block communications from these channels" +#: ../../include/channel.php:1639 ../../include/channel.php:1833 +msgid "Homepage:" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:112 -msgid "Only allow embeds from secure (SSL) websites and links." +#: ../../include/channel.php:1640 +msgid "Online Now" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:113 -msgid "Allow unfiltered embedded HTML content only from these domains" +#: ../../include/channel.php:1693 +msgid "Change your profile photo" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:113 -msgid "One site per line. By default embedded content is filtered." +#: ../../include/channel.php:1720 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:87 +msgid "Female" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:114 -msgid "Block embedded HTML from these domains" +#: ../../include/channel.php:1722 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:85 +msgid "Male" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:115 -msgid "Allow SVG thumbnails in file browser" +#: ../../include/channel.php:1724 +msgid "Trans" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:115 -msgid "WARNING: SVG images may contain malicious code." +#: ../../include/channel.php:1726 ../../include/selectors.php:60 +msgid "Neuter" msgstr "" -#: ../../Zotlabs/Module/Admin/Security.php:116 -msgid "Allow embedded (inline) PDF files" +#: ../../include/channel.php:1728 ../../include/selectors.php:60 +msgid "Non-specific" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:37 -#, php-format -msgid "%s account blocked/unblocked" -msgid_plural "%s account blocked/unblocked" -msgstr[0] "" -msgstr[1] "" +#: ../../include/channel.php:1770 +msgid "Like this channel" +msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:44 -#, php-format -msgid "%s account deleted" -msgid_plural "%s accounts deleted" -msgstr[0] "" -msgstr[1] "" +#: ../../include/channel.php:1794 +msgid "j F, Y" +msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:80 -msgid "Account not found" +#: ../../include/channel.php:1795 +msgid "j F" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:99 -#, php-format -msgid "Account '%s' blocked" +#: ../../include/channel.php:1802 +msgid "Birthday:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:107 +#: ../../include/channel.php:1815 #, php-format -msgid "Account '%s' unblocked" +msgid "for %1$d %2$s" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:169 -#: ../../Zotlabs/Module/Admin/Channels.php:148 -msgid "select all" +#: ../../include/channel.php:1827 +msgid "Tags:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:170 -msgid "Registrations waiting for confirm" +#: ../../include/channel.php:1831 +msgid "Sexual Preference:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:171 -msgid "Request date" +#: ../../include/channel.php:1837 +msgid "Political Views:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:172 -msgid "No registrations." +#: ../../include/channel.php:1839 +msgid "Religion:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:176 -#: ../../Zotlabs/Module/Connedit.php:628 -msgid "Block" +#: ../../include/channel.php:1843 +msgid "Hobbies/Interests:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:177 -#: ../../Zotlabs/Module/Connedit.php:628 -msgid "Unblock" +#: ../../include/channel.php:1845 +msgid "Likes:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:182 -msgid "ID" +#: ../../include/channel.php:1847 +msgid "Dislikes:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:184 -msgid "All Channels" +#: ../../include/channel.php:1849 +msgid "Contact information and Social Networks:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:185 -msgid "Register date" +#: ../../include/channel.php:1851 +msgid "My other channels:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:186 -msgid "Last login" +#: ../../include/channel.php:1853 +msgid "Musical interests:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:187 -msgid "Expires" +#: ../../include/channel.php:1855 +msgid "Books, literature:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:188 -msgid "Service Class" +#: ../../include/channel.php:1857 +msgid "Television:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:190 -msgid "" -"Selected accounts will be deleted!\\n\\nEverything these accounts had posted " -"on this site will be permanently deleted!\\n\\nAre you sure?" +#: ../../include/channel.php:1859 +msgid "Film/dance/culture/entertainment:" msgstr "" -#: ../../Zotlabs/Module/Admin/Accounts.php:191 -msgid "" -"The account {0} will be deleted!\\n\\nEverything this account has posted on " -"this site will be permanently deleted!\\n\\nAre you sure?" +#: ../../include/channel.php:1861 +msgid "Love/Romance:" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:165 -msgid "Site settings updated." +#: ../../include/channel.php:1863 +msgid "Work/employment:" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:202 -#: ../../Zotlabs/Module/Settings/Display.php:118 -#, php-format -msgid "%s - (Incompatible)" +#: ../../include/channel.php:1865 +msgid "School/education:" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:209 -msgid "mobile" +#: ../../include/channel.php:1888 +msgid "Like this thing" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:211 -msgid "experimental" +#: ../../include/features.php:86 +msgid "Start calendar week on Monday" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:213 -msgid "unsupported" +#: ../../include/features.php:87 +msgid "Default is Sunday" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:260 -msgid "Yes - with approval" +#: ../../include/features.php:94 +msgid "Event Timezone Selection" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:266 -msgid "My site is not a public server" +#: ../../include/features.php:95 +msgid "Allow event creation in timezones other than your own." msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:267 -msgid "My site has paid access only" +#: ../../include/features.php:108 +msgid "Search by Date" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:268 -msgid "My site has free access only" +#: ../../include/features.php:109 +msgid "Ability to select posts by date ranges" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:269 -msgid "My site offers free accounts with optional paid upgrades" +#: ../../include/features.php:116 +msgid "Tag Cloud" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:283 -msgid "Default permission role for new accounts" +#: ../../include/features.php:117 +msgid "Provide a personal tag cloud on your channel page" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:283 -msgid "" -"This role will be used for the first channel created after registration." +#: ../../include/features.php:124 ../../include/features.php:359 +msgid "Use blog/list mode" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:295 -msgid "File upload" +#: ../../include/features.php:125 ../../include/features.php:360 +msgid "Comments will be displayed separately" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:296 -msgid "Policies" +#: ../../include/features.php:137 +msgid "Connection Filtering" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:303 -msgid "Banner/Logo" +#: ../../include/features.php:138 +msgid "Filter incoming posts from connections based on keywords/content" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:303 -msgid "Unfiltered HTML/CSS/JS is allowed" +#: ../../include/features.php:146 +msgid "Conversation" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:304 -msgid "Administrator Information" +#: ../../include/features.php:158 +msgid "Emoji Reactions" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:304 -msgid "" -"Contact information for site administrators. Displayed on siteinfo page. " -"BBCode can be used here" +#: ../../include/features.php:159 +msgid "Add emoji reaction ability to posts" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:305 ../../Zotlabs/Module/Siteinfo.php:24 -msgid "Site Information" +#: ../../include/features.php:166 +msgid "Dislike Posts" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:305 -msgid "" -"Publicly visible description of this site. Displayed on siteinfo page. " -"BBCode can be used here" +#: ../../include/features.php:167 +msgid "Ability to dislike posts/comments" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:306 -msgid "System language" +#: ../../include/features.php:174 +msgid "Star Posts" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:307 -msgid "System theme" +#: ../../include/features.php:175 +msgid "Ability to mark special posts with a star indicator" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:307 -msgid "" -"Default system theme - may be over-ridden by user profiles - change theme settings" +#: ../../include/features.php:182 +msgid "Reply on comment" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:310 -msgid "Allow Feeds as Connections" +#: ../../include/features.php:183 +msgid "Ability to reply on selected comment" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:310 -msgid "(Heavy system resource usage)" +#: ../../include/features.php:196 +msgid "Advanced Directory Search" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:311 -msgid "Maximum image size" +#: ../../include/features.php:197 +msgid "Allows creation of complex directory search queries" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:311 -msgid "" -"Maximum size in bytes of uploaded images. Default is 0, which means no " -"limits." +#: ../../include/features.php:206 +msgid "Editor" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:312 -msgid "Does this site allow new member registration?" +#: ../../include/features.php:210 +msgid "Post Categories" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:313 -msgid "Invitation only" +#: ../../include/features.php:211 +msgid "Add categories to your posts" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:313 +#: ../../include/features.php:219 +msgid "Large Photos" +msgstr "" + +#: ../../include/features.php:220 msgid "" -"Only allow new member registrations with an invitation code. Above register " -"policy must be set to Yes." +"Include large (1024px) photo thumbnails in posts. If not enabled, use small " +"(640px) photo thumbnails" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:314 -msgid "Minimum age" +#: ../../include/features.php:227 +msgid "Even More Encryption" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:314 -msgid "Minimum age (in years) for who may register on this site." +#: ../../include/features.php:228 +msgid "" +"Allow optional encryption of content end-to-end with a shared secret key" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:315 -msgid "Which best describes the types of account offered by this hub?" +#: ../../include/features.php:235 +msgid "Disable Comments" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:315 -msgid "This is displayed on the public server site list." +#: ../../include/features.php:236 +msgid "Provide the option to disable comments for a post" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:316 -msgid "Register text" +#: ../../include/features.php:243 +msgid "Delayed Posting" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:316 -msgid "Will be displayed prominently on the registration page." +#: ../../include/features.php:244 +msgid "Allow posts to be published at a later date" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:318 -msgid "Site homepage to show visitors (default: login box)" +#: ../../include/features.php:251 +msgid "Content Expiration" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:318 -msgid "" -"example: 'pubstream' to show public stream, 'page/sys/home' to show a system " -"webpage called 'home' or 'include:home.html' to include a file." +#: ../../include/features.php:252 +msgid "Remove posts/comments and/or private messages at a future time" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:319 -msgid "Preserve site homepage URL" +#: ../../include/features.php:259 +msgid "Suppress Duplicate Posts/Comments" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:319 +#: ../../include/features.php:260 msgid "" -"Present the site homepage in a frame at the original location instead of " -"redirecting" +"Prevent posts with identical content to be published with less than two " +"minutes in between submissions." msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:320 -msgid "Accounts abandoned after x days" +#: ../../include/features.php:267 +msgid "Auto-save drafts of posts and comments" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:320 +#: ../../include/features.php:268 msgid "" -"Will not waste system resources polling external sites for abandonded " -"accounts. Enter 0 for no time limit." +"Automatically saves post and comment drafts in local browser storage to help " +"prevent accidental loss of compositions" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:321 -msgid "Allowed friend domains" +#: ../../include/features.php:277 +msgid "Manage" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:321 -msgid "" -"Comma separated list of domains which are allowed to establish friendships " -"with this site. Wildcards are accepted. Empty to allow any domains" +#: ../../include/features.php:281 +msgid "Navigation Channel Select" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:322 -msgid "Verify Email Addresses" +#: ../../include/features.php:282 +msgid "Change channels directly from within the navigation dropdown menu" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:322 -msgid "" -"Check to verify email addresses used in account registration (recommended)." +#: ../../include/features.php:295 +msgid "Events Filter" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:323 -msgid "Force publish" +#: ../../include/features.php:296 +msgid "Ability to display only events" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:323 -msgid "" -"Check to force all profiles on this site to be listed in the site directory." +#: ../../include/features.php:303 +msgid "Polls Filter" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:324 -msgid "Import Public Streams" +#: ../../include/features.php:304 +msgid "Ability to display only polls" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:324 -msgid "" -"Import and allow access to public content pulled from other sites. Warning: " -"this content is unmoderated." +#: ../../include/features.php:312 +msgid "Save search terms for re-use" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:325 -msgid "Site only Public Streams" +#: ../../include/features.php:320 +msgid "Ability to file posts under folders" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:325 -msgid "" -"Allow access to public content originating only from this site if Imported " -"Public Streams are disabled." +#: ../../include/features.php:327 +msgid "Alternate Stream Order" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:326 -msgid "Allow anybody on the internet to access the Public streams" +#: ../../include/features.php:328 +msgid "" +"Ability to order the stream by last post date, last comment date or " +"unthreaded activities" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:326 -msgid "" -"Disable to require authentication before viewing. Warning: this content is " -"unmoderated." +#: ../../include/features.php:335 +msgid "Contact Filter" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:327 -msgid "Only import Public stream posts with this text" +#: ../../include/features.php:336 +msgid "Ability to display only posts of a selected contact" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:327 -#: ../../Zotlabs/Module/Admin/Site.php:328 -#: ../../Zotlabs/Module/Connedit.php:884 ../../Zotlabs/Module/Connedit.php:885 -msgid "" -"words one per line or #tags or /patterns/ or lang=xx, leave blank to import " -"all posts" +#: ../../include/features.php:343 +msgid "Forum Filter" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:328 -msgid "Do not import Public stream posts with this text" +#: ../../include/features.php:344 +msgid "Ability to display only posts of a specific forum" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:331 -msgid "Login on Homepage" +#: ../../include/features.php:351 +msgid "Personal Posts Filter" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:331 -msgid "" -"Present a login box to visitors on the home page if no other content has " -"been configured." +#: ../../include/features.php:352 +msgid "Ability to display only posts that you've interacted on" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:332 -msgid "Enable context help" +#: ../../include/features.php:373 +msgid "Photo Location" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:332 -msgid "" -"Display contextual help for the current page when the help button is pressed." +#: ../../include/features.php:374 +msgid "If location data is available on uploaded photos, link this to a map." msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:334 -msgid "Reply-to email address for system generated email." +#: ../../include/features.php:387 +msgid "Advanced Profiles" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:335 -msgid "Sender (From) email address for system generated email." +#: ../../include/features.php:388 +msgid "Additional profile sections and selections" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:336 -msgid "Name of email sender for system generated email." +#: ../../include/features.php:395 +msgid "Profile Import/Export" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:338 -msgid "Directory Server URL" +#: ../../include/features.php:396 +msgid "Save and load profile details across sites/channels" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:338 -msgid "Default directory server" +#: ../../include/features.php:403 +msgid "Multiple Profiles" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:340 -msgid "Enable SSE Notifications" +#: ../../include/features.php:404 +msgid "Ability to create multiple profiles" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:340 -msgid "" -"If disabled, traditional polling will be used. Warning: this setting might " -"not be suited for shared hosting" +#: ../../include/auth.php:194 +msgid "Delegation session ended." msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:342 -msgid "Proxy user" +#: ../../include/auth.php:198 +msgid "Logged out." msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:343 -msgid "Proxy URL" +#: ../../include/auth.php:294 +msgid "Email validation is incomplete. Please check your email." msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:344 -msgid "Network timeout" +#: ../../include/auth.php:310 +msgid "Failed authentication" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:344 -msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." +#: ../../include/auth.php:320 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:188 +msgid "Login failed." msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:345 -msgid "Delivery interval" +#: ../../include/text.php:522 +msgid "prev" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:345 -msgid "" -"Delay background delivery processes by this many seconds to reduce system " -"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 " -"for large dedicated servers." +#: ../../include/text.php:524 +msgid "first" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:346 -msgid "Deliveries per process" +#: ../../include/text.php:553 +msgid "last" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:346 -msgid "" -"Number of deliveries to attempt in a single operating system process. Adjust " -"if necessary to tune system performance. Recommend: 1-5." +#: ../../include/text.php:556 +msgid "next" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:347 -msgid "Queue Threshold" +#: ../../include/text.php:574 +msgid "older" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:347 -msgid "" -"Always defer immediate delivery if queue contains more than this number of " -"entries." +#: ../../include/text.php:576 +msgid "newer" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:348 -msgid "Poll interval" +#: ../../include/text.php:1024 +msgid "No connections" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:348 -msgid "" -"Delay background polling processes by this many seconds to reduce system " -"load. If 0, use delivery interval." +#: ../../include/text.php:1076 +#, php-format +msgid "View all %s connections" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:349 -msgid "Path to ImageMagick convert program" +#: ../../include/text.php:1139 +#, php-format +msgid "Network: %s" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:349 -msgid "" -"If set, use this program to generate photo thumbnails for huge images ( > " -"4000 pixels in either dimension), otherwise memory exhaustion may occur. " -"Example: /usr/bin/convert" +#: ../../include/text.php:1242 ../../include/text.php:1246 +msgid "poke" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:350 -msgid "Maximum Load Average" +#: ../../include/text.php:1247 +msgid "ping" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:350 -msgid "" -"Maximum system load before delivery and poll processes are deferred - " -"default 50." +#: ../../include/text.php:1247 +msgid "pinged" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:351 -msgid "Expiration period in days for imported (grid/network) content" +#: ../../include/text.php:1248 +msgid "prod" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:351 -msgid "0 for no expiration of imported content" +#: ../../include/text.php:1248 +msgid "prodded" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:352 -msgid "" -"Do not expire any posts which have comments less than this many days ago" +#: ../../include/text.php:1249 +msgid "slap" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:354 -msgid "" -"Public servers: Optional landing (marketing) webpage for new registrants" +#: ../../include/text.php:1249 +msgid "slapped" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:354 -#, php-format -msgid "Create this page first. Default is %s/register" +#: ../../include/text.php:1250 +msgid "finger" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:355 -msgid "Page to display after creating a new channel" +#: ../../include/text.php:1250 +msgid "fingered" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:355 -msgid "Default: profiles" +#: ../../include/text.php:1251 +msgid "rebuff" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:357 -msgid "Optional: site location" +#: ../../include/text.php:1251 +msgid "rebuffed" msgstr "" -#: ../../Zotlabs/Module/Admin/Site.php:357 -msgid "Region or country" +#: ../../include/text.php:1274 +msgid "happy" msgstr "" -#: ../../Zotlabs/Module/Admin/Logs.php:28 -msgid "Log settings updated." +#: ../../include/text.php:1275 +msgid "sad" msgstr "" -#: ../../Zotlabs/Module/Admin/Logs.php:85 -msgid "Clear" +#: ../../include/text.php:1276 +msgid "mellow" msgstr "" -#: ../../Zotlabs/Module/Admin/Logs.php:91 -msgid "Debugging" +#: ../../include/text.php:1277 +msgid "tired" msgstr "" -#: ../../Zotlabs/Module/Admin/Logs.php:92 -msgid "Log file" +#: ../../include/text.php:1278 +msgid "perky" msgstr "" -#: ../../Zotlabs/Module/Admin/Logs.php:92 -msgid "" -"Must be writable by web server. Relative to your top-level webserver " -"directory." +#: ../../include/text.php:1279 +msgid "angry" msgstr "" -#: ../../Zotlabs/Module/Admin/Logs.php:93 -msgid "Log level" +#: ../../include/text.php:1280 +msgid "stupefied" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:31 -#, php-format -msgid "%s channel censored/uncensored" -msgid_plural "%s channels censored/uncensored" -msgstr[0] "" -msgstr[1] "" +#: ../../include/text.php:1281 +msgid "puzzled" +msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:40 -#, php-format -msgid "%s channel code allowed/disallowed" -msgid_plural "%s channels code allowed/disallowed" -msgstr[0] "" -msgstr[1] "" +#: ../../include/text.php:1282 +msgid "interested" +msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:46 -#, php-format -msgid "%s channel deleted" -msgid_plural "%s channels deleted" -msgstr[0] "" -msgstr[1] "" +#: ../../include/text.php:1283 +msgid "bitter" +msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:65 -msgid "Channel not found" +#: ../../include/text.php:1284 +msgid "cheerful" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:75 -#, php-format -msgid "Channel '%s' deleted" +#: ../../include/text.php:1285 +msgid "alive" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:87 -#, php-format -msgid "Channel '%s' censored" +#: ../../include/text.php:1286 +msgid "annoyed" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:87 -#, php-format -msgid "Channel '%s' uncensored" +#: ../../include/text.php:1287 +msgid "anxious" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:98 -#, php-format -msgid "Channel '%s' code allowed" +#: ../../include/text.php:1288 +msgid "cranky" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:98 -#, php-format -msgid "Channel '%s' code disallowed" +#: ../../include/text.php:1289 +msgid "disturbed" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:150 -#: ../../Zotlabs/Module/Directory.php:360 -msgid "Censor" +#: ../../include/text.php:1290 +msgid "frustrated" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:151 -#: ../../Zotlabs/Module/Directory.php:360 -msgid "Uncensor" +#: ../../include/text.php:1291 +msgid "depressed" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:152 -msgid "Allow Code" +#: ../../include/text.php:1292 +msgid "motivated" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:153 -msgid "Disallow Code" +#: ../../include/text.php:1293 +msgid "relaxed" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:158 -msgid "UID" +#: ../../include/text.php:1294 +msgid "surprised" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:162 -msgid "" -"Selected channels will be deleted!\\n\\nEverything that was posted in these " -"channels on this site will be permanently deleted!\\n\\nAre you sure?" +#: ../../include/text.php:1482 ../../include/js_strings.php:99 +msgid "Monday" msgstr "" -#: ../../Zotlabs/Module/Admin/Channels.php:163 -msgid "" -"The channel {0} will be deleted!\\n\\nEverything that was posted in this " -"channel on this site will be permanently deleted!\\n\\nAre you sure?" +#: ../../include/text.php:1482 ../../include/js_strings.php:100 +msgid "Tuesday" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:29 -#, php-format -msgid "Password changed for account %d." +#: ../../include/text.php:1482 ../../include/js_strings.php:101 +msgid "Wednesday" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:46 -msgid "Account settings updated." +#: ../../include/text.php:1482 ../../include/js_strings.php:102 +msgid "Thursday" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:61 -msgid "Account not found." +#: ../../include/text.php:1482 ../../include/js_strings.php:103 +msgid "Friday" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:68 -msgid "Account Edit" +#: ../../include/text.php:1482 ../../include/js_strings.php:104 +msgid "Saturday" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:69 -msgid "New Password" +#: ../../include/text.php:1482 ../../include/js_strings.php:98 +msgid "Sunday" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:70 -msgid "New Password again" +#: ../../include/text.php:1486 ../../include/js_strings.php:74 +msgid "January" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:71 -msgid "Account language (for emails)" +#: ../../include/text.php:1486 ../../include/js_strings.php:75 +msgid "February" msgstr "" -#: ../../Zotlabs/Module/Admin/Account_edit.php:72 -msgid "Service class" +#: ../../include/text.php:1486 ../../include/js_strings.php:76 +msgid "March" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:89 -msgid "New Profile Field" +#: ../../include/text.php:1486 ../../include/js_strings.php:77 +msgid "April" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:90 -#: ../../Zotlabs/Module/Admin/Profs.php:110 -msgid "Field nickname" +#: ../../include/text.php:1486 +msgid "May" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:90 -#: ../../Zotlabs/Module/Admin/Profs.php:110 -msgid "System name of field" +#: ../../include/text.php:1486 ../../include/js_strings.php:79 +msgid "June" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:91 -#: ../../Zotlabs/Module/Admin/Profs.php:111 -msgid "Input type" +#: ../../include/text.php:1486 ../../include/js_strings.php:80 +msgid "July" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:92 -#: ../../Zotlabs/Module/Admin/Profs.php:112 -msgid "Field Name" +#: ../../include/text.php:1486 ../../include/js_strings.php:81 +msgid "August" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:92 -#: ../../Zotlabs/Module/Admin/Profs.php:112 -msgid "Label on profile pages" +#: ../../include/text.php:1486 ../../include/js_strings.php:82 +msgid "September" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:93 -#: ../../Zotlabs/Module/Admin/Profs.php:113 -msgid "Help text" +#: ../../include/text.php:1486 ../../include/js_strings.php:83 +msgid "October" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:93 -#: ../../Zotlabs/Module/Admin/Profs.php:113 -msgid "Additional info (optional)" +#: ../../include/text.php:1486 ../../include/js_strings.php:84 +msgid "November" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:103 -msgid "Field definition not found" +#: ../../include/text.php:1486 ../../include/js_strings.php:85 +msgid "December" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:109 -msgid "Edit Profile Field" +#: ../../include/text.php:1560 +msgid "Unknown Attachment" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:169 -msgid "Basic Profile Fields" +#: ../../include/text.php:1562 ../../include/feedutils.php:873 +msgid "unknown" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:170 -msgid "Advanced Profile Fields" +#: ../../include/text.php:1598 +msgid "remove category" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:170 -msgid "(In addition to basic fields)" +#: ../../include/text.php:1674 +msgid "remove from file" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:172 -msgid "All available fields" +#: ../../include/text.php:1843 ../../include/message.php:13 +msgid "Download binary/encrypted content" msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:173 -msgid "Custom Fields" +#: ../../include/text.php:1914 +msgid "Poll has ended." msgstr "" -#: ../../Zotlabs/Module/Admin/Profs.php:177 -msgid "Create Custom Field" +#: ../../include/text.php:1917 +#, php-format +msgid "Poll ends: %s" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:19 -#: ../../Zotlabs/Module/Admin/Dbsync.php:59 -msgid "Update has been marked successful" +#: ../../include/text.php:2096 ../../include/language.php:424 +msgid "default" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:32 -#, php-format -msgid "Verification of update %s failed. Check system logs." +#: ../../include/text.php:2104 +msgid "Page layout" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:35 -#: ../../Zotlabs/Module/Admin/Dbsync.php:74 -#, php-format -msgid "Update %s was successfully applied." +#: ../../include/text.php:2104 +msgid "You can create your own with the layouts tool" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:39 -#, php-format -msgid "Verifying update %s did not return a status. Unknown if it succeeded." +#: ../../include/text.php:2115 +msgid "HTML" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:42 -#, php-format -msgid "Update %s does not contain a verification function." +#: ../../include/text.php:2118 +msgid "Comanche Layout" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:46 -#: ../../Zotlabs/Module/Admin/Dbsync.php:81 -#, php-format -msgid "Update function %s could not be found." +#: ../../include/text.php:2123 +msgid "PHP" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:71 -#, php-format -msgid "Executing update procedure %s failed. Check system logs." +#: ../../include/text.php:2132 +msgid "Page content type" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:78 -#, php-format -msgid "" -"Update %s did not return a status. It cannot be determined if it was " -"successful." +#: ../../include/text.php:2265 +msgid "activity" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:99 -msgid "Failed Updates" +#: ../../include/text.php:2268 +msgid "poll" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:101 -msgid "Mark success (if update was manually applied)" +#: ../../include/text.php:2369 +msgid "a-z, 0-9, -, and _ only" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:102 -msgid "Attempt to verify this update if a verification procedure exists" +#: ../../include/text.php:2695 +msgid "Design Tools" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:103 -msgid "Attempt to execute this update step automatically" +#: ../../include/text.php:2701 +msgid "Pages" msgstr "" -#: ../../Zotlabs/Module/Admin/Dbsync.php:108 -msgid "No failed updates." +#: ../../include/text.php:2713 +msgid "Import" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:290 -#, php-format -msgid "Plugin %s disabled." +#: ../../include/text.php:2714 +msgid "Import website..." msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:295 -#, php-format -msgid "Plugin %s enabled." +#: ../../include/text.php:2715 +msgid "Select folder to import" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:354 -msgid "Minimum project version: " +#: ../../include/text.php:2716 +msgid "Import from a zipped folder:" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:355 -msgid "Maximum project version: " +#: ../../include/text.php:2717 +msgid "Import from cloud files:" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:356 -msgid "Minimum PHP version: " +#: ../../include/text.php:2718 +msgid "/cloud/channel/path/to/folder" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:357 -msgid "Compatible Server Roles: " +#: ../../include/text.php:2719 +msgid "Enter path to website files" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:358 -msgid "Requires: " +#: ../../include/text.php:2720 +msgid "Select folder" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:359 -#: ../../Zotlabs/Module/Admin/Addons.php:446 -msgid "Disabled - version incompatibility" +#: ../../include/text.php:2721 +msgid "Export website..." msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:415 -msgid "Enter the public git repository URL of the addon repo." +#: ../../include/text.php:2722 +msgid "Export to a zip file" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:416 -msgid "Addon repo git URL" +#: ../../include/text.php:2723 +msgid "website.zip" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:417 -msgid "Custom repo name" +#: ../../include/text.php:2724 +msgid "Enter a name for the zip file." msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:417 -msgid "(optional)" +#: ../../include/text.php:2725 +msgid "Export to cloud files" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:418 -msgid "Download Addon Repo" +#: ../../include/text.php:2726 +msgid "/path/to/export/folder" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:425 -msgid "Install new repo" +#: ../../include/text.php:2727 +msgid "Enter a path to a cloud files destination." msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:426 ../../Zotlabs/Lib/Apps.php:536 -msgid "Install" +#: ../../include/text.php:2728 +msgid "Specify folder" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:449 -msgid "Manage Repos" +#: ../../include/message.php:41 +msgid "Unable to determine sender." msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:450 -msgid "Installed Addon Repositories" +#: ../../include/message.php:80 +msgid "No recipient provided." msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:451 -msgid "Install a New Addon Repository" +#: ../../include/message.php:85 +msgid "[no subject]" msgstr "" -#: ../../Zotlabs/Module/Admin/Addons.php:458 -msgid "Switch branch" +#: ../../include/message.php:214 +msgid "Stored post could not be verified." msgstr "" -#: ../../Zotlabs/Module/Apps.php:50 -msgid "Installed Apps" +#: ../../include/markdown.php:202 ../../include/bbcode.php:527 +#, php-format +msgid "%1$s wrote the following %2$s %3$s" msgstr "" -#: ../../Zotlabs/Module/Apps.php:53 -msgid "Manage Apps" +#: ../../include/markdown.php:251 ../../include/bbcode.php:612 +msgid "spoiler" msgstr "" -#: ../../Zotlabs/Module/Apps.php:54 -msgid "Create Custom App" +#: ../../include/acl_selectors.php:99 +msgid "Profile-Based Privacy Groups" msgstr "" -#: ../../Zotlabs/Module/Achievements.php:38 -msgid "Some blurb about what to do when you're new here" +#: ../../include/acl_selectors.php:118 +msgid "Private Forum" msgstr "" -#: ../../Zotlabs/Module/Removeme.php:35 -msgid "" -"Channel removals are not allowed within 48 hours of changing the account " -"password." +#: ../../include/acl_selectors.php:142 +msgid "Share with" msgstr "" -#: ../../Zotlabs/Module/Removeme.php:60 -msgid "Remove This Channel" +#: ../../include/acl_selectors.php:143 +msgid "Custom selection" msgstr "" -#: ../../Zotlabs/Module/Removeme.php:61 -#: ../../Zotlabs/Module/Removeaccount.php:58 -#: ../../Zotlabs/Module/Changeaddr.php:78 -msgid "WARNING: " +#: ../../include/acl_selectors.php:145 +msgid "" +"Select \"Allow\" to allow viewing. \"Don't allow\" lets you override and " +"limit the scope of \"Allow\"." msgstr "" -#: ../../Zotlabs/Module/Removeme.php:61 -msgid "This channel will be completely removed from the network. " +#: ../../include/acl_selectors.php:147 +msgid "Don't allow" msgstr "" -#: ../../Zotlabs/Module/Removeme.php:61 -#: ../../Zotlabs/Module/Removeaccount.php:58 -msgid "This action is permanent and can not be undone!" +#: ../../include/acl_selectors.php:180 +#, php-format +msgid "" +"Post permissions %s cannot be changed %s after a post is shared.
      These " +"permissions set who is allowed to view the post." msgstr "" -#: ../../Zotlabs/Module/Removeme.php:62 -#: ../../Zotlabs/Module/Removeaccount.php:59 -#: ../../Zotlabs/Module/Changeaddr.php:79 -msgid "Please enter your password for verification:" +#: ../../include/opengraph.php:56 +#, php-format +msgid "This is the home page of %s." msgstr "" -#: ../../Zotlabs/Module/Removeme.php:64 -#: ../../Zotlabs/Module/Settings/Channel.php:596 -msgid "Remove Channel" +#: ../../include/taxonomy.php:323 +msgid "Trending" msgstr "" -#: ../../Zotlabs/Module/Events.php:468 -msgid "Edit event title" +#: ../../include/taxonomy.php:559 +msgid "Keywords" msgstr "" -#: ../../Zotlabs/Module/Events.php:470 -msgid "Categories (comma-separated list)" +#: ../../include/taxonomy.php:580 +msgid "have" msgstr "" -#: ../../Zotlabs/Module/Events.php:471 -msgid "Edit Category" +#: ../../include/taxonomy.php:580 +msgid "has" msgstr "" -#: ../../Zotlabs/Module/Events.php:471 -msgid "Category" +#: ../../include/taxonomy.php:581 +msgid "want" msgstr "" -#: ../../Zotlabs/Module/Events.php:474 -msgid "Edit start date and time" +#: ../../include/taxonomy.php:581 +msgid "wants" msgstr "" -#: ../../Zotlabs/Module/Events.php:475 ../../Zotlabs/Module/Events.php:478 -msgid "Finish date and time are not known or not relevant" +#: ../../include/taxonomy.php:582 +msgid "likes" msgstr "" -#: ../../Zotlabs/Module/Events.php:477 -msgid "Edit finish date and time" +#: ../../include/taxonomy.php:583 +msgid "dislikes" msgstr "" -#: ../../Zotlabs/Module/Events.php:477 -msgid "Finish date and time" +#: ../../include/import.php:29 +msgid "Unable to import a removed channel." msgstr "" -#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Events.php:480 -msgid "Adjust for viewer timezone" +#: ../../include/import.php:55 +msgid "" +"Cannot create a duplicate channel identifier on this system. Import failed." msgstr "" -#: ../../Zotlabs/Module/Events.php:479 -msgid "" -"Important for events that happen in a particular place. Not practical for " -"global holidays." +#: ../../include/import.php:76 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:44 +msgid "Unable to create a unique channel address. Import failed." msgstr "" -#: ../../Zotlabs/Module/Events.php:481 -msgid "Edit Description" +#: ../../include/import.php:121 +msgid "Cloned channel not found. Import failed." msgstr "" -#: ../../Zotlabs/Module/Events.php:483 -msgid "Edit Location" +#: ../../include/nav.php:92 +msgid "Remote authentication" msgstr "" -#: ../../Zotlabs/Module/Events.php:502 -msgid "Advanced Options" +#: ../../include/nav.php:92 +msgid "Click to authenticate to your home hub" msgstr "" -#: ../../Zotlabs/Module/Events.php:613 -msgid "l, F j" +#: ../../include/nav.php:98 +msgid "Manage your channels" msgstr "" -#: ../../Zotlabs/Module/Events.php:696 -msgid "Edit Event" +#: ../../include/nav.php:101 +msgid "Manage your privacy groups" msgstr "" -#: ../../Zotlabs/Module/Events.php:696 -msgid "Create Event" +#: ../../include/nav.php:103 +msgid "Account/Channel Settings" msgstr "" -#: ../../Zotlabs/Module/Events.php:739 -msgid "Event removed" +#: ../../include/nav.php:109 ../../include/nav.php:138 +#: ../../include/nav.php:157 ../../boot.php:1704 +msgid "Logout" msgstr "" -#: ../../Zotlabs/Module/Manage.php:138 ../../Zotlabs/Module/New_channel.php:147 -#, php-format -msgid "You have created %1$.0f of %2$.0f allowed channels." +#: ../../include/nav.php:109 ../../include/nav.php:138 +msgid "End this session" msgstr "" -#: ../../Zotlabs/Module/Manage.php:145 -msgid "Create a new channel" +#: ../../include/nav.php:112 +msgid "Your profile page" msgstr "" -#: ../../Zotlabs/Module/Manage.php:171 -msgid "Current Channel" +#: ../../include/nav.php:115 +msgid "Manage/Edit profiles" msgstr "" -#: ../../Zotlabs/Module/Manage.php:173 -msgid "Switch to one of your channels by selecting it." +#: ../../include/nav.php:124 ../../include/nav.php:128 +msgid "Sign in" msgstr "" -#: ../../Zotlabs/Module/Manage.php:174 -msgid "Default Channel" +#: ../../include/nav.php:155 +msgid "Take me home" msgstr "" -#: ../../Zotlabs/Module/Manage.php:175 -msgid "Make Default" +#: ../../include/nav.php:157 +msgid "Log me out of this site" msgstr "" -#: ../../Zotlabs/Module/Manage.php:178 -#, php-format -msgid "%d new messages" +#: ../../include/nav.php:162 +msgid "Create an account" msgstr "" -#: ../../Zotlabs/Module/Manage.php:179 -#, php-format -msgid "%d new introductions" +#: ../../include/nav.php:174 +msgid "Help and documentation" msgstr "" -#: ../../Zotlabs/Module/Manage.php:181 -msgid "Delegated Channel" +#: ../../include/nav.php:188 +msgid "Search site @name, !forum, #tag, ?docs, content" msgstr "" -#: ../../Zotlabs/Module/Chanview.php:132 -msgid "toggle full screen mode" +#: ../../include/nav.php:194 +msgid "Site Setup and Configuration" msgstr "" -#: ../../Zotlabs/Module/Pubstream.php:20 -msgid "Public Stream App" +#: ../../include/nav.php:330 +msgid "@name, !forum, #tag, ?doc, content" msgstr "" -#: ../../Zotlabs/Module/Pubstream.php:21 -msgid "The unmoderated public stream of this hub" +#: ../../include/nav.php:331 +msgid "Please wait..." msgstr "" -#: ../../Zotlabs/Module/Chatsvc.php:131 -msgid "Away" +#: ../../include/nav.php:337 +msgid "Add Apps" msgstr "" -#: ../../Zotlabs/Module/Chatsvc.php:136 -msgid "Online" +#: ../../include/nav.php:338 +msgid "Arrange Apps" msgstr "" -#: ../../Zotlabs/Module/Permcats.php:29 -msgid "Permission category name is required." +#: ../../include/nav.php:339 +msgid "Toggle System Apps" msgstr "" -#: ../../Zotlabs/Module/Permcats.php:48 -msgid "Permission category saved." +#: ../../include/nav.php:424 +msgid "Status Messages and Posts" msgstr "" -#: ../../Zotlabs/Module/Permcats.php:63 -msgid "Permission Categories App" +#: ../../include/nav.php:437 +msgid "Profile Details" msgstr "" -#: ../../Zotlabs/Module/Permcats.php:64 -msgid "Create custom connection permission limits" +#: ../../include/nav.php:447 ../../include/photos.php:666 +msgid "Photo Albums" msgstr "" -#: ../../Zotlabs/Module/Permcats.php:80 -msgid "" -"Use this form to create permission rules for various classes of people or " -"connections." +#: ../../include/nav.php:455 +msgid "Files and Storage" msgstr "" -#: ../../Zotlabs/Module/Permcats.php:113 ../../Zotlabs/Lib/Apps.php:374 -msgid "Permission Categories" +#: ../../include/nav.php:493 +msgid "Saved Bookmarks" msgstr "" -#: ../../Zotlabs/Module/Permcats.php:121 -msgid "Permission category name" +#: ../../include/nav.php:504 +msgid "View Cards" msgstr "" -#: ../../Zotlabs/Module/Email_resend.php:12 -#: ../../Zotlabs/Module/Email_validation.php:24 -msgid "Token verification failed." +#: ../../include/nav.php:515 +msgid "View Articles" msgstr "" -#: ../../Zotlabs/Module/Email_resend.php:30 -msgid "Email verification resent" +#: ../../include/nav.php:527 +msgid "View Webpages" msgstr "" -#: ../../Zotlabs/Module/Email_resend.php:33 -msgid "Unable to resend email verification message." +#: ../../include/language.php:437 +msgid "Select an alternate language" msgstr "" -#: ../../Zotlabs/Module/Ratings.php:70 -msgid "No ratings" +#: ../../include/zid.php:360 +#, php-format +msgid "OpenWebAuth: %1$s welcomes %2$s" msgstr "" -#: ../../Zotlabs/Module/Ratings.php:98 -msgid "Rating: " +#: ../../include/bookmarks.php:34 +#, php-format +msgid "%1$s's bookmarks" msgstr "" -#: ../../Zotlabs/Module/Ratings.php:99 -msgid "Website: " +#: ../../include/activities.php:42 +msgid " and " msgstr "" -#: ../../Zotlabs/Module/Ratings.php:101 -msgid "Description: " +#: ../../include/activities.php:50 +msgid "public profile" msgstr "" -#: ../../Zotlabs/Module/Cal.php:64 -msgid "Permissions denied." +#: ../../include/activities.php:59 +#, php-format +msgid "%1$s changed %2$s to “%3$s”" msgstr "" -#: ../../Zotlabs/Module/Viewsrc.php:43 -msgid "item" +#: ../../include/activities.php:60 +#, php-format +msgid "Visit %1$s's %2$s" msgstr "" -#: ../../Zotlabs/Module/Apporder.php:47 -msgid "Change Order of Pinned Navbar Apps" +#: ../../include/activities.php:63 +#, php-format +msgid "%1$s has an updated %2$s, changing %3$s." msgstr "" -#: ../../Zotlabs/Module/Apporder.php:47 -msgid "Change Order of App Tray Apps" +#: ../../include/cdav.php:157 +msgid "INVALID EVENT DISMISSED!" msgstr "" -#: ../../Zotlabs/Module/Apporder.php:48 -msgid "" -"Use arrows to move the corresponding app left (top) or right (bottom) in the " -"navbar" +#: ../../include/cdav.php:158 +msgid "Summary: " msgstr "" -#: ../../Zotlabs/Module/Apporder.php:48 -msgid "Use arrows to move the corresponding app up or down in the app tray" +#: ../../include/cdav.php:159 +msgid "Date: " msgstr "" -#: ../../Zotlabs/Module/Oexchange.php:27 -msgid "Unable to find your hub." +#: ../../include/cdav.php:160 ../../include/cdav.php:168 +msgid "Reason: " msgstr "" -#: ../../Zotlabs/Module/Oexchange.php:41 -msgid "Post successful." +#: ../../include/cdav.php:166 +msgid "INVALID CARD DISMISSED!" msgstr "" -#: ../../Zotlabs/Module/Moderate.php:67 -msgid "Comment approved" +#: ../../include/cdav.php:167 +msgid "Name: " msgstr "" -#: ../../Zotlabs/Module/Moderate.php:71 -msgid "Comment deleted" +#: ../../include/photos.php:151 +#, php-format +msgid "Image exceeds website size limit of %lu bytes" msgstr "" -#: ../../Zotlabs/Module/Removeaccount.php:35 -msgid "" -"Account removals are not allowed within 48 hours of changing the account " -"password." +#: ../../include/photos.php:162 +msgid "Image file is empty." msgstr "" -#: ../../Zotlabs/Module/Removeaccount.php:57 -msgid "Remove This Account" +#: ../../include/photos.php:324 +msgid "Photo storage failed." msgstr "" -#: ../../Zotlabs/Module/Removeaccount.php:58 -msgid "" -"This account and all its channels will be completely removed from the " -"network. " +#: ../../include/photos.php:373 +msgid "a new photo" msgstr "" -#: ../../Zotlabs/Module/Removeaccount.php:61 -#: ../../Zotlabs/Module/Settings/Account.php:105 -msgid "Remove Account" +#: ../../include/photos.php:377 +#, php-format +msgctxt "photo_upload" +msgid "%1$s posted %2$s to %3$s" msgstr "" -#: ../../Zotlabs/Module/Lang.php:17 -msgid "Language App" +#: ../../include/photos.php:671 +msgid "Upload New Photos" msgstr "" -#: ../../Zotlabs/Module/Lang.php:18 -msgid "Change UI language" +#: ../../include/js_strings.php:5 +msgid "Delete this item?" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:61 -msgid "Channel Export App" +#: ../../include/js_strings.php:8 +#, php-format +msgid "%s show less" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:62 -msgid "Export your channel" +#: ../../include/js_strings.php:9 +#, php-format +msgid "%s expand" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:72 ../../Zotlabs/Module/Uexport.php:73 -msgid "Export Channel" +#: ../../include/js_strings.php:10 +#, php-format +msgid "%s collapse" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:74 -msgid "" -"Export your basic channel information to a file. This acts as a backup of " -"your connections, permissions, profile and basic data, which can be used to " -"import your data to a new server hub, but does not contain your content." +#: ../../include/js_strings.php:11 +msgid "Password too short" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:75 -msgid "Export Content" +#: ../../include/js_strings.php:12 +msgid "Passwords do not match" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:76 -msgid "" -"Export your channel information and recent content to a JSON backup that can " -"be restored or imported to another server hub. This backs up all of your " -"connections, permissions, profile data and several months of posts. This " -"file may be VERY large. Please be patient - it may take several minutes for " -"this download to begin." +#: ../../include/js_strings.php:13 +msgid "everybody" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:78 -msgid "Export your posts from a given year." +#: ../../include/js_strings.php:14 +msgid "Secret Passphrase" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:80 -msgid "" -"You may also export your posts and conversations for a particular year or " -"month. Adjust the date in your browser location bar to select other dates. " -"If the export fails (possibly due to memory exhaustion on your server hub), " -"please try again selecting a more limited date range." +#: ../../include/js_strings.php:15 +msgid "Passphrase hint" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:81 -#, php-format -msgid "" -"To select all posts for a given year, such as this year, visit %2$s" +#: ../../include/js_strings.php:16 +msgid "Notice: Permissions have changed but have not yet been submitted." msgstr "" -#: ../../Zotlabs/Module/Uexport.php:82 -#, php-format -msgid "" -"To select all posts for a given month, such as January of this year, visit " -"%2$s" +#: ../../include/js_strings.php:17 +msgid "close all" msgstr "" -#: ../../Zotlabs/Module/Uexport.php:83 -#, php-format -msgid "" -"These content files may be imported or restored by visiting " -"%2$s on any site containing your channel. For best results please import " -"or restore these in date order (oldest first)." +#: ../../include/js_strings.php:18 +msgid "Nothing new here" msgstr "" -#: ../../Zotlabs/Module/Display.php:377 -msgid "Article" +#: ../../include/js_strings.php:19 +msgid "Rate This Channel (this is public)" msgstr "" -#: ../../Zotlabs/Module/Display.php:422 -msgid "Item has been removed." +#: ../../include/js_strings.php:21 +msgid "Describe (optional)" msgstr "" -#: ../../Zotlabs/Module/Common.php:14 -msgid "No channel." +#: ../../include/js_strings.php:23 +msgid "Please enter a link URL" msgstr "" -#: ../../Zotlabs/Module/Common.php:45 -msgid "No connections in common." +#: ../../include/js_strings.php:24 +msgid "Unsaved changes. Are you sure you wish to leave this page?" msgstr "" -#: ../../Zotlabs/Module/Common.php:65 -msgid "View Common Connections" +#: ../../include/js_strings.php:26 +msgid "lovely" msgstr "" -#: ../../Zotlabs/Module/Impel.php:185 -#, php-format -msgid "%s element installed" +#: ../../include/js_strings.php:27 +msgid "wonderful" msgstr "" -#: ../../Zotlabs/Module/Impel.php:188 -#, php-format -msgid "%s element installation failed" +#: ../../include/js_strings.php:28 +msgid "fantastic" msgstr "" -#: ../../Zotlabs/Module/New_channel.php:159 -msgid "Your real name is recommended." +#: ../../include/js_strings.php:29 +msgid "great" msgstr "" -#: ../../Zotlabs/Module/New_channel.php:160 +#: ../../include/js_strings.php:30 msgid "" -"Examples: \"Bob Jameson\", \"Lisa and her Horses\", \"Soccer\", \"Aviation " -"Group\"" +"Your chosen nickname was either already taken or not valid. Please use our " +"suggestion (" msgstr "" -#: ../../Zotlabs/Module/New_channel.php:165 -msgid "" -"This will be used to create a unique network address (like an email address)." +#: ../../include/js_strings.php:31 +msgid ") or enter a new one." msgstr "" -#: ../../Zotlabs/Module/New_channel.php:167 -msgid "Allowed characters are a-z 0-9, - and _" +#: ../../include/js_strings.php:32 +msgid "Thank you, this nickname is valid." msgstr "" -#: ../../Zotlabs/Module/New_channel.php:175 -msgid "Channel name" +#: ../../include/js_strings.php:33 +msgid "A channel name is required." msgstr "" -#: ../../Zotlabs/Module/New_channel.php:178 -msgid "" -"Select a channel permission role compatible with your usage needs and " -"privacy requirements." +#: ../../include/js_strings.php:34 +msgid "This is a " msgstr "" -#: ../../Zotlabs/Module/New_channel.php:181 -msgid "Create a Channel" +#: ../../include/js_strings.php:35 +msgid " channel name" msgstr "" -#: ../../Zotlabs/Module/New_channel.php:182 -msgid "" -"A channel is a unique network identity. It can represent a person (social " -"network profile), a forum (group), a business or celebrity page, a newsfeed, " -"and many other things." +#: ../../include/js_strings.php:36 +msgid "Back to reply" msgstr "" -#: ../../Zotlabs/Module/New_channel.php:183 -msgid "" -"or import an existing channel from another location." +#: ../../include/js_strings.php:37 +msgid "Pinned" msgstr "" -#: ../../Zotlabs/Module/New_channel.php:188 -msgid "Validate" -msgstr "" +#: ../../include/js_strings.php:45 +#, php-format +msgid "%d minutes" +msgid_plural "%d minutes" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Ping.php:337 ../../Zotlabs/Lib/Enotify.php:948 -msgid "sent you a private message" -msgstr "" +#: ../../include/js_strings.php:46 +#, php-format +msgid "about %d hours" +msgid_plural "about %d hours" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Ping.php:393 ../../Zotlabs/Lib/Enotify.php:914 -msgid "added your channel" +#: ../../include/js_strings.php:47 +#, php-format +msgid "%d days" +msgid_plural "%d days" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:48 +#, php-format +msgid "%d months" +msgid_plural "%d months" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:49 +#, php-format +msgid "%d years" +msgid_plural "%d years" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:54 +msgid "timeago.prefixAgo" msgstr "" -#: ../../Zotlabs/Module/Ping.php:418 ../../Zotlabs/Lib/Enotify.php:986 -msgid "requires approval" +#: ../../include/js_strings.php:55 +msgid "timeago.prefixFromNow" msgstr "" -#: ../../Zotlabs/Module/Ping.php:428 ../../Zotlabs/Lib/Enotify.php:957 -msgid "g A l F d" +#: ../../include/js_strings.php:56 +msgid "timeago.suffixAgo" msgstr "" -#: ../../Zotlabs/Module/Ping.php:446 ../../Zotlabs/Lib/Enotify.php:960 -msgid "[today]" +#: ../../include/js_strings.php:57 +msgid "timeago.suffixFromNow" msgstr "" -#: ../../Zotlabs/Module/Ping.php:456 -msgid "posted an event" +#: ../../include/js_strings.php:60 +msgid "less than a minute" msgstr "" -#: ../../Zotlabs/Module/Ping.php:490 ../../Zotlabs/Lib/Enotify.php:829 -#: ../../Zotlabs/Lib/Enotify.php:931 -msgid "shared a file with you" +#: ../../include/js_strings.php:61 +msgid "about a minute" msgstr "" -#: ../../Zotlabs/Module/Ping.php:672 ../../Zotlabs/Module/Sse_bs.php:540 -msgid "Private forum" +#: ../../include/js_strings.php:63 +msgid "about an hour" msgstr "" -#: ../../Zotlabs/Module/Ping.php:672 ../../Zotlabs/Module/Sse_bs.php:540 -msgid "Public forum" +#: ../../include/js_strings.php:65 +msgid "a day" msgstr "" -#: ../../Zotlabs/Module/Dircensor.php:42 -msgid "Entry censored" +#: ../../include/js_strings.php:67 +msgid "about a month" msgstr "" -#: ../../Zotlabs/Module/Dircensor.php:45 -msgid "Entry uncensored" +#: ../../include/js_strings.php:69 +msgid "about a year" msgstr "" -#: ../../Zotlabs/Module/Service_limits.php:23 -msgid "No service class restrictions found." +#: ../../include/js_strings.php:71 +msgid " " msgstr "" -#: ../../Zotlabs/Module/Mood.php:134 -msgid "Mood App" +#: ../../include/js_strings.php:72 +msgid "timeago.numbers" msgstr "" -#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Module/Mood.php:155 -msgid "Set your current mood and tell your friends" +#: ../../include/js_strings.php:78 +msgctxt "long" +msgid "May" msgstr "" -#: ../../Zotlabs/Module/Mood.php:154 ../../Zotlabs/Lib/Apps.php:350 -msgid "Mood" +#: ../../include/js_strings.php:86 +msgid "Jan" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:21 -msgid "About this site" +#: ../../include/js_strings.php:87 +msgid "Feb" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:22 -msgid "Site Name" +#: ../../include/js_strings.php:88 +msgid "Mar" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:26 -msgid "Administrator" +#: ../../include/js_strings.php:89 +msgid "Apr" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:29 -msgid "Software and Project information" +#: ../../include/js_strings.php:90 +msgctxt "short" +msgid "May" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:30 -msgid "This site is powered by $Projectname" +#: ../../include/js_strings.php:91 +msgid "Jun" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:31 -msgid "" -"Federated and decentralised networking and identity services provided by Zot" +#: ../../include/js_strings.php:92 +msgid "Jul" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:34 -msgid "Additional federated transport protocols:" +#: ../../include/js_strings.php:93 +msgid "Aug" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:36 -#, php-format -msgid "Version %s" +#: ../../include/js_strings.php:94 +msgid "Sep" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:37 -msgid "Project homepage" +#: ../../include/js_strings.php:95 +msgid "Oct" msgstr "" -#: ../../Zotlabs/Module/Siteinfo.php:38 -msgid "Developer homepage" +#: ../../include/js_strings.php:96 +msgid "Nov" msgstr "" -#: ../../Zotlabs/Module/Appman.php:39 ../../Zotlabs/Module/Appman.php:56 -msgid "App installed." +#: ../../include/js_strings.php:97 +msgid "Dec" msgstr "" -#: ../../Zotlabs/Module/Appman.php:49 -msgid "Malformed app." +#: ../../include/js_strings.php:105 +msgid "Sun" msgstr "" -#: ../../Zotlabs/Module/Appman.php:132 -msgid "Embed code" +#: ../../include/js_strings.php:106 +msgid "Mon" msgstr "" -#: ../../Zotlabs/Module/Appman.php:138 -msgid "Edit App" +#: ../../include/js_strings.php:107 +msgid "Tue" msgstr "" -#: ../../Zotlabs/Module/Appman.php:138 -msgid "Create App" +#: ../../include/js_strings.php:108 +msgid "Wed" msgstr "" -#: ../../Zotlabs/Module/Appman.php:143 -msgid "Name of app" +#: ../../include/js_strings.php:109 +msgid "Thu" msgstr "" -#: ../../Zotlabs/Module/Appman.php:144 -msgid "Location (URL) of app" +#: ../../include/js_strings.php:110 +msgid "Fri" msgstr "" -#: ../../Zotlabs/Module/Appman.php:146 -msgid "Photo icon URL" +#: ../../include/js_strings.php:111 +msgid "Sat" msgstr "" -#: ../../Zotlabs/Module/Appman.php:146 -msgid "80 x 80 pixels - optional" +#: ../../include/js_strings.php:112 +msgctxt "calendar" +msgid "today" msgstr "" -#: ../../Zotlabs/Module/Appman.php:147 -msgid "Categories (optional, comma separated list)" +#: ../../include/js_strings.php:113 +msgctxt "calendar" +msgid "month" msgstr "" -#: ../../Zotlabs/Module/Appman.php:148 -msgid "Version ID" +#: ../../include/js_strings.php:114 +msgctxt "calendar" +msgid "week" msgstr "" -#: ../../Zotlabs/Module/Appman.php:149 -msgid "Price of app" +#: ../../include/js_strings.php:115 +msgctxt "calendar" +msgid "day" msgstr "" -#: ../../Zotlabs/Module/Appman.php:150 -msgid "Location (URL) to purchase app" +#: ../../include/js_strings.php:116 +msgctxt "calendar" +msgid "All day" msgstr "" -#: ../../Zotlabs/Module/Admin.php:97 -msgid "Blocked accounts" +#: ../../include/js_strings.php:119 +msgid "Please stand by while your download is being prepared." msgstr "" -#: ../../Zotlabs/Module/Admin.php:98 -msgid "Expired accounts" +#: ../../include/security.php:609 +msgid "" +"The form security token was not correct. This probably happened because the " +"form has been opened for too long (>3 hours) before submitting it." msgstr "" -#: ../../Zotlabs/Module/Admin.php:99 -msgid "Expiring accounts" +#: ../../include/selectors.php:18 +msgid "Profile to assign new connections" msgstr "" -#: ../../Zotlabs/Module/Admin.php:120 -msgid "Message queues" +#: ../../include/selectors.php:41 +msgid "Frequently" msgstr "" -#: ../../Zotlabs/Module/Admin.php:134 -msgid "Your software should be updated" +#: ../../include/selectors.php:42 +msgid "Hourly" msgstr "" -#: ../../Zotlabs/Module/Admin.php:139 -msgid "Summary" +#: ../../include/selectors.php:43 +msgid "Twice daily" msgstr "" -#: ../../Zotlabs/Module/Admin.php:142 -msgid "Registered accounts" +#: ../../include/selectors.php:44 +msgid "Daily" msgstr "" -#: ../../Zotlabs/Module/Admin.php:143 -msgid "Pending registrations" +#: ../../include/selectors.php:45 +msgid "Weekly" msgstr "" -#: ../../Zotlabs/Module/Admin.php:144 -msgid "Registered channels" +#: ../../include/selectors.php:46 +msgid "Monthly" msgstr "" -#: ../../Zotlabs/Module/Admin.php:145 -msgid "Active addons" +#: ../../include/selectors.php:60 +msgid "Currently Male" msgstr "" -#: ../../Zotlabs/Module/Admin.php:146 -msgid "Version" +#: ../../include/selectors.php:60 +msgid "Currently Female" msgstr "" -#: ../../Zotlabs/Module/Admin.php:147 -msgid "Repository version (master)" +#: ../../include/selectors.php:60 +msgid "Mostly Male" msgstr "" -#: ../../Zotlabs/Module/Admin.php:148 -msgid "Repository version (dev)" +#: ../../include/selectors.php:60 +msgid "Mostly Female" msgstr "" -#: ../../Zotlabs/Module/Cards.php:51 -msgid "Cards App" +#: ../../include/selectors.php:60 +msgid "Transgender" msgstr "" -#: ../../Zotlabs/Module/Cards.php:52 -msgid "Create personal planning cards" +#: ../../include/selectors.php:60 +msgid "Intersex" msgstr "" -#: ../../Zotlabs/Module/Cards.php:112 -msgid "Add Card" +#: ../../include/selectors.php:60 +msgid "Transsexual" msgstr "" -#: ../../Zotlabs/Module/Directory.php:120 -msgid "No default suggestions were found." +#: ../../include/selectors.php:60 +msgid "Hermaphrodite" msgstr "" -#: ../../Zotlabs/Module/Directory.php:280 -#, php-format -msgid "%d rating" -msgid_plural "%d ratings" -msgstr[0] "" -msgstr[1] "" - -#: ../../Zotlabs/Module/Directory.php:291 -msgid "Gender: " +#: ../../include/selectors.php:60 +msgid "Undecided" msgstr "" -#: ../../Zotlabs/Module/Directory.php:293 -msgid "Status: " +#: ../../include/selectors.php:96 ../../include/selectors.php:115 +msgid "Males" msgstr "" -#: ../../Zotlabs/Module/Directory.php:295 -msgid "Homepage: " +#: ../../include/selectors.php:96 ../../include/selectors.php:115 +msgid "Females" msgstr "" -#: ../../Zotlabs/Module/Directory.php:358 -msgid "Description:" +#: ../../include/selectors.php:96 +msgid "Gay" msgstr "" -#: ../../Zotlabs/Module/Directory.php:369 -msgid "Public Forum:" +#: ../../include/selectors.php:96 +msgid "Lesbian" msgstr "" -#: ../../Zotlabs/Module/Directory.php:372 -msgid "Keywords: " +#: ../../include/selectors.php:96 +msgid "No Preference" msgstr "" -#: ../../Zotlabs/Module/Directory.php:375 -msgid "Don't suggest" +#: ../../include/selectors.php:96 +msgid "Bisexual" msgstr "" -#: ../../Zotlabs/Module/Directory.php:377 -msgid "Common connections (estimated):" +#: ../../include/selectors.php:96 +msgid "Autosexual" msgstr "" -#: ../../Zotlabs/Module/Directory.php:426 -msgid "Global Directory" +#: ../../include/selectors.php:96 +msgid "Abstinent" msgstr "" -#: ../../Zotlabs/Module/Directory.php:426 -msgid "Local Directory" +#: ../../include/selectors.php:96 +msgid "Virgin" msgstr "" -#: ../../Zotlabs/Module/Directory.php:432 -msgid "Finding:" +#: ../../include/selectors.php:96 +msgid "Deviant" msgstr "" -#: ../../Zotlabs/Module/Directory.php:437 -msgid "next page" +#: ../../include/selectors.php:96 +msgid "Fetish" msgstr "" -#: ../../Zotlabs/Module/Directory.php:437 -msgid "previous page" +#: ../../include/selectors.php:96 +msgid "Oodles" msgstr "" -#: ../../Zotlabs/Module/Directory.php:438 -msgid "Sort options" +#: ../../include/selectors.php:96 +msgid "Nonsexual" msgstr "" -#: ../../Zotlabs/Module/Directory.php:439 -msgid "Alphabetic" +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Single" msgstr "" -#: ../../Zotlabs/Module/Directory.php:440 -msgid "Reverse Alphabetic" +#: ../../include/selectors.php:134 +msgid "Lonely" msgstr "" -#: ../../Zotlabs/Module/Directory.php:441 -msgid "Newest to Oldest" +#: ../../include/selectors.php:134 +msgid "Available" msgstr "" -#: ../../Zotlabs/Module/Directory.php:442 -msgid "Oldest to Newest" +#: ../../include/selectors.php:134 +msgid "Unavailable" msgstr "" -#: ../../Zotlabs/Module/Directory.php:459 -msgid "No entries (some entries may be hidden)." +#: ../../include/selectors.php:134 +msgid "Has crush" msgstr "" -#: ../../Zotlabs/Module/Api.php:74 ../../Zotlabs/Module/Api.php:95 -msgid "Authorize application connection" +#: ../../include/selectors.php:134 +msgid "Infatuated" msgstr "" -#: ../../Zotlabs/Module/Api.php:75 -msgid "Return to your app and insert this Security Code:" +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Dating" msgstr "" -#: ../../Zotlabs/Module/Api.php:85 -msgid "Please login to continue." +#: ../../include/selectors.php:134 +msgid "Unfaithful" msgstr "" -#: ../../Zotlabs/Module/Api.php:97 -msgid "" -"Do you want to authorize this application to access your posts and contacts, " -"and/or create new posts for you?" +#: ../../include/selectors.php:134 +msgid "Sex Addict" msgstr "" -#: ../../Zotlabs/Module/Regmod.php:15 -msgid "Please login." +#: ../../include/selectors.php:134 +msgid "Friends/Benefits" msgstr "" -#: ../../Zotlabs/Module/Blocks.php:97 ../../Zotlabs/Module/Blocks.php:155 -#: ../../Zotlabs/Module/Editblock.php:113 -msgid "Block Name" +#: ../../include/selectors.php:134 +msgid "Casual" msgstr "" -#: ../../Zotlabs/Module/Blocks.php:156 -msgid "Block Title" +#: ../../include/selectors.php:134 +msgid "Engaged" msgstr "" -#: ../../Zotlabs/Module/Email_validation.php:36 -msgid "Email Verification Required" +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Married" msgstr "" -#: ../../Zotlabs/Module/Email_validation.php:37 -#, php-format -msgid "" -"A verification token was sent to your email address [%s]. Enter that token " -"here to complete the account verification step. Please allow a few minutes " -"for delivery, and check your spam folder if you do not see the message." +#: ../../include/selectors.php:134 +msgid "Imaginarily married" msgstr "" -#: ../../Zotlabs/Module/Email_validation.php:38 -msgid "Resend Email" +#: ../../include/selectors.php:134 +msgid "Partners" msgstr "" -#: ../../Zotlabs/Module/Email_validation.php:41 -msgid "Validation token" +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Cohabiting" msgstr "" -#: ../../Zotlabs/Module/Attach.php:67 -msgid "Item not available." +#: ../../include/selectors.php:134 +msgid "Common law" msgstr "" -#: ../../Zotlabs/Module/Vote.php:40 -msgid "Poll not found." +#: ../../include/selectors.php:134 +msgid "Happy" msgstr "" -#: ../../Zotlabs/Module/Vote.php:71 -msgid "Invalid response." +#: ../../include/selectors.php:134 +msgid "Not looking" msgstr "" -#: ../../Zotlabs/Module/Vote.php:132 -msgid "Response submitted. Updates may not appear instantly." +#: ../../include/selectors.php:134 +msgid "Swinger" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:93 -#: ../../Zotlabs/Module/Cover_photo.php:85 -msgid "Image uploaded but image cropping failed." +#: ../../include/selectors.php:134 +msgid "Betrayed" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:166 -#: ../../Zotlabs/Module/Cover_photo.php:212 -msgid "Image resize failed." +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Separated" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:296 -#: ../../Zotlabs/Module/Cover_photo.php:265 -msgid "Image upload failed." +#: ../../include/selectors.php:134 +msgid "Unstable" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:315 -#: ../../Zotlabs/Module/Cover_photo.php:282 -msgid "Unable to process image." +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Divorced" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:379 -#: ../../Zotlabs/Module/Profile_photo.php:431 -#: ../../Zotlabs/Module/Cover_photo.php:367 -#: ../../Zotlabs/Module/Cover_photo.php:382 -msgid "Photo not available." +#: ../../include/selectors.php:134 +msgid "Imaginarily divorced" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:495 -msgid "" -"Your default profile photo is visible to anybody on the internet. Profile " -"photos for alternate profiles will inherit the permissions of the profile" +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Widowed" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:495 -msgid "" -"Your profile photo is visible to anybody on the internet and may be " -"distributed to other websites." +#: ../../include/selectors.php:134 +msgid "Uncertain" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:497 -#: ../../Zotlabs/Module/Cover_photo.php:420 -msgid "Upload File:" +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "It's complicated" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:498 -#: ../../Zotlabs/Module/Cover_photo.php:421 -msgid "Select a profile:" +#: ../../include/selectors.php:134 +msgid "Don't care" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:499 -msgid "Use Photo for Profile" +#: ../../include/selectors.php:134 +msgid "Ask me" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:499 -msgid "Change Profile Photo" +#: ../../include/network.php:1731 ../../include/network.php:1732 +msgid "Friendica" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:500 -msgid "Use" +#: ../../include/network.php:1733 +msgid "OStatus" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:505 -#: ../../Zotlabs/Module/Profile_photo.php:506 -#: ../../Zotlabs/Module/Cover_photo.php:426 -#: ../../Zotlabs/Module/Cover_photo.php:427 -msgid "Use a photo from your albums" +#: ../../include/network.php:1734 +msgid "GNU-Social" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:511 -#: ../../Zotlabs/Module/Cover_photo.php:432 ../../Zotlabs/Module/Wiki.php:405 -msgid "Choose a different album" +#: ../../include/network.php:1735 +msgid "RSS/Atom" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:516 -#: ../../Zotlabs/Module/Cover_photo.php:438 -msgid "Select existing photo" +#: ../../include/network.php:1738 +msgid "Diaspora" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:535 -#: ../../Zotlabs/Module/Cover_photo.php:455 -msgid "Crop Image" +#: ../../include/network.php:1739 +msgid "Facebook" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:536 -#: ../../Zotlabs/Module/Cover_photo.php:456 -msgid "Please adjust the image cropping for optimum viewing." +#: ../../include/network.php:1740 +msgid "Zot" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:538 -#: ../../Zotlabs/Module/Cover_photo.php:458 -msgid "Done Editing" +#: ../../include/network.php:1741 +msgid "LinkedIn" msgstr "" -#: ../../Zotlabs/Module/Editblock.php:138 -msgid "Edit Block" +#: ../../include/network.php:1742 +msgid "XMPP/IM" msgstr "" -#: ../../Zotlabs/Module/Filer.php:53 -msgid "Enter a folder name" +#: ../../include/network.php:1743 +msgid "MySpace" msgstr "" -#: ../../Zotlabs/Module/Filer.php:53 -msgid "or select an existing folder (doubleclick)" +#: ../../include/account.php:36 +msgid "Not a valid email address" msgstr "" -#: ../../Zotlabs/Module/Filer.php:55 ../../Zotlabs/Lib/ThreadItem.php:184 -msgid "Save to Folder" +#: ../../include/account.php:38 +msgid "Your email domain is not among those allowed on this site" msgstr "" -#: ../../Zotlabs/Module/Editlayout.php:128 ../../Zotlabs/Module/Layouts.php:129 -#: ../../Zotlabs/Module/Layouts.php:189 -msgid "Layout Name" +#: ../../include/account.php:44 +msgid "Your email address is already registered at this site." msgstr "" -#: ../../Zotlabs/Module/Editlayout.php:129 ../../Zotlabs/Module/Layouts.php:132 -msgid "Layout Description (Optional)" +#: ../../include/account.php:76 +msgid "An invitation is required." msgstr "" -#: ../../Zotlabs/Module/Editlayout.php:137 -msgid "Edit Layout" +#: ../../include/account.php:80 +msgid "Invitation could not be verified." msgstr "" -#: ../../Zotlabs/Module/Connections.php:58 -#: ../../Zotlabs/Module/Connections.php:115 -#: ../../Zotlabs/Module/Connections.php:273 -msgid "Active" +#: ../../include/account.php:156 +msgid "Please enter the required information." msgstr "" -#: ../../Zotlabs/Module/Connections.php:63 -#: ../../Zotlabs/Module/Connections.php:181 -#: ../../Zotlabs/Module/Connections.php:278 -msgid "Blocked" +#: ../../include/account.php:223 +msgid "Failed to store account information." msgstr "" -#: ../../Zotlabs/Module/Connections.php:68 -#: ../../Zotlabs/Module/Connections.php:188 -#: ../../Zotlabs/Module/Connections.php:277 -msgid "Ignored" +#: ../../include/account.php:311 +#, php-format +msgid "Registration confirmation for %s" msgstr "" -#: ../../Zotlabs/Module/Connections.php:73 -#: ../../Zotlabs/Module/Connections.php:202 -#: ../../Zotlabs/Module/Connections.php:276 -msgid "Hidden" +#: ../../include/account.php:380 +#, php-format +msgid "Registration request at %s" msgstr "" -#: ../../Zotlabs/Module/Connections.php:78 -#: ../../Zotlabs/Module/Connections.php:195 -msgid "Archived/Unreachable" +#: ../../include/account.php:402 +msgid "your registration password" msgstr "" -#: ../../Zotlabs/Module/Connections.php:83 -#: ../../Zotlabs/Module/Connections.php:92 ../../Zotlabs/Module/Menu.php:180 -#: ../../Zotlabs/Module/Notifications.php:50 -msgid "New" +#: ../../include/account.php:408 ../../include/account.php:471 +#, php-format +msgid "Registration details for %s" msgstr "" -#: ../../Zotlabs/Module/Connections.php:157 -msgid "Active Connections" +#: ../../include/account.php:482 +msgid "Account approved." msgstr "" -#: ../../Zotlabs/Module/Connections.php:160 -msgid "Show active connections" +#: ../../include/account.php:522 +#, php-format +msgid "Registration revoked for %s" msgstr "" -#: ../../Zotlabs/Module/Connections.php:167 -msgid "Show pending (new) connections" +#: ../../include/account.php:805 ../../include/account.php:807 +msgid "Click here to upgrade." msgstr "" -#: ../../Zotlabs/Module/Connections.php:184 -msgid "Only show blocked connections" +#: ../../include/account.php:813 +msgid "This action exceeds the limits set by your subscription plan." msgstr "" -#: ../../Zotlabs/Module/Connections.php:191 -msgid "Only show ignored connections" +#: ../../include/account.php:818 +msgid "This action is not available under your subscription plan." msgstr "" -#: ../../Zotlabs/Module/Connections.php:198 -msgid "Only show archived/unreachable connections" +#: ../../include/help.php:80 +msgid "Help:" msgstr "" -#: ../../Zotlabs/Module/Connections.php:205 -msgid "Only show hidden connections" +#: ../../include/help.php:129 +msgid "Not Found" msgstr "" -#: ../../Zotlabs/Module/Connections.php:220 -msgid "Show all connections" +#: ../../include/attach.php:273 ../../include/attach.php:324 +#: ../../include/attach.php:419 +msgid "Item was not found." msgstr "" -#: ../../Zotlabs/Module/Connections.php:274 -msgid "Pending approval" +#: ../../include/attach.php:290 +msgid "Unknown error." msgstr "" -#: ../../Zotlabs/Module/Connections.php:275 -msgid "Archived" +#: ../../include/attach.php:612 +msgid "No source file." msgstr "" -#: ../../Zotlabs/Module/Connections.php:279 -msgid "Not connected at this location" +#: ../../include/attach.php:634 +msgid "Cannot locate file to replace" msgstr "" -#: ../../Zotlabs/Module/Connections.php:318 -#, php-format -msgid "%1$s [%2$s]" +#: ../../include/attach.php:653 +msgid "Cannot locate file to revise/update" msgstr "" -#: ../../Zotlabs/Module/Connections.php:319 -msgid "Edit connection" +#: ../../include/attach.php:795 +#, php-format +msgid "File exceeds size limit of %d" msgstr "" -#: ../../Zotlabs/Module/Connections.php:321 -msgid "Delete connection" +#: ../../include/attach.php:816 +#, php-format +msgid "You have reached your limit of %1$.0f Mbytes attachment storage." msgstr "" -#: ../../Zotlabs/Module/Connections.php:330 -msgid "Channel address" +#: ../../include/attach.php:1004 +msgid "File upload failed. Possible system limit or action terminated." msgstr "" -#: ../../Zotlabs/Module/Connections.php:335 -msgid "Call" +#: ../../include/attach.php:1033 +msgid "Stored file could not be verified. Upload failed." msgstr "" -#: ../../Zotlabs/Module/Connections.php:337 -msgid "Status" +#: ../../include/attach.php:1105 ../../include/attach.php:1121 +msgid "Path not available." msgstr "" -#: ../../Zotlabs/Module/Connections.php:339 -msgid "Connected" +#: ../../include/attach.php:1169 ../../include/attach.php:1332 +msgid "Empty pathname" msgstr "" -#: ../../Zotlabs/Module/Connections.php:341 -msgid "Approve connection" +#: ../../include/attach.php:1195 +msgid "duplicate filename or path" msgstr "" -#: ../../Zotlabs/Module/Connections.php:343 -msgid "Ignore connection" +#: ../../include/attach.php:1220 +msgid "Path not found." msgstr "" -#: ../../Zotlabs/Module/Connections.php:344 -#: ../../Zotlabs/Module/Connedit.php:636 -msgid "Ignore" +#: ../../include/attach.php:1288 +msgid "mkdir failed." msgstr "" -#: ../../Zotlabs/Module/Connections.php:345 -msgid "Recent activity" +#: ../../include/attach.php:1292 +msgid "database storage failed." msgstr "" -#: ../../Zotlabs/Module/Connections.php:351 -msgid "Connect at this location" +#: ../../include/attach.php:1338 +msgid "Empty path" msgstr "" -#: ../../Zotlabs/Module/Connections.php:379 -msgid "Search your connections" +#: ../../include/attach.php:2099 +#, php-format +msgid "%s shared a %s with you" msgstr "" -#: ../../Zotlabs/Module/Connections.php:380 -msgid "Connections search" +#: ../../include/attach.php:2099 +#: ../../extend/addon/hzaddons/redfiles/redfilehelper.php:64 +msgid "file" msgstr "" -#: ../../Zotlabs/Module/Cover_photo.php:196 -#: ../../Zotlabs/Module/Cover_photo.php:254 -msgid "Cover Photos" +#: ../../include/connections.php:134 +msgid "New window" msgstr "" -#: ../../Zotlabs/Module/Cover_photo.php:418 -msgid "Your cover photo may be visible to anybody on the internet" +#: ../../include/connections.php:135 +msgid "Open the selected location in a different window or browser tab" msgstr "" -#: ../../Zotlabs/Module/Cover_photo.php:422 -msgid "Change Cover Photo" +#: ../../include/connections.php:736 ../../include/event.php:1424 +msgid "Home, Voice" msgstr "" -#: ../../Zotlabs/Module/Photos.php:80 -msgid "Page owner information could not be retrieved." +#: ../../include/connections.php:737 ../../include/event.php:1425 +msgid "Home, Fax" msgstr "" -#: ../../Zotlabs/Module/Photos.php:96 ../../Zotlabs/Module/Photos.php:115 -msgid "Album not found." +#: ../../include/connections.php:739 ../../include/event.php:1427 +msgid "Work, Voice" msgstr "" -#: ../../Zotlabs/Module/Photos.php:105 -msgid "Delete Album" +#: ../../include/connections.php:740 ../../include/event.php:1428 +msgid "Work, Fax" msgstr "" -#: ../../Zotlabs/Module/Photos.php:176 ../../Zotlabs/Module/Photos.php:1059 -msgid "Delete Photo" +#: ../../include/oembed.php:153 +msgid "View PDF" msgstr "" -#: ../../Zotlabs/Module/Photos.php:530 -msgid "No photos selected" +#: ../../include/oembed.php:357 +msgid " by " msgstr "" -#: ../../Zotlabs/Module/Photos.php:579 -msgid "Access to this item is restricted." +#: ../../include/oembed.php:358 +msgid " on " msgstr "" -#: ../../Zotlabs/Module/Photos.php:622 -#, php-format -msgid "%1$.2f MB of %2$.2f MB photo storage used." +#: ../../include/oembed.php:387 +msgid "Embedded content" msgstr "" -#: ../../Zotlabs/Module/Photos.php:625 -#, php-format -msgid "%1$.2f MB photo storage used." +#: ../../include/oembed.php:396 +msgid "Embedding disabled" msgstr "" -#: ../../Zotlabs/Module/Photos.php:667 -msgid "Upload Photos" +#: ../../include/event.php:33 ../../include/event.php:110 +msgid "l F d, Y \\@ g:i A" msgstr "" -#: ../../Zotlabs/Module/Photos.php:671 -msgid "Enter an album name" +#: ../../include/event.php:41 +msgid "Starts:" msgstr "" -#: ../../Zotlabs/Module/Photos.php:672 -msgid "or select an existing album (doubleclick)" +#: ../../include/event.php:51 +msgid "Finishes:" msgstr "" -#: ../../Zotlabs/Module/Photos.php:673 -msgid "Create a status post for this upload" +#: ../../include/event.php:110 +msgid "l F d, Y" msgstr "" -#: ../../Zotlabs/Module/Photos.php:675 -msgid "Description (optional)" +#: ../../include/event.php:114 +msgid "Start:" msgstr "" -#: ../../Zotlabs/Module/Photos.php:761 -msgid "Show Newest First" +#: ../../include/event.php:118 +msgid "End:" msgstr "" -#: ../../Zotlabs/Module/Photos.php:763 -msgid "Show Oldest First" +#: ../../include/event.php:123 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:67 +msgid "Timezone" msgstr "" -#: ../../Zotlabs/Module/Photos.php:820 ../../Zotlabs/Module/Photos.php:1364 -msgid "Add Photos" +#: ../../include/event.php:1106 +msgid "This event has been added to your calendar." msgstr "" -#: ../../Zotlabs/Module/Photos.php:868 -msgid "Permission denied. Access to this item may be restricted." +#: ../../include/event.php:1337 +msgid "Not specified" msgstr "" -#: ../../Zotlabs/Module/Photos.php:870 -msgid "Photo not available" +#: ../../include/event.php:1338 +msgid "Needs Action" msgstr "" -#: ../../Zotlabs/Module/Photos.php:928 -msgid "Use as profile photo" +#: ../../include/event.php:1339 +msgid "Completed" msgstr "" -#: ../../Zotlabs/Module/Photos.php:929 -msgid "Use as cover photo" +#: ../../include/event.php:1340 +msgid "In Process" msgstr "" -#: ../../Zotlabs/Module/Photos.php:936 -msgid "Private Photo" +#: ../../include/event.php:1341 +msgid "Cancelled" msgstr "" -#: ../../Zotlabs/Module/Photos.php:951 -msgid "View Full Size" +#: ../../include/datetime.php:140 +msgid "Birthday" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1033 -msgid "Edit photo" +#: ../../include/datetime.php:140 +msgid "Age: " msgstr "" -#: ../../Zotlabs/Module/Photos.php:1035 -msgid "Rotate CW (right)" +#: ../../include/datetime.php:140 +msgid "YYYY-MM-DD or MM-DD" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1036 -msgid "Rotate CCW (left)" +#: ../../include/datetime.php:238 ../../boot.php:2709 +msgid "never" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1039 -msgid "Move photo to album" +#: ../../include/datetime.php:244 +msgid "less than a second ago" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1040 -msgid "Enter a new album name" +#: ../../include/datetime.php:262 +#, php-format +msgctxt "e.g. 22 hours ago, 1 minute ago" +msgid "%1$d %2$s ago" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1041 -msgid "or select an existing one (doubleclick)" -msgstr "" +#: ../../include/datetime.php:273 +msgctxt "relative_date" +msgid "year" +msgid_plural "years" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Photos.php:1046 -msgid "Add a Tag" -msgstr "" +#: ../../include/datetime.php:276 +msgctxt "relative_date" +msgid "month" +msgid_plural "months" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Photos.php:1054 -msgid "Example: @bob, @Barbara_Jensen, @jim@example.com" -msgstr "" +#: ../../include/datetime.php:279 +msgctxt "relative_date" +msgid "week" +msgid_plural "weeks" +msgstr[0] "" +msgstr[1] "" -#: ../../Zotlabs/Module/Photos.php:1057 -msgid "Flag as adult in album view" +#: ../../include/datetime.php:282 +msgctxt "relative_date" +msgid "day" +msgid_plural "days" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:285 +msgctxt "relative_date" +msgid "hour" +msgid_plural "hours" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:288 +msgctxt "relative_date" +msgid "minute" +msgid_plural "minutes" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:291 +msgctxt "relative_date" +msgid "second" +msgid_plural "seconds" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:520 +#, php-format +msgid "%1$s's birthday" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1076 ../../Zotlabs/Lib/ThreadItem.php:317 -msgid "I like this (toggle)" +#: ../../include/datetime.php:521 +#, php-format +msgid "Happy Birthday %1$s" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1077 ../../Zotlabs/Lib/ThreadItem.php:318 -msgid "I don't like this (toggle)" +#: ../../include/items.php:999 ../../include/items.php:1059 +msgid "(Unknown)" msgstr "" -#: ../../Zotlabs/Module/Photos.php:1095 ../../Zotlabs/Module/Photos.php:1213 -#: ../../Zotlabs/Lib/ThreadItem.php:822 -msgid "This is you" +#: ../../include/items.php:1247 +msgid "Visible to anybody on the internet." msgstr "" -#: ../../Zotlabs/Module/Photos.php:1132 ../../Zotlabs/Module/Photos.php:1144 -#: ../../Zotlabs/Lib/ThreadItem.php:238 ../../Zotlabs/Lib/ThreadItem.php:250 -msgid "View all" +#: ../../include/items.php:1249 +msgid "Visible to you only." msgstr "" -#: ../../Zotlabs/Module/Photos.php:1247 -msgid "Photo Tools" +#: ../../include/items.php:1251 +msgid "Visible to anybody in this network." msgstr "" -#: ../../Zotlabs/Module/Photos.php:1256 -msgid "In This Photo:" +#: ../../include/items.php:1253 +msgid "Visible to anybody authenticated." msgstr "" -#: ../../Zotlabs/Module/Photos.php:1261 -msgid "Map" +#: ../../include/items.php:1255 +#, php-format +msgid "Visible to anybody on %s." msgstr "" -#: ../../Zotlabs/Module/Photos.php:1269 ../../Zotlabs/Lib/ThreadItem.php:489 -msgctxt "noun" -msgid "Likes" +#: ../../include/items.php:1257 +msgid "Visible to all connections." msgstr "" -#: ../../Zotlabs/Module/Photos.php:1270 ../../Zotlabs/Lib/ThreadItem.php:490 -msgctxt "noun" -msgid "Dislikes" +#: ../../include/items.php:1259 +msgid "Visible to approved connections." msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:19 -msgid "No valid account found." +#: ../../include/items.php:1261 +msgid "Visible to specific connections." msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:33 -msgid "Password reset request issued. Check your email." +#: ../../include/items.php:4507 +msgid "Privacy group is empty." msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108 +#: ../../include/items.php:4514 #, php-format -msgid "Site Member (%s)" +msgid "Privacy group: %s" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49 -#, php-format -msgid "Password reset requested at %s" +#: ../../include/items.php:4526 +msgid "Connection not found." msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:68 -msgid "" -"Request could not be verified. (You may have previously submitted it.) " -"Password reset failed." +#: ../../include/items.php:4867 +msgid "profile photo" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:91 ../../boot.php:1708 -msgid "Password Reset" +#: ../../include/items.php:5059 +#, php-format +msgid "[Edited %s]" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:92 -msgid "Your password has been reset as requested." +#: ../../include/items.php:5059 +msgctxt "edit_activity" +msgid "Post" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:93 -msgid "Your new password is" +#: ../../include/items.php:5059 +msgctxt "edit_activity" +msgid "Comment" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:94 -msgid "Save or copy your new password - and then" +#: ../../include/follow.php:84 +msgid "Response from remote channel was incomplete." msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:95 -msgid "click here to login" +#: ../../include/follow.php:96 +msgid "Premium channel - please visit:" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:96 -msgid "" -"Your password may be changed from the Settings page after " -"successful login." +#: ../../include/follow.php:110 +msgid "Channel was deleted and no longer exists." msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:117 -#, php-format -msgid "Your password has changed at %s" +#: ../../include/zot.php:775 +msgid "Invalid data packet" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:130 -msgid "Forgot your Password?" +#: ../../include/zot.php:4372 +msgid "invalid target signature" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:131 -msgid "" -"Enter your email address and submit to have your password reset. Then check " -"your email for further instructions." +#: ../../include/bbcode.php:221 ../../include/bbcode.php:896 +#: ../../include/bbcode.php:1486 ../../include/bbcode.php:1494 +msgid "Image/photo" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:132 -msgid "Email Address" +#: ../../include/bbcode.php:268 ../../include/bbcode.php:1511 +msgid "Encrypted content" msgstr "" -#: ../../Zotlabs/Module/Lostpass.php:133 ../../Zotlabs/Module/Pdledit.php:78 -msgid "Reset" +#: ../../include/bbcode.php:302 +#, php-format +msgid "Install %1$s element %2$s" msgstr "" -#: ../../Zotlabs/Module/Follow.php:93 -msgid "Connection added." +#: ../../include/bbcode.php:306 +#, php-format +msgid "" +"This post contains an installable %s element, however you lack permissions " +"to install it on this site." msgstr "" -#: ../../Zotlabs/Module/Page.php:39 ../../Zotlabs/Module/Block.php:29 -msgid "Invalid item." +#: ../../include/bbcode.php:519 +msgid "card" msgstr "" -#: ../../Zotlabs/Module/Page.php:173 -msgid "" -"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " -"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, " -"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo " -"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse " -"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " -"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +#: ../../include/bbcode.php:521 +msgid "article" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:26 ../../Zotlabs/Module/Profiles.php:186 -#: ../../Zotlabs/Module/Profiles.php:243 ../../Zotlabs/Module/Profiles.php:661 -msgid "Profile not found." +#: ../../include/bbcode.php:604 ../../include/bbcode.php:612 +msgid "Click to open/close" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:46 -msgid "Profile deleted." +#: ../../include/bbcode.php:625 +msgid "View article" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:70 ../../Zotlabs/Module/Profiles.php:107 -msgid "Profile-" +#: ../../include/bbcode.php:625 +msgid "View summary" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:92 ../../Zotlabs/Module/Profiles.php:129 -msgid "New profile created." +#: ../../include/bbcode.php:1474 +msgid "$1 wrote:" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:113 -msgid "Profile unavailable to clone." +#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:451 +msgid "Follow" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:148 -msgid "Profile unavailable to export." +#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:454 +#, php-format +msgid "%1$s is now following %2$s" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:254 -msgid "Profile Name is required." +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:16 +msgid "" +"The GNU-Social protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." msgstr "" -#: ../../Zotlabs/Module/Profiles.php:461 -msgid "Marital Status" +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22 +msgid "GNU-Social Protocol App" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:465 -msgid "Romantic Partner" +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:34 +msgid "GNU-Social Protocol" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:469 ../../Zotlabs/Module/Profiles.php:774 -msgid "Likes" +#: ../../extend/addon/hzaddons/qrator/qrator.php:48 +msgid "QR code" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:473 ../../Zotlabs/Module/Profiles.php:775 -msgid "Dislikes" +#: ../../extend/addon/hzaddons/qrator/qrator.php:63 +msgid "QR Generator" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:477 ../../Zotlabs/Module/Profiles.php:782 -msgid "Work/Employment" +#: ../../extend/addon/hzaddons/qrator/qrator.php:64 +msgid "Enter some text" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:480 -msgid "Religion" +#: ../../extend/addon/hzaddons/irc/Mod_Irc.php:23 +#: ../../extend/addon/hzaddons/irc/irc.php:41 +msgid "Popular Channels" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:484 -msgid "Political Views" +#: ../../extend/addon/hzaddons/irc/irc.php:37 +msgid "Channels to auto connect" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:492 -msgid "Sexual Preference" +#: ../../extend/addon/hzaddons/irc/irc.php:37 +#: ../../extend/addon/hzaddons/irc/irc.php:41 +msgid "Comma separated list" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:496 -msgid "Homepage" +#: ../../extend/addon/hzaddons/irc/irc.php:45 +msgid "IRC Settings" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:500 -msgid "Interests" +#: ../../extend/addon/hzaddons/irc/irc.php:54 +msgid "IRC settings saved." msgstr "" -#: ../../Zotlabs/Module/Profiles.php:596 -msgid "Profile updated." +#: ../../extend/addon/hzaddons/irc/irc.php:58 +msgid "IRC Chatroom" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:680 -msgid "Hide your connections list from viewers of this profile" +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:19 +msgid "Send email to all members" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:724 -msgid "Edit Profile Details" +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:50 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:50 +msgid "No recipients found." msgstr "" -#: ../../Zotlabs/Module/Profiles.php:726 -msgid "View this profile" +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:73 +#, php-format +msgid "%1$d of %2$d messages sent." msgstr "" -#: ../../Zotlabs/Module/Profiles.php:728 -msgid "Profile Tools" +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:81 +msgid "Send email to all hub members." msgstr "" -#: ../../Zotlabs/Module/Profiles.php:729 -msgid "Change cover photo" +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:92 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:96 +msgid "Message subject" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:731 -msgid "Create a new profile using these settings" +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:93 +msgid "Sender Email address" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:732 -msgid "Clone this profile" +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:94 +msgid "Test mode (only send to hub administrator)" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:733 -msgid "Delete this profile" +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:51 +msgid "Your Webbie:" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:734 -msgid "Add profile things" +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:54 +msgid "Fontsize (px):" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:735 -msgid "Personal" +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:68 +msgid "Link:" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:737 -msgid "Relationship" +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:70 +msgid "Like us on Hubzilla" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:740 -msgid "Import profile from file" +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:72 +msgid "Embed:" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:741 -msgid "Export profile to file" +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:46 +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:43 +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:150 +msgid "Save Settings" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:742 -msgid "Your gender" +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:47 +msgid "text to include in all outgoing posts from this site" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:743 -msgid "Marital status" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:19 +msgid "lonely" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:744 -msgid "Sexual preference" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:20 +msgid "drunk" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:747 -msgid "Profile name" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:21 +msgid "horny" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:749 -msgid "This is your default profile." +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:22 +msgid "stoned" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:751 -msgid "Your full name" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:23 +msgid "fucked up" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:752 -msgid "Title/Description" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:24 +msgid "clusterfucked" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:755 -msgid "Street address" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:25 +msgid "crazy" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:756 -msgid "Locality/City" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:26 +msgid "hurt" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:757 -msgid "Region/State" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:27 +msgid "sleepy" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:758 -msgid "Postal/Zip code" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:28 +msgid "grumpy" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:764 -msgid "Who (if applicable)" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:29 +msgid "high" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:764 -msgid "Examples: cathy123, Cathy Williams, cathy@example.com" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:30 +msgid "semi-conscious" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:765 -msgid "Since (date)" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:31 +msgid "in love" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:768 -msgid "Tell us about yourself" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:32 +msgid "in lust" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:770 -msgid "Hometown" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:33 +msgid "naked" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:771 -msgid "Political views" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:34 +msgid "stinky" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:772 -msgid "Religious views" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:35 +msgid "sweaty" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:773 -msgid "Keywords used in directory listings" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:36 +msgid "bleeding out" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:773 -msgid "Example: fishing photography software" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:37 +msgid "victorious" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:776 -msgid "Musical interests" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:38 +msgid "defeated" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:777 -msgid "Books, literature" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:39 +msgid "envious" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:778 -msgid "Television" +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:40 +msgid "jealous" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:779 -msgid "Film/Dance/Culture/Entertainment" +#: ../../extend/addon/hzaddons/piwik/piwik.php:85 +msgid "" +"This website is tracked using the Piwik " +"analytics tool." msgstr "" -#: ../../Zotlabs/Module/Profiles.php:780 -msgid "Hobbies/Interests" +#: ../../extend/addon/hzaddons/piwik/piwik.php:88 +#, php-format +msgid "" +"If you do not want that your visits are logged this way you can " +"set a cookie to prevent Piwik from tracking further visits of the site " +"(opt-out)." msgstr "" -#: ../../Zotlabs/Module/Profiles.php:781 -msgid "Love/Romance" +#: ../../extend/addon/hzaddons/piwik/piwik.php:96 +msgid "Piwik Base URL" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:783 -msgid "School/Education" +#: ../../extend/addon/hzaddons/piwik/piwik.php:96 +msgid "" +"Absolute path to your Piwik installation. (without protocol (http/s), with " +"trailing slash)" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:784 -msgid "Contact information and social networks" +#: ../../extend/addon/hzaddons/piwik/piwik.php:97 +msgid "Site ID" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:785 -msgid "My other channels" +#: ../../extend/addon/hzaddons/piwik/piwik.php:98 +msgid "Show opt-out cookie link?" msgstr "" -#: ../../Zotlabs/Module/Profiles.php:787 -msgid "Communications" +#: ../../extend/addon/hzaddons/piwik/piwik.php:99 +msgid "Asynchronous tracking" msgstr "" -#: ../../Zotlabs/Module/Subthread.php:143 -#, php-format -msgid "%1$s is following %2$s's %3$s" +#: ../../extend/addon/hzaddons/piwik/piwik.php:100 +msgid "Enable frontend JavaScript error tracking" msgstr "" -#: ../../Zotlabs/Module/Subthread.php:145 -#, php-format -msgid "%1$s stopped following %2$s's %3$s" +#: ../../extend/addon/hzaddons/piwik/piwik.php:100 +msgid "This feature requires Piwik >= 2.2.0" msgstr "" -#: ../../Zotlabs/Module/Articles.php:52 -msgid "Articles App" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:101 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:102 +#: ../../extend/addon/hzaddons/cart/myshop.php:144 +#: ../../extend/addon/hzaddons/cart/myshop.php:180 +#: ../../extend/addon/hzaddons/cart/myshop.php:214 +#: ../../extend/addon/hzaddons/cart/myshop.php:261 +#: ../../extend/addon/hzaddons/cart/myshop.php:296 +#: ../../extend/addon/hzaddons/cart/myshop.php:319 +msgid "Access Denied" msgstr "" -#: ../../Zotlabs/Module/Articles.php:53 -msgid "Create interactive articles" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:109 +msgid "Enable Community Moderation" msgstr "" -#: ../../Zotlabs/Module/Articles.php:116 -msgid "Add Article" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:117 +msgid "Reputation automatically given to new members" msgstr "" -#: ../../Zotlabs/Module/Bookmarks.php:62 -msgid "Bookmark added" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:118 +msgid "Reputation will never fall below this value" msgstr "" -#: ../../Zotlabs/Module/Bookmarks.php:78 -msgid "Bookmarks App" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:119 +msgid "Minimum reputation before posting is allowed" msgstr "" -#: ../../Zotlabs/Module/Bookmarks.php:79 -msgid "Bookmark links from posts and manage them" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:120 +msgid "Minimum reputation before commenting is allowed" msgstr "" -#: ../../Zotlabs/Module/Bookmarks.php:92 -msgid "My Bookmarks" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:121 +msgid "Minimum reputation before a member is able to moderate other posts" msgstr "" -#: ../../Zotlabs/Module/Bookmarks.php:103 -msgid "My Connections Bookmarks" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:122 +msgid "" +"Max ratio of moderator's reputation that can be added to/deducted from " +"reputation of person being moderated" msgstr "" -#: ../../Zotlabs/Module/Probe.php:18 -msgid "Remote Diagnostics App" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:123 +msgid "Reputation \"cost\" to post" msgstr "" -#: ../../Zotlabs/Module/Probe.php:19 -msgid "Perform diagnostics on remote channels" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:124 +msgid "Reputation \"cost\" to comment" msgstr "" -#: ../../Zotlabs/Module/Changeaddr.php:35 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:125 msgid "" -"Channel name changes are not allowed within 48 hours of changing the account " -"password." +"Reputation automatically recovers at this rate per hour until it reaches " +"minimum_to_post" msgstr "" -#: ../../Zotlabs/Module/Changeaddr.php:77 -msgid "Change channel nickname/address" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:126 +msgid "" +"When minimum_to_moderate > reputation > minimum_to_post reputation recovers " +"at this rate per hour" msgstr "" -#: ../../Zotlabs/Module/Changeaddr.php:78 -msgid "Any/all connections on other networks will be lost!" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:140 +msgid "Community Moderation Settings" msgstr "" -#: ../../Zotlabs/Module/Changeaddr.php:80 -msgid "New channel address" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:232 +msgid "Channel Reputation" msgstr "" -#: ../../Zotlabs/Module/Changeaddr.php:81 -msgid "Rename Channel" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:236 +msgid "An Error has occurred." msgstr "" -#: ../../Zotlabs/Module/Invite.php:37 -msgid "Total invitation limit exceeded." +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:254 +msgid "Upvote" msgstr "" -#: ../../Zotlabs/Module/Invite.php:61 -#, php-format -msgid "%s : Not a valid email address." +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:255 +msgid "Downvote" msgstr "" -#: ../../Zotlabs/Module/Invite.php:75 -msgid "Please join us on $Projectname" +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:414 +msgid "Can moderate reputation on my channel." msgstr "" -#: ../../Zotlabs/Module/Invite.php:85 -msgid "Invitation limit exceeded. Please contact your site administrator." +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:57 +msgid "Errors encountered deleting database table " msgstr "" -#: ../../Zotlabs/Module/Invite.php:94 -#, php-format -msgid "%d message sent." -msgid_plural "%d messages sent." -msgstr[0] "" -msgstr[1] "" - -#: ../../Zotlabs/Module/Invite.php:110 -msgid "Invite App" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:95 +#: ../../extend/addon/hzaddons/twitter/twitter.php:503 +msgid "Submit Settings" msgstr "" -#: ../../Zotlabs/Module/Invite.php:111 -msgid "Send email invitations to join this network" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96 +msgid "Drop tables when uninstalling?" msgstr "" -#: ../../Zotlabs/Module/Invite.php:124 -msgid "You have no more invitations available" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96 +msgid "" +"If checked, the Rendezvous database tables will be deleted when the plugin " +"is uninstalled." msgstr "" -#: ../../Zotlabs/Module/Invite.php:155 -msgid "Send invitations" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97 +msgid "Mapbox Access Token" msgstr "" -#: ../../Zotlabs/Module/Invite.php:156 -msgid "Enter email addresses, one per line:" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97 +msgid "" +"If you enter a Mapbox access token, it will be used to retrieve map tiles " +"from Mapbox instead of the default OpenStreetMap tile server." msgstr "" -#: ../../Zotlabs/Module/Invite.php:158 -msgid "Please join my community on $Projectname." +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:162 +msgid "Rendezvous" msgstr "" -#: ../../Zotlabs/Module/Invite.php:160 -msgid "You will need to supply this invitation code:" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:167 +msgid "" +"This identity has been deleted by another member due to inactivity. Please " +"press the \"New identity\" button or refresh the page to register a new " +"identity. You may use the same name." msgstr "" -#: ../../Zotlabs/Module/Invite.php:161 -msgid "1. Register at any $Projectname location (they are all inter-connected)" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:168 +msgid "Welcome to Rendezvous!" msgstr "" -#: ../../Zotlabs/Module/Invite.php:163 -msgid "2. Enter my $Projectname network address into the site searchbar." +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:169 +msgid "" +"Enter your name to join this rendezvous. To begin sharing your location with " +"the other members, tap the GPS control. When your location is discovered, a " +"red dot will appear and others will be able to see you on the map." msgstr "" -#: ../../Zotlabs/Module/Invite.php:164 -msgid "or visit" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:171 +msgid "Let's meet here" msgstr "" -#: ../../Zotlabs/Module/Invite.php:166 -msgid "3. Click [Connect]" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:174 +msgid "New marker" msgstr "" -#: ../../Zotlabs/Module/Notes.php:57 -msgid "Notes App" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:175 +msgid "Edit marker" msgstr "" -#: ../../Zotlabs/Module/Notes.php:58 -msgid "A simple notes app with a widget (note: notes are not encrypted)" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:176 +msgid "New identity" msgstr "" -#: ../../Zotlabs/Module/Xchan.php:10 -msgid "Xchan Lookup" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:177 +msgid "Delete marker" msgstr "" -#: ../../Zotlabs/Module/Xchan.php:13 -msgid "Lookup xchan beginning with (or webbie): " +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:178 +msgid "Delete member" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:35 -msgid "Affinity Tool settings updated." +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:179 +msgid "Edit proximity alert" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:47 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180 msgid "" -"This app presents a slider control in your connection editor and also on " -"your network page. The slider represents your degree of friendship " -"(affinity) with each connection. It allows you to zoom in or out and display " -"conversations from only your closest friends or everybody in your stream." +"A proximity alert will be issued when this member is within a certain radius " +"of you.

      Enter a radius in meters (0 to disable):" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:52 -msgid "Affinity Tool App" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:185 +msgid "distance" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:57 -msgid "" -"The numbers below represent the minimum and maximum slider default positions " -"for your network/stream page as a percentage." +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:181 +msgid "Proximity alert distance (meters)" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:64 -msgid "Default maximum affinity level" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:182 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:184 +msgid "" +"A proximity alert will be issued when you are within a certain radius of the " +"marker location.

      Enter a radius in meters (0 to disable):" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:64 -msgid "0-99 default 99" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:183 +msgid "Marker proximity alert" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:70 -msgid "Default minimum affinity level" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:186 +msgid "Reminder note" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:70 -msgid "0-99 - default 0" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:187 +msgid "" +"Enter a note to be displayed when you are within the specified proximity..." msgstr "" -#: ../../Zotlabs/Module/Affinity.php:76 -msgid "Persistent affinity levels" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:199 +msgid "Add new rendezvous" msgstr "" -#: ../../Zotlabs/Module/Affinity.php:76 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:200 msgid "" -"If disabled the max and min levels will be reset to default after page reload" +"Create a new rendezvous and share the access link with those you wish to " +"invite to the group. Those who open the link become members of the " +"rendezvous. They can view other member locations, add markers to the map, or " +"share their own locations with the group." msgstr "" -#: ../../Zotlabs/Module/Affinity.php:84 -msgid "Affinity Tool Settings" +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:232 +msgid "You have no rendezvous. Press the button above to create a rendezvous!" msgstr "" -#: ../../Zotlabs/Module/Rate.php:156 -msgid "Website:" +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32 +msgid "Skeleton App" msgstr "" -#: ../../Zotlabs/Module/Rate.php:159 -#, php-format -msgid "Remote Channel [%s] (not yet known on this site)" +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:33 +msgid "A skeleton for addons, you can copy/paste" msgstr "" -#: ../../Zotlabs/Module/Rate.php:160 -msgid "Rating (this information is public)" +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40 +msgid "Some setting" msgstr "" -#: ../../Zotlabs/Module/Rate.php:161 -msgid "Optionally explain your rating (this information is public)" +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40 +msgid "A setting" msgstr "" -#: ../../Zotlabs/Module/Settings/Network.php:42 -#: ../../Zotlabs/Module/Settings/Channel_home.php:46 -msgid "Max height of content (in pixels)" +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:48 +msgid "Skeleton Settings" msgstr "" -#: ../../Zotlabs/Module/Settings/Network.php:44 -#: ../../Zotlabs/Module/Settings/Channel_home.php:48 -msgid "Click to expand content exceeding this height" +#: ../../extend/addon/hzaddons/redred/redred.php:50 +msgid "Post to Hubzilla" msgstr "" -#: ../../Zotlabs/Module/Settings/Network.php:59 -msgid "Stream Settings" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:24 +msgid "Channel is required." msgstr "" -#: ../../Zotlabs/Module/Settings/Features.php:45 -msgid "Additional Features" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:38 +msgid "Hubzilla Crosspost Connector Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146 +msgid "Hubzilla Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:51 +msgid "Relay public postings to another Hubzilla channel" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:329 -msgid "Nobody except yourself" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +msgid "Send public postings to Hubzilla channel by default" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:330 -msgid "Only those you specifically allow" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67 +msgid "Hubzilla API Path" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:331 -msgid "Approved connections" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53 +msgid "https://{sitename}/api" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:332 -msgid "Any connections" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71 +msgid "Hubzilla login name" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:333 -msgid "Anybody on this website" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75 +msgid "Hubzilla channel name" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:334 -msgid "Anybody in this network" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:54 +msgid "Nickname" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:335 -msgid "Anybody authenticated" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:79 +msgid "Hubzilla password" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:336 -msgid "Anybody on the internet" +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:87 +msgid "Hubzilla Crosspost Connector" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:411 -msgid "Publish your default profile in the network directory" +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:23 +msgid "TOTP Two-Step Verification" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:416 -msgid "Allow us to suggest you as a potential friend to new members?" +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:24 +msgid "Enter the 2-step verification generated by your authenticator app:" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:420 -msgid "or" +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:25 +msgid "Success!" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:429 -msgid "Your channel address is" +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:26 +msgid "Invalid code, please try again." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:432 -msgid "Your files/photos are accessible via WebDAV at" +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:27 +msgid "Too many invalid codes..." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:472 -msgid "Automatic membership approval" +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:28 +msgid "Verify" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:472 -#: ../../Zotlabs/Module/Defperms.php:256 +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:90 msgid "" -"If enabled, connection requests will be approved without your interaction" -msgstr "" - -#: ../../Zotlabs/Module/Settings/Channel.php:493 -msgid "Channel Settings" +"You haven't set a TOTP secret yet.\n" +"Please click the button below to generate one and register this site\n" +"with your preferred authenticator app." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:500 -msgid "Basic Settings" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:93 +msgid "Your TOTP secret is" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:502 -#: ../../Zotlabs/Module/Settings/Account.php:104 -msgid "Email Address:" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:94 +msgid "" +"Be sure to save it somewhere in case you lose or replace your mobile " +"device.\n" +"Use your mobile device to scan the QR code below to register this site\n" +"with your preferred authenticator app." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:503 -msgid "Your Timezone:" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:99 +msgid "Test" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:504 -msgid "Default Post Location:" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:100 +msgid "Generate New Secret" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:504 -msgid "Geographical location to display on your posts" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:101 +msgid "Go" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:505 -msgid "Use Browser Location:" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:102 +msgid "Enter your password" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:507 -msgid "Adult Content" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:103 +msgid "enter TOTP code from your device" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:507 -msgid "" -"This channel frequently or regularly publishes adult content. (Please tag " -"any adult material and/or nudity with #NSFW)" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:104 +msgid "Pass!" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:509 -msgid "Security and Privacy Settings" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:105 +msgid "Fail" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:511 -msgid "Your permissions are already configured. Click to view/adjust" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:106 +msgid "Incorrect password, try again." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:513 -msgid "Hide my online presence" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:107 +msgid "Record your new TOTP secret and rescan the QR code above." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:513 -msgid "Prevents displaying in your profile that you are online" +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:115 +msgid "TOTP Settings" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:515 -msgid "Simple Privacy Settings:" +#: ../../extend/addon/hzaddons/testdrive/testdrive.php:104 +#, php-format +msgid "Your account on %s will expire in a few days." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:516 -msgid "" -"Very Public - extremely permissive (should be used with caution)" +#: ../../extend/addon/hzaddons/testdrive/testdrive.php:105 +msgid "Your $Productname test account is about to expire." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:517 -msgid "" -"Typical - default public, privacy when desired (similar to social " -"network permissions but with improved privacy)" +#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:70 +msgid "An account has been created for you." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:518 -msgid "Private - default private, never open or public" +#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:77 +msgid "Authentication successful but rejected: account creation is disabled." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:519 -msgid "Blocked - default blocked to/from everybody" +#: ../../extend/addon/hzaddons/cart/cart.php:252 +msgid "DB Cleanup Failure" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:521 -msgid "Allow others to tag your posts" +#: ../../extend/addon/hzaddons/cart/cart.php:674 +msgid "[cart] Item Added" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:521 -msgid "" -"Often used by the community to retro-actively flag inappropriate content" +#: ../../extend/addon/hzaddons/cart/cart.php:1063 +msgid "Order already checked out." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:523 -msgid "Channel Permission Limits" +#: ../../extend/addon/hzaddons/cart/cart.php:1368 +msgid "Drop database tables when uninstalling." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:525 -msgid "Expire other channel content after this many days" +#: ../../extend/addon/hzaddons/cart/cart.php:1375 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:129 +msgid "Cart Settings" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:525 -msgid "0 or blank to use the website limit." +#: ../../extend/addon/hzaddons/cart/cart.php:1387 +#: ../../extend/addon/hzaddons/cart/cart.php:1390 +msgid "Shop" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:525 -#, php-format -msgid "This website expires after %d days." +#: ../../extend/addon/hzaddons/cart/cart.php:1446 +#: ../../extend/addon/hzaddons/cart/myshop.php:112 +msgid "Order Not Found" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:525 -msgid "This website does not expire imported content." +#: ../../extend/addon/hzaddons/cart/cart.php:1507 +msgid "Cart utilities for orders and payments" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:525 -msgid "The website limit takes precedence if lower than your limit." +#: ../../extend/addon/hzaddons/cart/cart.php:1545 +msgid "You must be logged into the Grid to shop." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:526 -msgid "Maximum Friend Requests/Day:" +#: ../../extend/addon/hzaddons/cart/cart.php:1578 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:409 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:392 +#: ../../extend/addon/hzaddons/cart/manual_payments.php:68 +msgid "Order not found." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:526 -msgid "May reduce spam activity" +#: ../../extend/addon/hzaddons/cart/cart.php:1592 +msgid "Access denied." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:527 -msgid "Default Privacy Group" +#: ../../extend/addon/hzaddons/cart/cart.php:1644 +#: ../../extend/addon/hzaddons/cart/cart.php:1787 +msgid "No Order Found" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:529 -msgid "Use my default audience setting for the type of object published" +#: ../../extend/addon/hzaddons/cart/cart.php:1653 +msgid "An unknown error has occurred Please start again." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:538 -msgid "Default permissions category" +#: ../../extend/addon/hzaddons/cart/cart.php:1796 +msgid "Requirements not met." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:544 -msgid "Maximum private messages per day from unknown people:" +#: ../../extend/addon/hzaddons/cart/cart.php:1796 +msgid "Review your order and complete any needed requirements." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:544 -msgid "Useful to reduce spamming" +#: ../../extend/addon/hzaddons/cart/cart.php:1822 +msgid "Invalid Payment Type. Please start again." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:547 -#: ../../Zotlabs/Lib/Enotify.php:68 -msgid "Notification Settings" +#: ../../extend/addon/hzaddons/cart/cart.php:1829 +msgid "Order not found" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:548 -msgid "By default post a status message when:" +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:70 +msgid "Enable Order/Item Options" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:549 -msgid "accepting a friend request" +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:333 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:357 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:433 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:457 +msgid "Label" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:550 -msgid "joining a forum/community" +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:336 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:360 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:436 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:460 +msgid "Instructions" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:551 -msgid "making an interesting profile change" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:63 +msgid "Enable Hubzilla Services Module" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:552 -msgid "Send a notification email when:" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:162 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:172 +msgid "New Sku" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:553 -msgid "You receive a connection request" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:197 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:208 +msgid "Cannot save edits to locked item." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:554 -msgid "Your connections are confirmed" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:246 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:333 +msgid "SKU not found." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:555 -msgid "Someone writes on your profile wall" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:299 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:303 +msgid "Invalid Activation Directive." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:556 -msgid "Someone writes a followup comment" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:374 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:378 +msgid "Invalid Deactivation Directive." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:557 -msgid "You receive a private message" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:564 +msgid "Add to this privacy group" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:558 -msgid "You receive a friend suggestion" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:580 +msgid "Set user service class" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:559 -msgid "You are tagged in a post" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:607 +msgid "You must be using a local account to purchase this service." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:560 -msgid "You are poked/prodded/etc. in a post" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:647 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:252 +msgid "Changes Locked" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:562 -msgid "Someone likes your post/comment" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:651 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:256 +msgid "Item available for purchase." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:565 -msgid "Show visual notifications including:" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:658 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:263 +#: ../../extend/addon/hzaddons/cart/widgets/catalogitem.php:57 +msgid "Price" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:567 -msgid "Unseen stream activity" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:661 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:266 +msgid "Photo URL" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:568 -msgid "Unseen channel activity" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:665 +msgid "Add buyer to privacy group" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:569 -msgid "Unseen private messages" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:670 +msgid "Add buyer as connection" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:569 -#: ../../Zotlabs/Module/Settings/Channel.php:574 -#: ../../Zotlabs/Module/Settings/Channel.php:575 -#: ../../Zotlabs/Module/Settings/Channel.php:576 -msgid "Recommended" +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:678 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:720 +msgid "Set Service Class" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:570 -msgid "Upcoming events" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:151 +msgid "Enable Subscription Management Module" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:571 -msgid "Events today" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:223 +msgid "" +"Cannot include subscription items with different terms in the same order." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:572 -msgid "Upcoming birthdays" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:372 +msgid "Select Subscription to Edit" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:572 -msgid "Not available in all themes" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:380 +msgid "Edit Subscriptions" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:573 -msgid "System (personal) notifications" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:414 +msgid "Subscription SKU" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:574 -msgid "System info messages" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:419 +msgid "Catalog Description" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:575 -msgid "System critical alerts" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:423 +msgid "Subscription available for purchase." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:576 -msgid "New connections" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:428 +msgid "Maximum active subscriptions to this item per account." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:577 -msgid "System Registrations" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:431 +msgid "Subscription price." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:578 -msgid "Unseen shared files" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:435 +msgid "Quantity" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:579 -msgid "Unseen public stream activity" +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:439 +msgid "Term" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:580 -msgid "Unseen likes and dislikes" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:86 +msgid "Enable Paypal Button Module (API-v2)" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:581 -msgid "Unseen forum posts" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:94 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:93 +msgid "Use Production Key" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:582 -msgid "Email notification hub (hostname)" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:101 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:100 +msgid "Paypal Sandbox Client Key" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:582 -#, php-format -msgid "" -"If your channel is mirrored to multiple hubs, set this to your preferred " -"location. This will prevent duplicate email notifications. Example: %s" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:108 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:107 +msgid "Paypal Sandbox Secret Key" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:583 -msgid "Show new wall posts, private messages and connections under Notices" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:114 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:113 +msgid "Paypal Production Client Key" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:585 -msgid "Notify me of events this many days in advance" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:121 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:120 +msgid "Paypal Production Secret Key" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:585 -msgid "Must be greater than 0" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:264 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:252 +msgid "Paypal button payments are not enabled." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:590 -msgid "Advanced Account/Page Type Settings" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:282 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:270 +msgid "" +"Paypal button payments are not properly configured. Please choose another " +"payment option." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:591 -msgid "Change the behaviour of this account for special situations" +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:85 +msgid "Enable Paypal Button Module" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:593 -msgid "Miscellaneous Settings" +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:61 +msgid "Enable Manual Cart Module" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:594 -msgid "Default photo upload folder" +#: ../../extend/addon/hzaddons/cart/myshop.php:30 +msgid "Access Denied." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:594 -#: ../../Zotlabs/Module/Settings/Channel.php:595 -msgid "%Y - current year, %m - current month" +#: ../../extend/addon/hzaddons/cart/myshop.php:189 +#: ../../extend/addon/hzaddons/cart/myshop.php:223 +#: ../../extend/addon/hzaddons/cart/myshop.php:271 +#: ../../extend/addon/hzaddons/cart/myshop.php:329 +msgid "Invalid Item" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:595 -msgid "Default file upload folder" +#: ../../extend/addon/hzaddons/cart/manual_payments.php:7 +msgid "Error: order mismatch. Please try again." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel.php:597 -msgid "Remove this channel." +#: ../../extend/addon/hzaddons/cart/manual_payments.php:61 +msgid "Manual payments are not enabled." msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:19 -msgid "Not valid email." +#: ../../extend/addon/hzaddons/cart/manual_payments.php:77 +msgid "Finished" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:22 -msgid "Protected email address. Cannot change to that email." +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:58 +msgid "Enable Test Catalog" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:31 -msgid "System failure storing new email. Please try again." +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:70 +msgid "Enable Manual Payments" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:48 -msgid "Password verification failed." +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:90 +msgid "Base Merchant Currency" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:55 -msgid "Passwords do not match. Password unchanged." +#: ../../extend/addon/hzaddons/openid/openid.php:49 +msgid "" +"We encountered a problem while logging in with the OpenID you provided. " +"Please check the correct spelling of the ID." msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:59 -msgid "Empty passwords are not allowed. Password unchanged." +#: ../../extend/addon/hzaddons/openid/openid.php:49 +msgid "The error message was:" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:73 -msgid "Password changed." +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:52 +msgid "First Name" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:75 -msgid "Password update failed. Please try again." +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:53 +msgid "Last Name" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:99 -msgid "Account Settings" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:55 +msgid "Full Name" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:100 -msgid "Current Password" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:61 +msgid "Profile Photo 16px" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:101 -msgid "Enter New Password" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:62 +msgid "Profile Photo 32px" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:102 -msgid "Confirm New Password" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:63 +msgid "Profile Photo 48px" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:102 -msgid "Leave password fields blank unless changing" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:64 +msgid "Profile Photo 64px" msgstr "" -#: ../../Zotlabs/Module/Settings/Account.php:106 -msgid "Remove this account including all its channels" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:65 +msgid "Profile Photo 80px" msgstr "" -#: ../../Zotlabs/Module/Settings/Featured.php:25 -msgid "No feature settings configured" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:66 +msgid "Profile Photo 128px" msgstr "" -#: ../../Zotlabs/Module/Settings/Featured.php:34 -msgid "Addon Settings" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:70 +msgid "Birth Year" msgstr "" -#: ../../Zotlabs/Module/Settings/Featured.php:35 -msgid "Please save/submit changes to any panel before opening another." +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:71 +msgid "Birth Month" msgstr "" -#: ../../Zotlabs/Module/Settings/Events.php:40 -msgid "Events Settings" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:72 +msgid "Birth Day" msgstr "" -#: ../../Zotlabs/Module/Settings/Manage.php:41 -msgid "Channel Manager Settings" +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:73 +msgid "Birthdate" msgstr "" -#: ../../Zotlabs/Module/Settings/Channel_home.php:61 -msgid "Personal menu to display in your channel pages" +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:30 +msgid "OpenID protocol error. No ID returned." msgstr "" -#: ../../Zotlabs/Module/Settings/Channel_home.php:88 -msgid "Channel Home Settings" +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:81 +msgid "Hubzilla File Storage Import" msgstr "" -#: ../../Zotlabs/Module/Settings/Calendar.php:40 -msgid "Calendar Settings" +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:82 +msgid "This will import all your cloud files from another server." msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:127 -#, php-format -msgid "%s - (Experimental)" +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:83 +msgid "Hubzilla Server base URL" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:183 -msgid "Display Settings" +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:84 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:140 +msgid "Since modified date yyyy-mm-dd" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:184 -msgid "Theme Settings" +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:85 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:141 +msgid "Until modified date yyyy-mm-dd" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:185 -msgid "Custom Theme Settings" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:43 +msgid "Diaspora Protocol Settings updated." msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:186 -msgid "Content Settings" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:52 +msgid "" +"The diaspora protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:192 -msgid "Display Theme:" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:58 +msgid "Diaspora Protocol App" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:193 -msgid "Select scheme" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:75 +msgid "Allow any Diaspora member to comment on your public posts" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:195 -msgid "Preload images before rendering the page" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:79 +msgid "Prevent your hashtags from being redirected to other sites" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:195 -msgid "" -"The subjective page load time will be longer but the page will be ready when " -"displayed" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:83 +msgid "Sign and forward posts and comments with no existing Diaspora signature" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:196 -msgid "Enable user zoom on mobile devices" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:88 +msgid "Followed hashtags (comma separated, do not include the #)" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:197 -msgid "Update browser every xx seconds" +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:97 +msgid "Diaspora Protocol" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:197 -msgid "Minimum of 10 seconds, no maximum" +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:19 +msgid "No username found in import file." msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:198 -msgid "Maximum number of conversations to load at any time:" +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1541 +#, php-format +msgid "%1$s dislikes %2$s's %3$s" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:198 -msgid "Maximum of 30 items" +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:66 +msgid "" +"Please install the statistics addon to be able to configure a diaspora relay" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:199 -msgid "Show emoticons (smilies) as images" +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:76 +msgid "Diaspora Relay Handle" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:200 -msgid "Provide channel menu in navigation bar" +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:76 +msgid "Address of a diaspora relay. Example: relay@diasporarelay.tld" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:200 -msgid "Default: channel menu located in app menu" +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:96 +msgid "Diaspora relay could not be imported" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:201 -msgid "Link post titles to source" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:94 +msgid "Hubzilla Directory Stats" msgstr "" -#: ../../Zotlabs/Module/Settings/Display.php:203 -msgid "Display new member quick links menu" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:95 +msgid "Total Hubs" msgstr "" -#: ../../Zotlabs/Module/Settings/Directory.php:40 -msgid "Directory Settings" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:97 +msgid "Hubzilla Hubs" msgstr "" -#: ../../Zotlabs/Module/Settings/Editor.php:40 -msgid "Editor Settings" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:99 +msgid "Friendica Hubs" msgstr "" -#: ../../Zotlabs/Module/Settings/Connections.php:40 -msgid "Connections Settings" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:101 +msgid "Diaspora Pods" msgstr "" -#: ../../Zotlabs/Module/Settings/Photos.php:40 -msgid "Photos Settings" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:103 +msgid "Hubzilla Channels" msgstr "" -#: ../../Zotlabs/Module/Settings/Profiles.php:49 -msgid "Profiles Settings" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:105 +msgid "Friendica Channels" msgstr "" -#: ../../Zotlabs/Module/Settings/Conversation.php:23 -msgid "Settings saved." +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:107 +msgid "Diaspora Channels" msgstr "" -#: ../../Zotlabs/Module/Settings/Conversation.php:25 -msgid "Settings saved. Reload page please." +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:109 +msgid "Aged 35 and above" msgstr "" -#: ../../Zotlabs/Module/Settings/Conversation.php:47 -msgid "Conversation Settings" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:111 +msgid "Aged 34 and under" msgstr "" -#: ../../Zotlabs/Module/Menu.php:68 -msgid "Unable to update menu." +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:113 +msgid "Average Age" msgstr "" -#: ../../Zotlabs/Module/Menu.php:79 -msgid "Unable to create menu." +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:115 +msgid "Known Chatrooms" msgstr "" -#: ../../Zotlabs/Module/Menu.php:161 ../../Zotlabs/Module/Menu.php:174 -msgid "Menu Name" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:117 +msgid "Known Tags" msgstr "" -#: ../../Zotlabs/Module/Menu.php:161 -msgid "Unique name (not visible on webpage) - required" +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:119 +msgid "" +"Please note Diaspora and Friendica statistics are merely those **this " +"directory** is aware of, and not all those known in the network. This also " +"applies to chatrooms," msgstr "" -#: ../../Zotlabs/Module/Menu.php:162 ../../Zotlabs/Module/Menu.php:175 -msgid "Menu Title" +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:25 +msgid "Show Upload Limits" msgstr "" -#: ../../Zotlabs/Module/Menu.php:162 -msgid "Visible on webpage - leave empty for no title" +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:27 +msgid "Hubzilla configured maximum size: " msgstr "" -#: ../../Zotlabs/Module/Menu.php:163 -msgid "Allow Bookmarks" +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:28 +msgid "PHP upload_max_filesize: " msgstr "" -#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 -msgid "Menu may be used to store saved bookmarks" +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:29 +msgid "PHP post_max_size (must be larger than upload_max_filesize): " msgstr "" -#: ../../Zotlabs/Module/Menu.php:164 ../../Zotlabs/Module/Menu.php:225 -msgid "Submit and proceed" +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:23 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:27 +msgid "Hide Aside App" msgstr "" -#: ../../Zotlabs/Module/Menu.php:177 ../../Zotlabs/Module/Locs.php:131 -msgid "Drop" +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:24 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:28 +msgid "Fade out aside areas after a while when using endless scroll" msgstr "" -#: ../../Zotlabs/Module/Menu.php:181 -msgid "Bookmarks allowed" +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:27 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26 +msgid "Installed" msgstr "" -#: ../../Zotlabs/Module/Menu.php:183 -msgid "Delete this menu" +#: ../../extend/addon/hzaddons/randpost/randpost.php:97 +msgid "You're welcome." msgstr "" -#: ../../Zotlabs/Module/Menu.php:184 ../../Zotlabs/Module/Menu.php:219 -msgid "Edit menu contents" +#: ../../extend/addon/hzaddons/randpost/randpost.php:98 +msgid "Ah shucks..." msgstr "" -#: ../../Zotlabs/Module/Menu.php:185 -msgid "Edit this menu" +#: ../../extend/addon/hzaddons/randpost/randpost.php:99 +msgid "Don't mention it." msgstr "" -#: ../../Zotlabs/Module/Menu.php:201 -msgid "Menu could not be deleted." +#: ../../extend/addon/hzaddons/randpost/randpost.php:100 +msgid "<blush>" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:133 +msgid "View Larger" msgstr "" -#: ../../Zotlabs/Module/Menu.php:214 -msgid "Edit Menu" +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:156 +msgid "Tile Server URL" msgstr "" -#: ../../Zotlabs/Module/Menu.php:218 -msgid "Add or remove entries to this menu" +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:156 +msgid "" +"A list of public tile servers" msgstr "" -#: ../../Zotlabs/Module/Menu.php:220 -msgid "Menu name" +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:157 +msgid "Nominatim (reverse geocoding) Server URL" msgstr "" -#: ../../Zotlabs/Module/Menu.php:220 -msgid "Must be unique, only seen by you" +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:157 +msgid "" +"A list of Nominatim servers" msgstr "" -#: ../../Zotlabs/Module/Menu.php:221 -msgid "Menu title" +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:158 +msgid "Default zoom" msgstr "" -#: ../../Zotlabs/Module/Menu.php:221 -msgid "Menu title as seen by others" +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:158 +msgid "" +"The default zoom level. (1:world, 18:highest, also depends on tile server)" msgstr "" -#: ../../Zotlabs/Module/Menu.php:222 -msgid "Allow bookmarks" +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:159 +msgid "Include marker on map" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:68 ../../Zotlabs/Module/Connedit.php:89 -msgid "Could not access contact record." +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:159 +msgid "Include a marker on the map." msgstr "" -#: ../../Zotlabs/Module/Defperms.php:190 -msgid "Default Permissions App" +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:38 +msgid "Livejournal Crosspost Connector App" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:191 -msgid "Set custom default permissions for new connections" +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:39 +msgid "Relay public posts to Livejournal" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:255 ../../Zotlabs/Module/Connedit.php:859 -msgid "Connection Default Permissions" +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:55 +msgid "Livejournal username" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:256 ../../Zotlabs/Module/Connedit.php:860 -msgid "Apply these permissions automatically" +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:59 +msgid "Livejournal password" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:257 ../../Zotlabs/Module/Connedit.php:861 -msgid "Permission role" +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +msgid "Post to Livejournal by default" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:258 ../../Zotlabs/Module/Connedit.php:862 -msgid "Add permission role" +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +msgid "Send wall-to-wall posts to Livejournal" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:262 ../../Zotlabs/Module/Connedit.php:875 -msgid "" -"The permissions indicated on this page will be applied to all new " -"connections." +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +msgid "Add link to original post" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:263 -msgid "Automatic approval settings" +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:79 +msgid "Livejournal Crosspost Connector" msgstr "" -#: ../../Zotlabs/Module/Defperms.php:271 -msgid "" -"Some individual permissions may have been preset or locked based on your " -"channel type and privacy settings." +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:49 +msgid "Post to Livejournal" msgstr "" -#: ../../Zotlabs/Module/Pconfig.php:32 ../../Zotlabs/Module/Pconfig.php:68 -msgid "This setting requires special processing and editing has been blocked." +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:127 +msgid "Posted by" msgstr "" -#: ../../Zotlabs/Module/Pconfig.php:57 -msgid "Configuration Editor" +#: ../../extend/addon/hzaddons/workflow/workflow.php:222 +msgid "Workflow user." msgstr "" -#: ../../Zotlabs/Module/Pconfig.php:58 -msgid "" -"Warning: Changing some settings could render your channel inoperable. Please " -"leave this page unless you are comfortable with and knowledgeable about how " -"to correctly use this feature." +#: ../../extend/addon/hzaddons/workflow/workflow.php:272 +msgid "This channel" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:54 -msgid "Name and Secret are required" +#: ../../extend/addon/hzaddons/workflow/workflow.php:541 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1437 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1456 +msgid "Workflow" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:106 -msgid "OAuth2 Apps Manager App" +#: ../../extend/addon/hzaddons/workflow/workflow.php:1425 +msgid "No Workflows Available" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:107 -msgid "OAuth2 authenticatication tokens for mobile and remote apps" +#: ../../extend/addon/hzaddons/workflow/workflow.php:1455 +msgid "Add item to which workflow" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:115 -msgid "Add OAuth2 application" +#: ../../extend/addon/hzaddons/workflow/workflow.php:1515 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1634 +msgid "Create Workflow Item" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:149 -msgid "Grant Types" +#: ../../extend/addon/hzaddons/workflow/workflow.php:2596 +msgid "Link" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:122 -msgid "leave blank unless your application sepcifically requires this" +#: ../../extend/addon/hzaddons/workflow/workflow.php:2598 +msgid "Web link." msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:122 ../../Zotlabs/Module/Oauth2.php:150 -msgid "Authorization scope" +#: ../../extend/addon/hzaddons/workflow/workflow.php:2619 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2680 +msgid "Brief description or title" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:134 -msgid "OAuth2 Application not found." +#: ../../extend/addon/hzaddons/workflow/workflow.php:2627 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2688 +msgid "Notes and Info" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:149 ../../Zotlabs/Module/Oauth2.php:150 -msgid "leave blank unless your application specifically requires this" +#: ../../extend/addon/hzaddons/workflow/workflow.php:2686 +msgid "Body" msgstr "" -#: ../../Zotlabs/Module/Oauth2.php:192 -msgid "Connected OAuth2 Apps" +#: ../../extend/addon/hzaddons/workflow/Settings/Mod_WorkflowSettings.php:101 +msgid "Workflow Settings" msgstr "" -#: ../../Zotlabs/Module/Randprof.php:29 -msgid "Random Channel App" +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:44 +msgid "Jabber BOSH host" msgstr "" -#: ../../Zotlabs/Module/Randprof.php:30 -msgid "Visit a random channel in the $Projectname network" +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45 +msgid "Use central userbase" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:59 -msgid "Invalid message" +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45 +msgid "" +"If enabled, members will automatically login to an ejabberd server that has " +"to be installed on this machine with synchronized credentials via the " +"\"auth_ejabberd.php\" script." msgstr "" -#: ../../Zotlabs/Module/Dreport.php:93 -msgid "no results" +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:23 +msgid "XMPP settings updated." msgstr "" -#: ../../Zotlabs/Module/Dreport.php:107 -msgid "channel sync processed" +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35 +msgid "XMPP App" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:111 -msgid "queued" +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:36 +msgid "Embedded XMPP (Jabber) client" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:115 -msgid "posted" +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:52 +msgid "Individual credentials" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:119 -msgid "accepted for delivery" +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:58 +msgid "Jabber BOSH server" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:123 -msgid "updated" +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:67 +msgid "XMPP Settings" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:126 -msgid "update ignored" +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20 +msgid "Superblock App" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:129 -msgid "permission denied" +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:21 +msgid "Block channels" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:133 -msgid "recipient not found" +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:63 +msgid "superblock settings updated" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:136 -msgid "mail recalled" +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:87 +msgid "Currently blocked" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:139 -msgid "duplicate mail received" +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:89 +msgid "No channels currently blocked" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:142 -msgid "mail delivered" +#: ../../extend/addon/hzaddons/superblock/superblock.php:337 +msgid "Block Completely" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:162 -#, php-format -msgid "Delivery report for %1$s" +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23 +msgid "Random Planet App" msgstr "" -#: ../../Zotlabs/Module/Dreport.php:167 -msgid "Redeliver" +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:25 +msgid "" +"Set a random planet from the Star Wars Empire as your location when posting" msgstr "" -#: ../../Zotlabs/Module/Thing.php:122 -msgid "Thing updated" +#: ../../extend/addon/hzaddons/nsfw/nsfw.php:152 +msgid "Possible adult content" msgstr "" -#: ../../Zotlabs/Module/Thing.php:174 -msgid "Object store: failed" +#: ../../extend/addon/hzaddons/nsfw/nsfw.php:167 +#, php-format +msgid "%s - view" msgstr "" -#: ../../Zotlabs/Module/Thing.php:178 -msgid "Thing added" +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:22 +msgid "NSFW Settings saved." msgstr "" -#: ../../Zotlabs/Module/Thing.php:204 -#, php-format -msgid "OBJ: %1$s %2$s %3$s" +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33 +msgid "NSFW App" msgstr "" -#: ../../Zotlabs/Module/Thing.php:267 -msgid "Show Thing" +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:34 +msgid "Collapse content that contains predefined words" msgstr "" -#: ../../Zotlabs/Module/Thing.php:274 -msgid "item not found." +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:44 +msgid "" +"This app looks in posts for the words/text you specify below, and collapses " +"any content containing those keywords so it is not displayed at " +"inappropriate times, such as sexual innuendo that may be improper in a work " +"setting. It is polite and recommended to tag any content containing nudity " +"with #NSFW. This filter can also match any other word/text you specify, and " +"can thereby be used as a general purpose content filter." msgstr "" -#: ../../Zotlabs/Module/Thing.php:307 -msgid "Edit Thing" +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49 +msgid "Comma separated list of keywords to hide" msgstr "" -#: ../../Zotlabs/Module/Thing.php:309 ../../Zotlabs/Module/Thing.php:366 -msgid "Select a profile" +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49 +msgid "Word, /regular-expression/, lang=xx, lang!=xx" msgstr "" -#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 -msgid "Post an activity" +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:58 +msgid "NSFW" msgstr "" -#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 -msgid "Only sends to viewers of the applicable profile" +#: ../../extend/addon/hzaddons/tictac/tictac.php:21 +msgid "Three Dimensional Tic-Tac-Toe" msgstr "" -#: ../../Zotlabs/Module/Thing.php:315 ../../Zotlabs/Module/Thing.php:371 -msgid "Name of thing e.g. something" +#: ../../extend/addon/hzaddons/tictac/tictac.php:54 +msgid "3D Tic-Tac-Toe" msgstr "" -#: ../../Zotlabs/Module/Thing.php:317 ../../Zotlabs/Module/Thing.php:372 -msgid "URL of thing (optional)" +#: ../../extend/addon/hzaddons/tictac/tictac.php:59 +msgid "New game" msgstr "" -#: ../../Zotlabs/Module/Thing.php:319 ../../Zotlabs/Module/Thing.php:373 -msgid "URL for photo of thing (optional)" +#: ../../extend/addon/hzaddons/tictac/tictac.php:60 +msgid "New game with handicap" msgstr "" -#: ../../Zotlabs/Module/Thing.php:364 -msgid "Add Thing to your Profile" +#: ../../extend/addon/hzaddons/tictac/tictac.php:61 +msgid "" +"Three dimensional tic-tac-toe is just like the traditional game except that " +"it is played on multiple levels simultaneously. " msgstr "" -#: ../../Zotlabs/Module/Rmagic.php:46 -msgid "Authentication failed." +#: ../../extend/addon/hzaddons/tictac/tictac.php:62 +msgid "" +"In this case there are three levels. You win by getting three in a row on " +"any level, as well as up, down, and diagonally across the different levels." msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:27 -msgid "Layout updated." +#: ../../extend/addon/hzaddons/tictac/tictac.php:64 +msgid "" +"The handicap game disables the center position on the middle level because " +"the player claiming this square often has an unfair advantage." msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:43 -msgid "PDL Editor App" +#: ../../extend/addon/hzaddons/tictac/tictac.php:183 +msgid "You go first..." msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:44 -msgid "Provides the ability to edit system page layouts" +#: ../../extend/addon/hzaddons/tictac/tictac.php:188 +msgid "I'm going first this time..." msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:57 ../../Zotlabs/Module/Pdledit.php:100 -msgid "Edit System Page Description" +#: ../../extend/addon/hzaddons/tictac/tictac.php:194 +msgid "You won!" msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:78 -msgid "(modified)" +#: ../../extend/addon/hzaddons/tictac/tictac.php:200 +#: ../../extend/addon/hzaddons/tictac/tictac.php:225 +msgid "\"Cat\" game!" msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:95 -msgid "Layout not found." +#: ../../extend/addon/hzaddons/tictac/tictac.php:223 +msgid "I won!" msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:101 -msgid "Module Name:" +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:27 +msgid "Photo Cache settings saved." msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:102 -msgid "Layout Help" +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:36 +msgid "" +"Photo Cache addon saves a copy of images from external sites locally to " +"increase your anonymity in the web." msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:103 -msgid "Edit another layout" +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42 +msgid "Photo Cache App" msgstr "" -#: ../../Zotlabs/Module/Pdledit.php:104 -msgid "System layout" +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:53 +msgid "Minimal photo size for caching" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:52 -msgid "Wiki App" +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:55 +msgid "In pixels. From 1 up to 1024, 0 will be replaced with system default." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:53 -msgid "Provide a wiki for your channel" +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:64 +msgid "Photo Cache" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:133 -msgid "Error retrieving wiki" +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:26 +#, php-format +msgctxt "opensearch" +msgid "Search %1$s (%2$s)" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:140 -msgid "Error creating zip file export folder" +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:28 +msgctxt "opensearch" +msgid "$Projectname" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:191 -msgid "Error downloading wiki: " +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:43 +msgid "Search $Projectname" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:212 ../../Zotlabs/Storage/Browser.php:397 -msgid "Download" +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:25 +msgid "Libertree Crosspost Connector Settings saved." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:216 -msgid "Wiki name" +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35 +msgid "Libertree Crosspost Connector App" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:217 -msgid "Content type" +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:36 +msgid "Relay public posts to Libertree" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:219 ../../Zotlabs/Storage/Browser.php:371 -msgid "Type" +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:51 +msgid "Libertree API token" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:220 -msgid "Any type" +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:55 +msgid "Libertree site URL" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:227 -msgid "Lock content type" +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +msgid "Post to Libertree by default" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:228 -msgid "Create a status post for this wiki" +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:67 +msgid "Libertree Crosspost Connector" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:229 -msgid "Edit Wiki Name" +#: ../../extend/addon/hzaddons/libertree/libertree.php:43 +msgid "Post to Libertree" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:274 -msgid "Wiki not found" +#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:24 +msgid "Flag Adult Photos" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:300 -msgid "Rename page" +#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:25 +msgid "" +"Provide photo edit option to hide inappropriate photos from default album " +"view" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:321 -msgid "Error retrieving page content" +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:145 +msgid "Post to GNU social" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:329 ../../Zotlabs/Module/Wiki.php:331 -msgid "New page" +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:594 +msgid "API URL" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:366 -msgid "Revision Comparison" +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:597 +msgid "Application name" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:374 -msgid "Short description of your changes (optional)" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:61 +msgid "" +"Please contact your site administrator.
      The provided API URL is not " +"valid." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:394 -msgid "New page name" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:98 +msgid "We could not contact the GNU social API with the Path you entered." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:399 -msgid "Embed image from photo albums" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:130 +msgid "GNU social settings updated." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:410 -msgid "History" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:147 +msgid "" +"Relay public postings to a connected GNU social account (formerly StatusNet)" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:488 -msgid "Error creating wiki. Invalid name." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:181 +msgid "Globally Available GNU social OAuthKeys" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:495 -msgid "A wiki with this name already exists." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:183 +msgid "" +"There are preconfigured OAuth key pairs for some GNU social servers " +"available. If you are using one of them, please use these credentials.
      If not feel free to connect to any other GNU social instance (see below)." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:508 -msgid "Wiki created, but error creating Home page." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:198 +msgid "Provide your own OAuth Credentials" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:515 -msgid "Error creating wiki" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:200 +msgid "" +"No consumer key pair for GNU social found. Register your Hubzilla Account as " +"an desktop client on your GNU social account, copy the consumer key pair " +"here and enter the API base root.
      Before you register your own OAuth " +"key pair ask the administrator if there is already a key pair for this " +"Hubzilla installation at your favourite GNU social installation." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:539 -msgid "Error updating wiki. Invalid name." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:204 +msgid "OAuth Consumer Key" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:559 -msgid "Error updating wiki" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:208 +msgid "OAuth Consumer Secret" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:574 -msgid "Wiki delete permission denied." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212 +msgid "Base API Path" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:584 -msgid "Error deleting wiki" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212 +msgid "Remember the trailing /" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:617 -msgid "New page created" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:216 +msgid "GNU social application name" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:739 -msgid "Cannot delete Home" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:239 +msgid "" +"To connect to your GNU social account click the button below to get a " +"security code from GNU social which you have to copy into the input box " +"below and submit the form. Only your public posts will be " +"posted to GNU social." msgstr "" -#: ../../Zotlabs/Module/Wiki.php:803 -msgid "Current Revision" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:241 +msgid "Log in with GNU social" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:803 -msgid "Selected Revision" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:244 +msgid "Copy the security code from GNU social here" msgstr "" -#: ../../Zotlabs/Module/Wiki.php:853 -msgid "You must be authenticated." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:254 +msgid "Cancel Connection Process" msgstr "" -#: ../../Zotlabs/Module/Home.php:90 -#, php-format -msgid "Welcome to %s" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:256 +msgid "Current GNU social API is" msgstr "" -#: ../../Zotlabs/Module/Suggest.php:40 -msgid "Suggest Channels App" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +msgid "Cancel GNU social Connection" msgstr "" -#: ../../Zotlabs/Module/Suggest.php:41 -msgid "" -"Suggestions for channels in the $Projectname network you might be interested " -"in" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:272 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:147 +msgid "Currently connected to: " msgstr "" -#: ../../Zotlabs/Module/Suggest.php:54 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:277 msgid "" -"No suggestions available. If this is a new site, please try again in 24 " -"hours." +"Note: Due your privacy settings (Hide your profile " +"details from unknown viewers?) the link potentially included in public " +"postings relayed to GNU social will lead the visitor to a blank page " +"informing the visitor that the access to your profile has been restricted." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:120 -msgid "Could not locate selected profile." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +msgid "Post to GNU social by default" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:264 -msgid "Connection updated." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +msgid "" +"If enabled your public postings will be posted to the associated GNU-social " +"account by default" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:266 -msgid "Failed to update connection record." +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +msgid "Clear OAuth configuration" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:309 -msgid "is now connected to" +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:303 +msgid "GNU-Social Crosspost Connector" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:434 -msgid "Could not access address book record." +#: ../../extend/addon/hzaddons/wholikesme/wholikesme.php:29 +msgid "Who likes me?" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:482 ../../Zotlabs/Module/Connedit.php:486 -msgid "Refresh failed - channel is currently unavailable." +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:25 +msgid "ActivityPub Protocol Settings updated." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:501 ../../Zotlabs/Module/Connedit.php:510 -#: ../../Zotlabs/Module/Connedit.php:519 ../../Zotlabs/Module/Connedit.php:528 -#: ../../Zotlabs/Module/Connedit.php:541 -msgid "Unable to set address book parameters." +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:34 +msgid "" +"The activitypub protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:560 -msgid "Connection has been removed." +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40 +msgid "Activitypub Protocol App" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:603 -#, php-format -msgid "View %s's profile" +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50 +msgid "Deliver to ActivityPub recipients in privacy groups" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:607 -msgid "Refresh Permissions" +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50 +msgid "" +"May result in a large number of mentions and expose all the members of your " +"privacy group" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:610 -msgid "Fetch updated permissions" +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54 +msgid "Send multi-media HTML articles" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:614 -msgid "Refresh Photo" +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54 +msgid "Not supported by some microblog services such as Mastodon" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:617 -msgid "Fetch updated photo" +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:62 +msgid "Activitypub Protocol" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:624 -msgid "View recent posts and comments" +#: ../../extend/addon/hzaddons/ijpost/ijpost.php:44 +msgid "Post to Insane Journal" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:631 -msgid "Block (or Unblock) all communications with this connection" +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:23 +msgid "Insane Journal Crosspost Connector Settings saved." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:632 -msgid "This connection is blocked!" +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35 +msgid "Insane Journal Crosspost Connector App" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:636 -msgid "Unignore" +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:36 +msgid "Relay public postings to Insane Journal" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:639 -msgid "Ignore (or Unignore) all inbound communications from this connection" +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:53 +msgid "InsaneJournal username" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:640 -msgid "This connection is ignored!" +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:57 +msgid "InsaneJournal password" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:644 -msgid "Unarchive" +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +msgid "Post to InsaneJournal by default" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:644 -msgid "Archive" +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:69 +msgid "Insane Journal Crosspost Connector" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:647 -msgid "" -"Archive (or Unarchive) this connection - mark channel dead but keep content" +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:77 +msgid "Max queueworker threads" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:648 -msgid "This connection is archived!" +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:91 +msgid "Assume workers dead after ___ seconds" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:652 -msgid "Unhide" +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:105 +msgid "" +"Pause before starting next task: (microseconds. Minimum 100 = .0001 seconds)" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:652 -msgid "Hide" +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:116 +msgid "Queueworker Settings" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:655 -msgid "Hide or Unhide this connection from your other connections" +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:218 +msgid "Not allowed." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:656 -msgid "This connection is hidden!" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:123 +msgid "generic profile image" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:663 -msgid "Delete this connection" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:124 +msgid "random geometric pattern" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:671 -msgid "Fetch Vcard" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:125 +msgid "monster face" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:674 -msgid "Fetch electronic calling card for this connection" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:126 +msgid "computer generated face" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:685 -msgid "Open Individual Permissions section by default" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:127 +msgid "retro arcade style face" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:708 -msgid "Affinity" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:128 +msgid "Hub default profile photo" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:711 -msgid "Open Set Affinity section by default" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143 +msgid "Information" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:748 -msgid "Filter" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143 +msgid "" +"Libravatar addon is installed, too. Please disable Libravatar addon or this " +"Gravatar addon.
      The Libravatar addon will fall back to Gravatar if " +"nothing was found at Libravatar." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:751 -msgid "Open Custom Filter section by default" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151 +msgid "Default avatar image" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:788 -msgid "Approve this connection" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151 +msgid "Select default avatar image if none was found at Gravatar. See README" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:788 -msgid "Accept connection to allow communication" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152 +msgid "Rating of images" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:793 -msgid "Set Affinity" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152 +msgid "Select the appropriate avatar rating for your site. See README" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:796 -msgid "Set Profile" +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:165 +msgid "Gravatar settings updated." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:799 -msgid "Set Affinity & Profile" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:104 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:176 +msgid "Network error" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:847 -msgid "This connection is unreachable from this location." +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:108 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:180 +msgid "API error" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:848 -msgid "This connection may be unreachable from other channel locations." +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:112 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:184 +msgid "Unknown issue" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:850 -msgid "Location independence is not supported by their network." +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:168 +msgid "Unable to login using email address " msgstr "" -#: ../../Zotlabs/Module/Connedit.php:856 -msgid "" -"This connection is unreachable from this location. Location independence is " -"not supported by their network." +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:202 +msgid "Sign in to Hubzilla using a social account" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:860 -msgid "Connection requests will be approved without your interaction" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:207 +msgid "Social Authentication using your social media account" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:869 -msgid "This connection's primary address is" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:211 +msgid "" +"This app enables one or more social provider sign-in buttons on the login " +"page." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:870 -msgid "Available locations:" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:229 +msgid "Add an identity provider" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:876 -msgid "Connection Tools" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:256 +msgid "Enable " msgstr "" -#: ../../Zotlabs/Module/Connedit.php:878 -msgid "Slide to adjust your degree of friendship" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:263 +msgid "Key" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:880 -msgid "Slide to adjust your rating" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:263 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:268 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:284 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:297 +msgid "Word" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:881 ../../Zotlabs/Module/Connedit.php:886 -msgid "Optionally explain your rating" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:268 +msgid "Secret" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:883 -msgid "Custom Filter" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:297 +msgid "Add a custom provider" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:884 -msgid "Only import posts with this text" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:317 +msgid "Remove an identity provider" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:885 -msgid "Do not import posts with this text" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:327 +msgid "Social authentication" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:887 -msgid "This information is public!" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:366 +msgid "Error while saving provider settings" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:892 -msgid "Connection Pending Approval" +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:382 +msgid "Custom provider already exists" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:897 -#, php-format -msgid "" -"Please choose the profile you would like to display to %s when viewing your " -"profile securely." +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:399 +msgid "Social authentication settings saved." msgstr "" -#: ../../Zotlabs/Module/Connedit.php:904 -msgid "" -"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " -"individual settings. You can change those settings here but they wont have " -"any impact unless the inherited setting changes." +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:14 +msgid "Send your identity to all websites" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:905 -msgid "Last update:" +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20 +msgid "Sendzid App" msgstr "" -#: ../../Zotlabs/Module/Connedit.php:913 -msgid "Details" +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:32 +msgid "Send ZID" msgstr "" -#: ../../Zotlabs/Module/Notifications.php:55 ../../Zotlabs/Module/Notify.php:61 -msgid "No more system notifications." +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:106 +msgid "Photos imported" msgstr "" -#: ../../Zotlabs/Module/Notifications.php:59 ../../Zotlabs/Module/Notify.php:65 -msgid "System Notifications" +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:129 +msgid "Redmatrix Photo Album Import" msgstr "" -#: ../../Zotlabs/Module/Notifications.php:60 -#: ../../Zotlabs/Lib/ThreadItem.php:482 -msgid "Mark all seen" +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:130 +msgid "This will import all your Redmatrix photo albums to this channel." msgstr "" -#: ../../Zotlabs/Module/Layouts.php:186 -msgid "Comanche page description language help" +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:131 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:121 +msgid "Redmatrix Server base URL" msgstr "" -#: ../../Zotlabs/Module/Layouts.php:190 -msgid "Layout Description" +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:132 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:122 +msgid "Redmatrix Login Username" msgstr "" -#: ../../Zotlabs/Module/Layouts.php:195 -msgid "Download PDL file" +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:133 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:123 +msgid "Redmatrix Login Password" msgstr "" -#: ../../Zotlabs/Module/Locs.php:27 ../../Zotlabs/Module/Locs.php:66 -msgid "Location not found." +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134 +msgid "Import just this album" msgstr "" -#: ../../Zotlabs/Module/Locs.php:75 -msgid "Location lookup failed." +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134 +msgid "Leave blank to import all albums" msgstr "" -#: ../../Zotlabs/Module/Locs.php:79 -msgid "" -"Please select another location to become primary before removing the primary " -"location." +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135 +msgid "Maximum count to import" msgstr "" -#: ../../Zotlabs/Module/Locs.php:108 -msgid "Syncing locations" +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135 +msgid "0 or blank to import all available" msgstr "" -#: ../../Zotlabs/Module/Locs.php:117 -msgid "No locations found." +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:65 +msgid "Twitter settings updated." msgstr "" -#: ../../Zotlabs/Module/Locs.php:127 -msgid "Manage Channel Locations" +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78 +msgid "Twitter Crosspost Connector App" msgstr "" -#: ../../Zotlabs/Module/Locs.php:133 -msgid "Sync Now" +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:79 +msgid "Relay public posts to Twitter" msgstr "" -#: ../../Zotlabs/Module/Locs.php:134 -msgid "Please wait several minutes between consecutive operations." +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:103 +msgid "" +"No consumer key pair for Twitter found. Please contact your site " +"administrator." msgstr "" -#: ../../Zotlabs/Module/Locs.php:135 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:125 msgid "" -"When possible, drop a location by logging into that website/hub and removing " -"your channel." +"At this Hubzilla instance the Twitter plugin was enabled but you have not " +"yet connected your account to your Twitter account. To do so click the " +"button below to get a PIN from Twitter which you have to copy into the input " +"box below and submit the form. Only your public posts will " +"be posted to Twitter." msgstr "" -#: ../../Zotlabs/Module/Locs.php:136 -msgid "Use this form to drop the location if the hub is no longer operating." +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:127 +msgid "Log in with Twitter" msgstr "" -#: ../../Zotlabs/Module/Sources.php:41 -msgid "Failed to create source. No channel selected." +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:130 +msgid "Copy the PIN from Twitter here" msgstr "" -#: ../../Zotlabs/Module/Sources.php:57 -msgid "Source created." +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:152 +msgid "" +"Note: Due your privacy settings (Hide your profile " +"details from unknown viewers?) the link potentially included in public " +"postings relayed to Twitter will lead the visitor to a blank page informing " +"the visitor that the access to your profile has been restricted." msgstr "" -#: ../../Zotlabs/Module/Sources.php:70 -msgid "Source updated." +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157 +msgid "Twitter post length" msgstr "" -#: ../../Zotlabs/Module/Sources.php:88 -msgid "Sources App" +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157 +msgid "Maximum tweet length" msgstr "" -#: ../../Zotlabs/Module/Sources.php:89 -msgid "Automatically import channel content from other channels or feeds" +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +msgid "Send public postings to Twitter by default" msgstr "" -#: ../../Zotlabs/Module/Sources.php:101 -msgid "*" +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +msgid "" +"If enabled your public postings will be posted to the associated Twitter " +"account by default" msgstr "" -#: ../../Zotlabs/Module/Sources.php:107 ../../Zotlabs/Lib/Apps.php:368 -msgid "Channel Sources" +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:181 +msgid "Twitter Crosspost Connector" msgstr "" -#: ../../Zotlabs/Module/Sources.php:108 -msgid "Manage remote sources of content for your channel." +#: ../../extend/addon/hzaddons/twitter/twitter.php:109 +msgid "Post to Twitter" msgstr "" -#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:119 -msgid "New Source" +#: ../../extend/addon/hzaddons/donate/donate.php:21 +msgid "Project Servers and Resources" msgstr "" -#: ../../Zotlabs/Module/Sources.php:120 ../../Zotlabs/Module/Sources.php:154 +#: ../../extend/addon/hzaddons/donate/donate.php:22 +msgid "Project Creator and Tech Lead" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:49 msgid "" -"Import all or selected content from the following channel into this channel " -"and distribute it according to your channel settings." +"And the hundreds of other people and organisations who helped make the " +"Hubzilla possible." msgstr "" -#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 -msgid "Only import content with these words (one per line)" +#: ../../extend/addon/hzaddons/donate/donate.php:52 +msgid "" +"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving " +"their time and expertise - and often paying out of pocket for services they " +"share with others." msgstr "" -#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 -msgid "Leave blank to import all public content" +#: ../../extend/addon/hzaddons/donate/donate.php:53 +msgid "" +"There is no corporate funding and no ads, and we do not collect and sell " +"your personal information. (We don't control your personal information - " +"you do.)" msgstr "" -#: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:161 -msgid "Channel Name" +#: ../../extend/addon/hzaddons/donate/donate.php:54 +msgid "" +"Help support our ground-breaking work in decentralisation, web identity, and " +"privacy." msgstr "" -#: ../../Zotlabs/Module/Sources.php:123 ../../Zotlabs/Module/Sources.php:158 +#: ../../extend/addon/hzaddons/donate/donate.php:56 msgid "" -"Add the following categories to posts imported from this source (comma " -"separated)" +"Your donations keep servers and services running and also helps us to " +"provide innovative new features and continued development." msgstr "" -#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 -msgid "Resend posts with this channel as author" +#: ../../extend/addon/hzaddons/donate/donate.php:59 +msgid "Donate" msgstr "" -#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 -msgid "Copyrights may apply" +#: ../../extend/addon/hzaddons/donate/donate.php:61 +msgid "" +"Choose a project, developer, or public hub to support with a one-time " +"donation" msgstr "" -#: ../../Zotlabs/Module/Sources.php:144 ../../Zotlabs/Module/Sources.php:174 -msgid "Source not found." +#: ../../extend/addon/hzaddons/donate/donate.php:62 +msgid "Donate Now" msgstr "" -#: ../../Zotlabs/Module/Sources.php:151 -msgid "Edit Source" +#: ../../extend/addon/hzaddons/donate/donate.php:63 +msgid "" +"Or become a project sponsor (Hubzilla Project only)" msgstr "" -#: ../../Zotlabs/Module/Sources.php:152 -msgid "Delete Source" +#: ../../extend/addon/hzaddons/donate/donate.php:64 +msgid "" +"Please indicate if you would like your first name or full name (or nothing) " +"to appear in our sponsor listing" msgstr "" -#: ../../Zotlabs/Module/Sources.php:182 -msgid "Source removed" +#: ../../extend/addon/hzaddons/donate/donate.php:65 +msgid "Sponsor" msgstr "" -#: ../../Zotlabs/Module/Sources.php:184 -msgid "Unable to remove source." +#: ../../extend/addon/hzaddons/donate/donate.php:68 +msgid "Special thanks to: " msgstr "" -#: ../../Zotlabs/Module/Rbmark.php:94 -msgid "Select a bookmark folder" +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:26 +msgid "Dreamwidth Crosspost Connector Settings saved." msgstr "" -#: ../../Zotlabs/Module/Rbmark.php:99 -msgid "Save Bookmark" +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:39 +msgid "Dreamwidth Crosspost Connector App" msgstr "" -#: ../../Zotlabs/Module/Rbmark.php:100 -msgid "URL of bookmark" +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:40 +msgid "Relay public posts to Dreamwidth" msgstr "" -#: ../../Zotlabs/Module/Rbmark.php:105 -msgid "Or enter new bookmark folder name" +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:53 +msgid "Dreamwidth username" msgstr "" -#: ../../Zotlabs/Zot/Auth.php:152 -msgid "" -"Remote authentication blocked. You are logged into this site locally. Please " -"logout and retry." +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:57 +msgid "Dreamwidth password" msgstr "" -#: ../../Zotlabs/Lib/AccessList.php:28 -msgid "" -"A deleted list with this name was revived. Existing item permissions " -"may apply to this list and any future members. If this is " -"not what you intended, please create another list with a different name." +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +msgid "Post to Dreamwidth by default" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:69 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:98 +msgid "Link description (default:" msgstr "" -#: ../../Zotlabs/Lib/AccessList.php:286 -msgid "Add new connections to this access list" +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:77 +msgid "Dreamwidth Crosspost Connector" msgstr "" -#: ../../Zotlabs/Lib/AccessList.php:331 -msgid "Lists" +#: ../../extend/addon/hzaddons/dwpost/dwpost.php:49 +msgid "Post to Dreamwidth" msgstr "" -#: ../../Zotlabs/Lib/AccessList.php:332 -msgid "Edit list" +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:21 +msgid "nofed Settings saved." msgstr "" -#: ../../Zotlabs/Lib/AccessList.php:333 -msgid "Create new list" +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33 +msgid "No Federation App" msgstr "" -#: ../../Zotlabs/Lib/AccessList.php:334 -msgid "Channels not in any access list" +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:34 +msgid "" +"Prevent posting from being federated to anybody. It will exist only on your " +"channel page." msgstr "" -#: ../../Zotlabs/Lib/Permcat.php:82 -msgctxt "permcat" -msgid "default" +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +msgid "Federate posts by default" msgstr "" -#: ../../Zotlabs/Lib/Permcat.php:133 -msgctxt "permcat" -msgid "follower" +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:50 +msgid "No Federation" msgstr "" -#: ../../Zotlabs/Lib/Permcat.php:137 -msgctxt "permcat" -msgid "contributor" +#: ../../extend/addon/hzaddons/nofed/nofed.php:47 +msgid "Federate" msgstr "" -#: ../../Zotlabs/Lib/Permcat.php:141 -msgctxt "permcat" -msgid "publisher" +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:15 +msgid "WYSIWYG status editor" msgstr "" -#: ../../Zotlabs/Lib/Activity.php:2110 -#, php-format -msgid "Likes %1$s's %2$s" +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26 +msgid "WYSIWYG Status App" msgstr "" -#: ../../Zotlabs/Lib/Activity.php:2113 -#, php-format -msgid "Doesn't like %1$s's %2$s" +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:34 +msgid "WYSIWYG Status" msgstr "" -#: ../../Zotlabs/Lib/Activity.php:2119 -#, php-format -msgid "Will attend %s's event" +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:27 +msgid "No server specified" msgstr "" -#: ../../Zotlabs/Lib/Activity.php:2122 -#, php-format -msgid "Will not attend %s's event" +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:73 +msgid "Posts imported" msgstr "" -#: ../../Zotlabs/Lib/Activity.php:2125 -#, php-format -msgid "May attend %s's event" +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:113 +msgid "Files imported" msgstr "" -#: ../../Zotlabs/Lib/Activity.php:2128 -#, php-format -msgid "May not attend %s's event" +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:122 +msgid "" +"This addon app copies existing content and file storage to a cloned/copied " +"channel. Once the app is installed, visit the newly installed app. This will " +"allow you to set the location of your original channel and an optional date " +"range of files/conversations to copy." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:60 -msgid "$Projectname Notification" +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:136 +msgid "" +"This will import all your conversations and cloud files from a cloned " +"channel on another server. This may take a while if you have lots of posts " +"and or files." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:63 -msgid "Thank You," +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +msgid "Include posts" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:66 -#, php-format -msgid "This email was sent by %1$s at %2$s." +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +msgid "Conversations, Articles, Cards, and other posted content" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:67 -#, php-format -msgid "" -"To stop receiving these messages, please adjust your Notification Settings " -"at %s" +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +msgid "Include files" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:68 -#, php-format -msgid "To stop receiving these messages, please adjust your %s." +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +msgid "Files, Photos and other cloud storage" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:123 -#, php-format -msgid "%s " +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:139 +msgid "Original Server base URL" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:127 -#, php-format -msgid "[$Projectname:Notify] New mail received at %s" +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:48 +msgid "Your channel has been upgraded to $Projectname version" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:129 -#, php-format -msgid "%1$s sent you a new private message at %2$s." +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:50 +msgid "Please have a look at the" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:130 -#, php-format -msgid "%1$s sent you %2$s." +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:52 +msgid "git history" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:130 -msgid "a private message" +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:54 +msgid "change log" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:131 -#, php-format -msgid "Please visit %s to view and/or reply to your private messages." +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:55 +msgid "for further info." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:144 -msgid "commented on" +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:60 +msgid "Upgrade Info" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:157 -msgid "liked" +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:64 +msgid "Do not show this again" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:160 -msgid "disliked" +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:22 +msgid "pageheader Settings saved." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:165 -msgid "voted on" +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34 +msgid "Page Header App" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:208 -#, php-format -msgid "%1$s %2$s [zrl=%3$s]a %4$s[/zrl]" +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:35 +msgid "Inserts a page header" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:216 -#, php-format -msgid "%1$s %2$s [zrl=%3$s]%4$s's %5$s[/zrl]" +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:43 +msgid "Message to display on every page on this server" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:225 -#, php-format -msgid "%1$s %2$s [zrl=%3$s]your %4$s[/zrl]" +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:51 +msgid "Page Header" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:237 -#, php-format -msgid "[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s" +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:21 +msgid "Who viewed my channel/profile" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:239 -#, php-format -msgid "[$Projectname:Notify] Comment to conversation #%1$d by %2$s" +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:25 +msgid "Recent Channel/Profile Viewers" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:240 -#, php-format -msgid "%1$s commented on an item/conversation you have been following." +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:36 +msgid "No entries." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:243 ../../Zotlabs/Lib/Enotify.php:324 -#: ../../Zotlabs/Lib/Enotify.php:340 ../../Zotlabs/Lib/Enotify.php:365 -#: ../../Zotlabs/Lib/Enotify.php:382 ../../Zotlabs/Lib/Enotify.php:395 -#, php-format -msgid "Please visit %s to view and/or reply to the conversation." +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:39 +msgid "Messages" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:247 ../../Zotlabs/Lib/Enotify.php:248 -#, php-format -msgid "Please visit %s to approve or reject this comment." +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:52 +msgid "message" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:306 -#, php-format -msgid "%1$s liked [zrl=%2$s]your %3$s[/zrl]" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:92 +msgid "Message recalled." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:320 -#, php-format -msgid "[$Projectname:Notify] Like received to conversation #%1$d by %2$s" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:105 +msgid "Conversation removed." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:321 -#, php-format -msgid "%1$s liked an item/conversation you created." +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:120 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:241 +msgid "Expires YYYY-MM-DD HH:MM" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:332 -#, php-format -msgid "[$Projectname:Notify] %s posted to your profile wall" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:148 +msgid "Requested channel is not in this network" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:334 -#, php-format -msgid "%1$s posted to your profile wall at %2$s" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:156 +msgid "Send Private Message" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:336 -#, php-format -msgid "%1$s posted to [zrl=%2$s]your wall[/zrl]" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:157 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:300 +msgid "To:" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:359 -#, php-format -msgid "[$Projectname:Notify] %s tagged you" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:160 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:302 +msgid "Subject:" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:360 -#, php-format -msgid "%1$s tagged you at %2$s" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:165 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:308 +msgid "Attach file" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:361 -#, php-format -msgid "%1$s [zrl=%2$s]tagged you[/zrl]." +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:167 +msgid "Send" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:372 -#, php-format -msgid "[$Projectname:Notify] %1$s poked you" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:271 +msgid "Delete message" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:373 -#, php-format -msgid "%1$s poked you at %2$s" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:272 +msgid "Delivery report" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:374 -#, php-format -msgid "%1$s [zrl=%2$s]poked you[/zrl]." +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:273 +msgid "Recall message" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:389 -#, php-format -msgid "[$Projectname:Notify] %s tagged your post" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:275 +msgid "Message has been recalled." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:390 -#, php-format -msgid "%1$s tagged your post at %2$s" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:293 +msgid "Delete Conversation" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:391 -#, php-format -msgid "%1$s tagged [zrl=%2$s]your post[/zrl]" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:295 +msgid "" +"No secure communications available. You may be able to " +"respond from the sender's profile page." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:402 -msgid "[$Projectname:Notify] Introduction received" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:299 +msgid "Send Reply" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:403 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:304 #, php-format -msgid "You've received an new connection request from '%1$s' at %2$s" +msgid "Your message for %s (%s):" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:404 -#, php-format -msgid "You've received [zrl=%1$s]a new connection request[/zrl] from %2$s." +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:384 +msgid "Unable to lookup recipient." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:407 ../../Zotlabs/Lib/Enotify.php:425 -#, php-format -msgid "You may visit their profile at %s" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:391 +msgid "Unable to communicate with requested channel." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:409 -#, php-format -msgid "Please visit %s to approve or reject the connection request." +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:398 +msgid "Cannot verify requested channel." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:416 -msgid "[$Projectname:Notify] Friend suggestion received" +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:416 +msgid "Selected channel has private message restrictions. Send failed." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:417 -#, php-format -msgid "You've received a friend suggestion from '%1$s' at %2$s" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:50 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:128 +msgid "System defaults:" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:418 -#, php-format -msgid "You've received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s." +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54 +msgid "Preferred Clipart IDs" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:423 -msgid "Name:" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54 +msgid "List of preferred clipart ids. These will be shown first." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:424 -msgid "Photo:" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55 +msgid "Default Search Term" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:427 -#, php-format -msgid "Please visit %s to approve or reject the suggestion." +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55 +msgid "The default search term. These will be shown second." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:652 -msgid "[$Projectname:Notify]" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56 +msgid "Return After" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:820 -msgid "created a new poll" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56 +msgid "Page to load after image selection." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:820 -msgid "created a new post" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:59 +msgid "Profile List" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:821 -#, php-format -msgid "voted on %s's poll" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61 +msgid "Order of Preferred" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:821 -#, php-format -msgid "commented on %s's post" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61 +msgid "Sort order of preferred clipart ids." msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:825 -#, php-format -msgid "repeated %s's post" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:62 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:68 +msgid "Newest first" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:837 -#, php-format -msgid "edited a post dated %s" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:65 +msgid "As entered" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:841 -#, php-format -msgid "edited a comment dated %s" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67 +msgid "Order of other" msgstr "" -#: ../../Zotlabs/Lib/Enotify.php:970 -msgid "created an event" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67 +msgid "Sort order of other clipart ids." msgstr "" -#: ../../Zotlabs/Lib/Connect.php:271 -msgid "error saving data" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:69 +msgid "Most downloaded first" msgstr "" -#: ../../Zotlabs/Lib/Chatroom.php:25 -msgid "Missing room name" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:70 +msgid "Most liked first" msgstr "" -#: ../../Zotlabs/Lib/Chatroom.php:34 -msgid "Duplicate room name" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72 +msgid "Preferred IDs Message" msgstr "" -#: ../../Zotlabs/Lib/Chatroom.php:84 ../../Zotlabs/Lib/Chatroom.php:92 -msgid "Invalid room specifier." +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72 +msgid "Message to display above preferred results." msgstr "" -#: ../../Zotlabs/Lib/Chatroom.php:124 -msgid "Room not found." +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78 +msgid "Uploaded by: " msgstr "" -#: ../../Zotlabs/Lib/Chatroom.php:145 -msgid "Room is full" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78 +msgid "Drawn by: " msgstr "" -#: ../../Zotlabs/Lib/NativeWiki.php:145 -msgid "Wiki updated successfully" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:182 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:194 +msgid "Use this image" msgstr "" -#: ../../Zotlabs/Lib/NativeWiki.php:199 -msgid "Wiki files deleted successfully" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:192 +msgid "Or select from a free OpenClipart.org image:" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:323 -msgid "Apps" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:195 +msgid "Search Term" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:324 -msgid "Affinity Tool" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:232 +msgid "Unknown error. Please try again later." msgstr "" -#: ../../Zotlabs/Lib/Apps.php:327 -msgid "Site Admin" +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:308 +msgid "Profile photo updated successfully." msgstr "" -#: ../../Zotlabs/Lib/Apps.php:331 -msgid "Content Filter" +#: ../../extend/addon/hzaddons/gallery/gallery.php:43 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:136 +msgid "Gallery" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:334 -msgid "Remote Diagnostics" +#: ../../extend/addon/hzaddons/gallery/gallery.php:46 +msgid "Photo Gallery" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:335 -msgid "Suggest Channels" +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58 +msgid "Gallery App" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:338 -msgid "Stream" +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:59 +msgid "A simple gallery for your photo albums" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:349 -msgid "Mail" +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35 +msgid "Smileybutton App" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:352 -msgid "Chat" +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:36 +msgid "Adds a smileybutton to the jot editor" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:354 -msgid "Probe" +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +msgid "Hide the button and show the smilies directly." msgstr "" -#: ../../Zotlabs/Lib/Apps.php:355 -msgid "Suggest" +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:52 +msgid "Smileybutton Settings" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:356 -msgid "Random Channel" +#: ../../extend/addon/hzaddons/rtof/rtof.php:51 +msgid "Post to Friendica" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:357 -msgid "Invite" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:24 +msgid "Friendica Crosspost Connector Settings saved." msgstr "" -#: ../../Zotlabs/Lib/Apps.php:360 ../../Zotlabs/Storage/Browser.php:400 -msgid "Post" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36 +msgid "Friendica Crosspost Connector App" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:365 -msgid "Notifications" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:37 +msgid "Relay public postings to a connected Friendica account" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:366 -msgid "Order Apps" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +msgid "Send public postings to Friendica by default" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:367 -msgid "CardDAV" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53 +msgid "Friendica API Path" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:369 -msgid "Guest Access" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57 +msgid "Friendica login name" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:371 -msgid "OAuth Apps Manager" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:61 +msgid "Friendica password" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:372 -msgid "OAuth2 Apps Manager" +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:69 +msgid "Friendica Crosspost Connector" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:373 -msgid "PDL Editor" +#: ../../extend/addon/hzaddons/logrot/logrot.php:36 +msgid "Logfile archive directory" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:376 -msgid "My Chatrooms" +#: ../../extend/addon/hzaddons/logrot/logrot.php:36 +msgid "Directory to store rotated logs" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:377 -msgid "Channel Export" +#: ../../extend/addon/hzaddons/logrot/logrot.php:37 +msgid "Logfile size in bytes before rotating" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:554 -msgid "Purchase" +#: ../../extend/addon/hzaddons/logrot/logrot.php:38 +msgid "Number of logfiles to retain" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:559 -msgid "Undelete" +#: ../../extend/addon/hzaddons/wppost/wppost.php:46 +msgid "Post to WordPress" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:569 -msgid "Add to app-tray" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:30 +msgid "Wordpress Settings saved." msgstr "" -#: ../../Zotlabs/Lib/Apps.php:570 -msgid "Remove from app-tray" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:43 +msgid "Wordpress Post App" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:571 -msgid "Pin to navbar" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:44 +msgid "Post to WordPress or anything else which uses the wordpress XMLRPC API" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:572 -msgid "Unpin from navbar" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:69 +msgid "WordPress username" msgstr "" -#: ../../Zotlabs/Lib/Techlevels.php:10 -msgid "0. Beginner/Basic" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:73 +msgid "WordPress password" msgstr "" -#: ../../Zotlabs/Lib/Techlevels.php:11 -msgid "1. Novice - not skilled but willing to learn" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:77 +msgid "WordPress API URL" msgstr "" -#: ../../Zotlabs/Lib/Techlevels.php:12 -msgid "2. Intermediate - somewhat comfortable" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:78 +msgid "Typically https://your-blog.tld/xmlrpc.php" msgstr "" -#: ../../Zotlabs/Lib/Techlevels.php:13 -msgid "3. Advanced - very comfortable" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:81 +msgid "WordPress blogid" msgstr "" -#: ../../Zotlabs/Lib/Techlevels.php:14 -msgid "4. Expert - I can write computer code" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82 +msgid "For multi-user sites such as wordpress.com, otherwise leave blank" msgstr "" -#: ../../Zotlabs/Lib/Techlevels.php:15 -msgid "5. Wizard - I probably know more than you do" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +msgid "Post to WordPress by default" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:42 -#: ../../Zotlabs/Lib/NativeWikiPage.php:94 -msgid "(No Title)" +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +msgid "Forward comments (requires hubzilla_wp plugin)" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:109 -msgid "Wiki page create failed." +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:106 +msgid "Wordpress Post" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:122 -msgid "Wiki not found." +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:22 +msgid "" +"Allow magic authentication only to websites of your immediate connections" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:133 -msgid "Destination name already exists" +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33 +msgid "Authchoose App" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:166 -#: ../../Zotlabs/Lib/NativeWikiPage.php:362 -msgid "Page not found" +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:39 +msgid "Authchoose" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:197 -msgid "Error reading page content" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19 +msgid "bitchslap" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:353 -#: ../../Zotlabs/Lib/NativeWikiPage.php:402 -#: ../../Zotlabs/Lib/NativeWikiPage.php:469 -#: ../../Zotlabs/Lib/NativeWikiPage.php:510 -msgid "Error reading wiki" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19 +msgid "bitchslapped" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:390 -msgid "Page update failed." +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20 +msgid "shag" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:424 -msgid "Nothing deleted" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20 +msgid "shagged" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:490 -msgid "Compare: object not found." +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21 +msgid "patent" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:496 -msgid "Page updated" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21 +msgid "patented" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:499 -msgid "Untitled" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22 +msgid "hug" msgstr "" -#: ../../Zotlabs/Lib/NativeWikiPage.php:505 -msgid "Wiki resource_id required for git commit" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22 +msgid "hugged" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:130 -msgid "Privacy conflict. Discretion advised." +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23 +msgid "murder" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:174 ../../Zotlabs/Storage/Browser.php:362 -msgid "Admin Delete" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23 +msgid "murdered" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:319 -msgid "Reply on this comment" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24 +msgid "worship" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:319 -msgid "reply" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24 +msgid "worshipped" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:319 -msgid "Reply to" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25 +msgid "kiss" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:339 -msgid "Delivery Report" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25 +msgid "kissed" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:358 -#, php-format -msgid "%d comment" -msgid_plural "%d comments" -msgstr[0] "" -msgstr[1] "" - -#: ../../Zotlabs/Lib/ThreadItem.php:359 -#, php-format -msgid "%d unseen" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26 +msgid "tempt" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:412 -msgid "to" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26 +msgid "tempted" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:414 -msgid "Wall-to-Wall" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27 +msgid "raise eyebrows at" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:415 -msgid "via Wall-To-Wall:" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27 +msgid "raised their eyebrows at" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:442 -msgid "Attend" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28 +msgid "insult" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:460 -msgid "Go to previous comment" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28 +msgid "insulted" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:473 -msgid "Add to Calendar" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29 +msgid "praise" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:831 -msgid "Image" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29 +msgid "praised" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:833 -msgid "Insert Link" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30 +msgid "be dubious of" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:834 -msgid "Video" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30 +msgid "was dubious of" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:844 -msgid "Your full name (required)" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31 +msgid "eat" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:845 -msgid "Your email address (required)" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31 +msgid "ate" msgstr "" -#: ../../Zotlabs/Lib/ThreadItem.php:846 -msgid "Your website URL (optional)" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32 +msgid "giggle and fawn at" msgstr "" -#: ../../Zotlabs/Lib/DB_Upgrade.php:67 -msgid "Source code of failed update: " +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32 +msgid "giggled and fawned at" msgstr "" -#: ../../Zotlabs/Lib/DB_Upgrade.php:88 -#, php-format -msgid "Update Error at %s" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33 +msgid "doubt" msgstr "" -#: ../../Zotlabs/Lib/DB_Upgrade.php:94 -#, php-format -msgid "Update %s failed. See error logs." +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33 +msgid "doubted" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:108 -msgid "Public" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34 +msgid "glare" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:109 -msgid "Anybody in the $Projectname network" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34 +msgid "glared at" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:110 -#, php-format -msgid "Any account on %s" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35 +msgid "fuck" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:111 -msgid "Any of my connections" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35 +msgid "fucked" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:112 -msgid "Only connections I specifically allow" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36 +msgid "bonk" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:113 -msgid "Anybody authenticated (could include visitors from other networks)" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36 +msgid "bonked" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:114 -msgid "Any connections including those who haven't yet been approved" +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37 +msgid "declare undying love for" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:150 -msgid "" -"This is your default setting for the audience of your normal stream, and " -"posts." +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37 +msgid "declared undying love for" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:151 -msgid "" -"This is your default setting for who can view your default channel profile" +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:34 +msgid "New registration" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:152 -msgid "This is your default setting for who can view your connections" +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:42 +#, php-format +msgid "Message sent to %s. New account registration: %s" msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:153 -msgid "" -"This is your default setting for who can view your file storage and photos" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:40 +msgid "Pump.io Settings saved." msgstr "" -#: ../../Zotlabs/Lib/PermissionDescription.php:154 -msgid "This is your default setting for the audience of your webpages" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53 +msgid "Pump.io Crosspost Connector App" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:287 -msgid "Social Networking" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:54 +msgid "Relay public posts to pump.io" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:288 -msgid "Social - Federation" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73 +msgid "Pump.io servername" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:289 -msgid "Social - Mostly Public" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73 +msgid "Without \"http://\" or \"https://\"" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:290 -msgid "Social - Restricted" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77 +msgid "Pump.io username" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:291 -msgid "Social - Private" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77 +msgid "Without the servername" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:294 -msgid "Community Forum" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:88 +msgid "You are not authenticated to pumpio" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:295 -msgid "Forum - Mostly Public" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:90 +msgid "(Re-)Authenticate your pump.io connection" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:296 -msgid "Forum - Restricted" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +msgid "Post to pump.io by default" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:297 -msgid "Forum - Private" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +msgid "Should posts be public" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:300 -msgid "Feed Republish" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +msgid "Mirror all public posts" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:301 -msgid "Feed - Mostly Public" +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:112 +msgid "Pump.io Crosspost Connector" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:302 -msgid "Feed - Restricted" +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:152 +msgid "You are now authenticated to pumpio." msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:305 -msgid "Special Purpose" +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:153 +msgid "return to the featured settings page" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:306 -msgid "Special - Celebrity/Soapbox" +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:168 +msgid "Post to Pump.io" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:307 -msgid "Special - Group Repository" +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24 +msgid "NSA Bait App" msgstr "" -#: ../../Zotlabs/Access/PermissionRoles.php:311 -msgid "Custom/Expert Mode" +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:26 +msgid "Make yourself a political target" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:56 -msgid "Can view my channel stream and posts" +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:15 +msgid "Add some colour to tag clouds" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:57 -msgid "Can send me their channel stream and posts" +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26 +msgid "Rainbow Tag App" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:58 -msgid "Can view my default channel profile" +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:34 +msgid "Rainbow Tag" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:59 -msgid "Can view my connections" +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:19 +msgid "Send test email" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:60 -msgid "Can view my file storage and photos" +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:66 +msgid "Mail sent." msgstr "" -#: ../../Zotlabs/Access/Permissions.php:61 -msgid "Can upload/modify my file storage and photos" +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:68 +msgid "Sending of mail failed." msgstr "" -#: ../../Zotlabs/Access/Permissions.php:62 -msgid "Can view my channel webpages" +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:77 +msgid "Mail Test" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:63 -msgid "Can view my wiki pages" +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:119 +msgid "Redmatrix File Storage Import" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:64 -msgid "Can create/edit my channel webpages" +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:120 +msgid "This will import all your Redmatrix cloud files to this channel." msgstr "" -#: ../../Zotlabs/Access/Permissions.php:65 -msgid "Can write to my wiki pages" +#: ../../extend/addon/hzaddons/mdpost/mdpost.php:42 +msgid "Use markdown for editing posts" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:66 -msgid "Can post on my channel (wall) page" +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:22 +msgid "Fuzzloc Settings updated." msgstr "" -#: ../../Zotlabs/Access/Permissions.php:67 -msgid "Can comment on or like my posts" +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34 +msgid "Fuzzy Location App" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:68 -msgid "Can send me private mail messages" +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:35 +msgid "" +"Blur your precise location if your channel uses browser location mapping" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:69 -msgid "Can like/dislike profiles and profile things" +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:40 +msgid "Minimum offset in meters" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:70 -msgid "Can forward to all my channel connections via ! mentions in posts" +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:44 +msgid "Maximum offset in meters" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:71 -msgid "Can chat with me" +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:53 +msgid "Fuzzy Location" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:72 -msgid "Can source my public posts in derived channels" +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50 +msgid "Startpage App" msgstr "" -#: ../../Zotlabs/Access/Permissions.php:73 -msgid "Can administer my channel" +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:51 +msgid "Set a preferred page to load on login from home page" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:292 -msgid "Change filename to" +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62 +msgid "Page to load after login" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:302 ../../Zotlabs/Storage/Browser.php:383 -msgid "Select a target location" +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62 +msgid "" +"Examples: "apps", "network?f=&gid=37" (privacy " +"collection), "channel" or "notifications/system" (leave " +"blank for default network page (grid)." msgstr "" -#: ../../Zotlabs/Storage/Browser.php:303 ../../Zotlabs/Storage/Browser.php:384 -msgid "Copy to target location" +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:70 +msgid "Startpage" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:304 ../../Zotlabs/Storage/Browser.php:382 -msgid "Set permissions for all files and sub folders" +#: ../../view/theme/redbasic/php/config.php:16 +#: ../../view/theme/redbasic/php/config.php:19 +msgid "Focus (Hubzilla default)" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:305 -msgid "Notify your contacts about this file" +#: ../../view/theme/redbasic/php/config.php:98 +msgid "Theme settings" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:344 -msgid "File category" +#: ../../view/theme/redbasic/php/config.php:99 +msgid "Narrow navbar" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:355 -msgid "Total" +#: ../../view/theme/redbasic/php/config.php:100 +msgid "Navigation bar background color" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:357 -msgid "Shared" +#: ../../view/theme/redbasic/php/config.php:101 +msgid "Navigation bar icon color " msgstr "" -#: ../../Zotlabs/Storage/Browser.php:359 -msgid "Add Files" +#: ../../view/theme/redbasic/php/config.php:102 +msgid "Navigation bar active icon color " msgstr "" -#: ../../Zotlabs/Storage/Browser.php:374 -msgid "parent" +#: ../../view/theme/redbasic/php/config.php:103 +msgid "Link color" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:392 -msgid "Select All" +#: ../../view/theme/redbasic/php/config.php:104 +msgid "Set font-color for banner" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:393 -msgid "Bulk Actions" +#: ../../view/theme/redbasic/php/config.php:105 +msgid "Set the background color" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:394 -msgid "Adjust Permissions" +#: ../../view/theme/redbasic/php/config.php:106 +msgid "Set the background image" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:395 -msgid "Move or Copy" +#: ../../view/theme/redbasic/php/config.php:107 +msgid "Set the background color of items" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:398 -msgid "Info" +#: ../../view/theme/redbasic/php/config.php:108 +msgid "Set the background color of comments" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:399 -msgid "Rename" +#: ../../view/theme/redbasic/php/config.php:109 +msgid "Set font-size for the entire application" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:401 -msgid "Attachment BBcode" +#: ../../view/theme/redbasic/php/config.php:109 +msgid "Examples: 1rem, 100%, 16px" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:402 -msgid "Embed BBcode" +#: ../../view/theme/redbasic/php/config.php:110 +msgid "Set font-color for posts and comments" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:403 -msgid "Link BBcode" +#: ../../view/theme/redbasic/php/config.php:111 +msgid "Set radius of corners" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:473 -#, php-format -msgid "You are using %1$s of your available file storage." +#: ../../view/theme/redbasic/php/config.php:111 +msgid "Example: 4px" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:478 -#, php-format -msgid "You are using %1$s of %2$s available file storage. (%3$s%)" +#: ../../view/theme/redbasic/php/config.php:112 +msgid "Set shadow depth of photos" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:489 -msgid "WARNING:" +#: ../../view/theme/redbasic/php/config.php:113 +msgid "Set maximum width of content region in pixel" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:530 -msgid "Create new folder" +#: ../../view/theme/redbasic/php/config.php:113 +msgid "Leave empty for default width" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:532 -msgid "Upload file" +#: ../../view/theme/redbasic/php/config.php:114 +msgid "Set size of conversation author photo" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:544 -msgid "Drop files here to immediately upload" +#: ../../view/theme/redbasic/php/config.php:115 +msgid "Set size of followup author photos" msgstr "" -#: ../../Zotlabs/Storage/Browser.php:547 -msgid "" -"You can select files via the upload button or drop them right here or into " -"an existing folder." +#: ../../view/theme/redbasic/php/config.php:116 +msgid "Show advanced settings" msgstr "" -#: ../../boot.php:1678 +#: ../../boot.php:1684 msgid "Create an account to access services and applications" msgstr "" -#: ../../boot.php:1702 +#: ../../boot.php:1708 msgid "Login/Email" msgstr "" -#: ../../boot.php:1703 +#: ../../boot.php:1709 msgid "Password" msgstr "" -#: ../../boot.php:1704 +#: ../../boot.php:1710 msgid "Remember me" msgstr "" -#: ../../boot.php:1707 +#: ../../boot.php:1713 msgid "Forgot your password?" msgstr "" -#: ../../boot.php:2576 +#: ../../boot.php:2582 #, php-format msgid "[$Projectname] Website SSL error for %s" msgstr "" -#: ../../boot.php:2581 +#: ../../boot.php:2587 msgid "Website SSL certificate is not valid. Please correct." msgstr "" -#: ../../boot.php:2697 +#: ../../boot.php:2703 #, php-format msgid "[$Projectname] Cron tasks not running on %s" msgstr "" -#: ../../boot.php:2702 +#: ../../boot.php:2708 msgid "Cron/Scheduled tasks not running." msgstr "" diff --git a/view/pl/cert_bad_eml.tpl b/view/pl/cert_bad_eml.tpl new file mode 100644 index 000000000..cd1a62251 --- /dev/null +++ b/view/pl/cert_bad_eml.tpl @@ -0,0 +1,19 @@ +Komunikat serwera WWW pod adresem {{$sitename}}; + +Rutynowa kontrola wskazuje, że certyfikat SSL dla tej witryny jest +nieważny. Twój serwis internetowy nie może w pełni uczestniczyć w Hubzilli +dopóki ten problem nie zostanie rozwiązany. Sprawdź swój certyfikat i swojego +dostawcę certyfikatu lub usługodawcę, aby upewnić się, że jest on "akceptowany +przez przeglądarkę” i prawidłowo zainstalowany. Certyfikaty z podpisem własnym +NIE SĄ OBSŁUGIWANE i NIE SĄ DOZWOLONE w Hubzilli. + +Sprawdzenie odbywa się poprzez pobranie adresu URL z Twojej witryny z włączonym +ścisłym sprawdzaniem SSL, a jeśli to się nie powiedzie, ponowne sprawdzenie z SSL +z kontrolą wyłączoną. Możliwe, że może to spowodować przejściowy komunikat błędu, +lecz jeśli ostatnio wprowadzono zmiany w konfiguracji lub jeśli otrzymujesz tę +wiadomość więcej niż raz, sprawdź swój certyfikat. + +Komunikat o błędzie to '{{$error}}'. + +Przepraszam za utrudnienia, + Twój serwer WWW na {{$siteurl}} \ No newline at end of file diff --git a/view/pl/cron_bad_eml.tpl b/view/pl/cron_bad_eml.tpl new file mode 100644 index 000000000..809499971 --- /dev/null +++ b/view/pl/cron_bad_eml.tpl @@ -0,0 +1,16 @@ +Komunikat serwera WWW pod adresem {{$sitename}}; + +Rutynowa kontrola wskazuje, że zaplanowane zadania konserwacyjne na tym +serwisie internetowym nie działają. Przejrzyj swoje zadania "cron" lub plik +równoważnego mechanizmu w systemie operacyjnym i upewnij się, że mechanizm +ten jest uruchomiony. Proszę zapoznać się z instrukcjami w pliku INSTALLm jeśli +widzisz tą wiadomość po raz pierwszy. Jeśli te zadania konserwacyjne działały +do tej pory normalnie, sprawdź, czy coś mogło się nie udać, ponieważ nie obecnie +nie działają. Kontrola ta przeprowadzana jest mniej więcej co trzy dni. + +Komunikat błędu brzmi: '{{$error}}'. + +Ostatnia pozytywna kontrola odbyła się '{{$lastdate}}'. + +Przepraszam za utrudnienia, + Twój serwer WWW na {{$siteurl}} \ No newline at end of file diff --git a/view/pl/hmessages.mo b/view/pl/hmessages.mo new file mode 100644 index 000000000..cbf6f399c Binary files /dev/null and b/view/pl/hmessages.mo differ diff --git a/view/pl/hmessages.po b/view/pl/hmessages.po new file mode 100644 index 000000000..10dfc3b0b --- /dev/null +++ b/view/pl/hmessages.po @@ -0,0 +1,16453 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-01-21 12:07+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Andrzej Budziński \n" +"Language-Team: \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 " +"|| n%100>14) ? 1 : 2);\n" +"X-Generator: Poedit 2.3\n" + +#: ../../Zotlabs/Access/Permissions.php:56 +msgid "Can view my channel stream and posts" +msgstr "Może wyświetlać strumień i posty z mojego kanału" + +#: ../../Zotlabs/Access/Permissions.php:57 +msgid "Can send me their channel stream and posts" +msgstr "Może przesyłać mi strumień swojego kanału i posty" + +#: ../../Zotlabs/Access/Permissions.php:58 +msgid "Can view my default channel profile" +msgstr "Może wyświetlać mój domyślny profil kanału" + +#: ../../Zotlabs/Access/Permissions.php:59 +msgid "Can view my connections" +msgstr "Może wyświetlać moje połączenia" + +#: ../../Zotlabs/Access/Permissions.php:60 +msgid "Can view my file storage and photos" +msgstr "Może wyświetlać moje przechowywane pliki i zdjęcia" + +#: ../../Zotlabs/Access/Permissions.php:61 +msgid "Can upload/modify my file storage and photos" +msgstr "Może przesyłać/modyfikować moje przechowywane pliki i zdjęcia" + +#: ../../Zotlabs/Access/Permissions.php:62 +msgid "Can view my channel webpages" +msgstr "Może wyświetlać strony internetowe mojego kanału" + +#: ../../Zotlabs/Access/Permissions.php:63 +msgid "Can view my wiki pages" +msgstr "Może przeglądać moje strony wiki" + +#: ../../Zotlabs/Access/Permissions.php:64 +msgid "Can create/edit my channel webpages" +msgstr "Może tworzyć/edytować strony internetowe mojego kanału" + +#: ../../Zotlabs/Access/Permissions.php:65 +msgid "Can write to my wiki pages" +msgstr "Może pisać na moich stronach wiki" + +#: ../../Zotlabs/Access/Permissions.php:66 +msgid "Can post on my channel (wall) page" +msgstr "Może publikować na stronie mojego kanału (tablicy)" + +#: ../../Zotlabs/Access/Permissions.php:67 +msgid "Can comment on or like my posts" +msgstr "Może komentować lub polubić moje posty" + +#: ../../Zotlabs/Access/Permissions.php:68 +msgid "Can send me private mail messages" +msgstr "Może wysyłać mi prywatne wiadomości e-mail" + +#: ../../Zotlabs/Access/Permissions.php:69 +msgid "Can like/dislike profiles and profile things" +msgstr "Może polubiać/dezaprobować profile i rzeczy w profilach" + +#: ../../Zotlabs/Access/Permissions.php:70 +msgid "Can forward to all my channel connections via ! mentions in posts" +msgstr "" +"Może przekazywać informacje do wszystkich moich połączeń kanałowych za " +"pośrednictwem! wzmianki w postach" + +#: ../../Zotlabs/Access/Permissions.php:71 +msgid "Can chat with me" +msgstr "Może ze mną rozmawiać" + +#: ../../Zotlabs/Access/Permissions.php:72 +msgid "Can source my public posts in derived channels" +msgstr "Może pozyskiwać moje publiczne posty w kanałach pochodnych" + +#: ../../Zotlabs/Access/Permissions.php:73 +msgid "Can administer my channel" +msgstr "Może zarządzać moim kanałem" + +#: ../../Zotlabs/Access/PermissionRoles.php:287 +msgid "Social Networking" +msgstr "Sieć społecznościowa" + +#: ../../Zotlabs/Access/PermissionRoles.php:288 +msgid "Social - Federation" +msgstr "Społecznościowy - federacyjny" + +#: ../../Zotlabs/Access/PermissionRoles.php:289 +msgid "Social - Mostly Public" +msgstr "Społecznościowy - głównie publiczny" + +#: ../../Zotlabs/Access/PermissionRoles.php:290 +msgid "Social - Restricted" +msgstr "Społecznościowy - ograniczony" + +#: ../../Zotlabs/Access/PermissionRoles.php:291 +msgid "Social - Private" +msgstr "Społecznościowy - prywatny" + +#: ../../Zotlabs/Access/PermissionRoles.php:294 +msgid "Community Forum" +msgstr "Forum społecznościowe" + +#: ../../Zotlabs/Access/PermissionRoles.php:295 +msgid "Forum - Mostly Public" +msgstr "Forum - głównie publiczne" + +#: ../../Zotlabs/Access/PermissionRoles.php:296 +msgid "Forum - Restricted" +msgstr "Forum - ograniczone" + +#: ../../Zotlabs/Access/PermissionRoles.php:297 +msgid "Forum - Private" +msgstr "Forum - prywatne" + +#: ../../Zotlabs/Access/PermissionRoles.php:300 +msgid "Feed Republish" +msgstr "Opublikuj ponownie kanał RSS" + +#: ../../Zotlabs/Access/PermissionRoles.php:301 +msgid "Feed - Mostly Public" +msgstr "Kanał RSS - głównie publiczny" + +#: ../../Zotlabs/Access/PermissionRoles.php:302 +msgid "Feed - Restricted" +msgstr "Kanał RSS - ograniczony" + +#: ../../Zotlabs/Access/PermissionRoles.php:305 +msgid "Special Purpose" +msgstr "Specjalnego celu" + +#: ../../Zotlabs/Access/PermissionRoles.php:306 +msgid "Special - Celebrity/Soapbox" +msgstr "Specjalne - celebryckie i mównice" + +#: ../../Zotlabs/Access/PermissionRoles.php:307 +msgid "Special - Group Repository" +msgstr "Specjalne - repozytorium grupowe" + +#: ../../Zotlabs/Access/PermissionRoles.php:310 +#: ../../Zotlabs/Module/Cdav.php:1384 ../../Zotlabs/Module/Profiles.php:797 +#: ../../Zotlabs/Module/Connedit.php:927 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 ../../include/selectors.php:115 +#: ../../include/selectors.php:151 ../../include/connections.php:741 +#: ../../include/connections.php:748 ../../include/event.php:1429 +#: ../../include/event.php:1436 +msgid "Other" +msgstr "Inny" + +#: ../../Zotlabs/Access/PermissionRoles.php:311 +msgid "Custom/Expert Mode" +msgstr "Tryb niestandardowy/ekspercki" + +#: ../../Zotlabs/Module/Authtest.php:16 ../../Zotlabs/Module/Pdledit.php:35 +#: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Events.php:277 +#: ../../Zotlabs/Module/Bookmarks.php:70 ../../Zotlabs/Module/Webpages.php:133 +#: ../../Zotlabs/Module/Profiles.php:200 ../../Zotlabs/Module/Profiles.php:637 +#: ../../Zotlabs/Module/Like.php:230 ../../Zotlabs/Module/Defperms.php:182 +#: ../../Zotlabs/Module/Layouts.php:71 ../../Zotlabs/Module/Layouts.php:78 +#: ../../Zotlabs/Module/Layouts.php:89 ../../Zotlabs/Module/Group.php:15 +#: ../../Zotlabs/Module/Group.php:31 ../../Zotlabs/Module/Appman.php:87 +#: ../../Zotlabs/Module/Message.php:18 ../../Zotlabs/Module/Moderate.php:15 +#: ../../Zotlabs/Module/New_channel.php:105 +#: ../../Zotlabs/Module/New_channel.php:130 +#: ../../Zotlabs/Module/Filestorage.php:20 +#: ../../Zotlabs/Module/Filestorage.php:78 +#: ../../Zotlabs/Module/Filestorage.php:96 +#: ../../Zotlabs/Module/Filestorage.php:119 +#: ../../Zotlabs/Module/Filestorage.php:165 +#: ../../Zotlabs/Module/Card_edit.php:51 +#: ../../Zotlabs/Module/Viewconnections.php:28 +#: ../../Zotlabs/Module/Viewconnections.php:33 ../../Zotlabs/Module/Wiki.php:59 +#: ../../Zotlabs/Module/Wiki.php:285 ../../Zotlabs/Module/Wiki.php:428 +#: ../../Zotlabs/Module/Blocks.php:73 ../../Zotlabs/Module/Blocks.php:80 +#: ../../Zotlabs/Module/Locs.php:100 ../../Zotlabs/Module/Connedit.php:396 +#: ../../Zotlabs/Module/Profile_photo.php:338 +#: ../../Zotlabs/Module/Profile_photo.php:351 +#: ../../Zotlabs/Module/Sharedwithme.php:19 +#: ../../Zotlabs/Module/Editlayout.php:67 +#: ../../Zotlabs/Module/Editlayout.php:90 ../../Zotlabs/Module/Manage.php:10 +#: ../../Zotlabs/Module/Item.php:485 ../../Zotlabs/Module/Item.php:504 +#: ../../Zotlabs/Module/Item.php:514 ../../Zotlabs/Module/Item.php:1442 +#: ../../Zotlabs/Module/Rate.php:113 ../../Zotlabs/Module/Page.php:34 +#: ../../Zotlabs/Module/Page.php:133 ../../Zotlabs/Module/Achievements.php:34 +#: ../../Zotlabs/Module/Regmod.php:20 ../../Zotlabs/Module/Editblock.php:67 +#: ../../Zotlabs/Module/Chat.php:113 ../../Zotlabs/Module/Chat.php:118 +#: ../../Zotlabs/Module/Vote.php:19 ../../Zotlabs/Module/Display.php:425 +#: ../../Zotlabs/Module/Photos.php:71 ../../Zotlabs/Module/Channel.php:177 +#: ../../Zotlabs/Module/Channel.php:332 ../../Zotlabs/Module/Channel.php:371 +#: ../../Zotlabs/Module/Cards.php:86 ../../Zotlabs/Module/Connections.php:32 +#: ../../Zotlabs/Module/Editpost.php:17 ../../Zotlabs/Module/Block.php:24 +#: ../../Zotlabs/Module/Block.php:74 ../../Zotlabs/Module/Common.php:38 +#: ../../Zotlabs/Module/Editwebpage.php:68 +#: ../../Zotlabs/Module/Editwebpage.php:89 +#: ../../Zotlabs/Module/Editwebpage.php:107 +#: ../../Zotlabs/Module/Editwebpage.php:121 ../../Zotlabs/Module/Profile.php:85 +#: ../../Zotlabs/Module/Profile.php:101 +#: ../../Zotlabs/Module/Article_edit.php:51 ../../Zotlabs/Module/Thing.php:282 +#: ../../Zotlabs/Module/Thing.php:302 ../../Zotlabs/Module/Thing.php:343 +#: ../../Zotlabs/Module/Suggest.php:32 +#: ../../Zotlabs/Module/Notifications.php:11 +#: ../../Zotlabs/Module/Articles.php:89 ../../Zotlabs/Module/Setup.php:206 +#: ../../Zotlabs/Module/Mitem.php:129 ../../Zotlabs/Module/Mood.php:126 +#: ../../Zotlabs/Module/Register.php:80 +#: ../../Zotlabs/Module/Channel_calendar.php:230 +#: ../../Zotlabs/Module/Invite.php:21 ../../Zotlabs/Module/Invite.php:102 +#: ../../Zotlabs/Module/Service_limits.php:11 +#: ../../Zotlabs/Module/Cover_photo.php:341 +#: ../../Zotlabs/Module/Cover_photo.php:354 ../../Zotlabs/Module/Menu.php:130 +#: ../../Zotlabs/Module/Menu.php:141 ../../Zotlabs/Module/Sources.php:80 +#: ../../Zotlabs/Module/Poke.php:157 ../../Zotlabs/Module/Network.php:19 +#: ../../Zotlabs/Module/Attach_edit.php:90 +#: ../../Zotlabs/Module/Attach_edit.php:99 +#: ../../Zotlabs/Module/Attach_edit.php:106 +#: ../../Zotlabs/Module/Settings.php:59 ../../Zotlabs/Module/Viewsrc.php:19 +#: ../../Zotlabs/Web/WebServer.php:116 ../../Zotlabs/Lib/Chatroom.php:135 +#: ../../include/photos.php:27 ../../include/attach.php:156 +#: ../../include/attach.php:205 ../../include/attach.php:278 +#: ../../include/attach.php:329 ../../include/attach.php:424 +#: ../../include/attach.php:438 ../../include/attach.php:445 +#: ../../include/attach.php:527 ../../include/attach.php:1091 +#: ../../include/attach.php:1164 ../../include/attach.php:1327 +#: ../../include/items.php:3996 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:53 +#: ../../extend/addon/hzaddons/keepout/keepout.php:36 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:25 +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:44 +msgid "Permission denied." +msgstr "Dostęp zabroniony." + +#: ../../Zotlabs/Module/Pdledit.php:27 +msgid "Layout updated." +msgstr "Zaktualizowano układ." + +#: ../../Zotlabs/Module/Pdledit.php:43 +msgid "PDL Editor App" +msgstr "Aplikacja PDL Editor" + +#: ../../Zotlabs/Module/Pdledit.php:43 ../../Zotlabs/Module/Cdav.php:876 +#: ../../Zotlabs/Module/Bookmarks.php:78 ../../Zotlabs/Module/Webpages.php:48 +#: ../../Zotlabs/Module/Defperms.php:190 ../../Zotlabs/Module/Pubstream.php:20 +#: ../../Zotlabs/Module/Group.php:107 ../../Zotlabs/Module/Oauth.php:100 +#: ../../Zotlabs/Module/Oauth2.php:106 ../../Zotlabs/Module/Wiki.php:52 +#: ../../Zotlabs/Module/Chat.php:100 ../../Zotlabs/Module/Uexport.php:61 +#: ../../Zotlabs/Module/Cards.php:51 ../../Zotlabs/Module/Affinity.php:52 +#: ../../Zotlabs/Module/Randprof.php:29 ../../Zotlabs/Module/Suggest.php:40 +#: ../../Zotlabs/Module/Notes.php:57 ../../Zotlabs/Module/Tokens.php:99 +#: ../../Zotlabs/Module/Articles.php:52 ../../Zotlabs/Module/Mood.php:134 +#: ../../Zotlabs/Module/Permcats.php:63 ../../Zotlabs/Module/Probe.php:18 +#: ../../Zotlabs/Module/Invite.php:110 ../../Zotlabs/Module/Lang.php:17 +#: ../../Zotlabs/Module/Sources.php:88 ../../Zotlabs/Module/Poke.php:165 +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22 +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50 +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:58 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:23 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:38 +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35 +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20 +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33 +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35 +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:39 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21 +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:43 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21 +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34 +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50 +msgid "Not Installed" +msgstr "Nie zainstalowano" + +#: ../../Zotlabs/Module/Pdledit.php:44 +msgid "Provides the ability to edit system page layouts" +msgstr "Zapewnia możliwość edycji układów stron systemowych" + +#: ../../Zotlabs/Module/Pdledit.php:57 ../../Zotlabs/Module/Pdledit.php:100 +msgid "Edit System Page Description" +msgstr "Edytuj opis strony systemowej" + +#: ../../Zotlabs/Module/Pdledit.php:78 +msgid "(modified)" +msgstr "(zmodyfikowany)" + +#: ../../Zotlabs/Module/Pdledit.php:78 ../../Zotlabs/Module/Lostpass.php:133 +msgid "Reset" +msgstr "Resetuj" + +#: ../../Zotlabs/Module/Pdledit.php:95 +msgid "Layout not found." +msgstr "Nie znaleziono układu." + +#: ../../Zotlabs/Module/Pdledit.php:101 +msgid "Module Name:" +msgstr "Nazwa modułu:" + +#: ../../Zotlabs/Module/Pdledit.php:102 +msgid "Layout Help" +msgstr "Pomoc dotycząca układu" + +#: ../../Zotlabs/Module/Pdledit.php:103 +msgid "Edit another layout" +msgstr "Edytuj inny układ" + +#: ../../Zotlabs/Module/Pdledit.php:104 +msgid "System layout" +msgstr "Układ systemowy" + +#: ../../Zotlabs/Module/Pdledit.php:108 ../../Zotlabs/Module/Events.php:501 +#: ../../Zotlabs/Module/Profiles.php:725 ../../Zotlabs/Module/Import.php:645 +#: ../../Zotlabs/Module/Defperms.php:266 ../../Zotlabs/Module/Group.php:151 +#: ../../Zotlabs/Module/Group.php:167 ../../Zotlabs/Module/Appman.php:155 +#: ../../Zotlabs/Module/Oauth.php:111 ../../Zotlabs/Module/Import_items.php:129 +#: ../../Zotlabs/Module/Connect.php:107 +#: ../../Zotlabs/Module/Filestorage.php:208 ../../Zotlabs/Module/Oauth2.php:116 +#: ../../Zotlabs/Module/Wiki.php:215 ../../Zotlabs/Module/Locs.php:132 +#: ../../Zotlabs/Module/Connedit.php:896 ../../Zotlabs/Module/Rate.php:166 +#: ../../Zotlabs/Module/Xchan.php:15 ../../Zotlabs/Module/Chat.php:209 +#: ../../Zotlabs/Module/Chat.php:248 ../../Zotlabs/Module/Photos.php:1058 +#: ../../Zotlabs/Module/Photos.php:1098 ../../Zotlabs/Module/Photos.php:1216 +#: ../../Zotlabs/Module/Editpost.php:86 ../../Zotlabs/Module/Affinity.php:87 +#: ../../Zotlabs/Module/Pconfig.php:116 +#: ../../Zotlabs/Module/Admin/Themes.php:158 +#: ../../Zotlabs/Module/Admin/Security.php:120 +#: ../../Zotlabs/Module/Admin/Accounts.php:168 +#: ../../Zotlabs/Module/Admin/Features.php:66 +#: ../../Zotlabs/Module/Admin/Channels.php:147 +#: ../../Zotlabs/Module/Admin/Logs.php:84 +#: ../../Zotlabs/Module/Admin/Account_edit.php:73 +#: ../../Zotlabs/Module/Admin/Addons.php:442 +#: ../../Zotlabs/Module/Admin/Site.php:293 +#: ../../Zotlabs/Module/Admin/Profs.php:178 ../../Zotlabs/Module/Thing.php:328 +#: ../../Zotlabs/Module/Thing.php:381 +#: ../../Zotlabs/Module/Email_validation.php:40 +#: ../../Zotlabs/Module/Tokens.php:188 ../../Zotlabs/Module/Setup.php:304 +#: ../../Zotlabs/Module/Setup.php:344 ../../Zotlabs/Module/Mitem.php:259 +#: ../../Zotlabs/Module/Mood.php:158 ../../Zotlabs/Module/Permcats.php:129 +#: ../../Zotlabs/Module/Settings/Account.php:103 +#: ../../Zotlabs/Module/Settings/Events.php:42 +#: ../../Zotlabs/Module/Settings/Profiles.php:52 +#: ../../Zotlabs/Module/Settings/Editor.php:42 +#: ../../Zotlabs/Module/Settings/Features.php:48 +#: ../../Zotlabs/Module/Settings/Manage.php:43 +#: ../../Zotlabs/Module/Settings/Display.php:188 +#: ../../Zotlabs/Module/Settings/Photos.php:42 +#: ../../Zotlabs/Module/Settings/Channel.php:495 +#: ../../Zotlabs/Module/Settings/Connections.php:42 +#: ../../Zotlabs/Module/Settings/Calendar.php:42 +#: ../../Zotlabs/Module/Settings/Directory.php:42 +#: ../../Zotlabs/Module/Settings/Channel_home.php:91 +#: ../../Zotlabs/Module/Settings/Network.php:62 +#: ../../Zotlabs/Module/Settings/Conversation.php:49 +#: ../../Zotlabs/Module/Invite.php:168 ../../Zotlabs/Module/Sources.php:125 +#: ../../Zotlabs/Module/Sources.php:162 ../../Zotlabs/Module/Poke.php:217 +#: ../../Zotlabs/Storage/Browser.php:382 ../../Zotlabs/Lib/ThreadItem.php:825 +#: ../../Zotlabs/Widget/Wiki_pages.php:42 +#: ../../Zotlabs/Widget/Wiki_pages.php:99 +#: ../../Zotlabs/Widget/Eventstools.php:16 ../../include/js_strings.php:22 +#: ../../extend/addon/hzaddons/irc/irc.php:45 +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:95 +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:57 +#: ../../extend/addon/hzaddons/piwik/piwik.php:95 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:143 +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:51 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:90 +#: ../../extend/addon/hzaddons/cart/cart.php:1376 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:312 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:412 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:643 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:410 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:248 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:132 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:142 +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:86 +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:100 +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:75 +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:155 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:82 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1461 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1520 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1639 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2742 +#: ../../extend/addon/hzaddons/workflow/Settings/Mod_WorkflowSettings.php:94 +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:70 +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:61 +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:67 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:70 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:602 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:193 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:251 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:306 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:65 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:72 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:262 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:330 +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:136 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:184 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:80 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:53 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:142 +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:54 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:310 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:53 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:55 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:72 +#: ../../extend/addon/hzaddons/logrot/logrot.php:35 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:109 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:115 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:100 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:124 +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:56 +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:73 +#: ../../view/theme/redbasic/php/config.php:94 +msgid "Submit" +msgstr "Zatwierdź" + +#: ../../Zotlabs/Module/Z6trans.php:19 +msgid "Update to Hubzilla 5.0 step 2" +msgstr "Zaktualizuj do Hubzilli 5.0 krok 2" + +#: ../../Zotlabs/Module/Z6trans.php:21 +msgid "To complete the update please run" +msgstr "Uruchom, aby zakończyć aktualizację" + +#: ../../Zotlabs/Module/Z6trans.php:23 +msgid "php util/z6convert.php" +msgstr "php util/z6convert.php" + +#: ../../Zotlabs/Module/Z6trans.php:25 +msgid "from the terminal." +msgstr "z terminala." + +#: ../../Zotlabs/Module/Dreport.php:10 ../../Zotlabs/Module/Dreport.php:82 +#: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Cloud.php:123 +#: ../../Zotlabs/Module/Like.php:332 ../../Zotlabs/Module/Group.php:99 +#: ../../Zotlabs/Module/Import_items.php:120 +#: ../../Zotlabs/Module/Subthread.php:86 ../../Zotlabs/Module/Share.php:72 +#: ../../Zotlabs/Web/WebServer.php:115 ../../include/items.php:439 +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:75 +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:119 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:109 +msgid "Permission denied" +msgstr "Dostęp zabroniony" + +#: ../../Zotlabs/Module/Dreport.php:59 +msgid "Invalid message" +msgstr "Nieprawidłowa wiadomość" + +#: ../../Zotlabs/Module/Dreport.php:93 +msgid "no results" +msgstr "brak wyników" + +#: ../../Zotlabs/Module/Dreport.php:107 +msgid "channel sync processed" +msgstr "synchronizacja kanałów została przetworzona" + +#: ../../Zotlabs/Module/Dreport.php:111 +msgid "queued" +msgstr "w kolejce" + +#: ../../Zotlabs/Module/Dreport.php:115 +msgid "posted" +msgstr "opublikowane" + +#: ../../Zotlabs/Module/Dreport.php:119 +msgid "accepted for delivery" +msgstr "przyjęty do dostawy" + +#: ../../Zotlabs/Module/Dreport.php:123 +msgid "updated" +msgstr "zaktualizowany" + +#: ../../Zotlabs/Module/Dreport.php:126 +msgid "update ignored" +msgstr "aktualizacja zignorowana" + +#: ../../Zotlabs/Module/Dreport.php:129 +msgid "permission denied" +msgstr "dostęp zabroniony" + +#: ../../Zotlabs/Module/Dreport.php:133 +msgid "recipient not found" +msgstr "nie znaleziono odbiorcy" + +#: ../../Zotlabs/Module/Dreport.php:136 +msgid "mail recalled" +msgstr "mail odwołany" + +#: ../../Zotlabs/Module/Dreport.php:139 +msgid "duplicate mail received" +msgstr "otrzymano powieloną wiadomość" + +#: ../../Zotlabs/Module/Dreport.php:142 +msgid "mail delivered" +msgstr "dostarczono pocztę" + +#: ../../Zotlabs/Module/Dreport.php:162 +#, php-format +msgid "Delivery report for %1$s" +msgstr "Raport dostarczenia dla %1$s" + +#: ../../Zotlabs/Module/Dreport.php:166 ../../Zotlabs/Widget/Wiki_pages.php:41 +#: ../../Zotlabs/Widget/Wiki_pages.php:98 +msgid "Options" +msgstr "Opcje" + +#: ../../Zotlabs/Module/Dreport.php:167 +msgid "Redeliver" +msgstr "Dostarcz ponownie" + +#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63 +msgid "Invalid profile identifier." +msgstr "Nieprawidłowy identyfikator profilu." + +#: ../../Zotlabs/Module/Profperm.php:111 +msgid "Profile Visibility Editor" +msgstr "Edytor widoczności profilu" + +#: ../../Zotlabs/Module/Profperm.php:113 ../../Zotlabs/Lib/Apps.php:362 +#: ../../include/channel.php:1886 +msgid "Profile" +msgstr "Profil" + +#: ../../Zotlabs/Module/Profperm.php:115 +msgid "Click on a contact to add or remove." +msgstr "Kliknij kontakt, który chcesz dodać lub usunąć." + +#: ../../Zotlabs/Module/Profperm.php:124 +msgid "Visible To" +msgstr "Widoczne dla" + +#: ../../Zotlabs/Module/Profperm.php:140 +#: ../../Zotlabs/Module/Connections.php:217 +msgid "All Connections" +msgstr "Wszystkie połączenia" + +#: ../../Zotlabs/Module/Cloud.php:120 +msgid "Not found" +msgstr "Nie znaleziono" + +#: ../../Zotlabs/Module/Cloud.php:126 +msgid "Please refresh page" +msgstr "Odśwież stronę" + +#: ../../Zotlabs/Module/Cloud.php:129 +msgid "Unknown error" +msgstr "Nieznany błąd" + +#: ../../Zotlabs/Module/Authorize.php:17 +msgid "Unknown App" +msgstr "Aplikacja nieznana" + +#: ../../Zotlabs/Module/Authorize.php:29 +msgid "Authorize" +msgstr "Autoryzuj" + +#: ../../Zotlabs/Module/Authorize.php:30 +#, php-format +msgid "Do you authorize the app %s to access your channel data?" +msgstr "Czy zezwalasz aplikacji %s na dostęp do danych Twojego kanału?" + +#: ../../Zotlabs/Module/Authorize.php:32 ../../include/acl_selectors.php:146 +msgid "Allow" +msgstr "Zezwól" + +#: ../../Zotlabs/Module/Authorize.php:33 +#: ../../Zotlabs/Module/Admin/Accounts.php:174 +msgid "Deny" +msgstr "Zabroń" + +#: ../../Zotlabs/Module/Cdav.php:818 ../../Zotlabs/Module/Events.php:28 +msgid "Calendar entries imported." +msgstr "Zaimportowano wpisy kalendarza." + +#: ../../Zotlabs/Module/Cdav.php:820 ../../Zotlabs/Module/Events.php:30 +msgid "No calendar entries found." +msgstr "Nie znaleziono wpisów kalendarza." + +#: ../../Zotlabs/Module/Cdav.php:876 +msgid "CardDAV App" +msgstr "Aplikacja CardDAV" + +#: ../../Zotlabs/Module/Cdav.php:877 +msgid "CalDAV capable addressbook" +msgstr "Książka adresowa z obsługą CalDAV" + +#: ../../Zotlabs/Module/Cdav.php:943 ../../Zotlabs/Module/Cal.php:167 +#: ../../Zotlabs/Module/Channel_calendar.php:393 +msgid "Link to source" +msgstr "Link do źródła" + +#: ../../Zotlabs/Module/Cdav.php:1009 ../../Zotlabs/Module/Events.php:468 +msgid "Event title" +msgstr "Tytuł wydarzenia" + +#: ../../Zotlabs/Module/Cdav.php:1010 ../../Zotlabs/Module/Events.php:474 +msgid "Start date and time" +msgstr "Data i godzina rozpoczęcia" + +#: ../../Zotlabs/Module/Cdav.php:1011 +msgid "End date and time" +msgstr "Data i godzina zakończenia" + +#: ../../Zotlabs/Module/Cdav.php:1012 ../../Zotlabs/Module/Events.php:497 +msgid "Timezone:" +msgstr "Strefa czasowa:" + +#: ../../Zotlabs/Module/Cdav.php:1014 ../../Zotlabs/Module/Events.php:481 +#: ../../Zotlabs/Module/Appman.php:145 ../../Zotlabs/Module/Rbmark.php:101 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:173 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:655 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:260 +msgid "Description" +msgstr "Opis" + +#: ../../Zotlabs/Module/Cdav.php:1015 ../../Zotlabs/Module/Events.php:483 +#: ../../Zotlabs/Module/Profiles.php:511 ../../Zotlabs/Module/Profiles.php:736 +#: ../../Zotlabs/Module/Locs.php:128 ../../Zotlabs/Module/Pubsites.php:53 +#: ../../include/js_strings.php:25 +msgid "Location" +msgstr "Lokalizacja" + +#: ../../Zotlabs/Module/Cdav.php:1035 ../../Zotlabs/Module/Events.php:697 +#: ../../Zotlabs/Module/Events.php:706 ../../Zotlabs/Module/Photos.php:947 +#: ../../Zotlabs/Module/Cal.php:205 +msgid "Previous" +msgstr "Poprzedni" + +#: ../../Zotlabs/Module/Cdav.php:1036 ../../Zotlabs/Module/Events.php:698 +#: ../../Zotlabs/Module/Events.php:707 ../../Zotlabs/Module/Photos.php:956 +#: ../../Zotlabs/Module/Cal.php:206 ../../Zotlabs/Module/Setup.php:260 +msgid "Next" +msgstr "Nastęþny" + +#: ../../Zotlabs/Module/Cdav.php:1037 ../../Zotlabs/Module/Events.php:708 +#: ../../Zotlabs/Module/Cal.php:207 +msgid "Today" +msgstr "Dzisiaj" + +#: ../../Zotlabs/Module/Cdav.php:1038 ../../Zotlabs/Module/Events.php:703 +msgid "Month" +msgstr "Miesiąc" + +#: ../../Zotlabs/Module/Cdav.php:1039 ../../Zotlabs/Module/Events.php:704 +msgid "Week" +msgstr "Tydzień" + +#: ../../Zotlabs/Module/Cdav.php:1040 ../../Zotlabs/Module/Events.php:705 +msgid "Day" +msgstr "Dzień" + +#: ../../Zotlabs/Module/Cdav.php:1041 +msgid "List month" +msgstr "Wymień miesiąc" + +#: ../../Zotlabs/Module/Cdav.php:1042 +msgid "List week" +msgstr "Wymień tydzień" + +#: ../../Zotlabs/Module/Cdav.php:1043 +msgid "List day" +msgstr "Wymień dzień" + +#: ../../Zotlabs/Module/Cdav.php:1051 +msgid "More" +msgstr "Więcej" + +#: ../../Zotlabs/Module/Cdav.php:1052 +msgid "Less" +msgstr "Mniej" + +#: ../../Zotlabs/Module/Cdav.php:1053 ../../Zotlabs/Module/Cdav.php:1388 +#: ../../Zotlabs/Module/Profiles.php:801 ../../Zotlabs/Module/Oauth.php:53 +#: ../../Zotlabs/Module/Oauth.php:137 ../../Zotlabs/Module/Oauth2.php:58 +#: ../../Zotlabs/Module/Oauth2.php:144 ../../Zotlabs/Module/Connedit.php:931 +#: ../../Zotlabs/Module/Admin/Addons.php:457 ../../Zotlabs/Lib/Apps.php:536 +msgid "Update" +msgstr "Zaktualizuj" + +#: ../../Zotlabs/Module/Cdav.php:1054 +msgid "Select calendar" +msgstr "Wybierz kalendarz" + +#: ../../Zotlabs/Module/Cdav.php:1055 ../../Zotlabs/Widget/Cdav.php:143 +msgid "Channel Calendars" +msgstr "Kalendarze kanału" + +#: ../../Zotlabs/Module/Cdav.php:1055 ../../Zotlabs/Widget/Cdav.php:129 +#: ../../Zotlabs/Widget/Cdav.php:143 +msgid "CalDAV Calendars" +msgstr "Kalendarze CalDAV" + +#: ../../Zotlabs/Module/Cdav.php:1056 ../../Zotlabs/Module/Cdav.php:1389 +#: ../../Zotlabs/Module/Webpages.php:257 ../../Zotlabs/Module/Profiles.php:802 +#: ../../Zotlabs/Module/Oauth.php:174 ../../Zotlabs/Module/Card_edit.php:129 +#: ../../Zotlabs/Module/Oauth2.php:195 ../../Zotlabs/Module/Blocks.php:162 +#: ../../Zotlabs/Module/Connedit.php:660 ../../Zotlabs/Module/Connedit.php:932 +#: ../../Zotlabs/Module/Editlayout.php:138 +#: ../../Zotlabs/Module/Editblock.php:139 ../../Zotlabs/Module/Photos.php:1179 +#: ../../Zotlabs/Module/Connections.php:328 +#: ../../Zotlabs/Module/Editwebpage.php:167 +#: ../../Zotlabs/Module/Article_edit.php:128 +#: ../../Zotlabs/Module/Admin/Accounts.php:175 +#: ../../Zotlabs/Module/Admin/Channels.php:149 +#: ../../Zotlabs/Module/Admin/Profs.php:176 ../../Zotlabs/Module/Thing.php:269 +#: ../../Zotlabs/Storage/Browser.php:384 ../../Zotlabs/Lib/Apps.php:558 +#: ../../Zotlabs/Lib/ThreadItem.php:170 ../../include/conversation.php:730 +#: ../../include/conversation.php:775 +msgid "Delete" +msgstr "Usuń" + +#: ../../Zotlabs/Module/Cdav.php:1057 +msgid "Delete all" +msgstr "Usuń wszystko" + +#: ../../Zotlabs/Module/Cdav.php:1058 ../../Zotlabs/Module/Cdav.php:1390 +#: ../../Zotlabs/Module/Filer.php:56 ../../Zotlabs/Module/Profiles.php:803 +#: ../../Zotlabs/Module/Oauth.php:112 ../../Zotlabs/Module/Oauth.php:138 +#: ../../Zotlabs/Module/Card_edit.php:131 ../../Zotlabs/Module/Oauth2.php:117 +#: ../../Zotlabs/Module/Oauth2.php:145 ../../Zotlabs/Module/Wiki.php:368 +#: ../../Zotlabs/Module/Wiki.php:401 ../../Zotlabs/Module/Fbrowser.php:66 +#: ../../Zotlabs/Module/Fbrowser.php:88 ../../Zotlabs/Module/Connedit.php:933 +#: ../../Zotlabs/Module/Profile_photo.php:507 +#: ../../Zotlabs/Module/Editlayout.php:140 +#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Editpost.php:110 +#: ../../Zotlabs/Module/Tagrm.php:15 ../../Zotlabs/Module/Tagrm.php:138 +#: ../../Zotlabs/Module/Editwebpage.php:169 +#: ../../Zotlabs/Module/Article_edit.php:130 +#: ../../Zotlabs/Module/Admin/Addons.php:427 +#: ../../Zotlabs/Module/Cover_photo.php:428 +#: ../../Zotlabs/Storage/Browser.php:383 ../../include/conversation.php:1458 +#: ../../include/conversation.php:1511 +#: ../../extend/addon/hzaddons/hsse/hsse.php:209 +#: ../../extend/addon/hzaddons/hsse/hsse.php:258 +msgid "Cancel" +msgstr "Anuluj" + +#: ../../Zotlabs/Module/Cdav.php:1059 ../../Zotlabs/Module/Cdav.php:1387 +#: ../../Zotlabs/Module/Webpages.php:254 ../../Zotlabs/Module/Profiles.php:800 +#: ../../Zotlabs/Module/Layouts.php:185 +#: ../../Zotlabs/Module/New_channel.php:189 ../../Zotlabs/Module/Blocks.php:159 +#: ../../Zotlabs/Module/Connedit.php:930 ../../Zotlabs/Module/Cards.php:113 +#: ../../Zotlabs/Module/Articles.php:117 ../../Zotlabs/Module/Menu.php:182 +#: ../../Zotlabs/Storage/Browser.php:365 ../../Zotlabs/Storage/Browser.php:538 +#: ../../Zotlabs/Widget/Cdav.php:140 ../../Zotlabs/Widget/Cdav.php:178 +msgid "Create" +msgstr "Utwórz" + +#: ../../Zotlabs/Module/Cdav.php:1060 +msgid "Sorry! Editing of recurrent events is not yet implemented." +msgstr "" +"Przepraszamy! Edycja powtarzających się wydarzeń nie została jeszcze " +"zaimplementowana." + +#: ../../Zotlabs/Module/Cdav.php:1070 ../../Zotlabs/Storage/Browser.php:293 +#: ../../Zotlabs/Storage/Browser.php:388 ../../Zotlabs/Storage/Browser.php:403 +#: ../../Zotlabs/Widget/Appcategories.php:43 +#: ../../include/contact_widgets.php:108 ../../include/contact_widgets.php:152 +#: ../../include/contact_widgets.php:197 ../../include/contact_widgets.php:232 +#: ../../include/taxonomy.php:418 ../../include/taxonomy.php:500 +#: ../../include/taxonomy.php:520 ../../include/taxonomy.php:541 +msgid "Categories" +msgstr "Kategorie" + +#: ../../Zotlabs/Module/Cdav.php:1372 ../../Zotlabs/Module/Group.php:155 +#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth.php:139 +#: ../../Zotlabs/Module/Oauth2.php:118 ../../Zotlabs/Module/Oauth2.php:146 +#: ../../Zotlabs/Module/Wiki.php:218 ../../Zotlabs/Module/Connedit.php:915 +#: ../../Zotlabs/Module/Sharedwithme.php:106 ../../Zotlabs/Module/Chat.php:257 +#: ../../Zotlabs/Module/Admin/Channels.php:159 +#: ../../Zotlabs/Storage/Browser.php:377 +#: ../../Zotlabs/Lib/NativeWikiPage.php:564 +#: ../../Zotlabs/Widget/Wiki_page_history.php:22 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:172 +msgid "Name" +msgstr "Nazwa" + +#: ../../Zotlabs/Module/Cdav.php:1373 ../../Zotlabs/Module/Connedit.php:916 +msgid "Organisation" +msgstr "Organizacja" + +#: ../../Zotlabs/Module/Cdav.php:1374 ../../Zotlabs/Module/Connedit.php:917 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2617 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2678 +msgid "Title" +msgstr "Tytuł" + +#: ../../Zotlabs/Module/Cdav.php:1375 ../../Zotlabs/Module/Profiles.php:788 +#: ../../Zotlabs/Module/Connedit.php:918 +msgid "Phone" +msgstr "Numer telefonu" + +#: ../../Zotlabs/Module/Cdav.php:1376 ../../Zotlabs/Module/Profiles.php:789 +#: ../../Zotlabs/Module/Connedit.php:919 +#: ../../Zotlabs/Module/Admin/Accounts.php:171 +#: ../../Zotlabs/Module/Admin/Accounts.php:183 ../../include/network.php:1737 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:56 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:57 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57 +msgid "Email" +msgstr "Adres e-mail" + +#: ../../Zotlabs/Module/Cdav.php:1377 ../../Zotlabs/Module/Profiles.php:790 +#: ../../Zotlabs/Module/Connedit.php:920 +msgid "Instant messenger" +msgstr "Komunikator internetowy" + +#: ../../Zotlabs/Module/Cdav.php:1378 ../../Zotlabs/Module/Profiles.php:791 +#: ../../Zotlabs/Module/Connedit.php:921 +msgid "Website" +msgstr "Strona internetowa" + +#: ../../Zotlabs/Module/Cdav.php:1379 ../../Zotlabs/Module/Profiles.php:504 +#: ../../Zotlabs/Module/Profiles.php:792 ../../Zotlabs/Module/Locs.php:129 +#: ../../Zotlabs/Module/Connedit.php:922 +#: ../../Zotlabs/Module/Admin/Channels.php:160 +msgid "Address" +msgstr "Adres" + +#: ../../Zotlabs/Module/Cdav.php:1380 ../../Zotlabs/Module/Profiles.php:793 +#: ../../Zotlabs/Module/Connedit.php:923 +msgid "Note" +msgstr "Uwagi" + +#: ../../Zotlabs/Module/Cdav.php:1381 ../../Zotlabs/Module/Profiles.php:794 +#: ../../Zotlabs/Module/Connedit.php:924 ../../include/connections.php:734 +#: ../../include/event.php:1422 +msgid "Mobile" +msgstr "Komórka" + +#: ../../Zotlabs/Module/Cdav.php:1382 ../../Zotlabs/Module/Profiles.php:795 +#: ../../Zotlabs/Module/Connedit.php:925 ../../include/connections.php:735 +#: ../../include/event.php:1423 +msgid "Home" +msgstr "Domowy" + +#: ../../Zotlabs/Module/Cdav.php:1383 ../../Zotlabs/Module/Profiles.php:796 +#: ../../Zotlabs/Module/Connedit.php:926 ../../include/connections.php:738 +#: ../../include/event.php:1426 +msgid "Work" +msgstr "Praca" + +#: ../../Zotlabs/Module/Cdav.php:1385 ../../Zotlabs/Module/Profiles.php:798 +#: ../../Zotlabs/Module/Connedit.php:928 +msgid "Add Contact" +msgstr "Dodaj kontakt" + +#: ../../Zotlabs/Module/Cdav.php:1386 ../../Zotlabs/Module/Profiles.php:799 +#: ../../Zotlabs/Module/Connedit.php:929 +msgid "Add Field" +msgstr "Dodaj pole" + +#: ../../Zotlabs/Module/Cdav.php:1391 ../../Zotlabs/Module/Connedit.php:934 +msgid "P.O. Box" +msgstr "Skrytka pocztowa" + +#: ../../Zotlabs/Module/Cdav.php:1392 ../../Zotlabs/Module/Connedit.php:935 +msgid "Additional" +msgstr "Dodatkowe informacje" + +#: ../../Zotlabs/Module/Cdav.php:1393 ../../Zotlabs/Module/Connedit.php:936 +msgid "Street" +msgstr "Ulica" + +#: ../../Zotlabs/Module/Cdav.php:1394 ../../Zotlabs/Module/Connedit.php:937 +msgid "Locality" +msgstr "Miejscowość" + +#: ../../Zotlabs/Module/Cdav.php:1395 ../../Zotlabs/Module/Connedit.php:938 +msgid "Region" +msgstr "Region" + +#: ../../Zotlabs/Module/Cdav.php:1396 ../../Zotlabs/Module/Connedit.php:939 +msgid "ZIP Code" +msgstr "Kod pocztowy" + +#: ../../Zotlabs/Module/Cdav.php:1397 ../../Zotlabs/Module/Profiles.php:759 +#: ../../Zotlabs/Module/Connedit.php:940 +msgid "Country" +msgstr "Państwo" + +#: ../../Zotlabs/Module/Cdav.php:1456 +msgid "Default Calendar" +msgstr "Domyślny kalendarz" + +#: ../../Zotlabs/Module/Cdav.php:1467 +msgid "Default Addressbook" +msgstr "Domyślna książka adresowa" + +#: ../../Zotlabs/Module/Api.php:74 ../../Zotlabs/Module/Api.php:95 +msgid "Authorize application connection" +msgstr "Autoryzuj połączenie aplikacji" + +#: ../../Zotlabs/Module/Api.php:75 +msgid "Return to your app and insert this Security Code:" +msgstr "Wróć do aplikacji i wprowadź ten kod bezpieczeństwa:" + +#: ../../Zotlabs/Module/Api.php:85 +msgid "Please login to continue." +msgstr "Proszę się zalogować, aby kontynuować." + +#: ../../Zotlabs/Module/Api.php:97 +msgid "" +"Do you want to authorize this application to access your posts and contacts, " +"and/or create new posts for you?" +msgstr "" +"Czy chcesz zezwolić tej aplikacji na dostęp do Twoich postów i kontaktów " +"albo tworzenie dla Ciebie nowych postów ?" + +#: ../../Zotlabs/Module/Api.php:98 ../../Zotlabs/Module/Events.php:478 +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Profiles.php:683 +#: ../../Zotlabs/Module/Import.php:634 ../../Zotlabs/Module/Import.php:638 +#: ../../Zotlabs/Module/Import.php:639 ../../Zotlabs/Module/Defperms.php:198 +#: ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Filestorage.php:211 ../../Zotlabs/Module/Wiki.php:227 +#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 +#: ../../Zotlabs/Module/Photos.php:673 ../../Zotlabs/Module/Admin/Site.php:261 +#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177 +#: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257 +#: ../../Zotlabs/Module/Settings/Display.php:88 +#: ../../Zotlabs/Module/Settings/Channel.php:311 +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:311 +#: ../../Zotlabs/Storage/Browser.php:312 ../../Zotlabs/Storage/Browser.php:389 +#: ../../Zotlabs/Storage/Browser.php:391 ../../Zotlabs/Storage/Browser.php:552 +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:166 +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1466 +#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144 +#: ../../include/dir_fns.php:145 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +#: ../../extend/addon/hzaddons/cart/cart.php:1370 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:72 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:337 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:361 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:437 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:461 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:65 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:649 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:653 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:88 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:96 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:61 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:73 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:214 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +#: ../../view/theme/redbasic/php/config.php:99 +#: ../../view/theme/redbasic/php/config.php:116 ../../boot.php:1710 +msgid "Yes" +msgstr "Tak" + +#: ../../Zotlabs/Module/Api.php:99 ../../Zotlabs/Module/Events.php:478 +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Profiles.php:683 +#: ../../Zotlabs/Module/Import.php:634 ../../Zotlabs/Module/Import.php:638 +#: ../../Zotlabs/Module/Import.php:639 ../../Zotlabs/Module/Defperms.php:198 +#: ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Filestorage.php:211 ../../Zotlabs/Module/Wiki.php:227 +#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 +#: ../../Zotlabs/Module/Connedit.php:788 ../../Zotlabs/Module/Photos.php:673 +#: ../../Zotlabs/Module/Admin/Site.php:259 ../../Zotlabs/Module/Mitem.php:176 +#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:256 +#: ../../Zotlabs/Module/Mitem.php:257 +#: ../../Zotlabs/Module/Settings/Display.php:88 +#: ../../Zotlabs/Module/Settings/Channel.php:311 +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:311 +#: ../../Zotlabs/Storage/Browser.php:312 ../../Zotlabs/Storage/Browser.php:389 +#: ../../Zotlabs/Storage/Browser.php:391 ../../Zotlabs/Storage/Browser.php:552 +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:166 +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1466 +#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144 +#: ../../include/dir_fns.php:145 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +#: ../../extend/addon/hzaddons/cart/cart.php:1370 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:72 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:338 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:362 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:438 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:462 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:65 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:649 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:653 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:88 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:96 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:61 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:73 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:214 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +#: ../../view/theme/redbasic/php/config.php:99 +#: ../../view/theme/redbasic/php/config.php:116 ../../boot.php:1710 +msgid "No" +msgstr "Nie" + +#: ../../Zotlabs/Module/Dirsearch.php:28 ../../Zotlabs/Module/Regdir.php:52 +msgid "This site is not a directory server" +msgstr "Ta witryna nie jest serwerem katalogów" + +#: ../../Zotlabs/Module/Dirsearch.php:37 +msgid "This directory server requires an access token" +msgstr "Ten serwer katalogowy wymaga tokenu dostępu" + +#: ../../Zotlabs/Module/Filer.php:53 +msgid "Enter a folder name" +msgstr "Wprowadź nazwę folderu" + +#: ../../Zotlabs/Module/Filer.php:53 +msgid "or select an existing folder (doubleclick)" +msgstr "lub wybierz istniejący folder (kliknij dwukrotnie)" + +#: ../../Zotlabs/Module/Filer.php:54 ../../Zotlabs/Module/Admin/Profs.php:94 +#: ../../Zotlabs/Module/Admin/Profs.php:114 ../../Zotlabs/Module/Rbmark.php:32 +#: ../../Zotlabs/Module/Rbmark.php:104 ../../Zotlabs/Widget/Notes.php:23 +#: ../../include/text.php:1151 ../../include/text.php:1163 +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:119 +msgid "Save" +msgstr "Zapisz" + +#: ../../Zotlabs/Module/Filer.php:55 ../../Zotlabs/Lib/ThreadItem.php:184 +msgid "Save to Folder" +msgstr "Zapisz do folderu" + +#: ../../Zotlabs/Module/Events.php:113 +#: ../../Zotlabs/Module/Channel_calendar.php:57 +msgid "Event can not end before it has started." +msgstr "Wydarzenie nie może zakończyć się przed rozpoczęciem." + +#: ../../Zotlabs/Module/Events.php:115 ../../Zotlabs/Module/Events.php:124 +#: ../../Zotlabs/Module/Events.php:146 +#: ../../Zotlabs/Module/Channel_calendar.php:59 +#: ../../Zotlabs/Module/Channel_calendar.php:67 +#: ../../Zotlabs/Module/Channel_calendar.php:84 +msgid "Unable to generate preview." +msgstr "Nie można wygenerować podglądu." + +#: ../../Zotlabs/Module/Events.php:122 +#: ../../Zotlabs/Module/Channel_calendar.php:65 +msgid "Event title and start time are required." +msgstr "Wymaga się wprowadzenie tytułu wydarzenia i godziny rozpoczęcia." + +#: ../../Zotlabs/Module/Events.php:144 ../../Zotlabs/Module/Events.php:271 +#: ../../Zotlabs/Module/Channel_calendar.php:82 +#: ../../Zotlabs/Module/Channel_calendar.php:224 +msgid "Event not found." +msgstr "Nie znaleziono wydarzenia." + +#: ../../Zotlabs/Module/Events.php:266 ../../Zotlabs/Module/Like.php:435 +#: ../../Zotlabs/Module/Tagger.php:75 +#: ../../Zotlabs/Module/Channel_calendar.php:219 +#: ../../include/conversation.php:132 ../../include/text.php:2255 +#: ../../include/event.php:1259 +msgid "event" +msgstr "wydarzenie" + +#: ../../Zotlabs/Module/Events.php:468 +msgid "Edit event title" +msgstr "Edytuj tytuł wydarzenia" + +#: ../../Zotlabs/Module/Events.php:468 ../../Zotlabs/Module/Events.php:473 +#: ../../Zotlabs/Module/Profiles.php:747 ../../Zotlabs/Module/Profiles.php:751 +#: ../../Zotlabs/Module/Appman.php:143 ../../Zotlabs/Module/Appman.php:144 +#: ../../include/datetime.php:211 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:334 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:358 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:434 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:458 +msgid "Required" +msgstr "Wymagane" + +#: ../../Zotlabs/Module/Events.php:470 +msgid "Categories (comma-separated list)" +msgstr "Kategorie (lista rozdzielana przecinkami)" + +#: ../../Zotlabs/Module/Events.php:471 +msgid "Edit Category" +msgstr "Edytuj kategorię" + +#: ../../Zotlabs/Module/Events.php:471 +msgid "Category" +msgstr "Kategoria" + +#: ../../Zotlabs/Module/Events.php:474 +msgid "Edit start date and time" +msgstr "Edytuj datę i godzinę rozpoczęcia" + +#: ../../Zotlabs/Module/Events.php:475 ../../Zotlabs/Module/Events.php:478 +msgid "Finish date and time are not known or not relevant" +msgstr "Data i godzina zakończenia nie są znane lub nie mają znaczenia" + +#: ../../Zotlabs/Module/Events.php:477 +msgid "Edit finish date and time" +msgstr "Edytuj datę i godzinę zakończenia" + +#: ../../Zotlabs/Module/Events.php:477 +msgid "Finish date and time" +msgstr "Data i godzina zakończenia" + +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Events.php:480 +msgid "Adjust for viewer timezone" +msgstr "Dostosuj do strefy czasowej widza" + +#: ../../Zotlabs/Module/Events.php:479 +msgid "" +"Important for events that happen in a particular place. Not practical for " +"global holidays." +msgstr "" +"Ważne dla wydarzeń, które mają miejsce w określonym miejscu. Niepraktyczne " +"na globalne święta." + +#: ../../Zotlabs/Module/Events.php:481 +msgid "Edit Description" +msgstr "Edytuj opis" + +#: ../../Zotlabs/Module/Events.php:483 +msgid "Edit Location" +msgstr "Edytuj lokalizację" + +#: ../../Zotlabs/Module/Events.php:486 ../../Zotlabs/Module/Webpages.php:262 +#: ../../Zotlabs/Module/Photos.php:1099 ../../Zotlabs/Lib/ThreadItem.php:835 +#: ../../include/conversation.php:1402 +#: ../../extend/addon/hzaddons/hsse/hsse.php:153 +msgid "Preview" +msgstr "Podgląd" + +#: ../../Zotlabs/Module/Events.php:487 ../../include/conversation.php:1478 +#: ../../extend/addon/hzaddons/hsse/hsse.php:225 +msgid "Permission settings" +msgstr "Ustawienia dostępu" + +#: ../../Zotlabs/Module/Events.php:502 +msgid "Advanced Options" +msgstr "Zaawansowane opcje" + +#: ../../Zotlabs/Module/Events.php:613 +msgid "l, F j" +msgstr "l, F j" + +#: ../../Zotlabs/Module/Events.php:641 +#: ../../Zotlabs/Module/Channel_calendar.php:371 +msgid "Edit event" +msgstr "Edytuj wydarzenie" + +#: ../../Zotlabs/Module/Events.php:643 +#: ../../Zotlabs/Module/Channel_calendar.php:373 +msgid "Delete event" +msgstr "Usuń wydarzenie" + +#: ../../Zotlabs/Module/Events.php:669 ../../include/text.php:2074 +msgid "Link to Source" +msgstr "Link do źródła" + +#: ../../Zotlabs/Module/Events.php:677 +#: ../../Zotlabs/Module/Channel_calendar.php:407 +msgid "calendar" +msgstr "kalendarz" + +#: ../../Zotlabs/Module/Events.php:696 +msgid "Edit Event" +msgstr "Edytuj wydarzenie" + +#: ../../Zotlabs/Module/Events.php:696 +msgid "Create Event" +msgstr "Utwórz wydarzenie" + +#: ../../Zotlabs/Module/Events.php:699 ../../include/channel.php:1889 +msgid "Export" +msgstr "Eksport" + +#: ../../Zotlabs/Module/Events.php:702 ../../Zotlabs/Module/Webpages.php:261 +#: ../../Zotlabs/Module/Layouts.php:198 ../../Zotlabs/Module/Wiki.php:213 +#: ../../Zotlabs/Module/Wiki.php:409 ../../Zotlabs/Module/Blocks.php:166 +#: ../../Zotlabs/Module/Pubsites.php:61 +msgid "View" +msgstr "Widok" + +#: ../../Zotlabs/Module/Events.php:739 +msgid "Event removed" +msgstr "Wydarzenie usunięte" + +#: ../../Zotlabs/Module/Events.php:742 +#: ../../Zotlabs/Module/Channel_calendar.php:494 +msgid "Failed to remove event" +msgstr "Nie udało się usunąć wydarzenia" + +#: ../../Zotlabs/Module/Help.php:23 +msgid "Documentation Search" +msgstr "Przeszukaj dokumentację" + +#: ../../Zotlabs/Module/Help.php:83 ../../include/nav.php:434 +msgid "About" +msgstr "O platformie Hubzilla" + +#: ../../Zotlabs/Module/Help.php:84 ../../Zotlabs/Module/Group.php:156 +msgid "Members" +msgstr "Dla członków" + +#: ../../Zotlabs/Module/Help.php:85 +msgid "Administrators" +msgstr "Dla administratorów" + +#: ../../Zotlabs/Module/Help.php:86 +msgid "Developers" +msgstr "Dla deweloperów" + +#: ../../Zotlabs/Module/Help.php:87 +msgid "Tutorials" +msgstr "Poradniki" + +#: ../../Zotlabs/Module/Help.php:98 +msgid "$Projectname Documentation" +msgstr "Dokumentacja $Projectname" + +#: ../../Zotlabs/Module/Help.php:99 +msgid "Contents" +msgstr "Spis treści" + +#: ../../Zotlabs/Module/Bookmarks.php:62 +msgid "Bookmark added" +msgstr "Dodano zakładkę" + +#: ../../Zotlabs/Module/Bookmarks.php:78 +msgid "Bookmarks App" +msgstr "Aplikacja Bookmarks" + +#: ../../Zotlabs/Module/Bookmarks.php:79 +msgid "Bookmark links from posts and manage them" +msgstr "Dodaj do zakładek linki z postów i zarządzaj nimi" + +#: ../../Zotlabs/Module/Bookmarks.php:92 +msgid "My Bookmarks" +msgstr "Moje zakładki" + +#: ../../Zotlabs/Module/Bookmarks.php:103 +msgid "My Connections Bookmarks" +msgstr "Moje zakładki połączeń" + +#: ../../Zotlabs/Module/Webpages.php:39 ../../Zotlabs/Module/Layouts.php:31 +#: ../../Zotlabs/Module/Connect.php:17 ../../Zotlabs/Module/Filestorage.php:59 +#: ../../Zotlabs/Module/Blocks.php:33 ../../Zotlabs/Module/Editlayout.php:31 +#: ../../Zotlabs/Module/Achievements.php:15 +#: ../../Zotlabs/Module/Editblock.php:31 ../../Zotlabs/Module/Cards.php:42 +#: ../../Zotlabs/Module/Editwebpage.php:32 ../../Zotlabs/Module/Profile.php:20 +#: ../../Zotlabs/Module/Articles.php:43 ../../Zotlabs/Module/Hcard.php:12 +#: ../../Zotlabs/Module/Menu.php:92 ../../include/channel.php:1439 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:49 +msgid "Requested profile is not available." +msgstr "Żądany profil nie jest dostępny." + +#: ../../Zotlabs/Module/Webpages.php:48 +msgid "Webpages App" +msgstr "Aplikacja Webpages" + +#: ../../Zotlabs/Module/Webpages.php:49 +msgid "Provide managed web pages on your channel" +msgstr "Udostępnij zarządzane strony internetowe na swoim kanale" + +#: ../../Zotlabs/Module/Webpages.php:69 +msgid "Import Webpage Elements" +msgstr "Importuj elementy strony internetowej" + +#: ../../Zotlabs/Module/Webpages.php:70 +msgid "Import selected" +msgstr "Importuj wybrane" + +#: ../../Zotlabs/Module/Webpages.php:93 +msgid "Export Webpage Elements" +msgstr "Eksportuj elementy strony internetowej" + +#: ../../Zotlabs/Module/Webpages.php:94 +msgid "Export selected" +msgstr "Eksportuj wybrane" + +#: ../../Zotlabs/Module/Webpages.php:252 ../../Zotlabs/Lib/Apps.php:341 +#: ../../include/nav.php:524 +msgid "Webpages" +msgstr "Witryny internetowe" + +#: ../../Zotlabs/Module/Webpages.php:255 ../../Zotlabs/Module/Layouts.php:193 +#: ../../Zotlabs/Module/Group.php:253 ../../Zotlabs/Module/Oauth.php:173 +#: ../../Zotlabs/Module/Card_edit.php:99 ../../Zotlabs/Module/Oauth2.php:194 +#: ../../Zotlabs/Module/Wiki.php:211 ../../Zotlabs/Module/Wiki.php:384 +#: ../../Zotlabs/Module/Blocks.php:160 ../../Zotlabs/Module/Editlayout.php:114 +#: ../../Zotlabs/Module/Editblock.php:114 +#: ../../Zotlabs/Module/Connections.php:320 +#: ../../Zotlabs/Module/Connections.php:362 +#: ../../Zotlabs/Module/Connections.php:382 +#: ../../Zotlabs/Module/Editwebpage.php:142 +#: ../../Zotlabs/Module/Article_edit.php:98 +#: ../../Zotlabs/Module/Admin/Profs.php:175 ../../Zotlabs/Module/Thing.php:268 +#: ../../Zotlabs/Module/Menu.php:176 ../../Zotlabs/Lib/Apps.php:557 +#: ../../Zotlabs/Lib/ThreadItem.php:148 ../../Zotlabs/Widget/Cdav.php:138 +#: ../../Zotlabs/Widget/Cdav.php:175 ../../include/channel.php:1538 +#: ../../include/channel.php:1542 ../../include/menu.php:120 +msgid "Edit" +msgstr "Edytuj" + +#: ../../Zotlabs/Module/Webpages.php:256 ../../Zotlabs/Module/Layouts.php:194 +#: ../../Zotlabs/Module/Wiki.php:301 ../../Zotlabs/Module/Blocks.php:161 +#: ../../Zotlabs/Module/Photos.php:1078 ../../Zotlabs/Widget/Cdav.php:136 +#: ../../include/conversation.php:1435 +#: ../../extend/addon/hzaddons/hsse/hsse.php:186 +msgid "Share" +msgstr "Udostępnij" + +#: ../../Zotlabs/Module/Webpages.php:263 +msgid "Actions" +msgstr "Akcje" + +#: ../../Zotlabs/Module/Webpages.php:264 +msgid "Page Link" +msgstr "Link do strony" + +#: ../../Zotlabs/Module/Webpages.php:265 +msgid "Page Title" +msgstr "Tytuł strony" + +#: ../../Zotlabs/Module/Webpages.php:266 ../../Zotlabs/Module/Layouts.php:191 +#: ../../Zotlabs/Module/Blocks.php:157 ../../Zotlabs/Module/Menu.php:178 +msgid "Created" +msgstr "Utworzono" + +#: ../../Zotlabs/Module/Webpages.php:267 ../../Zotlabs/Module/Layouts.php:192 +#: ../../Zotlabs/Module/Blocks.php:158 ../../Zotlabs/Module/Menu.php:179 +msgid "Edited" +msgstr "Edytowano" + +#: ../../Zotlabs/Module/Webpages.php:295 +msgid "Invalid file type." +msgstr "Zły typ pliku." + +#: ../../Zotlabs/Module/Webpages.php:307 +msgid "Error opening zip file" +msgstr "Błąd podczas otwierania pliku zip" + +#: ../../Zotlabs/Module/Webpages.php:318 +msgid "Invalid folder path." +msgstr "Nieprawidłowa ścieżka folderu." + +#: ../../Zotlabs/Module/Webpages.php:345 +msgid "No webpage elements detected." +msgstr "Nie wykryto żadnych elementów strony internetowej." + +#: ../../Zotlabs/Module/Webpages.php:420 +msgid "Import complete." +msgstr "Import zakończony." + +#: ../../Zotlabs/Module/Profiles.php:26 ../../Zotlabs/Module/Profiles.php:186 +#: ../../Zotlabs/Module/Profiles.php:243 ../../Zotlabs/Module/Profiles.php:661 +msgid "Profile not found." +msgstr "Nie znaleziono profilu." + +#: ../../Zotlabs/Module/Profiles.php:46 +msgid "Profile deleted." +msgstr "Profil usunięty." + +#: ../../Zotlabs/Module/Profiles.php:70 ../../Zotlabs/Module/Profiles.php:107 +msgid "Profile-" +msgstr "Profil-" + +#: ../../Zotlabs/Module/Profiles.php:92 ../../Zotlabs/Module/Profiles.php:129 +msgid "New profile created." +msgstr "Utworzono nowy profil." + +#: ../../Zotlabs/Module/Profiles.php:113 +msgid "Profile unavailable to clone." +msgstr "Profil niedostępny do sklonowania." + +#: ../../Zotlabs/Module/Profiles.php:148 +msgid "Profile unavailable to export." +msgstr "Profil niedostępny do wyeksportowania." + +#: ../../Zotlabs/Module/Profiles.php:254 +msgid "Profile Name is required." +msgstr "Wymaga się podania nazwy profilu." + +#: ../../Zotlabs/Module/Profiles.php:461 +msgid "Marital Status" +msgstr "Stan cywilny" + +#: ../../Zotlabs/Module/Profiles.php:465 +msgid "Romantic Partner" +msgstr "Partner romantyczny" + +#: ../../Zotlabs/Module/Profiles.php:469 ../../Zotlabs/Module/Profiles.php:774 +msgid "Likes" +msgstr "Polubienia" + +#: ../../Zotlabs/Module/Profiles.php:473 ../../Zotlabs/Module/Profiles.php:775 +msgid "Dislikes" +msgstr "Dezaprobaty" + +#: ../../Zotlabs/Module/Profiles.php:477 ../../Zotlabs/Module/Profiles.php:782 +msgid "Work/Employment" +msgstr "Praca/Zatrudnienie" + +#: ../../Zotlabs/Module/Profiles.php:480 +msgid "Religion" +msgstr "Religia" + +#: ../../Zotlabs/Module/Profiles.php:484 +msgid "Political Views" +msgstr "Poglądy polityczny" + +#: ../../Zotlabs/Module/Profiles.php:488 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:74 +msgid "Gender" +msgstr "Płeć" + +#: ../../Zotlabs/Module/Profiles.php:492 +msgid "Sexual Preference" +msgstr "Prefernecje seksualne" + +#: ../../Zotlabs/Module/Profiles.php:496 +msgid "Homepage" +msgstr "Strona domowa" + +#: ../../Zotlabs/Module/Profiles.php:500 +msgid "Interests" +msgstr "Zainteresowania" + +#: ../../Zotlabs/Module/Profiles.php:596 +msgid "Profile updated." +msgstr "Profil został zaktualizowany." + +#: ../../Zotlabs/Module/Profiles.php:680 +msgid "Hide your connections list from viewers of this profile" +msgstr "Ukryj swoją listę kontaktów przed przeglądającymi ten profil" + +#: ../../Zotlabs/Module/Profiles.php:724 +msgid "Edit Profile Details" +msgstr "Edytuj szczegóły profilu" + +#: ../../Zotlabs/Module/Profiles.php:726 +msgid "View this profile" +msgstr "Zobacz ten profil" + +#: ../../Zotlabs/Module/Profiles.php:727 ../../Zotlabs/Module/Profiles.php:826 +#: ../../include/channel.php:1561 +msgid "Edit visibility" +msgstr "Edytuj dostępność" + +#: ../../Zotlabs/Module/Profiles.php:728 +msgid "Profile Tools" +msgstr "Narzędzia profili" + +#: ../../Zotlabs/Module/Profiles.php:729 +msgid "Change cover photo" +msgstr "Zmień zdjęcie okładkowe" + +#: ../../Zotlabs/Module/Profiles.php:730 ../../include/channel.php:1531 +msgid "Change profile photo" +msgstr "Zmień zdjęcie profilowe" + +#: ../../Zotlabs/Module/Profiles.php:731 +msgid "Create a new profile using these settings" +msgstr "Utwórz nowy profil, korzystając z tych ustawień" + +#: ../../Zotlabs/Module/Profiles.php:732 +msgid "Clone this profile" +msgstr "Sklonuj ten profil" + +#: ../../Zotlabs/Module/Profiles.php:733 +msgid "Delete this profile" +msgstr "Usuń ten profil" + +#: ../../Zotlabs/Module/Profiles.php:734 +msgid "Add profile things" +msgstr "Dodaj elementy profilu" + +#: ../../Zotlabs/Module/Profiles.php:735 +msgid "Personal" +msgstr "Osobisty" + +#: ../../Zotlabs/Module/Profiles.php:737 +msgid "Relationship" +msgstr "Relacja" + +#: ../../Zotlabs/Module/Profiles.php:738 ../../Zotlabs/Widget/Newmember.php:51 +#: ../../include/datetime.php:58 +msgid "Miscellaneous" +msgstr "Różne" + +#: ../../Zotlabs/Module/Profiles.php:740 +msgid "Import profile from file" +msgstr "Importuj profil z pliku" + +#: ../../Zotlabs/Module/Profiles.php:741 +msgid "Export profile to file" +msgstr "Eksportuj profil do pliku" + +#: ../../Zotlabs/Module/Profiles.php:742 +msgid "Your gender" +msgstr "Twoja płeć" + +#: ../../Zotlabs/Module/Profiles.php:743 +msgid "Marital status" +msgstr "Stan cywilny" + +#: ../../Zotlabs/Module/Profiles.php:744 +msgid "Sexual preference" +msgstr "Preferencje seksualne" + +#: ../../Zotlabs/Module/Profiles.php:747 +msgid "Profile name" +msgstr "Nazwa profilu" + +#: ../../Zotlabs/Module/Profiles.php:749 +msgid "This is your default profile." +msgstr "To jest Twój profil domyślny." + +#: ../../Zotlabs/Module/Profiles.php:751 +msgid "Your full name" +msgstr "Twoje imię i nazwisko lub pełna nazwa" + +#: ../../Zotlabs/Module/Profiles.php:752 +msgid "Short title/tescription" +msgstr "Krótki tytuł/opis" + +#: ../../Zotlabs/Module/Profiles.php:752 +msgid "Maximal 190 characters" +msgstr "Maksymalnie 190 znaków" + +#: ../../Zotlabs/Module/Profiles.php:755 +msgid "Street address" +msgstr "Ulica" + +#: ../../Zotlabs/Module/Profiles.php:756 +msgid "Locality/City" +msgstr "Miejscowość" + +#: ../../Zotlabs/Module/Profiles.php:757 +msgid "Region/State" +msgstr "Region/Stan" + +#: ../../Zotlabs/Module/Profiles.php:758 +msgid "Postal/Zip code" +msgstr "Kod pocztowy" + +#: ../../Zotlabs/Module/Profiles.php:764 +msgid "Who (if applicable)" +msgstr "Kto (jeśli dotyczy)" + +#: ../../Zotlabs/Module/Profiles.php:764 +msgid "Examples: cathy123, Cathy Williams, cathy@example.com" +msgstr "Przykłady: jan123, Jan Kowalski, jan@example.com" + +#: ../../Zotlabs/Module/Profiles.php:765 +msgid "Since (date)" +msgstr "Od (data)" + +#: ../../Zotlabs/Module/Profiles.php:768 +msgid "Tell us about yourself" +msgstr "Opowiedz nam o sobie" + +#: ../../Zotlabs/Module/Profiles.php:769 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:68 +msgid "Homepage URL" +msgstr "Adres URL strony domowej" + +#: ../../Zotlabs/Module/Profiles.php:770 +msgid "Hometown" +msgstr "Miejscowość zamieszkania" + +#: ../../Zotlabs/Module/Profiles.php:771 +msgid "Political views" +msgstr "Poglądy polityczne" + +#: ../../Zotlabs/Module/Profiles.php:772 +msgid "Religious views" +msgstr "Poglądy religijne" + +#: ../../Zotlabs/Module/Profiles.php:773 +msgid "Keywords used in directory listings" +msgstr "Słowa kluczowe używane w wykazach katalogów" + +#: ../../Zotlabs/Module/Profiles.php:773 +msgid "Example: fishing photography software" +msgstr "Przykład: oprogramowanie do fotografii wędkarskiej" + +#: ../../Zotlabs/Module/Profiles.php:776 +msgid "Musical interests" +msgstr "Zainteresowania muzyczne" + +#: ../../Zotlabs/Module/Profiles.php:777 +msgid "Books, literature" +msgstr "Ksiązki, literatura" + +#: ../../Zotlabs/Module/Profiles.php:778 +msgid "Television" +msgstr "Telewizja" + +#: ../../Zotlabs/Module/Profiles.php:779 +msgid "Film/Dance/Culture/Entertainment" +msgstr "Film/Dance/Culture/Entertainment" + +#: ../../Zotlabs/Module/Profiles.php:780 +msgid "Hobbies/Interests" +msgstr "Zainteresowania" + +#: ../../Zotlabs/Module/Profiles.php:781 +msgid "Love/Romance" +msgstr "Miłość/romans" + +#: ../../Zotlabs/Module/Profiles.php:783 +msgid "School/Education" +msgstr "Edukacja szkolna" + +#: ../../Zotlabs/Module/Profiles.php:784 +msgid "Contact information and social networks" +msgstr "Informacje kontaktowe i sieci społecznościowe" + +#: ../../Zotlabs/Module/Profiles.php:785 +msgid "My other channels" +msgstr "Moje inne kanały" + +#: ../../Zotlabs/Module/Profiles.php:787 +msgid "Communications" +msgstr "Komunikacja" + +#: ../../Zotlabs/Module/Profiles.php:822 ../../include/channel.php:1557 +msgid "Profile Image" +msgstr "Obraz profilowy" + +#: ../../Zotlabs/Module/Profiles.php:832 ../../include/channel.php:1538 +#: ../../include/nav.php:115 +msgid "Edit Profiles" +msgstr "Edytuj profile" + +#: ../../Zotlabs/Module/Profiles.php:833 ../../Zotlabs/Module/Wiki.php:214 +#: ../../Zotlabs/Module/Manage.php:145 ../../Zotlabs/Module/Chat.php:262 +msgid "Create New" +msgstr "Utwórz nowy" + +#: ../../Zotlabs/Module/Import.php:68 ../../Zotlabs/Module/Import_items.php:48 +msgid "Nothing to import." +msgstr "Nie ma nic do zaimportowania." + +#: ../../Zotlabs/Module/Import.php:83 ../../Zotlabs/Module/Import.php:99 +#: ../../Zotlabs/Module/Import_items.php:72 +msgid "Unable to download data from old server" +msgstr "Nie można pobrać danych ze starego serwera" + +#: ../../Zotlabs/Module/Import.php:106 ../../Zotlabs/Module/Import_items.php:77 +msgid "Imported file is empty." +msgstr "Zaimportowany plik jest pusty." + +#: ../../Zotlabs/Module/Import.php:162 +#, php-format +msgid "Your service plan only allows %d channels." +msgstr "Twój plan usług obejmuje tylko %d kanał(y)/kanałów." + +#: ../../Zotlabs/Module/Import.php:189 +msgid "No channel. Import failed." +msgstr "Brak kanału. Import nieudany." + +#: ../../Zotlabs/Module/Import.php:593 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:142 +msgid "Import completed." +msgstr "Import zakończony." + +#: ../../Zotlabs/Module/Import.php:621 +msgid "You must be logged in to use this feature." +msgstr "Trzeba się zalogować, aby korzystać z tej funkcji." + +#: ../../Zotlabs/Module/Import.php:626 +msgid "Import Channel" +msgstr "Importuj kanał" + +#: ../../Zotlabs/Module/Import.php:627 +msgid "" +"Use this form to import an existing channel from a different server/hub. You " +"may retrieve the channel identity from the old server/hub via the network or " +"provide an export file." +msgstr "" +"Użyj tego formularza, aby zaimportować istniejący kanał z innego serwera/" +"huba. Możesz pobrać tożsamość kanału ze starego serwera/huba przez sieć lub " +"dostarczyć plik eksportu." + +#: ../../Zotlabs/Module/Import.php:628 +#: ../../Zotlabs/Module/Import_items.php:127 +msgid "File to Upload" +msgstr "Plik do przesłania" + +#: ../../Zotlabs/Module/Import.php:629 +msgid "Or provide the old server/hub details" +msgstr "Lub podaj szczegóły starego serwera/huba" + +#: ../../Zotlabs/Module/Import.php:631 +msgid "Your old identity address (xyz@example.com)" +msgstr "Twój stary adres tożsamości (xyz@example.com)" + +#: ../../Zotlabs/Module/Import.php:632 +msgid "Your old login email address" +msgstr "Twój stary adres e-mail logowania" + +#: ../../Zotlabs/Module/Import.php:633 +msgid "Your old login password" +msgstr "Twoje stare hasło logowania" + +#: ../../Zotlabs/Module/Import.php:634 +msgid "Import a few months of posts if possible (limited by available memory" +msgstr "" +"Zaimportuj posty z kilku miesięcy, jeśli to możliwe (ograniczone dostępną " +"pamięcią" + +#: ../../Zotlabs/Module/Import.php:636 +msgid "" +"For either option, please choose whether to make this hub your new primary " +"address, or whether your old location should continue this role. You will be " +"able to post from either location, but only one can be marked as the primary " +"location for files, photos, and media." +msgstr "" +"W obu przypadkach wybierz, czy chcesz ustawić ten hub jako nowy adres " +"podstawowy, czy też rolę tą powinna pełnić Twoja stara lokalizacja. Będziesz " +"mógł/mogła publikować z dowolnej lokalizacji, ale tylko jedna z nich może " +"być oznaczona jako główna lokalizacja plików, zdjęć i multimediów." + +#: ../../Zotlabs/Module/Import.php:638 +msgid "Make this hub my primary location" +msgstr "Ustaw ten hub ako moją główną lokalizację" + +#: ../../Zotlabs/Module/Import.php:639 +msgid "Move this channel (disable all previous locations)" +msgstr "Przenieś ten kanał (wyłącz wszystkie poprzednie lokalizacje)" + +#: ../../Zotlabs/Module/Import.php:640 +msgid "Use this channel nickname instead of the one provided" +msgstr "Użyj tego pseudonimu kanału zamiast podanego" + +#: ../../Zotlabs/Module/Import.php:640 +msgid "" +"Leave blank to keep your existing channel nickname. You will be randomly " +"assigned a similar nickname if either name is already allocated on this site." +msgstr "" +"Pozostaw puste, aby zachować istniejący pseudonim kanału. Otrzymasz losowo " +"podobny pseudonim, jeśli któryś z nich jest już przydzielony na tej stronie." + +#: ../../Zotlabs/Module/Import.php:642 +msgid "" +"This process may take several minutes to complete. Please submit the form " +"only once and leave this page open until finished." +msgstr "" +"Ten proces może zająć kilka minut. Prześlij formularz tylko raz i pozostaw " +"tę stronę otwartą do zakończenia procedury." + +#: ../../Zotlabs/Module/Like.php:93 +msgid "Like/Dislike" +msgstr "Polub/Dezaprobuj" + +#: ../../Zotlabs/Module/Like.php:98 +msgid "This action is restricted to members." +msgstr "Ta akcja jest ograniczona do członków." + +#: ../../Zotlabs/Module/Like.php:99 +msgid "" +"Please login with your $Projectname ID or register as a new $Projectname member to continue." +msgstr "" +"Aby kontynuować, zaloguj się za pomocą ID $Projectname lub zarejestruj się jako nowy członek $Projectname." + +#: ../../Zotlabs/Module/Like.php:154 ../../Zotlabs/Module/Like.php:180 +#: ../../Zotlabs/Module/Like.php:218 +msgid "Invalid request." +msgstr "Nieprawidłowe żądanie." + +#: ../../Zotlabs/Module/Like.php:166 ../../include/conversation.php:135 +msgid "channel" +msgstr "kanał" + +#: ../../Zotlabs/Module/Like.php:195 +msgid "thing" +msgstr "rzecz" + +#: ../../Zotlabs/Module/Like.php:241 +msgid "Channel unavailable." +msgstr "Kanał niedostępny." + +#: ../../Zotlabs/Module/Like.php:277 +msgid "Previous action reversed." +msgstr "Poprzednia czynność została cofnięta." + +#: ../../Zotlabs/Module/Like.php:433 ../../Zotlabs/Module/Tagger.php:71 +#: ../../Zotlabs/Module/Subthread.php:112 ../../Zotlabs/Lib/Activity.php:2971 +#: ../../include/conversation.php:128 ../../include/text.php:2252 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1597 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1895 +#: ../../extend/addon/hzaddons/redphotos/redphotohelper.php:71 +msgid "photo" +msgstr "zdjecie" + +#: ../../Zotlabs/Module/Like.php:433 ../../Zotlabs/Module/Subthread.php:112 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1597 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1895 +msgid "status" +msgstr "stan" + +#: ../../Zotlabs/Module/Like.php:469 ../../Zotlabs/Lib/Activity.php:3006 +#: ../../include/conversation.php:174 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1537 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1932 +#, php-format +msgid "%1$s likes %2$s's %3$s" +msgstr "%1$s polubień %2$s %3$s" + +#: ../../Zotlabs/Module/Like.php:471 ../../Zotlabs/Lib/Activity.php:3008 +#: ../../include/conversation.php:177 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1934 +#, php-format +msgid "%1$s doesn't like %2$s's %3$s" +msgstr "%1$s sezaprobat %2$s %3$s" + +#: ../../Zotlabs/Module/Like.php:473 +#, php-format +msgid "%1$s agrees with %2$s's %3$s" +msgstr "%1$s zgadza się z %3$s dla %2$s" + +#: ../../Zotlabs/Module/Like.php:475 +#, php-format +msgid "%1$s doesn't agree with %2$s's %3$s" +msgstr "%1$s nie zgadza się z %3$s dla %2$s" + +#: ../../Zotlabs/Module/Like.php:477 +#, php-format +msgid "%1$s abstains from a decision on %2$s's %3$s" +msgstr "%1$s wstrzymuje się od decyzji w sprawie %3$s dla %2$s" + +#: ../../Zotlabs/Module/Like.php:479 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2184 +#, php-format +msgid "%1$s is attending %2$s's %3$s" +msgstr "%1$s uczesticzy %2$s %3$s" + +#: ../../Zotlabs/Module/Like.php:481 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2186 +#, php-format +msgid "%1$s is not attending %2$s's %3$s" +msgstr "%1$s nie uczestniczy %2$s %3$s" + +#: ../../Zotlabs/Module/Like.php:483 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2188 +#, php-format +msgid "%1$s may attend %2$s's %3$s" +msgstr "%1$s może uczestniczyć %2$s %3$s" + +#: ../../Zotlabs/Module/Like.php:592 +msgid "Action completed." +msgstr "Akcja zakończona." + +#: ../../Zotlabs/Module/Like.php:593 +msgid "Thank you." +msgstr "Dziękujemy." + +#: ../../Zotlabs/Module/Defperms.php:68 ../../Zotlabs/Module/Connedit.php:89 +msgid "Could not access contact record." +msgstr "Brak dostępu do rekordu kontaktu." + +#: ../../Zotlabs/Module/Defperms.php:112 +#: ../../Zotlabs/Module/Settings/Channel.php:267 +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:54 +#: ../../extend/addon/hzaddons/piwik/piwik.php:116 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:82 +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:93 +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171 +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:54 +#: ../../extend/addon/hzaddons/twitter/twitter.php:494 +#: ../../extend/addon/hzaddons/logrot/logrot.php:54 +msgid "Settings updated." +msgstr "Zaktualizowano ustawienia." + +#: ../../Zotlabs/Module/Defperms.php:190 +msgid "Default Permissions App" +msgstr "Aplikacja Default Permissions" + +#: ../../Zotlabs/Module/Defperms.php:191 +msgid "Set custom default permissions for new connections" +msgstr "Ustaw niestandardowe uprawnienia domyślne dla nowych połączeń" + +#: ../../Zotlabs/Module/Defperms.php:255 ../../Zotlabs/Module/Connedit.php:859 +msgid "Connection Default Permissions" +msgstr "Domyślne uprawnienia połączenia" + +#: ../../Zotlabs/Module/Defperms.php:256 ../../Zotlabs/Module/Connedit.php:860 +msgid "Apply these permissions automatically" +msgstr "Zastosuj te uprawnienia automatycznie" + +#: ../../Zotlabs/Module/Defperms.php:256 +#: ../../Zotlabs/Module/Settings/Channel.php:472 +msgid "" +"If enabled, connection requests will be approved without your interaction" +msgstr "" +"Jeśli jest włączone, prośby o połączenie będą zatwierdzane bez Twojej " +"interakcji" + +#: ../../Zotlabs/Module/Defperms.php:257 ../../Zotlabs/Module/Connedit.php:861 +msgid "Permission role" +msgstr "Rola uprawnień" + +#: ../../Zotlabs/Module/Defperms.php:257 +#: ../../Zotlabs/Module/New_channel.php:157 +#: ../../Zotlabs/Module/New_channel.php:164 +#: ../../Zotlabs/Module/Connedit.php:861 +#: ../../Zotlabs/Widget/Notifications.php:182 ../../include/nav.php:324 +msgid "Loading" +msgstr "Ładowanie" + +#: ../../Zotlabs/Module/Defperms.php:258 ../../Zotlabs/Module/Connedit.php:862 +msgid "Add permission role" +msgstr "Dodaj rolę uprawnień" + +#: ../../Zotlabs/Module/Defperms.php:262 ../../Zotlabs/Module/Connedit.php:875 +msgid "" +"The permissions indicated on this page will be applied to all new " +"connections." +msgstr "" +"Uprawnienia wskazane na tej stronie zostaną zastosowane do wszystkich nowych " +"połączeń." + +#: ../../Zotlabs/Module/Defperms.php:263 +msgid "Automatic approval settings" +msgstr "Ustawienia automatycznego zatwierdzania" + +#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Connedit.php:895 +#: ../../Zotlabs/Module/Tokens.php:183 ../../Zotlabs/Module/Permcats.php:124 +msgid "inherited" +msgstr "dziedziczone" + +#: ../../Zotlabs/Module/Defperms.php:267 ../../Zotlabs/Module/Connedit.php:900 +#: ../../Zotlabs/Module/Tokens.php:181 ../../Zotlabs/Module/Permcats.php:122 +msgid "My Settings" +msgstr "Moje ustawienia" + +#: ../../Zotlabs/Module/Defperms.php:270 ../../Zotlabs/Module/Connedit.php:902 +#: ../../Zotlabs/Module/Tokens.php:186 ../../Zotlabs/Module/Permcats.php:127 +msgid "Individual Permissions" +msgstr "Uprawnienia indywidualne" + +#: ../../Zotlabs/Module/Defperms.php:271 +msgid "" +"Some individual permissions may have been preset or locked based on your " +"channel type and privacy settings." +msgstr "" +"Niektóre indywidualne uprawnienia mogły zostać wstępnie ustawione lub " +"zablokowane w zależności od typu kanału i ustawień prywatności." + +#: ../../Zotlabs/Module/Layouts.php:129 ../../Zotlabs/Module/Layouts.php:189 +#: ../../Zotlabs/Module/Editlayout.php:128 +msgid "Layout Name" +msgstr "Nazwa układu" + +#: ../../Zotlabs/Module/Layouts.php:132 ../../Zotlabs/Module/Editlayout.php:129 +msgid "Layout Description (Optional)" +msgstr "Opis układu (opcjonalnie)" + +#: ../../Zotlabs/Module/Layouts.php:184 ../../include/text.php:2700 +msgid "Layouts" +msgstr "Układy" + +#: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:348 +#: ../../include/nav.php:174 ../../include/nav.php:320 +#: ../../include/help.php:117 ../../include/help.php:125 +msgid "Help" +msgstr "Pomoc" + +#: ../../Zotlabs/Module/Layouts.php:186 +msgid "Comanche page description language help" +msgstr "Pomoc w zakresie języka opisu strony Comanche" + +#: ../../Zotlabs/Module/Layouts.php:190 +msgid "Layout Description" +msgstr "Opis układu" + +#: ../../Zotlabs/Module/Layouts.php:195 +msgid "Download PDL file" +msgstr "Pobierz plik PDL" + +#: ../../Zotlabs/Module/Pubstream.php:20 +msgid "Public Stream App" +msgstr "Aplikacja Public Stream" + +#: ../../Zotlabs/Module/Pubstream.php:21 +msgid "The unmoderated public stream of this hub" +msgstr "Niemoderowany strumień publiczny tego huba" + +#: ../../Zotlabs/Module/Pubstream.php:95 ../../Zotlabs/Module/Display.php:76 +#: ../../Zotlabs/Module/Channel.php:224 ../../Zotlabs/Module/Hq.php:125 +#: ../../Zotlabs/Module/Network.php:205 +msgid "Reset form" +msgstr "Resetuj formularz" + +#: ../../Zotlabs/Module/Pubstream.php:105 ../../Zotlabs/Lib/Apps.php:375 +#: ../../Zotlabs/Widget/Notifications.php:162 +msgid "Public Stream" +msgstr "Strumień publiczny" + +#: ../../Zotlabs/Module/Sse_bs.php:540 ../../Zotlabs/Module/Ping.php:672 +msgid "Private forum" +msgstr "Prywatne forum" + +#: ../../Zotlabs/Module/Sse_bs.php:540 ../../Zotlabs/Module/Ping.php:672 +msgid "Public forum" +msgstr "Publiczne forum" + +#: ../../Zotlabs/Module/Group.php:46 +msgid "Privacy group created." +msgstr "Utworzono grupę prywatności." + +#: ../../Zotlabs/Module/Group.php:49 +msgid "Could not create privacy group." +msgstr "Nie udało się utworzyć grupy prywatności." + +#: ../../Zotlabs/Module/Group.php:62 ../../Zotlabs/Module/Group.php:214 +#: ../../include/items.php:4491 +msgid "Privacy group not found." +msgstr "Nie znaleziono grupy prywatności." + +#: ../../Zotlabs/Module/Group.php:81 +msgid "Privacy group updated." +msgstr "Grupa prywatności została zaktualizowana." + +#: ../../Zotlabs/Module/Group.php:107 +msgid "Privacy Groups App" +msgstr "Aplikacja Privacy Groups" + +#: ../../Zotlabs/Module/Group.php:108 +msgid "Management of privacy groups" +msgstr "Zarządzanie grupami prywatności" + +#: ../../Zotlabs/Module/Group.php:142 ../../Zotlabs/Module/Group.php:154 +#: ../../Zotlabs/Lib/Group.php:324 ../../Zotlabs/Lib/Apps.php:364 +#: ../../Zotlabs/Widget/Activity_filter.php:82 ../../include/group.php:321 +#: ../../include/acl_selectors.php:86 ../../include/nav.php:101 +msgid "Privacy Groups" +msgstr "Grupy prywatności" + +#: ../../Zotlabs/Module/Group.php:143 +msgid "Add Group" +msgstr "Dodaj grupę" + +#: ../../Zotlabs/Module/Group.php:147 +msgid "Privacy group name" +msgstr "Nazwa grupy prywatności" + +#: ../../Zotlabs/Module/Group.php:148 ../../Zotlabs/Module/Group.php:257 +msgid "Members are visible to other channels" +msgstr "Członkowie są widoczni dla innych kanałów" + +#: ../../Zotlabs/Module/Group.php:183 +msgid "Privacy group removed." +msgstr "Grupa prywatności została usunięta." + +#: ../../Zotlabs/Module/Group.php:186 +msgid "Unable to remove privacy group." +msgstr "Nie można usunąć grupy prywatności." + +#: ../../Zotlabs/Module/Group.php:252 +#, php-format +msgid "Privacy Group: %s" +msgstr "Grupa prywatności: %s" + +#: ../../Zotlabs/Module/Group.php:254 +msgid "Privacy group name: " +msgstr "Nazwa grupy prywatności: " + +#: ../../Zotlabs/Module/Group.php:259 +msgid "Delete Group" +msgstr "Usuń grupę" + +#: ../../Zotlabs/Module/Group.php:270 +msgid "Group members" +msgstr "Członkowie grupy" + +#: ../../Zotlabs/Module/Group.php:272 +msgid "Not in this group" +msgstr "Nie w tej grupie" + +#: ../../Zotlabs/Module/Group.php:304 +msgid "Click a channel to toggle membership" +msgstr "Kliknij kanał, aby przełączyć członkostwo" + +#: ../../Zotlabs/Module/Removeme.php:35 +msgid "" +"Channel removals are not allowed within 48 hours of changing the account " +"password." +msgstr "" +"Usunięcie kanału nie jest dozwolone w ciągu 48 godzin od zmiany hasła do " +"konta." + +#: ../../Zotlabs/Module/Removeme.php:60 +msgid "Remove This Channel" +msgstr "Usuń ten kanał" + +#: ../../Zotlabs/Module/Removeme.php:61 ../../Zotlabs/Module/Changeaddr.php:78 +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "WARNING: " +msgstr "UWAGA: " + +#: ../../Zotlabs/Module/Removeme.php:61 +msgid "This channel will be completely removed from the network. " +msgstr "Ten kanał zostanie całkowicie usunięty z sieci. " + +#: ../../Zotlabs/Module/Removeme.php:61 +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "This action is permanent and can not be undone!" +msgstr "Ta akcja jest bezpowrotna i nie można jej cofnąć!" + +#: ../../Zotlabs/Module/Removeme.php:62 ../../Zotlabs/Module/Changeaddr.php:79 +#: ../../Zotlabs/Module/Removeaccount.php:59 +msgid "Please enter your password for verification:" +msgstr "Wprowadź hasło do weryfikacji:" + +#: ../../Zotlabs/Module/Removeme.php:64 +#: ../../Zotlabs/Module/Settings/Channel.php:596 +msgid "Remove Channel" +msgstr "Usuń kanał" + +#: ../../Zotlabs/Module/Appman.php:39 ../../Zotlabs/Module/Appman.php:56 +msgid "App installed." +msgstr "Aplikacja została zainstalowana." + +#: ../../Zotlabs/Module/Appman.php:49 +msgid "Malformed app." +msgstr "Nieprawidłowa aplikacja." + +#: ../../Zotlabs/Module/Appman.php:132 +msgid "Embed code" +msgstr "Osadzony kod" + +#: ../../Zotlabs/Module/Appman.php:138 +msgid "Edit App" +msgstr "Edutuj aplikację" + +#: ../../Zotlabs/Module/Appman.php:138 +msgid "Create App" +msgstr "Utwórz aplikację" + +#: ../../Zotlabs/Module/Appman.php:143 +msgid "Name of app" +msgstr "Nazwa aplikacji" + +#: ../../Zotlabs/Module/Appman.php:144 +msgid "Location (URL) of app" +msgstr "Lokalizacja (URL) aplikacji" + +#: ../../Zotlabs/Module/Appman.php:146 +msgid "Photo icon URL" +msgstr "Adres URL ikony zdjęcia" + +#: ../../Zotlabs/Module/Appman.php:146 +msgid "80 x 80 pixels - optional" +msgstr "80 x 80 pikseli - opcjonalnie" + +#: ../../Zotlabs/Module/Appman.php:147 +msgid "Categories (optional, comma separated list)" +msgstr "Kategorie (opcjonalne, lista rozdzielana przecinkami)" + +#: ../../Zotlabs/Module/Appman.php:148 +msgid "Version ID" +msgstr "ID wesji" + +#: ../../Zotlabs/Module/Appman.php:149 +msgid "Price of app" +msgstr "Cena aplikacji" + +#: ../../Zotlabs/Module/Appman.php:150 +msgid "Location (URL) to purchase app" +msgstr "Lokalizacja (URL) do zakupu aplikacji" + +#: ../../Zotlabs/Module/Changeaddr.php:35 +msgid "" +"Channel name changes are not allowed within 48 hours of changing the account " +"password." +msgstr "" +"Zmiana nazwy kanału jest niedozwolona w ciągu 48 godzin od zmiany hasła do " +"konta." + +#: ../../Zotlabs/Module/Changeaddr.php:46 ../../include/channel.php:225 +#: ../../include/channel.php:706 +msgid "Reserved nickname. Please choose another." +msgstr "Zarezerwowany pseudonim. Proszę wybrać inny." + +#: ../../Zotlabs/Module/Changeaddr.php:51 ../../include/channel.php:230 +#: ../../include/channel.php:711 +msgid "" +"Nickname has unsupported characters or is already being used on this site." +msgstr "" +"Pseudonim zawiera nieobsługiwane znaki lub jest już używany w tym serwisie." + +#: ../../Zotlabs/Module/Changeaddr.php:77 +msgid "Change channel nickname/address" +msgstr "Zmień krótką nazwę/adres kanału" + +#: ../../Zotlabs/Module/Changeaddr.php:78 +msgid "Any/all connections on other networks will be lost!" +msgstr "Wszystkie połączenia w innych sieciach zostaną utracone!" + +#: ../../Zotlabs/Module/Changeaddr.php:80 +msgid "New channel address" +msgstr "Nowy adres kanału" + +#: ../../Zotlabs/Module/Changeaddr.php:81 +msgid "Rename Channel" +msgstr "Zmień nazwę kanału" + +#: ../../Zotlabs/Module/Oauth.php:45 +msgid "Name is required" +msgstr "Wymaga się podania nazwy" + +#: ../../Zotlabs/Module/Oauth.php:49 +msgid "Key and Secret are required" +msgstr "Wymaga się wprowadzenia klucza i sekretu" + +#: ../../Zotlabs/Module/Oauth.php:100 +msgid "OAuth Apps Manager App" +msgstr "Aplikacja OAuth Apps Manager" + +#: ../../Zotlabs/Module/Oauth.php:101 +msgid "OAuth authentication tokens for mobile and remote apps" +msgstr "Tokeny uwierzytelniania OAuth dla aplikacji mobilnych i zdalnych" + +#: ../../Zotlabs/Module/Oauth.php:110 ../../Zotlabs/Module/Oauth.php:136 +#: ../../Zotlabs/Module/Oauth.php:172 ../../Zotlabs/Module/Oauth2.php:143 +#: ../../Zotlabs/Module/Oauth2.php:193 +msgid "Add application" +msgstr "Dodaj aplikację" + +#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth2.php:118 +#: ../../Zotlabs/Module/Oauth2.php:146 +msgid "Name of application" +msgstr "Nazwa aplikacji" + +#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:140 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:596 +#: ../../extend/addon/hzaddons/twitter/twitter.php:505 +msgid "Consumer Key" +msgstr "Klucz konsumenta" + +#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:115 +#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 +msgid "Automatically generated - change if desired. Max length 20" +msgstr "" +"Wygenerowane automatycznie - w razie potrzeby zmień. Maksymalna długość 20" + +#: ../../Zotlabs/Module/Oauth.php:115 ../../Zotlabs/Module/Oauth.php:141 +#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:595 +#: ../../extend/addon/hzaddons/twitter/twitter.php:506 +msgid "Consumer Secret" +msgstr "Hasło konsumenta" + +#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth.php:142 +#: ../../Zotlabs/Module/Oauth2.php:120 ../../Zotlabs/Module/Oauth2.php:148 +msgid "Redirect" +msgstr "Przekierowanie" + +#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth2.php:120 +#: ../../Zotlabs/Module/Oauth2.php:148 +msgid "" +"Redirect URI - leave blank unless your application specifically requires this" +msgstr "" +"Identyfikator URI przekierowania - pozostaw puste, chyba że aplikacja tego " +"wymaga" + +#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Oauth.php:143 +msgid "Icon url" +msgstr "URL ikony" + +#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Sources.php:123 +#: ../../Zotlabs/Module/Sources.php:158 +msgid "Optional" +msgstr "Opcjonalne" + +#: ../../Zotlabs/Module/Oauth.php:128 +msgid "Application not found." +msgstr "Aplikacji nie znaleziono." + +#: ../../Zotlabs/Module/Oauth.php:171 +msgid "Connected OAuth Apps" +msgstr "Połączone aplikacje OAuth" + +#: ../../Zotlabs/Module/Oauth.php:175 ../../Zotlabs/Module/Oauth2.php:196 +msgid "Client key starts with" +msgstr "Klucz klienta zaczyna się od" + +#: ../../Zotlabs/Module/Oauth.php:176 ../../Zotlabs/Module/Oauth2.php:197 +msgid "No name" +msgstr "Brak nazwy" + +#: ../../Zotlabs/Module/Oauth.php:177 ../../Zotlabs/Module/Oauth2.php:198 +msgid "Remove authorization" +msgstr "Usuń autoryzację" + +#: ../../Zotlabs/Module/Email_resend.php:12 +#: ../../Zotlabs/Module/Email_validation.php:24 +msgid "Token verification failed." +msgstr "Weryfikacja tokena nie powiodła się." + +#: ../../Zotlabs/Module/Email_resend.php:30 +msgid "Email verification resent" +msgstr "Weryfikacja adresu e-mail została wysłana ponownie" + +#: ../../Zotlabs/Module/Email_resend.php:33 +msgid "Unable to resend email verification message." +msgstr "Nie można ponownie wysłać weryfikacyjną wiadomość e-mail." + +#: ../../Zotlabs/Module/Search.php:17 +#: ../../Zotlabs/Module/Viewconnections.php:23 +#: ../../Zotlabs/Module/Display.php:26 ../../Zotlabs/Module/Photos.php:519 +#: ../../Zotlabs/Module/Directory.php:73 ../../Zotlabs/Module/Directory.php:78 +#: ../../Zotlabs/Module/Ratings.php:83 +msgid "Public access denied." +msgstr "Odmowa dostępu publicznego." + +#: ../../Zotlabs/Module/Search.php:41 ../../Zotlabs/Module/Connections.php:378 +#: ../../Zotlabs/Lib/Apps.php:353 ../../Zotlabs/Widget/Sitesearch.php:31 +#: ../../Zotlabs/Widget/Activity_filter.php:193 ../../include/text.php:1150 +#: ../../include/text.php:1162 ../../include/acl_selectors.php:148 +#: ../../include/nav.php:188 +msgid "Search" +msgstr "Szukaj" + +#: ../../Zotlabs/Module/Search.php:222 +#, php-format +msgid "Items tagged with: %s" +msgstr "Elementy oznaczone tagiem: %s" + +#: ../../Zotlabs/Module/Search.php:224 +#, php-format +msgid "Search results for: %s" +msgstr "Wyniki wyszukiwania dla: %s" + +#: ../../Zotlabs/Module/Moderate.php:67 +msgid "Comment approved" +msgstr "Komentarz zatwierdzony" + +#: ../../Zotlabs/Module/Moderate.php:71 +msgid "Comment deleted" +msgstr "Komentarz usuniety" + +#: ../../Zotlabs/Module/Rpost.php:150 ../../Zotlabs/Module/Editpost.php:109 +msgid "Edit post" +msgstr "Edytuj post" + +#: ../../Zotlabs/Module/Oexchange.php:27 +msgid "Unable to find your hub." +msgstr "Nie można znaleźć Twojego huba." + +#: ../../Zotlabs/Module/Oexchange.php:41 +msgid "Post successful." +msgstr "Opublikowanie powiodło się." + +#: ../../Zotlabs/Module/Chanview.php:95 ../../Zotlabs/Module/Card_edit.php:44 +#: ../../Zotlabs/Module/Wall_upload.php:31 ../../Zotlabs/Module/Page.php:75 +#: ../../Zotlabs/Module/Block.php:41 ../../Zotlabs/Module/Article_edit.php:44 +#: ../../Zotlabs/Module/Attach.php:21 ../../Zotlabs/Module/Cal.php:31 +#: ../../Zotlabs/Module/Attach_edit.php:52 +msgid "Channel not found." +msgstr "Nie znaleziono kanału." + +#: ../../Zotlabs/Module/Chanview.php:132 +msgid "toggle full screen mode" +msgstr "przełącz tryb pełnego ekranu" + +#: ../../Zotlabs/Module/Tagger.php:50 +msgid "Post not found." +msgstr "Nie znaleziono postu." + +#: ../../Zotlabs/Module/Tagger.php:79 ../../Zotlabs/Lib/Activity.php:2971 +#: ../../include/conversation.php:158 ../../include/text.php:2258 +#: ../../include/markdown.php:204 ../../include/bbcode.php:523 +msgid "post" +msgstr "post" + +#: ../../Zotlabs/Module/Tagger.php:81 ../../include/conversation.php:160 +#: ../../include/text.php:2260 +msgid "comment" +msgstr "komentarz" + +#: ../../Zotlabs/Module/Tagger.php:121 +#, php-format +msgid "%1$s tagged %2$s's %3$s with %4$s" +msgstr "%1$s oznaczono tagiem %3$s %2$s w %4$s" + +#: ../../Zotlabs/Module/Import_items.php:93 +#, php-format +msgid "Warning: Database versions differ by %1$d updates." +msgstr "Ostrzeżenie: wersje baz danych różnią się o %1$d aktualizacji." + +#: ../../Zotlabs/Module/Import_items.php:108 +msgid "Import completed" +msgstr "Import zakończony" + +#: ../../Zotlabs/Module/Import_items.php:125 +msgid "Import Items" +msgstr "Importuj elementy" + +#: ../../Zotlabs/Module/Import_items.php:126 +msgid "Use this form to import existing posts and content from an export file." +msgstr "" +"Użyj tego formularza, aby zaimportować istniejące posty i treść z pliku " +"eksportu." + +#: ../../Zotlabs/Module/Connect.php:65 ../../Zotlabs/Module/Connect.php:118 +msgid "Continue" +msgstr "Kontynuj" + +#: ../../Zotlabs/Module/Connect.php:99 +msgid "Premium Channel Setup" +msgstr "Konfiguracja kanału Premium" + +#: ../../Zotlabs/Module/Connect.php:101 +msgid "Enable premium channel connection restrictions" +msgstr "Włącz ograniczenia połączeń z kanałem premium" + +#: ../../Zotlabs/Module/Connect.php:102 +msgid "" +"Please enter your restrictions or conditions, such as paypal receipt, usage " +"guidelines, etc." +msgstr "" +"Podaj swoje ograniczenia lub warunki, takie jak pokwitowanie PayPal, " +"wytyczne dotyczące użytkowania itp." + +#: ../../Zotlabs/Module/Connect.php:104 ../../Zotlabs/Module/Connect.php:124 +msgid "" +"This channel may require additional steps or acknowledgement of the " +"following conditions prior to connecting:" +msgstr "" +"Ten kanał, przed podłączeniem, może wymagać dodatkowych kroków lub " +"potwierdzenia następujących warunków:" + +#: ../../Zotlabs/Module/Connect.php:105 +msgid "" +"Potential connections will then see the following text before proceeding:" +msgstr "Potencjalne połączenia zobaczą następujący tekst przed kontynuowaniem:" + +#: ../../Zotlabs/Module/Connect.php:106 ../../Zotlabs/Module/Connect.php:127 +msgid "" +"By continuing, I certify that I have complied with any instructions provided " +"on this page." +msgstr "" +"Kontynuując, oświadczam, że postępowałem zgodnie z instrukcjami podanymi na " +"tej stronie." + +#: ../../Zotlabs/Module/Connect.php:115 +msgid "(No specific instructions have been provided by the channel owner.)" +msgstr "(Właściciel kanału nie przekazał żadnych szczegółowych instrukcji.)" + +#: ../../Zotlabs/Module/Connect.php:123 +msgid "Restricted or Premium Channel" +msgstr "Kanał z ograniczeniami lub premium" + +#: ../../Zotlabs/Module/New_channel.php:147 ../../Zotlabs/Module/Manage.php:138 +#, php-format +msgid "You have created %1$.0f of %2$.0f allowed channels." +msgstr "Utworzno %1$ .0f z %2$.0f dozwolonych kanałów." + +#: ../../Zotlabs/Module/New_channel.php:159 +msgid "Your real name is recommended." +msgstr "Zalecane jest podania prawdziwego imienia i nazwiska lub nazwy." + +#: ../../Zotlabs/Module/New_channel.php:160 +msgid "" +"Examples: \"Bob Jameson\", \"Lisa and her Horses\", \"Soccer\", \"Aviation " +"Group\"" +msgstr "" +"Przykłady: \"Bob Jameson\", \"Lisa i jej konie\", \"Piłka nożna\", \"Grupa " +"lotnicza\"" + +#: ../../Zotlabs/Module/New_channel.php:165 +msgid "" +"This will be used to create a unique network address (like an email address)." +msgstr "" +"Zostanie to zastosowane do utworzenia unikalnego adresu sieciowego " +"(podobnego do adresu e-mail)." + +#: ../../Zotlabs/Module/New_channel.php:167 +msgid "Allowed characters are a-z 0-9, - and _" +msgstr "Dozwolone znaki, to a-z 0-9, - oraz _" + +#: ../../Zotlabs/Module/New_channel.php:175 +msgid "Channel name" +msgstr "Nazwa kanału" + +#: ../../Zotlabs/Module/New_channel.php:177 +#: ../../Zotlabs/Module/Register.php:263 +msgid "Choose a short nickname" +msgstr "Wybierz krótki pseudonim" + +#: ../../Zotlabs/Module/New_channel.php:178 +#: ../../Zotlabs/Module/Register.php:264 +#: ../../Zotlabs/Module/Settings/Channel.php:537 +msgid "Channel role and privacy" +msgstr "Rola kanału i prywatność" + +#: ../../Zotlabs/Module/New_channel.php:178 +msgid "" +"Select a channel permission role compatible with your usage needs and " +"privacy requirements." +msgstr "" +"Wybierz rolę uprawnień do kanału, zgodną z Twoimi potrzebami użytkowania i " +"wymaganiami dotyczącymi prywatności." + +#: ../../Zotlabs/Module/New_channel.php:178 +#: ../../Zotlabs/Module/Register.php:264 +msgid "Read more about channel permission roles" +msgstr "Przeczytaj więcej o rolach uprawnień do kanału" + +#: ../../Zotlabs/Module/New_channel.php:181 +msgid "Create a Channel" +msgstr "Utwórz kanał" + +#: ../../Zotlabs/Module/New_channel.php:182 +msgid "" +"A channel is a unique network identity. It can represent a person (social " +"network profile), a forum (group), a business or celebrity page, a newsfeed, " +"and many other things." +msgstr "" +"Kanał to unikalna tożsamość sieciowa. Może reprezentować osobę (profil sieci " +"społecznościowej), forum (grupę), stronę biznesową lub celebrycką, kanał " +"informacyjny i wiele innych rzeczy." + +#: ../../Zotlabs/Module/New_channel.php:183 +msgid "" +"or import an existing channel from another location." +msgstr "" +"lub zaimportuj istniejący kanał z innej lokalizacji." + +#: ../../Zotlabs/Module/New_channel.php:188 +msgid "Validate" +msgstr "Zalegalizuj" + +#: ../../Zotlabs/Module/Apps.php:50 ../../Zotlabs/Widget/Appstore.php:14 +msgid "Available Apps" +msgstr "Dostępne aplikacje" + +#: ../../Zotlabs/Module/Apps.php:50 +msgid "Installed Apps" +msgstr "Zainstalowane aplikacje" + +#: ../../Zotlabs/Module/Apps.php:53 +msgid "Manage Apps" +msgstr "Zarządzaj aplikacjami" + +#: ../../Zotlabs/Module/Apps.php:54 +msgid "Create Custom App" +msgstr "Utwórz własną aplikację" + +#: ../../Zotlabs/Module/Removeaccount.php:35 +msgid "" +"Account removals are not allowed within 48 hours of changing the account " +"password." +msgstr "" +"Usunięcie konta nie jest dozwolone w ciągu 48 godzin od zmiany hasła do " +"konta." + +#: ../../Zotlabs/Module/Removeaccount.php:57 +msgid "Remove This Account" +msgstr "Usuń to konto" + +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "" +"This account and all its channels will be completely removed from the " +"network. " +msgstr "To konto i wszystkie jego kanały zostaną całkowicie usunięte z sieci. " + +#: ../../Zotlabs/Module/Removeaccount.php:61 +#: ../../Zotlabs/Module/Settings/Account.php:105 +msgid "Remove Account" +msgstr "Usuń konto" + +#: ../../Zotlabs/Module/Filestorage.php:14 +#: ../../Zotlabs/Module/Filestorage.php:53 +msgid "Deprecated!" +msgstr "Przestarzałe!" + +#: ../../Zotlabs/Module/Filestorage.php:29 ../../Zotlabs/Module/Display.php:42 +#: ../../Zotlabs/Module/Display.php:429 ../../Zotlabs/Module/Admin.php:62 +#: ../../Zotlabs/Module/Admin/Themes.php:72 +#: ../../Zotlabs/Module/Admin/Addons.php:260 ../../Zotlabs/Module/Thing.php:96 +#: ../../Zotlabs/Module/Viewsrc.php:25 ../../include/items.php:3919 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:284 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:285 +msgid "Item not found." +msgstr "Nie znaleziono elementu." + +#: ../../Zotlabs/Module/Filestorage.php:109 +#: ../../Zotlabs/Module/Attach_edit.php:69 +msgid "File not found." +msgstr "Nie znaleziono pliku." + +#: ../../Zotlabs/Module/Filestorage.php:157 +msgid "Permission Denied." +msgstr "Odmowa dostępu." + +#: ../../Zotlabs/Module/Filestorage.php:190 +msgid "Edit file permissions" +msgstr "Edytuj uprawnienia do plików" + +#: ../../Zotlabs/Module/Filestorage.php:195 +#: ../../Zotlabs/Module/Connedit.php:682 ../../Zotlabs/Module/Chat.php:241 +#: ../../Zotlabs/Module/Photos.php:678 ../../Zotlabs/Module/Photos.php:1047 +#: ../../Zotlabs/Module/Thing.php:321 ../../Zotlabs/Module/Thing.php:374 +#: ../../include/acl_selectors.php:153 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:254 +msgid "Permissions" +msgstr "Uprawnienia" + +#: ../../Zotlabs/Module/Filestorage.php:202 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:261 +msgid "Set/edit permissions" +msgstr "Ustaw/edytuj uprawnienia" + +#: ../../Zotlabs/Module/Filestorage.php:203 +msgid "Include all files and sub folders" +msgstr "Uwzględnij wszystkie pliki i podfoldery" + +#: ../../Zotlabs/Module/Filestorage.php:204 +msgid "Return to file list" +msgstr "Wróć do listy plików" + +#: ../../Zotlabs/Module/Filestorage.php:206 +#: ../../Zotlabs/Storage/Browser.php:386 +msgid "Copy/paste this code to attach file to a post" +msgstr "Skopiuj/wklej ten kod, aby dołączyć plik do postu" + +#: ../../Zotlabs/Module/Filestorage.php:207 +#: ../../Zotlabs/Storage/Browser.php:387 +msgid "Copy/paste this URL to link file from a web page" +msgstr "Skopiuj/wklej ten adres URL, aby zlinkować plik na stron internetowej" + +#: ../../Zotlabs/Module/Filestorage.php:209 +msgid "Share this file" +msgstr "Udostępnij ten plik" + +#: ../../Zotlabs/Module/Filestorage.php:210 +msgid "Show URL to this file" +msgstr "Pokaż adres URL do tego pliku" + +#: ../../Zotlabs/Module/Filestorage.php:211 +#: ../../Zotlabs/Storage/Browser.php:552 +msgid "Show in your contacts shared folder" +msgstr "Pokaż w folderze udostępnionym kontaktów" + +#: ../../Zotlabs/Module/Card_edit.php:17 ../../Zotlabs/Module/Card_edit.php:33 +#: ../../Zotlabs/Module/Editlayout.php:79 ../../Zotlabs/Module/Editblock.php:79 +#: ../../Zotlabs/Module/Editblock.php:95 ../../Zotlabs/Module/Editpost.php:24 +#: ../../Zotlabs/Module/Editwebpage.php:80 +#: ../../Zotlabs/Module/Article_edit.php:17 +#: ../../Zotlabs/Module/Article_edit.php:33 +msgid "Item not found" +msgstr "Nie znaleziono elementu" + +#: ../../Zotlabs/Module/Card_edit.php:101 +#: ../../Zotlabs/Module/Editblock.php:116 ../../Zotlabs/Module/Chat.php:220 +#: ../../Zotlabs/Module/Editwebpage.php:143 +#: ../../Zotlabs/Module/Article_edit.php:100 +#: ../../include/conversation.php:1341 +#: ../../extend/addon/hzaddons/hsse/hsse.php:95 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:166 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:309 +msgid "Insert web link" +msgstr "Wstaw link internetowy" + +#: ../../Zotlabs/Module/Card_edit.php:117 +#: ../../Zotlabs/Module/Editblock.php:129 ../../Zotlabs/Module/Photos.php:674 +#: ../../Zotlabs/Module/Photos.php:1044 +#: ../../Zotlabs/Module/Article_edit.php:116 +#: ../../include/conversation.php:1474 +#: ../../extend/addon/hzaddons/hsse/hsse.php:221 +msgid "Title (optional)" +msgstr "Tytuł (opcjonalnie)" + +#: ../../Zotlabs/Module/Card_edit.php:128 +msgid "Edit Card" +msgstr "Edytuj kartę" + +#: ../../Zotlabs/Module/Viewconnections.php:65 +msgid "No connections." +msgstr "Brak połączeń." + +#: ../../Zotlabs/Module/Viewconnections.php:80 +#: ../../Zotlabs/Module/Connections.php:288 ../../include/text.php:1044 +msgid "Accepts" +msgstr "Akceptacje" + +#: ../../Zotlabs/Module/Viewconnections.php:83 +#: ../../Zotlabs/Module/Connections.php:291 ../../include/text.php:1047 +msgid "Comments" +msgstr "Komentarze" + +#: ../../Zotlabs/Module/Viewconnections.php:88 +#: ../../Zotlabs/Module/Connections.php:296 ../../include/text.php:1052 +msgid "Stream items" +msgstr "Elementy strumienia" + +#: ../../Zotlabs/Module/Viewconnections.php:93 +#: ../../Zotlabs/Module/Connections.php:301 ../../include/text.php:1057 +msgid "Wall posts" +msgstr "Ściana postów" + +#: ../../Zotlabs/Module/Viewconnections.php:97 +#: ../../Zotlabs/Module/Connections.php:305 ../../include/text.php:1061 +msgid "Nothing" +msgstr "Nic" + +#: ../../Zotlabs/Module/Viewconnections.php:105 +#, php-format +msgid "Visit %s's profile [%s]" +msgstr "Odwiedź profil %s [%s]" + +#: ../../Zotlabs/Module/Viewconnections.php:135 +msgid "View Connections" +msgstr "Pokaż połączenia" + +#: ../../Zotlabs/Module/Oauth2.php:54 +msgid "Name and Secret are required" +msgstr "Wymagane jest ustawienie imienia i sekretu" + +#: ../../Zotlabs/Module/Oauth2.php:106 +msgid "OAuth2 Apps Manager App" +msgstr "Aplikacja OAuth2 Apps Manager" + +#: ../../Zotlabs/Module/Oauth2.php:107 +msgid "OAuth2 authenticatication tokens for mobile and remote apps" +msgstr "Tokeny uwierzytelniające OAuth2 dla aplikacji mobilnych i zdalnych" + +#: ../../Zotlabs/Module/Oauth2.php:115 +msgid "Add OAuth2 application" +msgstr "Dodaj aplikację OAuth2" + +#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:149 +msgid "Grant Types" +msgstr "Rodzaje dofinansowań" + +#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:122 +msgid "leave blank unless your application sepcifically requires this" +msgstr "pozostaw puste, chyba że Twoja aplikacja wyraźnie tego wymaga" + +#: ../../Zotlabs/Module/Oauth2.php:122 ../../Zotlabs/Module/Oauth2.php:150 +msgid "Authorization scope" +msgstr "Zakres uprawnień" + +#: ../../Zotlabs/Module/Oauth2.php:134 +msgid "OAuth2 Application not found." +msgstr "Nie znaleziono aplikacji OAuth2." + +#: ../../Zotlabs/Module/Oauth2.php:149 ../../Zotlabs/Module/Oauth2.php:150 +msgid "leave blank unless your application specifically requires this" +msgstr "pozostaw puste, chyba że Twoja aplikacja wyraźnie tego wymaga" + +#: ../../Zotlabs/Module/Oauth2.php:192 +msgid "Connected OAuth2 Apps" +msgstr "Aplikacje połączeń OAuth2" + +#: ../../Zotlabs/Module/Wiki.php:35 +#: ../../extend/addon/hzaddons/cart/cart.php:1410 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:51 +msgid "Profile Unavailable." +msgstr "Profil niedostępny." + +#: ../../Zotlabs/Module/Wiki.php:52 +msgid "Wiki App" +msgstr "Aplikacja Wiki" + +#: ../../Zotlabs/Module/Wiki.php:53 +msgid "Provide a wiki for your channel" +msgstr "Udostępnij wiki dla swojego kanału" + +#: ../../Zotlabs/Module/Wiki.php:77 +#: ../../extend/addon/hzaddons/cart/cart.php:1556 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:478 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:456 +#: ../../extend/addon/hzaddons/cart/myshop.php:37 +#: ../../extend/addon/hzaddons/cart/manual_payments.php:93 +msgid "Invalid channel" +msgstr "Zły kanał" + +#: ../../Zotlabs/Module/Wiki.php:133 +msgid "Error retrieving wiki" +msgstr "Błąd podczas pobierania wiki" + +#: ../../Zotlabs/Module/Wiki.php:140 +msgid "Error creating zip file export folder" +msgstr "Błąd podczas tworzenia folderu eksportu pliku ZIP" + +#: ../../Zotlabs/Module/Wiki.php:191 +msgid "Error downloading wiki: " +msgstr "Błąd podczas pobierania wiki: " + +#: ../../Zotlabs/Module/Wiki.php:206 ../../Zotlabs/Widget/Wiki_list.php:15 +#: ../../include/nav.php:536 +msgid "Wikis" +msgstr "Wiki" + +#: ../../Zotlabs/Module/Wiki.php:212 ../../Zotlabs/Storage/Browser.php:404 +msgid "Download" +msgstr "Pobierz" + +#: ../../Zotlabs/Module/Wiki.php:216 +msgid "Wiki name" +msgstr "Nazwa wiki" + +#: ../../Zotlabs/Module/Wiki.php:217 +msgid "Content type" +msgstr "Rodzaj treści" + +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2116 +#: ../../extend/addon/hzaddons/mdpost/mdpost.php:41 +msgid "Markdown" +msgstr "Markdown" + +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2114 +msgid "BBcode" +msgstr "BBcode" + +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2117 +msgid "Text" +msgstr "Text" + +#: ../../Zotlabs/Module/Wiki.php:219 ../../Zotlabs/Storage/Browser.php:378 +msgid "Type" +msgstr "Rodzaj" + +#: ../../Zotlabs/Module/Wiki.php:220 +msgid "Any type" +msgstr "Dwolny rodzaj" + +#: ../../Zotlabs/Module/Wiki.php:227 +msgid "Lock content type" +msgstr "Zablokuj rodzaj treści" + +#: ../../Zotlabs/Module/Wiki.php:228 +msgid "Create a status post for this wiki" +msgstr "Utwórz post statusu dla tego wiki" + +#: ../../Zotlabs/Module/Wiki.php:229 +msgid "Edit Wiki Name" +msgstr "Edytuj nazwę wiki" + +#: ../../Zotlabs/Module/Wiki.php:274 +msgid "Wiki not found" +msgstr "Nie znaleziono wiki" + +#: ../../Zotlabs/Module/Wiki.php:300 +msgid "Rename page" +msgstr "Zień nazwę strony" + +#: ../../Zotlabs/Module/Wiki.php:321 +msgid "Error retrieving page content" +msgstr "Błąd podczas pobierania treści strony" + +#: ../../Zotlabs/Module/Wiki.php:329 ../../Zotlabs/Module/Wiki.php:331 +msgid "New page" +msgstr "Nowa strona" + +#: ../../Zotlabs/Module/Wiki.php:366 +msgid "Revision Comparison" +msgstr "Porównanie wersji" + +#: ../../Zotlabs/Module/Wiki.php:367 ../../Zotlabs/Lib/NativeWikiPage.php:567 +#: ../../Zotlabs/Widget/Wiki_page_history.php:25 +msgid "Revert" +msgstr "Odwróć" + +#: ../../Zotlabs/Module/Wiki.php:374 +msgid "Short description of your changes (optional)" +msgstr "Krótki opis zmian (opcjonalnie)" + +#: ../../Zotlabs/Module/Wiki.php:384 +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:134 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:69 +#: ../../extend/addon/hzaddons/dwpost/dwpost.php:134 +#: ../../extend/addon/hzaddons/wppost/wppost.php:173 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:98 +msgid "Source" +msgstr "Źródło" + +#: ../../Zotlabs/Module/Wiki.php:394 +msgid "New page name" +msgstr "Nowa nazwa strony" + +#: ../../Zotlabs/Module/Wiki.php:399 +msgid "Embed image from photo albums" +msgstr "Osadź obraz z albumów fotograficznych" + +#: ../../Zotlabs/Module/Wiki.php:400 ../../include/conversation.php:1457 +#: ../../extend/addon/hzaddons/hsse/hsse.php:208 +msgid "Embed an image from your albums" +msgstr "Osadź obraz ze swoich albumów" + +#: ../../Zotlabs/Module/Wiki.php:402 ../../Zotlabs/Module/Profile_photo.php:508 +#: ../../Zotlabs/Module/Cover_photo.php:429 ../../include/conversation.php:1459 +#: ../../include/conversation.php:1510 +#: ../../extend/addon/hzaddons/hsse/hsse.php:210 +#: ../../extend/addon/hzaddons/hsse/hsse.php:257 +msgid "OK" +msgstr "Dobrze" + +#: ../../Zotlabs/Module/Wiki.php:403 ../../Zotlabs/Module/Profile_photo.php:509 +#: ../../Zotlabs/Module/Cover_photo.php:430 ../../include/conversation.php:1385 +#: ../../extend/addon/hzaddons/hsse/hsse.php:139 +msgid "Choose images to embed" +msgstr "Wybierz zdjęcie do osadzenia" + +#: ../../Zotlabs/Module/Wiki.php:404 ../../Zotlabs/Module/Profile_photo.php:510 +#: ../../Zotlabs/Module/Cover_photo.php:431 ../../include/conversation.php:1386 +#: ../../extend/addon/hzaddons/hsse/hsse.php:140 +msgid "Choose an album" +msgstr "Wybierz album" + +#: ../../Zotlabs/Module/Wiki.php:405 ../../Zotlabs/Module/Profile_photo.php:511 +#: ../../Zotlabs/Module/Cover_photo.php:432 +msgid "Choose a different album" +msgstr "Wybierz inny album" + +#: ../../Zotlabs/Module/Wiki.php:406 ../../Zotlabs/Module/Profile_photo.php:512 +#: ../../Zotlabs/Module/Cover_photo.php:433 ../../include/conversation.php:1388 +#: ../../extend/addon/hzaddons/hsse/hsse.php:142 +msgid "Error getting album list" +msgstr "Błąd podczas pobierania listy albumów" + +#: ../../Zotlabs/Module/Wiki.php:407 ../../Zotlabs/Module/Profile_photo.php:513 +#: ../../Zotlabs/Module/Cover_photo.php:434 ../../include/conversation.php:1389 +#: ../../extend/addon/hzaddons/hsse/hsse.php:143 +msgid "Error getting photo link" +msgstr "Błąd podczas pobierania linku do zdjęcia" + +#: ../../Zotlabs/Module/Wiki.php:408 ../../Zotlabs/Module/Profile_photo.php:514 +#: ../../Zotlabs/Module/Cover_photo.php:435 ../../include/conversation.php:1390 +#: ../../extend/addon/hzaddons/hsse/hsse.php:144 +msgid "Error getting album" +msgstr "Błąd podczas pobierania albumu" + +#: ../../Zotlabs/Module/Wiki.php:410 +msgid "History" +msgstr "Historia" + +#: ../../Zotlabs/Module/Wiki.php:488 +msgid "Error creating wiki. Invalid name." +msgstr "Błąd podczas tworzenia wiki. nieprawidłowa nazwa." + +#: ../../Zotlabs/Module/Wiki.php:495 +msgid "A wiki with this name already exists." +msgstr "Wiki o tej nazwie już istnieje." + +#: ../../Zotlabs/Module/Wiki.php:508 +msgid "Wiki created, but error creating Home page." +msgstr "Utworzono wiki, ale podczas tworzenia strony głównej wystąpił błąd." + +#: ../../Zotlabs/Module/Wiki.php:515 +msgid "Error creating wiki" +msgstr "Błąd podczas tworzenia wiki" + +#: ../../Zotlabs/Module/Wiki.php:539 +msgid "Error updating wiki. Invalid name." +msgstr "Błąd podczas aktualizowania wiki. Błędna nazwa." + +#: ../../Zotlabs/Module/Wiki.php:559 +msgid "Error updating wiki" +msgstr "Błąd podczas aktualizowania wiki" + +#: ../../Zotlabs/Module/Wiki.php:574 +msgid "Wiki delete permission denied." +msgstr "Odmowa pozwolenia na usunięcie Wiki." + +#: ../../Zotlabs/Module/Wiki.php:584 +msgid "Error deleting wiki" +msgstr "Błąd podczas usuwania wiki" + +#: ../../Zotlabs/Module/Wiki.php:617 +msgid "New page created" +msgstr "Utworzono nową stronę" + +#: ../../Zotlabs/Module/Wiki.php:739 +msgid "Cannot delete Home" +msgstr "Nie można usunąć strony głównej" + +#: ../../Zotlabs/Module/Wiki.php:803 +msgid "Current Revision" +msgstr "Bieżąca wersja" + +#: ../../Zotlabs/Module/Wiki.php:803 +msgid "Selected Revision" +msgstr "Wybrana wersja" + +#: ../../Zotlabs/Module/Wiki.php:853 +msgid "You must be authenticated." +msgstr "Trzeba być uwierzytelnionym." + +#: ../../Zotlabs/Module/Blocks.php:97 ../../Zotlabs/Module/Blocks.php:155 +#: ../../Zotlabs/Module/Editblock.php:113 +msgid "Block Name" +msgstr "Nazwa bloku" + +#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2698 +msgid "Blocks" +msgstr "Bloki" + +#: ../../Zotlabs/Module/Blocks.php:156 +msgid "Block Title" +msgstr "Tytuł bloku" + +#: ../../Zotlabs/Module/Dircensor.php:42 +msgid "Entry censored" +msgstr "Wpis ocenzurowany" + +#: ../../Zotlabs/Module/Dircensor.php:45 +msgid "Entry uncensored" +msgstr "Wpis nieocenzurowany" + +#: ../../Zotlabs/Module/Locs.php:27 ../../Zotlabs/Module/Locs.php:66 +msgid "Location not found." +msgstr "Nie znaleziono lokalizacjid." + +#: ../../Zotlabs/Module/Locs.php:75 +msgid "Location lookup failed." +msgstr "Wyszukiwanie lokalizacji nie powiodło się." + +#: ../../Zotlabs/Module/Locs.php:79 +msgid "" +"Please select another location to become primary before removing the primary " +"location." +msgstr "" +"Przed usunięciem lokalizacji podstawowej wybierz inną lokalizację jako " +"główną." + +#: ../../Zotlabs/Module/Locs.php:108 +msgid "Syncing locations" +msgstr "Synchronizuję lokalizacje" + +#: ../../Zotlabs/Module/Locs.php:117 +msgid "No locations found." +msgstr "Nie znaleziono żadnych lokalizacji." + +#: ../../Zotlabs/Module/Locs.php:127 +msgid "Manage Channel Locations" +msgstr "Zarządzaj lokalizacjami kanałów" + +#: ../../Zotlabs/Module/Locs.php:130 +#: ../../extend/addon/hzaddons/workflow/workflow.php:285 +msgid "Primary" +msgstr "Podstawowy" + +#: ../../Zotlabs/Module/Locs.php:131 ../../Zotlabs/Module/Menu.php:177 +msgid "Drop" +msgstr "Upuść" + +#: ../../Zotlabs/Module/Locs.php:133 +msgid "Sync Now" +msgstr "Synchronizuj teraz" + +#: ../../Zotlabs/Module/Locs.php:134 +msgid "Please wait several minutes between consecutive operations." +msgstr "Poczekaj kilka minut między kolejnymi operacjami." + +#: ../../Zotlabs/Module/Locs.php:135 +msgid "" +"When possible, drop a location by logging into that website/hub and removing " +"your channel." +msgstr "" +"Jeśli to możliwe, upuść lokalizację, logując się do tego huba i usuwając " +"swój kanał." + +#: ../../Zotlabs/Module/Locs.php:136 +msgid "Use this form to drop the location if the hub is no longer operating." +msgstr "" +"Użyj tego formularza, aby usunąć lokalizację, jeśli hub już nie działa." + +#: ../../Zotlabs/Module/Chatsvc.php:131 +msgid "Away" +msgstr "Z dala" + +#: ../../Zotlabs/Module/Chatsvc.php:136 +msgid "Online" +msgstr "Na linii" + +#: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:345 +#: ../../include/features.php:369 ../../include/nav.php:444 +msgid "Photos" +msgstr "Zdjęcia" + +#: ../../Zotlabs/Module/Fbrowser.php:85 ../../Zotlabs/Storage/Browser.php:351 +#: ../../Zotlabs/Lib/Apps.php:340 ../../include/nav.php:452 +msgid "Files" +msgstr "Pliki" + +#: ../../Zotlabs/Module/Connedit.php:120 +msgid "Could not locate selected profile." +msgstr "Nie udało się znaleźć wybranego profilu." + +#: ../../Zotlabs/Module/Connedit.php:264 +msgid "Connection updated." +msgstr "Zaktualizowano połączenie." + +#: ../../Zotlabs/Module/Connedit.php:266 +msgid "Failed to update connection record." +msgstr "Nie udało się zaktualizować rekordu połączenia." + +#: ../../Zotlabs/Module/Connedit.php:309 +msgid "is now connected to" +msgstr "jest teraz połączony z" + +#: ../../Zotlabs/Module/Connedit.php:434 +msgid "Could not access address book record." +msgstr "Nie można uzyskać dostępu do rekordu książki adresowej." + +#: ../../Zotlabs/Module/Connedit.php:482 ../../Zotlabs/Module/Connedit.php:486 +msgid "Refresh failed - channel is currently unavailable." +msgstr "Odświeżenie nie powiodło się - kanał jest obecnie niedostępny." + +#: ../../Zotlabs/Module/Connedit.php:501 ../../Zotlabs/Module/Connedit.php:510 +#: ../../Zotlabs/Module/Connedit.php:519 ../../Zotlabs/Module/Connedit.php:528 +#: ../../Zotlabs/Module/Connedit.php:541 +msgid "Unable to set address book parameters." +msgstr "Nie można ustawić parametrów książki adresowej." + +#: ../../Zotlabs/Module/Connedit.php:560 +msgid "Connection has been removed." +msgstr "Połączenie zostało usunięte." + +#: ../../Zotlabs/Module/Connedit.php:600 ../../Zotlabs/Lib/Apps.php:344 +#: ../../include/conversation.php:1080 ../../include/nav.php:112 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:57 +msgid "View Profile" +msgstr "Wyświetl profil" + +#: ../../Zotlabs/Module/Connedit.php:603 +#, php-format +msgid "View %s's profile" +msgstr "Wyświetl profil %s" + +#: ../../Zotlabs/Module/Connedit.php:607 +msgid "Refresh Permissions" +msgstr "Odśwież uprawnienia" + +#: ../../Zotlabs/Module/Connedit.php:610 +msgid "Fetch updated permissions" +msgstr "Pobierz zaktualizowane uprawnienia" + +#: ../../Zotlabs/Module/Connedit.php:614 +msgid "Refresh Photo" +msgstr "Odśwież zdjęcie" + +#: ../../Zotlabs/Module/Connedit.php:617 +msgid "Fetch updated photo" +msgstr "Pobierz zaktualizowane zdjęcie" + +#: ../../Zotlabs/Module/Connedit.php:621 ../../include/conversation.php:1090 +msgid "Recent Activity" +msgstr "Ostatnia aktywność" + +#: ../../Zotlabs/Module/Connedit.php:624 +msgid "View recent posts and comments" +msgstr "Wyświetl najnowsze posty i komentarze" + +#: ../../Zotlabs/Module/Connedit.php:628 +#: ../../Zotlabs/Module/Admin/Accounts.php:177 +msgid "Unblock" +msgstr "Odblokuj" + +#: ../../Zotlabs/Module/Connedit.php:628 +#: ../../Zotlabs/Module/Admin/Accounts.php:176 +msgid "Block" +msgstr "Zablokuj" + +#: ../../Zotlabs/Module/Connedit.php:631 +msgid "Block (or Unblock) all communications with this connection" +msgstr "Zablokuj (lub odblokuj) całą komunikację z tym połączeniem" + +#: ../../Zotlabs/Module/Connedit.php:632 +msgid "This connection is blocked!" +msgstr "To połączenie jest zablokowane!" + +#: ../../Zotlabs/Module/Connedit.php:636 +msgid "Unignore" +msgstr "Nie ignoruj" + +#: ../../Zotlabs/Module/Connedit.php:636 +#: ../../Zotlabs/Module/Connections.php:344 +msgid "Ignore" +msgstr "Ignoruj" + +#: ../../Zotlabs/Module/Connedit.php:639 +msgid "Ignore (or Unignore) all inbound communications from this connection" +msgstr "Ignoruj (lub przywróć) całą komunikację przychodzącą z tego połączenia" + +#: ../../Zotlabs/Module/Connedit.php:640 +msgid "This connection is ignored!" +msgstr "To połączenie jest ignorowane!" + +#: ../../Zotlabs/Module/Connedit.php:644 +msgid "Unarchive" +msgstr "Przywróć z archiwum" + +#: ../../Zotlabs/Module/Connedit.php:644 +msgid "Archive" +msgstr "Archiwizuj" + +#: ../../Zotlabs/Module/Connedit.php:647 +msgid "" +"Archive (or Unarchive) this connection - mark channel dead but keep content" +msgstr "" +"Archiwizuj (lub przywróć) to połączenie - zaznacz kanał jako martwy, ale " +"zachowaj zawartość" + +#: ../../Zotlabs/Module/Connedit.php:648 +msgid "This connection is archived!" +msgstr "To połączenie zostało zarchiwizowane!" + +#: ../../Zotlabs/Module/Connedit.php:652 +msgid "Unhide" +msgstr "Odkryj" + +#: ../../Zotlabs/Module/Connedit.php:652 +msgid "Hide" +msgstr "Ukryj" + +#: ../../Zotlabs/Module/Connedit.php:655 +msgid "Hide or Unhide this connection from your other connections" +msgstr "Ukryj lub odkryj to połączenie przed innymi kontaktami" + +#: ../../Zotlabs/Module/Connedit.php:656 +msgid "This connection is hidden!" +msgstr "To połączenie jest ukryte!" + +#: ../../Zotlabs/Module/Connedit.php:663 +msgid "Delete this connection" +msgstr "Usuń to połączenie" + +#: ../../Zotlabs/Module/Connedit.php:671 +msgid "Fetch Vcard" +msgstr "Pobierz Vcard" + +#: ../../Zotlabs/Module/Connedit.php:674 +msgid "Fetch electronic calling card for this connection" +msgstr "Pobierz elektroniczną kartę telefoniczną dla tego połączenia" + +#: ../../Zotlabs/Module/Connedit.php:685 +msgid "Open Individual Permissions section by default" +msgstr "Otwórz domyślnie sekcję Uprawnienia indywidualne" + +#: ../../Zotlabs/Module/Connedit.php:708 +msgid "Affinity" +msgstr "Koligacja" + +#: ../../Zotlabs/Module/Connedit.php:711 +msgid "Open Set Affinity section by default" +msgstr "Otwieraj domyślnie sekcję Ustaw koligację" + +#: ../../Zotlabs/Module/Connedit.php:715 ../../Zotlabs/Widget/Affinity.php:30 +msgid "Me" +msgstr "Ja" + +#: ../../Zotlabs/Module/Connedit.php:716 ../../Zotlabs/Widget/Affinity.php:31 +msgid "Family" +msgstr "Rodzina" + +#: ../../Zotlabs/Module/Connedit.php:717 +#: ../../Zotlabs/Module/Settings/Channel.php:71 +#: ../../Zotlabs/Module/Settings/Channel.php:75 +#: ../../Zotlabs/Module/Settings/Channel.php:76 +#: ../../Zotlabs/Module/Settings/Channel.php:79 +#: ../../Zotlabs/Module/Settings/Channel.php:90 +#: ../../Zotlabs/Widget/Affinity.php:32 ../../include/channel.php:505 +#: ../../include/channel.php:506 ../../include/channel.php:513 +#: ../../include/selectors.php:134 +msgid "Friends" +msgstr "Przyjaciele" + +#: ../../Zotlabs/Module/Connedit.php:718 ../../Zotlabs/Widget/Affinity.php:33 +msgid "Acquaintances" +msgstr "Znajomi" + +#: ../../Zotlabs/Module/Connedit.php:719 +#: ../../Zotlabs/Module/Connections.php:97 +#: ../../Zotlabs/Module/Connections.php:111 +#: ../../Zotlabs/Widget/Affinity.php:34 +msgid "All" +msgstr "Wszyscy" + +#: ../../Zotlabs/Module/Connedit.php:748 +msgid "Filter" +msgstr "Filtr" + +#: ../../Zotlabs/Module/Connedit.php:751 +msgid "Open Custom Filter section by default" +msgstr "Otwieraj domyślnie sekcję Filtr niestandardowy" + +#: ../../Zotlabs/Module/Connedit.php:788 +msgid "Approve this connection" +msgstr "Zatwierdź to połączenie" + +#: ../../Zotlabs/Module/Connedit.php:788 +msgid "Accept connection to allow communication" +msgstr "Zaakceptuj połączenie, aby umożliwić komunikację" + +#: ../../Zotlabs/Module/Connedit.php:793 +msgid "Set Affinity" +msgstr "Ustaw skoligacenie" + +#: ../../Zotlabs/Module/Connedit.php:796 +msgid "Set Profile" +msgstr "Ustaw profil" + +#: ../../Zotlabs/Module/Connedit.php:799 +msgid "Set Affinity & Profile" +msgstr "Ustaw skoligacenie i profil" + +#: ../../Zotlabs/Module/Connedit.php:847 +msgid "This connection is unreachable from this location." +msgstr "To połączenie jest nieosiągalne z tej lokalizacji." + +#: ../../Zotlabs/Module/Connedit.php:848 +msgid "This connection may be unreachable from other channel locations." +msgstr "To połączenie może być nieosiągalne z innych lokalizacji kanału." + +#: ../../Zotlabs/Module/Connedit.php:850 +msgid "Location independence is not supported by their network." +msgstr "Niezależność lokalizacji nie jest obsługiwana przez ich sieć." + +#: ../../Zotlabs/Module/Connedit.php:856 +msgid "" +"This connection is unreachable from this location. Location independence is " +"not supported by their network." +msgstr "" +"To połączenie jest nieosiągalne z tej lokalizacji. Niezależność lokalizacji " +"nie jest obsługiwana przez ich sieć." + +#: ../../Zotlabs/Module/Connedit.php:859 ../../include/items.php:4524 +#, php-format +msgid "Connection: %s" +msgstr "Połączenie: %s" + +#: ../../Zotlabs/Module/Connedit.php:860 +msgid "Connection requests will be approved without your interaction" +msgstr "Prośby o połączenie zostaną zatwierdzone bez Twojej interakcji" + +#: ../../Zotlabs/Module/Connedit.php:869 +msgid "This connection's primary address is" +msgstr "Podstawowy adres tego połączenia to" + +#: ../../Zotlabs/Module/Connedit.php:870 +msgid "Available locations:" +msgstr "Dostępne lokalizacje:" + +#: ../../Zotlabs/Module/Connedit.php:876 +msgid "Connection Tools" +msgstr "Narzędzia połączeń" + +#: ../../Zotlabs/Module/Connedit.php:878 +msgid "Slide to adjust your degree of friendship" +msgstr "Przesuń, aby dostosować stopień przyjaźni" + +#: ../../Zotlabs/Module/Connedit.php:879 ../../Zotlabs/Module/Rate.php:155 +#: ../../include/js_strings.php:20 +msgid "Rating" +msgstr "Ocena" + +#: ../../Zotlabs/Module/Connedit.php:880 +msgid "Slide to adjust your rating" +msgstr "Przesuń, aby dostosować swoją ocenę" + +#: ../../Zotlabs/Module/Connedit.php:881 ../../Zotlabs/Module/Connedit.php:886 +msgid "Optionally explain your rating" +msgstr "Ewentualnie wyjaśnij swoją ocenę" + +#: ../../Zotlabs/Module/Connedit.php:883 +msgid "Custom Filter" +msgstr "Własny filtr" + +#: ../../Zotlabs/Module/Connedit.php:884 +msgid "Only import posts with this text" +msgstr "Importuj tylko posty z tym tekstem" + +#: ../../Zotlabs/Module/Connedit.php:884 ../../Zotlabs/Module/Connedit.php:885 +#: ../../Zotlabs/Module/Admin/Site.php:327 +#: ../../Zotlabs/Module/Admin/Site.php:328 +msgid "" +"words one per line or #tags or /patterns/ or lang=xx, leave blank to import " +"all posts" +msgstr "" +"słowa po jednym w wierszu lub #tags lub /patterns/ lub lang=xx, pozostaw " +"puste, aby zaimportować wszystkie posty" + +#: ../../Zotlabs/Module/Connedit.php:885 +msgid "Do not import posts with this text" +msgstr "Nie importuj postów z tym tekstem" + +#: ../../Zotlabs/Module/Connedit.php:887 +msgid "This information is public!" +msgstr "Ta informacja jest publiczna!" + +#: ../../Zotlabs/Module/Connedit.php:892 +msgid "Connection Pending Approval" +msgstr "Połączenie oczekujące na zatwierdzenie" + +#: ../../Zotlabs/Module/Connedit.php:897 +#, php-format +msgid "" +"Please choose the profile you would like to display to %s when viewing your " +"profile securely." +msgstr "" +"Wybierz profil, który chcesz wyświetlić dla %s, podczas bezpiecznego " +"przeglądania swojego profilu." + +#: ../../Zotlabs/Module/Connedit.php:899 ../../Zotlabs/Module/Tokens.php:180 +msgid "Their Settings" +msgstr "Ich ustawienia" + +#: ../../Zotlabs/Module/Connedit.php:903 ../../Zotlabs/Module/Tokens.php:187 +#: ../../Zotlabs/Module/Permcats.php:128 +msgid "" +"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " +"individual settings. You can not change those settings here." +msgstr "" +"Niektóre uprawnienia mogą być dziedziczone z ustawień prywatności Twojego kanału, które mają " +"wyższy priorytet niż indywidualne ustawienia. Nie możesz " +"tutaj zmienić tych ustawień." + +#: ../../Zotlabs/Module/Connedit.php:904 +msgid "" +"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " +"individual settings. You can change those settings here but they wont have " +"any impact unless the inherited setting changes." +msgstr "" +"Niektóre uprawnienia mogą być dziedziczone z ustawień prywatności Twojego kanału, te które mają " +"wyższy priorytet niż indywidualne ustawienia. Możesz zmienić te ustawienia " +"tutaj, ale nie będą one miały żadnego wpływu, chyba że odziedziczone " +"ustawienie ulegnie zmianie." + +#: ../../Zotlabs/Module/Connedit.php:905 +msgid "Last update:" +msgstr "Ostatnia aktualizacja:" + +#: ../../Zotlabs/Module/Connedit.php:913 +msgid "Details" +msgstr "Szczegóły" + +#: ../../Zotlabs/Module/Profile_photo.php:93 +#: ../../Zotlabs/Module/Cover_photo.php:85 +msgid "Image uploaded but image cropping failed." +msgstr "Obraz został przesłany, ale przycinanie obrazu nie powiodło się." + +#: ../../Zotlabs/Module/Profile_photo.php:147 +#: ../../Zotlabs/Module/Profile_photo.php:284 +#: ../../include/photo/photo_driver.php:417 +msgid "Profile Photos" +msgstr "Zdjęcia profilowe" + +#: ../../Zotlabs/Module/Profile_photo.php:166 +#: ../../Zotlabs/Module/Cover_photo.php:212 +msgid "Image resize failed." +msgstr "Zmiana rozmiaru obrazu nie powiodła się." + +#: ../../Zotlabs/Module/Profile_photo.php:254 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:298 +msgid "" +"Shift-reload the page or clear browser cache if the new photo does not " +"display immediately." +msgstr "" +"Shift-przeładuj stronę lub wyczyść pamięć podręczną przeglądarki, jeśli nowe " +"zdjęcie nie zostanie wyświetlone od razu." + +#: ../../Zotlabs/Module/Profile_photo.php:261 +#: ../../Zotlabs/Module/Cover_photo.php:241 ../../include/photos.php:196 +msgid "Unable to process image" +msgstr "Nie można przetworzyć obrazu" + +#: ../../Zotlabs/Module/Profile_photo.php:296 +#: ../../Zotlabs/Module/Cover_photo.php:265 +msgid "Image upload failed." +msgstr "Przesyłanie obrazu nie powiodło się." + +#: ../../Zotlabs/Module/Profile_photo.php:315 +#: ../../Zotlabs/Module/Cover_photo.php:282 +msgid "Unable to process image." +msgstr "Nie można przetworzyć obrazu." + +#: ../../Zotlabs/Module/Profile_photo.php:379 +#: ../../Zotlabs/Module/Profile_photo.php:431 +#: ../../Zotlabs/Module/Cover_photo.php:367 +#: ../../Zotlabs/Module/Cover_photo.php:382 +msgid "Photo not available." +msgstr "Zdjęcie nie jest dostępne." + +#: ../../Zotlabs/Module/Profile_photo.php:495 +msgid "" +"Your default profile photo is visible to anybody on the internet. Profile " +"photos for alternate profiles will inherit the permissions of the profile" +msgstr "" +"Twoje domyślne zdjęcie profilowe jest widoczne dla każdego w internecie. " +"Zdjęcia profilowe dla profili alternatywnych odziedziczą uprawnienia profilu" + +#: ../../Zotlabs/Module/Profile_photo.php:495 +msgid "" +"Your profile photo is visible to anybody on the internet and may be " +"distributed to other websites." +msgstr "" +"Twoje zdjęcie profilowe jest widoczne dla każdego w internecie i może być " +"rozpowszechniane na innych stronach internetowych." + +#: ../../Zotlabs/Module/Profile_photo.php:497 +#: ../../Zotlabs/Module/Cover_photo.php:420 +msgid "Upload File:" +msgstr "Przesłanie pliku:" + +#: ../../Zotlabs/Module/Profile_photo.php:498 +#: ../../Zotlabs/Module/Cover_photo.php:421 +msgid "Select a profile:" +msgstr "Wybierz profil:" + +#: ../../Zotlabs/Module/Profile_photo.php:499 +msgid "Use Photo for Profile" +msgstr "Użyj zdjęcia do profilu" + +#: ../../Zotlabs/Module/Profile_photo.php:499 +msgid "Change Profile Photo" +msgstr "Zmień zdjęcie profilowe" + +#: ../../Zotlabs/Module/Profile_photo.php:500 +msgid "Use" +msgstr "Użyj" + +#: ../../Zotlabs/Module/Profile_photo.php:500 +#: ../../Zotlabs/Module/Photos.php:688 ../../Zotlabs/Module/Cover_photo.php:423 +#: ../../Zotlabs/Module/Embedphotos.php:188 +#: ../../Zotlabs/Storage/Browser.php:540 ../../Zotlabs/Widget/Cdav.php:146 +#: ../../Zotlabs/Widget/Cdav.php:182 ../../Zotlabs/Widget/Portfolio.php:110 +#: ../../Zotlabs/Widget/Album.php:97 +msgid "Upload" +msgstr "Prześlij" + +#: ../../Zotlabs/Module/Profile_photo.php:501 +#: ../../Zotlabs/Module/Photos.php:996 ../../Zotlabs/Module/Tagrm.php:137 +#: ../../Zotlabs/Module/Admin/Addons.php:459 +#: ../../Zotlabs/Module/Cover_photo.php:424 +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:91 +msgid "Remove" +msgstr "Usuń" + +#: ../../Zotlabs/Module/Profile_photo.php:505 +#: ../../Zotlabs/Module/Profile_photo.php:506 +#: ../../Zotlabs/Module/Cover_photo.php:426 +#: ../../Zotlabs/Module/Cover_photo.php:427 +msgid "Use a photo from your albums" +msgstr "Użyj zdjęcia ze swoich albumów" + +#: ../../Zotlabs/Module/Profile_photo.php:516 +#: ../../Zotlabs/Module/Cover_photo.php:438 +msgid "Select existing photo" +msgstr "Wybierz istniejące zdjęcie" + +#: ../../Zotlabs/Module/Profile_photo.php:535 +#: ../../Zotlabs/Module/Cover_photo.php:455 +msgid "Crop Image" +msgstr "Przytnij zdjęcie" + +#: ../../Zotlabs/Module/Profile_photo.php:536 +#: ../../Zotlabs/Module/Cover_photo.php:456 +msgid "Please adjust the image cropping for optimum viewing." +msgstr "Dostosuj kadrowanie obrazu, aby uzyskać optymalne wyświetlanie." + +#: ../../Zotlabs/Module/Profile_photo.php:538 +#: ../../Zotlabs/Module/Cover_photo.php:458 +msgid "Done Editing" +msgstr "Zakończono edycję" + +#: ../../Zotlabs/Module/Sharedwithme.php:105 +msgid "Files: shared with me" +msgstr "Pliki: udostępnione mi" + +#: ../../Zotlabs/Module/Sharedwithme.php:107 +msgid "NEW" +msgstr "NOWY" + +#: ../../Zotlabs/Module/Sharedwithme.php:108 +#: ../../Zotlabs/Storage/Browser.php:379 ../../include/text.php:1562 +msgid "Size" +msgstr "Rozmiar" + +#: ../../Zotlabs/Module/Sharedwithme.php:109 +#: ../../Zotlabs/Storage/Browser.php:380 +msgid "Last Modified" +msgstr "Ostatnio zmodyfikowane" + +#: ../../Zotlabs/Module/Sharedwithme.php:110 +msgid "Remove all files" +msgstr "Usuń wszystkie pliki" + +#: ../../Zotlabs/Module/Sharedwithme.php:111 +msgid "Remove this file" +msgstr "Usuń ten plik" + +#: ../../Zotlabs/Module/Editlayout.php:137 +msgid "Edit Layout" +msgstr "Edytuj układ" + +#: ../../Zotlabs/Module/Manage.php:145 +msgid "Create a new channel" +msgstr "Utwórz nowy kanał" + +#: ../../Zotlabs/Module/Manage.php:170 ../../Zotlabs/Lib/Apps.php:337 +#: ../../include/nav.php:98 +msgid "Channel Manager" +msgstr "Menadżer kanałów" + +#: ../../Zotlabs/Module/Manage.php:171 +msgid "Current Channel" +msgstr "Bieżący kanał" + +#: ../../Zotlabs/Module/Manage.php:173 +msgid "Switch to one of your channels by selecting it." +msgstr "Przełącz się na jeden ze swoich kanałów, wybierając go." + +#: ../../Zotlabs/Module/Manage.php:174 +msgid "Default Channel" +msgstr "Domyślny kanał" + +#: ../../Zotlabs/Module/Manage.php:175 +msgid "Make Default" +msgstr "Ustaw jako domyślny" + +#: ../../Zotlabs/Module/Manage.php:178 +#, php-format +msgid "%d new messages" +msgstr "%d nowych wiadomości" + +#: ../../Zotlabs/Module/Manage.php:179 +#, php-format +msgid "%d new introductions" +msgstr "%d nowych wprowadzeń" + +#: ../../Zotlabs/Module/Manage.php:181 +msgid "Delegated Channel" +msgstr "Deleguj kanał" + +#: ../../Zotlabs/Module/Follow.php:93 +msgid "Connection added." +msgstr "Dodano połączenie." + +#: ../../Zotlabs/Module/Item.php:450 ../../Zotlabs/Module/Pin.php:35 +msgid "Unable to locate original post." +msgstr "Nie można znaleźć oryginalnego postu." + +#: ../../Zotlabs/Module/Item.php:736 +msgid "Empty post discarded." +msgstr "Pusty post został odrzucony." + +#: ../../Zotlabs/Module/Item.php:1187 +msgid "Duplicate post suppressed." +msgstr "Powielony post został wyłączony." + +#: ../../Zotlabs/Module/Item.php:1332 +msgid "System error. Post not saved." +msgstr "Błąd systemu. Post nie został zapisany." + +#: ../../Zotlabs/Module/Item.php:1366 +msgid "Your comment is awaiting approval." +msgstr "Twój komentarz oczekuje na zatwierdzenie." + +#: ../../Zotlabs/Module/Item.php:1496 +msgid "Unable to obtain post information from database." +msgstr "Nie można uzyskać z bazy danych informacji o tym poście." + +#: ../../Zotlabs/Module/Item.php:1503 +#, php-format +msgid "You have reached your limit of %1$.0f top level posts." +msgstr "Osiągnięty został limit %1$.0f postów najwyższego poziomu." + +#: ../../Zotlabs/Module/Item.php:1510 +#, php-format +msgid "You have reached your limit of %1$.0f webpages." +msgstr "Osiągnięty został limit %1$.0f stron internetowych." + +#: ../../Zotlabs/Module/Rate.php:156 +msgid "Website:" +msgstr "Serwis internetowy:" + +#: ../../Zotlabs/Module/Rate.php:159 +#, php-format +msgid "Remote Channel [%s] (not yet known on this site)" +msgstr "Kanał zdalny [% s] (jeszcze nieznany w tym serwisie)" + +#: ../../Zotlabs/Module/Rate.php:160 +msgid "Rating (this information is public)" +msgstr "Ocena (ta informacja jest publiczna)" + +#: ../../Zotlabs/Module/Rate.php:161 +msgid "Optionally explain your rating (this information is public)" +msgstr "Ewentualnie wyjaśnij swoją ocenę (ta informacja jest publiczna)" + +#: ../../Zotlabs/Module/Page.php:39 ../../Zotlabs/Module/Block.php:29 +msgid "Invalid item." +msgstr "Nieprawidłowy element." + +#: ../../Zotlabs/Module/Page.php:136 ../../Zotlabs/Module/Display.php:136 +#: ../../Zotlabs/Module/Display.php:153 ../../Zotlabs/Module/Display.php:173 +#: ../../Zotlabs/Module/Display.php:179 ../../Zotlabs/Module/Block.php:77 +#: ../../Zotlabs/Web/Router.php:185 ../../Zotlabs/Lib/NativeWikiPage.php:521 +#: ../../include/help.php:132 +msgid "Page not found." +msgstr "Nie znaleziono strony." + +#: ../../Zotlabs/Module/Page.php:173 +msgid "" +"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " +"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, " +"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo " +"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse " +"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " +"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +msgstr "" +"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " +"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, " +"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo " +"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse " +"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " +"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + +#: ../../Zotlabs/Module/Xchan.php:10 +msgid "Xchan Lookup" +msgstr "Wyszukiwanie xchan" + +#: ../../Zotlabs/Module/Xchan.php:13 +msgid "Lookup xchan beginning with (or webbie): " +msgstr "Wyszukaj xchan (lub webbie) zaczynając od: " + +#: ../../Zotlabs/Module/Xchan.php:41 ../../Zotlabs/Module/Mitem.php:134 +#: ../../Zotlabs/Module/Menu.php:232 +msgid "Not found." +msgstr "Nie znaleziono." + +#: ../../Zotlabs/Module/Achievements.php:38 +msgid "Some blurb about what to do when you're new here" +msgstr "Kilka uwag o tym, co robisz, gdy jesteś tu nowy" + +#: ../../Zotlabs/Module/Subthread.php:143 +#, php-format +msgid "%1$s is following %2$s's %3$s" +msgstr "%1$s obserwuje %3$s %2$s" + +#: ../../Zotlabs/Module/Subthread.php:145 +#, php-format +msgid "%1$s stopped following %2$s's %3$s" +msgstr "%1$s przestał obserwować %3$s %2$s" + +#: ../../Zotlabs/Module/Regmod.php:15 +msgid "Please login." +msgstr "Proszę się zalogować." + +#: ../../Zotlabs/Module/Editblock.php:138 +msgid "Edit Block" +msgstr "Edytuj blok" + +#: ../../Zotlabs/Module/Impel.php:43 ../../include/bbcode.php:316 +msgid "webpage" +msgstr "strona internetowa" + +#: ../../Zotlabs/Module/Impel.php:48 ../../include/bbcode.php:322 +msgid "block" +msgstr "blok" + +#: ../../Zotlabs/Module/Impel.php:53 ../../include/bbcode.php:319 +msgid "layout" +msgstr "układ" + +#: ../../Zotlabs/Module/Impel.php:60 ../../include/bbcode.php:325 +msgid "menu" +msgstr "menu" + +#: ../../Zotlabs/Module/Impel.php:185 +#, php-format +msgid "%s element installed" +msgstr "Element %s zainstalowany" + +#: ../../Zotlabs/Module/Impel.php:188 +#, php-format +msgid "%s element installation failed" +msgstr "Instalacja elementu %s nie powiodła się" + +#: ../../Zotlabs/Module/Pubsites.php:25 ../../Zotlabs/Widget/Pubsites.php:12 +msgid "Public Hubs" +msgstr "Huby publiczne" + +#: ../../Zotlabs/Module/Pubsites.php:28 +msgid "" +"The listed hubs allow public registration for the $Projectname network. All " +"hubs in the network are interlinked so membership on any of them conveys " +"membership in the network as a whole. Some hubs may require subscription or " +"provide tiered service plans. The hub itself may provide " +"additional details." +msgstr "" +"Wymienione huby umożliwiają publiczną rejestrację w sieci $Projectname. " +"Wszystkie huby w sieci są ze sobą połączone, więc członkostwo w " +"którymkolwiek z nich oznacza członkostwo w całej sieci. Niektóre huby mogą " +"wymagać subskrypcji lub oferować warstwowe plany usług. Sam hub " +"może podać dodatkowe szczegóły." + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Hub URL" +msgstr "Adres URL huba" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Access Type" +msgstr "Typ dostępu" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Registration Policy" +msgstr "Zasady rejestracji" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Stats" +msgstr "Statystyki" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Software" +msgstr "Oprogramowanie" + +#: ../../Zotlabs/Module/Pubsites.php:36 ../../Zotlabs/Module/Ratings.php:97 +#: ../../include/conversation.php:1130 +msgid "Ratings" +msgstr "Oceny" + +#: ../../Zotlabs/Module/Pubsites.php:50 +msgid "Rate" +msgstr "Ocena" + +#: ../../Zotlabs/Module/Chat.php:29 ../../Zotlabs/Module/Channel.php:42 +#: ../../Zotlabs/Module/Ochannel.php:32 +msgid "You must be logged in to see this page." +msgstr "Musisz być zalogowany, aby zobaczyć tę stronę." + +#: ../../Zotlabs/Module/Chat.php:100 +msgid "Chatrooms App" +msgstr "Aplikacja Chatrooms" + +#: ../../Zotlabs/Module/Chat.php:101 +msgid "Access Controlled Chatrooms" +msgstr "Dostęp do kontrolowanych czatów" + +#: ../../Zotlabs/Module/Chat.php:194 +msgid "Room not found" +msgstr "Nie znaleziono pokoju" + +#: ../../Zotlabs/Module/Chat.php:210 +msgid "Leave Room" +msgstr "Opuść pokój" + +#: ../../Zotlabs/Module/Chat.php:211 +msgid "Delete Room" +msgstr "Usuń pokój" + +#: ../../Zotlabs/Module/Chat.php:212 +msgid "I am away right now" +msgstr "Nie ma mnie teraz" + +#: ../../Zotlabs/Module/Chat.php:213 +msgid "I am online" +msgstr "Jestem dostępny" + +#: ../../Zotlabs/Module/Chat.php:215 +msgid "Bookmark this room" +msgstr "Zaznacz ten pokój" + +#: ../../Zotlabs/Module/Chat.php:218 ../../include/conversation.php:1380 +#: ../../extend/addon/hzaddons/hsse/hsse.php:134 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:119 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:240 +msgid "Please enter a link URL:" +msgstr "Proszę wprowadzić adres URL linku:" + +#: ../../Zotlabs/Module/Chat.php:219 ../../Zotlabs/Lib/ThreadItem.php:839 +#: ../../include/conversation.php:1508 +#: ../../extend/addon/hzaddons/hsse/hsse.php:255 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:172 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:315 +msgid "Encrypt text" +msgstr "Szyfruj tekst" + +#: ../../Zotlabs/Module/Chat.php:238 +msgid "New Chatroom" +msgstr "Nowy czat" + +#: ../../Zotlabs/Module/Chat.php:239 +msgid "Chatroom name" +msgstr "Nazwa czatu" + +#: ../../Zotlabs/Module/Chat.php:240 +msgid "Expiration of chats (minutes)" +msgstr "Wygaśnięcie czatów (minuty)" + +#: ../../Zotlabs/Module/Chat.php:256 +#, php-format +msgid "%1$s's Chatrooms" +msgstr "Czaty %1$s" + +#: ../../Zotlabs/Module/Chat.php:261 +msgid "No chatrooms available" +msgstr "Brak dostępnych czatów" + +#: ../../Zotlabs/Module/Chat.php:265 +msgid "Expiration" +msgstr "Wygaśnięcie" + +#: ../../Zotlabs/Module/Chat.php:266 +msgid "min" +msgstr "min" + +#: ../../Zotlabs/Module/Uexport.php:61 +msgid "Channel Export App" +msgstr "Aplikacja Channel Export" + +#: ../../Zotlabs/Module/Uexport.php:62 +msgid "Export your channel" +msgstr "Wyeksportuj swój kanał" + +#: ../../Zotlabs/Module/Uexport.php:72 ../../Zotlabs/Module/Uexport.php:73 +msgid "Export Channel" +msgstr "Eksport kanału" + +#: ../../Zotlabs/Module/Uexport.php:74 +msgid "" +"Export your basic channel information to a file. This acts as a backup of " +"your connections, permissions, profile and basic data, which can be used to " +"import your data to a new server hub, but does not contain your content." +msgstr "" +"Wyeksportuj do pliku podstawowe informacje o kanale. Działa to jako kopia " +"zapasowa połączeń, uprawnień, profilu i podstawowych danych, których można " +"użyć do zaimportowania danych do nowego huba, ale nie zawiera treści." + +#: ../../Zotlabs/Module/Uexport.php:75 +msgid "Export Content" +msgstr "Eksport treści" + +#: ../../Zotlabs/Module/Uexport.php:76 +msgid "" +"Export your channel information and recent content to a JSON backup that can " +"be restored or imported to another server hub. This backs up all of your " +"connections, permissions, profile data and several months of posts. This " +"file may be VERY large. Please be patient - it may take several minutes for " +"this download to begin." +msgstr "" +"Wyeksportuj informacje o kanale i najnowsze treści do kopii zapasowej JSON, " +"którą można przywrócić lub zaimportować do innego huba. Tworzy to kopie " +"zapasowe wszystkich połączeń, uprawnień, danych profilu i kilku miesięcy " +"postów. Ten plik może być BARDZO duży. Prosimy o cierpliwość - rozpoczęcie " +"pobierania może zająć kilka minut." + +#: ../../Zotlabs/Module/Uexport.php:78 +msgid "Export your posts from a given year." +msgstr "Eksportuj swoje posty z danego roku." + +#: ../../Zotlabs/Module/Uexport.php:80 +msgid "" +"You may also export your posts and conversations for a particular year or " +"month. Adjust the date in your browser location bar to select other dates. " +"If the export fails (possibly due to memory exhaustion on your server hub), " +"please try again selecting a more limited date range." +msgstr "" +"Można także wyeksportować swoje posty i rozmowy z określonego rok lub " +"miesiąca. Dostosuj datę na pasku adresu przeglądarki, aby wybrać inne daty. " +"Jeśli eksport się nie powiedzie (prawdopodobnie z powodu wyczerpania pamięci " +"w serwera huba), spróbuj ponownie, wybierając bardziej ograniczony zakres " +"dat." + +#: ../../Zotlabs/Module/Uexport.php:81 +#, php-format +msgid "" +"To select all posts for a given year, such as this year, visit %2$s" +msgstr "" +"Aby wybrać wszystkie posty z danego roku, na przykład tego roku, odwiedź %2$s" + +#: ../../Zotlabs/Module/Uexport.php:82 +#, php-format +msgid "" +"To select all posts for a given month, such as January of this year, visit " +"%2$s" +msgstr "" +"Aby wybrać wszystkie posty z danego miesiąca, np. stycznia tego roku, " +"odwiedź %2$s" + +#: ../../Zotlabs/Module/Uexport.php:83 +#, php-format +msgid "" +"These content files may be imported or restored by visiting " +"%2$s on any site containing your channel. For best results please import " +"or restore these in date order (oldest first)." +msgstr "" +"Te pliki treści można zaimportować lub przywrócić, odwiedzając stronę %2$s w dowolnym serwisie zawierającym Twój kanał. Aby " +"uzyskać najlepsze wyniki, zaimportuj lub przywróć je w kolejności (od " +"najstarszych)." + +#: ../../Zotlabs/Module/Lostpass.php:19 +msgid "No valid account found." +msgstr "Nie znaleziono prawidłowego konta." + +#: ../../Zotlabs/Module/Lostpass.php:33 +msgid "Password reset request issued. Check your email." +msgstr "Wysłano prośbę o zresetowanie hasła. Sprawdź swoją skrzynkę e-mail." + +#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108 +#, php-format +msgid "Site Member (%s)" +msgstr "Członek serwisu (%s)" + +#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49 +#, php-format +msgid "Password reset requested at %s" +msgstr "Zresetowano hasło na %s" + +#: ../../Zotlabs/Module/Lostpass.php:68 +msgid "" +"Request could not be verified. (You may have previously submitted it.) " +"Password reset failed." +msgstr "" +"Nie można zweryfikować żądania. (Możliwe, że zostało już przesłane). " +"Resetowanie hasła nie powiodło się." + +#: ../../Zotlabs/Module/Lostpass.php:91 ../../boot.php:1714 +msgid "Password Reset" +msgstr "Resetowanie hasła" + +#: ../../Zotlabs/Module/Lostpass.php:92 +msgid "Your password has been reset as requested." +msgstr "Twoje hasło zostało zresetowane zgodnie z żądaniem." + +#: ../../Zotlabs/Module/Lostpass.php:93 +msgid "Your new password is" +msgstr "Twoje nowe hasło to" + +#: ../../Zotlabs/Module/Lostpass.php:94 +msgid "Save or copy your new password - and then" +msgstr "Zapisz lub skopiuj nowe hasło - a następnie" + +#: ../../Zotlabs/Module/Lostpass.php:95 +msgid "click here to login" +msgstr "kliknij tutaj aby się zalogować" + +#: ../../Zotlabs/Module/Lostpass.php:96 +msgid "" +"Your password may be changed from the Settings page after " +"successful login." +msgstr "" +"Twoje hasło może zostać zmienione na stronie Ustawienia po " +"pomyślnym zalogowaniu." + +#: ../../Zotlabs/Module/Lostpass.php:117 +#, php-format +msgid "Your password has changed at %s" +msgstr "Twoje hasło zostało zmienione na %s" + +#: ../../Zotlabs/Module/Lostpass.php:130 +msgid "Forgot your Password?" +msgstr "Zapomniałeś hasła?" + +#: ../../Zotlabs/Module/Lostpass.php:131 +msgid "" +"Enter your email address and submit to have your password reset. Then check " +"your email for further instructions." +msgstr "" +"Wpisz swój adres e-mail i prześlij, aby zresetować hasło. Następnie sprawdź " +"swoja skrzynkę e-mail, aby uzyskać dalsze instrukcje." + +#: ../../Zotlabs/Module/Lostpass.php:132 +msgid "Email Address" +msgstr "Adres e-mail" + +#: ../../Zotlabs/Module/Vote.php:40 +msgid "Poll not found." +msgstr "Nie znaleziono ankiety." + +#: ../../Zotlabs/Module/Vote.php:71 +msgid "Invalid response." +msgstr "Nieprawidłowa odpowiedź." + +#: ../../Zotlabs/Module/Vote.php:132 +msgid "Response submitted. Updates may not appear instantly." +msgstr "Odpowiedź przesłana. Aktualizacje mogą nie pojawiać się natychmiast." + +#: ../../Zotlabs/Module/Ping.php:337 ../../Zotlabs/Lib/Enotify.php:948 +msgid "sent you a private message" +msgstr "wysłał Ci prywatną wiadomość" + +#: ../../Zotlabs/Module/Ping.php:393 ../../Zotlabs/Lib/Enotify.php:914 +msgid "added your channel" +msgstr "dodał Twój kanał" + +#: ../../Zotlabs/Module/Ping.php:418 ../../Zotlabs/Lib/Enotify.php:986 +msgid "requires approval" +msgstr "wymaga zatwierdzenia" + +#: ../../Zotlabs/Module/Ping.php:428 ../../Zotlabs/Lib/Enotify.php:957 +msgid "g A l F d" +msgstr "g A l F d" + +#: ../../Zotlabs/Module/Ping.php:446 ../../Zotlabs/Lib/Enotify.php:960 +msgid "[today]" +msgstr "[dzisiaj]" + +#: ../../Zotlabs/Module/Ping.php:456 +msgid "posted an event" +msgstr "opublikował wydarzenie" + +#: ../../Zotlabs/Module/Ping.php:490 ../../Zotlabs/Lib/Enotify.php:829 +#: ../../Zotlabs/Lib/Enotify.php:931 +msgid "shared a file with you" +msgstr "udostępnił Ci plik" + +#: ../../Zotlabs/Module/Display.php:359 ../../Zotlabs/Module/Channel.php:449 +msgid "" +"You must enable javascript for your browser to be able to view this content." +msgstr "" +"Aby przeglądać te treści, musisz włączyć obsługę JavaScript w swojej " +"przeglądarce." + +#: ../../Zotlabs/Module/Display.php:377 +msgid "Article" +msgstr "Artykuł" + +#: ../../Zotlabs/Module/Display.php:422 +msgid "Item has been removed." +msgstr "Element został usunięty." + +#: ../../Zotlabs/Module/Admin.php:96 +#: ../../Zotlabs/Module/Admin/Accounts.php:167 +#: ../../Zotlabs/Module/Admin/Accounts.php:180 +#: ../../Zotlabs/Widget/Admin.php:23 +msgid "Accounts" +msgstr "Konta" + +#: ../../Zotlabs/Module/Admin.php:97 +msgid "Blocked accounts" +msgstr "Zablokowane konta" + +#: ../../Zotlabs/Module/Admin.php:98 +msgid "Expired accounts" +msgstr "Wygasłe konta" + +#: ../../Zotlabs/Module/Admin.php:99 +msgid "Expiring accounts" +msgstr "Wygasające konta" + +#: ../../Zotlabs/Module/Admin.php:114 +#: ../../Zotlabs/Module/Admin/Channels.php:146 +#: ../../Zotlabs/Widget/Admin.php:24 +msgid "Channels" +msgstr "Kanały" + +#: ../../Zotlabs/Module/Admin.php:120 +msgid "Message queues" +msgstr "Kolejki wiadomości" + +#: ../../Zotlabs/Module/Admin.php:134 +msgid "Your software should be updated" +msgstr "Twoje oprogramowanie powinno zostać zaktualizowane" + +#: ../../Zotlabs/Module/Admin.php:138 ../../Zotlabs/Module/Admin/Themes.php:122 +#: ../../Zotlabs/Module/Admin/Themes.php:156 +#: ../../Zotlabs/Module/Admin/Security.php:98 +#: ../../Zotlabs/Module/Admin/Accounts.php:166 +#: ../../Zotlabs/Module/Admin/Channels.php:145 +#: ../../Zotlabs/Module/Admin/Logs.php:82 +#: ../../Zotlabs/Module/Admin/Addons.php:342 +#: ../../Zotlabs/Module/Admin/Addons.php:440 +#: ../../Zotlabs/Module/Admin/Site.php:291 +msgid "Administration" +msgstr "Administracja" + +#: ../../Zotlabs/Module/Admin.php:139 +msgid "Summary" +msgstr "Posumowanie" + +#: ../../Zotlabs/Module/Admin.php:142 +msgid "Registered accounts" +msgstr "Zarejestrowane konta" + +#: ../../Zotlabs/Module/Admin.php:143 +msgid "Pending registrations" +msgstr "Rejestracja oczekująca" + +#: ../../Zotlabs/Module/Admin.php:144 +msgid "Registered channels" +msgstr "Zarejestrowane kanały" + +#: ../../Zotlabs/Module/Admin.php:145 +msgid "Active addons" +msgstr "Aktywne dodatki" + +#: ../../Zotlabs/Module/Admin.php:146 +msgid "Version" +msgstr "Wersja" + +#: ../../Zotlabs/Module/Admin.php:147 +msgid "Repository version (master)" +msgstr "Wersja repozytorium (master)" + +#: ../../Zotlabs/Module/Admin.php:148 +msgid "Repository version (dev)" +msgstr "Wersja repozytorium (dev)" + +#: ../../Zotlabs/Module/Photos.php:80 +msgid "Page owner information could not be retrieved." +msgstr "Nie można pobrać informacji o właścicielu strony." + +#: ../../Zotlabs/Module/Photos.php:96 ../../Zotlabs/Module/Photos.php:115 +msgid "Album not found." +msgstr "Nie znaleziono albumu." + +#: ../../Zotlabs/Module/Photos.php:105 +msgid "Delete Album" +msgstr "Usuń album" + +#: ../../Zotlabs/Module/Photos.php:176 ../../Zotlabs/Module/Photos.php:1059 +msgid "Delete Photo" +msgstr "Usuń zdjęcie" + +#: ../../Zotlabs/Module/Photos.php:530 +msgid "No photos selected" +msgstr "Nie wybrano zdjęć" + +#: ../../Zotlabs/Module/Photos.php:579 +msgid "Access to this item is restricted." +msgstr "Dostęp do tego elementu jest ograniczony." + +#: ../../Zotlabs/Module/Photos.php:622 +#, php-format +msgid "%1$.2f MB of %2$.2f MB photo storage used." +msgstr "Wykorzystane miejsce na zdjęcia: %1$.2f MB z %2$.2f MB." + +#: ../../Zotlabs/Module/Photos.php:625 +#, php-format +msgid "%1$.2f MB photo storage used." +msgstr "Wykorzystane miejsce na zdjęcia: %1$.2f MB." + +#: ../../Zotlabs/Module/Photos.php:667 +msgid "Upload Photos" +msgstr "Prześlij zdjęcia" + +#: ../../Zotlabs/Module/Photos.php:671 +msgid "Enter an album name" +msgstr "Wpisz nazwę albumu" + +#: ../../Zotlabs/Module/Photos.php:672 +msgid "or select an existing album (doubleclick)" +msgstr "lub wybierz istniejący album (podwójne kliknięcie)" + +#: ../../Zotlabs/Module/Photos.php:673 +msgid "Create a status post for this upload" +msgstr "Utwórz post o stanie tego przesyłania" + +#: ../../Zotlabs/Module/Photos.php:675 +msgid "Description (optional)" +msgstr "Opis (opcjonalnie)" + +#: ../../Zotlabs/Module/Photos.php:761 +msgid "Show Newest First" +msgstr "Pokaż najpierw najnowsze" + +#: ../../Zotlabs/Module/Photos.php:763 +msgid "Show Oldest First" +msgstr "Pokaż najpierw najstarsze" + +#: ../../Zotlabs/Module/Photos.php:787 ../../Zotlabs/Module/Photos.php:1333 +#: ../../Zotlabs/Module/Embedphotos.php:170 +#: ../../Zotlabs/Widget/Portfolio.php:87 ../../Zotlabs/Widget/Album.php:78 +msgid "View Photo" +msgstr "Zobacz zdjęcie" + +#: ../../Zotlabs/Module/Photos.php:793 ../../Zotlabs/Module/Photos.php:1255 +#: ../../Zotlabs/Module/Embedphotos.php:176 ../../Zotlabs/Lib/Apps.php:1112 +#: ../../Zotlabs/Lib/Apps.php:1196 ../../Zotlabs/Lib/Activity.php:1508 +#: ../../Zotlabs/Widget/Portfolio.php:95 ../../Zotlabs/Widget/Pinned.php:270 +#: ../../Zotlabs/Widget/Album.php:84 ../../include/conversation.php:1211 +#: ../../include/cdav.php:158 ../../include/cdav.php:159 +#: ../../include/cdav.php:167 ../../extend/addon/hzaddons/pubcrawl/as.php:1187 +msgid "Unknown" +msgstr "Nieznane" + +#: ../../Zotlabs/Module/Photos.php:818 ../../Zotlabs/Module/Embedphotos.php:186 +#: ../../Zotlabs/Widget/Portfolio.php:108 ../../Zotlabs/Widget/Album.php:95 +msgid "Edit Album" +msgstr "Edytuj album" + +#: ../../Zotlabs/Module/Photos.php:820 ../../Zotlabs/Module/Photos.php:1364 +msgid "Add Photos" +msgstr "Dodaj zdjęcia" + +#: ../../Zotlabs/Module/Photos.php:868 +msgid "Permission denied. Access to this item may be restricted." +msgstr "Odmowa dostęþu. Dostęp do tej pozycji może być ograniczony." + +#: ../../Zotlabs/Module/Photos.php:870 +msgid "Photo not available" +msgstr "Zdjęcie niedostępne" + +#: ../../Zotlabs/Module/Photos.php:928 +msgid "Use as profile photo" +msgstr "Użyj jako zdjęcie profilowe" + +#: ../../Zotlabs/Module/Photos.php:929 +msgid "Use as cover photo" +msgstr "Użyj jako zdjęcia okładkowe" + +#: ../../Zotlabs/Module/Photos.php:936 +msgid "Private Photo" +msgstr "Zdjęcie prywatne" + +#: ../../Zotlabs/Module/Photos.php:951 +msgid "View Full Size" +msgstr "Zobacz pełny rozmiar" + +#: ../../Zotlabs/Module/Photos.php:1033 +msgid "Edit photo" +msgstr "Edutuj zdjęcie" + +#: ../../Zotlabs/Module/Photos.php:1035 +msgid "Rotate CW (right)" +msgstr "Obróć w prawo" + +#: ../../Zotlabs/Module/Photos.php:1036 +msgid "Rotate CCW (left)" +msgstr "Obróć w lewo" + +#: ../../Zotlabs/Module/Photos.php:1039 +msgid "Move photo to album" +msgstr "Przenieś zdjęcie do albumu" + +#: ../../Zotlabs/Module/Photos.php:1040 +msgid "Enter a new album name" +msgstr "Wpisz nową nazwę albumu" + +#: ../../Zotlabs/Module/Photos.php:1041 +msgid "or select an existing one (doubleclick)" +msgstr "lub wybierz istniejący (podwójne kliknięcie)" + +#: ../../Zotlabs/Module/Photos.php:1046 +msgid "Add a Tag" +msgstr "Dodaj tag" + +#: ../../Zotlabs/Module/Photos.php:1054 +msgid "Example: @bob, @Barbara_Jensen, @jim@example.com" +msgstr "Przykład: @bob, @Barbara_Jensen, @jim@example.com" + +#: ../../Zotlabs/Module/Photos.php:1057 +msgid "Flag as adult in album view" +msgstr "Oznacz jako \"dla dorosłych\" w widoku albumu" + +#: ../../Zotlabs/Module/Photos.php:1076 ../../Zotlabs/Lib/ThreadItem.php:317 +msgid "I like this (toggle)" +msgstr "Lubię to (przełącz)" + +#: ../../Zotlabs/Module/Photos.php:1077 ../../Zotlabs/Lib/ThreadItem.php:318 +msgid "I don't like this (toggle)" +msgstr "Nie podoba mi się to (przełącz)" + +#: ../../Zotlabs/Module/Photos.php:1079 ../../Zotlabs/Lib/ThreadItem.php:501 +#: ../../include/conversation.php:827 +msgid "Please wait" +msgstr "Proszę czekać" + +#: ../../Zotlabs/Module/Photos.php:1095 ../../Zotlabs/Module/Photos.php:1213 +#: ../../Zotlabs/Lib/ThreadItem.php:822 +msgid "This is you" +msgstr "To jesteś ty" + +#: ../../Zotlabs/Module/Photos.php:1097 ../../Zotlabs/Module/Photos.php:1215 +#: ../../Zotlabs/Lib/ThreadItem.php:824 ../../include/js_strings.php:6 +msgid "Comment" +msgstr "Komentarz" + +#: ../../Zotlabs/Module/Photos.php:1113 ../../include/conversation.php:652 +msgctxt "title" +msgid "Likes" +msgstr "Polubienia" + +#: ../../Zotlabs/Module/Photos.php:1113 ../../include/conversation.php:653 +msgctxt "title" +msgid "Dislikes" +msgstr "Dezaprobaty" + +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:77 +#: ../../include/conversation.php:654 +msgctxt "title" +msgid "Agree" +msgstr "Zgoda" + +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:78 +#: ../../include/conversation.php:655 +msgctxt "title" +msgid "Disagree" +msgstr "Sprzeciw" + +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:79 +#: ../../include/conversation.php:656 +msgctxt "title" +msgid "Abstain" +msgstr "Wstrzymuję się" + +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:66 +#: ../../include/conversation.php:657 +msgctxt "title" +msgid "Attending" +msgstr "Uczestniczę" + +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:67 +#: ../../include/conversation.php:658 +msgctxt "title" +msgid "Not attending" +msgstr "Nie uczestniczę" + +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:68 +#: ../../include/conversation.php:659 +msgctxt "title" +msgid "Might attend" +msgstr "Mogę uczestniczyć" + +#: ../../Zotlabs/Module/Photos.php:1132 ../../Zotlabs/Module/Photos.php:1144 +#: ../../Zotlabs/Lib/ThreadItem.php:238 ../../Zotlabs/Lib/ThreadItem.php:250 +msgid "View all" +msgstr "Pokaż wszystkie" + +#: ../../Zotlabs/Module/Photos.php:1136 ../../Zotlabs/Lib/ThreadItem.php:242 +#: ../../include/conversation.php:1749 ../../include/channel.php:1781 +#: ../../include/taxonomy.php:668 +msgctxt "noun" +msgid "Like" +msgid_plural "Likes" +msgstr[0] "Lubi" +msgstr[1] "Lubią" +msgstr[2] "Lubi" + +#: ../../Zotlabs/Module/Photos.php:1141 ../../Zotlabs/Lib/ThreadItem.php:247 +#: ../../include/conversation.php:1752 +msgctxt "noun" +msgid "Dislike" +msgid_plural "Dislikes" +msgstr[0] "Nie lubi" +msgstr[1] "Nie lubią" +msgstr[2] "Nie lubi" + +#: ../../Zotlabs/Module/Photos.php:1247 +msgid "Photo Tools" +msgstr "Narzędzia fotograficzne" + +#: ../../Zotlabs/Module/Photos.php:1256 +msgid "In This Photo:" +msgstr "Na tym zdjęciu:" + +#: ../../Zotlabs/Module/Photos.php:1261 +msgid "Map" +msgstr "Mapa" + +#: ../../Zotlabs/Module/Photos.php:1269 ../../Zotlabs/Lib/ThreadItem.php:489 +msgctxt "noun" +msgid "Likes" +msgstr "Polubienia" + +#: ../../Zotlabs/Module/Photos.php:1270 ../../Zotlabs/Lib/ThreadItem.php:490 +msgctxt "noun" +msgid "Dislikes" +msgstr "Dezaprobaty" + +#: ../../Zotlabs/Module/Photos.php:1275 ../../Zotlabs/Storage/Browser.php:411 +#: ../../Zotlabs/Lib/ThreadItem.php:495 ../../Zotlabs/Widget/Pinned.php:160 +#: ../../include/acl_selectors.php:155 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:233 +msgid "Close" +msgstr "Zamknięte" + +#: ../../Zotlabs/Module/Photos.php:1348 ../../Zotlabs/Module/Photos.php:1361 +#: ../../Zotlabs/Module/Photos.php:1362 ../../include/photos.php:667 +msgid "Recent Photos" +msgstr "Najnowsze zdjęcia" + +#: ../../Zotlabs/Module/Channel.php:99 ../../Zotlabs/Module/Profile.php:45 +#: ../../Zotlabs/Module/Hcard.php:37 +msgid "Posts and comments" +msgstr "Posty i komentarze" + +#: ../../Zotlabs/Module/Channel.php:106 ../../Zotlabs/Module/Profile.php:52 +#: ../../Zotlabs/Module/Hcard.php:44 +msgid "Only posts" +msgstr "Tylko posty" + +#: ../../Zotlabs/Module/Channel.php:174 +msgid "Insufficient permissions. Request redirected to profile page." +msgstr "" +"Niewystarczające uprawnienia. Żądanie zostało przekierowane na stronę " +"profilu." + +#: ../../Zotlabs/Module/Channel.php:189 ../../Zotlabs/Module/Network.php:164 +msgid "Search Results For:" +msgstr "Wyniki wyszukiwania dla:" + +#: ../../Zotlabs/Module/Cards.php:51 +msgid "Cards App" +msgstr "Aplikacja Cards" + +#: ../../Zotlabs/Module/Cards.php:52 +msgid "Create personal planning cards" +msgstr "Twórz osobiste karty planowania" + +#: ../../Zotlabs/Module/Cards.php:112 +msgid "Add Card" +msgstr "Dodaj kartę" + +#: ../../Zotlabs/Module/Cards.php:207 ../../Zotlabs/Lib/Apps.php:326 +#: ../../include/nav.php:501 +msgid "Cards" +msgstr "Karty" + +#: ../../Zotlabs/Module/Go.php:21 +msgid "This page is available only to site members" +msgstr "Ta strona jest dostępna tylko dla członków serwisu" + +#: ../../Zotlabs/Module/Go.php:27 +msgid "Welcome" +msgstr "Witamy" + +#: ../../Zotlabs/Module/Go.php:29 +msgid "What would you like to do?" +msgstr "Co chciałbyś zrobić?" + +#: ../../Zotlabs/Module/Go.php:31 +msgid "" +"Please bookmark this page if you would like to return to it in the future" +msgstr "Dodaj tę stronę do zakładek, jeśli chcesz wrócić do niej w przyszłości" + +#: ../../Zotlabs/Module/Go.php:35 +msgid "Upload a profile photo" +msgstr "Prześlij zdjęcie profilowe" + +#: ../../Zotlabs/Module/Go.php:36 +msgid "Upload a cover photo" +msgstr "Prześlij zdjęcie na okładkę" + +#: ../../Zotlabs/Module/Go.php:37 +msgid "Edit your default profile" +msgstr "Edytuj swój domyślny profil" + +#: ../../Zotlabs/Module/Go.php:38 ../../Zotlabs/Widget/Newmember.php:41 +msgid "View friend suggestions" +msgstr "Zobacz propozycje znajomości" + +#: ../../Zotlabs/Module/Go.php:39 +msgid "View the channel directory" +msgstr "Wyświetl katalog kanałów" + +#: ../../Zotlabs/Module/Go.php:40 +msgid "View/edit your channel settings" +msgstr "Wyświetl/edytuj ustawienia swojego kanału" + +#: ../../Zotlabs/Module/Go.php:41 +msgid "View the site or project documentation" +msgstr "Wyświetl witrynę lub dokumentację projektu" + +#: ../../Zotlabs/Module/Go.php:42 +msgid "Visit your channel homepage" +msgstr "Odwiedź stronę główną swojego kanału" + +#: ../../Zotlabs/Module/Go.php:43 +msgid "" +"View your connections and/or add somebody whose address you already know" +msgstr "Wyświetl swoje kontakty albo dodaj osobę, której adres już znasz" + +#: ../../Zotlabs/Module/Go.php:44 +msgid "" +"View your personal stream (this may be empty until you add some connections)" +msgstr "" +"Wyświetl swój osobisty strumień (może być pusty, dopóki nie dodasz " +"niektórych połączeń)" + +#: ../../Zotlabs/Module/Go.php:52 +msgid "View the public stream. Warning: this content is not moderated" +msgstr "" +"Wyświetl strumień publiczny. Ostrzeżenie: ta zawartość nie jest moderowana" + +#: ../../Zotlabs/Module/Connections.php:58 +#: ../../Zotlabs/Module/Connections.php:115 +#: ../../Zotlabs/Module/Connections.php:273 +msgid "Active" +msgstr "Aktywny" + +#: ../../Zotlabs/Module/Connections.php:63 +#: ../../Zotlabs/Module/Connections.php:181 +#: ../../Zotlabs/Module/Connections.php:278 +msgid "Blocked" +msgstr "Zablokowany" + +#: ../../Zotlabs/Module/Connections.php:68 +#: ../../Zotlabs/Module/Connections.php:188 +#: ../../Zotlabs/Module/Connections.php:277 +msgid "Ignored" +msgstr "Ignorowany" + +#: ../../Zotlabs/Module/Connections.php:73 +#: ../../Zotlabs/Module/Connections.php:202 +#: ../../Zotlabs/Module/Connections.php:276 +msgid "Hidden" +msgstr "Ukryty" + +#: ../../Zotlabs/Module/Connections.php:78 +#: ../../Zotlabs/Module/Connections.php:195 +msgid "Archived/Unreachable" +msgstr "Zarchiwizowane/Nieosiągalne" + +#: ../../Zotlabs/Module/Connections.php:83 +#: ../../Zotlabs/Module/Connections.php:92 +#: ../../Zotlabs/Module/Notifications.php:50 ../../Zotlabs/Module/Menu.php:180 +msgid "New" +msgstr "Nowy" + +#: ../../Zotlabs/Module/Connections.php:157 +msgid "Active Connections" +msgstr "Aktywne połączenia" + +#: ../../Zotlabs/Module/Connections.php:160 +msgid "Show active connections" +msgstr "Pokaż aktywne połączenia" + +#: ../../Zotlabs/Module/Connections.php:164 +#: ../../Zotlabs/Widget/Notifications.php:104 +msgid "New Connections" +msgstr "Nowe połączenia" + +#: ../../Zotlabs/Module/Connections.php:167 +msgid "Show pending (new) connections" +msgstr "Pokaż oczekujące (nowe) połączenia" + +#: ../../Zotlabs/Module/Connections.php:184 +msgid "Only show blocked connections" +msgstr "Pokaż tylko zablokowane połączenia" + +#: ../../Zotlabs/Module/Connections.php:191 +msgid "Only show ignored connections" +msgstr "Pokaż tylko ignorowane połączenia" + +#: ../../Zotlabs/Module/Connections.php:198 +msgid "Only show archived/unreachable connections" +msgstr "Pokaż tylko zarchiwizowane/nieosiągalne połączenia" + +#: ../../Zotlabs/Module/Connections.php:205 +msgid "Only show hidden connections" +msgstr "Pokaż tylko ukryte połączenia" + +#: ../../Zotlabs/Module/Connections.php:220 +msgid "Show all connections" +msgstr "Pokaż wszystkie połączenia" + +#: ../../Zotlabs/Module/Connections.php:274 +msgid "Pending approval" +msgstr "W oczekiwaniu na zatwierdzenie" + +#: ../../Zotlabs/Module/Connections.php:275 +msgid "Archived" +msgstr "Zarchiwizowane" + +#: ../../Zotlabs/Module/Connections.php:279 +msgid "Not connected at this location" +msgstr "Brak połączenia w tej lokalizacji" + +#: ../../Zotlabs/Module/Connections.php:318 +#, php-format +msgid "%1$s [%2$s]" +msgstr "%1$s [%2$s]" + +#: ../../Zotlabs/Module/Connections.php:319 +msgid "Edit connection" +msgstr "Edytuj połączenie" + +#: ../../Zotlabs/Module/Connections.php:321 +msgid "Delete connection" +msgstr "Usuń połączenie" + +#: ../../Zotlabs/Module/Connections.php:330 +msgid "Channel address" +msgstr "Adres kanału" + +#: ../../Zotlabs/Module/Connections.php:332 ../../include/features.php:291 +msgid "Network" +msgstr "Sieć" + +#: ../../Zotlabs/Module/Connections.php:335 +msgid "Call" +msgstr "Połączenie" + +#: ../../Zotlabs/Module/Connections.php:337 +msgid "Status" +msgstr "Stan" + +#: ../../Zotlabs/Module/Connections.php:339 +msgid "Connected" +msgstr "Połączene" + +#: ../../Zotlabs/Module/Connections.php:341 +msgid "Approve connection" +msgstr "Zatwierdź połączenie" + +#: ../../Zotlabs/Module/Connections.php:342 +#: ../../Zotlabs/Module/Admin/Accounts.php:173 +#: ../../include/conversation.php:774 +msgid "Approve" +msgstr "Zatwierdź" + +#: ../../Zotlabs/Module/Connections.php:343 +msgid "Ignore connection" +msgstr "Ignoruj połączenie" + +#: ../../Zotlabs/Module/Connections.php:345 +msgid "Recent activity" +msgstr "Ostatnia aktywność" + +#: ../../Zotlabs/Module/Connections.php:349 ../../Zotlabs/Module/Suggest.php:71 +#: ../../Zotlabs/Module/Directory.php:370 ../../Zotlabs/Widget/Follow.php:32 +#: ../../Zotlabs/Widget/Suggestions.php:46 ../../include/conversation.php:1100 +#: ../../include/channel.php:1618 ../../include/connections.php:110 +msgid "Connect" +msgstr "Połączenie" + +#: ../../Zotlabs/Module/Connections.php:351 +msgid "Connect at this location" +msgstr "Połącz w tej lokalizacji" + +#: ../../Zotlabs/Module/Connections.php:374 ../../Zotlabs/Lib/Apps.php:333 +#: ../../include/features.php:133 ../../include/text.php:1036 +msgid "Connections" +msgstr "Połączenia" + +#: ../../Zotlabs/Module/Connections.php:379 +msgid "Search your connections" +msgstr "Wyszukaj swoje połączenia" + +#: ../../Zotlabs/Module/Connections.php:380 +msgid "Connections search" +msgstr "Wyszukiwanie połączeń" + +#: ../../Zotlabs/Module/Connections.php:381 +#: ../../Zotlabs/Module/Directory.php:433 +#: ../../Zotlabs/Module/Directory.php:438 ../../include/contact_widgets.php:23 +msgid "Find" +msgstr "Znajdź" + +#: ../../Zotlabs/Module/Editpost.php:38 ../../Zotlabs/Module/Editpost.php:43 +msgid "Item is not editable" +msgstr "Elementu nie można edytować" + +#: ../../Zotlabs/Module/Tagrm.php:48 ../../Zotlabs/Module/Tagrm.php:98 +msgid "Tag removed" +msgstr "Tag został usunięty" + +#: ../../Zotlabs/Module/Tagrm.php:123 +msgid "Remove Item Tag" +msgstr "Usuń tag elementy" + +#: ../../Zotlabs/Module/Tagrm.php:125 +msgid "Select a tag to remove: " +msgstr "Wybierz tag do usunięcia: " + +#: ../../Zotlabs/Module/Affinity.php:35 +msgid "Affinity Tool settings updated." +msgstr "Zaktualizowano ustawienia narzędzia Affinity." + +#: ../../Zotlabs/Module/Affinity.php:47 +msgid "" +"This app presents a slider control in your connection editor and also on " +"your network page. The slider represents your degree of friendship " +"(affinity) with each connection. It allows you to zoom in or out and display " +"conversations from only your closest friends or everybody in your stream." +msgstr "" +"Ta aplikacja przedstawia suwak w edytorze połączeń, a także na stronie " +"internetowej. Suwak przedstawia stopień przyjaźni (koligacji) z każdym " +"połączeniem. Umożliwia powiększanie i pomniejszanie oraz wyświetlanie rozmów " +"tylko od najbliższych znajomych lub wszystkich w strumieniu." + +#: ../../Zotlabs/Module/Affinity.php:52 +msgid "Affinity Tool App" +msgstr "Aplikacja Affinity Tool" + +#: ../../Zotlabs/Module/Affinity.php:57 +msgid "" +"The numbers below represent the minimum and maximum slider default positions " +"for your network/stream page as a percentage." +msgstr "" +"Poniższe liczby przedstawiają minimalne i maksymalne domyślne pozycje " +"suwaków na stronie sieci/strumienia w procentach." + +#: ../../Zotlabs/Module/Affinity.php:64 +msgid "Default maximum affinity level" +msgstr "Domyślny maksymalny poziom więzi" + +#: ../../Zotlabs/Module/Affinity.php:64 +msgid "0-99 default 99" +msgstr "0-99, domyślnie 99" + +#: ../../Zotlabs/Module/Affinity.php:70 +msgid "Default minimum affinity level" +msgstr "Domyślny minimalny poziom więzi" + +#: ../../Zotlabs/Module/Affinity.php:70 +msgid "0-99 - default 0" +msgstr "0-99, domyślnie 0" + +#: ../../Zotlabs/Module/Affinity.php:76 +msgid "Persistent affinity levels" +msgstr "Trwałe poziomy więzi" + +#: ../../Zotlabs/Module/Affinity.php:76 +msgid "" +"If disabled the max and min levels will be reset to default after page reload" +msgstr "" +"Jeśli wyłączone, maksymalne i minimalne poziomy zostaną zresetowane do " +"wartości domyślnych po ponownym załadowaniu strony" + +#: ../../Zotlabs/Module/Affinity.php:84 +msgid "Affinity Tool Settings" +msgstr "Ustawienia Affinity Tool" + +#: ../../Zotlabs/Module/Common.php:14 +msgid "No channel." +msgstr "Brak kanału." + +#: ../../Zotlabs/Module/Common.php:45 +msgid "No connections in common." +msgstr "Brak wspólnych połączeń." + +#: ../../Zotlabs/Module/Common.php:65 +msgid "View Common Connections" +msgstr "Wyświetl typowe połączenia" + +#: ../../Zotlabs/Module/Share.php:104 ../../Zotlabs/Lib/Activity.php:2133 +#, php-format +msgid "🔁 Repeated %1$s's %2$s" +msgstr "🔁 Powtórzony %2$s %1$s" + +#: ../../Zotlabs/Module/Share.php:120 +msgid "Post repeated" +msgstr "Post powtórzony" + +#: ../../Zotlabs/Module/Editwebpage.php:139 +msgid "Page link" +msgstr "Link do strony" + +#: ../../Zotlabs/Module/Editwebpage.php:166 +msgid "Edit Webpage" +msgstr "Edytuj stronę internetową" + +#: ../../Zotlabs/Module/Profile.php:93 +msgid "vcard" +msgstr "vcard" + +#: ../../Zotlabs/Module/Article_edit.php:127 +msgid "Edit Article" +msgstr "Edutuj artykuł" + +#: ../../Zotlabs/Module/Rmagic.php:46 +msgid "Authentication failed." +msgstr "Uwierzytelnianie nie powiodło się." + +#: ../../Zotlabs/Module/Rmagic.php:96 ../../include/channel.php:2597 +#: ../../boot.php:1706 +msgid "Remote Authentication" +msgstr "Zdalne uwierzytelnianie" + +#: ../../Zotlabs/Module/Rmagic.php:97 ../../include/channel.php:2598 +msgid "Enter your channel address (e.g. channel@example.com)" +msgstr "Wpisz adres swojego kanału (np. kanał@example.com)" + +#: ../../Zotlabs/Module/Rmagic.php:98 ../../include/channel.php:2599 +msgid "Authenticate" +msgstr "Uwierzytelnianie" + +#: ../../Zotlabs/Module/Attach.php:67 +msgid "Item not available." +msgstr "Element nie jest dostępny." + +#: ../../Zotlabs/Module/Pconfig.php:32 ../../Zotlabs/Module/Pconfig.php:68 +msgid "This setting requires special processing and editing has been blocked." +msgstr "" +"To ustawienie wymaga specjalnego przetwarzania, a edycja została zablokowana." + +#: ../../Zotlabs/Module/Pconfig.php:57 +msgid "Configuration Editor" +msgstr "Edytor konfiguracji" + +#: ../../Zotlabs/Module/Pconfig.php:58 +msgid "" +"Warning: Changing some settings could render your channel inoperable. Please " +"leave this page unless you are comfortable with and knowledgeable about how " +"to correctly use this feature." +msgstr "" +"Ostrzeżenie: zmiana niektórych ustawień może spowodować, że Twój kanał " +"przestanie działać. Opuść tę stronę, chyba że czujesz się komfortowo i nie " +"wiesz, jak prawidłowo korzystać z tej funkcji." + +#: ../../Zotlabs/Module/Randprof.php:29 +msgid "Random Channel App" +msgstr "Aplikacja Random Channel" + +#: ../../Zotlabs/Module/Randprof.php:30 +msgid "Visit a random channel in the $Projectname network" +msgstr "Odwiedź losowy kanał w sieci $Projectname" + +#: ../../Zotlabs/Module/Admin/Themes.php:26 +msgid "Theme settings updated." +msgstr "Zaktualizowano ustawienia motywu." + +#: ../../Zotlabs/Module/Admin/Themes.php:61 +msgid "No themes found." +msgstr "Nie znaleziono motywów." + +#: ../../Zotlabs/Module/Admin/Themes.php:95 +#: ../../Zotlabs/Module/Admin/Addons.php:311 +msgid "Disable" +msgstr "Wyłącz" + +#: ../../Zotlabs/Module/Admin/Themes.php:97 +#: ../../Zotlabs/Module/Admin/Addons.php:314 +msgid "Enable" +msgstr "Włącz" + +#: ../../Zotlabs/Module/Admin/Themes.php:116 +msgid "Screenshot" +msgstr "Zrzut ekranu" + +#: ../../Zotlabs/Module/Admin/Themes.php:123 +#: ../../Zotlabs/Module/Admin/Themes.php:157 ../../Zotlabs/Widget/Admin.php:28 +msgid "Themes" +msgstr "Motywy" + +#: ../../Zotlabs/Module/Admin/Themes.php:124 +#: ../../Zotlabs/Module/Admin/Addons.php:344 +msgid "Toggle" +msgstr "Przełącz" + +#: ../../Zotlabs/Module/Admin/Themes.php:125 +#: ../../Zotlabs/Module/Admin/Addons.php:345 ../../Zotlabs/Lib/Apps.php:339 +#: ../../Zotlabs/Widget/Settings_menu.php:61 +#: ../../Zotlabs/Widget/Newmember.php:53 ../../include/nav.php:103 +msgid "Settings" +msgstr "Ustawienia" + +#: ../../Zotlabs/Module/Admin/Themes.php:134 +#: ../../Zotlabs/Module/Admin/Addons.php:352 +msgid "Author: " +msgstr "Autor: " + +#: ../../Zotlabs/Module/Admin/Themes.php:135 +#: ../../Zotlabs/Module/Admin/Addons.php:353 +msgid "Maintainer: " +msgstr "Opiekun: " + +#: ../../Zotlabs/Module/Admin/Themes.php:162 +msgid "[Experimental]" +msgstr "[Eksperymentalne]" + +#: ../../Zotlabs/Module/Admin/Themes.php:163 +msgid "[Unsupported]" +msgstr "[Nieobsługiwane]" + +#: ../../Zotlabs/Module/Admin/Security.php:89 +msgid "" +"By default, unfiltered HTML is allowed in embedded media. This is inherently " +"insecure." +msgstr "" +"Domyślnie, w osadzonych mediach jest dozwolony niefiltrowany HTML. Jest to " +"z natury niebezpieczne." + +#: ../../Zotlabs/Module/Admin/Security.php:92 +msgid "" +"The recommended setting is to only allow unfiltered HTML from the following " +"sites:" +msgstr "" +"Zalecane ustawienie to zezwalanie na niefiltrowany kodu HTML tylko z " +"następujących serwisów:" + +#: ../../Zotlabs/Module/Admin/Security.php:93 +msgid "" +"https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/" +"
      https://vimeo.com/
      https://soundcloud.com/
      " +msgstr "" +"https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/" +"
      https://vimeo.com/
      https://soundcloud.com/
      " + +#: ../../Zotlabs/Module/Admin/Security.php:94 +msgid "" +"All other embedded content will be filtered, unless " +"embedded content from that site is explicitly blocked." +msgstr "" +"Wszystkie inne osadzone treści będą filtrowane, chyba że " +"osadzone treści z tego serwisu są jawnie zablokowane." + +#: ../../Zotlabs/Module/Admin/Security.php:99 ../../Zotlabs/Widget/Admin.php:25 +msgid "Security" +msgstr "Bezpieczeństwo" + +#: ../../Zotlabs/Module/Admin/Security.php:101 +msgid "Block public" +msgstr "Zablokuj publiczny dstęp" + +#: ../../Zotlabs/Module/Admin/Security.php:101 +msgid "" +"Check to block public access to all otherwise public personal pages on this " +"site unless you are currently authenticated." +msgstr "" +"Zaznacz, aby zablokować publiczny dostęp do wszystkich innych publicznych " +"stron osobistych w tej witrynie, chyba że jesteś obecnie uwierzytelniony." + +#: ../../Zotlabs/Module/Admin/Security.php:102 +msgid "Provide a cloud root directory" +msgstr "Podaj katalog główny w chmurze" + +#: ../../Zotlabs/Module/Admin/Security.php:102 +msgid "" +"The cloud root directory lists all channel names which provide public files" +msgstr "" +"Katalog główny w chmurze zawiera listę wszystkich nazw kanałów, które " +"udostępniają pliki publiczne" + +#: ../../Zotlabs/Module/Admin/Security.php:103 +msgid "Show total disk space available to cloud uploads" +msgstr "" +"Pokaż całkowitą przestrzeń dyskową dostępną do przesyłania plików do chmury" + +#: ../../Zotlabs/Module/Admin/Security.php:104 +msgid "Set \"Transport Security\" HTTP header" +msgstr "Ustaw nagłówek HTTP \"Transport Security\"" + +#: ../../Zotlabs/Module/Admin/Security.php:105 +msgid "Set \"Content Security Policy\" HTTP header" +msgstr "Ustaw nagłówek HTTP \"Content Security Policy\"" + +#: ../../Zotlabs/Module/Admin/Security.php:106 +msgid "Allowed email domains" +msgstr "Dozwolone domeny e-mail" + +#: ../../Zotlabs/Module/Admin/Security.php:106 +msgid "" +"Comma separated list of domains which are allowed in email addresses for " +"registrations to this site. Wildcards are accepted. Empty to allow any " +"domains" +msgstr "" +"Rozdzielana przecinkami lista domen, które są dozwolone w adresach e-mail " +"podczas rejestracji w tym serwisie. Akceptowane są symbole wieloznaczne. " +"Puste pole oznacza zezwolenie na dowolne domeny" + +#: ../../Zotlabs/Module/Admin/Security.php:107 +msgid "Not allowed email domains" +msgstr "Niedozwolone domeny e-mail" + +#: ../../Zotlabs/Module/Admin/Security.php:107 +msgid "" +"Comma separated list of domains which are not allowed in email addresses for " +"registrations to this site. Wildcards are accepted. Empty to allow any " +"domains, unless allowed domains have been defined." +msgstr "" +"Rozdzielana przecinkami lista domen, które nie są dozwolone w adresach e-" +"mail podczas rejestracji w tym serwisie. Akceptowane są symbole " +"wieloznaczne. Puste pole oznacza zezwolenie na wszystkie domeny, chyba że " +"zostały uprzednio zdefiniowane jakieś dozwolone domeny." + +#: ../../Zotlabs/Module/Admin/Security.php:108 +msgid "Allow communications only from these sites" +msgstr "Zezwalaj na komunikację tylko z tych serwisów" + +#: ../../Zotlabs/Module/Admin/Security.php:108 +msgid "" +"One site per line. Leave empty to allow communication from anywhere by " +"default" +msgstr "" +"Jeden serwis w wierszu. Pozostaw puste, aby domyślnie zezwolić na " +"komunikację z dowolnego miejsca" + +#: ../../Zotlabs/Module/Admin/Security.php:109 +msgid "Block communications from these sites" +msgstr "Blokuj komunikację z tych serwisów" + +#: ../../Zotlabs/Module/Admin/Security.php:110 +msgid "Allow communications only from these channels" +msgstr "Zezwalaj na komunikację tylko z tych kanałów" + +#: ../../Zotlabs/Module/Admin/Security.php:110 +msgid "" +"One channel (hash) per line. Leave empty to allow from any channel by default" +msgstr "" +"Jeden kanał (hash) na linię. Pozostaw puste, aby domyślnie zezwolić z " +"dowolnego kanału" + +#: ../../Zotlabs/Module/Admin/Security.php:111 +msgid "Block communications from these channels" +msgstr "Blokuj komunikację z tych kanałów" + +#: ../../Zotlabs/Module/Admin/Security.php:112 +msgid "Only allow embeds from secure (SSL) websites and links." +msgstr "Zezwalaj na osadzanie tylko z bezpiecznych (SSL) witryn i linków ." + +#: ../../Zotlabs/Module/Admin/Security.php:113 +msgid "Allow unfiltered embedded HTML content only from these domains" +msgstr "Zezwalaj na niefiltrowaną osadzony kod HTML tylko z tych domen" + +#: ../../Zotlabs/Module/Admin/Security.php:113 +msgid "One site per line. By default embedded content is filtered." +msgstr "Jedna witryna w wierszu. Domyślnie, treść osadzona jest filtrowana." + +#: ../../Zotlabs/Module/Admin/Security.php:114 +msgid "Block embedded HTML from these domains" +msgstr "Zablokuj osadzony kod HTML z tych domen" + +#: ../../Zotlabs/Module/Admin/Security.php:115 +msgid "Allow SVG thumbnails in file browser" +msgstr "Zezwalaj na miniatury SVG w przeglądarce plików" + +#: ../../Zotlabs/Module/Admin/Security.php:115 +msgid "WARNING: SVG images may contain malicious code." +msgstr "OSTRZEŻENIE: obrazy SVG mogą zawierać złośliwy kod." + +#: ../../Zotlabs/Module/Admin/Security.php:116 +msgid "Allow embedded (inline) PDF files" +msgstr "Zezwalaj na osadzone (międzywierszowe) pliki PDF" + +#: ../../Zotlabs/Module/Admin/Accounts.php:37 +#, php-format +msgid "%s account blocked/unblocked" +msgid_plural "%s account blocked/unblocked" +msgstr[0] "%s konto jest zablokowane/odblokowane" +msgstr[1] "%s konto są zablokowane/odblokowane" +msgstr[2] "%s kont jest zablokowanych/odblokowanych" + +#: ../../Zotlabs/Module/Admin/Accounts.php:44 +#, php-format +msgid "%s account deleted" +msgid_plural "%s accounts deleted" +msgstr[0] "%s konto jest usunięte" +msgstr[1] "%s konta są usunięte" +msgstr[2] "%s kont jest usuniętych" + +#: ../../Zotlabs/Module/Admin/Accounts.php:80 +msgid "Account not found" +msgstr "Konto nie znalezione" + +#: ../../Zotlabs/Module/Admin/Accounts.php:91 ../../include/channel.php:2757 +#, php-format +msgid "Account '%s' deleted" +msgstr "Usunieto konto '%s'" + +#: ../../Zotlabs/Module/Admin/Accounts.php:99 +#, php-format +msgid "Account '%s' blocked" +msgstr "Konto '%s' zostało zablokowane" + +#: ../../Zotlabs/Module/Admin/Accounts.php:107 +#, php-format +msgid "Account '%s' unblocked" +msgstr "Konto '%s' zostało odblokowane" + +#: ../../Zotlabs/Module/Admin/Accounts.php:169 +#: ../../Zotlabs/Module/Admin/Channels.php:148 +msgid "select all" +msgstr "wybierz wszystkie" + +#: ../../Zotlabs/Module/Admin/Accounts.php:170 +msgid "Registrations waiting for confirm" +msgstr "Rejestracje czekają na potwierdzenie" + +#: ../../Zotlabs/Module/Admin/Accounts.php:171 +msgid "Request date" +msgstr "Data wniosku" + +#: ../../Zotlabs/Module/Admin/Accounts.php:172 +msgid "No registrations." +msgstr "Brak rejestracji." + +#: ../../Zotlabs/Module/Admin/Accounts.php:182 +msgid "ID" +msgstr "ID" + +#: ../../Zotlabs/Module/Admin/Accounts.php:184 +msgid "All Channels" +msgstr "Wszytskie kanały" + +#: ../../Zotlabs/Module/Admin/Accounts.php:185 +msgid "Register date" +msgstr "Data rejestracji" + +#: ../../Zotlabs/Module/Admin/Accounts.php:186 +msgid "Last login" +msgstr "Ostatnie logowanie" + +#: ../../Zotlabs/Module/Admin/Accounts.php:187 +msgid "Expires" +msgstr "Wygasa" + +#: ../../Zotlabs/Module/Admin/Accounts.php:188 +msgid "Service Class" +msgstr "Klasa usługi" + +#: ../../Zotlabs/Module/Admin/Accounts.php:190 +msgid "" +"Selected accounts will be deleted!\\n\\nEverything these accounts had posted " +"on this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" +"Wybrane konta zostaną usunięte!\\n\\nWszystko, co z tych kont zostało " +"opublikowane na tym serwisie, zostanie bezpowrotnie usunięte!\\n\\nCzy na " +"pewno usunąć?" + +#: ../../Zotlabs/Module/Admin/Accounts.php:191 +msgid "" +"The account {0} will be deleted!\\n\\nEverything this account has posted on " +"this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" +"Konto {0} zostanie usuniete!\\n\\nWszystko co opublikowano z tego konta na " +"tym serwisie zostanie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?" + +#: ../../Zotlabs/Module/Admin/Features.php:55 +#: ../../Zotlabs/Module/Admin/Features.php:56 +#: ../../Zotlabs/Module/Settings/Features.php:38 ../../include/features.php:55 +msgid "Off" +msgstr "Off" + +#: ../../Zotlabs/Module/Admin/Features.php:55 +#: ../../Zotlabs/Module/Admin/Features.php:56 +#: ../../Zotlabs/Module/Settings/Features.php:38 ../../include/features.php:55 +msgid "On" +msgstr "On" + +#: ../../Zotlabs/Module/Admin/Features.php:56 +#, php-format +msgid "Lock feature %s" +msgstr "Funkcja blokady %s" + +#: ../../Zotlabs/Module/Admin/Features.php:64 +msgid "Manage Additional Features" +msgstr "Zarządzaj dodatkowymi funkcjami" + +#: ../../Zotlabs/Module/Admin/Queue.php:35 +msgid "Queue Statistics" +msgstr "Statystyki kolejki" + +#: ../../Zotlabs/Module/Admin/Queue.php:36 +msgid "Total Entries" +msgstr "Ogółem postów" + +#: ../../Zotlabs/Module/Admin/Queue.php:37 +msgid "Priority" +msgstr "Priorytet" + +#: ../../Zotlabs/Module/Admin/Queue.php:38 +msgid "Destination URL" +msgstr "Docelowy URL" + +#: ../../Zotlabs/Module/Admin/Queue.php:39 +msgid "Mark hub permanently offline" +msgstr "Oznacz hub na stałe w trybie offline" + +#: ../../Zotlabs/Module/Admin/Queue.php:40 +msgid "Empty queue for this hub" +msgstr "Pusta kolejka dla tego huba" + +#: ../../Zotlabs/Module/Admin/Queue.php:41 +msgid "Last known contact" +msgstr "Ostatni znany kontakt" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:19 +#: ../../Zotlabs/Module/Admin/Dbsync.php:59 +msgid "Update has been marked successful" +msgstr "Aktualizacja została oznaczona jako pomyślna" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:32 +#, php-format +msgid "Verification of update %s failed. Check system logs." +msgstr "" +"Weryfikacja aktualizacji %s nie zakończyła się pomyślnie. Sprawdź dzienniki " +"systemowe." + +#: ../../Zotlabs/Module/Admin/Dbsync.php:35 +#: ../../Zotlabs/Module/Admin/Dbsync.php:74 +#, php-format +msgid "Update %s was successfully applied." +msgstr "Aktualizacja %s została pomyślnie zastosowana." + +#: ../../Zotlabs/Module/Admin/Dbsync.php:39 +#, php-format +msgid "Verifying update %s did not return a status. Unknown if it succeeded." +msgstr "" +"Weryfikacja aktualizacji %s nie zwróciła stanu. Nie wiadomo, czy się udało." + +#: ../../Zotlabs/Module/Admin/Dbsync.php:42 +#, php-format +msgid "Update %s does not contain a verification function." +msgstr "Aktualizacja %s nie zawiera funkcji weryfikacji." + +#: ../../Zotlabs/Module/Admin/Dbsync.php:46 +#: ../../Zotlabs/Module/Admin/Dbsync.php:81 +#, php-format +msgid "Update function %s could not be found." +msgstr "Nie można znaleźć funkcji aktualizacji %s." + +#: ../../Zotlabs/Module/Admin/Dbsync.php:71 +#, php-format +msgid "Executing update procedure %s failed. Check system logs." +msgstr "" +"Wykonanie procedury aktualizacji %s nie powiodło się. Sprawdź dzienniki " +"systemowe." + +#: ../../Zotlabs/Module/Admin/Dbsync.php:78 +#, php-format +msgid "" +"Update %s did not return a status. It cannot be determined if it was " +"successful." +msgstr "Aktualizacja %s nie zwróciła stanu. Nie można ustalić, czy się udało." + +#: ../../Zotlabs/Module/Admin/Dbsync.php:99 +msgid "Failed Updates" +msgstr "Nieudane aktualizacje" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:101 +msgid "Mark success (if update was manually applied)" +msgstr "Oznacz sukces (jeśli aktualizacja została wykonana ręcznie)" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:102 +msgid "Attempt to verify this update if a verification procedure exists" +msgstr "" +"Spróbuj zweryfikować tą aktualizację, jeśli istnieje procedura weryfikacji" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:103 +msgid "Attempt to execute this update step automatically" +msgstr "Spróbuj automatycznie wykonać ten krok aktualizacji" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:108 +msgid "No failed updates." +msgstr "Nie ma nieudanych aktualizacji." + +#: ../../Zotlabs/Module/Admin/Channels.php:31 +#, php-format +msgid "%s channel censored/uncensored" +msgid_plural "%s channels censored/uncensored" +msgstr[0] "%s kanał jest ocenzurowany/nieocenzurowany" +msgstr[1] "%s kanały są ocenzurowane/nieocenzurowane" +msgstr[2] "%s kanałów jest ocenzurowanych/nieocenzurowanych" + +#: ../../Zotlabs/Module/Admin/Channels.php:40 +#, php-format +msgid "%s channel code allowed/disallowed" +msgid_plural "%s channels code allowed/disallowed" +msgstr[0] "Kod %s kanału jest dozwolony /niedozwolony" +msgstr[1] "Kod %s kanałów jest dozwolony/niedozwolony" +msgstr[2] "Kod %s kanałów jest dozwolony/niedozwolony" + +#: ../../Zotlabs/Module/Admin/Channels.php:46 +#, php-format +msgid "%s channel deleted" +msgid_plural "%s channels deleted" +msgstr[0] "%s kanał został usunięty" +msgstr[1] "%s kanały zostały usunięte" +msgstr[2] "%s kanałów został usuniętych" + +#: ../../Zotlabs/Module/Admin/Channels.php:65 +msgid "Channel not found" +msgstr "Kanał nie został znaleziony" + +#: ../../Zotlabs/Module/Admin/Channels.php:75 +#, php-format +msgid "Channel '%s' deleted" +msgstr "Kanał '%s' został usunięty" + +#: ../../Zotlabs/Module/Admin/Channels.php:87 +#, php-format +msgid "Channel '%s' censored" +msgstr "Kanał '%s' został ocenzurowany" + +#: ../../Zotlabs/Module/Admin/Channels.php:87 +#, php-format +msgid "Channel '%s' uncensored" +msgstr "Kanał '%s' jest nieocenzurowany" + +#: ../../Zotlabs/Module/Admin/Channels.php:98 +#, php-format +msgid "Channel '%s' code allowed" +msgstr "Dozwolony kod kanału '%s'" + +#: ../../Zotlabs/Module/Admin/Channels.php:98 +#, php-format +msgid "Channel '%s' code disallowed" +msgstr "Niedozwolony kod kanału '%s'" + +#: ../../Zotlabs/Module/Admin/Channels.php:150 +#: ../../Zotlabs/Module/Directory.php:362 +msgid "Censor" +msgstr "Cezoruj" + +#: ../../Zotlabs/Module/Admin/Channels.php:151 +#: ../../Zotlabs/Module/Directory.php:362 +msgid "Uncensor" +msgstr "Usuń cenzurę" + +#: ../../Zotlabs/Module/Admin/Channels.php:152 +msgid "Allow Code" +msgstr "Zezwalaj na kod" + +#: ../../Zotlabs/Module/Admin/Channels.php:153 +msgid "Disallow Code" +msgstr "Nie zezwalaj na kod" + +#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:421 +msgid "Channel" +msgstr "Kanał" + +#: ../../Zotlabs/Module/Admin/Channels.php:158 +msgid "UID" +msgstr "UID" + +#: ../../Zotlabs/Module/Admin/Channels.php:162 +msgid "" +"Selected channels will be deleted!\\n\\nEverything that was posted in these " +"channels on this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" +"Wybrane kanały zostaną usunięte!\\n\\nWszystko co zostało w nich " +"opublikowane będzie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?" + +#: ../../Zotlabs/Module/Admin/Channels.php:163 +msgid "" +"The channel {0} will be deleted!\\n\\nEverything that was posted in this " +"channel on this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" +"Kanał {0} zostanie usunięty!\\n\\nWszystko co opublikowano na tym kanale " +"będzie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?" + +#: ../../Zotlabs/Module/Admin/Logs.php:28 +msgid "Log settings updated." +msgstr "Zaktualizowano ustawienia dziennika." + +#: ../../Zotlabs/Module/Admin/Logs.php:83 ../../Zotlabs/Widget/Admin.php:48 +#: ../../Zotlabs/Widget/Admin.php:58 +msgid "Logs" +msgstr "Logi" + +#: ../../Zotlabs/Module/Admin/Logs.php:85 +msgid "Clear" +msgstr "Wyczyść" + +#: ../../Zotlabs/Module/Admin/Logs.php:91 +msgid "Debugging" +msgstr "Debugowanie" + +#: ../../Zotlabs/Module/Admin/Logs.php:92 +msgid "Log file" +msgstr "Plik dziennika" + +#: ../../Zotlabs/Module/Admin/Logs.php:92 +msgid "" +"Must be writable by web server. Relative to your top-level webserver " +"directory." +msgstr "" +"Musi mieć możliwość zapisu przez serwer WWW. Względnie do katalogu głównego " +"serwera WWW." + +#: ../../Zotlabs/Module/Admin/Logs.php:93 +msgid "Log level" +msgstr "Poziom rejestrowania zdarzeń" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:29 +#, php-format +msgid "Password changed for account %d." +msgstr "Hasło zostało zmienione do konta%d." + +#: ../../Zotlabs/Module/Admin/Account_edit.php:46 +msgid "Account settings updated." +msgstr "Zaktualizowano ustawienia konta." + +#: ../../Zotlabs/Module/Admin/Account_edit.php:61 +msgid "Account not found." +msgstr "Konto nie zostało znalezione." + +#: ../../Zotlabs/Module/Admin/Account_edit.php:68 +msgid "Account Edit" +msgstr "Edycja konta" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:69 +msgid "New Password" +msgstr "Nowe hasło" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:70 +msgid "New Password again" +msgstr "Powtórz nowe hasło" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:71 +msgid "Account language (for emails)" +msgstr "Język konta (dla wiadomości e-mail)" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:72 +msgid "Service class" +msgstr "Klasa usługi" + +#: ../../Zotlabs/Module/Admin/Addons.php:290 +#, php-format +msgid "Plugin %s disabled." +msgstr "Wtyczka %s jest wyłączona." + +#: ../../Zotlabs/Module/Admin/Addons.php:295 +#, php-format +msgid "Plugin %s enabled." +msgstr "Wtyczka %s jest włączona." + +#: ../../Zotlabs/Module/Admin/Addons.php:343 +#: ../../Zotlabs/Module/Admin/Addons.php:441 ../../Zotlabs/Widget/Admin.php:27 +msgid "Addons" +msgstr "Dodatki" + +#: ../../Zotlabs/Module/Admin/Addons.php:354 +msgid "Minimum project version: " +msgstr "Minimalna wersja projektu: " + +#: ../../Zotlabs/Module/Admin/Addons.php:355 +msgid "Maximum project version: " +msgstr "Maksymalna wersja projektu: " + +#: ../../Zotlabs/Module/Admin/Addons.php:356 +msgid "Minimum PHP version: " +msgstr "Minimalna wersja PHP: " + +#: ../../Zotlabs/Module/Admin/Addons.php:357 +msgid "Compatible Server Roles: " +msgstr "Zgodne role serwera: " + +#: ../../Zotlabs/Module/Admin/Addons.php:358 +msgid "Requires: " +msgstr "Wymaga: " + +#: ../../Zotlabs/Module/Admin/Addons.php:359 +#: ../../Zotlabs/Module/Admin/Addons.php:446 +msgid "Disabled - version incompatibility" +msgstr "Wyłączone - niezgodność wersji" + +#: ../../Zotlabs/Module/Admin/Addons.php:415 +msgid "Enter the public git repository URL of the addon repo." +msgstr "Wprowadź adres URL publicznego repozytorium Git dodatków." + +#: ../../Zotlabs/Module/Admin/Addons.php:416 +msgid "Addon repo git URL" +msgstr "Adres URL repozytorium Git dodatków" + +#: ../../Zotlabs/Module/Admin/Addons.php:417 +msgid "Custom repo name" +msgstr "Własna nazwa repozytorium" + +#: ../../Zotlabs/Module/Admin/Addons.php:417 +msgid "(optional)" +msgstr "(opcjonalnie)" + +#: ../../Zotlabs/Module/Admin/Addons.php:418 +msgid "Download Addon Repo" +msgstr "Pobierz repozytorium dodatków" + +#: ../../Zotlabs/Module/Admin/Addons.php:425 +msgid "Install new repo" +msgstr "Zainstaluj nowe repozytorium" + +#: ../../Zotlabs/Module/Admin/Addons.php:426 ../../Zotlabs/Lib/Apps.php:536 +msgid "Install" +msgstr "Zainstaluj" + +#: ../../Zotlabs/Module/Admin/Addons.php:449 +msgid "Manage Repos" +msgstr "Zarządzaj repozytoriami" + +#: ../../Zotlabs/Module/Admin/Addons.php:450 +msgid "Installed Addon Repositories" +msgstr "Zainstalowane repozytoria dodatków" + +#: ../../Zotlabs/Module/Admin/Addons.php:451 +msgid "Install a New Addon Repository" +msgstr "Zainstaluj nowe repozytorium dodatków" + +#: ../../Zotlabs/Module/Admin/Addons.php:458 +msgid "Switch branch" +msgstr "Przełącz gałąź" + +#: ../../Zotlabs/Module/Admin/Site.php:165 +msgid "Site settings updated." +msgstr "Zaktualizowano ustawienia serwisu." + +# hubzilla +# Copyright (C) 2012-2016 hubzilla +# This file is distributed under the same license as the hubzilla package. +# +# Translators: +# Alfonso Martínez , 2015 +# inboxwall , 2015 +# jeroenpraat, 2015 +# Manuel Jiménez Friaza , 2017-2020 +# Manuel Jiménez Friaza , 2015-2017 +# Rafael, 2015 +# tony baldwin , 2014 +#: ../../Zotlabs/Module/Admin/Site.php:191 ../../include/text.php:3381 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:335 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:359 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:435 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:459 +#: ../../view/theme/redbasic/php/config.php:15 +msgid "Default" +msgstr "Domyślnie" + +#: ../../Zotlabs/Module/Admin/Site.php:202 +#: ../../Zotlabs/Module/Settings/Display.php:118 +#, php-format +msgid "%s - (Incompatible)" +msgstr "%s - (niekompatybilne)" + +#: ../../Zotlabs/Module/Admin/Site.php:209 +msgid "mobile" +msgstr "urządzenie przenośne" + +#: ../../Zotlabs/Module/Admin/Site.php:211 +msgid "experimental" +msgstr "eksperymentalne" + +#: ../../Zotlabs/Module/Admin/Site.php:213 +msgid "unsupported" +msgstr "nieobsługiwane" + +#: ../../Zotlabs/Module/Admin/Site.php:260 +msgid "Yes - with approval" +msgstr "Tak - za zgodą" + +#: ../../Zotlabs/Module/Admin/Site.php:266 +msgid "My site is not a public server" +msgstr "Mój sewis nie jest serwerem publicznym" + +#: ../../Zotlabs/Module/Admin/Site.php:267 +msgid "My site has paid access only" +msgstr "Mój serwis ma tylko płatny dostęp" + +#: ../../Zotlabs/Module/Admin/Site.php:268 +msgid "My site has free access only" +msgstr "Mój serwis ma tylko bezpłatny dostęp" + +#: ../../Zotlabs/Module/Admin/Site.php:269 +msgid "My site offers free accounts with optional paid upgrades" +msgstr "" +"Mój serwis oferuje darmowe konta z opcjonalnymi płatnymi aktualizacjami" + +#: ../../Zotlabs/Module/Admin/Site.php:283 +msgid "Default permission role for new accounts" +msgstr "Domyślna rola uprawnień dla nowych kont" + +#: ../../Zotlabs/Module/Admin/Site.php:283 +msgid "" +"This role will be used for the first channel created after registration." +msgstr "" +"Ta rola będzie używana dla pierwszego kanału utworzonego po rejestracji." + +#: ../../Zotlabs/Module/Admin/Site.php:292 ../../Zotlabs/Widget/Admin.php:22 +msgid "Site" +msgstr "Witryna" + +#: ../../Zotlabs/Module/Admin/Site.php:294 +#: ../../Zotlabs/Module/Register.php:277 +msgid "Registration" +msgstr "Rejestracja" + +#: ../../Zotlabs/Module/Admin/Site.php:295 +msgid "File upload" +msgstr "Udostępnianie pliku" + +#: ../../Zotlabs/Module/Admin/Site.php:296 +msgid "Policies" +msgstr "Zasady" + +#: ../../Zotlabs/Module/Admin/Site.php:297 ../../include/contact_widgets.php:16 +#: ../../include/acl_selectors.php:144 +msgid "Advanced" +msgstr "Zaawansowane" + +#: ../../Zotlabs/Module/Admin/Site.php:301 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:593 +msgid "Site name" +msgstr "Nazwa witryny internetowej" + +#: ../../Zotlabs/Module/Admin/Site.php:303 +msgid "Banner/Logo" +msgstr "Baner/Logo" + +#: ../../Zotlabs/Module/Admin/Site.php:303 +msgid "Unfiltered HTML/CSS/JS is allowed" +msgstr "Dozwolony jest niefiltrowany kodd HTML/CSS /JS" + +#: ../../Zotlabs/Module/Admin/Site.php:304 +msgid "Administrator Information" +msgstr "Informacje administratora" + +#: ../../Zotlabs/Module/Admin/Site.php:304 +msgid "" +"Contact information for site administrators. Displayed on siteinfo page. " +"BBCode can be used here" +msgstr "" +"Informacje kontaktowe dla administratorów serwisu. Wyświetlane na stronie " +"informacji o serwisie. Tutaj można użyć BBCode" + +#: ../../Zotlabs/Module/Admin/Site.php:305 ../../Zotlabs/Module/Siteinfo.php:24 +msgid "Site Information" +msgstr "Informacje o serwisie" + +#: ../../Zotlabs/Module/Admin/Site.php:305 +msgid "" +"Publicly visible description of this site. Displayed on siteinfo page. " +"BBCode can be used here" +msgstr "" +"Publicznie widoczny opis tego serwisu. Wyświetlane na stronie informacji o " +"serwisie. Tutaj można użyć BBCode" + +#: ../../Zotlabs/Module/Admin/Site.php:306 +msgid "System language" +msgstr "Język systemu" + +#: ../../Zotlabs/Module/Admin/Site.php:307 +msgid "System theme" +msgstr "Motyw systemu" + +#: ../../Zotlabs/Module/Admin/Site.php:307 +msgid "" +"Default system theme - may be over-ridden by user profiles - change theme settings" +msgstr "" +"Domyślny motyw systemu - może zostać zastąpiony przez profile użytkowników - " +"zmień ustawienia motywu" + +#: ../../Zotlabs/Module/Admin/Site.php:310 +msgid "Allow Feeds as Connections" +msgstr "Zezwalaj na kanały jako połączenia" + +#: ../../Zotlabs/Module/Admin/Site.php:310 +msgid "(Heavy system resource usage)" +msgstr "(Duże zużycie zasobów systemowych)" + +#: ../../Zotlabs/Module/Admin/Site.php:311 +msgid "Maximum image size" +msgstr "Maksymalny rozmiar obrazu" + +#: ../../Zotlabs/Module/Admin/Site.php:311 +msgid "" +"Maximum size in bytes of uploaded images. Default is 0, which means no " +"limits." +msgstr "" +"Maksymalny rozmiar przesłanych obrazów w bajtach. Wartość domyślna to 0, co " +"oznacza brak ograniczeń." + +#: ../../Zotlabs/Module/Admin/Site.php:312 +msgid "Does this site allow new member registration?" +msgstr "Czy ta witryna umożliwia rejestrację nowych członków?" + +#: ../../Zotlabs/Module/Admin/Site.php:313 +msgid "Invitation only" +msgstr "Tylko z zaproszeniem" + +#: ../../Zotlabs/Module/Admin/Site.php:313 +msgid "" +"Only allow new member registrations with an invitation code. Above register " +"policy must be set to Yes." +msgstr "" +"Zezwalaj tylko na rejestracje nowych członków za pomocą kodu zaproszenia. " +"Powyższe zasady rejestrów muszą być ustawione na Tak." + +#: ../../Zotlabs/Module/Admin/Site.php:314 +msgid "Minimum age" +msgstr "Minimalny wiek" + +#: ../../Zotlabs/Module/Admin/Site.php:314 +msgid "Minimum age (in years) for who may register on this site." +msgstr "" +"Minimalny wiek (w latach) dla osób, które mogą zarejestrować się na tej " +"stronie." + +#: ../../Zotlabs/Module/Admin/Site.php:315 +msgid "Which best describes the types of account offered by this hub?" +msgstr "" +"Które z poniższych stwierdzeń najlepiej opisuje rodzaje kont oferowanych " +"przez ten hub?" + +#: ../../Zotlabs/Module/Admin/Site.php:315 +msgid "This is displayed on the public server site list." +msgstr "Jest to wyświetlane na liście witryn publicznych serwerów." + +#: ../../Zotlabs/Module/Admin/Site.php:316 +msgid "Register text" +msgstr "Tekst rejestracyjny" + +#: ../../Zotlabs/Module/Admin/Site.php:316 +msgid "Will be displayed prominently on the registration page." +msgstr "Zostanie on wyświetlony w widocznym miejscu na stronie rejestracji." + +#: ../../Zotlabs/Module/Admin/Site.php:318 +msgid "Site homepage to show visitors (default: login box)" +msgstr "" +"Strona główna serwisu do wyświetlania odwiedzającym (domyślnie: formularz " +"logowania)" + +#: ../../Zotlabs/Module/Admin/Site.php:318 +msgid "" +"example: 'pubstream' to show public stream, 'page/sys/home' to show a system " +"webpage called 'home' or 'include:home.html' to include a file." +msgstr "" +"przykład: 'pubstream', aby pokazać strumień publiczny, 'page/sys/home', aby " +"wyświetlić systemową stronę internetową o nazwie 'home' lub 'include: home." +"html', aby dołączyć plik." + +#: ../../Zotlabs/Module/Admin/Site.php:319 +msgid "Preserve site homepage URL" +msgstr "Zachowaj adres URL strony głównej serwisu" + +#: ../../Zotlabs/Module/Admin/Site.php:319 +msgid "" +"Present the site homepage in a frame at the original location instead of " +"redirecting" +msgstr "" +"Przedstaw stronę główną serwisu w ramce w oryginalnej lokalizacji zamiast " +"przekierowywania" + +#: ../../Zotlabs/Module/Admin/Site.php:320 +msgid "Accounts abandoned after x days" +msgstr "Konta porzucone po x dniach" + +#: ../../Zotlabs/Module/Admin/Site.php:320 +msgid "" +"Will not waste system resources polling external sites for abandonded " +"accounts. Enter 0 for no time limit." +msgstr "" +"Nie marnuje zasobów systemowych na odpytywanie zewnętrznych witryn w " +"poszukiwaniu porzuconych kont. Wpisz 0, aby nie mieć limitu czasu." + +#: ../../Zotlabs/Module/Admin/Site.php:321 +msgid "Allowed friend domains" +msgstr "Dozwolone domeny znajomych" + +#: ../../Zotlabs/Module/Admin/Site.php:321 +msgid "" +"Comma separated list of domains which are allowed to establish friendships " +"with this site. Wildcards are accepted. Empty to allow any domains" +msgstr "" +"Rozdzielana przecinkami lista domen, które mogą zawierać przyjaźnie z tą " +"witryną. Akceptowane są symbole wieloznaczne. Puste oznacza zezwolenie na " +"dowolne domeny" + +#: ../../Zotlabs/Module/Admin/Site.php:322 +msgid "Verify Email Addresses" +msgstr "Zweryfikuj adresy e-mail" + +#: ../../Zotlabs/Module/Admin/Site.php:322 +msgid "" +"Check to verify email addresses used in account registration (recommended)." +msgstr "" +"Zaznacz, aby zweryfikować adresy e-mail użyte podczas rejestracji konta " +"(zalecane)." + +#: ../../Zotlabs/Module/Admin/Site.php:323 +msgid "Force publish" +msgstr "Wymuś publikację" + +#: ../../Zotlabs/Module/Admin/Site.php:323 +msgid "" +"Check to force all profiles on this site to be listed in the site directory." +msgstr "" +"Zaznacz, aby wymusić wyświetlanie wszystkich profili w tym serwisie w " +"katalogu witryn." + +#: ../../Zotlabs/Module/Admin/Site.php:324 +msgid "Import Public Streams" +msgstr "Importuj strumienie publiczne" + +#: ../../Zotlabs/Module/Admin/Site.php:324 +msgid "" +"Import and allow access to public content pulled from other sites. Warning: " +"this content is unmoderated." +msgstr "" +"Importuj i zezwalaj na dostęp do treści publicznych pobranych z innych " +"serwisów. Ostrzeżenie: ta zawartość jest niemoderowana." + +#: ../../Zotlabs/Module/Admin/Site.php:325 +msgid "Site only Public Streams" +msgstr "W serwisie tylko strumienie publiczne" + +#: ../../Zotlabs/Module/Admin/Site.php:325 +msgid "" +"Allow access to public content originating only from this site if Imported " +"Public Streams are disabled." +msgstr "" +"Zezwalaj na dostęp do treści publicznych pochodzących tylko z tego serwisu, " +"jeśli importowane strumienie publiczne są wyłączone." + +#: ../../Zotlabs/Module/Admin/Site.php:326 +msgid "Allow anybody on the internet to access the Public streams" +msgstr "Zezwól każdemu w internecie na dostęp do strumieni publicznych" + +#: ../../Zotlabs/Module/Admin/Site.php:326 +msgid "" +"Disable to require authentication before viewing. Warning: this content is " +"unmoderated." +msgstr "" +"Wyłącz, aby wymagać uwierzytelnienia przed przeglądaniem. Ostrzeżenie: ta " +"zawartość jest niemoderowana." + +#: ../../Zotlabs/Module/Admin/Site.php:327 +msgid "Only import Public stream posts with this text" +msgstr "Importuj tylko posty ze strumienia publicznego z tym tekstem" + +#: ../../Zotlabs/Module/Admin/Site.php:328 +msgid "Do not import Public stream posts with this text" +msgstr "Nie importuj postów ze strumienia publicznego z tym tekstem" + +#: ../../Zotlabs/Module/Admin/Site.php:331 +msgid "Login on Homepage" +msgstr "Zaloguj się na stronie głównej" + +#: ../../Zotlabs/Module/Admin/Site.php:331 +msgid "" +"Present a login box to visitors on the home page if no other content has " +"been configured." +msgstr "" +"Przedstaw formularz logowania odwiedzającym na stronie głównej, jeśli nie " +"skonfigurowano żadnych innych treści." + +#: ../../Zotlabs/Module/Admin/Site.php:332 +msgid "Enable context help" +msgstr "Włącz pomoc kontekstową" + +#: ../../Zotlabs/Module/Admin/Site.php:332 +msgid "" +"Display contextual help for the current page when the help button is pressed." +msgstr "" +"Wyświetlanie pomocy kontekstowej dla bieżącej strony po naciśnięciu " +"przycisku pomocy." + +#: ../../Zotlabs/Module/Admin/Site.php:334 +msgid "Reply-to email address for system generated email." +msgstr "Zwrotny adres e-mail dla wiadomości wygenerowanych przez system." + +#: ../../Zotlabs/Module/Admin/Site.php:335 +msgid "Sender (From) email address for system generated email." +msgstr "" +"Adres e-mail nadawcy (Od) wiadomości e-mail wygenerowanej przez system." + +#: ../../Zotlabs/Module/Admin/Site.php:336 +msgid "Name of email sender for system generated email." +msgstr "Nazwa nadawcy wiadomości e-mail wygenerowanej przez system." + +#: ../../Zotlabs/Module/Admin/Site.php:338 +msgid "Directory Server URL" +msgstr "Adres URL serwera katalogowego" + +#: ../../Zotlabs/Module/Admin/Site.php:338 +msgid "Default directory server" +msgstr "Domyślny serwer katalogowy" + +#: ../../Zotlabs/Module/Admin/Site.php:340 +msgid "Enable SSE Notifications" +msgstr "Włącz powiadomienia SSE" + +#: ../../Zotlabs/Module/Admin/Site.php:340 +msgid "" +"If disabled, traditional polling will be used. Warning: this setting might " +"not be suited for shared hosting" +msgstr "" +"Jeśli wyłączone, będzie używane tradycyjne odpytywanie. Ostrzeżenie: to " +"ustawienie może nie być odpowiednie dla hostingu współdzielonego" + +#: ../../Zotlabs/Module/Admin/Site.php:342 +msgid "Proxy user" +msgstr "Użytkownik proxy" + +#: ../../Zotlabs/Module/Admin/Site.php:343 +msgid "Proxy URL" +msgstr "URL proxy" + +#: ../../Zotlabs/Module/Admin/Site.php:344 +msgid "Network timeout" +msgstr "Limit czasu sieci" + +#: ../../Zotlabs/Module/Admin/Site.php:344 +msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." +msgstr "" +"Wartość w sekundach. Ustaw na 0 dla nieograniczonej liczby (niezalecane)." + +#: ../../Zotlabs/Module/Admin/Site.php:345 +msgid "Delivery interval" +msgstr "Interwał dostaw" + +#: ../../Zotlabs/Module/Admin/Site.php:345 +msgid "" +"Delay background delivery processes by this many seconds to reduce system " +"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 " +"for large dedicated servers." +msgstr "" +"Opóźnij procesy dostarczania w tle o kilka sekund, aby zmniejszyć obciążenie " +"systemu. Zalecane: 4-5 dla hostów współdzielonych, 2-3 dla wirtualnych " +"serwerów prywatnych. 0-1 dla dużych serwerów dedykowanych." + +#: ../../Zotlabs/Module/Admin/Site.php:346 +msgid "Deliveries per process" +msgstr "Dostawy na proces" + +#: ../../Zotlabs/Module/Admin/Site.php:346 +msgid "" +"Number of deliveries to attempt in a single operating system process. Adjust " +"if necessary to tune system performance. Recommend: 1-5." +msgstr "" +"Liczba dostaw do podjęcia w ramach jednego procesu systemu operacyjnego. W " +"razie potrzeby dostosuj, aby dostroić wydajność systemu. Polecam: 1-5." + +#: ../../Zotlabs/Module/Admin/Site.php:347 +msgid "Queue Threshold" +msgstr "Próg kolejki" + +#: ../../Zotlabs/Module/Admin/Site.php:347 +msgid "" +"Always defer immediate delivery if queue contains more than this number of " +"entries." +msgstr "" +"Zawsze odraczaj natychmiastowe dostarczenie, jeśli kolejka zawiera więcej " +"pozycji niż ta." + +#: ../../Zotlabs/Module/Admin/Site.php:348 +msgid "Poll interval" +msgstr "Okres odpytywania" + +#: ../../Zotlabs/Module/Admin/Site.php:348 +msgid "" +"Delay background polling processes by this many seconds to reduce system " +"load. If 0, use delivery interval." +msgstr "" +"Opóźnij procesy sondowania w tle o kilka sekund, aby zmniejszyć obciążenie " +"systemu. Jeśli 0, użyty będzie interwał dostawy." + +#: ../../Zotlabs/Module/Admin/Site.php:349 +msgid "Path to ImageMagick convert program" +msgstr "Ścieżka do programu konwertującego ImageMagick" + +#: ../../Zotlabs/Module/Admin/Site.php:349 +msgid "" +"If set, use this program to generate photo thumbnails for huge images ( > " +"4000 pixels in either dimension), otherwise memory exhaustion may occur. " +"Example: /usr/bin/convert" +msgstr "" +"Jeśli jest ustawiona, użyj tego programu do generowania miniatur zdjęć dla " +"dużych obrazów (> 4000 pikseli w każdym wymiarze), w przeciwnym razie może " +"wystąpić wyczerpanie pamięci. Przykład: /usr/bin/convert" + +#: ../../Zotlabs/Module/Admin/Site.php:350 +msgid "Maximum Load Average" +msgstr "Maksymalne średnie obciążenie" + +#: ../../Zotlabs/Module/Admin/Site.php:350 +msgid "" +"Maximum system load before delivery and poll processes are deferred - " +"default 50." +msgstr "" +"Maksymalne obciążenie systemu przed odroczeniem procesów dostarczania i " +"odpytywania - domyślnie 50." + +#: ../../Zotlabs/Module/Admin/Site.php:351 +msgid "Expiration period in days for imported (grid/network) content" +msgstr "Okres ważności w dniach dla zaimportowanej treści (siatki/sieci)" + +#: ../../Zotlabs/Module/Admin/Site.php:351 +msgid "0 for no expiration of imported content" +msgstr "0 dla braku wygaśnięcia zaimportowanej treści" + +#: ../../Zotlabs/Module/Admin/Site.php:352 +msgid "" +"Do not expire any posts which have comments less than this many days ago" +msgstr "" +"Nie wygasaj żadnych postów, które mają komentarze z datami mniejszymi niż ta " +"wartość dni temu" + +#: ../../Zotlabs/Module/Admin/Site.php:354 +msgid "" +"Public servers: Optional landing (marketing) webpage for new registrants" +msgstr "" +"Serwery publiczne: opcjonalna strona lądowania (marketingowa) dla nowych " +"rejestrujących" + +#: ../../Zotlabs/Module/Admin/Site.php:354 +#, php-format +msgid "Create this page first. Default is %s/register" +msgstr "Utwórz najpierw tą stronę. Domyślnie %s/ register" + +#: ../../Zotlabs/Module/Admin/Site.php:355 +msgid "Page to display after creating a new channel" +msgstr "Strona do wyświetlenia po utworzeniu nowego kanału" + +#: ../../Zotlabs/Module/Admin/Site.php:355 +msgid "Default: profiles" +msgstr "Domyślnie: profile" + +#: ../../Zotlabs/Module/Admin/Site.php:357 +msgid "Optional: site location" +msgstr "Opcjonalnie: lokalizacja serwisu" + +#: ../../Zotlabs/Module/Admin/Site.php:357 +msgid "Region or country" +msgstr "Region lub kraj" + +#: ../../Zotlabs/Module/Admin/Profs.php:89 +msgid "New Profile Field" +msgstr "Nowe pole profilu" + +#: ../../Zotlabs/Module/Admin/Profs.php:90 +#: ../../Zotlabs/Module/Admin/Profs.php:110 +msgid "Field nickname" +msgstr "Krótka nazwa pola" + +#: ../../Zotlabs/Module/Admin/Profs.php:90 +#: ../../Zotlabs/Module/Admin/Profs.php:110 +msgid "System name of field" +msgstr "Systemowa nazwa pola" + +#: ../../Zotlabs/Module/Admin/Profs.php:91 +#: ../../Zotlabs/Module/Admin/Profs.php:111 +msgid "Input type" +msgstr "Typ wejścia" + +#: ../../Zotlabs/Module/Admin/Profs.php:92 +#: ../../Zotlabs/Module/Admin/Profs.php:112 +msgid "Field Name" +msgstr "Nazwa Pola" + +#: ../../Zotlabs/Module/Admin/Profs.php:92 +#: ../../Zotlabs/Module/Admin/Profs.php:112 +msgid "Label on profile pages" +msgstr "Etykieta na stronach profilu" + +#: ../../Zotlabs/Module/Admin/Profs.php:93 +#: ../../Zotlabs/Module/Admin/Profs.php:113 +msgid "Help text" +msgstr "Tekst pomocy" + +#: ../../Zotlabs/Module/Admin/Profs.php:93 +#: ../../Zotlabs/Module/Admin/Profs.php:113 +msgid "Additional info (optional)" +msgstr "Dodatkowe informacje (opcjonalnie)" + +#: ../../Zotlabs/Module/Admin/Profs.php:103 +msgid "Field definition not found" +msgstr "Nie znaleziono definicji pola" + +#: ../../Zotlabs/Module/Admin/Profs.php:109 +msgid "Edit Profile Field" +msgstr "Edytuj pole profilu" + +#: ../../Zotlabs/Module/Admin/Profs.php:168 ../../Zotlabs/Widget/Admin.php:30 +msgid "Profile Fields" +msgstr "Pola profilu" + +#: ../../Zotlabs/Module/Admin/Profs.php:169 +msgid "Basic Profile Fields" +msgstr "Podstawowe pola profilu" + +#: ../../Zotlabs/Module/Admin/Profs.php:170 +msgid "Advanced Profile Fields" +msgstr "Zaawansowane pola profilu" + +#: ../../Zotlabs/Module/Admin/Profs.php:170 +msgid "(In addition to basic fields)" +msgstr "(Oprócz podstawowych pól)" + +#: ../../Zotlabs/Module/Admin/Profs.php:172 +msgid "All available fields" +msgstr "Wszystkie dostępne pola" + +#: ../../Zotlabs/Module/Admin/Profs.php:173 +msgid "Custom Fields" +msgstr "Pola niestandardowe" + +#: ../../Zotlabs/Module/Admin/Profs.php:177 +msgid "Create Custom Field" +msgstr "Utwórz własne pole" + +#: ../../Zotlabs/Module/Notify.php:61 ../../Zotlabs/Module/Notifications.php:55 +msgid "No more system notifications." +msgstr "Nigdy więcej powiadomień systemowych." + +#: ../../Zotlabs/Module/Notify.php:65 ../../Zotlabs/Module/Notifications.php:59 +msgid "System Notifications" +msgstr "Powiadomienia systemowe" + +#: ../../Zotlabs/Module/Cal.php:64 +msgid "Permissions denied." +msgstr "Odmowa dostępu." + +#: ../../Zotlabs/Module/Thing.php:122 +msgid "Thing updated" +msgstr "Rzecz zaktualizowana" + +#: ../../Zotlabs/Module/Thing.php:174 +msgid "Object store: failed" +msgstr "Magazyn obiektów: błąd" + +#: ../../Zotlabs/Module/Thing.php:178 +msgid "Thing added" +msgstr "Rzecz dodana" + +#: ../../Zotlabs/Module/Thing.php:204 +#, php-format +msgid "OBJ: %1$s %2$s %3$s" +msgstr "OBJ: %1$s %2$s %3$s" + +#: ../../Zotlabs/Module/Thing.php:267 +msgid "Show Thing" +msgstr "Wyświetl rzecz" + +#: ../../Zotlabs/Module/Thing.php:274 +msgid "item not found." +msgstr "pozycja nie została znaleziona." + +#: ../../Zotlabs/Module/Thing.php:307 +msgid "Edit Thing" +msgstr "Edytuj rzecz" + +#: ../../Zotlabs/Module/Thing.php:309 ../../Zotlabs/Module/Thing.php:366 +msgid "Select a profile" +msgstr "Wybierz profile" + +#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 +msgid "Post an activity" +msgstr "Opublikuj aktywność" + +#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 +msgid "Only sends to viewers of the applicable profile" +msgstr "Wysyłane tylko do osób przeglądających odpowiedni profil" + +#: ../../Zotlabs/Module/Thing.php:315 ../../Zotlabs/Module/Thing.php:371 +msgid "Name of thing e.g. something" +msgstr "Nazwa rzeczy, np. coś" + +#: ../../Zotlabs/Module/Thing.php:317 ../../Zotlabs/Module/Thing.php:372 +msgid "URL of thing (optional)" +msgstr "URL rzeczy (opcjonalnie)" + +#: ../../Zotlabs/Module/Thing.php:319 ../../Zotlabs/Module/Thing.php:373 +msgid "URL for photo of thing (optional)" +msgstr "URL do zdjęcia rzeczy (opcjonalnie)" + +#: ../../Zotlabs/Module/Thing.php:364 +msgid "Add Thing to your Profile" +msgstr "Dodaj rzecz do swojego profilu" + +#: ../../Zotlabs/Module/Suggest.php:40 +msgid "Suggest Channels App" +msgstr "Aplikacja Suggest Channels" + +#: ../../Zotlabs/Module/Suggest.php:41 +msgid "" +"Suggestions for channels in the $Projectname network you might be interested " +"in" +msgstr "" +"Propozycje dotyczące kanałów w sieci $Projectname, które mogą Cię " +"zainteresować" + +#: ../../Zotlabs/Module/Suggest.php:54 +msgid "" +"No suggestions available. If this is a new site, please try again in 24 " +"hours." +msgstr "" +"Brak dostępnych prpozycji. Jeśli to jest nowy serwis, spróbuj ponownie za 24 " +"godziny." + +#: ../../Zotlabs/Module/Suggest.php:73 ../../Zotlabs/Widget/Suggestions.php:48 +msgid "Ignore/Hide" +msgstr "Ignoruj/Ukryj" + +#: ../../Zotlabs/Module/Suggest.php:79 ../../Zotlabs/Module/Directory.php:437 +#: ../../include/contact_widgets.php:24 +msgid "Channel Suggestions" +msgstr "Sugerowane kanały" + +#: ../../Zotlabs/Module/Email_validation.php:36 +msgid "Email Verification Required" +msgstr "Wymagana jest weryfikacja adresu e-mail" + +#: ../../Zotlabs/Module/Email_validation.php:37 +#, php-format +msgid "" +"A verification token was sent to your email address [%s]. Enter that token " +"here to complete the account verification step. Please allow a few minutes " +"for delivery, and check your spam folder if you do not see the message." +msgstr "" +"Token weryfikacyjny został wysłany na Twój adres e-mail [% s]. Wprowadź tuta " +"ten token, aby zakończyć etap weryfikacji konta. Poczekaj kilka minut na " +"dostarczenie i jeśli nie widzisz wiadomości, sprawdź folder ze spamem." + +#: ../../Zotlabs/Module/Email_validation.php:38 +msgid "Resend Email" +msgstr "Wyślij ponownie wiadomość e-mail" + +#: ../../Zotlabs/Module/Email_validation.php:41 +msgid "Validation token" +msgstr "Token walidacyjny" + +#: ../../Zotlabs/Module/Notes.php:57 +msgid "Notes App" +msgstr "Aplikacja Notes" + +#: ../../Zotlabs/Module/Notes.php:58 +msgid "A simple notes app with a widget (note: notes are not encrypted)" +msgstr "" +"Prosta aplikacja do notatek z widżetem (uwaga: notatki nie są szyfrowane)" + +#: ../../Zotlabs/Module/Tokens.php:39 +#, php-format +msgid "This channel is limited to %d tokens" +msgstr "Ten kanał jest ograniczony do %d tokenów" + +#: ../../Zotlabs/Module/Tokens.php:45 +msgid "Name and Password are required." +msgstr "Wymagane są Imię i hasło." + +#: ../../Zotlabs/Module/Tokens.php:85 +msgid "Token saved." +msgstr "Token został zapisany." + +#: ../../Zotlabs/Module/Tokens.php:99 +msgid "Guest Access App" +msgstr "Aplikacja Guest Access" + +#: ../../Zotlabs/Module/Tokens.php:100 +msgid "Create access tokens so that non-members can access private content" +msgstr "" +"Utwórz tokeny dostępu, aby osoby niebędące członkami mogły uzyskać dostęp do " +"treści prywatnych" + +#: ../../Zotlabs/Module/Tokens.php:133 +msgid "" +"Use this form to create temporary access identifiers to share things with " +"non-members. These identities may be used in Access Control Lists and " +"visitors may login using these credentials to access private content." +msgstr "" +"Użyj tego formularza, aby utworzyć tymczasowe identyfikatory dostępu, aby " +"udostępniać rzeczy osobom niebędącym członkami. Tożsamości te mogą być " +"używane na listach kontroli dostępu, a odwiedzający mogą logować się przy " +"użyciu tych poświadczeń, aby uzyskać dostęp do treści prywatnych." + +#: ../../Zotlabs/Module/Tokens.php:135 +msgid "" +"You may also provide dropbox style access links to friends and " +"associates by adding the Login Password to any specific site URL as shown. " +"Examples:" +msgstr "" +"Możesz także udostępnić znajomym i współpracownikom łącza dostępu w stylu " +"dropbox, dodając hasło logowania do dowolnego adresu URL witryny, " +"jak pokazano na ilustracji. Przykłady:" + +#: ../../Zotlabs/Module/Tokens.php:170 +msgid "Guest Access Tokens" +msgstr "Tokent Guest Access" + +#: ../../Zotlabs/Module/Tokens.php:177 +msgid "Login Name" +msgstr "Nazwa logowania" + +#: ../../Zotlabs/Module/Tokens.php:178 +msgid "Login Password" +msgstr "Hasło logowania" + +#: ../../Zotlabs/Module/Tokens.php:179 +msgid "Expires (yyyy-mm-dd)" +msgstr "Wygasa (rrrr-mm-dd)" + +#: ../../Zotlabs/Module/Apporder.php:47 +msgid "Change Order of Pinned Navbar Apps" +msgstr "Zmień kolejność aplikacji przypiętych do paska nawigacyjnego" + +#: ../../Zotlabs/Module/Apporder.php:47 +msgid "Change Order of App Tray Apps" +msgstr "Zmień kolejność aplikacji na pasku aplikacji" + +#: ../../Zotlabs/Module/Apporder.php:48 +msgid "" +"Use arrows to move the corresponding app left (top) or right (bottom) in the " +"navbar" +msgstr "" +"Użyj strzałek, aby przesunąć odpowiednią aplikację w lewo (u góry) lub w " +"prawo (u dołu) na pasku nawigacyjnym" + +#: ../../Zotlabs/Module/Apporder.php:48 +msgid "Use arrows to move the corresponding app up or down in the app tray" +msgstr "" +"Użyj strzałek, aby przesunąć odpowiednią aplikację w górę lub w dół w " +"zasobniku aplikacji" + +#: ../../Zotlabs/Module/Notifications.php:60 +#: ../../Zotlabs/Lib/ThreadItem.php:482 +msgid "Mark all seen" +msgstr "Oznacz wszystkie jako oglądnięte" + +#: ../../Zotlabs/Module/Home.php:72 ../../Zotlabs/Module/Home.php:80 +#: ../../Zotlabs/Lib/Enotify.php:66 +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:42 +msgid "$Projectname" +msgstr "Hubzilla" + +#: ../../Zotlabs/Module/Home.php:90 +#, php-format +msgid "Welcome to %s" +msgstr "Witamy w %s" + +#: ../../Zotlabs/Module/Articles.php:52 +msgid "Articles App" +msgstr "Aplikacja Articles" + +#: ../../Zotlabs/Module/Articles.php:53 +msgid "Create interactive articles" +msgstr "Twórz interaktywne artykuły" + +#: ../../Zotlabs/Module/Articles.php:116 +msgid "Add Article" +msgstr "Dodaj artykuł" + +#: ../../Zotlabs/Module/Articles.php:226 ../../Zotlabs/Lib/Apps.php:325 +#: ../../include/nav.php:512 +msgid "Articles" +msgstr "Artykuły" + +#: ../../Zotlabs/Module/Setup.php:167 +msgid "$Projectname Server - Setup" +msgstr "Serwer $Projectname - Konfiguracja" + +#: ../../Zotlabs/Module/Setup.php:171 +msgid "Could not connect to database." +msgstr "Nie można połączyć się z bazą danych." + +#: ../../Zotlabs/Module/Setup.php:175 +msgid "" +"Could not connect to specified site URL. Possible SSL certificate or DNS " +"issue." +msgstr "" +"Nie można połączyć się z określonym adresem URL serwisu. Możliwy problem z " +"certyfikatem SSL lub DNS." + +#: ../../Zotlabs/Module/Setup.php:182 +msgid "Could not create table." +msgstr "Nie udało się utworzyć tabeli." + +#: ../../Zotlabs/Module/Setup.php:188 +msgid "Your site database has been installed." +msgstr "Baza danych serwisu została zainstalowana." + +#: ../../Zotlabs/Module/Setup.php:194 +msgid "" +"You may need to import the file \"install/schema_xxx.sql\" manually using a " +"database client." +msgstr "" +"Może być konieczne ręczne zaimportowanie pliku „install/schema_xxx.sql” za " +"pomocą klienta bazy danych." + +#: ../../Zotlabs/Module/Setup.php:195 ../../Zotlabs/Module/Setup.php:259 +#: ../../Zotlabs/Module/Setup.php:766 +msgid "Please see the file \"install/INSTALL.txt\"." +msgstr "Zobacz plik \"install/INSTALL.txt\"." + +#: ../../Zotlabs/Module/Setup.php:256 +msgid "System check" +msgstr "Sprawdzanie systemu" + +#: ../../Zotlabs/Module/Setup.php:261 +msgid "Check again" +msgstr "Sprawdź ponownie" + +#: ../../Zotlabs/Module/Setup.php:282 +msgid "Database connection" +msgstr "Połączenie z bazą danych" + +#: ../../Zotlabs/Module/Setup.php:283 +msgid "" +"In order to install $Projectname we need to know how to connect to your " +"database." +msgstr "" +"Aby zainstalować $Projectname, musimy wiedzieć, jak połączyć się z twoją " +"bazą danych." + +#: ../../Zotlabs/Module/Setup.php:284 +msgid "" +"Please contact your hosting provider or site administrator if you have " +"questions about these settings." +msgstr "" +"Jeśli masz pytania dotyczące tych ustawień, skontaktuj się z dostawcą usług " +"hostingowych lub administratorem serwisu." + +#: ../../Zotlabs/Module/Setup.php:285 +msgid "" +"The database you specify below should already exist. If it does not, please " +"create it before continuing." +msgstr "" +"Baza danych, którą określisz poniżej, powinna już istnieć. Jeśli tak się nie " +"stało, utwórz ją przed kontynuowaniem." + +#: ../../Zotlabs/Module/Setup.php:289 +msgid "Database Server Name" +msgstr "Nazwa serwera bazy danych" + +#: ../../Zotlabs/Module/Setup.php:289 +msgid "Default is 127.0.0.1" +msgstr "Domyślnie, 127.0.0.1" + +#: ../../Zotlabs/Module/Setup.php:290 +msgid "Database Port" +msgstr "Port bazy danych" + +#: ../../Zotlabs/Module/Setup.php:290 +msgid "Communication port number - use 0 for default" +msgstr "Numer portu komunikacyjnego - dla wartości domyślnej użyj 0" + +#: ../../Zotlabs/Module/Setup.php:291 +msgid "Database Login Name" +msgstr "Nazwa logowania do bazy danych" + +#: ../../Zotlabs/Module/Setup.php:292 +msgid "Database Login Password" +msgstr "Hasło logowania do bazy danych" + +#: ../../Zotlabs/Module/Setup.php:293 +msgid "Database Name" +msgstr "Nazwa bazy danych" + +#: ../../Zotlabs/Module/Setup.php:294 +msgid "Database Type" +msgstr "Typ bazy danych" + +#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 +msgid "Site administrator email address" +msgstr "Adres e-mail administratora serwisu" + +#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 +msgid "" +"Your account email address must match this in order to use the web admin " +"panel." +msgstr "" +"Adres e-mail Twojego konta będzie musi być zgodny z tym adresem, aby móc " +"korzystać z panelu administratora sieci." + +#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 +msgid "Website URL" +msgstr "Adres URL serwisu" + +#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 +msgid "Please use SSL (https) URL if available." +msgstr "Użyj adresu URL z SSL (https), jeśli jest dostępny." + +#: ../../Zotlabs/Module/Setup.php:298 ../../Zotlabs/Module/Setup.php:340 +msgid "Please select a default timezone for your website" +msgstr "Wybierz domyślną strefę czasową dla swojego serwisu" + +#: ../../Zotlabs/Module/Setup.php:325 +msgid "Site settings" +msgstr "Ustawienia serwisu" + +#: ../../Zotlabs/Module/Setup.php:379 +msgid "PHP version 7.1 or greater is required." +msgstr "Wymagany jest PHP w wersji 7.1 lub wyższej." + +#: ../../Zotlabs/Module/Setup.php:380 +msgid "PHP version" +msgstr "Wersja PHP" + +#: ../../Zotlabs/Module/Setup.php:396 +msgid "Could not find a command line version of PHP in the web server PATH." +msgstr "Nie można znaleźć wersji CLI PHP w zmiennej PATH serwerze WWW." + +#: ../../Zotlabs/Module/Setup.php:397 +msgid "" +"If you don't have a command line version of PHP installed on server, you " +"will not be able to run background polling via cron." +msgstr "" +"Jeśli nie masz wersji CLI PHP zainstalowanej na serwerze, nie będzie można " +"uruchomić odpytywania w tle przez cron." + +#: ../../Zotlabs/Module/Setup.php:401 +msgid "PHP executable path" +msgstr "Ścieżka do pliku wykonywalnego PHP" + +#: ../../Zotlabs/Module/Setup.php:401 +msgid "" +"Enter full path to php executable. You can leave this blank to continue the " +"installation." +msgstr "" +"Wpisz pełną ścieżkę do pliku wykonywalnego php. Możesz pozostawić to pole " +"puste, aby kontynuować instalację." + +#: ../../Zotlabs/Module/Setup.php:406 +msgid "Command line PHP" +msgstr "PHP CLI" + +#: ../../Zotlabs/Module/Setup.php:416 +msgid "" +"Unable to check command line PHP, as shell_exec() is disabled. This is " +"required." +msgstr "" +"Nie można sprawdzić PHP CLI, ponieważ funkcja shell_exec() jest wyłączona. " +"To jest wymagane." + +#: ../../Zotlabs/Module/Setup.php:420 +msgid "" +"The command line version of PHP on your system does not have " +"\"register_argc_argv\" enabled." +msgstr "PHP CLI w Twoim systemie nie ma włączonego \"register_argc_argv\"." + +#: ../../Zotlabs/Module/Setup.php:421 +msgid "This is required for message delivery to work." +msgstr "Jest to konieczne,, aby dostarczanie wiadomości działało." + +#: ../../Zotlabs/Module/Setup.php:424 +msgid "PHP register_argc_argv" +msgstr "PHP register_argc_argv" + +#: ../../Zotlabs/Module/Setup.php:444 +msgid "" +"This is not sufficient to upload larger images or files. You should be able " +"to upload at least 4 MB at once." +msgstr "" +"To nie wystarczy, aby przesłać większe obrazy lub pliki. Powinieneś móc " +"przesłać co najmniej 4 MB na raz." + +#: ../../Zotlabs/Module/Setup.php:446 +#, php-format +msgid "" +"Your max allowed total upload size is set to %s. Maximum size of one file to " +"upload is set to %s. You are allowed to upload up to %d files at once." +msgstr "" +"Twój maksymalny dopuszczalny łączny rozmiar przesyłanych plików to %s. " +"Maksymalny rozmiar jednego pliku do przesłania to %s. Możesz przesłać " +"jednocześnie do %d plików." + +#: ../../Zotlabs/Module/Setup.php:452 +msgid "You can adjust these settings in the server php.ini file." +msgstr "Możesz dostosować te ustawienia w pliku php.ini na serwerze." + +#: ../../Zotlabs/Module/Setup.php:454 +msgid "PHP upload limits" +msgstr "Limity wysyłania PHP" + +#: ../../Zotlabs/Module/Setup.php:477 +msgid "" +"Error: the \"openssl_pkey_new\" function on this system is not able to " +"generate encryption keys" +msgstr "" +"Błąd: funkcja \"openssl_pkey_new\" w tym systemie nie jest w stanie " +"wygenerować kluczy szyfrujących" + +#: ../../Zotlabs/Module/Setup.php:478 +msgid "" +"If running under Windows, please see \"http://www.php.net/manual/en/openssl." +"installation.php\"." +msgstr "" +"Jeśli pracujesz w systemie Windows, przeczytaj \"http://www.php.net/manual/" +"en/openssl.installation.php\"." + +#: ../../Zotlabs/Module/Setup.php:481 +msgid "Generate encryption keys" +msgstr "Wygeneruj klucze szyfrowania" + +#: ../../Zotlabs/Module/Setup.php:498 +msgid "libCurl PHP module" +msgstr "moduł PHP libCurl" + +#: ../../Zotlabs/Module/Setup.php:499 +msgid "GD graphics PHP module" +msgstr "Moduł PHP GD graphics" + +#: ../../Zotlabs/Module/Setup.php:500 +msgid "OpenSSL PHP module" +msgstr "Moduł PHP OpenSSL" + +#: ../../Zotlabs/Module/Setup.php:501 +msgid "PDO database PHP module" +msgstr "Moduł PHP PDO" + +#: ../../Zotlabs/Module/Setup.php:502 +msgid "mb_string PHP module" +msgstr "moduł PHP mb_string PHP" + +#: ../../Zotlabs/Module/Setup.php:503 +msgid "xml PHP module" +msgstr "moduł PHP xml" + +#: ../../Zotlabs/Module/Setup.php:504 +msgid "zip PHP module" +msgstr "moduł PHP zip" + +#: ../../Zotlabs/Module/Setup.php:508 ../../Zotlabs/Module/Setup.php:510 +msgid "Apache mod_rewrite module" +msgstr "Moduł Apache mod_rewrite" + +#: ../../Zotlabs/Module/Setup.php:508 +msgid "" +"Error: Apache webserver mod-rewrite module is required but not installed." +msgstr "" +"Błąd: wymagany jest moduł mod-rewrite serwera Apache, ale nie jest " +"zainstalowany." + +#: ../../Zotlabs/Module/Setup.php:514 ../../Zotlabs/Module/Setup.php:517 +msgid "exec" +msgstr "exec" + +#: ../../Zotlabs/Module/Setup.php:514 +msgid "" +"Error: exec is required but is either not installed or has been disabled in " +"php.ini" +msgstr "" +"Błąd: wymagany jest program exec ale nie jest on zainstalowany lub został " +"wyłączony w php.ini" + +#: ../../Zotlabs/Module/Setup.php:520 ../../Zotlabs/Module/Setup.php:523 +msgid "shell_exec" +msgstr "shell_exec" + +#: ../../Zotlabs/Module/Setup.php:520 +msgid "" +"Error: shell_exec is required but is either not installed or has been " +"disabled in php.ini" +msgstr "" +"Błąd: wymagany jest shell_exec, ale nie jest zainstalowany lub został " +"wyłączony w php.ini" + +#: ../../Zotlabs/Module/Setup.php:528 +msgid "Error: libCURL PHP module required but not installed." +msgstr "Błąd: wymagany jest moduł PHP libCURL, ale nie jest zainstalowany." + +#: ../../Zotlabs/Module/Setup.php:532 +msgid "" +"Error: GD PHP module with JPEG support or ImageMagick graphics library " +"required but not installed." +msgstr "" +"Błąd: wymagany jest moduł PHP GD z obsługą formatu JPEG lub biblioteką " +"graficzną ImageMagick, ale nie jest on zainstalowany." + +#: ../../Zotlabs/Module/Setup.php:536 +msgid "Error: openssl PHP module required but not installed." +msgstr "Błąd: wymagany jest moduł PHP openssl, ale niezainstalowany." + +#: ../../Zotlabs/Module/Setup.php:542 +msgid "" +"Error: PDO database PHP module missing a driver for either mysql or pgsql." +msgstr "Błąd: w module PHP PDO brakuje sterownika dla mysql lub pgsql." + +#: ../../Zotlabs/Module/Setup.php:547 +msgid "Error: PDO database PHP module required but not installed." +msgstr "Błąd: wymagany jest moduł PHP PDO, ale nie jest zainstalowany." + +#: ../../Zotlabs/Module/Setup.php:551 +msgid "Error: mb_string PHP module required but not installed." +msgstr "Błąd: wymagany, ale niezainstalowany moduł mb_string PHP." + +#: ../../Zotlabs/Module/Setup.php:555 +msgid "Error: xml PHP module required for DAV but not installed." +msgstr "Błąd: moduł XML PHP wymagany dla DAV, ale nie jest zainstalowany." + +#: ../../Zotlabs/Module/Setup.php:559 +msgid "Error: zip PHP module required but not installed." +msgstr "Błąd: wymagany jest moduł PHP zip, ale nie jest on zainstalowany." + +#: ../../Zotlabs/Module/Setup.php:578 ../../Zotlabs/Module/Setup.php:587 +msgid ".htconfig.php is writable" +msgstr ".htconfig.php jest możliwy do zapisu" + +#: ../../Zotlabs/Module/Setup.php:583 +msgid "" +"The web installer needs to be able to create a file called \".htconfig.php\" " +"in the top folder of your web server and it is unable to do so." +msgstr "" +"Instalator internetowy musi mieć możliwość utworzenia pliku o nazwie \"." +"htconfig.php\" w głównym folderze serwera WWW a nie może tego zrobić." + +#: ../../Zotlabs/Module/Setup.php:584 +msgid "" +"This is most often a permission setting, as the web server may not be able " +"to write files in your folder - even if you can." +msgstr "" +"Najczęściej jest to ustawienie uprawnień, ponieważ serwer WWW może nie być w " +"stanie zapisywać plików w Twoim folderze - nawet jeśli możesz." + +#: ../../Zotlabs/Module/Setup.php:585 +msgid "Please see install/INSTALL.txt for additional information." +msgstr "Dodatkowe informacje można znaleźć w pliku install/INSTALL.txt." + +#: ../../Zotlabs/Module/Setup.php:601 +msgid "" +"This software uses the Smarty3 template engine to render its web views. " +"Smarty3 compiles templates to PHP to speed up rendering." +msgstr "" +"To oprogramowanie wykorzystuje silnik szablonów Smarty3 do renderowania " +"widoków internetowych. Smarty3 kompiluje szablony do PHP, aby przyspieszyć " +"renderowanie." + +#: ../../Zotlabs/Module/Setup.php:602 +#, php-format +msgid "" +"In order to store these compiled templates, the web server needs to have " +"write access to the directory %s under the top level web folder." +msgstr "" +"Aby przechowywać te skompilowane szablony, serwer sieciowy musi mieć dostęp " +"do zapisu w katalogu %s zlokalizowanym w folderze głównym serwera WWW." + +#: ../../Zotlabs/Module/Setup.php:603 ../../Zotlabs/Module/Setup.php:624 +msgid "" +"Please ensure that the user that your web server runs as (e.g. www-data) has " +"write access to this folder." +msgstr "" +"Upewnij się, że właściciel procesu serwer WWW (np. www-data), ma prawo do " +"zapisu w tym folderze." + +#: ../../Zotlabs/Module/Setup.php:604 +#, php-format +msgid "" +"Note: as a security measure, you should give the web server write access to " +"%s only--not the template files (.tpl) that it contains." +msgstr "" +"Uwaga: ze względów bezpieczeństwa powinno się dać serwerowi WWW prawo zapisu " +"tylko do %s - nie do plików szablonów (.tpl), które on zawiera." + +#: ../../Zotlabs/Module/Setup.php:607 +#, php-format +msgid "%s is writable" +msgstr "%s jest możliwy do zapisu" + +#: ../../Zotlabs/Module/Setup.php:623 +msgid "" +"This software uses the store directory to save uploaded files. The web " +"server needs to have write access to the store directory under the top level " +"web folder" +msgstr "" +"To oprogramowanie używa katalogu store do zapisywania przesyłanych " +"plików. Serwer WWW musi mieć dostęp do zapisu w katalogu store, " +"znajdującego się w folderze serwera WWW najwyższego poziomu" + +#: ../../Zotlabs/Module/Setup.php:627 +msgid "store is writable" +msgstr "katalog store jest możliwy do zapisu" + +#: ../../Zotlabs/Module/Setup.php:659 +msgid "" +"SSL certificate cannot be validated. Fix certificate or disable https access " +"to this site." +msgstr "" +"Nie można zweryfikować certyfikatu SSL. Napraw certyfikat lub wyłącz dostęp " +"https do tej witryny." + +#: ../../Zotlabs/Module/Setup.php:660 +msgid "" +"If you have https access to your website or allow connections to TCP port " +"443 (the https: port), you MUST use a browser-valid certificate. You MUST " +"NOT use self-signed certificates!" +msgstr "" +"Jeśli masz dostęp https do swojego serwisu internetowego lub zezwalasz na " +"połączenia z portem TCP 443 (port https:), MUSISZ użyć certyfikatu " +"akceptowanego przez przeglądarki. NIE WOLNO używać certyfikatów z podpisem " +"własnym!" + +#: ../../Zotlabs/Module/Setup.php:661 +msgid "" +"This restriction is incorporated because public posts from you may for " +"example contain references to images on your own hub." +msgstr "" +"To ograniczenie zostało wprowadzone, ponieważ Twoje publiczne posty mogą na " +"przykład zawierać odniesienia do obrazów na Twoim hubie." + +#: ../../Zotlabs/Module/Setup.php:662 +msgid "" +"If your certificate is not recognized, members of other sites (who may " +"themselves have valid certificates) will get a warning message on their own " +"site complaining about security issues." +msgstr "" +"Jeśli Twój certyfikat nie zostanie rozpoznany, członkowie innych witryn " +"(którzy sami mogą mieć ważne certyfikaty) otrzymają komunikat ostrzegawczy " +"we własnej witrynie, ostrzegający o problemie z bezpieczeństwem." + +#: ../../Zotlabs/Module/Setup.php:663 +msgid "" +"This can cause usability issues elsewhere (not just on your own site) so we " +"must insist on this requirement." +msgstr "" +"Może to powodować problemy z użytecznością w innym serwisie (nie tylko na " +"Twoim), więc musimy nalegać na to wymaganie." + +#: ../../Zotlabs/Module/Setup.php:664 +msgid "" +"Providers are available that issue free certificates which are browser-valid." +msgstr "" +"Są dostępni dostawcy, którzy wydają bezpłatne certyfikaty akceptowane przez " +"przeglądarki." + +#: ../../Zotlabs/Module/Setup.php:665 +msgid "" +"If you are confident that the certificate is valid and signed by a trusted " +"authority, check to see if you have failed to install an intermediate cert. " +"These are not normally required by browsers, but are required for server-to-" +"server communications." +msgstr "" +"Jeśli masz pewność, że certyfikat jest ważny i podpisany przez zaufany " +"urząd, sprawdź, czy nie udało się zainstalować certyfikatu pośredniego. " +"Zwykle nie są one wymagane przez przeglądarki, ale są wymagane do " +"komunikacji między serwerami." + +#: ../../Zotlabs/Module/Setup.php:667 +msgid "SSL certificate validation" +msgstr "Walidacja certyfikatu SSL" + +#: ../../Zotlabs/Module/Setup.php:673 +msgid "" +"Url rewrite in .htaccess is not working. Check your server configuration." +"Test: " +msgstr "" +"Przepisywanie adresu URL w .htaccess nie działa. Sprawdź konfigurację " +"serwera. Test: " + +#: ../../Zotlabs/Module/Setup.php:676 +msgid "Url rewrite is working" +msgstr "Przepisywanie adresu URL działa" + +#: ../../Zotlabs/Module/Setup.php:689 +msgid "" +"The database configuration file \".htconfig.php\" could not be written. " +"Please use the enclosed text to create a configuration file in your web " +"server root." +msgstr "" +"Nie można zapisać pliku konfiguracyjnego bazy danych \".htconfig.php\". Użyj " +"załączonego tekstu, aby utworzyć plik konfiguracyjny w katalogu głównym " +"serwera WWW." + +#: ../../Zotlabs/Module/Setup.php:718 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:401 +msgid "Errors encountered creating database tables." +msgstr "Napotkano błędy podczas tworzenia tabel bazy danych." + +#: ../../Zotlabs/Module/Setup.php:764 +msgid "

      What next?

      " +msgstr "

      Co następnie?

      " + +#: ../../Zotlabs/Module/Setup.php:765 +msgid "" +"IMPORTANT: You will need to [manually] setup a scheduled task for the poller." +msgstr "" +"WAŻNE: Będziesz musiał [ręcznie] ustawić zaplanowane zadanie dla ankietera." + +#: ../../Zotlabs/Module/Directory.php:122 +msgid "No default suggestions were found." +msgstr "Nie znaleziono domyślnych prpozycji." + +#: ../../Zotlabs/Module/Directory.php:282 +#, php-format +msgid "%d rating" +msgid_plural "%d ratings" +msgstr[0] "%d ocen" +msgstr[1] "%d oceny" +msgstr[2] "%d ocen" + +#: ../../Zotlabs/Module/Directory.php:293 +msgid "Gender: " +msgstr "Płeć: " + +#: ../../Zotlabs/Module/Directory.php:295 +msgid "Status: " +msgstr "Status: " + +#: ../../Zotlabs/Module/Directory.php:297 +msgid "Homepage: " +msgstr "Strona główna: " + +#: ../../Zotlabs/Module/Directory.php:349 ../../include/channel.php:1806 +msgid "Age:" +msgstr "Wiek:" + +#: ../../Zotlabs/Module/Directory.php:354 ../../include/channel.php:1633 +#: ../../include/event.php:63 ../../include/event.php:134 +msgid "Location:" +msgstr "Lokalizacja:" + +#: ../../Zotlabs/Module/Directory.php:360 +msgid "Description:" +msgstr "Opis:" + +#: ../../Zotlabs/Module/Directory.php:367 ../../include/channel.php:1835 +msgid "Hometown:" +msgstr "Miasto pobytu:" + +#: ../../Zotlabs/Module/Directory.php:369 ../../include/channel.php:1841 +msgid "About:" +msgstr "O mnie:" + +#: ../../Zotlabs/Module/Directory.php:371 +msgid "Public Forum:" +msgstr "Forum publiczne:" + +#: ../../Zotlabs/Module/Directory.php:374 +msgid "Keywords: " +msgstr "Słowa kluczowe: " + +#: ../../Zotlabs/Module/Directory.php:377 +msgid "Don't suggest" +msgstr "Nie sugeruj" + +#: ../../Zotlabs/Module/Directory.php:379 +msgid "Common connections (estimated):" +msgstr "Popularne połączenia (oszacowanie):" + +#: ../../Zotlabs/Module/Directory.php:428 +msgid "Global Directory" +msgstr "Katalog globalny" + +#: ../../Zotlabs/Module/Directory.php:428 +msgid "Local Directory" +msgstr "Katalog lokalny" + +#: ../../Zotlabs/Module/Directory.php:434 +msgid "Finding:" +msgstr "Odnaleziono:" + +#: ../../Zotlabs/Module/Directory.php:439 +msgid "next page" +msgstr "następna strona" + +#: ../../Zotlabs/Module/Directory.php:439 +msgid "previous page" +msgstr "poprzednia strona" + +#: ../../Zotlabs/Module/Directory.php:440 +msgid "Sort options" +msgstr "Opcje sortowania" + +#: ../../Zotlabs/Module/Directory.php:441 +msgid "Alphabetic" +msgstr "Alfabetycznie" + +#: ../../Zotlabs/Module/Directory.php:442 +msgid "Reverse Alphabetic" +msgstr "Odwróć alfabetycznie" + +#: ../../Zotlabs/Module/Directory.php:443 +msgid "Newest to Oldest" +msgstr "Od najnowszych do najstarszych" + +#: ../../Zotlabs/Module/Directory.php:444 +msgid "Oldest to Newest" +msgstr "Od najstarszych do najnowszych" + +#: ../../Zotlabs/Module/Directory.php:461 +msgid "No entries (some entries may be hidden)." +msgstr "Brak postów (niektóre posty mogą być ukryte)." + +#: ../../Zotlabs/Module/Mitem.php:31 ../../Zotlabs/Module/Menu.php:209 +msgid "Menu not found." +msgstr "Nie znaleziono menu." + +#: ../../Zotlabs/Module/Mitem.php:63 +msgid "Unable to create element." +msgstr "Nie można utworzyć elementu." + +#: ../../Zotlabs/Module/Mitem.php:87 +msgid "Unable to update menu element." +msgstr "Nie można zaktualizować elementu menu." + +#: ../../Zotlabs/Module/Mitem.php:103 +msgid "Unable to add menu element." +msgstr "Nie można dodać elementu menu." + +#: ../../Zotlabs/Module/Mitem.php:167 ../../Zotlabs/Module/Mitem.php:246 +msgid "Menu Item Permissions" +msgstr "Uprawnienia do pozycji menu" + +#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247 +#: ../../Zotlabs/Module/Settings/Channel.php:528 +msgid "(click to open/close)" +msgstr "(kliknij, aby otworzyć/zamknąć)" + +#: ../../Zotlabs/Module/Mitem.php:174 ../../Zotlabs/Module/Mitem.php:191 +msgid "Link Name" +msgstr "Nazwa linku" + +#: ../../Zotlabs/Module/Mitem.php:175 ../../Zotlabs/Module/Mitem.php:255 +msgid "Link or Submenu Target" +msgstr "Link lub element docelowy podmenu" + +#: ../../Zotlabs/Module/Mitem.php:175 +msgid "Enter URL of the link or select a menu name to create a submenu" +msgstr "Wprowadź adres URL linku lub wybierz nazwę menu, aby utworzyć podmenu" + +#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:256 +msgid "Use magic-auth if available" +msgstr "Użyj magicznego uwierzytelniania, jeśli jest dostępne" + +#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:257 +msgid "Open link in new window" +msgstr "Otwórz link w nowym oknie" + +#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 +msgid "Order in list" +msgstr "Porządek listy" + +#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 +msgid "Higher numbers will sink to bottom of listing" +msgstr "Wyższe liczby spadną na koniec listy" + +#: ../../Zotlabs/Module/Mitem.php:179 +msgid "Submit and finish" +msgstr "Prześlij i zakończ" + +#: ../../Zotlabs/Module/Mitem.php:180 +msgid "Submit and continue" +msgstr "Prześlij i kontynuuj" + +#: ../../Zotlabs/Module/Mitem.php:189 +msgid "Menu:" +msgstr "Menu:" + +#: ../../Zotlabs/Module/Mitem.php:192 +msgid "Link Target" +msgstr "Cel linku" + +#: ../../Zotlabs/Module/Mitem.php:195 +msgid "Edit menu" +msgstr "Edytuj menu" + +#: ../../Zotlabs/Module/Mitem.php:198 +msgid "Edit element" +msgstr "Edytuj element" + +#: ../../Zotlabs/Module/Mitem.php:199 +msgid "Drop element" +msgstr "Upuść element" + +#: ../../Zotlabs/Module/Mitem.php:200 +msgid "New element" +msgstr "Nowy element" + +#: ../../Zotlabs/Module/Mitem.php:201 +msgid "Edit this menu container" +msgstr "Edytuj ten kontener menu" + +#: ../../Zotlabs/Module/Mitem.php:202 +msgid "Add menu element" +msgstr "Dodaj element menu" + +#: ../../Zotlabs/Module/Mitem.php:203 +msgid "Delete this menu item" +msgstr "Usuń tę pozycję menu" + +#: ../../Zotlabs/Module/Mitem.php:204 +msgid "Edit this menu item" +msgstr "Edytuj tę pozycję menu" + +#: ../../Zotlabs/Module/Mitem.php:222 +msgid "Menu item not found." +msgstr "Nie znaleziono elementu menu." + +#: ../../Zotlabs/Module/Mitem.php:235 +msgid "Menu item deleted." +msgstr "Usunieto element menu." + +#: ../../Zotlabs/Module/Mitem.php:237 +msgid "Menu item could not be deleted." +msgstr "Nie można usunąć elementu menu." + +#: ../../Zotlabs/Module/Mitem.php:244 +msgid "Edit Menu Element" +msgstr "Edytuj element menu" + +#: ../../Zotlabs/Module/Mitem.php:254 +msgid "Link text" +msgstr "Tekst linku" + +#: ../../Zotlabs/Module/Mood.php:76 ../../include/conversation.php:286 +#, php-format +msgctxt "mood" +msgid "%1$s is %2$s" +msgstr "%1$s jest %2$s" + +#: ../../Zotlabs/Module/Mood.php:134 +msgid "Mood App" +msgstr "Aplikacja Mood" + +#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Module/Mood.php:155 +msgid "Set your current mood and tell your friends" +msgstr "Ustaw swój aktualny nastrój i podziel się tym ze znajomymi" + +#: ../../Zotlabs/Module/Mood.php:154 ../../Zotlabs/Lib/Apps.php:350 +msgid "Mood" +msgstr "Mood" + +#: ../../Zotlabs/Module/Permcats.php:29 +msgid "Permission category name is required." +msgstr "Wymaga się podania nazwy kategorii uprawnień." + +#: ../../Zotlabs/Module/Permcats.php:48 +msgid "Permission category saved." +msgstr "Kategoria uprawnień została zapisana." + +#: ../../Zotlabs/Module/Permcats.php:63 +msgid "Permission Categories App" +msgstr "Aplikacja Permission Categories" + +#: ../../Zotlabs/Module/Permcats.php:64 +msgid "Create custom connection permission limits" +msgstr "Utwórz własne limity uprawnień do połączeń" + +#: ../../Zotlabs/Module/Permcats.php:80 +msgid "" +"Use this form to create permission rules for various classes of people or " +"connections." +msgstr "" +"Użyj tego formularza, aby utworzyć reguły uprawnień dla różnych klas osób " +"lub połączeń." + +#: ../../Zotlabs/Module/Permcats.php:113 ../../Zotlabs/Lib/Apps.php:374 +msgid "Permission Categories" +msgstr "Kategorie uprawnień" + +#: ../../Zotlabs/Module/Permcats.php:121 +msgid "Permission category name" +msgstr "Nazwa kategorii uprawnień" + +#: ../../Zotlabs/Module/Ratings.php:70 +msgid "No ratings" +msgstr "Brak ocen" + +#: ../../Zotlabs/Module/Ratings.php:98 +msgid "Rating: " +msgstr "Ocena: " + +#: ../../Zotlabs/Module/Ratings.php:99 +msgid "Website: " +msgstr "Serwis: " + +#: ../../Zotlabs/Module/Ratings.php:101 +msgid "Description: " +msgstr "Opis: " + +#: ../../Zotlabs/Module/Register.php:52 +msgid "Maximum daily site registrations exceeded. Please try again tomorrow." +msgstr "" +"Przekroczono maksymalną dzienną liczbę rejestracji witryn. Proszę spróbuj " +"ponownie jutro." + +#: ../../Zotlabs/Module/Register.php:58 +msgid "" +"Please indicate acceptance of the Terms of Service. Registration failed." +msgstr "" +"Proszę zaznaczyć akceptację Warunków korzystania z usługi. " +"Rejestracja nieudana." + +#: ../../Zotlabs/Module/Register.php:92 +msgid "Passwords do not match." +msgstr "Hasła niezgodne." + +#: ../../Zotlabs/Module/Register.php:135 +msgid "Registration successful. Continue to create your first channel..." +msgstr "" +"Rejestracja pomyślna. Kontynuuj tworzenie swojego pierwszego kanału ..." + +#: ../../Zotlabs/Module/Register.php:138 +msgid "" +"Registration successful. Please check your email for validation instructions." +msgstr "" +"Rejestracja oomyślna. Sprawdź pocztę e-mail, aby uzyskać instrukcje " +"dotyczące weryfikacji." + +#: ../../Zotlabs/Module/Register.php:145 +msgid "Your registration is pending approval by the site owner." +msgstr "Twoja rejestracja oczekuje na zatwierdzenie przez właściciela serwisu." + +#: ../../Zotlabs/Module/Register.php:148 +msgid "Your registration can not be processed." +msgstr "Twoja rejestracja oczekuje na zatwierdzenie przez właściciela witryny." + +#: ../../Zotlabs/Module/Register.php:195 +msgid "Registration on this hub is disabled." +msgstr "Rejestracja na tym hubie jest wyłączona." + +#: ../../Zotlabs/Module/Register.php:204 +msgid "Registration on this hub is by approval only." +msgstr "Rejestracja na tym hubie wymaga zatwierdzenia." + +#: ../../Zotlabs/Module/Register.php:205 ../../Zotlabs/Module/Register.php:214 +msgid "Register at another affiliated hub." +msgstr "" +"Zarejestruj się na innym stowarzyszonym hubie. " + +#: ../../Zotlabs/Module/Register.php:213 +msgid "Registration on this hub is by invitation only." +msgstr "Rejestracja na tym hubie wumaga uprzedniego zaproszenia." + +#: ../../Zotlabs/Module/Register.php:224 +msgid "" +"This site has exceeded the number of allowed daily account registrations. " +"Please try again tomorrow." +msgstr "" +"Na tym serwisie przekroczono dozwoloną liczbę dziennych rejestracji kont. " +"Proszę spróbuj ponownie jutro." + +#: ../../Zotlabs/Module/Register.php:239 ../../Zotlabs/Module/Siteinfo.php:28 +msgid "Terms of Service" +msgstr "Regulamin" + +#: ../../Zotlabs/Module/Register.php:245 +#, php-format +msgid "I accept the %s for this website" +msgstr "Akceptuję % s dla tego serwisu" + +#: ../../Zotlabs/Module/Register.php:252 +#, php-format +msgid "I am over %s years of age and accept the %s for this website" +msgstr "Mam ponad % s lat i akceptuję % s dla tego serwisu" + +#: ../../Zotlabs/Module/Register.php:257 +msgid "Your email address" +msgstr "Twój adres e-mail" + +#: ../../Zotlabs/Module/Register.php:258 +msgid "Choose a password" +msgstr "Wybierz hasło" + +#: ../../Zotlabs/Module/Register.php:259 +msgid "Please re-enter your password" +msgstr "Wprowadź ponownie swoje hasło" + +#: ../../Zotlabs/Module/Register.php:260 +msgid "Please enter your invitation code" +msgstr "Wprowadź kod zaproszenia" + +#: ../../Zotlabs/Module/Register.php:261 +msgid "Your Name" +msgstr "Twoja nazwa" + +#: ../../Zotlabs/Module/Register.php:261 +msgid "Real names are preferred." +msgstr "Preferowane są prawdziwe imiona." + +#: ../../Zotlabs/Module/Register.php:263 +#, php-format +msgid "" +"Your nickname will be used to create an easy to remember channel address e." +"g. nickname%s" +msgstr "" +"Twój pseudonim posłuży do stworzenia łatwego do zapamiętania adresu kanału, " +"np. pseudonim%s" + +#: ../../Zotlabs/Module/Register.php:264 +msgid "" +"Select a channel permission role for your usage needs and privacy " +"requirements." +msgstr "" +"Wybierz rolę uprawnień do kanału zgodnie z potrzebami użytkowania i " +"wymaganiami dotyczącymi prywatności." + +#: ../../Zotlabs/Module/Register.php:265 +msgid "no" +msgstr "nie" + +#: ../../Zotlabs/Module/Register.php:265 +msgid "yes" +msgstr "tak" + +#: ../../Zotlabs/Module/Register.php:293 ../../include/nav.php:162 +#: ../../boot.php:1685 +msgid "Register" +msgstr "Zarejestruj się" + +#: ../../Zotlabs/Module/Register.php:294 +msgid "" +"This site requires email verification. After completing this form, please " +"check your email for further instructions." +msgstr "" +"Ta witryna wymaga weryfikację adresu e-mail. Po wypełnieniu tego formularza " +"sprawdź swoją pocztę e-mail, aby uzyskać dalsze instrukcje." + +#: ../../Zotlabs/Module/Acl.php:123 ../../Zotlabs/Module/Lockview.php:117 +#: ../../Zotlabs/Module/Lockview.php:153 +msgctxt "acl" +msgid "Profile" +msgstr "Profil" + +#: ../../Zotlabs/Module/Acl.php:370 +msgid "network" +msgstr "sieć" + +#: ../../Zotlabs/Module/Settings/Featured.php:25 +msgid "No feature settings configured" +msgstr "Brak skonfigurowanych ustawień funkcji" + +#: ../../Zotlabs/Module/Settings/Featured.php:34 +msgid "Addon Settings" +msgstr "Ustawienia dodatków" + +#: ../../Zotlabs/Module/Settings/Featured.php:35 +msgid "Please save/submit changes to any panel before opening another." +msgstr "Zapisz/prześlij zmiany do dowolnego panelu przed otwarciem kolejnego." + +#: ../../Zotlabs/Module/Settings/Account.php:19 +msgid "Not valid email." +msgstr "Nieprawidłowy adres e-mail." + +#: ../../Zotlabs/Module/Settings/Account.php:22 +msgid "Protected email address. Cannot change to that email." +msgstr "Chroniony adres e-mail. Nie można zmienić tego adresu e-mail." + +#: ../../Zotlabs/Module/Settings/Account.php:31 +msgid "System failure storing new email. Please try again." +msgstr "" +"Błąd systemu podczas zapisywania nowej wiadomości e-mail. Proszę spróbuj " +"ponownie." + +#: ../../Zotlabs/Module/Settings/Account.php:48 +msgid "Password verification failed." +msgstr "Weryfikacja hasła nie powiodła się." + +#: ../../Zotlabs/Module/Settings/Account.php:55 +msgid "Passwords do not match. Password unchanged." +msgstr "Hasła nie pasują do siebie. Nie zmieniono hasła." + +#: ../../Zotlabs/Module/Settings/Account.php:59 +msgid "Empty passwords are not allowed. Password unchanged." +msgstr "Puste hasła są niedozwolone. Nie zmieniono hasła." + +#: ../../Zotlabs/Module/Settings/Account.php:73 +msgid "Password changed." +msgstr "Hasło zostało zmienione." + +#: ../../Zotlabs/Module/Settings/Account.php:75 +msgid "Password update failed. Please try again." +msgstr "Aktualizacja hasła nie powiodła się. Proszę spróbuj ponownie." + +#: ../../Zotlabs/Module/Settings/Account.php:99 +msgid "Account Settings" +msgstr "Ustawienia konta" + +#: ../../Zotlabs/Module/Settings/Account.php:100 +msgid "Current Password" +msgstr "Bieżące hasło" + +#: ../../Zotlabs/Module/Settings/Account.php:101 +msgid "Enter New Password" +msgstr "Wprowadź nowe hasło" + +#: ../../Zotlabs/Module/Settings/Account.php:102 +msgid "Confirm New Password" +msgstr "Potwierdź nowe hasło" + +#: ../../Zotlabs/Module/Settings/Account.php:102 +msgid "Leave password fields blank unless changing" +msgstr "Pozostaw pola hasła puste, chyba że je zmieniasz" + +#: ../../Zotlabs/Module/Settings/Account.php:104 +#: ../../Zotlabs/Module/Settings/Channel.php:502 +msgid "Email Address:" +msgstr "Adres e-mail:" + +#: ../../Zotlabs/Module/Settings/Account.php:106 +msgid "Remove this account including all its channels" +msgstr "Usuń to konto wraz ze wszystkimi jego kanałami" + +#: ../../Zotlabs/Module/Settings/Events.php:40 +msgid "Events Settings" +msgstr "Ustawienia wydarzeń" + +#: ../../Zotlabs/Module/Settings/Profiles.php:49 +msgid "Profiles Settings" +msgstr "Ustawienia profili" + +#: ../../Zotlabs/Module/Settings/Editor.php:40 +msgid "Editor Settings" +msgstr "Editor Settings" + +#: ../../Zotlabs/Module/Settings/Features.php:45 +msgid "Additional Features" +msgstr "Dodatkowe funkcjonalności" + +#: ../../Zotlabs/Module/Settings/Manage.php:41 +msgid "Channel Manager Settings" +msgstr "Ustawienia menadżera kanałów" + +#: ../../Zotlabs/Module/Settings/Display.php:127 +#, php-format +msgid "%s - (Experimental)" +msgstr "%s - (eksperymentalne)" + +#: ../../Zotlabs/Module/Settings/Display.php:183 +msgid "Display Settings" +msgstr "Ustawienia wyświetlania" + +#: ../../Zotlabs/Module/Settings/Display.php:184 +msgid "Theme Settings" +msgstr "Ustawienia motywu" + +#: ../../Zotlabs/Module/Settings/Display.php:185 +msgid "Custom Theme Settings" +msgstr "Ustawienia własnego motywu" + +#: ../../Zotlabs/Module/Settings/Display.php:186 +msgid "Content Settings" +msgstr "Ustawienia treści" + +#: ../../Zotlabs/Module/Settings/Display.php:192 +msgid "Display Theme:" +msgstr "Wyświetl motyw:" + +#: ../../Zotlabs/Module/Settings/Display.php:193 +msgid "Select scheme" +msgstr "Wybierz schemat" + +#: ../../Zotlabs/Module/Settings/Display.php:195 +msgid "Preload images before rendering the page" +msgstr "Przeładuj obrazy przed renderowaniem strony" + +#: ../../Zotlabs/Module/Settings/Display.php:195 +msgid "" +"The subjective page load time will be longer but the page will be ready when " +"displayed" +msgstr "" +"Subiektywny czas ładowania strony będzie dłuższy, ale strona będzie gotowa " +"po wyświetleniu" + +#: ../../Zotlabs/Module/Settings/Display.php:196 +msgid "Enable user zoom on mobile devices" +msgstr "Włącz zoom użytkownika na urządzeniach mobilnych" + +#: ../../Zotlabs/Module/Settings/Display.php:197 +msgid "Update browser every xx seconds" +msgstr "Aktualizuj przeglądarkę co xx sekund" + +#: ../../Zotlabs/Module/Settings/Display.php:197 +msgid "Minimum of 10 seconds, no maximum" +msgstr "Co najmniej 10 sekund, nie maksimum" + +#: ../../Zotlabs/Module/Settings/Display.php:198 +msgid "Maximum number of conversations to load at any time:" +msgstr "Maksymalna liczba rozmów do załadowania w dowolnym momencie:" + +#: ../../Zotlabs/Module/Settings/Display.php:198 +msgid "Maximum of 30 items" +msgstr "Maksymalnie 30 pozycji" + +#: ../../Zotlabs/Module/Settings/Display.php:199 +msgid "Show emoticons (smilies) as images" +msgstr "Pokaż emotikony (uśmieszki) jako obrazy" + +#: ../../Zotlabs/Module/Settings/Display.php:200 +msgid "Provide channel menu in navigation bar" +msgstr "Podaj menu kanału na pasku nawigacji" + +#: ../../Zotlabs/Module/Settings/Display.php:200 +msgid "Default: channel menu located in app menu" +msgstr "Domyślnie: menu kanału znajduje się w menu aplikacji" + +#: ../../Zotlabs/Module/Settings/Display.php:201 +msgid "Link post titles to source" +msgstr "Połącz tytuły postów ze źródłem" + +#: ../../Zotlabs/Module/Settings/Display.php:203 +#: ../../Zotlabs/Widget/Newmember.php:75 +msgid "New Member Links" +msgstr "Linki dla nowych członków" + +#: ../../Zotlabs/Module/Settings/Display.php:203 +msgid "Display new member quick links menu" +msgstr "Wyświetl menu szybkich łączy dla nowych członków" + +#: ../../Zotlabs/Module/Settings/Photos.php:40 +msgid "Photos Settings" +msgstr "Ustawienia zdjęć" + +#: ../../Zotlabs/Module/Settings/Channel.php:329 +msgid "Nobody except yourself" +msgstr "Nikt oprócz ciebie" + +#: ../../Zotlabs/Module/Settings/Channel.php:330 +msgid "Only those you specifically allow" +msgstr "Tylko te, na które jawnie zezwalasz" + +#: ../../Zotlabs/Module/Settings/Channel.php:331 +msgid "Approved connections" +msgstr "Zatwierdzone połączenia" + +#: ../../Zotlabs/Module/Settings/Channel.php:332 +msgid "Any connections" +msgstr "Wszelkie połączenia" + +#: ../../Zotlabs/Module/Settings/Channel.php:333 +msgid "Anybody on this website" +msgstr "Każdy w tym serwisie" + +#: ../../Zotlabs/Module/Settings/Channel.php:334 +msgid "Anybody in this network" +msgstr "Każdy w tej sieci" + +#: ../../Zotlabs/Module/Settings/Channel.php:335 +msgid "Anybody authenticated" +msgstr "Każda uwierzytelniona osoba" + +#: ../../Zotlabs/Module/Settings/Channel.php:336 +msgid "Anybody on the internet" +msgstr "Każdy w internecie" + +#: ../../Zotlabs/Module/Settings/Channel.php:411 +msgid "Publish your default profile in the network directory" +msgstr "Opublikuj swój domyślny profil w katalogu sieciowym" + +#: ../../Zotlabs/Module/Settings/Channel.php:416 +msgid "Allow us to suggest you as a potential friend to new members?" +msgstr "" +"Czy pozwalasz nam sugerować Ciebie jako potencjalnego przyjaciela nowym " +"członkom?" + +#: ../../Zotlabs/Module/Settings/Channel.php:420 +msgid "or" +msgstr "lub" + +#: ../../Zotlabs/Module/Settings/Channel.php:429 +msgid "Your channel address is" +msgstr "Twój adres kanału to" + +#: ../../Zotlabs/Module/Settings/Channel.php:432 +msgid "Your files/photos are accessible via WebDAV at" +msgstr "Twoje pliki/zdjęcia są dostępne przez WebDAV pod adresem" + +#: ../../Zotlabs/Module/Settings/Channel.php:472 +msgid "Automatic membership approval" +msgstr "Automatyczne zatwierdzanie członkostwa" + +#: ../../Zotlabs/Module/Settings/Channel.php:493 +msgid "Channel Settings" +msgstr "Ustawienia kanału" + +#: ../../Zotlabs/Module/Settings/Channel.php:500 +msgid "Basic Settings" +msgstr "Podstawowe ustawienia" + +#: ../../Zotlabs/Module/Settings/Channel.php:501 ../../include/channel.php:1763 +msgid "Full Name:" +msgstr "Pełna nazwa:" + +#: ../../Zotlabs/Module/Settings/Channel.php:503 +msgid "Your Timezone:" +msgstr "Twoja strefa czasowa:" + +#: ../../Zotlabs/Module/Settings/Channel.php:504 +msgid "Default Post Location:" +msgstr "Domyślna lokalizacja postu:" + +#: ../../Zotlabs/Module/Settings/Channel.php:504 +msgid "Geographical location to display on your posts" +msgstr "Lokalizacja geograficzna do wyświetlania w Twoich postach" + +#: ../../Zotlabs/Module/Settings/Channel.php:505 +msgid "Use Browser Location:" +msgstr "Użyj lokalizacji przeglądarki:" + +#: ../../Zotlabs/Module/Settings/Channel.php:507 +msgid "Adult Content" +msgstr "Treść dla dorosłych" + +#: ../../Zotlabs/Module/Settings/Channel.php:507 +msgid "" +"This channel frequently or regularly publishes adult content. (Please tag " +"any adult material and/or nudity with #NSFW)" +msgstr "" +"Ten kanał często lub regularnie publikuje treści dla dorosłych. (Oznacz " +"wszelkie materiały dla dorosłych albo nagość tagiem #NSFW)" + +#: ../../Zotlabs/Module/Settings/Channel.php:509 +msgid "Security and Privacy Settings" +msgstr "Ustawienia bezpieczeństwa i prywatności" + +#: ../../Zotlabs/Module/Settings/Channel.php:511 +msgid "Your permissions are already configured. Click to view/adjust" +msgstr "" +"Twoje uprawnienia są już skonfigurowane. Kliknij, aby wyświetlić/dostosować" + +#: ../../Zotlabs/Module/Settings/Channel.php:513 +msgid "Hide my online presence" +msgstr "Ukryj moją obecność w Internecie" + +#: ../../Zotlabs/Module/Settings/Channel.php:513 +msgid "Prevents displaying in your profile that you are online" +msgstr "Zapobiega wyświetlaniu w Twoim profilu, że jesteś online" + +#: ../../Zotlabs/Module/Settings/Channel.php:515 +msgid "Simple Privacy Settings:" +msgstr "Proste ustawienia prywatności:" + +#: ../../Zotlabs/Module/Settings/Channel.php:516 +msgid "" +"Very Public - extremely permissive (should be used with caution)" +msgstr "" +"Bardzo publiczne - wyjątkowo pobłażliwe (należy używać ostrożnie)" + +#: ../../Zotlabs/Module/Settings/Channel.php:517 +msgid "" +"Typical - default public, privacy when desired (similar to social " +"network permissions but with improved privacy)" +msgstr "" +"Typowe - domyślne publiczne, prywatność w razie potrzeby (podobne do " +"uprawnień w popularnych sieciach społecznościowych, ale z podwyższoną " +"prywatnością)" + +#: ../../Zotlabs/Module/Settings/Channel.php:518 +msgid "Private - default private, never open or public" +msgstr "Prywatne - domyślnie prywatne, nigdy otwarte ani publiczne" + +#: ../../Zotlabs/Module/Settings/Channel.php:519 +msgid "Blocked - default blocked to/from everybody" +msgstr "Zablokowane - domyślnie zablokowane dla/od wszystkich" + +#: ../../Zotlabs/Module/Settings/Channel.php:521 +msgid "Allow others to tag your posts" +msgstr "Pozwól innym oznaczać Twoje posty" + +#: ../../Zotlabs/Module/Settings/Channel.php:521 +msgid "" +"Often used by the community to retro-actively flag inappropriate content" +msgstr "" +"Często używany przez społeczność do oznaczania nieodpowiednich treści z mocą " +"wsteczną" + +#: ../../Zotlabs/Module/Settings/Channel.php:523 +msgid "Channel Permission Limits" +msgstr "Limity uprawnień kanału" + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "Expire other channel content after this many days" +msgstr "Po tej ilości dni wygasają inne treści w kanale" + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "0 or blank to use the website limit." +msgstr "0 lub puste, aby użyć limitu serwisu." + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +#, php-format +msgid "This website expires after %d days." +msgstr "Ta strona wygasa po %d dniach." + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "This website does not expire imported content." +msgstr "" +"Na tym serwis internetowym importowanej zawartości nie jest wygaszana." + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "The website limit takes precedence if lower than your limit." +msgstr "Limit serwisu ma pierwszeństwo, jeśli jest niższy niż Twój limit." + +#: ../../Zotlabs/Module/Settings/Channel.php:526 +msgid "Maximum Friend Requests/Day:" +msgstr "Maksymalna liczba zaproszeń do znajomych, dziennie:" + +#: ../../Zotlabs/Module/Settings/Channel.php:526 +msgid "May reduce spam activity" +msgstr "Może zmniejszyć aktywność spamu" + +#: ../../Zotlabs/Module/Settings/Channel.php:527 +msgid "Default Privacy Group" +msgstr "Domyślna grupa prywatności" + +#: ../../Zotlabs/Module/Settings/Channel.php:529 +msgid "Use my default audience setting for the type of object published" +msgstr "" +"Użyj mojego domyślnego ustawienia odbiorców dla typu publikowanego obiektu" + +#: ../../Zotlabs/Module/Settings/Channel.php:538 +msgid "Default permissions category" +msgstr "Domyślna kategoria uprawnień" + +#: ../../Zotlabs/Module/Settings/Channel.php:544 +msgid "Maximum private messages per day from unknown people:" +msgstr "Maksymalna liczba prywatnych wiadomości dziennie od nieznanych osób:" + +#: ../../Zotlabs/Module/Settings/Channel.php:544 +msgid "Useful to reduce spamming" +msgstr "Przydatne do ograniczenia spamowania" + +#: ../../Zotlabs/Module/Settings/Channel.php:547 +#: ../../Zotlabs/Lib/Enotify.php:68 +msgid "Notification Settings" +msgstr "Ustawienia powiadomień" + +#: ../../Zotlabs/Module/Settings/Channel.php:548 +msgid "By default post a status message when:" +msgstr "Domyślnie publikuj komunikat o stanie, gdy:" + +#: ../../Zotlabs/Module/Settings/Channel.php:549 +msgid "accepting a friend request" +msgstr "zaakceptowano zaproszenia do znajomych" + +#: ../../Zotlabs/Module/Settings/Channel.php:550 +msgid "joining a forum/community" +msgstr "dołączoni do forum/społeczności" + +#: ../../Zotlabs/Module/Settings/Channel.php:551 +msgid "making an interesting profile change" +msgstr "dokonano interesującej zmiany profilu" + +#: ../../Zotlabs/Module/Settings/Channel.php:552 +msgid "Send a notification email when:" +msgstr "Wyślij e-mail z powiadomieniem, gdy:" + +#: ../../Zotlabs/Module/Settings/Channel.php:553 +msgid "You receive a connection request" +msgstr "Otrzymujesz żądanie połączenia" + +#: ../../Zotlabs/Module/Settings/Channel.php:554 +msgid "Your connections are confirmed" +msgstr "Twoje połączenia są potwierdzone" + +#: ../../Zotlabs/Module/Settings/Channel.php:555 +msgid "Someone writes on your profile wall" +msgstr "Ktoś pisze na Twojej ścianie profilu" + +#: ../../Zotlabs/Module/Settings/Channel.php:556 +msgid "Someone writes a followup comment" +msgstr "Ktoś pisze komentarz uzupełniający" + +#: ../../Zotlabs/Module/Settings/Channel.php:557 +msgid "You receive a private message" +msgstr "Otrzymujesz prywatną wiadomość" + +#: ../../Zotlabs/Module/Settings/Channel.php:558 +msgid "You receive a friend suggestion" +msgstr "Otrzymasz propozycję znajomości" + +#: ../../Zotlabs/Module/Settings/Channel.php:559 +msgid "You are tagged in a post" +msgstr "Oznaczono Ciebie tagiem w poście" + +#: ../../Zotlabs/Module/Settings/Channel.php:560 +msgid "You are poked/prodded/etc. in a post" +msgstr "Szturchnięto Ciebie w poście" + +#: ../../Zotlabs/Module/Settings/Channel.php:562 +msgid "Someone likes your post/comment" +msgstr "Ktoś polubił Twój post/komentarz" + +#: ../../Zotlabs/Module/Settings/Channel.php:565 +msgid "Show visual notifications including:" +msgstr "Pokaż powiadomienia wizualne, w tym:" + +#: ../../Zotlabs/Module/Settings/Channel.php:567 +msgid "Unseen stream activity" +msgstr "Niewidoczną aktywność na strumieniu" + +#: ../../Zotlabs/Module/Settings/Channel.php:568 +msgid "Unseen channel activity" +msgstr "Niewidoczną aktywność w kanale" + +#: ../../Zotlabs/Module/Settings/Channel.php:569 +msgid "Unseen private messages" +msgstr "Niewidoczną wiadomości prywatne" + +#: ../../Zotlabs/Module/Settings/Channel.php:569 +#: ../../Zotlabs/Module/Settings/Channel.php:574 +#: ../../Zotlabs/Module/Settings/Channel.php:575 +#: ../../Zotlabs/Module/Settings/Channel.php:576 +msgid "Recommended" +msgstr "Zalecane" + +#: ../../Zotlabs/Module/Settings/Channel.php:570 +msgid "Upcoming events" +msgstr "Nadchodzące wydarzenia" + +#: ../../Zotlabs/Module/Settings/Channel.php:571 +msgid "Events today" +msgstr "Wydarzenia dzisiejsze" + +#: ../../Zotlabs/Module/Settings/Channel.php:572 +msgid "Upcoming birthdays" +msgstr "Nadchodzące urodziny" + +#: ../../Zotlabs/Module/Settings/Channel.php:572 +msgid "Not available in all themes" +msgstr "Niedostępne we wszystkich motywach" + +#: ../../Zotlabs/Module/Settings/Channel.php:573 +msgid "System (personal) notifications" +msgstr "Powiadomienia systemowe (osobiste)" + +#: ../../Zotlabs/Module/Settings/Channel.php:574 +msgid "System info messages" +msgstr "Systemowe komunikaty informacyjne" + +#: ../../Zotlabs/Module/Settings/Channel.php:575 +msgid "System critical alerts" +msgstr "Systemowe alerty krytyczne" + +#: ../../Zotlabs/Module/Settings/Channel.php:576 +msgid "New connections" +msgstr "Nowe połączenia" + +#: ../../Zotlabs/Module/Settings/Channel.php:577 +msgid "System Registrations" +msgstr "Rejestracje systemowe" + +#: ../../Zotlabs/Module/Settings/Channel.php:578 +msgid "Unseen shared files" +msgstr "Niewidoczne udostępnione pliki" + +#: ../../Zotlabs/Module/Settings/Channel.php:579 +msgid "Unseen public stream activity" +msgstr "Niewidoczna aktywność na publicznym strumieniu" + +#: ../../Zotlabs/Module/Settings/Channel.php:580 +msgid "Unseen likes and dislikes" +msgstr "Niewidoczne polubienia i dezaprobaty" + +#: ../../Zotlabs/Module/Settings/Channel.php:581 +msgid "Unseen forum posts" +msgstr "Niewidoczne posty na forum" + +#: ../../Zotlabs/Module/Settings/Channel.php:582 +msgid "Email notification hub (hostname)" +msgstr "Hub powiadomień e-mail (nazwa hosta)" + +#: ../../Zotlabs/Module/Settings/Channel.php:582 +#, php-format +msgid "" +"If your channel is mirrored to multiple hubs, set this to your preferred " +"location. This will prevent duplicate email notifications. Example: %s" +msgstr "" +"Jeśli twój kanał jest powielany na wielu hubach, ustaw to na preferowaną " +"lokalizację. Zapobiegnie to powielaniu powiadomień e-mail. Przykład: % s" + +#: ../../Zotlabs/Module/Settings/Channel.php:583 +msgid "Show new wall posts, private messages and connections under Notices" +msgstr "" +"Pokaż w powiadomieniach nowe posty na ścianie, prywatne wiadomości i " +"połączenia" + +#: ../../Zotlabs/Module/Settings/Channel.php:585 +msgid "Notify me of events this many days in advance" +msgstr "Informuj mnie o wydarzeniach z tak wielodniowym wyprzedzeniem" + +#: ../../Zotlabs/Module/Settings/Channel.php:585 +msgid "Must be greater than 0" +msgstr "Musi być większa od 0" + +#: ../../Zotlabs/Module/Settings/Channel.php:590 +msgid "Advanced Account/Page Type Settings" +msgstr "Zaawansowane ustawienia konta/typu strony" + +#: ../../Zotlabs/Module/Settings/Channel.php:591 +msgid "Change the behaviour of this account for special situations" +msgstr "Zmień zachowanie tego konta w szczególnych sytuacjach" + +#: ../../Zotlabs/Module/Settings/Channel.php:593 +msgid "Miscellaneous Settings" +msgstr "Różne ustawienia" + +#: ../../Zotlabs/Module/Settings/Channel.php:594 +msgid "Default photo upload folder" +msgstr "Domyślny folder przesyłania zdjęć" + +#: ../../Zotlabs/Module/Settings/Channel.php:594 +#: ../../Zotlabs/Module/Settings/Channel.php:595 +msgid "%Y - current year, %m - current month" +msgstr "%Y - bieżący rok, %m - bieżący miesiąc" + +#: ../../Zotlabs/Module/Settings/Channel.php:595 +msgid "Default file upload folder" +msgstr "Domyślny folder przesyłania plików" + +#: ../../Zotlabs/Module/Settings/Channel.php:597 +msgid "Remove this channel." +msgstr "Usuń ten kanał." + +#: ../../Zotlabs/Module/Settings/Connections.php:40 +msgid "Connections Settings" +msgstr "Ustawienia połączeń" + +#: ../../Zotlabs/Module/Settings/Calendar.php:40 +msgid "Calendar Settings" +msgstr "Ustawienia kalendarza" + +#: ../../Zotlabs/Module/Settings/Directory.php:40 +msgid "Directory Settings" +msgstr "Ustawienia katalogu" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:46 +#: ../../Zotlabs/Module/Settings/Network.php:42 +msgid "Max height of content (in pixels)" +msgstr "Maksymalna wysokość pola treści (w pikselach)" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:48 +#: ../../Zotlabs/Module/Settings/Network.php:44 +msgid "Click to expand content exceeding this height" +msgstr "Kliknij, aby rozwinąć treść przekraczającą tę wysokość" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:61 +msgid "Personal menu to display in your channel pages" +msgstr "Menu osobiste do wyświetlania na stronach Twojego kanał" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:88 +msgid "Channel Home Settings" +msgstr "Ustawienia strony głównej kanału" + +#: ../../Zotlabs/Module/Settings/Network.php:59 +msgid "Stream Settings" +msgstr "Ustawienia strumienia" + +#: ../../Zotlabs/Module/Settings/Conversation.php:23 +msgid "Settings saved." +msgstr "Ustawienia zapisane." + +#: ../../Zotlabs/Module/Settings/Conversation.php:25 +msgid "Settings saved. Reload page please." +msgstr "Ustawienia zapisane. Proszę ponownie załadować stronę." + +#: ../../Zotlabs/Module/Settings/Conversation.php:47 +msgid "Conversation Settings" +msgstr "Ustawienia rozmów" + +#: ../../Zotlabs/Module/Probe.php:18 +msgid "Remote Diagnostics App" +msgstr "Aplikacja Remote Diagnostics" + +#: ../../Zotlabs/Module/Probe.php:19 +msgid "Perform diagnostics on remote channels" +msgstr "Przeprowadź diagnostykę zdalnych kanałów" + +#: ../../Zotlabs/Module/Invite.php:37 +msgid "Total invitation limit exceeded." +msgstr "Przekroczono łączny limit zaproszeń." + +#: ../../Zotlabs/Module/Invite.php:61 +#, php-format +msgid "%s : Not a valid email address." +msgstr "% s: nieprawidłowy adres e-mail." + +#: ../../Zotlabs/Module/Invite.php:75 +msgid "Please join us on $Projectname" +msgstr "Dołącz do nas na $Projectname" + +#: ../../Zotlabs/Module/Invite.php:85 +msgid "Invitation limit exceeded. Please contact your site administrator." +msgstr "" +"Przekroczono limit zaproszeń. Skontaktuj się z administratorem serwisu." + +#: ../../Zotlabs/Module/Invite.php:90 +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:40 +#, php-format +msgid "%s : Message delivery failed." +msgstr "%s: dostarczenie wiadomości nie powiodło się." + +#: ../../Zotlabs/Module/Invite.php:94 +#, php-format +msgid "%d message sent." +msgid_plural "%d messages sent." +msgstr[0] "Wysłano %d wiadomość." +msgstr[1] "Wysłano %d wiadomości." +msgstr[2] "Wysłano %d wiadomości." + +#: ../../Zotlabs/Module/Invite.php:110 +msgid "Invite App" +msgstr "Aplikacja Invite" + +#: ../../Zotlabs/Module/Invite.php:111 +msgid "Send email invitations to join this network" +msgstr "" +"Wyślij wiadomości e-mail z zaproszeniami do przyłączenia się do tej sieci" + +#: ../../Zotlabs/Module/Invite.php:124 +msgid "You have no more invitations available" +msgstr "Nie masz więcej dostępnych zaproszeń" + +#: ../../Zotlabs/Module/Invite.php:155 +msgid "Send invitations" +msgstr "Wysyłać zaproszenia" + +#: ../../Zotlabs/Module/Invite.php:156 +msgid "Enter email addresses, one per line:" +msgstr "Wprowadź adresy e-mail, po jednym w każdym wierszu:" + +#: ../../Zotlabs/Module/Invite.php:157 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:163 +msgid "Your message:" +msgstr "Twoja wiadomość:" + +#: ../../Zotlabs/Module/Invite.php:158 +msgid "Please join my community on $Projectname." +msgstr "Dołącz do mojej społeczności w $Projectname." + +#: ../../Zotlabs/Module/Invite.php:160 +msgid "You will need to supply this invitation code:" +msgstr "Trzeba będzie podać ten kod zaproszenia:" + +#: ../../Zotlabs/Module/Invite.php:161 +msgid "1. Register at any $Projectname location (they are all inter-connected)" +msgstr "" +"1. Zarejestruj się w dowolnej lokalizacji $Projectname (wszystkie są ze sobą " +"połączone)" + +#: ../../Zotlabs/Module/Invite.php:163 +msgid "2. Enter my $Projectname network address into the site searchbar." +msgstr "2. Wpisz mój adres sieciowy $Projectname w pasku wyszukiwania serwisu." + +#: ../../Zotlabs/Module/Invite.php:164 +msgid "or visit" +msgstr "lub odwiedź" + +#: ../../Zotlabs/Module/Invite.php:166 +msgid "3. Click [Connect]" +msgstr "3. Kliknij [Połącz]" + +#: ../../Zotlabs/Module/Siteinfo.php:21 +msgid "About this site" +msgstr "O tym serwisie" + +#: ../../Zotlabs/Module/Siteinfo.php:22 +msgid "Site Name" +msgstr "Nazwa witryny" + +#: ../../Zotlabs/Module/Siteinfo.php:26 +msgid "Administrator" +msgstr "Administrator" + +#: ../../Zotlabs/Module/Siteinfo.php:29 +msgid "Software and Project information" +msgstr "Informacje o oprogramowaniu i projekcie" + +#: ../../Zotlabs/Module/Siteinfo.php:30 +msgid "This site is powered by $Projectname" +msgstr "Ta witryna jest oparta na $Projectname" + +#: ../../Zotlabs/Module/Siteinfo.php:31 +msgid "" +"Federated and decentralised networking and identity services provided by Zot" +msgstr "" +"Sfederowane i zdecentralizowane usługi sieciowe i tożsamości wykorzystujące " +"protokół Zot" + +#: ../../Zotlabs/Module/Siteinfo.php:34 +msgid "Additional federated transport protocols:" +msgstr "Dodatkowe protokoły transportu federacyjnego:" + +#: ../../Zotlabs/Module/Siteinfo.php:36 +#, php-format +msgid "Version %s" +msgstr "Wersja %s" + +#: ../../Zotlabs/Module/Siteinfo.php:37 +msgid "Project homepage" +msgstr "Strona główna projektu" + +#: ../../Zotlabs/Module/Siteinfo.php:38 +msgid "Developer homepage" +msgstr "Strona główna developerów" + +#: ../../Zotlabs/Module/Service_limits.php:23 +msgid "No service class restrictions found." +msgstr "Nie znaleziono ograniczeń klasy usług." + +#: ../../Zotlabs/Module/Rbmark.php:94 +msgid "Select a bookmark folder" +msgstr "Wybierz folder zakładek" + +#: ../../Zotlabs/Module/Rbmark.php:99 +msgid "Save Bookmark" +msgstr "Zapisz zakładkę" + +#: ../../Zotlabs/Module/Rbmark.php:100 +msgid "URL of bookmark" +msgstr "URL zakładki" + +#: ../../Zotlabs/Module/Rbmark.php:105 +msgid "Or enter new bookmark folder name" +msgstr "Lub wprowadź nową nazwę folderu zakładek" + +#: ../../Zotlabs/Module/Lang.php:17 +msgid "Language App" +msgstr "Aplikacja Language" + +#: ../../Zotlabs/Module/Lang.php:18 +msgid "Change UI language" +msgstr "Zmień język interfejsu użytkownika" + +#: ../../Zotlabs/Module/Hq.php:131 +msgid "Welcome to Hubzilla!" +msgstr "Witamy w Hubzilla!" + +#: ../../Zotlabs/Module/Hq.php:131 +msgid "You have got no unseen posts..." +msgstr "Nie masz żadnych nieoglądniętych postów..." + +#: ../../Zotlabs/Module/Cover_photo.php:196 +#: ../../Zotlabs/Module/Cover_photo.php:254 +msgid "Cover Photos" +msgstr "Zdjęcia na okładkę" + +#: ../../Zotlabs/Module/Cover_photo.php:297 ../../include/items.php:4860 +msgid "female" +msgstr "kobieta" + +#: ../../Zotlabs/Module/Cover_photo.php:298 ../../include/items.php:4861 +#, php-format +msgid "%1$s updated her %2$s" +msgstr "%1$s zaktualizował ją %2$s" + +#: ../../Zotlabs/Module/Cover_photo.php:299 ../../include/items.php:4862 +msgid "male" +msgstr "mężczyzna" + +#: ../../Zotlabs/Module/Cover_photo.php:300 ../../include/items.php:4863 +#, php-format +msgid "%1$s updated his %2$s" +msgstr "%1$s zaktualizował go %2$s" + +#: ../../Zotlabs/Module/Cover_photo.php:302 ../../include/items.php:4865 +#, php-format +msgid "%1$s updated their %2$s" +msgstr "%1$s zaktualizował ich %2$s" + +#: ../../Zotlabs/Module/Cover_photo.php:304 ../../include/channel.php:2328 +msgid "cover photo" +msgstr "zdjęcie okładkowe" + +#: ../../Zotlabs/Module/Cover_photo.php:418 +msgid "Your cover photo may be visible to anybody on the internet" +msgstr "Twoje zdjęcie okładkowe może być widoczne dla każdego w internecie" + +#: ../../Zotlabs/Module/Cover_photo.php:422 +msgid "Change Cover Photo" +msgstr "Zmień zdjęcie na okładkę" + +#: ../../Zotlabs/Module/Menu.php:68 +msgid "Unable to update menu." +msgstr "Nie można zaktualizować menu." + +#: ../../Zotlabs/Module/Menu.php:79 +msgid "Unable to create menu." +msgstr "Nie można utworzyć menu." + +#: ../../Zotlabs/Module/Menu.php:161 ../../Zotlabs/Module/Menu.php:174 +msgid "Menu Name" +msgstr "Nazwa menu" + +#: ../../Zotlabs/Module/Menu.php:161 +msgid "Unique name (not visible on webpage) - required" +msgstr "Unikalna nazwa (niewidoczna na stronie) - wymagana" + +#: ../../Zotlabs/Module/Menu.php:162 ../../Zotlabs/Module/Menu.php:175 +msgid "Menu Title" +msgstr "Tytuł menu" + +#: ../../Zotlabs/Module/Menu.php:162 +msgid "Visible on webpage - leave empty for no title" +msgstr "Widoczne na stronie - pozostaw puste bez tytułu" + +#: ../../Zotlabs/Module/Menu.php:163 +msgid "Allow Bookmarks" +msgstr "Zezwalaj na zakładki" + +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +msgid "Menu may be used to store saved bookmarks" +msgstr "Menu może służyć do przechowywania zapisanych zakładek" + +#: ../../Zotlabs/Module/Menu.php:164 ../../Zotlabs/Module/Menu.php:225 +msgid "Submit and proceed" +msgstr "Prześlij i kontynuuj" + +#: ../../Zotlabs/Module/Menu.php:171 ../../include/text.php:2699 +msgid "Menus" +msgstr "Menu" + +#: ../../Zotlabs/Module/Menu.php:181 +msgid "Bookmarks allowed" +msgstr "Zakładki są dozwolone" + +#: ../../Zotlabs/Module/Menu.php:183 +msgid "Delete this menu" +msgstr "Usuń to menu" + +#: ../../Zotlabs/Module/Menu.php:184 ../../Zotlabs/Module/Menu.php:219 +msgid "Edit menu contents" +msgstr "Edytuj zawartość menu" + +#: ../../Zotlabs/Module/Menu.php:185 +msgid "Edit this menu" +msgstr "Edytuj to menu" + +#: ../../Zotlabs/Module/Menu.php:201 +msgid "Menu could not be deleted." +msgstr "Nie udało się usunąć menu." + +#: ../../Zotlabs/Module/Menu.php:214 +msgid "Edit Menu" +msgstr "Edytuj menu" + +#: ../../Zotlabs/Module/Menu.php:218 +msgid "Add or remove entries to this menu" +msgstr "Dodaj lub usuń posty w tym menu" + +#: ../../Zotlabs/Module/Menu.php:220 +msgid "Menu name" +msgstr "Nazwa menu" + +#: ../../Zotlabs/Module/Menu.php:220 +msgid "Must be unique, only seen by you" +msgstr "Musi być wyjątkowy, widoczny tylko dla Ciebie" + +#: ../../Zotlabs/Module/Menu.php:221 +msgid "Menu title" +msgstr "Tytuł menu" + +#: ../../Zotlabs/Module/Menu.php:221 +msgid "Menu title as seen by others" +msgstr "Tytuł menu widziany przez innych" + +#: ../../Zotlabs/Module/Menu.php:222 +msgid "Allow bookmarks" +msgstr "Zezwalaj na zakładki" + +#: ../../Zotlabs/Module/Sources.php:41 +msgid "Failed to create source. No channel selected." +msgstr "Nie udało się utworzyć źródła. Nie wybrano kanału." + +#: ../../Zotlabs/Module/Sources.php:57 +msgid "Source created." +msgstr "Utworzono źródło." + +#: ../../Zotlabs/Module/Sources.php:70 +msgid "Source updated." +msgstr "Źródło zaktualizowane." + +#: ../../Zotlabs/Module/Sources.php:88 +msgid "Sources App" +msgstr "Aplikacja Sources" + +#: ../../Zotlabs/Module/Sources.php:89 +msgid "Automatically import channel content from other channels or feeds" +msgstr "Automatycznie importuj zawartość kanału z innych kanałów lub źródeł" + +#: ../../Zotlabs/Module/Sources.php:101 +msgid "*" +msgstr "*" + +#: ../../Zotlabs/Module/Sources.php:107 ../../Zotlabs/Lib/Apps.php:368 +msgid "Channel Sources" +msgstr "Źródła kanałów" + +#: ../../Zotlabs/Module/Sources.php:108 +msgid "Manage remote sources of content for your channel." +msgstr "Zarządzaj zdalnymi źródłami treści na swoim kanale." + +#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:119 +msgid "New Source" +msgstr "Nowe źródło" + +#: ../../Zotlabs/Module/Sources.php:120 ../../Zotlabs/Module/Sources.php:154 +msgid "" +"Import all or selected content from the following channel into this channel " +"and distribute it according to your channel settings." +msgstr "" +"Zaimportuj wszystkie lub wybrane treści z następującego kanału do tego " +"kanału i rozpowszechniaj je zgodnie z ustawieniami kanału." + +#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 +msgid "Only import content with these words (one per line)" +msgstr "Importuj tylko zawartość z tymi słowami (po jednym w każdym wierszu)" + +#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 +msgid "Leave blank to import all public content" +msgstr "Pozostaw puste, aby zaimportować całą zawartość publiczną" + +#: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:161 +msgid "Channel Name" +msgstr "Nazwa kanału" + +#: ../../Zotlabs/Module/Sources.php:123 ../../Zotlabs/Module/Sources.php:158 +msgid "" +"Add the following categories to posts imported from this source (comma " +"separated)" +msgstr "" +"Dodaj następujące kategorie do postów zaimportowanych z tego źródła " +"(oddzielone przecinkami)" + +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +msgid "Resend posts with this channel as author" +msgstr "Wyślij ponownie posty z tym kanałem jako autorem" + +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +msgid "Copyrights may apply" +msgstr "Copyrights may apply" + +#: ../../Zotlabs/Module/Sources.php:144 ../../Zotlabs/Module/Sources.php:174 +msgid "Source not found." +msgstr "Nie znaleziono źródła." + +#: ../../Zotlabs/Module/Sources.php:151 +msgid "Edit Source" +msgstr "Edytuj źródło" + +#: ../../Zotlabs/Module/Sources.php:152 +msgid "Delete Source" +msgstr "Usuń źródło" + +#: ../../Zotlabs/Module/Sources.php:182 +msgid "Source removed" +msgstr "Źródło zostało usunięte" + +#: ../../Zotlabs/Module/Sources.php:184 +msgid "Unable to remove source." +msgstr "Nie można usunąć źródła." + +#: ../../Zotlabs/Module/Poke.php:165 +msgid "Poke App" +msgstr "Aplikacja Poke" + +#: ../../Zotlabs/Module/Poke.php:166 +msgid "Poke somebody in your addressbook" +msgstr "Szturchij kogoś w swojej książce adresowej" + +#: ../../Zotlabs/Module/Poke.php:199 ../../Zotlabs/Lib/Apps.php:351 +#: ../../include/conversation.php:1140 +msgid "Poke" +msgstr "Szturchnij" + +#: ../../Zotlabs/Module/Poke.php:200 +msgid "Poke somebody" +msgstr "Szturchnij kogoś" + +#: ../../Zotlabs/Module/Poke.php:203 +msgid "Poke/Prod" +msgstr "Szturchnij" + +#: ../../Zotlabs/Module/Poke.php:204 +msgid "Poke, prod or do other things to somebody" +msgstr "Szturchać, badać, testować lub robić z kimś podobne rzeczy" + +#: ../../Zotlabs/Module/Poke.php:211 +msgid "Recipient" +msgstr "Odbiorca" + +#: ../../Zotlabs/Module/Poke.php:212 +msgid "Choose what you wish to do to recipient" +msgstr "Wybierz, co chcesz zrobić odbiorcy" + +#: ../../Zotlabs/Module/Poke.php:215 ../../Zotlabs/Module/Poke.php:216 +msgid "Make this post private" +msgstr "Ustaw ten post jako prywatny" + +#: ../../Zotlabs/Module/Network.php:105 +msgid "No such group" +msgstr "Nie ma takiej grupy" + +#: ../../Zotlabs/Module/Network.php:152 +msgid "No such channel" +msgstr "Nie ma takiego kanału" + +#: ../../Zotlabs/Module/Network.php:239 +msgid "Privacy group is empty" +msgstr "Grupa prywatności jest pusta" + +#: ../../Zotlabs/Module/Network.php:249 +msgid "Privacy group: " +msgstr "Grupa prywatności: " + +#: ../../Zotlabs/Module/Network.php:322 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:29 +msgid "Invalid channel." +msgstr "Zły kanał." + +#: ../../Zotlabs/Module/Attach_edit.php:118 +msgid "Can not copy folder into itself." +msgstr "Nie można skopiować folderu do siebie." + +#: ../../Zotlabs/Module/Attach_edit.php:131 +#, php-format +msgid "Can not move folder \"%s\" into itself." +msgstr "Nie można przenieść folderu \"%s\" do samego siebie." + +#: ../../Zotlabs/Module/Viewsrc.php:43 +msgid "item" +msgstr "element" + +#: ../../Zotlabs/Module/Lockview.php:75 +msgid "Remote privacy information not available." +msgstr "Zdalne informacje o prywatności nie są dostępne." + +#: ../../Zotlabs/Module/Lockview.php:96 +msgid "Visible to:" +msgstr "Widoczne dla:" + +#: ../../Zotlabs/Storage/Browser.php:292 +msgid "Change filename to" +msgstr "Zmień nazwę pliku na" + +#: ../../Zotlabs/Storage/Browser.php:309 ../../Zotlabs/Storage/Browser.php:390 +msgid "Select a target location" +msgstr "Wybierz lokalizację docelową" + +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:391 +msgid "Copy to target location" +msgstr "Skopiuj do lokalizacji docelowej" + +#: ../../Zotlabs/Storage/Browser.php:311 ../../Zotlabs/Storage/Browser.php:389 +msgid "Set permissions for all files and sub folders" +msgstr "Ustaw uprawnienia dla wszystkich plików i podfolderów" + +#: ../../Zotlabs/Storage/Browser.php:312 +msgid "Notify your contacts about this file" +msgstr "Powiadom swoje kontakty o tym pliku" + +#: ../../Zotlabs/Storage/Browser.php:351 +msgid "File category" +msgstr "Kategoria plików" + +#: ../../Zotlabs/Storage/Browser.php:362 +msgid "Total" +msgstr "Ogólnie" + +#: ../../Zotlabs/Storage/Browser.php:364 +msgid "Shared" +msgstr "Udostępnione" + +#: ../../Zotlabs/Storage/Browser.php:366 +msgid "Add Files" +msgstr "Dodaj pliki" + +#: ../../Zotlabs/Storage/Browser.php:369 ../../Zotlabs/Lib/ThreadItem.php:174 +msgid "Admin Delete" +msgstr "Usuń przez administratora" + +#: ../../Zotlabs/Storage/Browser.php:381 +msgid "parent" +msgstr "rodzic" + +#: ../../Zotlabs/Storage/Browser.php:399 +msgid "Select All" +msgstr "Zaznacz wszystko" + +#: ../../Zotlabs/Storage/Browser.php:400 +msgid "Bulk Actions" +msgstr "Działania masowe" + +#: ../../Zotlabs/Storage/Browser.php:401 +msgid "Adjust Permissions" +msgstr "Dostosuj uprawnienia" + +#: ../../Zotlabs/Storage/Browser.php:402 +msgid "Move or Copy" +msgstr "Przenieś lub skopiuj" + +#: ../../Zotlabs/Storage/Browser.php:405 +msgid "Info" +msgstr "Informacje" + +#: ../../Zotlabs/Storage/Browser.php:406 +msgid "Rename" +msgstr "Zień nazwę" + +#: ../../Zotlabs/Storage/Browser.php:407 ../../Zotlabs/Lib/Apps.php:360 +msgid "Post" +msgstr "Post" + +#: ../../Zotlabs/Storage/Browser.php:408 +msgid "Attachment BBcode" +msgstr "Attachment BBcode" + +#: ../../Zotlabs/Storage/Browser.php:409 +msgid "Embed BBcode" +msgstr "Osadź BBcode" + +#: ../../Zotlabs/Storage/Browser.php:410 +msgid "Link BBcode" +msgstr "Połącz BBcode" + +#: ../../Zotlabs/Storage/Browser.php:480 +#, php-format +msgid "You are using %1$s of your available file storage." +msgstr "Używasz %1$s dostępnego miejsca na pliki." + +#: ../../Zotlabs/Storage/Browser.php:485 +#, php-format +msgid "You are using %1$s of %2$s available file storage. (%3$s%)" +msgstr "Używasz %1$s z %2$s dostępnego miejsca na pliki. (%3$s %)" + +#: ../../Zotlabs/Storage/Browser.php:496 +msgid "WARNING:" +msgstr "OSTRZEŻENIE:" + +#: ../../Zotlabs/Storage/Browser.php:537 +msgid "Create new folder" +msgstr "Stwórz nowy folder" + +#: ../../Zotlabs/Storage/Browser.php:539 +msgid "Upload file" +msgstr "Przesyłanie pliku" + +#: ../../Zotlabs/Storage/Browser.php:551 +msgid "Drop files here to immediately upload" +msgstr "Upuść pliki tutaj, aby natychmiast przesłać" + +#: ../../Zotlabs/Storage/Browser.php:554 +msgid "" +"You can select files via the upload button or drop them right here or into " +"an existing folder." +msgstr "" +"Możesz wybrać pliki za pomocą przycisku przesyłania lub upuścić je tutaj lub " +"do istniejącego folderu." + +#: ../../Zotlabs/Zot/Auth.php:152 +msgid "" +"Remote authentication blocked. You are logged into this site locally. Please " +"logout and retry." +msgstr "" +"Zdalne uwierzytelnianie zablokowane. Jesteś zalogowany lokalnie na tej " +"stronie. Wyloguj się i spróbuj ponownie." + +#: ../../Zotlabs/Zot/Auth.php:264 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:76 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:178 +#, php-format +msgid "Welcome %s. Remote authentication successful." +msgstr "Witaj %s. Zdalne uwierzytelnianie powiodło się." + +#: ../../Zotlabs/Lib/Group.php:28 ../../include/group.php:23 +msgid "" +"A deleted group with this name was revived. Existing item permissions " +"may apply to this group and any future members. If this is " +"not what you intended, please create another group with a different name." +msgstr "" +"Przywrócono usuniętą grupę o tej nazwie. Istniejące uprawnienia dotyczące " +"elementów mogą dotyczyć tej grupy i wszystkich przyszłych " +"członków. Jeśli nie tego chciałeś, utwórz kolejną grupę o innej nazwie." + +#: ../../Zotlabs/Lib/Group.php:270 ../../include/group.php:265 +msgid "Add new connections to this privacy group" +msgstr "Dodaj nowe połączenia do tej grupy prywatności" + +#: ../../Zotlabs/Lib/Group.php:302 ../../Zotlabs/Lib/AccessList.php:311 +#: ../../include/group.php:299 +msgid "edit" +msgstr "edutuj" + +#: ../../Zotlabs/Lib/Group.php:325 ../../include/group.php:322 +msgid "Edit group" +msgstr "Edytuj grupę" + +#: ../../Zotlabs/Lib/Group.php:326 ../../include/group.php:323 +msgid "Add privacy group" +msgstr "Dodaj grupę prywatności" + +#: ../../Zotlabs/Lib/Group.php:327 ../../include/group.php:324 +msgid "Channels not in any privacy group" +msgstr "Kanały spoza jakiejkolwiek grupy prywatności" + +#: ../../Zotlabs/Lib/Group.php:329 ../../Zotlabs/Lib/AccessList.php:336 +#: ../../Zotlabs/Widget/Savedsearch.php:84 ../../include/group.php:326 +msgid "add" +msgstr "dodaj" + +#: ../../Zotlabs/Lib/Connect.php:46 ../../Zotlabs/Lib/Connect.php:143 +#: ../../include/follow.php:37 +msgid "Channel is blocked on this site." +msgstr "Kanał jest zablokowany na tej stronie." + +#: ../../Zotlabs/Lib/Connect.php:51 ../../include/follow.php:42 +msgid "Channel location missing." +msgstr "Brak lokalizacji kanału." + +#: ../../Zotlabs/Lib/Connect.php:103 ../../include/follow.php:166 +msgid "Remote channel or protocol unavailable." +msgstr "Zdalny kanał lub protokół jest niedostępny." + +#: ../../Zotlabs/Lib/Connect.php:137 ../../include/follow.php:190 +msgid "Channel discovery failed." +msgstr "Wyszukanie kanału nie powiodło się." + +#: ../../Zotlabs/Lib/Connect.php:155 ../../include/follow.php:202 +msgid "Protocol disabled." +msgstr "Protokół wyłączony." + +#: ../../Zotlabs/Lib/Connect.php:167 ../../include/follow.php:213 +msgid "Cannot connect to yourself." +msgstr "Nie można połączyć się ze sobą." + +#: ../../Zotlabs/Lib/Connect.php:271 +msgid "error saving data" +msgstr "błąd podczas zapisywania danych" + +#: ../../Zotlabs/Lib/Apps.php:323 +msgid "Apps" +msgstr "Aplikacje" + +#: ../../Zotlabs/Lib/Apps.php:324 +msgid "Affinity Tool" +msgstr "Narzędzie koligacji" + +#: ../../Zotlabs/Lib/Apps.php:327 +msgid "Site Admin" +msgstr "Administrator serwisu" + +#: ../../Zotlabs/Lib/Apps.php:328 +#: ../../extend/addon/hzaddons/buglink/buglink.php:16 +msgid "Report Bug" +msgstr "Raport błędów" + +#: ../../Zotlabs/Lib/Apps.php:329 ../../include/nav.php:490 +msgid "Bookmarks" +msgstr "Zakładki" + +#: ../../Zotlabs/Lib/Apps.php:330 ../../Zotlabs/Widget/Chatroom_list.php:16 +#: ../../include/nav.php:477 ../../include/nav.php:480 +msgid "Chatrooms" +msgstr "Czaty" + +#: ../../Zotlabs/Lib/Apps.php:331 +msgid "Content Filter" +msgstr "Filtr treści" + +#: ../../Zotlabs/Lib/Apps.php:332 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:135 +msgid "Content Import" +msgstr "Import treści" + +#: ../../Zotlabs/Lib/Apps.php:334 +msgid "Remote Diagnostics" +msgstr "Zdalna diagnostyka" + +#: ../../Zotlabs/Lib/Apps.php:335 +msgid "Suggest Channels" +msgstr "Zaproponuj kanały" + +#: ../../Zotlabs/Lib/Apps.php:336 ../../include/nav.php:124 +#: ../../include/nav.php:128 ../../boot.php:1705 +msgid "Login" +msgstr "Zaloguj się" + +#: ../../Zotlabs/Lib/Apps.php:338 +msgid "Stream" +msgstr "Strumień" + +#: ../../Zotlabs/Lib/Apps.php:342 ../../include/nav.php:539 +msgid "Wiki" +msgstr "Wiki" + +#: ../../Zotlabs/Lib/Apps.php:343 ../../include/features.php:104 +msgid "Channel Home" +msgstr "Strona główna kanału" + +#: ../../Zotlabs/Lib/Apps.php:346 ../../include/features.php:82 +#: ../../include/nav.php:463 ../../include/nav.php:466 +msgid "Calendar" +msgstr "Kalendarz" + +#: ../../Zotlabs/Lib/Apps.php:347 ../../include/features.php:192 +msgid "Directory" +msgstr "Katalog" + +#: ../../Zotlabs/Lib/Apps.php:349 +msgid "Mail" +msgstr "Poczta" + +#: ../../Zotlabs/Lib/Apps.php:352 +msgid "Chat" +msgstr "Czat" + +#: ../../Zotlabs/Lib/Apps.php:354 +msgid "Probe" +msgstr "Sonda" + +#: ../../Zotlabs/Lib/Apps.php:355 +msgid "Suggest" +msgstr "Prpozycja" + +#: ../../Zotlabs/Lib/Apps.php:356 +msgid "Random Channel" +msgstr "Losowy kanał" + +#: ../../Zotlabs/Lib/Apps.php:357 +msgid "Invite" +msgstr "Zaproszenie" + +#: ../../Zotlabs/Lib/Apps.php:358 ../../Zotlabs/Widget/Admin.php:26 +msgid "Features" +msgstr "Funkcje" + +#: ../../Zotlabs/Lib/Apps.php:359 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:69 +msgid "Language" +msgstr "Język" + +#: ../../Zotlabs/Lib/Apps.php:361 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:58 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:59 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:60 +msgid "Profile Photo" +msgstr "Zdjęcie profilowe" + +#: ../../Zotlabs/Lib/Apps.php:363 ../../include/features.php:383 +msgid "Profiles" +msgstr "Profile" + +#: ../../Zotlabs/Lib/Apps.php:365 +msgid "Notifications" +msgstr "Powiadomienie" + +#: ../../Zotlabs/Lib/Apps.php:366 +msgid "Order Apps" +msgstr "Kolejność aplikacji" + +#: ../../Zotlabs/Lib/Apps.php:367 +msgid "CardDAV" +msgstr "CardDAV" + +#: ../../Zotlabs/Lib/Apps.php:369 +msgid "Guest Access" +msgstr "Dostęp gościa" + +#: ../../Zotlabs/Lib/Apps.php:370 ../../Zotlabs/Widget/Notes.php:21 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2625 +msgid "Notes" +msgstr "Uwagi" + +#: ../../Zotlabs/Lib/Apps.php:371 +msgid "OAuth Apps Manager" +msgstr "Menadżer aplikacji OAuth" + +#: ../../Zotlabs/Lib/Apps.php:372 +msgid "OAuth2 Apps Manager" +msgstr "Menadżer aplikacji OAuth2" + +#: ../../Zotlabs/Lib/Apps.php:373 +msgid "PDL Editor" +msgstr "Edytor PDL" + +#: ../../Zotlabs/Lib/Apps.php:376 +msgid "My Chatrooms" +msgstr "Moje czaty" + +#: ../../Zotlabs/Lib/Apps.php:377 +msgid "Channel Export" +msgstr "Eksport kanału" + +#: ../../Zotlabs/Lib/Apps.php:554 +msgid "Purchase" +msgstr "Zakup" + +#: ../../Zotlabs/Lib/Apps.php:559 +msgid "Undelete" +msgstr "Cofnij usunięcie" + +#: ../../Zotlabs/Lib/Apps.php:569 +msgid "Add to app-tray" +msgstr "Dodaj do zasobnika aplikacji" + +#: ../../Zotlabs/Lib/Apps.php:570 +msgid "Remove from app-tray" +msgstr "Usuń z zasobnika aplikacji" + +#: ../../Zotlabs/Lib/Apps.php:571 +msgid "Pin to navbar" +msgstr "Przypnij do paska nawigacyjnego" + +#: ../../Zotlabs/Lib/Apps.php:572 +msgid "Unpin from navbar" +msgstr "Odepnij od paska nawigacyjnego" + +#: ../../Zotlabs/Lib/DB_Upgrade.php:67 +msgid "Source code of failed update: " +msgstr "Kod źródłowy nieudanej aktualizacji: " + +#: ../../Zotlabs/Lib/DB_Upgrade.php:88 +#, php-format +msgid "Update Error at %s" +msgstr "Błąd aktualizacji na %s" + +#: ../../Zotlabs/Lib/DB_Upgrade.php:94 +#, php-format +msgid "Update %s failed. See error logs." +msgstr "Aktualizacja %s nie powiodła się. Zobacz dzienniki błędów." + +#: ../../Zotlabs/Lib/AccessList.php:28 +msgid "" +"A deleted list with this name was revived. Existing item permissions " +"may apply to this list and any future members. If this is " +"not what you intended, please create another list with a different name." +msgstr "" +"Przywrócono usuniętą listę o tej nazwie. Istniejące uprawnienia dotyczące " +"elementów mogą dotyczyć tej listy i wszystkich przyszłych " +"członków. Jeśli nie tego chciałeś, utwórz kolejną listę z inną nazwą." + +#: ../../Zotlabs/Lib/AccessList.php:286 +msgid "Add new connections to this access list" +msgstr "Dodaj nowe połączenia do tej listy dostępu" + +#: ../../Zotlabs/Lib/AccessList.php:331 +msgid "Lists" +msgstr "Listy" + +#: ../../Zotlabs/Lib/AccessList.php:332 +msgid "Edit list" +msgstr "Edytuj listę" + +#: ../../Zotlabs/Lib/AccessList.php:333 +msgid "Create new list" +msgstr "Utwórz nową listę" + +#: ../../Zotlabs/Lib/AccessList.php:334 +msgid "Channels not in any access list" +msgstr "Kanały, których nie ma na żadnej liście dostępu" + +#: ../../Zotlabs/Lib/Chatroom.php:25 +msgid "Missing room name" +msgstr "Brak nazwy pokoju" + +#: ../../Zotlabs/Lib/Chatroom.php:34 +msgid "Duplicate room name" +msgstr "Zduplikowana nazwa pokoju" + +#: ../../Zotlabs/Lib/Chatroom.php:84 ../../Zotlabs/Lib/Chatroom.php:92 +msgid "Invalid room specifier." +msgstr "Nieprawidłowy specyfikator sali." + +#: ../../Zotlabs/Lib/Chatroom.php:124 +msgid "Room not found." +msgstr "Nie znaleziono pokoju." + +#: ../../Zotlabs/Lib/Chatroom.php:145 +msgid "Room is full" +msgstr "Pokój jest pełny" + +#: ../../Zotlabs/Lib/Techlevels.php:10 +msgid "0. Beginner/Basic" +msgstr "0. Poczatkujący/Podstawowy" + +#: ../../Zotlabs/Lib/Techlevels.php:11 +msgid "1. Novice - not skilled but willing to learn" +msgstr "1. Nowicjusz - nie ma umiejętności, ale chętnie się uczy" + +#: ../../Zotlabs/Lib/Techlevels.php:12 +msgid "2. Intermediate - somewhat comfortable" +msgstr "2. Średniozaawansowany - dość wygodne" + +#: ../../Zotlabs/Lib/Techlevels.php:13 +msgid "3. Advanced - very comfortable" +msgstr "3. Zaawansowany - bardzo wygodne" + +#: ../../Zotlabs/Lib/Techlevels.php:14 +msgid "4. Expert - I can write computer code" +msgstr "4. Ekspert - umiem pisać kod komputerowy" + +#: ../../Zotlabs/Lib/Techlevels.php:15 +msgid "5. Wizard - I probably know more than you do" +msgstr "5. Czarodziej - prawdopodobnie wiem więcej niż Ty" + +#: ../../Zotlabs/Lib/Enotify.php:60 +msgid "$Projectname Notification" +msgstr "Powiadomienie $Projectname" + +#: ../../Zotlabs/Lib/Enotify.php:61 +#: ../../extend/addon/hzaddons/diaspora/util.php:336 +#: ../../extend/addon/hzaddons/diaspora/util.php:349 +#: ../../extend/addon/hzaddons/diaspora/p.php:48 +msgid "$projectname" +msgstr "Hubzilla" + +#: ../../Zotlabs/Lib/Enotify.php:63 +msgid "Thank You," +msgstr "Dziękujemy," + +#: ../../Zotlabs/Lib/Enotify.php:65 +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:33 +#, php-format +msgid "%s Administrator" +msgstr "Administrator %s" + +#: ../../Zotlabs/Lib/Enotify.php:66 +#, php-format +msgid "This email was sent by %1$s at %2$s." +msgstr "Ta wiadomość e-mail została wysłana przez %1$s na numer %2$s." + +#: ../../Zotlabs/Lib/Enotify.php:67 +#, php-format +msgid "" +"To stop receiving these messages, please adjust your Notification Settings " +"at %s" +msgstr "Aby nie otrzymywać tych wiadomości, zmień ustawienia powiadomień na %s" + +#: ../../Zotlabs/Lib/Enotify.php:68 +#, php-format +msgid "To stop receiving these messages, please adjust your %s." +msgstr "Aby nie otrzymywać tych wiadomości, zmień %s." + +#: ../../Zotlabs/Lib/Enotify.php:123 +#, php-format +msgid "%s " +msgstr "%s " + +#: ../../Zotlabs/Lib/Enotify.php:127 +#, php-format +msgid "[$Projectname:Notify] New mail received at %s" +msgstr "[$Projectname:Notify] Otrzymano nową pocztę na %s" + +#: ../../Zotlabs/Lib/Enotify.php:129 +#, php-format +msgid "%1$s sent you a new private message at %2$s." +msgstr "%1$s wysłał Ci nową prywatną wiadomość na %2$s." + +#: ../../Zotlabs/Lib/Enotify.php:130 +#, php-format +msgid "%1$s sent you %2$s." +msgstr "%1$s wysłał Ci %2$s." + +#: ../../Zotlabs/Lib/Enotify.php:130 +msgid "a private message" +msgstr "prywatna wiadomość" + +#: ../../Zotlabs/Lib/Enotify.php:131 +#, php-format +msgid "Please visit %s to view and/or reply to your private messages." +msgstr "" +"Odwiedź %s, aby wyświetlić albo odpowiedzieć na swoje prywatne wiadomości." + +#: ../../Zotlabs/Lib/Enotify.php:144 +msgid "commented on" +msgstr "skomentował" + +#: ../../Zotlabs/Lib/Enotify.php:157 +msgid "liked" +msgstr "polubił" + +#: ../../Zotlabs/Lib/Enotify.php:160 +msgid "disliked" +msgstr "dezaprobował" + +#: ../../Zotlabs/Lib/Enotify.php:165 +msgid "voted on" +msgstr "głosował" + +#: ../../Zotlabs/Lib/Enotify.php:208 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]a %4$s[/zrl]" +msgstr "%1$s %2$s [zrl=%3$s]%4$s[/zrl]" + +#: ../../Zotlabs/Lib/Enotify.php:216 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]%4$s's %5$s[/zrl]" +msgstr "%1$s %2$s [zrl=%3$s]%5$s %4$s[/zrl]" + +#: ../../Zotlabs/Lib/Enotify.php:225 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]your %4$s[/zrl]" +msgstr "%1$s %2$s [zrl=%3$s]Twój %4$s[/zrl]" + +#: ../../Zotlabs/Lib/Enotify.php:237 +#, php-format +msgid "[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s" +msgstr "[$Projectname:Notify] Moderowany komentarz do rozmowy #%1$d przez %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:239 +#, php-format +msgid "[$Projectname:Notify] Comment to conversation #%1$d by %2$s" +msgstr "[$Projectname:Notify] Komentarz do roz,owy #%1$d przez %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:240 +#, php-format +msgid "%1$s commented on an item/conversation you have been following." +msgstr "%1$s skomentował obserwowany element/rozmowę." + +#: ../../Zotlabs/Lib/Enotify.php:243 ../../Zotlabs/Lib/Enotify.php:324 +#: ../../Zotlabs/Lib/Enotify.php:340 ../../Zotlabs/Lib/Enotify.php:365 +#: ../../Zotlabs/Lib/Enotify.php:382 ../../Zotlabs/Lib/Enotify.php:395 +#, php-format +msgid "Please visit %s to view and/or reply to the conversation." +msgstr "Odwiedź %s, aby wyświetlić rozmowę albo odpowiedzieć na nią." + +#: ../../Zotlabs/Lib/Enotify.php:247 ../../Zotlabs/Lib/Enotify.php:248 +#, php-format +msgid "Please visit %s to approve or reject this comment." +msgstr "Odwiedź %s, aby zaakceptować lub odrzucić ten komentarz." + +#: ../../Zotlabs/Lib/Enotify.php:306 +#, php-format +msgid "%1$s liked [zrl=%2$s]your %3$s[/zrl]" +msgstr "%1$s polubił [zrl=%2$s]Twój %3$s[/zrl]" + +#: ../../Zotlabs/Lib/Enotify.php:320 +#, php-format +msgid "[$Projectname:Notify] Like received to conversation #%1$d by %2$s" +msgstr "[$Projectname:Notify] Polubienie wysłane dla rozmowy #%1$d przez %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:321 +#, php-format +msgid "%1$s liked an item/conversation you created." +msgstr "%1$s polubił utworzony przez Ciebie element/rozmowę." + +#: ../../Zotlabs/Lib/Enotify.php:332 +#, php-format +msgid "[$Projectname:Notify] %s posted to your profile wall" +msgstr "[$Projectname:Notify]%s opublikowany na Twojej ścianie profilu" + +#: ../../Zotlabs/Lib/Enotify.php:334 +#, php-format +msgid "%1$s posted to your profile wall at %2$s" +msgstr "%1$s opublikowano na ścianie Twojego profilu pod adresem %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:336 +#, php-format +msgid "%1$s posted to [zrl=%2$s]your wall[/zrl]" +msgstr "%1$s opublikował na [zrl=%2$s]Twojej ścianie[/zrl]" + +#: ../../Zotlabs/Lib/Enotify.php:359 +#, php-format +msgid "[$Projectname:Notify] %s tagged you" +msgstr "[$Projectname:Notify]%s oznaczył Cię tagiem" + +#: ../../Zotlabs/Lib/Enotify.php:360 +#, php-format +msgid "%1$s tagged you at %2$s" +msgstr "%1$s oznaczył Cię tagiem %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:361 +#, php-format +msgid "%1$s [zrl=%2$s]tagged you[/zrl]." +msgstr "%1$s [zrl=%2$s]oznaczył Cię tagiem[/zrl]." + +#: ../../Zotlabs/Lib/Enotify.php:372 +#, php-format +msgid "[$Projectname:Notify] %1$s poked you" +msgstr "[$Projectname:Notify] %1$s szturchnął Cię" + +#: ../../Zotlabs/Lib/Enotify.php:373 +#, php-format +msgid "%1$s poked you at %2$s" +msgstr "%1$s szturchnął Cię %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:374 +#, php-format +msgid "%1$s [zrl=%2$s]poked you[/zrl]." +msgstr "%1$s [zrl=%2$s]szturchnął Cię[/zrl]." + +#: ../../Zotlabs/Lib/Enotify.php:389 +#, php-format +msgid "[$Projectname:Notify] %s tagged your post" +msgstr "[$Projectname:Notify] %s oznaczył tagiem Twój post" + +#: ../../Zotlabs/Lib/Enotify.php:390 +#, php-format +msgid "%1$s tagged your post at %2$s" +msgstr "%1$s oznaczył tagiem Twój post na %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:391 +#, php-format +msgid "%1$s tagged [zrl=%2$s]your post[/zrl]" +msgstr "%1$s tagged [zrl=%2$s]Twój post[/zrl]" + +#: ../../Zotlabs/Lib/Enotify.php:402 +msgid "[$Projectname:Notify] Introduction received" +msgstr "[$Projectname:Notify] Otrzymano wprowadzenie" + +#: ../../Zotlabs/Lib/Enotify.php:403 +#, php-format +msgid "You've received an new connection request from '%1$s' at %2$s" +msgstr "Otrzymałeś nowe żądanie połączenia od „%1$s” na %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:404 +#, php-format +msgid "You've received [zrl=%1$s]a new connection request[/zrl] from %2$s." +msgstr "Otrzymałeś [zrl=%1$s]nowe żądanie połączenia [/zrl] od %2$s." + +#: ../../Zotlabs/Lib/Enotify.php:407 ../../Zotlabs/Lib/Enotify.php:425 +#, php-format +msgid "You may visit their profile at %s" +msgstr "Możesz odwiedzić ich profil na %s" + +#: ../../Zotlabs/Lib/Enotify.php:409 +#, php-format +msgid "Please visit %s to approve or reject the connection request." +msgstr "Odwiedź %s, aby zatwierdzić lub odrzucić prośbę o połączenie." + +#: ../../Zotlabs/Lib/Enotify.php:416 +msgid "[$Projectname:Notify] Friend suggestion received" +msgstr "[$Projectname:Notify] Otrzymano propozycję znajomości" + +#: ../../Zotlabs/Lib/Enotify.php:417 +#, php-format +msgid "You've received a friend suggestion from '%1$s' at %2$s" +msgstr "Otrzymałeś propozycję znajomości od „%1$s” na %2$s" + +#: ../../Zotlabs/Lib/Enotify.php:418 +#, php-format +msgid "You've received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s." +msgstr "Otrzymałeś [zrl=%1$s] prpozycję znajomości[/ zrl] dla %2$s od %3$s." + +#: ../../Zotlabs/Lib/Enotify.php:423 +msgid "Name:" +msgstr "Nazwa:" + +#: ../../Zotlabs/Lib/Enotify.php:424 +msgid "Photo:" +msgstr "Zdjęcie:" + +#: ../../Zotlabs/Lib/Enotify.php:427 +#, php-format +msgid "Please visit %s to approve or reject the suggestion." +msgstr "Odwiedź %s, aby zaakceptować lub odrzucić popozycję." + +#: ../../Zotlabs/Lib/Enotify.php:652 +msgid "[$Projectname:Notify]" +msgstr "[$Projectname:Notify]" + +#: ../../Zotlabs/Lib/Enotify.php:820 +msgid "created a new poll" +msgstr "utworzył nową ankietę" + +#: ../../Zotlabs/Lib/Enotify.php:820 +msgid "created a new post" +msgstr "utworzył nowy post" + +#: ../../Zotlabs/Lib/Enotify.php:821 +#, php-format +msgid "voted on %s's poll" +msgstr "głosował w ankiecie %s" + +#: ../../Zotlabs/Lib/Enotify.php:821 +#, php-format +msgid "commented on %s's post" +msgstr "skomentował post %s" + +#: ../../Zotlabs/Lib/Enotify.php:825 +#, php-format +msgid "repeated %s's post" +msgstr "powtórzony post %s" + +#: ../../Zotlabs/Lib/Enotify.php:837 +#, php-format +msgid "edited a post dated %s" +msgstr "edytował post z dnia %s" + +#: ../../Zotlabs/Lib/Enotify.php:841 +#, php-format +msgid "edited a comment dated %s" +msgstr "edytował komentarz z dnia %s" + +#: ../../Zotlabs/Lib/Enotify.php:970 +msgid "created an event" +msgstr "utworzono wydarzenie" + +#: ../../Zotlabs/Lib/Libsync.php:740 ../../include/zot.php:2657 +#, php-format +msgid "Unable to verify site signature for %s" +msgstr "Nie można zweryfikować podpisu witryny dla %s" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:42 +#: ../../Zotlabs/Lib/NativeWikiPage.php:94 +msgid "(No Title)" +msgstr "(Brak tytułu)" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:109 +msgid "Wiki page create failed." +msgstr "Tworzenie strony Wiki nie powiodło się." + +#: ../../Zotlabs/Lib/NativeWikiPage.php:122 +msgid "Wiki not found." +msgstr "Nie znaleziono wiki." + +#: ../../Zotlabs/Lib/NativeWikiPage.php:133 +msgid "Destination name already exists" +msgstr "Nazwa celu już istnieje" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:166 +#: ../../Zotlabs/Lib/NativeWikiPage.php:362 +msgid "Page not found" +msgstr "Strona nie znaleziona" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:197 +msgid "Error reading page content" +msgstr "Błąd podczas odczytu zawartości strony" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:353 +#: ../../Zotlabs/Lib/NativeWikiPage.php:402 +#: ../../Zotlabs/Lib/NativeWikiPage.php:469 +#: ../../Zotlabs/Lib/NativeWikiPage.php:510 +msgid "Error reading wiki" +msgstr "Błąd podczas odczytu wiki" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:390 +msgid "Page update failed." +msgstr "Aktualizacja strony nie powiodła się." + +#: ../../Zotlabs/Lib/NativeWikiPage.php:424 +msgid "Nothing deleted" +msgstr "Nic nie zostało usunięte" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:490 +msgid "Compare: object not found." +msgstr "Porównaj: nie znaleziono obiektu." + +#: ../../Zotlabs/Lib/NativeWikiPage.php:496 +msgid "Page updated" +msgstr "Strona została zaktualizowana" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:499 +msgid "Untitled" +msgstr "Bez tytułu" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:505 +msgid "Wiki resource_id required for git commit" +msgstr "Identyfikator zasobu Wiki wymagany do zatwierdzenia przez Git" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:565 +#: ../../Zotlabs/Widget/Wiki_page_history.php:23 +msgctxt "wiki_history" +msgid "Message" +msgstr "Wiadomość" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:566 +#: ../../Zotlabs/Widget/Wiki_page_history.php:24 +msgid "Date" +msgstr "Data" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:568 +#: ../../Zotlabs/Widget/Wiki_page_history.php:26 +msgid "Compare" +msgstr "Porównaj" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:606 ../../include/bbcode.php:1018 +#: ../../include/bbcode.php:1190 +msgid "Different viewers will see this text differently" +msgstr "Różni widzowie będą inaczej widzieć ten tekst" + +#: ../../Zotlabs/Lib/ThreadItem.php:103 ../../include/conversation.php:739 +msgid "Private Message" +msgstr "Wiadomość prywatna" + +#: ../../Zotlabs/Lib/ThreadItem.php:130 +msgid "Privacy conflict. Discretion advised." +msgstr "Konflikt prywatności. Zalecana dyskrecja." + +#: ../../Zotlabs/Lib/ThreadItem.php:180 ../../include/conversation.php:729 +msgid "Select" +msgstr "Wybierz" + +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I will attend" +msgstr "Będę uczestniczył" + +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I will not attend" +msgstr "Nie będę uczestniczył" + +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I might attend" +msgstr "Mogę wziąć udział" + +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I agree" +msgstr "Zgadzam się" + +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I disagree" +msgstr "Nie zgadzam się" + +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I abstain" +msgstr "Wstrzymuję się" + +# Sprawdzić w kontekscie! +#: ../../Zotlabs/Lib/ThreadItem.php:273 ../../include/conversation.php:734 +msgid "Toggle Star Status" +msgstr "Przełącz stan gwiazdki" + +#: ../../Zotlabs/Lib/ThreadItem.php:284 ../../Zotlabs/Widget/Pinned.php:88 +#: ../../include/conversation.php:746 +msgid "Message signature validated" +msgstr "Podpis wiadomości został zatwierdzony" + +#: ../../Zotlabs/Lib/ThreadItem.php:285 ../../Zotlabs/Widget/Pinned.php:89 +#: ../../include/conversation.php:747 +msgid "Message signature incorrect" +msgstr "Niepoprawny podpis wiadomości" + +#: ../../Zotlabs/Lib/ThreadItem.php:301 ../../include/conversation.php:933 +msgid "Conversation Tools" +msgstr "Narzędzia do konwersacji" + +#: ../../Zotlabs/Lib/ThreadItem.php:317 ../../include/taxonomy.php:582 +msgid "like" +msgstr "lubi" + +#: ../../Zotlabs/Lib/ThreadItem.php:318 ../../include/taxonomy.php:583 +msgid "dislike" +msgstr "nie lubi" + +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "Reply on this comment" +msgstr "Odpowiedz na ten komentarz" + +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "reply" +msgstr "odpowiedz" + +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "Reply to" +msgstr "Odpowiedź dla" + +#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Widget/Pinned.php:99 +msgid "Share This" +msgstr "Udostępnij to" + +#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Widget/Pinned.php:99 +msgid "share" +msgstr "udostępnij" + +#: ../../Zotlabs/Lib/ThreadItem.php:339 +msgid "Delivery Report" +msgstr "Raport dostawy" + +#: ../../Zotlabs/Lib/ThreadItem.php:358 +#, php-format +msgid "%d comment" +msgid_plural "%d comments" +msgstr[0] "%d komentarz" +msgstr[1] "%d komentarze" +msgstr[2] "%d komentarzy" + +#: ../../Zotlabs/Lib/ThreadItem.php:359 +#, php-format +msgid "%d unseen" +msgstr "%d niezobaczone" + +#: ../../Zotlabs/Lib/ThreadItem.php:412 +msgid "to" +msgstr "do" + +#: ../../Zotlabs/Lib/ThreadItem.php:413 ../../Zotlabs/Widget/Pinned.php:128 +msgid "via" +msgstr "poprzez" + +#: ../../Zotlabs/Lib/ThreadItem.php:414 +msgid "Wall-to-Wall" +msgstr "Wall-to-Wall" + +#: ../../Zotlabs/Lib/ThreadItem.php:415 +msgid "via Wall-To-Wall:" +msgstr "poprzez Wall-To-Wall:" + +#: ../../Zotlabs/Lib/ThreadItem.php:429 ../../Zotlabs/Widget/Pinned.php:133 +#: ../../include/conversation.php:806 +#, php-format +msgid "from %s" +msgstr "od %s" + +#: ../../Zotlabs/Lib/ThreadItem.php:432 ../../Zotlabs/Widget/Pinned.php:136 +#: ../../include/conversation.php:809 +#, php-format +msgid "last edited: %s" +msgstr "ostatnio edytowane: %s" + +#: ../../Zotlabs/Lib/ThreadItem.php:433 ../../Zotlabs/Widget/Pinned.php:137 +#: ../../include/conversation.php:810 +#, php-format +msgid "Expires: %s" +msgstr "Wygasa: %s" + +#: ../../Zotlabs/Lib/ThreadItem.php:442 +msgid "Attend" +msgstr "Uczestnicz" + +#: ../../Zotlabs/Lib/ThreadItem.php:443 ../../Zotlabs/Widget/Pinned.php:143 +msgid "Attendance Options" +msgstr "Opcje obecności" + +#: ../../Zotlabs/Lib/ThreadItem.php:444 ../../include/text.php:1922 +msgid "Vote" +msgstr "Głosuj" + +#: ../../Zotlabs/Lib/ThreadItem.php:445 ../../Zotlabs/Widget/Pinned.php:144 +msgid "Voting Options" +msgstr "Opcje głosowania" + +#: ../../Zotlabs/Lib/ThreadItem.php:460 +msgid "Go to previous comment" +msgstr "Przejdź do poprzedniego komentarza" + +#: ../../Zotlabs/Lib/ThreadItem.php:469 ../../Zotlabs/Widget/Pinned.php:156 +msgid "Pinned post" +msgstr "Posty przypięte" + +#: ../../Zotlabs/Lib/ThreadItem.php:471 ../../Zotlabs/Widget/Pinned.php:157 +#: ../../include/js_strings.php:39 +msgid "Unpin from the top" +msgstr "Odepnij z góry" + +#: ../../Zotlabs/Lib/ThreadItem.php:471 ../../include/js_strings.php:38 +msgid "Pin to the top" +msgstr "Przypnij u góry" + +#: ../../Zotlabs/Lib/ThreadItem.php:472 +#: ../../extend/addon/hzaddons/bookmarker/bookmarker.php:38 +msgid "Save Bookmarks" +msgstr "Zapisz zakładki" + +#: ../../Zotlabs/Lib/ThreadItem.php:473 +msgid "Add to Calendar" +msgstr "Dodaj do kalendarza" + +#: ../../Zotlabs/Lib/ThreadItem.php:500 ../../include/conversation.php:516 +msgid "This is an unsaved preview" +msgstr "Ten podgląd nie został zapisany" + +#: ../../Zotlabs/Lib/ThreadItem.php:533 ../../include/js_strings.php:7 +#, php-format +msgid "%s show all" +msgstr "%s pokaż wszystko" + +#: ../../Zotlabs/Lib/ThreadItem.php:826 ../../include/conversation.php:1449 +#: ../../extend/addon/hzaddons/hsse/hsse.php:200 +msgid "Bold" +msgstr "Gruby" + +#: ../../Zotlabs/Lib/ThreadItem.php:827 ../../include/conversation.php:1450 +#: ../../extend/addon/hzaddons/hsse/hsse.php:201 +msgid "Italic" +msgstr "Pochyły" + +#: ../../Zotlabs/Lib/ThreadItem.php:828 ../../include/conversation.php:1451 +#: ../../extend/addon/hzaddons/hsse/hsse.php:202 +msgid "Underline" +msgstr "Podkreślony" + +#: ../../Zotlabs/Lib/ThreadItem.php:829 ../../include/conversation.php:1452 +#: ../../extend/addon/hzaddons/hsse/hsse.php:203 +msgid "Quote" +msgstr "Cytat" + +#: ../../Zotlabs/Lib/ThreadItem.php:830 ../../include/conversation.php:1453 +#: ../../extend/addon/hzaddons/hsse/hsse.php:204 +msgid "Code" +msgstr "Kod" + +#: ../../Zotlabs/Lib/ThreadItem.php:831 +msgid "Image" +msgstr "Obraz" + +#: ../../Zotlabs/Lib/ThreadItem.php:832 ../../include/conversation.php:1454 +#: ../../extend/addon/hzaddons/hsse/hsse.php:205 +msgid "Attach/Upload file" +msgstr "Załącz / prześlij plik" + +#: ../../Zotlabs/Lib/ThreadItem.php:833 +msgid "Insert Link" +msgstr "Wstaw link" + +#: ../../Zotlabs/Lib/ThreadItem.php:834 +msgid "Video" +msgstr "Wideo" + +#: ../../Zotlabs/Lib/ThreadItem.php:844 +msgid "Your full name (required)" +msgstr "Twoja imię i nazwisko lub pełna nazwa (wymagane)" + +#: ../../Zotlabs/Lib/ThreadItem.php:845 +msgid "Your email address (required)" +msgstr "Twój adres email (wymagane)" + +#: ../../Zotlabs/Lib/ThreadItem.php:846 +msgid "Your website URL (optional)" +msgstr "Adres URL Twojej witryny (opcjonalnie)" + +#: ../../Zotlabs/Lib/Activity.php:2110 +#, php-format +msgid "Likes %1$s's %2$s" +msgstr "Polibień %2$s %1$s" + +#: ../../Zotlabs/Lib/Activity.php:2113 +#, php-format +msgid "Doesn't like %1$s's %2$s" +msgstr "Dezaprobat %2$s %1$s" + +#: ../../Zotlabs/Lib/Activity.php:2119 +#, php-format +msgid "Will attend %s's event" +msgstr "Weźmie udział w wydarzeniu %s" + +#: ../../Zotlabs/Lib/Activity.php:2122 +#, php-format +msgid "Will not attend %s's event" +msgstr "Nie weźmie udziału w wydarzeniu %s" + +#: ../../Zotlabs/Lib/Activity.php:2125 +#, php-format +msgid "May attend %s's event" +msgstr "Może uczestniczyć w wydarzeniu %s" + +#: ../../Zotlabs/Lib/Activity.php:2128 +#, php-format +msgid "May not attend %s's event" +msgstr "Nie może uczestniczyć w wydarzeniu %s" + +#: ../../Zotlabs/Lib/Activity.php:2821 ../../Zotlabs/Lib/Activity.php:3015 +#: ../../include/network.php:1736 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1479 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1733 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1941 +msgid "ActivityPub" +msgstr "ActivityPub" + +#: ../../Zotlabs/Lib/NativeWiki.php:145 +msgid "Wiki updated successfully" +msgstr "Wiki zaktualizowane pomyślnie" + +#: ../../Zotlabs/Lib/NativeWiki.php:199 +msgid "Wiki files deleted successfully" +msgstr "Pliki Wiki zostały pomyślnie usunięte" + +#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../include/dir_fns.php:141 +msgid "Directory Options" +msgstr "Opcje katalogu" + +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../include/dir_fns.php:143 +msgid "Safe Mode" +msgstr "Tryb bezpieczny" + +#: ../../Zotlabs/Lib/Libzotdir.php:166 ../../include/dir_fns.php:144 +msgid "Public Forums Only" +msgstr "Tylko fora publiczne" + +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/dir_fns.php:145 +msgid "This Website Only" +msgstr "Tylko ten serwis" + +#: ../../Zotlabs/Lib/Permcat.php:82 +msgctxt "permcat" +msgid "default" +msgstr "domyślnie" + +#: ../../Zotlabs/Lib/Permcat.php:133 +msgctxt "permcat" +msgid "follower" +msgstr "obserwujący" + +#: ../../Zotlabs/Lib/Permcat.php:137 +msgctxt "permcat" +msgid "contributor" +msgstr "współpracownik" + +#: ../../Zotlabs/Lib/Permcat.php:141 +msgctxt "permcat" +msgid "publisher" +msgstr "wydawca" + +#: ../../Zotlabs/Lib/Libzot.php:656 ../../include/zot.php:802 +msgid "Unable to verify channel signature" +msgstr "Nie można zweryfikować podpisu kanału" + +#: ../../Zotlabs/Lib/PermissionDescription.php:34 +#: ../../include/acl_selectors.php:33 +msgid "Visible to your default audience" +msgstr "Widoczne dla domyślnych odbiorców" + +#: ../../Zotlabs/Lib/PermissionDescription.php:107 +#: ../../include/acl_selectors.php:135 +msgid "Only me" +msgstr "Tylko ja" + +#: ../../Zotlabs/Lib/PermissionDescription.php:108 +msgid "Public" +msgstr "Publiczny" + +#: ../../Zotlabs/Lib/PermissionDescription.php:109 +msgid "Anybody in the $Projectname network" +msgstr "Każdy w sieci $Projectname" + +#: ../../Zotlabs/Lib/PermissionDescription.php:110 +#, php-format +msgid "Any account on %s" +msgstr "Dowolne konto na %s" + +#: ../../Zotlabs/Lib/PermissionDescription.php:111 +msgid "Any of my connections" +msgstr "Wszystkie moje połączenia" + +#: ../../Zotlabs/Lib/PermissionDescription.php:112 +msgid "Only connections I specifically allow" +msgstr "Tylko połączenia, na które wyraźnie zezwalam" + +#: ../../Zotlabs/Lib/PermissionDescription.php:113 +msgid "Anybody authenticated (could include visitors from other networks)" +msgstr "Każdy uwierzytelniony (może obejmować odwiedzających z innych sieci)" + +#: ../../Zotlabs/Lib/PermissionDescription.php:114 +msgid "Any connections including those who haven't yet been approved" +msgstr "Wszelkie połączenia, w tym te, które nie zostały jeszcze zatwierdzone" + +#: ../../Zotlabs/Lib/PermissionDescription.php:150 +msgid "" +"This is your default setting for the audience of your normal stream, and " +"posts." +msgstr "" +"To jest domyślne ustawienie odbiorców Twojego normalnego strumienia i postów." + +#: ../../Zotlabs/Lib/PermissionDescription.php:151 +msgid "" +"This is your default setting for who can view your default channel profile" +msgstr "" +"To jest domyślne ustawienie określające, kto może wyświetlać Twój domyślny " +"profil kanału" + +#: ../../Zotlabs/Lib/PermissionDescription.php:152 +msgid "This is your default setting for who can view your connections" +msgstr "" +"To jest domyślne ustawienie określające, kto może wyświetlać Twoje połączenia" + +#: ../../Zotlabs/Lib/PermissionDescription.php:153 +msgid "" +"This is your default setting for who can view your file storage and photos" +msgstr "" +"Jest to domyślne ustawienie określające, kto może wyświetlać miejsce na " +"pliki i zdjęcia" + +#: ../../Zotlabs/Lib/PermissionDescription.php:154 +msgid "This is your default setting for the audience of your webpages" +msgstr "" +"To jest domyślne ustawienie dotyczące odbiorców Twoich stron internetowych" + +#: ../../Zotlabs/Widget/Appcategories.php:46 ../../Zotlabs/Widget/Filer.php:31 +#: ../../include/contact_widgets.php:56 ../../include/contact_widgets.php:111 +#: ../../include/contact_widgets.php:155 ../../include/contact_widgets.php:200 +#: ../../include/contact_widgets.php:235 +msgid "Everything" +msgstr "Wszystko" + +#: ../../Zotlabs/Widget/Cdav.php:37 +msgid "Select Channel" +msgstr "Wybierz kanał" + +#: ../../Zotlabs/Widget/Cdav.php:42 +msgid "Read-write" +msgstr "Czytanie i zapis" + +#: ../../Zotlabs/Widget/Cdav.php:43 +msgid "Read-only" +msgstr "Tylko odczyt" + +#: ../../Zotlabs/Widget/Cdav.php:127 +msgid "Channel Calendar" +msgstr "Kalendarz kanału" + +#: ../../Zotlabs/Widget/Cdav.php:131 +msgid "Shared CalDAV Calendars" +msgstr "Udostępnione kalendarze CalDAV" + +#: ../../Zotlabs/Widget/Cdav.php:135 +msgid "Share this calendar" +msgstr "Udostępnij ten kalendarz" + +#: ../../Zotlabs/Widget/Cdav.php:137 +msgid "Calendar name and color" +msgstr "Nazwa kalendarza i kolor" + +#: ../../Zotlabs/Widget/Cdav.php:139 +msgid "Create new CalDAV calendar" +msgstr "Utwórz nowy kalendarz CalDAV" + +#: ../../Zotlabs/Widget/Cdav.php:141 +msgid "Calendar Name" +msgstr "Nazwa kalendarza" + +#: ../../Zotlabs/Widget/Cdav.php:142 +msgid "Calendar Tools" +msgstr "Narzędzia kalendarza" + +#: ../../Zotlabs/Widget/Cdav.php:144 +msgid "Import calendar" +msgstr "Importuj kalendarz" + +#: ../../Zotlabs/Widget/Cdav.php:145 +msgid "Select a calendar to import to" +msgstr "Wybierz kalendarz do zaimportowania" + +#: ../../Zotlabs/Widget/Cdav.php:172 +msgid "Addressbooks" +msgstr "Książki adresowe" + +#: ../../Zotlabs/Widget/Cdav.php:174 +msgid "Addressbook name" +msgstr "Nazwa książki adresowej" + +#: ../../Zotlabs/Widget/Cdav.php:176 +msgid "Create new addressbook" +msgstr "Utwórz nową książkę adresową" + +#: ../../Zotlabs/Widget/Cdav.php:177 +msgid "Addressbook Name" +msgstr "Nazwa książki adresowej" + +#: ../../Zotlabs/Widget/Cdav.php:179 +msgid "Addressbook Tools" +msgstr "Narzędzia książki adresowej" + +#: ../../Zotlabs/Widget/Cdav.php:180 +msgid "Import addressbook" +msgstr "Importuj książkę adresową" + +#: ../../Zotlabs/Widget/Cdav.php:181 +msgid "Select an addressbook to import to" +msgstr "Wybierz książkę adresową do zaimportowania" + +#: ../../Zotlabs/Widget/Filer.php:28 +#: ../../Zotlabs/Widget/Activity_filter.php:179 +#: ../../include/contact_widgets.php:53 ../../include/features.php:319 +msgid "Saved Folders" +msgstr "Zapisywanie foldery" + +#: ../../Zotlabs/Widget/Tagcloud.php:22 ../../include/taxonomy.php:323 +#: ../../include/taxonomy.php:458 ../../include/taxonomy.php:479 +msgid "Tags" +msgstr "Tagi" + +#: ../../Zotlabs/Widget/Archive.php:43 +msgid "Archives" +msgstr "Archiwa" + +#: ../../Zotlabs/Widget/Chatroom_members.php:11 +msgid "Chat Members" +msgstr "Członkowie czatu" + +#: ../../Zotlabs/Widget/Rating.php:51 +msgid "Rating Tools" +msgstr "Narzędzia" + +#: ../../Zotlabs/Widget/Rating.php:55 ../../Zotlabs/Widget/Rating.php:57 +msgid "Rate Me" +msgstr "Oceń mnie" + +#: ../../Zotlabs/Widget/Rating.php:60 +msgid "View Ratings" +msgstr "Pokaż oceny" + +#: ../../Zotlabs/Widget/Wiki_pages.php:34 +#: ../../Zotlabs/Widget/Wiki_pages.php:91 +msgid "Add new page" +msgstr "Dodaj nową stronę" + +#: ../../Zotlabs/Widget/Wiki_pages.php:85 +msgid "Wiki Pages" +msgstr "Strony wiki" + +#: ../../Zotlabs/Widget/Wiki_pages.php:96 +msgid "Page name" +msgstr "Nazwa strony" + +#: ../../Zotlabs/Widget/Bookmarkedchats.php:24 +msgid "Bookmarked Chatrooms" +msgstr "Czaty dodane do zakładek" + +#: ../../Zotlabs/Widget/Photo.php:48 ../../Zotlabs/Widget/Photo_rand.php:58 +msgid "photo/image" +msgstr "zdjęcie/obraz" + +#: ../../Zotlabs/Widget/Forums.php:100 +#: ../../Zotlabs/Widget/Activity_filter.php:115 +#: ../../Zotlabs/Widget/Notifications.php:139 +#: ../../Zotlabs/Widget/Notifications.php:140 +#: ../../include/acl_selectors.php:124 +msgid "Forums" +msgstr "Fora" + +#: ../../Zotlabs/Widget/Savedsearch.php:75 +msgid "Remove term" +msgstr "Usuń termin" + +#: ../../Zotlabs/Widget/Savedsearch.php:83 ../../include/features.php:311 +msgid "Saved Searches" +msgstr "Zapisywanie wyszukiwania" + +#: ../../Zotlabs/Widget/Follow.php:22 +#, php-format +msgid "You have %1$.0f of %2$.0f allowed connections." +msgstr "Masz %1$.0f z %2$.0f dozwolonych połączeń." + +#: ../../Zotlabs/Widget/Follow.php:29 +msgid "Add New Connection" +msgstr "Dodaj nowe połączenie" + +#: ../../Zotlabs/Widget/Follow.php:30 +msgid "Enter channel address" +msgstr "Wprowadź adres kanału" + +#: ../../Zotlabs/Widget/Follow.php:31 +msgid "Examples: bob@example.com, https://example.com/barbara" +msgstr "Przykłady: bob@example.com, https://example.com/barbara" + +#: ../../Zotlabs/Widget/Suggestions.php:53 +msgid "Suggestions" +msgstr "Prpozycje" + +#: ../../Zotlabs/Widget/Suggestions.php:54 +msgid "See more..." +msgstr "Zobacz więcej..." + +#: ../../Zotlabs/Widget/Tasklist.php:23 +msgid "Tasks" +msgstr "Zadania" + +#: ../../Zotlabs/Widget/Admin.php:23 ../../Zotlabs/Widget/Admin.php:60 +msgid "Member registrations waiting for confirmation" +msgstr "Rejestracja członków czeka na potwierdzenie" + +#: ../../Zotlabs/Widget/Admin.php:29 +msgid "Inspect queue" +msgstr "Sprawdź kolejkę" + +#: ../../Zotlabs/Widget/Admin.php:31 +msgid "DB updates" +msgstr "Aktualizacje bazy danych" + +#: ../../Zotlabs/Widget/Admin.php:55 ../../include/nav.php:194 +msgid "Admin" +msgstr "Admin" + +#: ../../Zotlabs/Widget/Admin.php:56 +msgid "Addon Features" +msgstr "Funkcje dodatków" + +#: ../../Zotlabs/Widget/Chatroom_list.php:20 +msgid "Overview" +msgstr "Przegląd" + +#: ../../Zotlabs/Widget/Appstore.php:11 +msgid "App Collections" +msgstr "Kolekcja aplikacji" + +#: ../../Zotlabs/Widget/Appstore.php:13 +msgid "Installed apps" +msgstr "Zainstalowane aplikacje" + +#: ../../Zotlabs/Widget/Activity_order.php:90 +msgid "Commented Date" +msgstr "Data skomentowania" + +#: ../../Zotlabs/Widget/Activity_order.php:94 +msgid "Order by last commented date" +msgstr "Sortuj według najnowszej daty skomentowania" + +#: ../../Zotlabs/Widget/Activity_order.php:97 +msgid "Posted Date" +msgstr "Data opublikowania" + +#: ../../Zotlabs/Widget/Activity_order.php:101 +msgid "Order by last posted date" +msgstr "Sortuj według najnowszej daty publikacji" + +#: ../../Zotlabs/Widget/Activity_order.php:104 +msgid "Date Unthreaded" +msgstr "Data zakończenia wątku" + +#: ../../Zotlabs/Widget/Activity_order.php:108 +msgid "Order unthreaded by date" +msgstr "Sortuj według daty zakończenia wątku" + +#: ../../Zotlabs/Widget/Activity_order.php:123 +msgid "Stream Order" +msgstr "Kolejność strumienia" + +#: ../../Zotlabs/Widget/Mailmenu.php:13 +msgid "Private Mail Menu" +msgstr "Menu prywatnej poczty" + +#: ../../Zotlabs/Widget/Mailmenu.php:15 +msgid "Combined View" +msgstr "Widok łączony" + +#: ../../Zotlabs/Widget/Mailmenu.php:20 +msgid "Inbox" +msgstr "Skrzynka odbiorcza" + +#: ../../Zotlabs/Widget/Mailmenu.php:25 +msgid "Outbox" +msgstr "Skrzynka nadawcza" + +#: ../../Zotlabs/Widget/Mailmenu.php:30 +msgid "New Message" +msgstr "Nowy komunikat" + +#: ../../Zotlabs/Widget/Affinity.php:54 +msgid "Refresh" +msgstr "Odśwież" + +#: ../../Zotlabs/Widget/Hq_controls.php:14 +msgid "HQ Control Panel" +msgstr "Panel kontrolny HQ" + +#: ../../Zotlabs/Widget/Hq_controls.php:17 +msgid "Create a new post" +msgstr "Utwórz nowy post" + +#: ../../Zotlabs/Widget/Eventstools.php:13 +msgid "Events Tools" +msgstr "Narzędzia wydarzeń" + +#: ../../Zotlabs/Widget/Eventstools.php:14 +msgid "Export Calendar" +msgstr "Eksport kalendarza" + +#: ../../Zotlabs/Widget/Eventstools.php:15 +msgid "Import Calendar" +msgstr "Import kalendarza" + +#: ../../Zotlabs/Widget/Activity_filter.php:33 +msgid "Direct Messages" +msgstr "Bezpośrednie wiadomości" + +#: ../../Zotlabs/Widget/Activity_filter.php:37 +msgid "Show direct (private) messages" +msgstr "Pokaż bezpośrednie (prywatne) wiadomości" + +#: ../../Zotlabs/Widget/Activity_filter.php:42 +msgid "Events" +msgstr "Wydarzenia" + +#: ../../Zotlabs/Widget/Activity_filter.php:46 +msgid "Show posts that include events" +msgstr "Pokaż posty zawierające wydarzenia" + +#: ../../Zotlabs/Widget/Activity_filter.php:52 +msgid "Polls" +msgstr "Ankiety" + +#: ../../Zotlabs/Widget/Activity_filter.php:56 +msgid "Show posts that include polls" +msgstr "Pokaż posty zawierające ankiety" + +#: ../../Zotlabs/Widget/Activity_filter.php:77 +#, php-format +msgid "Show posts related to the %s privacy group" +msgstr "Pokaż posty związane z grupą prywatności %s" + +#: ../../Zotlabs/Widget/Activity_filter.php:86 +msgid "Show my privacy groups" +msgstr "Pokaż moje grupy prywatności" + +#: ../../Zotlabs/Widget/Activity_filter.php:108 +msgid "Show posts to this forum" +msgstr "Pokaż posty na tym forum" + +#: ../../Zotlabs/Widget/Activity_filter.php:119 +msgid "Show forums" +msgstr "Pokaż fora" + +#: ../../Zotlabs/Widget/Activity_filter.php:133 +msgid "Starred Posts" +msgstr "Wyróżnione posty" + +#: ../../Zotlabs/Widget/Activity_filter.php:137 +msgid "Show posts that I have starred" +msgstr "Pokaż posty, które oznaczyłem gwiazdką" + +#: ../../Zotlabs/Widget/Activity_filter.php:148 +msgid "Personal Posts" +msgstr "Posty osobiste" + +#: ../../Zotlabs/Widget/Activity_filter.php:152 +msgid "Show posts that mention or involve me" +msgstr "Pokaż posty, które wspominają o mnie lub mnie dotyczą" + +#: ../../Zotlabs/Widget/Activity_filter.php:173 +#, php-format +msgid "Show posts that I have filed to %s" +msgstr "Pokaż posty przesłane przeze mnie do %s" + +#: ../../Zotlabs/Widget/Activity_filter.php:183 +msgid "Show filed post categories" +msgstr "Pokaż wprowadzone kategorie postów" + +#: ../../Zotlabs/Widget/Activity_filter.php:197 +msgid "Panel search" +msgstr "Przeszukiwanie panelu" + +#: ../../Zotlabs/Widget/Activity_filter.php:207 +msgid "Filter by name" +msgstr "Filtruj wg nazwy" + +#: ../../Zotlabs/Widget/Activity_filter.php:222 +msgid "Remove active filter" +msgstr "Usuń aktywny filtr" + +#: ../../Zotlabs/Widget/Activity_filter.php:238 +msgid "Stream Filters" +msgstr "Filtry strumienia" + +#: ../../Zotlabs/Widget/Activity.php:50 +msgctxt "widget" +msgid "Activity" +msgstr "Aktywność" + +#: ../../Zotlabs/Widget/Notifications.php:16 +msgid "New Network Activity" +msgstr "Nowa aktywność sieciowa" + +#: ../../Zotlabs/Widget/Notifications.php:17 +msgid "New Network Activity Notifications" +msgstr "Powiadomienia o nowej aktywności sieciowej" + +#: ../../Zotlabs/Widget/Notifications.php:20 +msgid "View your network activity" +msgstr "Wyświetl swoją aktywność w sieci" + +#: ../../Zotlabs/Widget/Notifications.php:23 +#: ../../Zotlabs/Widget/Notifications.php:62 +msgid "Mark all notifications read" +msgstr "Oznacz wszystkie powiadomienia jako przeczytane" + +#: ../../Zotlabs/Widget/Notifications.php:26 +#: ../../Zotlabs/Widget/Notifications.php:46 +#: ../../Zotlabs/Widget/Notifications.php:65 +#: ../../Zotlabs/Widget/Notifications.php:172 +msgid "Show new posts only" +msgstr "Pokaż tylko nowe posty" + +#: ../../Zotlabs/Widget/Notifications.php:27 +#: ../../Zotlabs/Widget/Notifications.php:47 +#: ../../Zotlabs/Widget/Notifications.php:66 +#: ../../Zotlabs/Widget/Notifications.php:142 +#: ../../Zotlabs/Widget/Notifications.php:173 +msgid "Filter by name or address" +msgstr "Filtruj według nazwy lub adresu" + +# Sprawdzić w kontekście! +#: ../../Zotlabs/Widget/Notifications.php:36 +msgid "New Home Activity" +msgstr "Nowa aktywność domowa" + +#: ../../Zotlabs/Widget/Notifications.php:37 +msgid "New Home Activity Notifications" +msgstr "Powiadomienia o nowej aktywności domowej" + +#: ../../Zotlabs/Widget/Notifications.php:40 +msgid "View your home activity" +msgstr "Wyświetl swoją aktywność domową" + +#: ../../Zotlabs/Widget/Notifications.php:43 +#: ../../Zotlabs/Widget/Notifications.php:169 +msgid "Mark all notifications seen" +msgstr "Oznacz wszystkie powiadomienia jako oglądnięte" + +#: ../../Zotlabs/Widget/Notifications.php:55 +msgid "New Direct Messages" +msgstr "Nowe bezpośrednie wiadomości" + +#: ../../Zotlabs/Widget/Notifications.php:56 +msgid "New Direct Messages Notifications" +msgstr "Powiadomienia o nowych wiadomościach bezpośrednich" + +#: ../../Zotlabs/Widget/Notifications.php:59 +msgid "View your direct messages" +msgstr "Wyświetl swoje bezpośrednie wiadomości" + +#: ../../Zotlabs/Widget/Notifications.php:74 +msgid "New Mails" +msgstr "Nowe wiadomości e-mail" + +#: ../../Zotlabs/Widget/Notifications.php:75 +msgid "New Mails Notifications" +msgstr "Powiadomienia o nowych wiadomościach e-mail" + +#: ../../Zotlabs/Widget/Notifications.php:78 +msgid "View your private mails" +msgstr "Zobacz swoje prywatne wiadomości" + +#: ../../Zotlabs/Widget/Notifications.php:81 +msgid "Mark all messages seen" +msgstr "Oznacz wszystkie wiadomości jako oglądnięte" + +#: ../../Zotlabs/Widget/Notifications.php:89 +msgid "New Events" +msgstr "Nowe wydarzenia" + +#: ../../Zotlabs/Widget/Notifications.php:90 +msgid "New Events Notifications" +msgstr "Powiadomienia o nowych wydarzeniach" + +#: ../../Zotlabs/Widget/Notifications.php:93 +msgid "View events" +msgstr "Pokaż wydarzenia" + +#: ../../Zotlabs/Widget/Notifications.php:96 +msgid "Mark all events seen" +msgstr "Oznacza wydarzenia jako oglądnięte" + +#: ../../Zotlabs/Widget/Notifications.php:105 +msgid "New Connections Notifications" +msgstr "Powiadomienia o nowych połączeniach" + +#: ../../Zotlabs/Widget/Notifications.php:108 +msgid "View all connections" +msgstr "Pokaż wszystkie połączenia" + +#: ../../Zotlabs/Widget/Notifications.php:116 +msgid "New Files" +msgstr "Nowe pliki" + +#: ../../Zotlabs/Widget/Notifications.php:117 +msgid "New Files Notifications" +msgstr "Powiadomienia o nowych plikach" + +#: ../../Zotlabs/Widget/Notifications.php:124 +#: ../../Zotlabs/Widget/Notifications.php:125 +msgid "Notices" +msgstr "Powiadomienia" + +#: ../../Zotlabs/Widget/Notifications.php:128 +msgid "View all notices" +msgstr "Pokaż wszystkie powiadomienia" + +#: ../../Zotlabs/Widget/Notifications.php:131 +msgid "Mark all notices seen" +msgstr "Oznacza wszystkie powiadomienia jako oglądnięte" + +#: ../../Zotlabs/Widget/Notifications.php:152 +msgid "New Registrations" +msgstr "Nowe rejestracje" + +#: ../../Zotlabs/Widget/Notifications.php:153 +msgid "New Registrations Notifications" +msgstr "Powiadomienia o nowych rejestracjach" + +#: ../../Zotlabs/Widget/Notifications.php:163 +msgid "Public Stream Notifications" +msgstr "Powiadomienia o strimieniu publicznym" + +#: ../../Zotlabs/Widget/Notifications.php:166 +msgid "View the public stream" +msgstr "Pokaż strumień publiczny" + +#: ../../Zotlabs/Widget/Notifications.php:181 +msgid "Sorry, you have got no notifications at the moment" +msgstr "W tej chwili nie masz żadnych powiadomień" + +#: ../../Zotlabs/Widget/Pinned.php:123 ../../Zotlabs/Widget/Pinned.php:124 +#, php-format +msgid "View %s's profile - %s" +msgstr "Pokaż profile %s - %s" + +#: ../../Zotlabs/Widget/Pinned.php:158 +msgid "Don't show" +msgstr "Nie pokazuj" + +#: ../../Zotlabs/Widget/Settings_menu.php:32 +msgid "Account settings" +msgstr "Ustawienia konta" + +#: ../../Zotlabs/Widget/Settings_menu.php:38 +msgid "Channel settings" +msgstr "Ustawienia kanału" + +#: ../../Zotlabs/Widget/Settings_menu.php:46 +msgid "Display settings" +msgstr "Ustawienia wyświetlania" + +#: ../../Zotlabs/Widget/Settings_menu.php:53 +msgid "Manage locations" +msgstr "Zarządzaj lokalizacjami" + +#: ../../Zotlabs/Widget/Suggestedchats.php:32 +msgid "Suggested Chatrooms" +msgstr "Sugerowane czaty" + +#: ../../Zotlabs/Widget/Conversations.php:17 +msgid "Received Messages" +msgstr "Otrzymane wiadomości" + +#: ../../Zotlabs/Widget/Conversations.php:21 +msgid "Sent Messages" +msgstr "Wysłane wiadomości" + +#: ../../Zotlabs/Widget/Conversations.php:25 +msgid "Conversations" +msgstr "Rozmowy" + +#: ../../Zotlabs/Widget/Conversations.php:37 +msgid "No messages." +msgstr "Brak wiadomości." + +#: ../../Zotlabs/Widget/Conversations.php:57 +msgid "Delete conversation" +msgstr "Usuń rozmowę" + +#: ../../Zotlabs/Widget/Newmember.php:31 +msgid "Profile Creation" +msgstr "Tworzenie profilu" + +#: ../../Zotlabs/Widget/Newmember.php:33 +msgid "Upload profile photo" +msgstr "Prześlij zdjęcie profilowe" + +#: ../../Zotlabs/Widget/Newmember.php:34 +msgid "Upload cover photo" +msgstr "Prześlij zdjęcie okładkowe" + +#: ../../Zotlabs/Widget/Newmember.php:35 ../../include/nav.php:117 +msgid "Edit your profile" +msgstr "Edytuj swój profil" + +#: ../../Zotlabs/Widget/Newmember.php:38 +msgid "Find and Connect with others" +msgstr "Znajdź i połącz się z innymi" + +#: ../../Zotlabs/Widget/Newmember.php:40 +msgid "View the directory" +msgstr "Pokaż katalog" + +#: ../../Zotlabs/Widget/Newmember.php:42 +msgid "Manage your connections" +msgstr "Zarządzaj swoimi połączeniami" + +#: ../../Zotlabs/Widget/Newmember.php:45 +msgid "Communicate" +msgstr "Komunikuj się" + +#: ../../Zotlabs/Widget/Newmember.php:47 +msgid "View your channel homepage" +msgstr "Wyświetl stronę główną swojego kanału" + +#: ../../Zotlabs/Widget/Newmember.php:48 +msgid "View your network stream" +msgstr "Wyświetl swój strumień sieciowy" + +#: ../../Zotlabs/Widget/Newmember.php:54 +msgid "Documentation" +msgstr "Dokumentacja" + +#: ../../Zotlabs/Widget/Newmember.php:57 +msgid "Missing Features?" +msgstr "Brakuje funkcji?" + +#: ../../Zotlabs/Widget/Newmember.php:59 +msgid "Pin apps to navigation bar" +msgstr "Przypinaj aplikacje do paska nawigacji" + +#: ../../Zotlabs/Widget/Newmember.php:60 +msgid "Install more apps" +msgstr "Zainstaluj więcej aplikacji" + +#: ../../Zotlabs/Widget/Newmember.php:71 +msgid "View public stream" +msgstr "Pokaż publiczny strumień" + +#: ../../Zotlabs/Widget/Cover_photo.php:65 +msgid "Click to show more" +msgstr "Kliknij, aby pokazać więcej" + +#: ../../util/nconfig.php:34 +msgid "Source channel not found." +msgstr "Nie znaleziono kanału źródłowego." + +#: ../../include/contact_widgets.php:11 +#, php-format +msgid "%d invitation available" +msgid_plural "%d invitations available" +msgstr[0] "%d dostępne zaproszenie" +msgstr[1] "%d dostępne zaproszenia" +msgstr[2] "%d dostępnych zaproszeń" + +#: ../../include/contact_widgets.php:19 +msgid "Find Channels" +msgstr "Znajdź kanały" + +#: ../../include/contact_widgets.php:20 +msgid "Enter name or interest" +msgstr "Wpisz nazwę lub zainteresowanie" + +#: ../../include/contact_widgets.php:21 +msgid "Connect/Follow" +msgstr "Połącz/Obserwuj" + +#: ../../include/contact_widgets.php:22 +msgid "Examples: Robert Morgenstein, Fishing" +msgstr "Przykłady: Robert Morgenstein, łowienie ryb" + +#: ../../include/contact_widgets.php:26 +msgid "Random Profile" +msgstr "Losowy profil" + +#: ../../include/contact_widgets.php:27 +msgid "Invite Friends" +msgstr "Zaproś przyjaciół" + +#: ../../include/contact_widgets.php:29 +msgid "Advanced example: name=fred and country=iceland" +msgstr "Zaawansowany przykład: name=fred i country=iceland" + +#: ../../include/contact_widgets.php:265 +msgid "Common Connections" +msgstr "Popularne połączenia" + +#: ../../include/contact_widgets.php:269 +#, php-format +msgid "View all %d common connections" +msgstr "Wyświetl wszystkie %d popularne połączenia" + +#: ../../include/conversation.php:183 +#, php-format +msgid "likes %1$s's %2$s" +msgstr "polubień %1$s %2$s" + +#: ../../include/conversation.php:186 +#, php-format +msgid "doesn't like %1$s's %2$s" +msgstr "dezaprobat %1$s %2$s" + +#: ../../include/conversation.php:226 ../../include/conversation.php:228 +#, php-format +msgid "%1$s is now connected with %2$s" +msgstr "%1$s jest teraz połączony z %2$s" + +#: ../../include/conversation.php:263 +#, php-format +msgid "%1$s poked %2$s" +msgstr "%1$s szturchnął %2$s" + +#: ../../include/conversation.php:267 ../../include/text.php:1242 +#: ../../include/text.php:1246 +msgid "poked" +msgstr "szturchnięty" + +#: ../../include/conversation.php:779 +#, php-format +msgid "View %s's profile @ %s" +msgstr "Pokaż profil %s @ %s" + +#: ../../include/conversation.php:799 +msgid "Categories:" +msgstr "Kategorie:" + +#: ../../include/conversation.php:800 +msgid "Filed under:" +msgstr "Złożone pod:" + +#: ../../include/conversation.php:825 +msgid "View in context" +msgstr "Zobacz w kontekście" + +#: ../../include/conversation.php:928 +msgid "remove" +msgstr "usuń" + +#: ../../include/conversation.php:932 +msgid "Loading..." +msgstr "Ładowanie ..." + +#: ../../include/conversation.php:934 +msgid "Delete Selected Items" +msgstr "Usuń wybrane elementy" + +#: ../../include/conversation.php:977 +msgid "View Source" +msgstr "Pokaż źródło" + +#: ../../include/conversation.php:987 +msgid "Follow Thread" +msgstr "Obserwuj wątek" + +#: ../../include/conversation.php:996 +msgid "Unfollow Thread" +msgstr "Przestań obserwować wątek" + +#: ../../include/conversation.php:1110 +msgid "Edit Connection" +msgstr "Edytuj połączenie" + +#: ../../include/conversation.php:1120 +msgid "Message" +msgstr "Wiadowmość" + +#: ../../include/conversation.php:1262 +#, php-format +msgid "%s likes this." +msgstr "%s lubi to." + +#: ../../include/conversation.php:1262 +#, php-format +msgid "%s doesn't like this." +msgstr "%s nie lubi tego." + +#: ../../include/conversation.php:1266 +#, php-format +msgid "%2$d people like this." +msgid_plural "%2$d people like this." +msgstr[0] "%2$d osoba lubi to." +msgstr[1] "%2$d osoby lubią tego." +msgstr[2] "%2$d osób lubi tego." + +#: ../../include/conversation.php:1268 +#, php-format +msgid "%2$d people don't like this." +msgid_plural "%2$d people don't like this." +msgstr[0] "%2$d osoba nie lubi to." +msgstr[1] "%2$d osoby nie lubią tego." +msgstr[2] "%2$d osób nie lubią tego." + +#: ../../include/conversation.php:1274 +msgid "and" +msgstr "i" + +#: ../../include/conversation.php:1277 +#, php-format +msgid ", and %d other people" +msgid_plural ", and %d other people" +msgstr[0] ", i %d inna osoba" +msgstr[1] ", i %d inne osoby" +msgstr[2] ", i %d innych osób" + +#: ../../include/conversation.php:1278 +#, php-format +msgid "%s like this." +msgstr "%s lubi to." + +#: ../../include/conversation.php:1278 +#, php-format +msgid "%s don't like this." +msgstr "%s nie lubi tego." + +#: ../../include/conversation.php:1328 +#: ../../extend/addon/hzaddons/hsse/hsse.php:82 +msgid "Set your location" +msgstr "Ustaw swoją lokalizację" + +#: ../../include/conversation.php:1329 +#: ../../extend/addon/hzaddons/hsse/hsse.php:83 +msgid "Clear browser location" +msgstr "Wyczyść lokalizację przeglądarki" + +#: ../../include/conversation.php:1345 +#: ../../extend/addon/hzaddons/hsse/hsse.php:99 +msgid "Embed (existing) photo from your photo albums" +msgstr "Osadź (istniejące) zdjęcie z albumów ze zdjęciami" + +#: ../../include/conversation.php:1381 +#: ../../extend/addon/hzaddons/hsse/hsse.php:135 +msgid "Tag term:" +msgstr "Termin tagu:" + +#: ../../include/conversation.php:1382 +#: ../../extend/addon/hzaddons/hsse/hsse.php:136 +msgid "Where are you right now?" +msgstr "Gdzie teraz jesteś?" + +#: ../../include/conversation.php:1387 +#: ../../extend/addon/hzaddons/hsse/hsse.php:141 +msgid "Choose a different album..." +msgstr "Wybierz inny album..." + +#: ../../include/conversation.php:1391 +#: ../../extend/addon/hzaddons/hsse/hsse.php:145 +msgid "Comments enabled" +msgstr "Włączone komentowanie" + +#: ../../include/conversation.php:1392 +#: ../../extend/addon/hzaddons/hsse/hsse.php:146 +msgid "Comments disabled" +msgstr "Wyłączone komentowanie" + +#: ../../include/conversation.php:1444 +#: ../../extend/addon/hzaddons/hsse/hsse.php:195 +msgid "Page link name" +msgstr "Nazwa linku do strony" + +#: ../../include/conversation.php:1447 +#: ../../extend/addon/hzaddons/hsse/hsse.php:198 +msgid "Post as" +msgstr "Opublikuj jako" + +#: ../../include/conversation.php:1461 +#: ../../extend/addon/hzaddons/hsse/hsse.php:212 +msgid "Toggle voting" +msgstr "Przełącz głosowanie" + +#: ../../include/conversation.php:1462 +msgid "Toggle poll" +msgstr "Przełącz ankietę" + +#: ../../include/conversation.php:1463 +msgid "Option" +msgstr "Opcja" + +#: ../../include/conversation.php:1464 +msgid "Add option" +msgstr "Dodaj opcję" + +#: ../../include/conversation.php:1465 +msgid "Minutes" +msgstr "Minuty" + +#: ../../include/conversation.php:1465 +msgid "Hours" +msgstr "Godziny" + +#: ../../include/conversation.php:1465 +msgid "Days" +msgstr "Dni" + +#: ../../include/conversation.php:1466 +msgid "Allow multiple answers" +msgstr "Zezwalaj na wiele odpowiedzi" + +#: ../../include/conversation.php:1468 +#: ../../extend/addon/hzaddons/hsse/hsse.php:215 +msgid "Disable comments" +msgstr "Wyłącz komentarze" + +#: ../../include/conversation.php:1469 +#: ../../extend/addon/hzaddons/hsse/hsse.php:216 +msgid "Toggle comments" +msgstr "Przełącz komentarze" + +#: ../../include/conversation.php:1477 +#: ../../extend/addon/hzaddons/hsse/hsse.php:224 +msgid "Categories (optional, comma-separated list)" +msgstr "Kategorie (opcjonalnie, lista rozdzielana przecinkami)" + +#: ../../include/conversation.php:1500 +#: ../../extend/addon/hzaddons/hsse/hsse.php:247 +msgid "Other networks and post services" +msgstr "Inne sieci i usługi społecznościowe" + +#: ../../include/conversation.php:1503 +#: ../../extend/addon/hzaddons/hsse/hsse.php:250 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:170 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:313 +msgid "Set expiration date" +msgstr "Ustaw datę wygaśnięcia" + +#: ../../include/conversation.php:1506 +#: ../../extend/addon/hzaddons/hsse/hsse.php:253 +msgid "Set publish date" +msgstr "Ustaw datę publikacji" + +#: ../../include/conversation.php:1755 +msgctxt "noun" +msgid "Attending" +msgid_plural "Attending" +msgstr[0] "Uczestniczy" +msgstr[1] "Uczestnictwa" +msgstr[2] "Uczestnictw" + +#: ../../include/conversation.php:1758 +msgctxt "noun" +msgid "Not Attending" +msgid_plural "Not Attending" +msgstr[0] "Nie uczesticzy" +msgstr[1] "Nie uczestniczą" +msgstr[2] "Nie uczestniczy" + +#: ../../include/conversation.php:1761 +msgctxt "noun" +msgid "Undecided" +msgid_plural "Undecided" +msgstr[0] "Niezdecydowany" +msgstr[1] "Niezdecydowane" +msgstr[2] "Niezdecydowanych" + +#: ../../include/conversation.php:1764 +msgctxt "noun" +msgid "Agree" +msgid_plural "Agrees" +msgstr[0] "Zgadza się" +msgstr[1] "Zgadają się" +msgstr[2] "Zgadza się" + +#: ../../include/conversation.php:1767 +msgctxt "noun" +msgid "Disagree" +msgid_plural "Disagrees" +msgstr[0] "Nie zgadza się" +msgstr[1] "Nie zgadzają się" +msgstr[2] "Nie zgadza się" + +#: ../../include/conversation.php:1770 +msgctxt "noun" +msgid "Abstain" +msgid_plural "Abstains" +msgstr[0] "Wstrzymuje się" +msgstr[1] "Wstrzymują się" +msgstr[2] "Wstrzymuje się" + +#: ../../include/channel.php:46 +msgid "Unable to obtain identity information from database" +msgstr "Nie można uzyskać informacji z bazy danych o tożsamości" + +#: ../../include/channel.php:79 +msgid "Empty name" +msgstr "Pusta nazwa" + +#: ../../include/channel.php:82 +msgid "Name too long" +msgstr "Nazwa jest za długa" + +#: ../../include/channel.php:199 +msgid "No account identifier" +msgstr "Brak identyfikatora konta" + +#: ../../include/channel.php:211 +msgid "Nickname is required." +msgstr "Pseudonim jest wymagany." + +#: ../../include/channel.php:294 +msgid "Unable to retrieve created identity" +msgstr "Nie można pobrać utworzonej tożsamości" + +#: ../../include/channel.php:441 +msgid "Default Profile" +msgstr "Domyślny profil" + +#: ../../include/channel.php:639 ../../include/channel.php:728 +msgid "Unable to retrieve modified identity" +msgstr "Nie można pobrać zmodyfikowanej tożsamości" + +#: ../../include/channel.php:1385 +msgid "Requested channel is not available." +msgstr "Żądany kanał nie jest dostępny." + +#: ../../include/channel.php:1539 +msgid "Create New Profile" +msgstr "Utwórz nowy profil" + +#: ../../include/channel.php:1542 ../../include/nav.php:117 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:58 +msgid "Edit Profile" +msgstr "Edytuj profil" + +#: ../../include/channel.php:1560 +msgid "Visible to everybody" +msgstr "Widoczne dla każdego" + +#: ../../include/channel.php:1637 ../../include/channel.php:1765 +msgid "Gender:" +msgstr "Płeć:" + +#: ../../include/channel.php:1638 ../../include/channel.php:1809 +msgid "Status:" +msgstr "Status:" + +#: ../../include/channel.php:1639 ../../include/channel.php:1833 +msgid "Homepage:" +msgstr "Strona domowa:" + +#: ../../include/channel.php:1640 +msgid "Online Now" +msgstr "Teraz online" + +#: ../../include/channel.php:1693 +msgid "Change your profile photo" +msgstr "Zmień swoje zdjęcie profilowe" + +#: ../../include/channel.php:1720 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:87 +msgid "Female" +msgstr "Kobieta" + +#: ../../include/channel.php:1722 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:85 +msgid "Male" +msgstr "Mężczyzna" + +#: ../../include/channel.php:1724 +msgid "Trans" +msgstr "Trans" + +#: ../../include/channel.php:1726 ../../include/selectors.php:60 +msgid "Neuter" +msgstr "Neutralne" + +#: ../../include/channel.php:1728 ../../include/selectors.php:60 +msgid "Non-specific" +msgstr "Nie określone" + +#: ../../include/channel.php:1770 +msgid "Like this channel" +msgstr "Polub ten kanał" + +#: ../../include/channel.php:1794 +msgid "j F, Y" +msgstr "d M, R" + +#: ../../include/channel.php:1795 +msgid "j F" +msgstr "d M" + +#: ../../include/channel.php:1802 +msgid "Birthday:" +msgstr "Urodziny:" + +#: ../../include/channel.php:1815 +#, php-format +msgid "for %1$d %2$s" +msgstr "dla %1$d %2$s" + +#: ../../include/channel.php:1827 +msgid "Tags:" +msgstr "Tagi:" + +#: ../../include/channel.php:1831 +msgid "Sexual Preference:" +msgstr "Preferencje seksualne:" + +#: ../../include/channel.php:1837 +msgid "Political Views:" +msgstr "Poglądy polityczne:" + +#: ../../include/channel.php:1839 +msgid "Religion:" +msgstr "Religia:" + +#: ../../include/channel.php:1843 +msgid "Hobbies/Interests:" +msgstr "Hobby/Zainteresowania:" + +#: ../../include/channel.php:1845 +msgid "Likes:" +msgstr "Polubień:" + +#: ../../include/channel.php:1847 +msgid "Dislikes:" +msgstr "Dezaprobat:" + +#: ../../include/channel.php:1849 +msgid "Contact information and Social Networks:" +msgstr "Informacje kontaktowe i sieci społecznościowe:" + +#: ../../include/channel.php:1851 +msgid "My other channels:" +msgstr "Moje inne kanały:" + +#: ../../include/channel.php:1853 +msgid "Musical interests:" +msgstr "Zainteresowania muzyczne:" + +#: ../../include/channel.php:1855 +msgid "Books, literature:" +msgstr "Książki, literatura:" + +#: ../../include/channel.php:1857 +msgid "Television:" +msgstr "Telewizja:" + +#: ../../include/channel.php:1859 +msgid "Film/dance/culture/entertainment:" +msgstr "Film/taniec/kultura/rozrywka:" + +#: ../../include/channel.php:1861 +msgid "Love/Romance:" +msgstr "Miłość/romans:" + +#: ../../include/channel.php:1863 +msgid "Work/employment:" +msgstr "Praca/zatrudnienie:" + +#: ../../include/channel.php:1865 +msgid "School/education:" +msgstr "Szkoła/edukacja:" + +#: ../../include/channel.php:1888 +msgid "Like this thing" +msgstr "Jak ta rzecz" + +#: ../../include/features.php:86 +msgid "Start calendar week on Monday" +msgstr "Rozpocznij tydzień kalendarzowy w poniedziałek" + +#: ../../include/features.php:87 +msgid "Default is Sunday" +msgstr "Domyślnie jest to niedziela" + +#: ../../include/features.php:94 +msgid "Event Timezone Selection" +msgstr "Wybór strefy czasowej wydarzenia" + +#: ../../include/features.php:95 +msgid "Allow event creation in timezones other than your own." +msgstr "Zezwalaj na tworzenie wydarzeń w strefach czasowych innych niż Twoja." + +#: ../../include/features.php:108 +msgid "Search by Date" +msgstr "Wyszukaj po dacie" + +#: ../../include/features.php:109 +msgid "Ability to select posts by date ranges" +msgstr "Możliwość wyboru postów według zakresów dat" + +#: ../../include/features.php:116 +msgid "Tag Cloud" +msgstr "Chmura tagów" + +#: ../../include/features.php:117 +msgid "Provide a personal tag cloud on your channel page" +msgstr "Udostępnij osobistą chmurę tagów na stronie swojego kanału" + +#: ../../include/features.php:124 ../../include/features.php:359 +msgid "Use blog/list mode" +msgstr "Użyj trybu bloga/listy" + +#: ../../include/features.php:125 ../../include/features.php:360 +msgid "Comments will be displayed separately" +msgstr "Komentarze będą wyświetlane osobno" + +#: ../../include/features.php:137 +msgid "Connection Filtering" +msgstr "Filtrowanie połączeń" + +#: ../../include/features.php:138 +msgid "Filter incoming posts from connections based on keywords/content" +msgstr "" +"Filtruj przychodzące posty z połączeń, na podstawie słów kluczowych lub " +"treści" + +#: ../../include/features.php:146 +msgid "Conversation" +msgstr "Rozmowa" + +#: ../../include/features.php:158 +msgid "Emoji Reactions" +msgstr "Reakcje emoji" + +#: ../../include/features.php:159 +msgid "Add emoji reaction ability to posts" +msgstr "Dodaj możliwość reakcji emoji do postów" + +#: ../../include/features.php:166 +msgid "Dislike Posts" +msgstr "Nielubienie postów" + +#: ../../include/features.php:167 +msgid "Ability to dislike posts/comments" +msgstr "Możliwość postów i komentarzy jako nielubiane" + +#: ../../include/features.php:174 +msgid "Star Posts" +msgstr "Wyróżnianie postów" + +#: ../../include/features.php:175 +msgid "Ability to mark special posts with a star indicator" +msgstr "Możliwość oznaczania wyróżnionych postów wskaźnikiem gwiazdki" + +#: ../../include/features.php:182 +msgid "Reply on comment" +msgstr "Odpowiedanie na komentarze" + +#: ../../include/features.php:183 +msgid "Ability to reply on selected comment" +msgstr "Możliwość udzielenia odpowiedzi na wybrany komentarz" + +#: ../../include/features.php:196 +msgid "Advanced Directory Search" +msgstr "Zaawansowane przeszukiwanie katalogu" + +#: ../../include/features.php:197 +msgid "Allows creation of complex directory search queries" +msgstr "Umożliwia tworzenie złożonych zapytań wyszukiwania w katalogu" + +#: ../../include/features.php:206 +msgid "Editor" +msgstr "Edytor" + +#: ../../include/features.php:210 +msgid "Post Categories" +msgstr "Kategorie postów" + +#: ../../include/features.php:211 +msgid "Add categories to your posts" +msgstr "Dodaj kategorie do swoich postów" + +#: ../../include/features.php:219 +msgid "Large Photos" +msgstr "Duże zdjęcia" + +#: ../../include/features.php:220 +msgid "" +"Include large (1024px) photo thumbnails in posts. If not enabled, use small " +"(640px) photo thumbnails" +msgstr "" +"Dołączaj duże miniatury zdjęć (1024px) do postów. Jeśli nie jest to " +"włączone, będzie można używać małych miniatur (640 px)" + +#: ../../include/features.php:227 +msgid "Even More Encryption" +msgstr "Jeszcze więcej szyfrowania" + +#: ../../include/features.php:228 +msgid "" +"Allow optional encryption of content end-to-end with a shared secret key" +msgstr "" +"Zezwalaj na opcjonalne szyfrowanie zawartości od końca do końca za pomocą " +"wspólnego tajnego klucza" + +#: ../../include/features.php:235 +msgid "Disable Comments" +msgstr "Wyłącz komentarze" + +#: ../../include/features.php:236 +msgid "Provide the option to disable comments for a post" +msgstr "Zapewnia możliwość wyłączenia komentowania postu" + +#: ../../include/features.php:243 +msgid "Delayed Posting" +msgstr "Opóźnione publikowanie" + +#: ../../include/features.php:244 +msgid "Allow posts to be published at a later date" +msgstr "Pozwal na publikację postów w późniejszym terminie" + +#: ../../include/features.php:251 +msgid "Content Expiration" +msgstr "Wygaśnięcie treści" + +#: ../../include/features.php:252 +msgid "Remove posts/comments and/or private messages at a future time" +msgstr "Usuwanie postów i komentarzy lub prywatnych wiadomości w przyszłości" + +#: ../../include/features.php:259 +msgid "Suppress Duplicate Posts/Comments" +msgstr "Pomiń zduplikowane posty i komentarze" + +#: ../../include/features.php:260 +msgid "" +"Prevent posts with identical content to be published with less than two " +"minutes in between submissions." +msgstr "" +"Zapobiegaj publikowaniu postów o identycznej treści, mających mniej niż dwie " +"minuty między przesłaniami." + +#: ../../include/features.php:267 +msgid "Auto-save drafts of posts and comments" +msgstr "Automatyczne zapisywanie wersji roboczych postów i komentarzy" + +#: ../../include/features.php:268 +msgid "" +"Automatically saves post and comment drafts in local browser storage to help " +"prevent accidental loss of compositions" +msgstr "" +"Automatycznie zapisuje wersje robocze postów i komentarzy w lokalnej pamięci " +"przeglądarki, aby zapobiec przypadkowej utracie kompozycji" + +#: ../../include/features.php:277 +msgid "Manage" +msgstr "Zarządzaj" + +#: ../../include/features.php:281 +msgid "Navigation Channel Select" +msgstr "Wybór kanału przez nawigację" + +#: ../../include/features.php:282 +msgid "Change channels directly from within the navigation dropdown menu" +msgstr "Zmiana kanału bezpośrednio z rozwijanego menu nawigacji" + +#: ../../include/features.php:295 +msgid "Events Filter" +msgstr "Filtr wydarzeń" + +#: ../../include/features.php:296 +msgid "Ability to display only events" +msgstr "Możliwość wyświetlania tylko wydarzeń" + +#: ../../include/features.php:303 +msgid "Polls Filter" +msgstr "Filtr ankiet" + +#: ../../include/features.php:304 +msgid "Ability to display only polls" +msgstr "Możliwość wyświetlania tylko ankiet" + +#: ../../include/features.php:312 +msgid "Save search terms for re-use" +msgstr "Zapisywanie wyszukiwanych haseł do ponownego wykorzystania" + +#: ../../include/features.php:320 +msgid "Ability to file posts under folders" +msgstr "Możliwość umieszczania postów w folderach" + +#: ../../include/features.php:327 +msgid "Alternate Stream Order" +msgstr "Alternatywna kolejność strumienia" + +#: ../../include/features.php:328 +msgid "" +"Ability to order the stream by last post date, last comment date or " +"unthreaded activities" +msgstr "" +"Możliwość uporządkowania strumienia według daty ostatniego postu, daty " +"ostatniego komentarza lub nieprzeczytanych aktywności" + +#: ../../include/features.php:335 +msgid "Contact Filter" +msgstr "Filtr kontaktów" + +#: ../../include/features.php:336 +msgid "Ability to display only posts of a selected contact" +msgstr "Możliwość wyświetlania postów autorstwa tylko wybranego kontaktu" + +#: ../../include/features.php:343 +msgid "Forum Filter" +msgstr "Filtr forów" + +#: ../../include/features.php:344 +msgid "Ability to display only posts of a specific forum" +msgstr "Możliwość wyświetlania postów tylko z określonego forum" + +#: ../../include/features.php:351 +msgid "Personal Posts Filter" +msgstr "Filtr postów osobistych" + +#: ../../include/features.php:352 +msgid "Ability to display only posts that you've interacted on" +msgstr "" +"Możliwość wyświetlania tylko tych postów, z którymi miało się interakcję" + +#: ../../include/features.php:373 +msgid "Photo Location" +msgstr "Lokalizacja zdjęcia" + +#: ../../include/features.php:374 +msgid "If location data is available on uploaded photos, link this to a map." +msgstr "" +"Jeśli dane lokalizacji są dostępne na przesłanych zdjęciach, połącz je z " +"mapą." + +#: ../../include/features.php:387 +msgid "Advanced Profiles" +msgstr "Profile zaawansowane" + +#: ../../include/features.php:388 +msgid "Additional profile sections and selections" +msgstr "Dodatkowe sekcje profilu i pól wyborów" + +#: ../../include/features.php:395 +msgid "Profile Import/Export" +msgstr "Profile Import/Export" + +#: ../../include/features.php:396 +msgid "Save and load profile details across sites/channels" +msgstr "Zapisz i wczytaj szczegóły profilu w różnych witrynach i kanałach" + +#: ../../include/features.php:403 +msgid "Multiple Profiles" +msgstr "Wiele profili" + +#: ../../include/features.php:404 +msgid "Ability to create multiple profiles" +msgstr "Możliwość tworzenia wielu profili" + +#: ../../include/auth.php:194 +msgid "Delegation session ended." +msgstr "Sesja delegacji zakończyła się." + +#: ../../include/auth.php:198 +msgid "Logged out." +msgstr "Wylogowano." + +#: ../../include/auth.php:294 +msgid "Email validation is incomplete. Please check your email." +msgstr "" +"Weryfikacja adresu e-mail jest niekompletna. Proszę sprawdzić swój adres " +"email." + +#: ../../include/auth.php:310 +msgid "Failed authentication" +msgstr "Uwierzytelnianie nie powiodło się" + +#: ../../include/auth.php:320 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:188 +msgid "Login failed." +msgstr "Logowanie nie powiodło się." + +#: ../../include/text.php:522 +msgid "prev" +msgstr "poprzedni" + +#: ../../include/text.php:524 +msgid "first" +msgstr "pierwszy" + +#: ../../include/text.php:553 +msgid "last" +msgstr "ostatni" + +#: ../../include/text.php:556 +msgid "next" +msgstr "następny" + +#: ../../include/text.php:574 +msgid "older" +msgstr "starszy" + +#: ../../include/text.php:576 +msgid "newer" +msgstr "nowszy" + +#: ../../include/text.php:1024 +msgid "No connections" +msgstr "Brak połączeń" + +#: ../../include/text.php:1076 +#, php-format +msgid "View all %s connections" +msgstr "Wyświetl wszystkie połączenia %s" + +#: ../../include/text.php:1139 +#, php-format +msgid "Network: %s" +msgstr "Sieć: %s" + +#: ../../include/text.php:1242 ../../include/text.php:1246 +msgid "poke" +msgstr "szturchać" + +#: ../../include/text.php:1247 +msgid "ping" +msgstr "ping" + +#: ../../include/text.php:1247 +msgid "pinged" +msgstr "spingowany" + +#: ../../include/text.php:1248 +msgid "prod" +msgstr "szturchać" + +#: ../../include/text.php:1248 +msgid "prodded" +msgstr "szturchać" + +#: ../../include/text.php:1249 +msgid "slap" +msgstr "spoliczkować" + +#: ../../include/text.php:1249 +msgid "slapped" +msgstr "spoliczkowany" + +#: ../../include/text.php:1250 +msgid "finger" +msgstr "dotknąć" + +#: ../../include/text.php:1250 +msgid "fingered" +msgstr "dotknięty" + +#: ../../include/text.php:1251 +msgid "rebuff" +msgstr "odprawiać" + +#: ../../include/text.php:1251 +msgid "rebuffed" +msgstr "odprawiony" + +#: ../../include/text.php:1274 +msgid "happy" +msgstr "szczęśliwy" + +#: ../../include/text.php:1275 +msgid "sad" +msgstr "smutny" + +#: ../../include/text.php:1276 +msgid "mellow" +msgstr "łagodny" + +#: ../../include/text.php:1277 +msgid "tired" +msgstr "zmęczony" + +#: ../../include/text.php:1278 +msgid "perky" +msgstr "dziarski" + +#: ../../include/text.php:1279 +msgid "angry" +msgstr "gniewny" + +#: ../../include/text.php:1280 +msgid "stupefied" +msgstr "oszołomiony" + +#: ../../include/text.php:1281 +msgid "puzzled" +msgstr "zdziwiony" + +#: ../../include/text.php:1282 +msgid "interested" +msgstr "zainteresowany" + +#: ../../include/text.php:1283 +msgid "bitter" +msgstr "gorzki" + +#: ../../include/text.php:1284 +msgid "cheerful" +msgstr "wesoły" + +#: ../../include/text.php:1285 +msgid "alive" +msgstr "żywy" + +#: ../../include/text.php:1286 +msgid "annoyed" +msgstr "zirytowany" + +#: ../../include/text.php:1287 +msgid "anxious" +msgstr "niespokojny" + +#: ../../include/text.php:1288 +msgid "cranky" +msgstr "zepsuty" + +#: ../../include/text.php:1289 +msgid "disturbed" +msgstr "zaniepokojony" + +#: ../../include/text.php:1290 +msgid "frustrated" +msgstr "sfrustrowany" + +#: ../../include/text.php:1291 +msgid "depressed" +msgstr "przygnębiony" + +#: ../../include/text.php:1292 +msgid "motivated" +msgstr "zmotywowany" + +#: ../../include/text.php:1293 +msgid "relaxed" +msgstr "zThese " +"permissions set who is allowed to view the post." +msgstr "" +"Uprawnienia do publikowania %s nie mogą być zmieniane %s po udostępnieniu " +"postu.
      Te uprawnienia określają, kto może oglądać post." + +#: ../../include/opengraph.php:56 +#, php-format +msgid "This is the home page of %s." +msgstr "To jest strona główna %s." + +#: ../../include/taxonomy.php:323 +msgid "Trending" +msgstr "Trendy" + +#: ../../include/taxonomy.php:559 +msgid "Keywords" +msgstr "Słowa kluczowe" + +#: ../../include/taxonomy.php:580 +msgid "have" +msgstr "ma" + +#: ../../include/taxonomy.php:580 +msgid "has" +msgstr "mają" + +#: ../../include/taxonomy.php:581 +msgid "want" +msgstr "chce" + +#: ../../include/taxonomy.php:581 +msgid "wants" +msgstr "chcą" + +#: ../../include/taxonomy.php:582 +msgid "likes" +msgstr "lubią" + +#: ../../include/taxonomy.php:583 +msgid "dislikes" +msgstr "nie lubią" + +#: ../../include/import.php:29 +msgid "Unable to import a removed channel." +msgstr "Nie można zaimportować usuniętego kanału." + +#: ../../include/import.php:55 +msgid "" +"Cannot create a duplicate channel identifier on this system. Import failed." +msgstr "" +"Nie można utworzyć zduplikowanego identyfikatora kanału w tym systemie. " +"Import nieudany." + +#: ../../include/import.php:76 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:44 +msgid "Unable to create a unique channel address. Import failed." +msgstr "Nie można utworzyć unikalnego adresu kanału. Import nieudany." + +#: ../../include/import.php:121 +msgid "Cloned channel not found. Import failed." +msgstr "Nie znaleziono sklonowanego kanału. Import nieudany." + +#: ../../include/nav.php:92 +msgid "Remote authentication" +msgstr "Zdalne uwierzytelnianie" + +#: ../../include/nav.php:92 +msgid "Click to authenticate to your home hub" +msgstr "Kliknij, aby uwierzytelnić się na swoim głównym hubie" + +#: ../../include/nav.php:98 +msgid "Manage your channels" +msgstr "Zarządzaj swoimi kanałami" + +#: ../../include/nav.php:101 +msgid "Manage your privacy groups" +msgstr "Zarządzaj swoimi grupami prywatności" + +#: ../../include/nav.php:103 +msgid "Account/Channel Settings" +msgstr "Ustawienia kanału/konta" + +#: ../../include/nav.php:109 ../../include/nav.php:138 +#: ../../include/nav.php:157 ../../boot.php:1704 +msgid "Logout" +msgstr "Wyloguj się" + +#: ../../include/nav.php:109 ../../include/nav.php:138 +msgid "End this session" +msgstr "Zakończ tą sesję" + +#: ../../include/nav.php:112 +msgid "Your profile page" +msgstr "Strona Twojego profilu" + +#: ../../include/nav.php:115 +msgid "Manage/Edit profiles" +msgstr "Zarządzaj/edytuj profile" + +#: ../../include/nav.php:124 ../../include/nav.php:128 +msgid "Sign in" +msgstr "Zaloguj się" + +#: ../../include/nav.php:155 +msgid "Take me home" +msgstr "Zabierz mnie do domu" + +#: ../../include/nav.php:157 +msgid "Log me out of this site" +msgstr "Wyloguj mnie z tej witryny" + +#: ../../include/nav.php:162 +msgid "Create an account" +msgstr "Utwórz konto" + +#: ../../include/nav.php:174 +msgid "Help and documentation" +msgstr "Pomoc i dokumentacja" + +#: ../../include/nav.php:188 +msgid "Search site @name, !forum, #tag, ?docs, content" +msgstr "Szukaj w witrynie @name, !forum, #tag, ?docs, content" + +#: ../../include/nav.php:194 +msgid "Site Setup and Configuration" +msgstr "Instalacja i konfiguracja witryny" + +#: ../../include/nav.php:330 +msgid "@name, !forum, #tag, ?doc, content" +msgstr "@name, !forum, #tag, ?doc, content" + +#: ../../include/nav.php:331 +msgid "Please wait..." +msgstr "Proszę czekać ..." + +#: ../../include/nav.php:337 +msgid "Add Apps" +msgstr "Dodaj aplikacje" + +#: ../../include/nav.php:338 +msgid "Arrange Apps" +msgstr "Rozmieść aplikacje" + +#: ../../include/nav.php:339 +msgid "Toggle System Apps" +msgstr "Przełącz aplikacje systemowe" + +#: ../../include/nav.php:424 +msgid "Status Messages and Posts" +msgstr "Komunikaty o stanie i posty" + +#: ../../include/nav.php:437 +msgid "Profile Details" +msgstr "Szczegóły profilu" + +#: ../../include/nav.php:447 ../../include/photos.php:666 +msgid "Photo Albums" +msgstr "Albumy zdjęć" + +#: ../../include/nav.php:455 +msgid "Files and Storage" +msgstr "Pliki i ich magazyn" + +#: ../../include/nav.php:493 +msgid "Saved Bookmarks" +msgstr "Zapisane zakładki" + +#: ../../include/nav.php:504 +msgid "View Cards" +msgstr "Wyświetl karty" + +#: ../../include/nav.php:515 +msgid "View Articles" +msgstr "Wyświetl artykuły" + +#: ../../include/nav.php:527 +msgid "View Webpages" +msgstr "Wyświetl witryny internetowe" + +#: ../../include/language.php:437 +msgid "Select an alternate language" +msgstr "Wybierz alternatywny język" + +#: ../../include/zid.php:360 +#, php-format +msgid "OpenWebAuth: %1$s welcomes %2$s" +msgstr "OpenWebAuth: %1$s wita %2$s" + +#: ../../include/bookmarks.php:34 +#, php-format +msgid "%1$s's bookmarks" +msgstr "zakładki %1$s" + +#: ../../include/activities.php:42 +msgid " and " +msgstr " i " + +#: ../../include/activities.php:50 +msgid "public profile" +msgstr "profil publiczny" + +#: ../../include/activities.php:59 +#, php-format +msgid "%1$s changed %2$s to “%3$s”" +msgstr "%1$s zmienił %2$s na „%3$s”" + +#: ../../include/activities.php:60 +#, php-format +msgid "Visit %1$s's %2$s" +msgstr "Odwiedzin %1$s %2$s" + +#: ../../include/activities.php:63 +#, php-format +msgid "%1$s has an updated %2$s, changing %3$s." +msgstr "%1$s ma zaktualizowane %2$s, zmieniając %3$s." + +#: ../../include/cdav.php:157 +msgid "INVALID EVENT DISMISSED!" +msgstr "ODRZUCONO NIEPRAWIDŁOWE WYDARZENIE!" + +#: ../../include/cdav.php:158 +msgid "Summary: " +msgstr "Podsumowanie: " + +#: ../../include/cdav.php:159 +msgid "Date: " +msgstr "Data: " + +#: ../../include/cdav.php:160 ../../include/cdav.php:168 +msgid "Reason: " +msgstr "Powód: " + +#: ../../include/cdav.php:166 +msgid "INVALID CARD DISMISSED!" +msgstr "ODRZUCONO NIEPRAWIDŁOWĄ KARTĘ!" + +#: ../../include/cdav.php:167 +msgid "Name: " +msgstr "Nazwa: " + +#: ../../include/photos.php:151 +#, php-format +msgid "Image exceeds website size limit of %lu bytes" +msgstr "Obraz przekracza limit rozmiaru witryny wynoszący %lu bajtów" + +#: ../../include/photos.php:162 +msgid "Image file is empty." +msgstr "Plik obrazu jest pusty." + +#: ../../include/photos.php:324 +msgid "Photo storage failed." +msgstr "Zapis zdjęcia nie powiódł się." + +#: ../../include/photos.php:373 +msgid "a new photo" +msgstr "nowe zdjęcie" + +#: ../../include/photos.php:377 +#, php-format +msgctxt "photo_upload" +msgid "%1$s posted %2$s to %3$s" +msgstr "%1$s wysłał %2$s do %3$s" + +#: ../../include/photos.php:671 +msgid "Upload New Photos" +msgstr "Prześlij nowe zdjęcia" + +#: ../../include/js_strings.php:5 +msgid "Delete this item?" +msgstr "Usunąć tą pozycjęD?" + +#: ../../include/js_strings.php:8 +#, php-format +msgid "%s show less" +msgstr "%s pokaż mniej" + +#: ../../include/js_strings.php:9 +#, php-format +msgid "%s expand" +msgstr "%s rozwiń" + +#: ../../include/js_strings.php:10 +#, php-format +msgid "%s collapse" +msgstr "%s zwiń" + +#: ../../include/js_strings.php:11 +msgid "Password too short" +msgstr "Hasło jest za krótkie" + +#: ../../include/js_strings.php:12 +msgid "Passwords do not match" +msgstr "Hasła nie pasują do siebie" + +#: ../../include/js_strings.php:13 +msgid "everybody" +msgstr "wszyscy" + +#: ../../include/js_strings.php:14 +msgid "Secret Passphrase" +msgstr "Tajna hasło" + +#: ../../include/js_strings.php:15 +msgid "Passphrase hint" +msgstr "Wskazówka dotycząca hasła" + +#: ../../include/js_strings.php:16 +msgid "Notice: Permissions have changed but have not yet been submitted." +msgstr "Uwaga: uprawnienia uległy zmianie, ale nie zostały jeszcze przesłane." + +#: ../../include/js_strings.php:17 +msgid "close all" +msgstr "zamknij wszystko" + +#: ../../include/js_strings.php:18 +msgid "Nothing new here" +msgstr "Nic nowego tutaj" + +#: ../../include/js_strings.php:19 +msgid "Rate This Channel (this is public)" +msgstr "Oceń ten kanał (to jest publiczne)" + +#: ../../include/js_strings.php:21 +msgid "Describe (optional)" +msgstr "Opisz (opcjonalnie)" + +#: ../../include/js_strings.php:23 +msgid "Please enter a link URL" +msgstr "Proszę wprowadzić URL linku" + +#: ../../include/js_strings.php:24 +msgid "Unsaved changes. Are you sure you wish to leave this page?" +msgstr "Niezapisane zmiany. Czy na pewno chcesz opuścić tę stronę?" + +#: ../../include/js_strings.php:26 +msgid "lovely" +msgstr "śliczne" + +#: ../../include/js_strings.php:27 +msgid "wonderful" +msgstr "wspaniałe" + +#: ../../include/js_strings.php:28 +msgid "fantastic" +msgstr "fantastyczne" + +#: ../../include/js_strings.php:29 +msgid "great" +msgstr "świetne" + +#: ../../include/js_strings.php:30 +msgid "" +"Your chosen nickname was either already taken or not valid. Please use our " +"suggestion (" +msgstr "" +"Twój wybrany pseudonim jest już zajęty lub nieważny. Skorzystaj z naszej " +"prpozycji (" + +#: ../../include/js_strings.php:31 +msgid ") or enter a new one." +msgstr ") lub wprowadź nowy." + +#: ../../include/js_strings.php:32 +msgid "Thank you, this nickname is valid." +msgstr "Dziękuję, ten pseudonim jest prawidłowy." + +#: ../../include/js_strings.php:33 +msgid "A channel name is required." +msgstr "Wymagana jest nazwa kanału." + +#: ../../include/js_strings.php:34 +msgid "This is a " +msgstr "To jest " + +#: ../../include/js_strings.php:35 +msgid " channel name" +msgstr " nazwa kanału" + +#: ../../include/js_strings.php:36 +msgid "Back to reply" +msgstr "Wróć do odpowiedzi" + +#: ../../include/js_strings.php:37 +msgid "Pinned" +msgstr "Przypięte" + +#: ../../include/js_strings.php:45 +#, php-format +msgid "%d minutes" +msgid_plural "%d minutes" +msgstr[0] "%d minuta" +msgstr[1] "%d minuty" +msgstr[2] "%d minut" + +#: ../../include/js_strings.php:46 +#, php-format +msgid "about %d hours" +msgid_plural "about %d hours" +msgstr[0] "około %d godziny" +msgstr[1] "około %d godzin" +msgstr[2] "około %d godzin" + +#: ../../include/js_strings.php:47 +#, php-format +msgid "%d days" +msgid_plural "%d days" +msgstr[0] "%d dzień" +msgstr[1] "%d dni" +msgstr[2] "%d dni" + +#: ../../include/js_strings.php:48 +#, php-format +msgid "%d months" +msgid_plural "%d months" +msgstr[0] "%d miesiąc" +msgstr[1] "%d miesięcy" +msgstr[2] "%d miesięcy" + +#: ../../include/js_strings.php:49 +#, php-format +msgid "%d years" +msgid_plural "%d years" +msgstr[0] "%d rok" +msgstr[1] "%d lata" +msgstr[2] "%d lat" + +#: ../../include/js_strings.php:54 +msgid "timeago.prefixAgo" +msgstr "temu" + +#: ../../include/js_strings.php:55 +msgid "timeago.prefixFromNow" +msgstr "od teraz" + +#: ../../include/js_strings.php:56 +msgid "timeago.suffixAgo" +msgstr "temu" + +#: ../../include/js_strings.php:57 +msgid "timeago.suffixFromNow" +msgstr "od teraz" + +#: ../../include/js_strings.php:60 +msgid "less than a minute" +msgstr "mniej niż minutę" + +#: ../../include/js_strings.php:61 +msgid "about a minute" +msgstr "około minuty" + +#: ../../include/js_strings.php:63 +msgid "about an hour" +msgstr "około godziny" + +#: ../../include/js_strings.php:65 +msgid "a day" +msgstr "dzień" + +#: ../../include/js_strings.php:67 +msgid "about a month" +msgstr "około miesiąca" + +#: ../../include/js_strings.php:69 +msgid "about a year" +msgstr "około roku" + +#: ../../include/js_strings.php:71 +msgid " " +msgstr " " + +#: ../../include/js_strings.php:72 +msgid "timeago.numbers" +msgstr "timeago.numbers" + +#: ../../include/js_strings.php:78 +msgctxt "long" +msgid "May" +msgstr "Maj" + +#: ../../include/js_strings.php:86 +msgid "Jan" +msgstr "Sty" + +#: ../../include/js_strings.php:87 +msgid "Feb" +msgstr "Lut" + +#: ../../include/js_strings.php:88 +msgid "Mar" +msgstr "Mar" + +#: ../../include/js_strings.php:89 +msgid "Apr" +msgstr "Kwi" + +#: ../../include/js_strings.php:90 +msgctxt "short" +msgid "May" +msgstr "Maj" + +#: ../../include/js_strings.php:91 +msgid "Jun" +msgstr "Cze" + +#: ../../include/js_strings.php:92 +msgid "Jul" +msgstr "Lop" + +#: ../../include/js_strings.php:93 +msgid "Aug" +msgstr "Sie" + +#: ../../include/js_strings.php:94 +msgid "Sep" +msgstr "Wrz" + +#: ../../include/js_strings.php:95 +msgid "Oct" +msgstr "Paź" + +#: ../../include/js_strings.php:96 +msgid "Nov" +msgstr "Lis" + +#: ../../include/js_strings.php:97 +msgid "Dec" +msgstr "Gru" + +#: ../../include/js_strings.php:105 +msgid "Sun" +msgstr "Nie" + +#: ../../include/js_strings.php:106 +msgid "Mon" +msgstr "Pon" + +#: ../../include/js_strings.php:107 +msgid "Tue" +msgstr "Wto" + +#: ../../include/js_strings.php:108 +msgid "Wed" +msgstr "Śro" + +#: ../../include/js_strings.php:109 +msgid "Thu" +msgstr "Czw" + +#: ../../include/js_strings.php:110 +msgid "Fri" +msgstr "Pią" + +#: ../../include/js_strings.php:111 +msgid "Sat" +msgstr "Sob" + +#: ../../include/js_strings.php:112 +msgctxt "calendar" +msgid "today" +msgstr "dzisiaj" + +#: ../../include/js_strings.php:113 +msgctxt "calendar" +msgid "month" +msgstr "miesiąc" + +#: ../../include/js_strings.php:114 +msgctxt "calendar" +msgid "week" +msgstr "tydzień" + +#: ../../include/js_strings.php:115 +msgctxt "calendar" +msgid "day" +msgstr "dzień" + +#: ../../include/js_strings.php:116 +msgctxt "calendar" +msgid "All day" +msgstr "Cały dzień" + +#: ../../include/js_strings.php:119 +msgid "Please stand by while your download is being prepared." +msgstr "Proszę czekać, aż pobieranie jest przygotowywane." + +#: ../../include/security.php:609 +msgid "" +"The form security token was not correct. This probably happened because the " +"form has been opened for too long (>3 hours) before submitting it." +msgstr "" +"Token bezpieczeństwa formularza był nieprawidłowy. Prawdopodobnie stało się " +"tak, ponieważ formularz był otwarty zbyt długo (> 3 godziny) przed wysłaniem." + +#: ../../include/selectors.php:18 +msgid "Profile to assign new connections" +msgstr "Profil do przypisywania nowych połączeń" + +#: ../../include/selectors.php:41 +msgid "Frequently" +msgstr "Często" + +#: ../../include/selectors.php:42 +msgid "Hourly" +msgstr "Co godzinnę" + +#: ../../include/selectors.php:43 +msgid "Twice daily" +msgstr "Dwa razy dziennie" + +#: ../../include/selectors.php:44 +msgid "Daily" +msgstr "Co dzień" + +#: ../../include/selectors.php:45 +msgid "Weekly" +msgstr "Co tydzień" + +#: ../../include/selectors.php:46 +msgid "Monthly" +msgstr "Co miesiąc" + +#: ../../include/selectors.php:60 +msgid "Currently Male" +msgstr "Obecnie mężczyzna" + +#: ../../include/selectors.php:60 +msgid "Currently Female" +msgstr "Obecnie kobieta" + +#: ../../include/selectors.php:60 +msgid "Mostly Male" +msgstr "Głównie mężczyźna" + +#: ../../include/selectors.php:60 +msgid "Mostly Female" +msgstr "Głównie kobieta" + +#: ../../include/selectors.php:60 +msgid "Transgender" +msgstr "Transgender" + +#: ../../include/selectors.php:60 +msgid "Intersex" +msgstr "Interpłciowość" + +#: ../../include/selectors.php:60 +msgid "Transsexual" +msgstr "Transseksualność" + +#: ../../include/selectors.php:60 +msgid "Hermaphrodite" +msgstr "Hermafrodyta" + +#: ../../include/selectors.php:60 +msgid "Undecided" +msgstr "Niezdecydowano" + +#: ../../include/selectors.php:96 ../../include/selectors.php:115 +msgid "Males" +msgstr "Mężczyżni" + +#: ../../include/selectors.php:96 ../../include/selectors.php:115 +msgid "Females" +msgstr "Kobiety" + +#: ../../include/selectors.php:96 +msgid "Gay" +msgstr "Homoseksualista" + +#: ../../include/selectors.php:96 +msgid "Lesbian" +msgstr "Lesbijka" + +#: ../../include/selectors.php:96 +msgid "No Preference" +msgstr "Bez preferencji" + +#: ../../include/selectors.php:96 +msgid "Bisexual" +msgstr "Biseksualne" + +#: ../../include/selectors.php:96 +msgid "Autosexual" +msgstr "Autoseksualne" + +#: ../../include/selectors.php:96 +msgid "Abstinent" +msgstr "Abstyncja" + +#: ../../include/selectors.php:96 +msgid "Virgin" +msgstr "Dziewice" + +#: ../../include/selectors.php:96 +msgid "Deviant" +msgstr "Dewiant" + +#: ../../include/selectors.php:96 +msgid "Fetish" +msgstr "Fetysz" + +#: ../../include/selectors.php:96 +msgid "Oodles" +msgstr "Oodles" + +#: ../../include/selectors.php:96 +msgid "Nonsexual" +msgstr "Nonsexual" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Single" +msgstr "Singiel" + +#: ../../include/selectors.php:134 +msgid "Lonely" +msgstr "Samotny/Samotna" + +#: ../../include/selectors.php:134 +msgid "Available" +msgstr "Dostępny/Dostęnna" + +#: ../../include/selectors.php:134 +msgid "Unavailable" +msgstr "Niedostępny/Niedostęþna" + +#: ../../include/selectors.php:134 +msgid "Has crush" +msgstr "Zadużony/Zadużona" + +#: ../../include/selectors.php:134 +msgid "Infatuated" +msgstr "Zakochany/Zakochana" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Dating" +msgstr "Randki" + +#: ../../include/selectors.php:134 +msgid "Unfaithful" +msgstr "Niewierny" + +#: ../../include/selectors.php:134 +msgid "Sex Addict" +msgstr "Uzależniony/Uzależniona od seksu" + +#: ../../include/selectors.php:134 +msgid "Friends/Benefits" +msgstr "Przyjaciele/Korzyści" + +#: ../../include/selectors.php:134 +msgid "Casual" +msgstr "Przygodnie" + +#: ../../include/selectors.php:134 +msgid "Engaged" +msgstr "Zaręczony/Zaręczona" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Married" +msgstr "Zaślubiony/Zaślubiona" + +#: ../../include/selectors.php:134 +msgid "Imaginarily married" +msgstr "Zaślubiony/Zaślubiona w myślach" + +#: ../../include/selectors.php:134 +msgid "Partners" +msgstr "Patner/Partnerka" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Cohabiting" +msgstr "Konkubent/Konkubina" + +#: ../../include/selectors.php:134 +msgid "Common law" +msgstr "Prawo zwyczajowe" + +#: ../../include/selectors.php:134 +msgid "Happy" +msgstr "Szczęsliwy/Szczęśliwa" + +#: ../../include/selectors.php:134 +msgid "Not looking" +msgstr "Nie szukający/Nie szukająca" + +#: ../../include/selectors.php:134 +msgid "Swinger" +msgstr "Swinger" + +#: ../../include/selectors.php:134 +msgid "Betrayed" +msgstr "Zdradzony/Zdradzona" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Separated" +msgstr "W separacji" + +#: ../../include/selectors.php:134 +msgid "Unstable" +msgstr "Niestabilny/Niestabilna" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Divorced" +msgstr "Rozwiedziony/Rozwiedziona" + +#: ../../include/selectors.php:134 +msgid "Imaginarily divorced" +msgstr "Rozwiedziony/Rozwiedziona w myślach" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Widowed" +msgstr "Wdowiec/Wdowa" + +#: ../../include/selectors.php:134 +msgid "Uncertain" +msgstr "Niezdecydowany/Niezdecydowana" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "It's complicated" +msgstr "To skomplikowane" + +#: ../../include/selectors.php:134 +msgid "Don't care" +msgstr "Nie obchodzi mnie to" + +#: ../../include/selectors.php:134 +msgid "Ask me" +msgstr "Zapytaj mnie" + +#: ../../include/network.php:1731 ../../include/network.php:1732 +msgid "Friendica" +msgstr "Friendica" + +#: ../../include/network.php:1733 +msgid "OStatus" +msgstr "OStatus" + +#: ../../include/network.php:1734 +msgid "GNU-Social" +msgstr "GNU-Social" + +#: ../../include/network.php:1735 +msgid "RSS/Atom" +msgstr "RSS/Atom" + +#: ../../include/network.php:1738 +msgid "Diaspora" +msgstr "Diaspora" + +#: ../../include/network.php:1739 +msgid "Facebook" +msgstr "Facebook" + +#: ../../include/network.php:1740 +msgid "Zot" +msgstr "Zot" + +#: ../../include/network.php:1741 +msgid "LinkedIn" +msgstr "LinkedIn" + +#: ../../include/network.php:1742 +msgid "XMPP/IM" +msgstr "XMPP/IM" + +#: ../../include/network.php:1743 +msgid "MySpace" +msgstr "MySpace" + +#: ../../include/account.php:36 +msgid "Not a valid email address" +msgstr "Nieprawidłowy adres e-mail" + +#: ../../include/account.php:38 +msgid "Your email domain is not among those allowed on this site" +msgstr "Twoja domena e-mail nie należy do domen dozwolonych w tym serwisie" + +#: ../../include/account.php:44 +msgid "Your email address is already registered at this site." +msgstr "Twój adres e-mail jest już zarejestrowany w tym serwisie." + +#: ../../include/account.php:76 +msgid "An invitation is required." +msgstr "Wymagane jest zaproszenie." + +#: ../../include/account.php:80 +msgid "Invitation could not be verified." +msgstr "Nie udało się zweryfikować zaproszenia." + +#: ../../include/account.php:156 +msgid "Please enter the required information." +msgstr "Proszę wprowadzić wymagane informacje." + +#: ../../include/account.php:223 +msgid "Failed to store account information." +msgstr "Nie udało się zapisać informacji o koncie." + +#: ../../include/account.php:311 +#, php-format +msgid "Registration confirmation for %s" +msgstr "Potwierdzenie rejestracji dla %s" + +#: ../../include/account.php:380 +#, php-format +msgid "Registration request at %s" +msgstr "Wniosek o rejestrację na %s" + +#: ../../include/account.php:402 +msgid "your registration password" +msgstr "hasło rejestracyjne" + +#: ../../include/account.php:408 ../../include/account.php:471 +#, php-format +msgid "Registration details for %s" +msgstr "Szczegóły rejestracji dla %s" + +#: ../../include/account.php:482 +msgid "Account approved." +msgstr "Konto zostało zatwierdzone." + +#: ../../include/account.php:522 +#, php-format +msgid "Registration revoked for %s" +msgstr "Rejestracja cofnięta dla %s" + +#: ../../include/account.php:805 ../../include/account.php:807 +msgid "Click here to upgrade." +msgstr "Kliknij tutaj, aby zaktualizować." + +#: ../../include/account.php:813 +msgid "This action exceeds the limits set by your subscription plan." +msgstr "Ta czynność wykracza poza limity określone w planie subskrypcji." + +#: ../../include/account.php:818 +msgid "This action is not available under your subscription plan." +msgstr "Ta czynność nie jest dostępna w ramach Twojego planu subskrypcji." + +#: ../../include/help.php:80 +msgid "Help:" +msgstr "Pomoc:" + +#: ../../include/help.php:129 +msgid "Not Found" +msgstr "Nie znaleziono" + +#: ../../include/attach.php:273 ../../include/attach.php:324 +#: ../../include/attach.php:419 +msgid "Item was not found." +msgstr "Nie znaleziono elementu." + +#: ../../include/attach.php:290 +msgid "Unknown error." +msgstr "Nieznany błąd." + +#: ../../include/attach.php:612 +msgid "No source file." +msgstr "Brak pliku źródłowego." + +#: ../../include/attach.php:634 +msgid "Cannot locate file to replace" +msgstr "Nie można znaleźć pliku do zastąpienia" + +#: ../../include/attach.php:653 +msgid "Cannot locate file to revise/update" +msgstr "Nie można zlokalizować pliku do poprawienia/aktualizacji" + +#: ../../include/attach.php:795 +#, php-format +msgid "File exceeds size limit of %d" +msgstr "Plik przekracza limit rozmiaru %d" + +#: ../../include/attach.php:816 +#, php-format +msgid "You have reached your limit of %1$.0f Mbytes attachment storage." +msgstr "Osiągnęty został limit %1$.0f MB miejsca na załączniki." + +#: ../../include/attach.php:1004 +msgid "File upload failed. Possible system limit or action terminated." +msgstr "" +"Przesyłanie pliku nie powiodło się. Możliwe ograniczenie systemowe lub " +"działanie zakończone." + +#: ../../include/attach.php:1033 +msgid "Stored file could not be verified. Upload failed." +msgstr "Nie można zweryfikować zapisanego pliku. Przesyłanie nie powiodło się." + +#: ../../include/attach.php:1105 ../../include/attach.php:1121 +msgid "Path not available." +msgstr "Ścieżka niedostępna." + +#: ../../include/attach.php:1169 ../../include/attach.php:1332 +msgid "Empty pathname" +msgstr "Pusta ścieżka" + +#: ../../include/attach.php:1195 +msgid "duplicate filename or path" +msgstr "zduplikowana nazwa pliku lub ścieżka" + +#: ../../include/attach.php:1220 +msgid "Path not found." +msgstr "Ścieżka nie znaleziona." + +#: ../../include/attach.php:1288 +msgid "mkdir failed." +msgstr "mkdir zakończył sie błędem." + +#: ../../include/attach.php:1292 +msgid "database storage failed." +msgstr "zapis w bazie danych nie powiódł się." + +#: ../../include/attach.php:1338 +msgid "Empty path" +msgstr "Pusta ścieżka" + +#: ../../include/attach.php:2099 +#, php-format +msgid "%s shared a %s with you" +msgstr "%s udostępnił Ci %s" + +#: ../../include/attach.php:2099 +#: ../../extend/addon/hzaddons/redfiles/redfilehelper.php:64 +msgid "file" +msgstr "plik" + +#: ../../include/connections.php:134 +msgid "New window" +msgstr "Nowe okno" + +#: ../../include/connections.php:135 +msgid "Open the selected location in a different window or browser tab" +msgstr "Otwórz wybraną lokalizację w innym oknie lub karcie przeglądarki" + +#: ../../include/connections.php:736 ../../include/event.php:1424 +msgid "Home, Voice" +msgstr "Dom, głosowy" + +#: ../../include/connections.php:737 ../../include/event.php:1425 +msgid "Home, Fax" +msgstr "Dom, fax" + +#: ../../include/connections.php:739 ../../include/event.php:1427 +msgid "Work, Voice" +msgstr "Praca, głosowy" + +#: ../../include/connections.php:740 ../../include/event.php:1428 +msgid "Work, Fax" +msgstr "Praca, fax" + +#: ../../include/oembed.php:153 +msgid "View PDF" +msgstr "Wyświetl PDF" + +#: ../../include/oembed.php:357 +msgid " by " +msgstr " przez " + +#: ../../include/oembed.php:358 +msgid " on " +msgstr " na " + +#: ../../include/oembed.php:387 +msgid "Embedded content" +msgstr "Osadzone treści" + +#: ../../include/oembed.php:396 +msgid "Embedding disabled" +msgstr "Osadzanie wyłączone" + +#: ../../include/event.php:33 ../../include/event.php:110 +msgid "l F d, Y \\@ g:i A" +msgstr "l F d, Y \\@ g:i A" + +#: ../../include/event.php:41 +msgid "Starts:" +msgstr "Rozpoczętych:" + +#: ../../include/event.php:51 +msgid "Finishes:" +msgstr "Zakończonych:" + +#: ../../include/event.php:110 +msgid "l F d, Y" +msgstr "l F d, Y" + +#: ../../include/event.php:114 +msgid "Start:" +msgstr "Rozpoczęto:" + +#: ../../include/event.php:118 +msgid "End:" +msgstr "Zakończono:" + +#: ../../include/event.php:123 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:67 +msgid "Timezone" +msgstr "Strefa czasowa" + +#: ../../include/event.php:1106 +msgid "This event has been added to your calendar." +msgstr "To wydarzenie zostało dodane do Twojego kalendarza." + +#: ../../include/event.php:1337 +msgid "Not specified" +msgstr "Nieokreślone" + +#: ../../include/event.php:1338 +msgid "Needs Action" +msgstr "Wymaga działania" + +#: ../../include/event.php:1339 +msgid "Completed" +msgstr "Zakończone" + +#: ../../include/event.php:1340 +msgid "In Process" +msgstr "W trakcie" + +#: ../../include/event.php:1341 +msgid "Cancelled" +msgstr "Usuniete" + +#: ../../include/datetime.php:140 +msgid "Birthday" +msgstr "Urodziny" + +#: ../../include/datetime.php:140 +msgid "Age: " +msgstr "Wiek: " + +#: ../../include/datetime.php:140 +msgid "YYYY-MM-DD or MM-DD" +msgstr "RRRR-MM-DD lub MM-DD" + +#: ../../include/datetime.php:238 ../../boot.php:2709 +msgid "never" +msgstr "nigdy" + +#: ../../include/datetime.php:244 +msgid "less than a second ago" +msgstr "mniej niż sekundę temu" + +#: ../../include/datetime.php:262 +#, php-format +msgctxt "e.g. 22 hours ago, 1 minute ago" +msgid "%1$d %2$s ago" +msgstr "%1$d %2$s temu" + +#: ../../include/datetime.php:273 +msgctxt "relative_date" +msgid "year" +msgid_plural "years" +msgstr[0] "rok" +msgstr[1] "lata" +msgstr[2] "lat" + +#: ../../include/datetime.php:276 +msgctxt "relative_date" +msgid "month" +msgid_plural "months" +msgstr[0] "miesiąc" +msgstr[1] "miesiące" +msgstr[2] "miesięcy" + +#: ../../include/datetime.php:279 +msgctxt "relative_date" +msgid "week" +msgid_plural "weeks" +msgstr[0] "tydzień" +msgstr[1] "tygodnie" +msgstr[2] "tygodni" + +#: ../../include/datetime.php:282 +msgctxt "relative_date" +msgid "day" +msgid_plural "days" +msgstr[0] "dzień" +msgstr[1] "dni" +msgstr[2] "dni" + +#: ../../include/datetime.php:285 +msgctxt "relative_date" +msgid "hour" +msgid_plural "hours" +msgstr[0] "godzina" +msgstr[1] "godziny" +msgstr[2] "godzin" + +#: ../../include/datetime.php:288 +msgctxt "relative_date" +msgid "minute" +msgid_plural "minutes" +msgstr[0] "minuta" +msgstr[1] "minuty" +msgstr[2] "minut" + +#: ../../include/datetime.php:291 +msgctxt "relative_date" +msgid "second" +msgid_plural "seconds" +msgstr[0] "sekunda" +msgstr[1] "sekundy" +msgstr[2] "sekund" + +#: ../../include/datetime.php:520 +#, php-format +msgid "%1$s's birthday" +msgstr "urodziny %1$s" + +#: ../../include/datetime.php:521 +#, php-format +msgid "Happy Birthday %1$s" +msgstr "%1$s, wszystkiego najlepszego z okazji urodzin" + +#: ../../include/items.php:999 ../../include/items.php:1059 +msgid "(Unknown)" +msgstr "(Nieznane)" + +#: ../../include/items.php:1247 +msgid "Visible to anybody on the internet." +msgstr "Widoczne dla każdego w internecie." + +#: ../../include/items.php:1249 +msgid "Visible to you only." +msgstr "Widoczne tylko dla Ciebie." + +#: ../../include/items.php:1251 +msgid "Visible to anybody in this network." +msgstr "Widoczne dla każdego w tej sieci." + +#: ../../include/items.php:1253 +msgid "Visible to anybody authenticated." +msgstr "Widoczne dla każdego uwierzytelnionego." + +#: ../../include/items.php:1255 +#, php-format +msgid "Visible to anybody on %s." +msgstr "Widoczne dla wszystkich na %s." + +#: ../../include/items.php:1257 +msgid "Visible to all connections." +msgstr "Widoczny dla wszystkich połączeń." + +#: ../../include/items.php:1259 +msgid "Visible to approved connections." +msgstr "Widoczny dla zatwierdzonych połączeń." + +#: ../../include/items.php:1261 +msgid "Visible to specific connections." +msgstr "Widoczny dla określonych połączeń." + +#: ../../include/items.php:4507 +msgid "Privacy group is empty." +msgstr "Grupa prywatności jest pusta." + +#: ../../include/items.php:4514 +#, php-format +msgid "Privacy group: %s" +msgstr "Grupa prywatności: %s" + +#: ../../include/items.php:4526 +msgid "Connection not found." +msgstr "Nie znaleziono połączenia." + +#: ../../include/items.php:4867 +msgid "profile photo" +msgstr "zdjęcie profilowe" + +#: ../../include/items.php:5059 +#, php-format +msgid "[Edited %s]" +msgstr "[Edytowane %s]" + +#: ../../include/items.php:5059 +msgctxt "edit_activity" +msgid "Post" +msgstr "Post" + +#: ../../include/items.php:5059 +msgctxt "edit_activity" +msgid "Comment" +msgstr "Komentarz" + +#: ../../include/follow.php:84 +msgid "Response from remote channel was incomplete." +msgstr "Odpowiedź z kanału zdalnego była niekompletna." + +#: ../../include/follow.php:96 +msgid "Premium channel - please visit:" +msgstr "Kanał premium - odwiedź:" + +#: ../../include/follow.php:110 +msgid "Channel was deleted and no longer exists." +msgstr "Kanał został usunięty i już nie istnieje." + +#: ../../include/zot.php:775 +msgid "Invalid data packet" +msgstr "Nieprawidłowy pakiet danych" + +#: ../../include/zot.php:4372 +msgid "invalid target signature" +msgstr "nieprawidłowy podpis docelowy" + +#: ../../include/bbcode.php:221 ../../include/bbcode.php:896 +#: ../../include/bbcode.php:1486 ../../include/bbcode.php:1494 +msgid "Image/photo" +msgstr "Obraz/zdjęcie" + +#: ../../include/bbcode.php:268 ../../include/bbcode.php:1511 +msgid "Encrypted content" +msgstr "Zaszyfrowana treść" + +#: ../../include/bbcode.php:302 +#, php-format +msgid "Install %1$s element %2$s" +msgstr "Zainstaluj element %1$s %2$s" + +#: ../../include/bbcode.php:306 +#, php-format +msgid "" +"This post contains an installable %s element, however you lack permissions " +"to install it on this site." +msgstr "" +"Ten post zawiera możliwy do zainstalowania element %s, jednak nie masz " +"uprawnień do zainstalowania go w tym serwisie." + +#: ../../include/bbcode.php:519 +msgid "card" +msgstr "karta" + +#: ../../include/bbcode.php:521 +msgid "article" +msgstr "artykuł" + +#: ../../include/bbcode.php:604 ../../include/bbcode.php:612 +msgid "Click to open/close" +msgstr "Kliknij, any otworzyć/zamknąć" + +#: ../../include/bbcode.php:625 +msgid "View article" +msgstr "Wyświetl artykuł" + +#: ../../include/bbcode.php:625 +msgid "View summary" +msgstr "Wyświetl podsumowanie" + +#: ../../include/bbcode.php:1474 +msgid "$1 wrote:" +msgstr "$1 napisał:" + +#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:451 +msgid "Follow" +msgstr "Obserwuj" + +#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:454 +#, php-format +msgid "%1$s is now following %2$s" +msgstr "%1$s obserwujesz teraz %2$s" + +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:16 +msgid "" +"The GNU-Social protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." +msgstr "" +"Protokół GNU-Social nie obsługuje niezależności od lokalizacji. Połączenia " +"nawiązane w tej sieci mogą być niedostępne z innych lokalizacji kanałów." + +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22 +msgid "GNU-Social Protocol App" +msgstr "Aplikacja Protokół GNU-Social" + +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:34 +msgid "GNU-Social Protocol" +msgstr "GNU-Social Protocol" + +#: ../../extend/addon/hzaddons/qrator/qrator.php:48 +msgid "QR code" +msgstr "Kod QR" + +#: ../../extend/addon/hzaddons/qrator/qrator.php:63 +msgid "QR Generator" +msgstr "Generator QR" + +#: ../../extend/addon/hzaddons/qrator/qrator.php:64 +msgid "Enter some text" +msgstr "Wprowadź jakiś tekst" + +#: ../../extend/addon/hzaddons/irc/Mod_Irc.php:23 +#: ../../extend/addon/hzaddons/irc/irc.php:41 +msgid "Popular Channels" +msgstr "Popularne kanały" + +#: ../../extend/addon/hzaddons/irc/irc.php:37 +msgid "Channels to auto connect" +msgstr "Kanały do automatycznego podłączenia" + +#: ../../extend/addon/hzaddons/irc/irc.php:37 +#: ../../extend/addon/hzaddons/irc/irc.php:41 +msgid "Comma separated list" +msgstr "Lista rozdzielana przecinkami" + +#: ../../extend/addon/hzaddons/irc/irc.php:45 +msgid "IRC Settings" +msgstr "Ustawienia IRC" + +#: ../../extend/addon/hzaddons/irc/irc.php:54 +msgid "IRC settings saved." +msgstr "Zapisano ustawienia IRC." + +#: ../../extend/addon/hzaddons/irc/irc.php:58 +msgid "IRC Chatroom" +msgstr "Pokój rozmów IRC" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:19 +msgid "Send email to all members" +msgstr "Wyślij e-mail do wszystkich członków" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:50 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:50 +msgid "No recipients found." +msgstr "Nie znaleziono adresatów." + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:73 +#, php-format +msgid "%1$d of %2$d messages sent." +msgstr "Wysłano %1$d wiadomości z %2$d zadysponowanych." + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:81 +msgid "Send email to all hub members." +msgstr "Wyślij wiadomość e-mail do wszystkich członków huba." + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:92 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:96 +msgid "Message subject" +msgstr "Temat wiadomości" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:93 +msgid "Sender Email address" +msgstr "Adres e-mail nadawcy" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:94 +msgid "Test mode (only send to hub administrator)" +msgstr "Tryb testowy (wysyłaj tylko do administratora huba)" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:51 +msgid "Your Webbie:" +msgstr "Twój Webbie:" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:54 +msgid "Fontsize (px):" +msgstr "Wielkość czcionki (px):" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:68 +msgid "Link:" +msgstr "Link:" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:70 +msgid "Like us on Hubzilla" +msgstr "Polub nas na Hubzilli" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:72 +msgid "Embed:" +msgstr "Osadzone:" + +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:46 +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:43 +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:150 +msgid "Save Settings" +msgstr "Zapisz ustawienia" + +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:47 +msgid "text to include in all outgoing posts from this site" +msgstr "tekst do umieszczania we wszystkich postach wychodzących z tej witryny" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:19 +msgid "lonely" +msgstr "samotny" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:20 +msgid "drunk" +msgstr "pijany" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:21 +msgid "horny" +msgstr "seksualnie podniecony" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:22 +msgid "stoned" +msgstr "zjarany" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:23 +msgid "fucked up" +msgstr "spieprzone" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:24 +msgid "clusterfucked" +msgstr "klasterfucked" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:25 +msgid "crazy" +msgstr "zwariowany" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:26 +msgid "hurt" +msgstr "ból" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:27 +msgid "sleepy" +msgstr "senny" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:28 +msgid "grumpy" +msgstr "gderliwy" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:29 +msgid "high" +msgstr "wysoki" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:30 +msgid "semi-conscious" +msgstr "półprzytomny" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:31 +msgid "in love" +msgstr "zakochany" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:32 +msgid "in lust" +msgstr "w pożądaniu" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:33 +msgid "naked" +msgstr "nagi" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:34 +msgid "stinky" +msgstr "śmierdzący" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:35 +msgid "sweaty" +msgstr "spocony" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:36 +msgid "bleeding out" +msgstr "wykrwawiać się" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:37 +msgid "victorious" +msgstr "zwycięski" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:38 +msgid "defeated" +msgstr "pokonany" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:39 +msgid "envious" +msgstr "zazdrosny" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:40 +msgid "jealous" +msgstr "zazdrosny" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:85 +msgid "" +"This website is tracked using the Piwik " +"analytics tool." +msgstr "" +"Ta witryna jest śledzona za pomocą narzędzia analitycznego Piwik." + +#: ../../extend/addon/hzaddons/piwik/piwik.php:88 +#, php-format +msgid "" +"If you do not want that your visits are logged this way you can " +"set a cookie to prevent Piwik from tracking further visits of the site " +"(opt-out)." +msgstr "" +"Jeśli nie chcesz, aby Twoje wizyty były rejestrowane w ten sposób, możesz ustawić plik cookie, aby uniemożliwić Piwik śledzenie " +"dalszych wizyt na stronie (rezygnacja)." + +#: ../../extend/addon/hzaddons/piwik/piwik.php:96 +msgid "Piwik Base URL" +msgstr "Bazowy adres URL Piwik" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:96 +msgid "" +"Absolute path to your Piwik installation. (without protocol (http/s), with " +"trailing slash)" +msgstr "" +"Absolutna ścieżka do instalacji Piwika. (bez protokołu (http/s), z końcowym " +"ukośnikiem)" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:97 +msgid "Site ID" +msgstr "ID witryny" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:98 +msgid "Show opt-out cookie link?" +msgstr "Pokazać link do rezygnacji z pliku cookie?" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:99 +msgid "Asynchronous tracking" +msgstr "Śledzenie asynchroniczne" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:100 +msgid "Enable frontend JavaScript error tracking" +msgstr "Włącz śledzenie błędów JavaScript w interfejsie użytkownika" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:100 +msgid "This feature requires Piwik >= 2.2.0" +msgstr "Ta funkcjonalność wymaga Piwik >= 2.2.0" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:101 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:102 +#: ../../extend/addon/hzaddons/cart/myshop.php:144 +#: ../../extend/addon/hzaddons/cart/myshop.php:180 +#: ../../extend/addon/hzaddons/cart/myshop.php:214 +#: ../../extend/addon/hzaddons/cart/myshop.php:261 +#: ../../extend/addon/hzaddons/cart/myshop.php:296 +#: ../../extend/addon/hzaddons/cart/myshop.php:319 +msgid "Access Denied" +msgstr "Dostęp zabroniony" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:109 +msgid "Enable Community Moderation" +msgstr "Włącz moderację społecznościową" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:117 +msgid "Reputation automatically given to new members" +msgstr "Reputacja przyznawana automatycznie nowym członkom" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:118 +msgid "Reputation will never fall below this value" +msgstr "Reputacja nigdy nie spadnie poniżej tej wartości" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:119 +msgid "Minimum reputation before posting is allowed" +msgstr "Dozwolona jest minimalna reputacja przed rozpoczęciem postów" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:120 +msgid "Minimum reputation before commenting is allowed" +msgstr "Dozwolona jest minimalna reputacja przed rozpoczęciem komentowania" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:121 +msgid "Minimum reputation before a member is able to moderate other posts" +msgstr "Minimalna reputacja, zanim członek będzie mógł moderować inne posty" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:122 +msgid "" +"Max ratio of moderator's reputation that can be added to/deducted from " +"reputation of person being moderated" +msgstr "" +"Maksymalny współczynnik reputacji moderatora, który można dodać do reputacji " +"moderowanej osoby lub od niej odjąć" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:123 +msgid "Reputation \"cost\" to post" +msgstr "\"Koszt\" reputacji dla postu" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:124 +msgid "Reputation \"cost\" to comment" +msgstr "\"Koszt\" reputacji dla komentarza" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:125 +msgid "" +"Reputation automatically recovers at this rate per hour until it reaches " +"minimum_to_post" +msgstr "" +"Reputacja automatycznie odświeżana jest w tym tempie co godzinę, dopóki nie " +"osiągnie minimum_to_post" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:126 +msgid "" +"When minimum_to_moderate > reputation > minimum_to_post reputation recovers " +"at this rate per hour" +msgstr "" +"Kiedy minimum_to_moderate > reputation> minimum_to_post reputacja odświeża " +"na jest z taką szybkością na godzinę" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:140 +msgid "Community Moderation Settings" +msgstr "Ustawienia moderowania społecznościowego" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:232 +msgid "Channel Reputation" +msgstr "Reputacja kanału" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:236 +msgid "An Error has occurred." +msgstr "Wystąpił błąd." + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:254 +msgid "Upvote" +msgstr "Głosuj za" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:255 +msgid "Downvote" +msgstr "Głosuj przeciw" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:414 +msgid "Can moderate reputation on my channel." +msgstr "Mogę moderować reputację na moim kanale." + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:57 +msgid "Errors encountered deleting database table " +msgstr "Napotkano błędy podczas usuwania tabeli bazy danych " + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:95 +#: ../../extend/addon/hzaddons/twitter/twitter.php:503 +msgid "Submit Settings" +msgstr "Prześlij ustawienia" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96 +msgid "Drop tables when uninstalling?" +msgstr "Usunąć tabele podczas odinstalowywania?" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96 +msgid "" +"If checked, the Rendezvous database tables will be deleted when the plugin " +"is uninstalled." +msgstr "" +"Jeśli zaznaczone, po odinstalowaniu wtyczki zostaną usunięte wszystkie " +"tabele z bazy danych Rendezvous." + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97 +msgid "Mapbox Access Token" +msgstr "Token Mapbox Access" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97 +msgid "" +"If you enter a Mapbox access token, it will be used to retrieve map tiles " +"from Mapbox instead of the default OpenStreetMap tile server." +msgstr "" +"Jeśli wprowadzisz token dostępu Mapbox, będzie on używany do pobierania " +"fragmentów mapy z Mapbox, zamiast z domyślnego serwera kafelków " +"OpenStreetMap." + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:162 +msgid "Rendezvous" +msgstr "Rendezvous" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:167 +msgid "" +"This identity has been deleted by another member due to inactivity. Please " +"press the \"New identity\" button or refresh the page to register a new " +"identity. You may use the same name." +msgstr "" +"Ta tożsamość została usunięta przez innego członka z powodu braku " +"aktywności. Proszę nacisnąć przycisk \"Nowa tożsamość\" lub odświeżyć " +"stronę, aby zarejestrować nową tożsamość. Możesz użyć tej samej nazwy." + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:168 +msgid "Welcome to Rendezvous!" +msgstr "Witamy w Rendezvous!" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:169 +msgid "" +"Enter your name to join this rendezvous. To begin sharing your location with " +"the other members, tap the GPS control. When your location is discovered, a " +"red dot will appear and others will be able to see you on the map." +msgstr "" +"Wpisz swoje imię i nazwisko, aby dołączyć do tego spotkania. W celu " +"rozpoczęcia udostępniania swojej lokalizacji innym członkom, dotknij " +"elementu sterującego GPS. Gdy Twoja lokalizacja zostanie odkryta, pojawi się " +"czerwona kropka i inni będą mogli Cię zobaczyć na mapie." + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:171 +msgid "Let's meet here" +msgstr "Spotkajmy się tutaj" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:174 +msgid "New marker" +msgstr "Nowy znacznik" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:175 +msgid "Edit marker" +msgstr "Edytuj znacznik" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:176 +msgid "New identity" +msgstr "Nowa tożsamość" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:177 +msgid "Delete marker" +msgstr "Usuń znacznik" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:178 +msgid "Delete member" +msgstr "Usuń członka" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:179 +msgid "Edit proximity alert" +msgstr "Edytuj alert zbliżeniowy" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180 +msgid "" +"A proximity alert will be issued when this member is within a certain radius " +"of you.

      Enter a radius in meters (0 to disable):" +msgstr "" +"Alert zbliżeniowy zostanie wygenerowany, gdy ten członek znajdzie się w " +"określonym promieniu od Ciebie.

      Wprowadź promień w metrach (0, aby " +"wyłączyć):" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:185 +msgid "distance" +msgstr "odległość" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:181 +msgid "Proximity alert distance (meters)" +msgstr "Odległość ostrzeżenia o bliskości (metry)" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:182 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:184 +msgid "" +"A proximity alert will be issued when you are within a certain radius of the " +"marker location.

      Enter a radius in meters (0 to disable):" +msgstr "" +"Alert zbliżeniowy zostanie wygenerowany, gdy znajdziesz się w określonym " +"promieniu od lokalizacji znacznika.

      Wprowadź promień w metrach (0, " +"aby wyłączyć):" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:183 +msgid "Marker proximity alert" +msgstr "Ostrzeżenie o bliskości znacznika" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:186 +msgid "Reminder note" +msgstr "Notatka przypominająca" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:187 +msgid "" +"Enter a note to be displayed when you are within the specified proximity..." +msgstr "" +"Wprowadź notatkę, która będzie wyświetlana, gdy będziesz w określonej " +"odległości ..." + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:199 +msgid "Add new rendezvous" +msgstr "Dodaj nowe spotkanie" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:200 +msgid "" +"Create a new rendezvous and share the access link with those you wish to " +"invite to the group. Those who open the link become members of the " +"rendezvous. They can view other member locations, add markers to the map, or " +"share their own locations with the group." +msgstr "" +"Utwórz nowe spotkanie i udostępnij łącze dostępu tym, których chcesz " +"zaprosić do grupy. Osoby, które otworzą łącze, stają się członkami " +"spotkania. Mogą wyświetlać lokalizacje innych członków, dodawać znaczniki do " +"mapy lub udostępniać własne lokalizacje grupie." + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:232 +msgid "You have no rendezvous. Press the button above to create a rendezvous!" +msgstr "Nie masz spotkania. Naciśnij przycisk powyżej, aby utworzyć spotkanie!" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32 +msgid "Skeleton App" +msgstr "Aplikacja Szkielet" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:33 +msgid "A skeleton for addons, you can copy/paste" +msgstr "Szkielet dodatków, który można skopiować i wkleić" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40 +msgid "Some setting" +msgstr "Jakieś ustawienie" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40 +msgid "A setting" +msgstr "Ustawienie" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:48 +msgid "Skeleton Settings" +msgstr "Ustawienia Skeleton" + +#: ../../extend/addon/hzaddons/redred/redred.php:50 +msgid "Post to Hubzilla" +msgstr "Wyślij do Hubzilli" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:24 +msgid "Channel is required." +msgstr "Kanał jest wymagany." + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:38 +msgid "Hubzilla Crosspost Connector Settings saved." +msgstr "Ustawienia Hubzilla Crosspost Connector zostały zapisane." + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146 +msgid "Hubzilla Crosspost Connector App" +msgstr "Aplikacja Hubzilla Crosspost Connector" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:51 +msgid "Relay public postings to another Hubzilla channel" +msgstr "Przekaż publiczne posty na inny kanał Hubzilla" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +msgid "Send public postings to Hubzilla channel by default" +msgstr "Domyślnie wysyłaj publiczne posty na kanał Hubzilla" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67 +msgid "Hubzilla API Path" +msgstr "Ścieżka API Hubzilla" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53 +msgid "https://{sitename}/api" +msgstr "https://{sitename}/api" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71 +msgid "Hubzilla login name" +msgstr "Nazwa logowania Hubzilla" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75 +msgid "Hubzilla channel name" +msgstr "Nazwa kanału Hubzilla" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:54 +msgid "Nickname" +msgstr "Pseudonim" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:79 +msgid "Hubzilla password" +msgstr "Hasło Hubzilla" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:87 +msgid "Hubzilla Crosspost Connector" +msgstr "Hubzilla Crosspost Connector" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:23 +msgid "TOTP Two-Step Verification" +msgstr "Weryfikacja dwuetapowa TOTP" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:24 +msgid "Enter the 2-step verification generated by your authenticator app:" +msgstr "" +"Wprowadź dwuetapową weryfikację wygenerowaną przez aplikację " +"uwierzytelniającą:" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:25 +msgid "Success!" +msgstr "Powodzenie!" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:26 +msgid "Invalid code, please try again." +msgstr "Nieprawidłowy kod, proszę spróbować ponownie." + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:27 +msgid "Too many invalid codes..." +msgstr "Za dużo nieprawidłowych kodów ..." + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:28 +msgid "Verify" +msgstr "Zweryfikuj" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:90 +msgid "" +"You haven't set a TOTP secret yet.\n" +"Please click the button below to generate one and register this site\n" +"with your preferred authenticator app." +msgstr "" +"Nie ustawiłeś jeszcze sekretu TOTP.\n" +"Kliknij przycisk poniżej, aby to wygenerować i zarejestrować witrynę\n" +"w preferowanej aplikacji uwierzytelniającej." + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:93 +msgid "Your TOTP secret is" +msgstr "Twój sekret TOTP to" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:94 +msgid "" +"Be sure to save it somewhere in case you lose or replace your mobile " +"device.\n" +"Use your mobile device to scan the QR code below to register this site\n" +"with your preferred authenticator app." +msgstr "" +"Zapisz go gdzieś na wypadek zgubienia lub wymiany urządzenia mobilnego.\n" +"Użyj urządzenia mobilnego, aby zeskanować poniższy kod QR i zarejestrować tą " +"witrynę\n" +"w preferowanej aplikacji uwierzytelniającej." + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:99 +msgid "Test" +msgstr "Test" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:100 +msgid "Generate New Secret" +msgstr "Generowanie nowego sekretu" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:101 +msgid "Go" +msgstr "Idź dalej" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:102 +msgid "Enter your password" +msgstr "Wprowadź swoje hasło" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:103 +msgid "enter TOTP code from your device" +msgstr "wprowadź kod TOTP z urządzenia" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:104 +msgid "Pass!" +msgstr "Przeszło!" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:105 +msgid "Fail" +msgstr "Błąd" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:106 +msgid "Incorrect password, try again." +msgstr "Nieprawidłowe hasło, spróbuj ponownie." + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:107 +msgid "Record your new TOTP secret and rescan the QR code above." +msgstr "Zapisz swój nowy sekret TOTP i ponownie przeskanuj powyższy kod QR." + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:115 +msgid "TOTP Settings" +msgstr "Ustawienia TOTP" + +#: ../../extend/addon/hzaddons/testdrive/testdrive.php:104 +#, php-format +msgid "Your account on %s will expire in a few days." +msgstr "Twoje konto na %s wygaśnie za kilka dni." + +#: ../../extend/addon/hzaddons/testdrive/testdrive.php:105 +msgid "Your $Productname test account is about to expire." +msgstr "Twoje konto testowe $Productname wkrótce wygaśnie." + +#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:70 +msgid "An account has been created for you." +msgstr "Konto zostało dla Ciebie utworzone." + +#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:77 +msgid "Authentication successful but rejected: account creation is disabled." +msgstr "" +"Uwierzytelnianie przebiegło pomyślne, ale zostało odrzucone: tworzenie konta " +"jest wyłączone." + +#: ../../extend/addon/hzaddons/cart/cart.php:252 +msgid "DB Cleanup Failure" +msgstr "Błąd czyszczenia bazy danych" + +#: ../../extend/addon/hzaddons/cart/cart.php:674 +msgid "[cart] Item Added" +msgstr "[koszyk] Dodano element" + +#: ../../extend/addon/hzaddons/cart/cart.php:1063 +msgid "Order already checked out." +msgstr "Zamówienie już jest wyrejestrowane." + +#: ../../extend/addon/hzaddons/cart/cart.php:1368 +msgid "Drop database tables when uninstalling." +msgstr "Usuń tabele bazy danych podczas odinstalowywania." + +#: ../../extend/addon/hzaddons/cart/cart.php:1375 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:129 +msgid "Cart Settings" +msgstr "Ustawienia koszyka" + +#: ../../extend/addon/hzaddons/cart/cart.php:1387 +#: ../../extend/addon/hzaddons/cart/cart.php:1390 +msgid "Shop" +msgstr "Sklep" + +#: ../../extend/addon/hzaddons/cart/cart.php:1446 +#: ../../extend/addon/hzaddons/cart/myshop.php:112 +msgid "Order Not Found" +msgstr "Nie znaleziono zamówienia" + +#: ../../extend/addon/hzaddons/cart/cart.php:1507 +msgid "Cart utilities for orders and payments" +msgstr "Narzędzia koszyka do zamówień i płatności" + +#: ../../extend/addon/hzaddons/cart/cart.php:1545 +msgid "You must be logged into the Grid to shop." +msgstr "Aby robić zakupy, musisz być zalogowany do Siatki." + +#: ../../extend/addon/hzaddons/cart/cart.php:1578 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:409 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:392 +#: ../../extend/addon/hzaddons/cart/manual_payments.php:68 +msgid "Order not found." +msgstr "Nie znaleziono zamówienia." + +#: ../../extend/addon/hzaddons/cart/cart.php:1592 +msgid "Access denied." +msgstr "Dostęp zabroniony." + +#: ../../extend/addon/hzaddons/cart/cart.php:1644 +#: ../../extend/addon/hzaddons/cart/cart.php:1787 +msgid "No Order Found" +msgstr "Nie znaleziono zamówienia" + +#: ../../extend/addon/hzaddons/cart/cart.php:1653 +msgid "An unknown error has occurred Please start again." +msgstr "Wystąpił nieznany błąd. Zacznij od nowa." + +#: ../../extend/addon/hzaddons/cart/cart.php:1796 +msgid "Requirements not met." +msgstr "Nie spełnia wymagań." + +#: ../../extend/addon/hzaddons/cart/cart.php:1796 +msgid "Review your order and complete any needed requirements." +msgstr "Przejrzyj swoje zamówienie i spełnij wszystkie wymagania." + +#: ../../extend/addon/hzaddons/cart/cart.php:1822 +msgid "Invalid Payment Type. Please start again." +msgstr "Nieprawidłowy typ płatności. Zacznij od nowa." + +#: ../../extend/addon/hzaddons/cart/cart.php:1829 +msgid "Order not found" +msgstr "Nie znaleziono zamówienia" + +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:70 +msgid "Enable Order/Item Options" +msgstr "Włącz opcję Zamówienie/Element" + +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:333 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:357 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:433 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:457 +msgid "Label" +msgstr "Etykieta" + +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:336 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:360 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:436 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:460 +msgid "Instructions" +msgstr "Instukcje" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:63 +msgid "Enable Hubzilla Services Module" +msgstr "Włącz moduł usług Hubzilla" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:162 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:172 +msgid "New Sku" +msgstr "Nowy SKU" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:197 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:208 +msgid "Cannot save edits to locked item." +msgstr "Nie można zapisać zmian w zablokowanym elemencie." + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:246 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:333 +msgid "SKU not found." +msgstr "Nie znaleziono SKU." + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:299 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:303 +msgid "Invalid Activation Directive." +msgstr "Nieprawidłowa dyrektywa aktywacyjna." + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:374 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:378 +msgid "Invalid Deactivation Directive." +msgstr "Nieprawidłowa dyrektywa dezaktywacyjna." + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:564 +msgid "Add to this privacy group" +msgstr "Dodaj do tej grupy prywatności" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:580 +msgid "Set user service class" +msgstr "Ustaw klasę usług użytkownika" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:607 +msgid "You must be using a local account to purchase this service." +msgstr "Aby kupić tę usługę, musisz korzystać z konta lokalnego." + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:647 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:252 +msgid "Changes Locked" +msgstr "Zmiany zablokowane" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:651 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:256 +msgid "Item available for purchase." +msgstr "Element dostępny do zakupu." + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:658 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:263 +#: ../../extend/addon/hzaddons/cart/widgets/catalogitem.php:57 +msgid "Price" +msgstr "Cena" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:661 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:266 +msgid "Photo URL" +msgstr "Adres URL zdjęcia" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:665 +msgid "Add buyer to privacy group" +msgstr "Dodaj kupującego do grupy prywatności" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:670 +msgid "Add buyer as connection" +msgstr "Dodaj kupującego jako połączenie" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:678 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:720 +msgid "Set Service Class" +msgstr "Ustaw klasę usługi" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:151 +msgid "Enable Subscription Management Module" +msgstr "Włącz moduł zarządzania subskrypcjami" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:223 +msgid "" +"Cannot include subscription items with different terms in the same order." +msgstr "" +"Nie może zawierać elementów subskrypcji z różnymi terminami w tej samej " +"kolejności." + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:372 +msgid "Select Subscription to Edit" +msgstr "Wybierz subskrypcję do edycji" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:380 +msgid "Edit Subscriptions" +msgstr "Edytuj subskrypcje" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:414 +msgid "Subscription SKU" +msgstr "Subskrypcja SKU" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:419 +msgid "Catalog Description" +msgstr "Opis katalogu" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:423 +msgid "Subscription available for purchase." +msgstr "Subskrypcja dostępna do zakupu." + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:428 +msgid "Maximum active subscriptions to this item per account." +msgstr "Maksymalna liczba aktywnych subskrypcji tego elementu na konto." + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:431 +msgid "Subscription price." +msgstr "Cena subskrypcji." + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:435 +msgid "Quantity" +msgstr "Ilość" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:439 +msgid "Term" +msgstr "Termin" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:86 +msgid "Enable Paypal Button Module (API-v2)" +msgstr "Włącz moduł przycisków Paypal (API-v2)" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:94 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:93 +msgid "Use Production Key" +msgstr "Użyj klucza produkcyjnego" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:101 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:100 +msgid "Paypal Sandbox Client Key" +msgstr "Klucz klienta Paypal Sandbox" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:108 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:107 +msgid "Paypal Sandbox Secret Key" +msgstr "Tajny klucz Paypal Sandbox" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:114 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:113 +msgid "Paypal Production Client Key" +msgstr "Klucz klienta produkcyjny Paypal" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:121 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:120 +msgid "Paypal Production Secret Key" +msgstr "Tajny klucz produkcyjny Paypal" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:264 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:252 +msgid "Paypal button payments are not enabled." +msgstr "Płatności za pomocą przycisku PayPal nie są włączone." + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:282 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:270 +msgid "" +"Paypal button payments are not properly configured. Please choose another " +"payment option." +msgstr "" +"Płatności za pomocą przycisku PayPal nie są poprawnie skonfigurowane. " +"Wybierz inną opcję płatności." + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:85 +msgid "Enable Paypal Button Module" +msgstr "Włącz moduł przycisku Paypal" + +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:61 +msgid "Enable Manual Cart Module" +msgstr "Włącz moduł ręcznego koszyka" + +#: ../../extend/addon/hzaddons/cart/myshop.php:30 +msgid "Access Denied." +msgstr "Dostęp zabroniony." + +#: ../../extend/addon/hzaddons/cart/myshop.php:189 +#: ../../extend/addon/hzaddons/cart/myshop.php:223 +#: ../../extend/addon/hzaddons/cart/myshop.php:271 +#: ../../extend/addon/hzaddons/cart/myshop.php:329 +msgid "Invalid Item" +msgstr "Zła pozycja" + +#: ../../extend/addon/hzaddons/cart/manual_payments.php:7 +msgid "Error: order mismatch. Please try again." +msgstr "Błąd: niezgodność zamówienia. Proszę spróbuj ponownie." + +#: ../../extend/addon/hzaddons/cart/manual_payments.php:61 +msgid "Manual payments are not enabled." +msgstr "Płatności ręczne nie są włączone." + +#: ../../extend/addon/hzaddons/cart/manual_payments.php:77 +msgid "Finished" +msgstr "Zakończone" + +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:58 +msgid "Enable Test Catalog" +msgstr "Włącz katalog testów" + +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:70 +msgid "Enable Manual Payments" +msgstr "Włącz płatności ręczne" + +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:90 +msgid "Base Merchant Currency" +msgstr "Podstawowa waluta sprzedawcy" + +#: ../../extend/addon/hzaddons/openid/openid.php:49 +msgid "" +"We encountered a problem while logging in with the OpenID you provided. " +"Please check the correct spelling of the ID." +msgstr "" +"Napotkaliśmy problem podczas logowania za pomocą podanego przez Ciebie " +"identyfikatora OpenID. Sprawdź poprawną pisownię identyfikatora." + +#: ../../extend/addon/hzaddons/openid/openid.php:49 +msgid "The error message was:" +msgstr "Komunikat o błędzie brzmi:" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:52 +msgid "First Name" +msgstr "Imię" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:53 +msgid "Last Name" +msgstr "Nazwisko" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:55 +msgid "Full Name" +msgstr "Pełna nazwa" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:61 +msgid "Profile Photo 16px" +msgstr "Zdjęcie profilowe 16px" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:62 +msgid "Profile Photo 32px" +msgstr "Zdjęcie profilowe 32px" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:63 +msgid "Profile Photo 48px" +msgstr "Zdjęcie profilowe 48px" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:64 +msgid "Profile Photo 64px" +msgstr "Zdjęcie profilowe 64px" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:65 +msgid "Profile Photo 80px" +msgstr "Zdjęcie profilowe 80px" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:66 +msgid "Profile Photo 128px" +msgstr "Zdjęcie profilowe 128px" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:70 +msgid "Birth Year" +msgstr "Rok urodzenia" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:71 +msgid "Birth Month" +msgstr "Miesiąc urodzenia" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:72 +msgid "Birth Day" +msgstr "Dzień urodzenia" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:73 +msgid "Birthdate" +msgstr "Data urodzenia" + +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:30 +msgid "OpenID protocol error. No ID returned." +msgstr "Błąd protokołu OpenID. Brak identyfikatora." + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:81 +msgid "Hubzilla File Storage Import" +msgstr "Import z magazynu plików Hubzilla" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:82 +msgid "This will import all your cloud files from another server." +msgstr "" +"Spowoduje to zaimportowanie wszystkich plików w chmurze z innego huba " +"Hubzilla." + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:83 +msgid "Hubzilla Server base URL" +msgstr "Bazowy adres URL serwera Hubzilla" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:84 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:140 +msgid "Since modified date yyyy-mm-dd" +msgstr "Od daty modyfikacji rrrr-mm-dd" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:85 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:141 +msgid "Until modified date yyyy-mm-dd" +msgstr "Do daty modyfikacji rrrr-mm-dd" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:43 +msgid "Diaspora Protocol Settings updated." +msgstr "Zaktualizowano ustawienia protokołu Diaspora." + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:52 +msgid "" +"The diaspora protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." +msgstr "" +"Protokół Diaspora nie obsługuje niezależności lokalizacji. Połączenia " +"nawiązane w tej sieci mogą być niedostępne z innych lokalizacji kanałów." + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:58 +msgid "Diaspora Protocol App" +msgstr "Aplikacja Diaspora Protocol" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:75 +msgid "Allow any Diaspora member to comment on your public posts" +msgstr "Pozwól każdemu członkowi Diaspory komentować Twoje publiczne posty" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:79 +msgid "Prevent your hashtags from being redirected to other sites" +msgstr "Zapobiegaj przekierowywaniu hashtagów do innych witryn" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:83 +msgid "Sign and forward posts and comments with no existing Diaspora signature" +msgstr "Podpisuj i przesyłaj dalej posty i komentarze bez podpisu Diaspory" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:88 +msgid "Followed hashtags (comma separated, do not include the #)" +msgstr "Obserwowane hashtagi (oddzielone przecinkami, nie dodawaj #)" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:97 +msgid "Diaspora Protocol" +msgstr "Diaspora Protocol" + +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:19 +msgid "No username found in import file." +msgstr "W pliku importu nie znaleziono nazwy użytkownika." + +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1541 +#, php-format +msgid "%1$s dislikes %2$s's %3$s" +msgstr "%1$s desaprobat %2$s %3$s" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:66 +msgid "" +"Please install the statistics addon to be able to configure a diaspora relay" +msgstr "" +"Zainstaluj dodatek do statystyk, aby móc skonfigurować przekaźnik Diaspory" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:76 +msgid "Diaspora Relay Handle" +msgstr "Uchwyt przekaźnika Diaspory" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:76 +msgid "Address of a diaspora relay. Example: relay@diasporarelay.tld" +msgstr "Adres przekaźnika diaspory. Przykład: relay@diasporarelay.tld" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:96 +msgid "Diaspora relay could not be imported" +msgstr "Nie można zaimportować przekaźnika diaspory" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:94 +msgid "Hubzilla Directory Stats" +msgstr "Statystyki katalogowe Hubzilla" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:95 +msgid "Total Hubs" +msgstr "Razem huby" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:97 +msgid "Hubzilla Hubs" +msgstr "Huby Hubzilla" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:99 +msgid "Friendica Hubs" +msgstr "Huby Friendica" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:101 +msgid "Diaspora Pods" +msgstr "Pody Diaspora" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:103 +msgid "Hubzilla Channels" +msgstr "Kanały Hubzilla" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:105 +msgid "Friendica Channels" +msgstr "Kanały Friendica" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:107 +msgid "Diaspora Channels" +msgstr "Kanały Diaspora" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:109 +msgid "Aged 35 and above" +msgstr "W wieku 35 lat i więcej" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:111 +msgid "Aged 34 and under" +msgstr "W wieku 34 lat i poniżej" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:113 +msgid "Average Age" +msgstr "Średni wiek" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:115 +msgid "Known Chatrooms" +msgstr "Znane czaty" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:117 +msgid "Known Tags" +msgstr "Znane tagi" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:119 +msgid "" +"Please note Diaspora and Friendica statistics are merely those **this " +"directory** is aware of, and not all those known in the network. This also " +"applies to chatrooms," +msgstr "" +"Proszę mieć na uwadze, że statystyki Diaspory i Friendica to tylko te,które " +"są widoczne dla **tego katalogu**, a nie wszystkie znane w sieci. Dotyczy to " +"również czatów," + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:25 +msgid "Show Upload Limits" +msgstr "Pokaż limity przesyłania" + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:27 +msgid "Hubzilla configured maximum size: " +msgstr "Maksymalny rozmiar skonfigurowany w Hubzilli: " + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:28 +msgid "PHP upload_max_filesize: " +msgstr "PHP upload_max_filesize: " + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:29 +msgid "PHP post_max_size (must be larger than upload_max_filesize): " +msgstr "PHP post_max_size (musi być większe od upload_max_filesize): " + +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:23 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:27 +msgid "Hide Aside App" +msgstr "Aplikacja Hide Aside" + +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:24 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:28 +msgid "Fade out aside areas after a while when using endless scroll" +msgstr "Powoduje zanikanie obszaru po chwili, gdy używasz długiego przewijania" + +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:27 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26 +msgid "Installed" +msgstr "Zainstalowane" + +#: ../../extend/addon/hzaddons/randpost/randpost.php:97 +msgid "You're welcome." +msgstr "Proszę bardzo." + +#: ../../extend/addon/hzaddons/randpost/randpost.php:98 +msgid "Ah shucks..." +msgstr "O cholera ..." + +#: ../../extend/addon/hzaddons/randpost/randpost.php:99 +msgid "Don't mention it." +msgstr "Nie wspominaj o tym." + +#: ../../extend/addon/hzaddons/randpost/randpost.php:100 +msgid "<blush>" +msgstr "<rumieniec>" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:133 +msgid "View Larger" +msgstr "Zobacz większe" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:156 +msgid "Tile Server URL" +msgstr "Adres URL serwera kafelków rastrowych" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:156 +msgid "" +"A list of public tile servers" +msgstr "" +"Lista publicznych serwerów kafelków" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:157 +msgid "Nominatim (reverse geocoding) Server URL" +msgstr "Adres URL serwera Nominatim (odwrotne geokodowanie)" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:157 +msgid "" +"A list of Nominatim servers" +msgstr "" +"Lista serwerów Nominatim" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:158 +msgid "Default zoom" +msgstr "Powiększenie domyślne" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:158 +msgid "" +"The default zoom level. (1:world, 18:highest, also depends on tile server)" +msgstr "" +"Domyślny poziom powiększenia. (1: świat, 18: najwyższy, zależy również od " +"serwera kafelków)" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:159 +msgid "Include marker on map" +msgstr "Uwzględnij znacznik na mapie" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:159 +msgid "Include a marker on the map." +msgstr "Umieść znacznik na tej mapie." + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:38 +msgid "Livejournal Crosspost Connector App" +msgstr "Aplikacja Livejournal Crosspost Connector" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:39 +msgid "Relay public posts to Livejournal" +msgstr "Przekazuj publiczne posty do Livejournal" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:55 +msgid "Livejournal username" +msgstr "Nazwa użytkownika w Livejournal" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:59 +msgid "Livejournal password" +msgstr "Hasło do Livejournal" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +msgid "Post to Livejournal by default" +msgstr "Domyślnie wysyłaj do Livejournal" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +msgid "Send wall-to-wall posts to Livejournal" +msgstr "Wysyłaj posty \"wall-to-wall\" do Livejournal" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +msgid "Add link to original post" +msgstr "Dodaj odnośnik do oryginalnego postu" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:79 +msgid "Livejournal Crosspost Connector" +msgstr "Livejournal Crosspost Connector" + +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:49 +msgid "Post to Livejournal" +msgstr "Publikuj w Livejournal" + +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:127 +msgid "Posted by" +msgstr "Wysłane przez" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:222 +msgid "Workflow user." +msgstr "Przepływ pracy użytkownika." + +#: ../../extend/addon/hzaddons/workflow/workflow.php:272 +msgid "This channel" +msgstr "Ten kanał" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:541 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1437 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1456 +msgid "Workflow" +msgstr "Przepływ pracy" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:1425 +msgid "No Workflows Available" +msgstr "Żaden przepływ nie jest dostępny" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:1455 +msgid "Add item to which workflow" +msgstr "Dodaj element do przepływu pracy" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:1515 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1634 +msgid "Create Workflow Item" +msgstr "Utwórz element przepływu pracy" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2596 +msgid "Link" +msgstr "Link" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2598 +msgid "Web link." +msgstr "Link do strony internetowej." + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2619 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2680 +msgid "Brief description or title" +msgstr "Krótki opis lub tytuł" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2627 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2688 +msgid "Notes and Info" +msgstr "Uwagi i informacje" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2686 +msgid "Body" +msgstr "Ciało" + +#: ../../extend/addon/hzaddons/workflow/Settings/Mod_WorkflowSettings.php:101 +msgid "Workflow Settings" +msgstr "Ustawienia przepływu pracy" + +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:44 +msgid "Jabber BOSH host" +msgstr "Host Jabber BOSH" + +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45 +msgid "Use central userbase" +msgstr "Użyj centralnej bazy użytkowników" + +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45 +msgid "" +"If enabled, members will automatically login to an ejabberd server that has " +"to be installed on this machine with synchronized credentials via the " +"\"auth_ejabberd.php\" script." +msgstr "" +"Jeśli jest włączone, członkowie będą automatycznie logować się do serwera " +"ejabberd, który musi być zainstalowany na tym komputerze z " +"zsynchronizowanymi danymi uwierzytelniającymi za pośrednictwem skryptu " +"„auth_ejabberd.php”." + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:23 +msgid "XMPP settings updated." +msgstr "Zaktualizowano ustawienia XMPP." + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35 +msgid "XMPP App" +msgstr "Aplikacja XMPP" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:36 +msgid "Embedded XMPP (Jabber) client" +msgstr "Osadzony klient XMPP (Jabber)" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:52 +msgid "Individual credentials" +msgstr "Indywidualne poświadczenia" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:58 +msgid "Jabber BOSH server" +msgstr "Serwer Jabber BOSH" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:67 +msgid "XMPP Settings" +msgstr "Ustawienia XMPP" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20 +msgid "Superblock App" +msgstr "Aplikacja Superblock" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:21 +msgid "Block channels" +msgstr "Blokuj kanał" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:63 +msgid "superblock settings updated" +msgstr "zaktualizowano ustawienia superbloku" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:87 +msgid "Currently blocked" +msgstr "Obecnie zablokowane" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:89 +msgid "No channels currently blocked" +msgstr "Obecnie żadne kanały nie są zablokowane" + +#: ../../extend/addon/hzaddons/superblock/superblock.php:337 +msgid "Block Completely" +msgstr "Zablokuj całkowicie" + +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23 +msgid "Random Planet App" +msgstr "Aplikacja Random Planet" + +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:25 +msgid "" +"Set a random planet from the Star Wars Empire as your location when posting" +msgstr "" +"Podczas wysyłania ustaw, jako lokalizację, losową planetę z Imperium " +"Gwiezdnych Wojen" + +#: ../../extend/addon/hzaddons/nsfw/nsfw.php:152 +msgid "Possible adult content" +msgstr "Możliwe treści dla dorosłych" + +#: ../../extend/addon/hzaddons/nsfw/nsfw.php:167 +#, php-format +msgid "%s - view" +msgstr "%s - widok" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:22 +msgid "NSFW Settings saved." +msgstr "Zapisano ustawienia NSFW." + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33 +msgid "NSFW App" +msgstr "Aplikacja NSFW" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:34 +msgid "Collapse content that contains predefined words" +msgstr "Zwiń zawartość zawierającą predefiniowane słowa" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:44 +msgid "" +"This app looks in posts for the words/text you specify below, and collapses " +"any content containing those keywords so it is not displayed at " +"inappropriate times, such as sexual innuendo that may be improper in a work " +"setting. It is polite and recommended to tag any content containing nudity " +"with #NSFW. This filter can also match any other word/text you specify, and " +"can thereby be used as a general purpose content filter." +msgstr "" +"Ta aplikacja wyszukuje słowa lub tekst, określone poniżej i zwija wszelkie " +"treści zawierające te słowa kluczowe, aby nie były wyświetlane w " +"nieodpowiednich momentach, takich jak insynuacje seksualne, które mogą być " +"niewłaściwe w miejscu pracy. Grzecznie jest i zaleca się, oznaczanie " +"wszelkich treści zawierających nagość tagiem #NSFW. Ten filtr może również " +"pasować do dowolnego innego określonego słowa lub tekstu, dzięki czemu może " +"być używany jako filtr treści ogólnego przeznaczenia." + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49 +msgid "Comma separated list of keywords to hide" +msgstr "Lista słów kluczowych rozdzielona przecinkami" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49 +msgid "Word, /regular-expression/, lang=xx, lang!=xx" +msgstr "Słowo, /wyrażenie regularne/, lang=xx, lang!=xx" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:58 +msgid "NSFW" +msgstr "NSFW" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:21 +msgid "Three Dimensional Tic-Tac-Toe" +msgstr "Trójwymiarowy Tic-Tac-Toe" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:54 +msgid "3D Tic-Tac-Toe" +msgstr "3D Tic-Tac-Toe" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:59 +msgid "New game" +msgstr "Nowa gra" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:60 +msgid "New game with handicap" +msgstr "Nowa gra z handicapem" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:61 +msgid "" +"Three dimensional tic-tac-toe is just like the traditional game except that " +"it is played on multiple levels simultaneously. " +msgstr "" +"Trójwymiarowa gra w kółko i krzyżyk jest podobna do tradycyjnej gry, z tym " +"wyjątkiem, że gra się w nią na wielu poziomach jednocześnie. " + +#: ../../extend/addon/hzaddons/tictac/tictac.php:62 +msgid "" +"In this case there are three levels. You win by getting three in a row on " +"any level, as well as up, down, and diagonally across the different levels." +msgstr "" +"W tym przypadku są trzy poziomy. Wygrywasz, zdobywając trzy z rzędu na " +"dowolnym poziomie, a także w górę, w dół i po przekątnej na różnych " +"poziomach." + +#: ../../extend/addon/hzaddons/tictac/tictac.php:64 +msgid "" +"The handicap game disables the center position on the middle level because " +"the player claiming this square often has an unfair advantage." +msgstr "" +"Gra z handicapem wyłącza środkową pozycję na środkowym poziomie, ponieważ " +"gracz zajmujący to pole często ma nieuczciwą przewagę." + +#: ../../extend/addon/hzaddons/tictac/tictac.php:183 +msgid "You go first..." +msgstr "Ty pierwszy ..." + +#: ../../extend/addon/hzaddons/tictac/tictac.php:188 +msgid "I'm going first this time..." +msgstr "Tym razem idę pierwszy ..." + +#: ../../extend/addon/hzaddons/tictac/tictac.php:194 +msgid "You won!" +msgstr "Wygrałeś!" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:200 +#: ../../extend/addon/hzaddons/tictac/tictac.php:225 +msgid "\"Cat\" game!" +msgstr "Gra \"Kot\"!" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:223 +msgid "I won!" +msgstr "Wygrałem!" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:27 +msgid "Photo Cache settings saved." +msgstr "Zapisano ustawienia pamięci podręcznej zdjęć." + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:36 +msgid "" +"Photo Cache addon saves a copy of images from external sites locally to " +"increase your anonymity in the web." +msgstr "" +"Dodatek Photo Cache zapisuje lokalnie kopie obrazów z zewnętrznych witryn, " +"aby zwiększyć Twoją anonimowość w sieci." + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42 +msgid "Photo Cache App" +msgstr "Aplikacja Photo Cache" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:53 +msgid "Minimal photo size for caching" +msgstr "Minimalny rozmiar zdjęcia do buforowania" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:55 +msgid "In pixels. From 1 up to 1024, 0 will be replaced with system default." +msgstr "" +"W pikselach. Od 1 do 1024, 0 zostanie zastąpione domyślnymi ustawieniami " +"systemowymi." + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:64 +msgid "Photo Cache" +msgstr "Photo Cache" + +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:26 +#, php-format +msgctxt "opensearch" +msgid "Search %1$s (%2$s)" +msgstr "Szukaj %1$s (%2$s)" + +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:28 +msgctxt "opensearch" +msgid "$Projectname" +msgstr "Hubzilla" + +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:43 +msgid "Search $Projectname" +msgstr "Szukaj w Hubzilla" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:25 +msgid "Libertree Crosspost Connector Settings saved." +msgstr "Zapisano ustawienia Libertree Crosspost Connector." + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35 +msgid "Libertree Crosspost Connector App" +msgstr "Aplikacja Libertree Crosspost Connector" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:36 +msgid "Relay public posts to Libertree" +msgstr "Przekazuj publiczne posty do Libertree" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:51 +msgid "Libertree API token" +msgstr "Token API Libertree" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:55 +msgid "Libertree site URL" +msgstr "Adres URL witrny Libertree" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +msgid "Post to Libertree by default" +msgstr "Domyślnie publikuj w Libertree" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:67 +msgid "Libertree Crosspost Connector" +msgstr "Libertree Crosspost Connector" + +#: ../../extend/addon/hzaddons/libertree/libertree.php:43 +msgid "Post to Libertree" +msgstr "Publikuj w Libertree" + +#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:24 +msgid "Flag Adult Photos" +msgstr "Oznaczanie zdjęć dla dorosłych" + +#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:25 +msgid "" +"Provide photo edit option to hide inappropriate photos from default album " +"view" +msgstr "" +"Dostarcza opcję edycji zdjęć, umożliwiającą ukrywanie nieodpowiednich zdjęć " +"w domyślnym widoku albumu" + +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:145 +msgid "Post to GNU social" +msgstr "Publikuj w serwisie społecznościowym GNU" + +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:594 +msgid "API URL" +msgstr "Adres URL API" + +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:597 +msgid "Application name" +msgstr "Nazwa aplikacji" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:61 +msgid "" +"Please contact your site administrator.
      The provided API URL is not " +"valid." +msgstr "" +"Skontaktuj się z administratorem witryny.
      Podany adres URL interfejsu " +"API jest nieprawidłowy." + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:98 +msgid "We could not contact the GNU social API with the Path you entered." +msgstr "" +"Nie mogliśmy nawiązać połączenia ze społecznościowym API GNU o podanej " +"ścieżce." + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:130 +msgid "GNU social settings updated." +msgstr "Ustawienia społecznościowe GNU zostały zaktualizowane." + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:147 +msgid "" +"Relay public postings to a connected GNU social account (formerly StatusNet)" +msgstr "" +"Przekazywanie publicznych postów na połączone konto społecznościowe GNU " +"(dawniej StatusNet)" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:181 +msgid "Globally Available GNU social OAuthKeys" +msgstr "Globalnie dostępne klucze OAuthKey społecznościowe GNU" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:183 +msgid "" +"There are preconfigured OAuth key pairs for some GNU social servers " +"available. If you are using one of them, please use these credentials.
      If not feel free to connect to any other GNU social instance (see below)." +msgstr "" +"Dostępne są wstępnie skonfigurowane pary kluczy OAuth dla niektórych " +"serwerów społecznościowych GNU. Jeśli używasz jednego z nich, użyj tych " +"poświadczeń.
      Jeśli nie możesz połączyć się z inną instancją " +"społecznościową GNU (patrz poniżej)." + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:198 +msgid "Provide your own OAuth Credentials" +msgstr "Podaj własne dane logowania OAuth" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:200 +msgid "" +"No consumer key pair for GNU social found. Register your Hubzilla Account as " +"an desktop client on your GNU social account, copy the consumer key pair " +"here and enter the API base root.
      Before you register your own OAuth " +"key pair ask the administrator if there is already a key pair for this " +"Hubzilla installation at your favourite GNU social installation." +msgstr "" +"Nie znaleziono pary kluczy konsumenckich dla społeczności GNU. Zarejestruj " +"swoje konto Hubzilla jako klienta stacjonarnego na swoim koncie " +"społecznościowym GNU, skopiuj tutaj parę kluczy klienta i wprowadź " +"podstawowy katalog główny API.
      Przed zarejestrowaniem własnej pary " +"kluczy OAuth zapytaj administratora, czy istnieje już para kluczy dla tej " +"instalacji Hubzilli w Twojej ulubionej instalacji społecznościowej GNU." + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:204 +msgid "OAuth Consumer Key" +msgstr "Klucz klienta OAuth" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:208 +msgid "OAuth Consumer Secret" +msgstr "Tajny klucz klienta OAuth" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212 +msgid "Base API Path" +msgstr "Podstawowa ścieżka API" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212 +msgid "Remember the trailing /" +msgstr "Zapamiętaj końcowy ukośnik /" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:216 +msgid "GNU social application name" +msgstr "Nazwa aplikacji społecznościowej GNU" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:239 +msgid "" +"To connect to your GNU social account click the button below to get a " +"security code from GNU social which you have to copy into the input box " +"below and submit the form. Only your public posts will be " +"posted to GNU social." +msgstr "" +"W celu połączenia się ze swoim kontem społecznościowym GNU, kliknij poniższy " +"przycisk, aby uzyskać kod zabezpieczający z serwisu społecznościowego GNU, " +"który musisz skopiować do pola wprowadzania poniżej i przesłać formularz. " +"Tylko twoje publiczne posty będą publikowane w " +"społecznościach GNU." + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:241 +msgid "Log in with GNU social" +msgstr "Zaloguj się za pomocą serwisu społecznościowego GNU" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:244 +msgid "Copy the security code from GNU social here" +msgstr "Skopiuj tutaj kod bezpieczeństwa z GNU Social" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:254 +msgid "Cancel Connection Process" +msgstr "Anuluj proces łączenia" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:256 +msgid "Current GNU social API is" +msgstr "Obecne API społecznościowe GNU to" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +msgid "Cancel GNU social Connection" +msgstr "Anuluj połączenie społecznościowe GNU" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:272 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:147 +msgid "Currently connected to: " +msgstr "Obecnie połączony z: " + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:277 +msgid "" +"Note: Due your privacy settings (Hide your profile " +"details from unknown viewers?) the link potentially included in public " +"postings relayed to GNU social will lead the visitor to a blank page " +"informing the visitor that the access to your profile has been restricted." +msgstr "" +"Uwaga: Ze względu na Twoje ustawienia prywatności, odnośnik " +"(Ukryj szczegóły swojego profilu przed nieznanymi widzami? ), " +"ewentualnie zawarty w publicznych postach przekazywanych do społeczności " +"GNU, będzie kierował odwiedzającego na pustą stronę z informacją dla " +"odwiedzającego, że dostęp do Twojego profilu został ograniczony." + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +msgid "Post to GNU social by default" +msgstr "Wysyłaj domyślnie do społeczności GNU" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +msgid "" +"If enabled your public postings will be posted to the associated GNU-social " +"account by default" +msgstr "" +"Jeśli ta opcja jest włączona, twoje publiczne posty będą domyślnie wysyłane " +"na powiązane konto społecznościowe GNU" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +msgid "Clear OAuth configuration" +msgstr "Wyczyść konfigurację OAuth" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:303 +msgid "GNU-Social Crosspost Connector" +msgstr "GNU-Social Crosspost Connector" + +#: ../../extend/addon/hzaddons/wholikesme/wholikesme.php:29 +msgid "Who likes me?" +msgstr "Kto mnie lubi?" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:25 +msgid "ActivityPub Protocol Settings updated." +msgstr "Zaktualizowano ustawienia ActivityPub Protocol." + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:34 +msgid "" +"The activitypub protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." +msgstr "" +"Protokół AactivityPub nie obsługuje niezależności od lokalizacji. Połączenia " +"nawiązane w tej sieci mogą być niedostępne z innych lokalizacji kanałów." + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40 +msgid "Activitypub Protocol App" +msgstr "Aplikacja Activitypub Protocol" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50 +msgid "Deliver to ActivityPub recipients in privacy groups" +msgstr "Dostarcz do odbiorców ActivityPub w grupach prywatności" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50 +msgid "" +"May result in a large number of mentions and expose all the members of your " +"privacy group" +msgstr "" +"Może skutkować dużą liczbą wzmianek i ujawnieniem wszystkich członków Twojej " +"grupy prywatności" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54 +msgid "Send multi-media HTML articles" +msgstr "Wysyłaj multimedialne artykuły HTML" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54 +msgid "Not supported by some microblog services such as Mastodon" +msgstr "Nieobsługiwane przez niektóre usługi mikroblogów, takie jak Mastodon" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:62 +msgid "Activitypub Protocol" +msgstr "Activitypub Protocol" + +#: ../../extend/addon/hzaddons/ijpost/ijpost.php:44 +msgid "Post to Insane Journal" +msgstr "Publikuj w Insane Journal" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:23 +msgid "Insane Journal Crosspost Connector Settings saved." +msgstr "Zapisano ustawienia Insane Journal Crosspost Connector." + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35 +msgid "Insane Journal Crosspost Connector App" +msgstr "Aplikacja Insane Journal Crosspost Connector" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:36 +msgid "Relay public postings to Insane Journal" +msgstr "Przekaż publiczne posty do Insane Journal" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:53 +msgid "InsaneJournal username" +msgstr "Nazwa użytkownika InsaneJournal" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:57 +msgid "InsaneJournal password" +msgstr "Hasło InsaneJournal" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +msgid "Post to InsaneJournal by default" +msgstr "Domyślnie publikuj w InsaneJournal" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:69 +msgid "Insane Journal Crosspost Connector" +msgstr "Insane Journal Crosspost Connector" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:77 +msgid "Max queueworker threads" +msgstr "Maksymalna liczba wątków w kolejce" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:91 +msgid "Assume workers dead after ___ seconds" +msgstr "Załóż, że workery wygasają po ___ sekundach" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:105 +msgid "" +"Pause before starting next task: (microseconds. Minimum 100 = .0001 seconds)" +msgstr "" +"Wstrzymaj przed rozpoczęciem następnego zadania: (w mikrosekundach. Minimum " +"100 = .0001 sekund)" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:116 +msgid "Queueworker Settings" +msgstr "Ustawienia Queueworkera" + +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:218 +msgid "Not allowed." +msgstr "Niedozwolone." + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:123 +msgid "generic profile image" +msgstr "ogólne zdjęcie profilowe" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:124 +msgid "random geometric pattern" +msgstr "losowy wzór geometryczny" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:125 +msgid "monster face" +msgstr "twarz potwora" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:126 +msgid "computer generated face" +msgstr "wygenerowana komputerowo twarz" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:127 +msgid "retro arcade style face" +msgstr "twarz w stylu retro arcade" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:128 +msgid "Hub default profile photo" +msgstr "Domyślne zdjęcie profilowe huba" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143 +msgid "Information" +msgstr "Informacje" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143 +msgid "" +"Libravatar addon is installed, too. Please disable Libravatar addon or this " +"Gravatar addon.
      The Libravatar addon will fall back to Gravatar if " +"nothing was found at Libravatar." +msgstr "" +"Dodatek Libravatar jest również zainstalowany. Proszę wyłączyć dodatek " +"Libravatar lub ten dodatek Gravatar.
      Dodatek Libravatar wykorzysta " +"Gravatara, jeśli nic nie zostanie znalezione w bibliotece Libravatara." + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151 +msgid "Default avatar image" +msgstr "Domyślny obraz awatara" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151 +msgid "Select default avatar image if none was found at Gravatar. See README" +msgstr "" +"Wybierz domyślny obraz awatara, jeśli nic nie zostało znaleziony w " +"Gravatarze. Zobacz README" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152 +msgid "Rating of images" +msgstr "Ocena zdjęć" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152 +msgid "Select the appropriate avatar rating for your site. See README" +msgstr "Wybierz odpowiednią ocenę awatara dla swojej witryny. Zobacz README" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:165 +msgid "Gravatar settings updated." +msgstr "Zaktualizowano ustawienia Gravatara." + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:104 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:176 +msgid "Network error" +msgstr "Błąd sieci" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:108 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:180 +msgid "API error" +msgstr "Błąd API" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:112 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:184 +msgid "Unknown issue" +msgstr "Nieznany problem" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:168 +msgid "Unable to login using email address " +msgstr "Nie można zalogować się przy użyciu adresu e-mail " + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:202 +msgid "Sign in to Hubzilla using a social account" +msgstr "Zaloguj się do Hubzilli za pomocą konta społecznościowego" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:207 +msgid "Social Authentication using your social media account" +msgstr "" +"Uwierzytelnianie społecznościowe za pomocą konta w mediach społecznościowych" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:211 +msgid "" +"This app enables one or more social provider sign-in buttons on the login " +"page." +msgstr "" +"Ta aplikacja umożliwia korzystanie na stronie logowania z co najmniej " +"jednego przycisku logowania dostawcy usług społecznościowych." + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:229 +msgid "Add an identity provider" +msgstr "Dodaj dostawcę tożsamości" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:256 +msgid "Enable " +msgstr "Włącz " + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:263 +msgid "Key" +msgstr "Klucz" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:263 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:268 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:284 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:297 +msgid "Word" +msgstr "Słowo" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:268 +msgid "Secret" +msgstr "Sekret" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:297 +msgid "Add a custom provider" +msgstr "Dodaj własnego dostawcę" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:317 +msgid "Remove an identity provider" +msgstr "Usuń dostawcę tożsamości" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:327 +msgid "Social authentication" +msgstr "Uwierzytelnianie społecznościowe" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:366 +msgid "Error while saving provider settings" +msgstr "Błąd podczas zapisywania ustawień dostawcy" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:382 +msgid "Custom provider already exists" +msgstr "Własny dostawca już istnieje" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:399 +msgid "Social authentication settings saved." +msgstr "Zapisano ustawienia uwierzytelniania społecznościowego." + +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:14 +msgid "Send your identity to all websites" +msgstr "Wyślij swoją tożsamość do wszystkich witryn internetowych" + +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20 +msgid "Sendzid App" +msgstr "Aplikacja Sendzid" + +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:32 +msgid "Send ZID" +msgstr "Wyślij ZID" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:106 +msgid "Photos imported" +msgstr "Zdjęcia zaimportowane" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:129 +msgid "Redmatrix Photo Album Import" +msgstr "Import albumu fotograficznego Redmatrix" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:130 +msgid "This will import all your Redmatrix photo albums to this channel." +msgstr "" +"Spowoduje to zaimportowanie wszystkich albumów ze zdjęciami z Redmatrix do " +"tego kanału." + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:131 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:121 +msgid "Redmatrix Server base URL" +msgstr "Podstawowy adres URL serwera Redmatrix" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:132 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:122 +msgid "Redmatrix Login Username" +msgstr "Nazwa użytkownika logowania w Redmatrix" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:133 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:123 +msgid "Redmatrix Login Password" +msgstr "Hasło logowania do Redmatrix" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134 +msgid "Import just this album" +msgstr "Zaimportuj tylko ten album" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134 +msgid "Leave blank to import all albums" +msgstr "Pozostaw puste, aby zaimportować wszystkie albumy" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135 +msgid "Maximum count to import" +msgstr "Maksymalna liczba albumów do zaimportowania" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135 +msgid "0 or blank to import all available" +msgstr "0 lub puste, aby zaimportować wszystkie dostępne" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:65 +msgid "Twitter settings updated." +msgstr "Zaktualizowano ustawienia Twittera." + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78 +msgid "Twitter Crosspost Connector App" +msgstr "Aplikacja Twitter Crosspost Connector" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:79 +msgid "Relay public posts to Twitter" +msgstr "Przekazuj publiczne posty na Twitter" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:103 +msgid "" +"No consumer key pair for Twitter found. Please contact your site " +"administrator." +msgstr "" +"Nie znaleziono pary kluczy klienta dla Twittera. Skontaktuj się z " +"administratorem witryny." + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:125 +msgid "" +"At this Hubzilla instance the Twitter plugin was enabled but you have not " +"yet connected your account to your Twitter account. To do so click the " +"button below to get a PIN from Twitter which you have to copy into the input " +"box below and submit the form. Only your public posts will " +"be posted to Twitter." +msgstr "" +"W tej instancji Hubzilla wtyczka Twittera była włączona, ale nie połączyłeś " +"jeszcze swojego konta z kontem na Twitterze. Aby to zrobić, kliknij poniższy " +"przycisk, aby uzyskać kod PIN z Twittera, który należy skopiować do pola " +"wprowadzania poniżej i przesłać formularz. Na Twitterze będą publikowane " +"tylko Twoje publiczne posty." + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:127 +msgid "Log in with Twitter" +msgstr "Zaloguj się za pomocą Twittera" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:130 +msgid "Copy the PIN from Twitter here" +msgstr "Skopiuj tutaj PIN z Twittera" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:152 +msgid "" +"Note: Due your privacy settings (Hide your profile " +"details from unknown viewers?) the link potentially included in public " +"postings relayed to Twitter will lead the visitor to a blank page informing " +"the visitor that the access to your profile has been restricted." +msgstr "" +" Uwaga: Ze względu na Twoje ustawienia prywatności " +"(Ukryj szczegóły swojego profilu przed nieznanymi widzami?) ten " +"link, potencjalnie zawarty w publicznych postach przekazywanych do Twittera, " +"będzie prowadził odwiedzającego do pustej strony informującej gościa, że " +"dostęp do Twojego profilu został ograniczony." + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157 +msgid "Twitter post length" +msgstr "Długość postu na Twitterze" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157 +msgid "Maximum tweet length" +msgstr "Maksymalna długość tweeta" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +msgid "Send public postings to Twitter by default" +msgstr "Domyślnie wysyłaj publiczne posty na Twitter" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +msgid "" +"If enabled your public postings will be posted to the associated Twitter " +"account by default" +msgstr "" +"Jeśli ta opcja jest włączona, Twoje publiczne posty będą domyślnie " +"publikowane na powiązanym koncie Twittera" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:181 +msgid "Twitter Crosspost Connector" +msgstr "Twitter Crosspost Connector" + +#: ../../extend/addon/hzaddons/twitter/twitter.php:109 +msgid "Post to Twitter" +msgstr "Opublikuj na Twitterze" + +#: ../../extend/addon/hzaddons/donate/donate.php:21 +msgid "Project Servers and Resources" +msgstr "Serwery projektów i zasoby" + +#: ../../extend/addon/hzaddons/donate/donate.php:22 +msgid "Project Creator and Tech Lead" +msgstr "Twórca projektu i kierownik techniczny" + +#: ../../extend/addon/hzaddons/donate/donate.php:49 +msgid "" +"And the hundreds of other people and organisations who helped make the " +"Hubzilla possible." +msgstr "Oraz setki innych osób i organizacji, które pomogły stworzyć Hubzillę." + +#: ../../extend/addon/hzaddons/donate/donate.php:52 +msgid "" +"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving " +"their time and expertise - and often paying out of pocket for services they " +"share with others." +msgstr "" +"Projekty Redmatrix i Hubzilla są realizowane głównie przez wolontariuszy, " +"którzy poświęcają swój czas i wiedzę i często płacą z własnej kieszeni za " +"usługi, którymi dzielą się z innymi." + +#: ../../extend/addon/hzaddons/donate/donate.php:53 +msgid "" +"There is no corporate funding and no ads, and we do not collect and sell " +"your personal information. (We don't control your personal information - " +"you do.)" +msgstr "" +"Nie ma żadnych funduszy korporacyjnych ani reklam a my nie zbieramy i nie " +"sprzedajemy Twoich danych osobowych. (Nie kontrolujemy Twoich danych " +"osobowych - Ty tak )." + +#: ../../extend/addon/hzaddons/donate/donate.php:54 +msgid "" +"Help support our ground-breaking work in decentralisation, web identity, and " +"privacy." +msgstr "" +"Pomóż nam wspierać nasze przełomowe prace w zakresie decentralizacji, " +"tożsamości internetowej i prywatności." + +#: ../../extend/addon/hzaddons/donate/donate.php:56 +msgid "" +"Your donations keep servers and services running and also helps us to " +"provide innovative new features and continued development." +msgstr "" +"Twoje darowizny zapewniają nieprzerwane działanie serwerów i usług, a także " +"pomagają nam w zapewnianiu innowacyjnych nowych funkcji i ciągłym rozwoju." + +#: ../../extend/addon/hzaddons/donate/donate.php:59 +msgid "Donate" +msgstr "Wspomóż" + +#: ../../extend/addon/hzaddons/donate/donate.php:61 +msgid "" +"Choose a project, developer, or public hub to support with a one-time " +"donation" +msgstr "" +"Wybierz projekt, dewelopera lub publiczny hub, aby wesprzeć jednorazową " +"darowizną" + +#: ../../extend/addon/hzaddons/donate/donate.php:62 +msgid "Donate Now" +msgstr "Wpłać teraz" + +#: ../../extend/addon/hzaddons/donate/donate.php:63 +msgid "" +"Or become a project sponsor (Hubzilla Project only)" +msgstr "" +"lub zostań sponsorem projektu (tylko Projekt " +"Hubzilla)" + +#: ../../extend/addon/hzaddons/donate/donate.php:64 +msgid "" +"Please indicate if you would like your first name or full name (or nothing) " +"to appear in our sponsor listing" +msgstr "" +"Wskaż, czy chcesz, aby Twoje imię lub imię i nazwisko pojawiało się na " +"naszej liście sponsorów" + +#: ../../extend/addon/hzaddons/donate/donate.php:65 +msgid "Sponsor" +msgstr "Sponsor" + +#: ../../extend/addon/hzaddons/donate/donate.php:68 +msgid "Special thanks to: " +msgstr "Specjalne podziękowania dla: " + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:26 +msgid "Dreamwidth Crosspost Connector Settings saved." +msgstr "Zapisano ustawienia Dreamwidth Crosspost Connector." + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:39 +msgid "Dreamwidth Crosspost Connector App" +msgstr "Aplikacja Dreamwidth Crosspost Connector" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:40 +msgid "Relay public posts to Dreamwidth" +msgstr "Przekazuj publiczne posty do Dreamwidth" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:53 +msgid "Dreamwidth username" +msgstr "Nazwa użytkownika Dreamwidth" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:57 +msgid "Dreamwidth password" +msgstr "Hasło Dreamwidth" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +msgid "Post to Dreamwidth by default" +msgstr "Domyślnie publikuj na Dreamwidth" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:69 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:98 +msgid "Link description (default:" +msgstr "Opis odnośnika (domyślnie:" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:77 +msgid "Dreamwidth Crosspost Connector" +msgstr "Dreamwidth Crosspost Connector" + +#: ../../extend/addon/hzaddons/dwpost/dwpost.php:49 +msgid "Post to Dreamwidth" +msgstr "Publikuj na Dreamwidth" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:21 +msgid "nofed Settings saved." +msgstr "nofed - zapisano ustawienie." + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33 +msgid "No Federation App" +msgstr "Brak aplikacji Federation" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:34 +msgid "" +"Prevent posting from being federated to anybody. It will exist only on your " +"channel page." +msgstr "" +"Zapobiegaj federowaniu wiadomości do kogokolwiek. Będzie istnieć tylko na " +"stronie Twojego kanału." + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +msgid "Federate posts by default" +msgstr "Domyślnie, posty Federate" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:50 +msgid "No Federation" +msgstr "Brak Federation" + +#: ../../extend/addon/hzaddons/nofed/nofed.php:47 +msgid "Federate" +msgstr "Federate" + +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:15 +msgid "WYSIWYG status editor" +msgstr "Edytor aplikacji WYSIWYG Status" + +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26 +msgid "WYSIWYG Status App" +msgstr "Aplikacja WYSIWYG Status" + +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:34 +msgid "WYSIWYG Status" +msgstr "WYSIWYG Status" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:27 +msgid "No server specified" +msgstr "Nie określono serwera" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:73 +msgid "Posts imported" +msgstr "Zaimportowano posty" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:113 +msgid "Files imported" +msgstr "Zaimportowano pliki" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:122 +msgid "" +"This addon app copies existing content and file storage to a cloned/copied " +"channel. Once the app is installed, visit the newly installed app. This will " +"allow you to set the location of your original channel and an optional date " +"range of files/conversations to copy." +msgstr "" +"Ten dodatek kopiuje istniejące treści i magazyn plików do sklonowanego lub " +"skopiowanego kanału. Po zainstalowaniu, odwiedź nowo zainstalowaną " +"aplikację. Umożliwi Ci to ustawienie lokalizacji oryginalnego kanału i " +"opcjonalnego zakresu dat plików lub konwersacji do skopiowania." + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:136 +msgid "" +"This will import all your conversations and cloud files from a cloned " +"channel on another server. This may take a while if you have lots of posts " +"and or files." +msgstr "" +"Spowoduje to zaimportowanie wszystkich rozmów i plików przechowywanych w " +"chmurze ze sklonowanego kanału na innym serwerze. Może to chwilę potrwać, " +"jeśli masz dużo postów lun plików." + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +msgid "Include posts" +msgstr "Dołącz posty" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +msgid "Conversations, Articles, Cards, and other posted content" +msgstr "Rozmowy, artykuły, karty i inne opublikowane treści" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +msgid "Include files" +msgstr "Dołącz pliki" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +msgid "Files, Photos and other cloud storage" +msgstr "Pliki, zdjęcia i inne przechowywane w chmurze rzeczy" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:139 +msgid "Original Server base URL" +msgstr "Oryginalny podstawowy adres URL serwera" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:48 +msgid "Your channel has been upgraded to $Projectname version" +msgstr "Twój kanał został uaktualniony do wersji $Projectname" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:50 +msgid "Please have a look at the" +msgstr "Proszę spojrzeć na" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:52 +msgid "git history" +msgstr "historia repozytorium Git" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:54 +msgid "change log" +msgstr "dziennik zmian" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:55 +msgid "for further info." +msgstr "po dalsze informacje." + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:60 +msgid "Upgrade Info" +msgstr "Informacja o aktualizacji" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:64 +msgid "Do not show this again" +msgstr "Nie pokazuj tego ponownie" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:22 +msgid "pageheader Settings saved." +msgstr "pageheader - zapisano ustawienie." + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34 +msgid "Page Header App" +msgstr "Aplikacja Page Header" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:35 +msgid "Inserts a page header" +msgstr "Wstawia nagłówek strony" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:43 +msgid "Message to display on every page on this server" +msgstr "Wiadomość do wyświetlenia na każdej stronie na tym serwerze" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:51 +msgid "Page Header" +msgstr "Page Header" + +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:21 +msgid "Who viewed my channel/profile" +msgstr "Kto oglądał mój kanał lub profil" + +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:25 +msgid "Recent Channel/Profile Viewers" +msgstr "Ostatnio wyświetlający mój kanał lub profil" + +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:36 +msgid "No entries." +msgstr "Brak postów." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:39 +msgid "Messages" +msgstr "Wiadomości" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:52 +msgid "message" +msgstr "wiadomość" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:92 +msgid "Message recalled." +msgstr "Wiadomość przywołana." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:105 +msgid "Conversation removed." +msgstr "Rozmowa została usunięta." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:120 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:241 +msgid "Expires YYYY-MM-DD HH:MM" +msgstr "Wygasa YYYY-MM-DD HH:MM" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:148 +msgid "Requested channel is not in this network" +msgstr "Żądanego kanału nie ma w tej sieci" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:156 +msgid "Send Private Message" +msgstr "Wyślij prywatną wiadomość" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:157 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:300 +msgid "To:" +msgstr "Do:" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:160 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:302 +msgid "Subject:" +msgstr "Temat:" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:165 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:308 +msgid "Attach file" +msgstr "Dołącz plik" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:167 +msgid "Send" +msgstr "Wyślij" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:271 +msgid "Delete message" +msgstr "Usuń wiadomość" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:272 +msgid "Delivery report" +msgstr "Raport dostawy" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:273 +msgid "Recall message" +msgstr "Odwołaj wiadomość" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:275 +msgid "Message has been recalled." +msgstr "Wiadomość została odwołana." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:293 +msgid "Delete Conversation" +msgstr "Usuń rozmowę" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:295 +msgid "" +"No secure communications available. You may be able to " +"respond from the sender's profile page." +msgstr "" +"Brak bezpiecznej komunikacji. Możesz odpowiedzieć ze strony " +"profilu nadawcy." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:299 +msgid "Send Reply" +msgstr "Wyślij odpowiedź" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:304 +#, php-format +msgid "Your message for %s (%s):" +msgstr "Twoja wiadomość dla %s (%s):" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:384 +msgid "Unable to lookup recipient." +msgstr "Nie można znaleźć adresata." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:391 +msgid "Unable to communicate with requested channel." +msgstr "Nie można skomunikować się z żądanym kanałem." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:398 +msgid "Cannot verify requested channel." +msgstr "Nie można zweryfikować żądanego kanału." + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:416 +msgid "Selected channel has private message restrictions. Send failed." +msgstr "" +"Wybrany kanał ma ograniczenia dotyczące wiadomości prywatnych. Wysyłanie nie " +"powiodło się." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:50 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:128 +msgid "System defaults:" +msgstr "Domyślne wartości systemowe:" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54 +msgid "Preferred Clipart IDs" +msgstr "Identyfikatory preferowanych clipartów" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54 +msgid "List of preferred clipart ids. These will be shown first." +msgstr "Lista identyfikatorów preferowanych clipartów." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55 +msgid "Default Search Term" +msgstr "Domyślna fraza wyszukiwania" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55 +msgid "The default search term. These will be shown second." +msgstr "Domyślna fraza wyszukiwania. Będzie ona wyświetlana jako druga." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56 +msgid "Return After" +msgstr "Wróć po" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56 +msgid "Page to load after image selection." +msgstr "Strona do załadowania po wybraniu obrazu." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:59 +msgid "Profile List" +msgstr "Lista profili" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61 +msgid "Order of Preferred" +msgstr "Kolejność preferowanych" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61 +msgid "Sort order of preferred clipart ids." +msgstr "Sortuj preferowane identyfikatory clipart." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:62 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:68 +msgid "Newest first" +msgstr "Od najnowszych" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:65 +msgid "As entered" +msgstr "Jak wprowadzono" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67 +msgid "Order of other" +msgstr "Kolejność innych" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67 +msgid "Sort order of other clipart ids." +msgstr "Kolejność sortowania innych identyfikatorów clipartów." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:69 +msgid "Most downloaded first" +msgstr "Najczęściej pobierane jako pierwsze" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:70 +msgid "Most liked first" +msgstr "Najbardziej lubiane jako pierwsze" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72 +msgid "Preferred IDs Message" +msgstr "Komunikat o preferowanych identyfikatorach" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72 +msgid "Message to display above preferred results." +msgstr "Wiadomość do wyświetlenia powyżej preferowanych wyników." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78 +msgid "Uploaded by: " +msgstr "Przesłane przez: " + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78 +msgid "Drawn by: " +msgstr "Narysowane przez: " + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:182 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:194 +msgid "Use this image" +msgstr "Użyj tego obrazu" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:192 +msgid "Or select from a free OpenClipart.org image:" +msgstr "Lub wybierz bezpłatny obraz z OpenClipart.org:" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:195 +msgid "Search Term" +msgstr "Fraza wyszukiwania" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:232 +msgid "Unknown error. Please try again later." +msgstr "Nieznany błąd. Spróbuj ponownie później." + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:308 +msgid "Profile photo updated successfully." +msgstr "Zdjęcie profilowe zostało pomyślnie zaktualizowane." + +#: ../../extend/addon/hzaddons/gallery/gallery.php:43 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:136 +msgid "Gallery" +msgstr "Gallery" + +#: ../../extend/addon/hzaddons/gallery/gallery.php:46 +msgid "Photo Gallery" +msgstr "Galeria zdjęć" + +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58 +msgid "Gallery App" +msgstr "Aplikacja Gallery" + +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:59 +msgid "A simple gallery for your photo albums" +msgstr "Prosta galeria dla albumów ze zdjęciami" + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35 +msgid "Smileybutton App" +msgstr "Aplikacja Smileybutton" + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:36 +msgid "Adds a smileybutton to the jot editor" +msgstr "Dodaje przycisk emotikonów do edytora jot" + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +msgid "Hide the button and show the smilies directly." +msgstr "Ukryj przycisk i bezpośrednio wyświetlaj emotikony." + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:52 +msgid "Smileybutton Settings" +msgstr "Ustawienia Smileybutton" + +#: ../../extend/addon/hzaddons/rtof/rtof.php:51 +msgid "Post to Friendica" +msgstr "Opublikuj w sieci Hubzilla" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:24 +msgid "Friendica Crosspost Connector Settings saved." +msgstr "Zapisano ustawienia Friendica Crosspost Connector ." + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36 +msgid "Friendica Crosspost Connector App" +msgstr "Aplikacja Hubzilla Crosspost Connector" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:37 +msgid "Relay public postings to a connected Friendica account" +msgstr "Przekazywanie publicznych postów do połączonego konta Friendica" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +msgid "Send public postings to Friendica by default" +msgstr "Domyślnie wysyłaj publiczne posty na kanał Hubzilla" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53 +msgid "Friendica API Path" +msgstr "Ścieżka API Hubzilla" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57 +msgid "Friendica login name" +msgstr "Nazwa logowania w Hubzilla" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:61 +msgid "Friendica password" +msgstr "Hasło Hubzilla" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:69 +msgid "Friendica Crosspost Connector" +msgstr "Friendica Crosspost Connector" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:36 +msgid "Logfile archive directory" +msgstr "Katalog archiwum plików dziennika zdarzeń" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:36 +msgid "Directory to store rotated logs" +msgstr "Katalog do przechowywania rotowanych dzienników zdarzeń" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:37 +msgid "Logfile size in bytes before rotating" +msgstr "Rozmiar pliku dziennika w bajtach przed dokonaniem odnowienia" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:38 +msgid "Number of logfiles to retain" +msgstr "Liczba plików dziennika do przechowania" + +#: ../../extend/addon/hzaddons/wppost/wppost.php:46 +msgid "Post to WordPress" +msgstr "Opubikuj w WordPress" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:30 +msgid "Wordpress Settings saved." +msgstr "Zapisano ustawienia Wordpress." + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:43 +msgid "Wordpress Post App" +msgstr "Aplikacja Wordpress Post" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:44 +msgid "Post to WordPress or anything else which uses the wordpress XMLRPC API" +msgstr "" +"Opublikuj na WordPress lub czymkolwiek innym, co używa API XMLRPC WordPress" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:69 +msgid "WordPress username" +msgstr "Nazwa użytkownika WordPress" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:73 +msgid "WordPress password" +msgstr "Hasło WordPress" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:77 +msgid "WordPress API URL" +msgstr "Adres URL API WordPress" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:78 +msgid "Typically https://your-blog.tld/xmlrpc.php" +msgstr "Zwykle https://your-blog.tld/xmlrpc.php" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:81 +msgid "WordPress blogid" +msgstr "Identyfikator blogu WordPress" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82 +msgid "For multi-user sites such as wordpress.com, otherwise leave blank" +msgstr "" +"Dla serwisów wielowitrynowych, takich jak wordpress.com, w przeciwnym razie " +"pozostaw puste" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +msgid "Post to WordPress by default" +msgstr "Domyślnie publikuj na WordPress" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +msgid "Forward comments (requires hubzilla_wp plugin)" +msgstr "Przekazywanie komentarzy (wymaga wtyczki hubzilla_wp)" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:106 +msgid "Wordpress Post" +msgstr "Wordpress Post" + +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:22 +msgid "" +"Allow magic authentication only to websites of your immediate connections" +msgstr "" +"Zezwalaj na magiczne uwierzytelnianie tylko w witrynach internetowych Twoich " +"bezpośrednich połączeń" + +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33 +msgid "Authchoose App" +msgstr "APlikacja Authchoose" + +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:39 +msgid "Authchoose" +msgstr "Authchoose" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19 +msgid "bitchslap" +msgstr "bitchslap" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19 +msgid "bitchslapped" +msgstr "bitchslapped" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20 +msgid "shag" +msgstr "shag" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20 +msgid "shagged" +msgstr "shagged" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21 +msgid "patent" +msgstr "patent" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21 +msgid "patented" +msgstr "opatentowany" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22 +msgid "hug" +msgstr "przytulić" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22 +msgid "hugged" +msgstr "przytulony" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23 +msgid "murder" +msgstr "zamordować" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23 +msgid "murdered" +msgstr "zamordowany" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24 +msgid "worship" +msgstr "uwielbiać" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24 +msgid "worshipped" +msgstr "uwielbiany" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25 +msgid "kiss" +msgstr "pocałować" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25 +msgid "kissed" +msgstr "pocałowany" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26 +msgid "tempt" +msgstr "kusić" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26 +msgid "tempted" +msgstr "skuszony" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27 +msgid "raise eyebrows at" +msgstr "unieść brwi" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27 +msgid "raised their eyebrows at" +msgstr "podnieśli brwi" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28 +msgid "insult" +msgstr "zniewaga" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28 +msgid "insulted" +msgstr "znieważony" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29 +msgid "praise" +msgstr "pochwała" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29 +msgid "praised" +msgstr "pochwalony" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30 +msgid "be dubious of" +msgstr "mieć wątpliwości" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30 +msgid "was dubious of" +msgstr "zwątpiony" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31 +msgid "eat" +msgstr "jeść" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31 +msgid "ate" +msgstr "najedzony" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32 +msgid "giggle and fawn at" +msgstr "chichotać i płakać" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32 +msgid "giggled and fawned at" +msgstr "chichotał i łakał" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33 +msgid "doubt" +msgstr "wątpić" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33 +msgid "doubted" +msgstr "zwątpił" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34 +msgid "glare" +msgstr "piorunujące spojrzenie" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34 +msgid "glared at" +msgstr "obrzucił spojrzeniem" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35 +msgid "fuck" +msgstr "pierdolić" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35 +msgid "fucked" +msgstr "przejebane" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36 +msgid "bonk" +msgstr "rżnąć" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36 +msgid "bonked" +msgstr "zerżnięty" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37 +msgid "declare undying love for" +msgstr "deklaruj wieczną miłość" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37 +msgid "declared undying love for" +msgstr "zadeklarował wieczną miłość" + +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:34 +msgid "New registration" +msgstr "Nowa rejestracja" + +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:42 +#, php-format +msgid "Message sent to %s. New account registration: %s" +msgstr "Wiadomość wysłana do%s. Rejestracja nowego konta: %s" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:40 +msgid "Pump.io Settings saved." +msgstr "Ustawienia Pump.io zostały zapisane." + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53 +msgid "Pump.io Crosspost Connector App" +msgstr "Aplikacja Pump.io Crosspost Connector" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:54 +msgid "Relay public posts to pump.io" +msgstr "Przekazuj publiczne posty do Pump.io" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73 +msgid "Pump.io servername" +msgstr "Nazwa serwera Pump.io" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73 +msgid "Without \"http://\" or \"https://\"" +msgstr "Bez \"http: //\" lub \"https: //\"" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77 +msgid "Pump.io username" +msgstr "Nazwa użytkownika Pump.io" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77 +msgid "Without the servername" +msgstr "Bez nazwy serwera" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:88 +msgid "You are not authenticated to pumpio" +msgstr "Nie jesteś uwierzytelniony w pumpio" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:90 +msgid "(Re-)Authenticate your pump.io connection" +msgstr "(Ponownie) Uwierzytelnij swoje połączenie pump.io" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +msgid "Post to pump.io by default" +msgstr "Piblikuj domyślnie w pump.io" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +msgid "Should posts be public" +msgstr "Posty powinny być publiczne" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +msgid "Mirror all public posts" +msgstr "Powielaj wszystkie posty publiczne" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:112 +msgid "Pump.io Crosspost Connector" +msgstr "Pump.io Crosspost Connector" + +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:152 +msgid "You are now authenticated to pumpio." +msgstr "Jesteś teraz uwierzytelniony w pumpio." + +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:153 +msgid "return to the featured settings page" +msgstr "wróć do polecanej strony ustawień" + +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:168 +msgid "Post to Pump.io" +msgstr "Opublikuj na Pump.io" + +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24 +msgid "NSA Bait App" +msgstr "Aplikacja NSA Bait" + +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:26 +msgid "Make yourself a political target" +msgstr "Stań się celem politycznym" + +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:15 +msgid "Add some colour to tag clouds" +msgstr "Dodaj jakiś kolor do oznaczania chmur" + +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26 +msgid "Rainbow Tag App" +msgstr "Aplikacja Rainbow Tag" + +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:34 +msgid "Rainbow Tag" +msgstr "Rainbow Tag" + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:19 +msgid "Send test email" +msgstr "Wyślij testową wiadomość e-mail" + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:66 +msgid "Mail sent." +msgstr "Mail wysłany." + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:68 +msgid "Sending of mail failed." +msgstr "Wysyłanie poczty nie powiodło się." + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:77 +msgid "Mail Test" +msgstr "Test poczty" + +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:119 +msgid "Redmatrix File Storage Import" +msgstr "Import magazyn plików Redmatrix" + +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:120 +msgid "This will import all your Redmatrix cloud files to this channel." +msgstr "" +"Spowoduje to zaimportowanie wszystkich plików chmury Redmatrix do tego " +"kanału." + +#: ../../extend/addon/hzaddons/mdpost/mdpost.php:42 +msgid "Use markdown for editing posts" +msgstr "Użyj markdown do edycji postów" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:22 +msgid "Fuzzloc Settings updated." +msgstr "Zaktualizowano ustawienia Fuzzloc." + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34 +msgid "Fuzzy Location App" +msgstr "Aplikacja Fuzzy Location" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:35 +msgid "" +"Blur your precise location if your channel uses browser location mapping" +msgstr "" +"Zamaż swoją dokładną lokalizację, jeśli Twój kanał używa mapowania " +"lokalizacji w przeglądarce" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:40 +msgid "Minimum offset in meters" +msgstr "Minimalne przesunięcie w metrach" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:44 +msgid "Maximum offset in meters" +msgstr "Maksymalne przesunięcie w metrach" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:53 +msgid "Fuzzy Location" +msgstr "Fuzzy Location" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50 +msgid "Startpage App" +msgstr "Aplikacja Startpage" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:51 +msgid "Set a preferred page to load on login from home page" +msgstr "" +"Ustaw preferowaną stronę do załadowania przy logowaniu ze strony głównej" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62 +msgid "Page to load after login" +msgstr "Strona do załadowania po zalogowaniu" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62 +msgid "" +"Examples: "apps", "network?f=&gid=37" (privacy " +"collection), "channel" or "notifications/system" (leave " +"blank for default network page (grid)." +msgstr "" +"Przykłady: "aplikacje", "sieć?f=&gid=37" (kolekcja " +"prywatności), "kanał" lub "powiadomienie/system" " +"(pozostaw puste dla domyślnej stony sieci (siatki)." + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:70 +msgid "Startpage" +msgstr "Startpage" + +#: ../../view/theme/redbasic/php/config.php:16 +#: ../../view/theme/redbasic/php/config.php:19 +msgid "Focus (Hubzilla default)" +msgstr "Fokus (domyślnie Hubzilla)" + +#: ../../view/theme/redbasic/php/config.php:98 +msgid "Theme settings" +msgstr "Ustawienia motywu" + +#: ../../view/theme/redbasic/php/config.php:99 +msgid "Narrow navbar" +msgstr "Wąski pasek nawigacyjny" + +#: ../../view/theme/redbasic/php/config.php:100 +msgid "Navigation bar background color" +msgstr "Kolor tła paska nawigacji" + +#: ../../view/theme/redbasic/php/config.php:101 +msgid "Navigation bar icon color " +msgstr "Kolor ikony paska nawigacji " + +#: ../../view/theme/redbasic/php/config.php:102 +msgid "Navigation bar active icon color " +msgstr "Kolor ikony aktywnego paska nawigacji " + +#: ../../view/theme/redbasic/php/config.php:103 +msgid "Link color" +msgstr "Kolor odnośnika" + +#: ../../view/theme/redbasic/php/config.php:104 +msgid "Set font-color for banner" +msgstr "Ustaw kolor czcionki na banerze" + +#: ../../view/theme/redbasic/php/config.php:105 +msgid "Set the background color" +msgstr "Ustaw kolor tła" + +#: ../../view/theme/redbasic/php/config.php:106 +msgid "Set the background image" +msgstr "Ustaw obraz tła" + +#: ../../view/theme/redbasic/php/config.php:107 +msgid "Set the background color of items" +msgstr "Ustaw kolor tła elementów" + +#: ../../view/theme/redbasic/php/config.php:108 +msgid "Set the background color of comments" +msgstr "Ustaw kolor tła komentarzy" + +#: ../../view/theme/redbasic/php/config.php:109 +msgid "Set font-size for the entire application" +msgstr "Ustaw rozmiar czcionki dla całej aplikacji" + +#: ../../view/theme/redbasic/php/config.php:109 +msgid "Examples: 1rem, 100%, 16px" +msgstr "Przykłady: 1rem, 100%, 16px" + +#: ../../view/theme/redbasic/php/config.php:110 +msgid "Set font-color for posts and comments" +msgstr "Ustaw kolor czcionki dla postów i komentarzy" + +#: ../../view/theme/redbasic/php/config.php:111 +msgid "Set radius of corners" +msgstr "Ustaw promień narożników" + +#: ../../view/theme/redbasic/php/config.php:111 +msgid "Example: 4px" +msgstr "Przykład: 4px" + +#: ../../view/theme/redbasic/php/config.php:112 +msgid "Set shadow depth of photos" +msgstr "Ustaw głębię cienia zdjęć" + +#: ../../view/theme/redbasic/php/config.php:113 +msgid "Set maximum width of content region in pixel" +msgstr "Ustaw maksymalną szerokość obszaru treści w pikselach" + +#: ../../view/theme/redbasic/php/config.php:113 +msgid "Leave empty for default width" +msgstr "Pozostaw puste dla domyślnej szerokości" + +#: ../../view/theme/redbasic/php/config.php:114 +msgid "Set size of conversation author photo" +msgstr "Ustaw rozmiar zdjęcia autora rozmowy" + +#: ../../view/theme/redbasic/php/config.php:115 +msgid "Set size of followup author photos" +msgstr "Ustaw rozmiar kolejnych zdjęć autora" + +#: ../../view/theme/redbasic/php/config.php:116 +msgid "Show advanced settings" +msgstr "Pokaż ustawienia zaawansowane" + +#: ../../boot.php:1684 +msgid "Create an account to access services and applications" +msgstr "Utwórz konto, aby uzyskać dostęp do usług i aplikacji" + +#: ../../boot.php:1708 +msgid "Login/Email" +msgstr "Login/Email" + +#: ../../boot.php:1709 +msgid "Password" +msgstr "Hasło" + +#: ../../boot.php:1710 +msgid "Remember me" +msgstr "Zapamiętaj mnie" + +#: ../../boot.php:1713 +msgid "Forgot your password?" +msgstr "Nie pamiętasz hasła?" + +#: ../../boot.php:2582 +#, php-format +msgid "[$Projectname] Website SSL error for %s" +msgstr "[$Projectname] Błąd SSL witryny internetowej dla %s" + +#: ../../boot.php:2587 +msgid "Website SSL certificate is not valid. Please correct." +msgstr "Certyfikat SSL witryny jest nieprawidłowy. Proszę popraw." + +#: ../../boot.php:2703 +#, php-format +msgid "[$Projectname] Cron tasks not running on %s" +msgstr "[$Projectname] Zadania Crona nie działają na %s" + +#: ../../boot.php:2708 +msgid "Cron/Scheduled tasks not running." +msgstr "Zadania Crona (zaplanowane) nie działają." + +#~ msgid "Collection" +#~ msgstr "Kolekcja" + +#~ msgid "Who can see this?" +#~ msgstr "Kto może to zobaczyć?" + +#~ msgid "Show" +#~ msgstr "Pokaż" + +#~ msgid "" +#~ "INFO: this command can take a very long time depending on your DB size." +#~ msgstr "" +#~ "INFORMACJA: wykonanie tego polecenia może zająć bardzo dużo czasu w " +#~ "zależności od rozmiaru bazy danych." + +#~ msgid "Remove this channel and all its clones from the network" +#~ msgstr "Usuń ten kanał i wszystkie jego klony z sieci" + +#~ msgid "" +#~ "By default only the instance of the channel located on this hub will be " +#~ "removed from the network" +#~ msgstr "" +#~ "Domyślnie tylko instancja kanału znajdującego się na tym hubie zostanie " +#~ "usunięta z sieci" + +#~ msgid "" +#~ "Remove this account, all its channels and all its channel clones from the " +#~ "network" +#~ msgstr "" +#~ "Usuń to konto, wszystkie jego kanały i wszystkie klony kanałów z sieci" + +#~ msgid "" +#~ "By default only the instances of the channels located on this hub will be " +#~ "removed from the network" +#~ msgstr "" +#~ "Domyślnie, zostaną usunięte z sieci tylko instancje kanałów znajdujące " +#~ "się na tym hubie" + +#~ msgid "Hub not found." +#~ msgstr "Nie znaleziono huba." + +#~ msgid "Manual conversation updates" +#~ msgstr "Ręczne aktualizacje rozmów" + +#~ msgid "Default is on, turning this off may increase screen jumping" +#~ msgstr "" +#~ "Domyślnie jest włączone, wyłączenie tego może zwiększyć przeskakiwanie " +#~ "ekranu" + +#~ msgid "Principal" +#~ msgstr "Pryncypał" + +#~ msgid "Addressbook" +#~ msgstr "Książka adresowa" + +#~ msgid "Schedule Inbox" +#~ msgstr "Zaplanuj skrzynkę odbiorczą" + +#~ msgid "Schedule Outbox" +#~ msgstr "Zaplanuj skrzynkę nadawczą" diff --git a/view/pl/hmessages.pot b/view/pl/hmessages.pot new file mode 100644 index 000000000..961e07f2f --- /dev/null +++ b/view/pl/hmessages.pot @@ -0,0 +1,15710 @@ +# hubzilla +# Copyright (C) 2012-2016 hubzilla +# This file is distributed under the same license as the hubzilla package. +# Mike Macgirvin, 2012 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 5.2.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-01-21 12:07+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../Zotlabs/Access/Permissions.php:56 +msgid "Can view my channel stream and posts" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:57 +msgid "Can send me their channel stream and posts" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:58 +msgid "Can view my default channel profile" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:59 +msgid "Can view my connections" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:60 +msgid "Can view my file storage and photos" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:61 +msgid "Can upload/modify my file storage and photos" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:62 +msgid "Can view my channel webpages" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:63 +msgid "Can view my wiki pages" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:64 +msgid "Can create/edit my channel webpages" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:65 +msgid "Can write to my wiki pages" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:66 +msgid "Can post on my channel (wall) page" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:67 +msgid "Can comment on or like my posts" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:68 +msgid "Can send me private mail messages" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:69 +msgid "Can like/dislike profiles and profile things" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:70 +msgid "Can forward to all my channel connections via ! mentions in posts" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:71 +msgid "Can chat with me" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:72 +msgid "Can source my public posts in derived channels" +msgstr "" + +#: ../../Zotlabs/Access/Permissions.php:73 +msgid "Can administer my channel" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:287 +msgid "Social Networking" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:288 +msgid "Social - Federation" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:289 +msgid "Social - Mostly Public" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:290 +msgid "Social - Restricted" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:291 +msgid "Social - Private" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:294 +msgid "Community Forum" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:295 +msgid "Forum - Mostly Public" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:296 +msgid "Forum - Restricted" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:297 +msgid "Forum - Private" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:300 +msgid "Feed Republish" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:301 +msgid "Feed - Mostly Public" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:302 +msgid "Feed - Restricted" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:305 +msgid "Special Purpose" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:306 +msgid "Special - Celebrity/Soapbox" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:307 +msgid "Special - Group Repository" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:310 +#: ../../Zotlabs/Module/Cdav.php:1384 ../../Zotlabs/Module/Profiles.php:797 +#: ../../Zotlabs/Module/Connedit.php:927 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 ../../include/selectors.php:115 +#: ../../include/selectors.php:151 ../../include/connections.php:741 +#: ../../include/connections.php:748 ../../include/event.php:1429 +#: ../../include/event.php:1436 +msgid "Other" +msgstr "" + +#: ../../Zotlabs/Access/PermissionRoles.php:311 +msgid "Custom/Expert Mode" +msgstr "" + +#: ../../Zotlabs/Module/Authtest.php:16 ../../Zotlabs/Module/Pdledit.php:35 +#: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Events.php:277 +#: ../../Zotlabs/Module/Bookmarks.php:70 ../../Zotlabs/Module/Webpages.php:133 +#: ../../Zotlabs/Module/Profiles.php:200 ../../Zotlabs/Module/Profiles.php:637 +#: ../../Zotlabs/Module/Like.php:230 ../../Zotlabs/Module/Defperms.php:182 +#: ../../Zotlabs/Module/Layouts.php:71 ../../Zotlabs/Module/Layouts.php:78 +#: ../../Zotlabs/Module/Layouts.php:89 ../../Zotlabs/Module/Group.php:15 +#: ../../Zotlabs/Module/Group.php:31 ../../Zotlabs/Module/Appman.php:87 +#: ../../Zotlabs/Module/Message.php:18 ../../Zotlabs/Module/Moderate.php:15 +#: ../../Zotlabs/Module/New_channel.php:105 +#: ../../Zotlabs/Module/New_channel.php:130 +#: ../../Zotlabs/Module/Filestorage.php:20 +#: ../../Zotlabs/Module/Filestorage.php:78 +#: ../../Zotlabs/Module/Filestorage.php:96 +#: ../../Zotlabs/Module/Filestorage.php:119 +#: ../../Zotlabs/Module/Filestorage.php:165 +#: ../../Zotlabs/Module/Card_edit.php:51 +#: ../../Zotlabs/Module/Viewconnections.php:28 +#: ../../Zotlabs/Module/Viewconnections.php:33 ../../Zotlabs/Module/Wiki.php:59 +#: ../../Zotlabs/Module/Wiki.php:285 ../../Zotlabs/Module/Wiki.php:428 +#: ../../Zotlabs/Module/Blocks.php:73 ../../Zotlabs/Module/Blocks.php:80 +#: ../../Zotlabs/Module/Locs.php:100 ../../Zotlabs/Module/Connedit.php:396 +#: ../../Zotlabs/Module/Profile_photo.php:338 +#: ../../Zotlabs/Module/Profile_photo.php:351 +#: ../../Zotlabs/Module/Sharedwithme.php:19 +#: ../../Zotlabs/Module/Editlayout.php:67 +#: ../../Zotlabs/Module/Editlayout.php:90 ../../Zotlabs/Module/Manage.php:10 +#: ../../Zotlabs/Module/Item.php:485 ../../Zotlabs/Module/Item.php:504 +#: ../../Zotlabs/Module/Item.php:514 ../../Zotlabs/Module/Item.php:1442 +#: ../../Zotlabs/Module/Rate.php:113 ../../Zotlabs/Module/Page.php:34 +#: ../../Zotlabs/Module/Page.php:133 ../../Zotlabs/Module/Achievements.php:34 +#: ../../Zotlabs/Module/Regmod.php:20 ../../Zotlabs/Module/Editblock.php:67 +#: ../../Zotlabs/Module/Chat.php:113 ../../Zotlabs/Module/Chat.php:118 +#: ../../Zotlabs/Module/Vote.php:19 ../../Zotlabs/Module/Display.php:425 +#: ../../Zotlabs/Module/Photos.php:71 ../../Zotlabs/Module/Channel.php:177 +#: ../../Zotlabs/Module/Channel.php:332 ../../Zotlabs/Module/Channel.php:371 +#: ../../Zotlabs/Module/Cards.php:86 ../../Zotlabs/Module/Connections.php:32 +#: ../../Zotlabs/Module/Editpost.php:17 ../../Zotlabs/Module/Block.php:24 +#: ../../Zotlabs/Module/Block.php:74 ../../Zotlabs/Module/Common.php:38 +#: ../../Zotlabs/Module/Editwebpage.php:68 +#: ../../Zotlabs/Module/Editwebpage.php:89 +#: ../../Zotlabs/Module/Editwebpage.php:107 +#: ../../Zotlabs/Module/Editwebpage.php:121 ../../Zotlabs/Module/Profile.php:85 +#: ../../Zotlabs/Module/Profile.php:101 +#: ../../Zotlabs/Module/Article_edit.php:51 ../../Zotlabs/Module/Thing.php:282 +#: ../../Zotlabs/Module/Thing.php:302 ../../Zotlabs/Module/Thing.php:343 +#: ../../Zotlabs/Module/Suggest.php:32 +#: ../../Zotlabs/Module/Notifications.php:11 +#: ../../Zotlabs/Module/Articles.php:89 ../../Zotlabs/Module/Setup.php:206 +#: ../../Zotlabs/Module/Mitem.php:129 ../../Zotlabs/Module/Mood.php:126 +#: ../../Zotlabs/Module/Register.php:80 +#: ../../Zotlabs/Module/Channel_calendar.php:230 +#: ../../Zotlabs/Module/Invite.php:21 ../../Zotlabs/Module/Invite.php:102 +#: ../../Zotlabs/Module/Service_limits.php:11 +#: ../../Zotlabs/Module/Cover_photo.php:341 +#: ../../Zotlabs/Module/Cover_photo.php:354 ../../Zotlabs/Module/Menu.php:130 +#: ../../Zotlabs/Module/Menu.php:141 ../../Zotlabs/Module/Sources.php:80 +#: ../../Zotlabs/Module/Poke.php:157 ../../Zotlabs/Module/Network.php:19 +#: ../../Zotlabs/Module/Attach_edit.php:90 +#: ../../Zotlabs/Module/Attach_edit.php:99 +#: ../../Zotlabs/Module/Attach_edit.php:106 +#: ../../Zotlabs/Module/Settings.php:59 ../../Zotlabs/Module/Viewsrc.php:19 +#: ../../Zotlabs/Web/WebServer.php:116 ../../Zotlabs/Lib/Chatroom.php:135 +#: ../../include/photos.php:27 ../../include/attach.php:156 +#: ../../include/attach.php:205 ../../include/attach.php:278 +#: ../../include/attach.php:329 ../../include/attach.php:424 +#: ../../include/attach.php:438 ../../include/attach.php:445 +#: ../../include/attach.php:527 ../../include/attach.php:1091 +#: ../../include/attach.php:1164 ../../include/attach.php:1327 +#: ../../include/items.php:3996 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:53 +#: ../../extend/addon/hzaddons/keepout/keepout.php:36 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:25 +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:44 +msgid "Permission denied." +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:27 +msgid "Layout updated." +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:43 +msgid "PDL Editor App" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:43 ../../Zotlabs/Module/Cdav.php:876 +#: ../../Zotlabs/Module/Bookmarks.php:78 ../../Zotlabs/Module/Webpages.php:48 +#: ../../Zotlabs/Module/Defperms.php:190 ../../Zotlabs/Module/Pubstream.php:20 +#: ../../Zotlabs/Module/Group.php:107 ../../Zotlabs/Module/Oauth.php:100 +#: ../../Zotlabs/Module/Oauth2.php:106 ../../Zotlabs/Module/Wiki.php:52 +#: ../../Zotlabs/Module/Chat.php:100 ../../Zotlabs/Module/Uexport.php:61 +#: ../../Zotlabs/Module/Cards.php:51 ../../Zotlabs/Module/Affinity.php:52 +#: ../../Zotlabs/Module/Randprof.php:29 ../../Zotlabs/Module/Suggest.php:40 +#: ../../Zotlabs/Module/Notes.php:57 ../../Zotlabs/Module/Tokens.php:99 +#: ../../Zotlabs/Module/Articles.php:52 ../../Zotlabs/Module/Mood.php:134 +#: ../../Zotlabs/Module/Permcats.php:63 ../../Zotlabs/Module/Probe.php:18 +#: ../../Zotlabs/Module/Invite.php:110 ../../Zotlabs/Module/Lang.php:17 +#: ../../Zotlabs/Module/Sources.php:88 ../../Zotlabs/Module/Poke.php:165 +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22 +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50 +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:58 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:23 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:38 +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35 +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20 +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33 +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35 +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:39 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21 +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:43 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21 +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34 +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50 +msgid "Not Installed" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:44 +msgid "Provides the ability to edit system page layouts" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:57 ../../Zotlabs/Module/Pdledit.php:100 +msgid "Edit System Page Description" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:78 +msgid "(modified)" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:78 ../../Zotlabs/Module/Lostpass.php:133 +msgid "Reset" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:95 +msgid "Layout not found." +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:101 +msgid "Module Name:" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:102 +msgid "Layout Help" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:103 +msgid "Edit another layout" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:104 +msgid "System layout" +msgstr "" + +#: ../../Zotlabs/Module/Pdledit.php:108 ../../Zotlabs/Module/Events.php:501 +#: ../../Zotlabs/Module/Profiles.php:725 ../../Zotlabs/Module/Import.php:645 +#: ../../Zotlabs/Module/Defperms.php:266 ../../Zotlabs/Module/Group.php:151 +#: ../../Zotlabs/Module/Group.php:167 ../../Zotlabs/Module/Appman.php:155 +#: ../../Zotlabs/Module/Oauth.php:111 ../../Zotlabs/Module/Import_items.php:129 +#: ../../Zotlabs/Module/Connect.php:107 +#: ../../Zotlabs/Module/Filestorage.php:208 ../../Zotlabs/Module/Oauth2.php:116 +#: ../../Zotlabs/Module/Wiki.php:215 ../../Zotlabs/Module/Locs.php:132 +#: ../../Zotlabs/Module/Connedit.php:896 ../../Zotlabs/Module/Rate.php:166 +#: ../../Zotlabs/Module/Xchan.php:15 ../../Zotlabs/Module/Chat.php:209 +#: ../../Zotlabs/Module/Chat.php:248 ../../Zotlabs/Module/Photos.php:1058 +#: ../../Zotlabs/Module/Photos.php:1098 ../../Zotlabs/Module/Photos.php:1216 +#: ../../Zotlabs/Module/Editpost.php:86 ../../Zotlabs/Module/Affinity.php:87 +#: ../../Zotlabs/Module/Pconfig.php:116 +#: ../../Zotlabs/Module/Admin/Themes.php:158 +#: ../../Zotlabs/Module/Admin/Security.php:120 +#: ../../Zotlabs/Module/Admin/Accounts.php:168 +#: ../../Zotlabs/Module/Admin/Features.php:66 +#: ../../Zotlabs/Module/Admin/Channels.php:147 +#: ../../Zotlabs/Module/Admin/Logs.php:84 +#: ../../Zotlabs/Module/Admin/Account_edit.php:73 +#: ../../Zotlabs/Module/Admin/Addons.php:442 +#: ../../Zotlabs/Module/Admin/Site.php:293 +#: ../../Zotlabs/Module/Admin/Profs.php:178 ../../Zotlabs/Module/Thing.php:328 +#: ../../Zotlabs/Module/Thing.php:381 +#: ../../Zotlabs/Module/Email_validation.php:40 +#: ../../Zotlabs/Module/Tokens.php:188 ../../Zotlabs/Module/Setup.php:304 +#: ../../Zotlabs/Module/Setup.php:344 ../../Zotlabs/Module/Mitem.php:259 +#: ../../Zotlabs/Module/Mood.php:158 ../../Zotlabs/Module/Permcats.php:129 +#: ../../Zotlabs/Module/Settings/Account.php:103 +#: ../../Zotlabs/Module/Settings/Events.php:42 +#: ../../Zotlabs/Module/Settings/Profiles.php:52 +#: ../../Zotlabs/Module/Settings/Editor.php:42 +#: ../../Zotlabs/Module/Settings/Features.php:48 +#: ../../Zotlabs/Module/Settings/Manage.php:43 +#: ../../Zotlabs/Module/Settings/Display.php:188 +#: ../../Zotlabs/Module/Settings/Photos.php:42 +#: ../../Zotlabs/Module/Settings/Channel.php:495 +#: ../../Zotlabs/Module/Settings/Connections.php:42 +#: ../../Zotlabs/Module/Settings/Calendar.php:42 +#: ../../Zotlabs/Module/Settings/Directory.php:42 +#: ../../Zotlabs/Module/Settings/Channel_home.php:91 +#: ../../Zotlabs/Module/Settings/Network.php:62 +#: ../../Zotlabs/Module/Settings/Conversation.php:49 +#: ../../Zotlabs/Module/Invite.php:168 ../../Zotlabs/Module/Sources.php:125 +#: ../../Zotlabs/Module/Sources.php:162 ../../Zotlabs/Module/Poke.php:217 +#: ../../Zotlabs/Storage/Browser.php:382 ../../Zotlabs/Lib/ThreadItem.php:825 +#: ../../Zotlabs/Widget/Wiki_pages.php:42 +#: ../../Zotlabs/Widget/Wiki_pages.php:99 +#: ../../Zotlabs/Widget/Eventstools.php:16 ../../include/js_strings.php:22 +#: ../../extend/addon/hzaddons/irc/irc.php:45 +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:95 +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:57 +#: ../../extend/addon/hzaddons/piwik/piwik.php:95 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:143 +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:51 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:90 +#: ../../extend/addon/hzaddons/cart/cart.php:1376 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:312 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:412 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:643 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:410 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:248 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:132 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:142 +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:86 +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:100 +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:75 +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:155 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:82 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1461 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1520 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1639 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2742 +#: ../../extend/addon/hzaddons/workflow/Settings/Mod_WorkflowSettings.php:94 +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:70 +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:61 +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:67 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:70 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:602 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:193 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:251 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:306 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:65 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:72 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:262 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:330 +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:136 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:184 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:80 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:53 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:142 +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:54 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:310 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:53 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:55 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:72 +#: ../../extend/addon/hzaddons/logrot/logrot.php:35 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:109 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:115 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:100 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:124 +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:56 +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:73 +#: ../../view/theme/redbasic/php/config.php:94 +msgid "Submit" +msgstr "" + +#: ../../Zotlabs/Module/Z6trans.php:19 +msgid "Update to Hubzilla 5.0 step 2" +msgstr "" + +#: ../../Zotlabs/Module/Z6trans.php:21 +msgid "To complete the update please run" +msgstr "" + +#: ../../Zotlabs/Module/Z6trans.php:23 +msgid "php util/z6convert.php" +msgstr "" + +#: ../../Zotlabs/Module/Z6trans.php:25 +msgid "from the terminal." +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:10 ../../Zotlabs/Module/Dreport.php:82 +#: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Cloud.php:123 +#: ../../Zotlabs/Module/Like.php:332 ../../Zotlabs/Module/Group.php:99 +#: ../../Zotlabs/Module/Import_items.php:120 +#: ../../Zotlabs/Module/Subthread.php:86 ../../Zotlabs/Module/Share.php:72 +#: ../../Zotlabs/Web/WebServer.php:115 ../../include/items.php:439 +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:75 +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:119 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:109 +msgid "Permission denied" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:59 +msgid "Invalid message" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:93 +msgid "no results" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:107 +msgid "channel sync processed" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:111 +msgid "queued" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:115 +msgid "posted" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:119 +msgid "accepted for delivery" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:123 +msgid "updated" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:126 +msgid "update ignored" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:129 +msgid "permission denied" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:133 +msgid "recipient not found" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:136 +msgid "mail recalled" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:139 +msgid "duplicate mail received" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:142 +msgid "mail delivered" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:162 +#, php-format +msgid "Delivery report for %1$s" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:166 ../../Zotlabs/Widget/Wiki_pages.php:41 +#: ../../Zotlabs/Widget/Wiki_pages.php:98 +msgid "Options" +msgstr "" + +#: ../../Zotlabs/Module/Dreport.php:167 +msgid "Redeliver" +msgstr "" + +#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63 +msgid "Invalid profile identifier." +msgstr "" + +#: ../../Zotlabs/Module/Profperm.php:111 +msgid "Profile Visibility Editor" +msgstr "" + +#: ../../Zotlabs/Module/Profperm.php:113 ../../Zotlabs/Lib/Apps.php:362 +#: ../../include/channel.php:1886 +msgid "Profile" +msgstr "" + +#: ../../Zotlabs/Module/Profperm.php:115 +msgid "Click on a contact to add or remove." +msgstr "" + +#: ../../Zotlabs/Module/Profperm.php:124 +msgid "Visible To" +msgstr "" + +#: ../../Zotlabs/Module/Profperm.php:140 +#: ../../Zotlabs/Module/Connections.php:217 +msgid "All Connections" +msgstr "" + +#: ../../Zotlabs/Module/Cloud.php:120 +msgid "Not found" +msgstr "" + +#: ../../Zotlabs/Module/Cloud.php:126 +msgid "Please refresh page" +msgstr "" + +#: ../../Zotlabs/Module/Cloud.php:129 +msgid "Unknown error" +msgstr "" + +#: ../../Zotlabs/Module/Authorize.php:17 +msgid "Unknown App" +msgstr "" + +#: ../../Zotlabs/Module/Authorize.php:29 +msgid "Authorize" +msgstr "" + +#: ../../Zotlabs/Module/Authorize.php:30 +#, php-format +msgid "Do you authorize the app %s to access your channel data?" +msgstr "" + +#: ../../Zotlabs/Module/Authorize.php:32 ../../include/acl_selectors.php:146 +msgid "Allow" +msgstr "" + +#: ../../Zotlabs/Module/Authorize.php:33 +#: ../../Zotlabs/Module/Admin/Accounts.php:174 +msgid "Deny" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:818 ../../Zotlabs/Module/Events.php:28 +msgid "Calendar entries imported." +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:820 ../../Zotlabs/Module/Events.php:30 +msgid "No calendar entries found." +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:876 +msgid "CardDAV App" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:877 +msgid "CalDAV capable addressbook" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:943 ../../Zotlabs/Module/Cal.php:167 +#: ../../Zotlabs/Module/Channel_calendar.php:393 +msgid "Link to source" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1009 ../../Zotlabs/Module/Events.php:468 +msgid "Event title" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1010 ../../Zotlabs/Module/Events.php:474 +msgid "Start date and time" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1011 +msgid "End date and time" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1012 ../../Zotlabs/Module/Events.php:497 +msgid "Timezone:" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1014 ../../Zotlabs/Module/Events.php:481 +#: ../../Zotlabs/Module/Appman.php:145 ../../Zotlabs/Module/Rbmark.php:101 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:173 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:655 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:260 +msgid "Description" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1015 ../../Zotlabs/Module/Events.php:483 +#: ../../Zotlabs/Module/Profiles.php:511 ../../Zotlabs/Module/Profiles.php:736 +#: ../../Zotlabs/Module/Locs.php:128 ../../Zotlabs/Module/Pubsites.php:53 +#: ../../include/js_strings.php:25 +msgid "Location" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1035 ../../Zotlabs/Module/Events.php:697 +#: ../../Zotlabs/Module/Events.php:706 ../../Zotlabs/Module/Photos.php:947 +#: ../../Zotlabs/Module/Cal.php:205 +msgid "Previous" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1036 ../../Zotlabs/Module/Events.php:698 +#: ../../Zotlabs/Module/Events.php:707 ../../Zotlabs/Module/Photos.php:956 +#: ../../Zotlabs/Module/Cal.php:206 ../../Zotlabs/Module/Setup.php:260 +msgid "Next" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1037 ../../Zotlabs/Module/Events.php:708 +#: ../../Zotlabs/Module/Cal.php:207 +msgid "Today" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1038 ../../Zotlabs/Module/Events.php:703 +msgid "Month" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1039 ../../Zotlabs/Module/Events.php:704 +msgid "Week" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1040 ../../Zotlabs/Module/Events.php:705 +msgid "Day" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1041 +msgid "List month" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1042 +msgid "List week" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1043 +msgid "List day" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1051 +msgid "More" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1052 +msgid "Less" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1053 ../../Zotlabs/Module/Cdav.php:1388 +#: ../../Zotlabs/Module/Profiles.php:801 ../../Zotlabs/Module/Oauth.php:53 +#: ../../Zotlabs/Module/Oauth.php:137 ../../Zotlabs/Module/Oauth2.php:58 +#: ../../Zotlabs/Module/Oauth2.php:144 ../../Zotlabs/Module/Connedit.php:931 +#: ../../Zotlabs/Module/Admin/Addons.php:457 ../../Zotlabs/Lib/Apps.php:536 +msgid "Update" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1054 +msgid "Select calendar" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1055 ../../Zotlabs/Widget/Cdav.php:143 +msgid "Channel Calendars" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1055 ../../Zotlabs/Widget/Cdav.php:129 +#: ../../Zotlabs/Widget/Cdav.php:143 +msgid "CalDAV Calendars" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1056 ../../Zotlabs/Module/Cdav.php:1389 +#: ../../Zotlabs/Module/Webpages.php:257 ../../Zotlabs/Module/Profiles.php:802 +#: ../../Zotlabs/Module/Oauth.php:174 ../../Zotlabs/Module/Card_edit.php:129 +#: ../../Zotlabs/Module/Oauth2.php:195 ../../Zotlabs/Module/Blocks.php:162 +#: ../../Zotlabs/Module/Connedit.php:660 ../../Zotlabs/Module/Connedit.php:932 +#: ../../Zotlabs/Module/Editlayout.php:138 +#: ../../Zotlabs/Module/Editblock.php:139 ../../Zotlabs/Module/Photos.php:1179 +#: ../../Zotlabs/Module/Connections.php:328 +#: ../../Zotlabs/Module/Editwebpage.php:167 +#: ../../Zotlabs/Module/Article_edit.php:128 +#: ../../Zotlabs/Module/Admin/Accounts.php:175 +#: ../../Zotlabs/Module/Admin/Channels.php:149 +#: ../../Zotlabs/Module/Admin/Profs.php:176 ../../Zotlabs/Module/Thing.php:269 +#: ../../Zotlabs/Storage/Browser.php:384 ../../Zotlabs/Lib/Apps.php:558 +#: ../../Zotlabs/Lib/ThreadItem.php:170 ../../include/conversation.php:730 +#: ../../include/conversation.php:775 +msgid "Delete" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1057 +msgid "Delete all" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1058 ../../Zotlabs/Module/Cdav.php:1390 +#: ../../Zotlabs/Module/Filer.php:56 ../../Zotlabs/Module/Profiles.php:803 +#: ../../Zotlabs/Module/Oauth.php:112 ../../Zotlabs/Module/Oauth.php:138 +#: ../../Zotlabs/Module/Card_edit.php:131 ../../Zotlabs/Module/Oauth2.php:117 +#: ../../Zotlabs/Module/Oauth2.php:145 ../../Zotlabs/Module/Wiki.php:368 +#: ../../Zotlabs/Module/Wiki.php:401 ../../Zotlabs/Module/Fbrowser.php:66 +#: ../../Zotlabs/Module/Fbrowser.php:88 ../../Zotlabs/Module/Connedit.php:933 +#: ../../Zotlabs/Module/Profile_photo.php:507 +#: ../../Zotlabs/Module/Editlayout.php:140 +#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Editpost.php:110 +#: ../../Zotlabs/Module/Tagrm.php:15 ../../Zotlabs/Module/Tagrm.php:138 +#: ../../Zotlabs/Module/Editwebpage.php:169 +#: ../../Zotlabs/Module/Article_edit.php:130 +#: ../../Zotlabs/Module/Admin/Addons.php:427 +#: ../../Zotlabs/Module/Cover_photo.php:428 +#: ../../Zotlabs/Storage/Browser.php:383 ../../include/conversation.php:1458 +#: ../../include/conversation.php:1511 +#: ../../extend/addon/hzaddons/hsse/hsse.php:209 +#: ../../extend/addon/hzaddons/hsse/hsse.php:258 +msgid "Cancel" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1059 ../../Zotlabs/Module/Cdav.php:1387 +#: ../../Zotlabs/Module/Webpages.php:254 ../../Zotlabs/Module/Profiles.php:800 +#: ../../Zotlabs/Module/Layouts.php:185 +#: ../../Zotlabs/Module/New_channel.php:189 ../../Zotlabs/Module/Blocks.php:159 +#: ../../Zotlabs/Module/Connedit.php:930 ../../Zotlabs/Module/Cards.php:113 +#: ../../Zotlabs/Module/Articles.php:117 ../../Zotlabs/Module/Menu.php:182 +#: ../../Zotlabs/Storage/Browser.php:365 ../../Zotlabs/Storage/Browser.php:538 +#: ../../Zotlabs/Widget/Cdav.php:140 ../../Zotlabs/Widget/Cdav.php:178 +msgid "Create" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1060 +msgid "Sorry! Editing of recurrent events is not yet implemented." +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1070 ../../Zotlabs/Storage/Browser.php:293 +#: ../../Zotlabs/Storage/Browser.php:388 ../../Zotlabs/Storage/Browser.php:403 +#: ../../Zotlabs/Widget/Appcategories.php:43 +#: ../../include/contact_widgets.php:108 ../../include/contact_widgets.php:152 +#: ../../include/contact_widgets.php:197 ../../include/contact_widgets.php:232 +#: ../../include/taxonomy.php:418 ../../include/taxonomy.php:500 +#: ../../include/taxonomy.php:520 ../../include/taxonomy.php:541 +msgid "Categories" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1372 ../../Zotlabs/Module/Group.php:155 +#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth.php:139 +#: ../../Zotlabs/Module/Oauth2.php:118 ../../Zotlabs/Module/Oauth2.php:146 +#: ../../Zotlabs/Module/Wiki.php:218 ../../Zotlabs/Module/Connedit.php:915 +#: ../../Zotlabs/Module/Sharedwithme.php:106 ../../Zotlabs/Module/Chat.php:257 +#: ../../Zotlabs/Module/Admin/Channels.php:159 +#: ../../Zotlabs/Storage/Browser.php:377 +#: ../../Zotlabs/Lib/NativeWikiPage.php:564 +#: ../../Zotlabs/Widget/Wiki_page_history.php:22 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:172 +msgid "Name" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1373 ../../Zotlabs/Module/Connedit.php:916 +msgid "Organisation" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1374 ../../Zotlabs/Module/Connedit.php:917 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2617 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2678 +msgid "Title" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1375 ../../Zotlabs/Module/Profiles.php:788 +#: ../../Zotlabs/Module/Connedit.php:918 +msgid "Phone" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1376 ../../Zotlabs/Module/Profiles.php:789 +#: ../../Zotlabs/Module/Connedit.php:919 +#: ../../Zotlabs/Module/Admin/Accounts.php:171 +#: ../../Zotlabs/Module/Admin/Accounts.php:183 ../../include/network.php:1737 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:56 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:57 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57 +msgid "Email" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1377 ../../Zotlabs/Module/Profiles.php:790 +#: ../../Zotlabs/Module/Connedit.php:920 +msgid "Instant messenger" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1378 ../../Zotlabs/Module/Profiles.php:791 +#: ../../Zotlabs/Module/Connedit.php:921 +msgid "Website" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1379 ../../Zotlabs/Module/Profiles.php:504 +#: ../../Zotlabs/Module/Profiles.php:792 ../../Zotlabs/Module/Locs.php:129 +#: ../../Zotlabs/Module/Connedit.php:922 +#: ../../Zotlabs/Module/Admin/Channels.php:160 +msgid "Address" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1380 ../../Zotlabs/Module/Profiles.php:793 +#: ../../Zotlabs/Module/Connedit.php:923 +msgid "Note" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1381 ../../Zotlabs/Module/Profiles.php:794 +#: ../../Zotlabs/Module/Connedit.php:924 ../../include/connections.php:734 +#: ../../include/event.php:1422 +msgid "Mobile" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1382 ../../Zotlabs/Module/Profiles.php:795 +#: ../../Zotlabs/Module/Connedit.php:925 ../../include/connections.php:735 +#: ../../include/event.php:1423 +msgid "Home" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1383 ../../Zotlabs/Module/Profiles.php:796 +#: ../../Zotlabs/Module/Connedit.php:926 ../../include/connections.php:738 +#: ../../include/event.php:1426 +msgid "Work" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1385 ../../Zotlabs/Module/Profiles.php:798 +#: ../../Zotlabs/Module/Connedit.php:928 +msgid "Add Contact" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1386 ../../Zotlabs/Module/Profiles.php:799 +#: ../../Zotlabs/Module/Connedit.php:929 +msgid "Add Field" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1391 ../../Zotlabs/Module/Connedit.php:934 +msgid "P.O. Box" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1392 ../../Zotlabs/Module/Connedit.php:935 +msgid "Additional" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1393 ../../Zotlabs/Module/Connedit.php:936 +msgid "Street" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1394 ../../Zotlabs/Module/Connedit.php:937 +msgid "Locality" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1395 ../../Zotlabs/Module/Connedit.php:938 +msgid "Region" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1396 ../../Zotlabs/Module/Connedit.php:939 +msgid "ZIP Code" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1397 ../../Zotlabs/Module/Profiles.php:759 +#: ../../Zotlabs/Module/Connedit.php:940 +msgid "Country" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1456 +msgid "Default Calendar" +msgstr "" + +#: ../../Zotlabs/Module/Cdav.php:1467 +msgid "Default Addressbook" +msgstr "" + +#: ../../Zotlabs/Module/Api.php:74 ../../Zotlabs/Module/Api.php:95 +msgid "Authorize application connection" +msgstr "" + +#: ../../Zotlabs/Module/Api.php:75 +msgid "Return to your app and insert this Security Code:" +msgstr "" + +#: ../../Zotlabs/Module/Api.php:85 +msgid "Please login to continue." +msgstr "" + +#: ../../Zotlabs/Module/Api.php:97 +msgid "" +"Do you want to authorize this application to access your posts and contacts, " +"and/or create new posts for you?" +msgstr "" + +#: ../../Zotlabs/Module/Api.php:98 ../../Zotlabs/Module/Events.php:478 +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Profiles.php:683 +#: ../../Zotlabs/Module/Import.php:634 ../../Zotlabs/Module/Import.php:638 +#: ../../Zotlabs/Module/Import.php:639 ../../Zotlabs/Module/Defperms.php:198 +#: ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Filestorage.php:211 ../../Zotlabs/Module/Wiki.php:227 +#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 +#: ../../Zotlabs/Module/Photos.php:673 ../../Zotlabs/Module/Admin/Site.php:261 +#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177 +#: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257 +#: ../../Zotlabs/Module/Settings/Display.php:88 +#: ../../Zotlabs/Module/Settings/Channel.php:311 +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:311 +#: ../../Zotlabs/Storage/Browser.php:312 ../../Zotlabs/Storage/Browser.php:389 +#: ../../Zotlabs/Storage/Browser.php:391 ../../Zotlabs/Storage/Browser.php:552 +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:166 +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1466 +#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144 +#: ../../include/dir_fns.php:145 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +#: ../../extend/addon/hzaddons/cart/cart.php:1370 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:72 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:337 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:361 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:437 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:461 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:65 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:649 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:653 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:88 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:96 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:61 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:73 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:214 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +#: ../../view/theme/redbasic/php/config.php:99 +#: ../../view/theme/redbasic/php/config.php:116 ../../boot.php:1710 +msgid "Yes" +msgstr "" + +#: ../../Zotlabs/Module/Api.php:99 ../../Zotlabs/Module/Events.php:478 +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Profiles.php:683 +#: ../../Zotlabs/Module/Import.php:634 ../../Zotlabs/Module/Import.php:638 +#: ../../Zotlabs/Module/Import.php:639 ../../Zotlabs/Module/Defperms.php:198 +#: ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Filestorage.php:211 ../../Zotlabs/Module/Wiki.php:227 +#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:403 +#: ../../Zotlabs/Module/Connedit.php:788 ../../Zotlabs/Module/Photos.php:673 +#: ../../Zotlabs/Module/Admin/Site.php:259 ../../Zotlabs/Module/Mitem.php:176 +#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:256 +#: ../../Zotlabs/Module/Mitem.php:257 +#: ../../Zotlabs/Module/Settings/Display.php:88 +#: ../../Zotlabs/Module/Settings/Channel.php:311 +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:311 +#: ../../Zotlabs/Storage/Browser.php:312 ../../Zotlabs/Storage/Browser.php:389 +#: ../../Zotlabs/Storage/Browser.php:391 ../../Zotlabs/Storage/Browser.php:552 +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:166 +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1466 +#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144 +#: ../../include/dir_fns.php:145 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +#: ../../extend/addon/hzaddons/cart/cart.php:1370 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:72 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:338 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:362 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:438 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:462 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:65 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:649 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:653 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:88 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:96 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:61 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:73 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45 +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:214 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +#: ../../view/theme/redbasic/php/config.php:99 +#: ../../view/theme/redbasic/php/config.php:116 ../../boot.php:1710 +msgid "No" +msgstr "" + +#: ../../Zotlabs/Module/Dirsearch.php:28 ../../Zotlabs/Module/Regdir.php:52 +msgid "This site is not a directory server" +msgstr "" + +#: ../../Zotlabs/Module/Dirsearch.php:37 +msgid "This directory server requires an access token" +msgstr "" + +#: ../../Zotlabs/Module/Filer.php:53 +msgid "Enter a folder name" +msgstr "" + +#: ../../Zotlabs/Module/Filer.php:53 +msgid "or select an existing folder (doubleclick)" +msgstr "" + +#: ../../Zotlabs/Module/Filer.php:54 ../../Zotlabs/Module/Admin/Profs.php:94 +#: ../../Zotlabs/Module/Admin/Profs.php:114 ../../Zotlabs/Module/Rbmark.php:32 +#: ../../Zotlabs/Module/Rbmark.php:104 ../../Zotlabs/Widget/Notes.php:23 +#: ../../include/text.php:1151 ../../include/text.php:1163 +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:119 +msgid "Save" +msgstr "" + +#: ../../Zotlabs/Module/Filer.php:55 ../../Zotlabs/Lib/ThreadItem.php:184 +msgid "Save to Folder" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:113 +#: ../../Zotlabs/Module/Channel_calendar.php:57 +msgid "Event can not end before it has started." +msgstr "" + +#: ../../Zotlabs/Module/Events.php:115 ../../Zotlabs/Module/Events.php:124 +#: ../../Zotlabs/Module/Events.php:146 +#: ../../Zotlabs/Module/Channel_calendar.php:59 +#: ../../Zotlabs/Module/Channel_calendar.php:67 +#: ../../Zotlabs/Module/Channel_calendar.php:84 +msgid "Unable to generate preview." +msgstr "" + +#: ../../Zotlabs/Module/Events.php:122 +#: ../../Zotlabs/Module/Channel_calendar.php:65 +msgid "Event title and start time are required." +msgstr "" + +#: ../../Zotlabs/Module/Events.php:144 ../../Zotlabs/Module/Events.php:271 +#: ../../Zotlabs/Module/Channel_calendar.php:82 +#: ../../Zotlabs/Module/Channel_calendar.php:224 +msgid "Event not found." +msgstr "" + +#: ../../Zotlabs/Module/Events.php:266 ../../Zotlabs/Module/Like.php:435 +#: ../../Zotlabs/Module/Tagger.php:75 +#: ../../Zotlabs/Module/Channel_calendar.php:219 +#: ../../include/conversation.php:132 ../../include/text.php:2255 +#: ../../include/event.php:1259 +msgid "event" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:468 +msgid "Edit event title" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:468 ../../Zotlabs/Module/Events.php:473 +#: ../../Zotlabs/Module/Profiles.php:747 ../../Zotlabs/Module/Profiles.php:751 +#: ../../Zotlabs/Module/Appman.php:143 ../../Zotlabs/Module/Appman.php:144 +#: ../../include/datetime.php:211 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:334 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:358 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:434 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:458 +msgid "Required" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:470 +msgid "Categories (comma-separated list)" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:471 +msgid "Edit Category" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:471 +msgid "Category" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:474 +msgid "Edit start date and time" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:475 ../../Zotlabs/Module/Events.php:478 +msgid "Finish date and time are not known or not relevant" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:477 +msgid "Edit finish date and time" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:477 +msgid "Finish date and time" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:479 ../../Zotlabs/Module/Events.php:480 +msgid "Adjust for viewer timezone" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:479 +msgid "" +"Important for events that happen in a particular place. Not practical for " +"global holidays." +msgstr "" + +#: ../../Zotlabs/Module/Events.php:481 +msgid "Edit Description" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:483 +msgid "Edit Location" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:486 ../../Zotlabs/Module/Webpages.php:262 +#: ../../Zotlabs/Module/Photos.php:1099 ../../Zotlabs/Lib/ThreadItem.php:835 +#: ../../include/conversation.php:1402 +#: ../../extend/addon/hzaddons/hsse/hsse.php:153 +msgid "Preview" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:487 ../../include/conversation.php:1478 +#: ../../extend/addon/hzaddons/hsse/hsse.php:225 +msgid "Permission settings" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:502 +msgid "Advanced Options" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:613 +msgid "l, F j" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:641 +#: ../../Zotlabs/Module/Channel_calendar.php:371 +msgid "Edit event" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:643 +#: ../../Zotlabs/Module/Channel_calendar.php:373 +msgid "Delete event" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:669 ../../include/text.php:2074 +msgid "Link to Source" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:677 +#: ../../Zotlabs/Module/Channel_calendar.php:407 +msgid "calendar" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:696 +msgid "Edit Event" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:696 +msgid "Create Event" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:699 ../../include/channel.php:1889 +msgid "Export" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:702 ../../Zotlabs/Module/Webpages.php:261 +#: ../../Zotlabs/Module/Layouts.php:198 ../../Zotlabs/Module/Wiki.php:213 +#: ../../Zotlabs/Module/Wiki.php:409 ../../Zotlabs/Module/Blocks.php:166 +#: ../../Zotlabs/Module/Pubsites.php:61 +msgid "View" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:739 +msgid "Event removed" +msgstr "" + +#: ../../Zotlabs/Module/Events.php:742 +#: ../../Zotlabs/Module/Channel_calendar.php:494 +msgid "Failed to remove event" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:23 +msgid "Documentation Search" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:83 ../../include/nav.php:434 +msgid "About" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:84 ../../Zotlabs/Module/Group.php:156 +msgid "Members" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:85 +msgid "Administrators" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:86 +msgid "Developers" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:87 +msgid "Tutorials" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:98 +msgid "$Projectname Documentation" +msgstr "" + +#: ../../Zotlabs/Module/Help.php:99 +msgid "Contents" +msgstr "" + +#: ../../Zotlabs/Module/Bookmarks.php:62 +msgid "Bookmark added" +msgstr "" + +#: ../../Zotlabs/Module/Bookmarks.php:78 +msgid "Bookmarks App" +msgstr "" + +#: ../../Zotlabs/Module/Bookmarks.php:79 +msgid "Bookmark links from posts and manage them" +msgstr "" + +#: ../../Zotlabs/Module/Bookmarks.php:92 +msgid "My Bookmarks" +msgstr "" + +#: ../../Zotlabs/Module/Bookmarks.php:103 +msgid "My Connections Bookmarks" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:39 ../../Zotlabs/Module/Layouts.php:31 +#: ../../Zotlabs/Module/Connect.php:17 ../../Zotlabs/Module/Filestorage.php:59 +#: ../../Zotlabs/Module/Blocks.php:33 ../../Zotlabs/Module/Editlayout.php:31 +#: ../../Zotlabs/Module/Achievements.php:15 +#: ../../Zotlabs/Module/Editblock.php:31 ../../Zotlabs/Module/Cards.php:42 +#: ../../Zotlabs/Module/Editwebpage.php:32 ../../Zotlabs/Module/Profile.php:20 +#: ../../Zotlabs/Module/Articles.php:43 ../../Zotlabs/Module/Hcard.php:12 +#: ../../Zotlabs/Module/Menu.php:92 ../../include/channel.php:1439 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:49 +msgid "Requested profile is not available." +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:48 +msgid "Webpages App" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:49 +msgid "Provide managed web pages on your channel" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:69 +msgid "Import Webpage Elements" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:70 +msgid "Import selected" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:93 +msgid "Export Webpage Elements" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:94 +msgid "Export selected" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:252 ../../Zotlabs/Lib/Apps.php:341 +#: ../../include/nav.php:524 +msgid "Webpages" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:255 ../../Zotlabs/Module/Layouts.php:193 +#: ../../Zotlabs/Module/Group.php:253 ../../Zotlabs/Module/Oauth.php:173 +#: ../../Zotlabs/Module/Card_edit.php:99 ../../Zotlabs/Module/Oauth2.php:194 +#: ../../Zotlabs/Module/Wiki.php:211 ../../Zotlabs/Module/Wiki.php:384 +#: ../../Zotlabs/Module/Blocks.php:160 ../../Zotlabs/Module/Editlayout.php:114 +#: ../../Zotlabs/Module/Editblock.php:114 +#: ../../Zotlabs/Module/Connections.php:320 +#: ../../Zotlabs/Module/Connections.php:362 +#: ../../Zotlabs/Module/Connections.php:382 +#: ../../Zotlabs/Module/Editwebpage.php:142 +#: ../../Zotlabs/Module/Article_edit.php:98 +#: ../../Zotlabs/Module/Admin/Profs.php:175 ../../Zotlabs/Module/Thing.php:268 +#: ../../Zotlabs/Module/Menu.php:176 ../../Zotlabs/Lib/Apps.php:557 +#: ../../Zotlabs/Lib/ThreadItem.php:148 ../../Zotlabs/Widget/Cdav.php:138 +#: ../../Zotlabs/Widget/Cdav.php:175 ../../include/channel.php:1538 +#: ../../include/channel.php:1542 ../../include/menu.php:120 +msgid "Edit" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:256 ../../Zotlabs/Module/Layouts.php:194 +#: ../../Zotlabs/Module/Wiki.php:301 ../../Zotlabs/Module/Blocks.php:161 +#: ../../Zotlabs/Module/Photos.php:1078 ../../Zotlabs/Widget/Cdav.php:136 +#: ../../include/conversation.php:1435 +#: ../../extend/addon/hzaddons/hsse/hsse.php:186 +msgid "Share" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:263 +msgid "Actions" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:264 +msgid "Page Link" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:265 +msgid "Page Title" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:266 ../../Zotlabs/Module/Layouts.php:191 +#: ../../Zotlabs/Module/Blocks.php:157 ../../Zotlabs/Module/Menu.php:178 +msgid "Created" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:267 ../../Zotlabs/Module/Layouts.php:192 +#: ../../Zotlabs/Module/Blocks.php:158 ../../Zotlabs/Module/Menu.php:179 +msgid "Edited" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:295 +msgid "Invalid file type." +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:307 +msgid "Error opening zip file" +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:318 +msgid "Invalid folder path." +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:345 +msgid "No webpage elements detected." +msgstr "" + +#: ../../Zotlabs/Module/Webpages.php:420 +msgid "Import complete." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:26 ../../Zotlabs/Module/Profiles.php:186 +#: ../../Zotlabs/Module/Profiles.php:243 ../../Zotlabs/Module/Profiles.php:661 +msgid "Profile not found." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:46 +msgid "Profile deleted." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:70 ../../Zotlabs/Module/Profiles.php:107 +msgid "Profile-" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:92 ../../Zotlabs/Module/Profiles.php:129 +msgid "New profile created." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:113 +msgid "Profile unavailable to clone." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:148 +msgid "Profile unavailable to export." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:254 +msgid "Profile Name is required." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:461 +msgid "Marital Status" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:465 +msgid "Romantic Partner" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:469 ../../Zotlabs/Module/Profiles.php:774 +msgid "Likes" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:473 ../../Zotlabs/Module/Profiles.php:775 +msgid "Dislikes" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:477 ../../Zotlabs/Module/Profiles.php:782 +msgid "Work/Employment" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:480 +msgid "Religion" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:484 +msgid "Political Views" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:488 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:74 +msgid "Gender" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:492 +msgid "Sexual Preference" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:496 +msgid "Homepage" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:500 +msgid "Interests" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:596 +msgid "Profile updated." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:680 +msgid "Hide your connections list from viewers of this profile" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:724 +msgid "Edit Profile Details" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:726 +msgid "View this profile" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:727 ../../Zotlabs/Module/Profiles.php:826 +#: ../../include/channel.php:1561 +msgid "Edit visibility" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:728 +msgid "Profile Tools" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:729 +msgid "Change cover photo" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:730 ../../include/channel.php:1531 +msgid "Change profile photo" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:731 +msgid "Create a new profile using these settings" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:732 +msgid "Clone this profile" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:733 +msgid "Delete this profile" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:734 +msgid "Add profile things" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:735 +msgid "Personal" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:737 +msgid "Relationship" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:738 ../../Zotlabs/Widget/Newmember.php:51 +#: ../../include/datetime.php:58 +msgid "Miscellaneous" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:740 +msgid "Import profile from file" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:741 +msgid "Export profile to file" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:742 +msgid "Your gender" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:743 +msgid "Marital status" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:744 +msgid "Sexual preference" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:747 +msgid "Profile name" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:749 +msgid "This is your default profile." +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:751 +msgid "Your full name" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:752 +msgid "Short title/tescription" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:752 +msgid "Maximal 190 characters" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:755 +msgid "Street address" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:756 +msgid "Locality/City" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:757 +msgid "Region/State" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:758 +msgid "Postal/Zip code" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:764 +msgid "Who (if applicable)" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:764 +msgid "Examples: cathy123, Cathy Williams, cathy@example.com" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:765 +msgid "Since (date)" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:768 +msgid "Tell us about yourself" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:769 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:68 +msgid "Homepage URL" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:770 +msgid "Hometown" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:771 +msgid "Political views" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:772 +msgid "Religious views" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:773 +msgid "Keywords used in directory listings" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:773 +msgid "Example: fishing photography software" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:776 +msgid "Musical interests" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:777 +msgid "Books, literature" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:778 +msgid "Television" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:779 +msgid "Film/Dance/Culture/Entertainment" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:780 +msgid "Hobbies/Interests" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:781 +msgid "Love/Romance" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:783 +msgid "School/Education" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:784 +msgid "Contact information and social networks" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:785 +msgid "My other channels" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:787 +msgid "Communications" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:822 ../../include/channel.php:1557 +msgid "Profile Image" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:832 ../../include/channel.php:1538 +#: ../../include/nav.php:115 +msgid "Edit Profiles" +msgstr "" + +#: ../../Zotlabs/Module/Profiles.php:833 ../../Zotlabs/Module/Wiki.php:214 +#: ../../Zotlabs/Module/Manage.php:145 ../../Zotlabs/Module/Chat.php:262 +msgid "Create New" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:68 ../../Zotlabs/Module/Import_items.php:48 +msgid "Nothing to import." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:83 ../../Zotlabs/Module/Import.php:99 +#: ../../Zotlabs/Module/Import_items.php:72 +msgid "Unable to download data from old server" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:106 ../../Zotlabs/Module/Import_items.php:77 +msgid "Imported file is empty." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:162 +#, php-format +msgid "Your service plan only allows %d channels." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:189 +msgid "No channel. Import failed." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:593 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:142 +msgid "Import completed." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:621 +msgid "You must be logged in to use this feature." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:626 +msgid "Import Channel" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:627 +msgid "" +"Use this form to import an existing channel from a different server/hub. You " +"may retrieve the channel identity from the old server/hub via the network or " +"provide an export file." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:628 +#: ../../Zotlabs/Module/Import_items.php:127 +msgid "File to Upload" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:629 +msgid "Or provide the old server/hub details" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:631 +msgid "Your old identity address (xyz@example.com)" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:632 +msgid "Your old login email address" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:633 +msgid "Your old login password" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:634 +msgid "Import a few months of posts if possible (limited by available memory" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:636 +msgid "" +"For either option, please choose whether to make this hub your new primary " +"address, or whether your old location should continue this role. You will be " +"able to post from either location, but only one can be marked as the primary " +"location for files, photos, and media." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:638 +msgid "Make this hub my primary location" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:639 +msgid "Move this channel (disable all previous locations)" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:640 +msgid "Use this channel nickname instead of the one provided" +msgstr "" + +#: ../../Zotlabs/Module/Import.php:640 +msgid "" +"Leave blank to keep your existing channel nickname. You will be randomly " +"assigned a similar nickname if either name is already allocated on this site." +msgstr "" + +#: ../../Zotlabs/Module/Import.php:642 +msgid "" +"This process may take several minutes to complete. Please submit the form " +"only once and leave this page open until finished." +msgstr "" + +#: ../../Zotlabs/Module/Like.php:93 +msgid "Like/Dislike" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:98 +msgid "This action is restricted to members." +msgstr "" + +#: ../../Zotlabs/Module/Like.php:99 +msgid "" +"Please login with your $Projectname ID or register as a new $Projectname member to continue." +msgstr "" + +#: ../../Zotlabs/Module/Like.php:154 ../../Zotlabs/Module/Like.php:180 +#: ../../Zotlabs/Module/Like.php:218 +msgid "Invalid request." +msgstr "" + +#: ../../Zotlabs/Module/Like.php:166 ../../include/conversation.php:135 +msgid "channel" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:195 +msgid "thing" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:241 +msgid "Channel unavailable." +msgstr "" + +#: ../../Zotlabs/Module/Like.php:277 +msgid "Previous action reversed." +msgstr "" + +#: ../../Zotlabs/Module/Like.php:433 ../../Zotlabs/Module/Tagger.php:71 +#: ../../Zotlabs/Module/Subthread.php:112 ../../Zotlabs/Lib/Activity.php:2971 +#: ../../include/conversation.php:128 ../../include/text.php:2252 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1597 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1895 +#: ../../extend/addon/hzaddons/redphotos/redphotohelper.php:71 +msgid "photo" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:433 ../../Zotlabs/Module/Subthread.php:112 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1597 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1895 +msgid "status" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:469 ../../Zotlabs/Lib/Activity.php:3006 +#: ../../include/conversation.php:174 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1537 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1932 +#, php-format +msgid "%1$s likes %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:471 ../../Zotlabs/Lib/Activity.php:3008 +#: ../../include/conversation.php:177 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1934 +#, php-format +msgid "%1$s doesn't like %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:473 +#, php-format +msgid "%1$s agrees with %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:475 +#, php-format +msgid "%1$s doesn't agree with %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:477 +#, php-format +msgid "%1$s abstains from a decision on %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:479 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2184 +#, php-format +msgid "%1$s is attending %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:481 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2186 +#, php-format +msgid "%1$s is not attending %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:483 +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2188 +#, php-format +msgid "%1$s may attend %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Like.php:592 +msgid "Action completed." +msgstr "" + +#: ../../Zotlabs/Module/Like.php:593 +msgid "Thank you." +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:68 ../../Zotlabs/Module/Connedit.php:89 +msgid "Could not access contact record." +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:112 +#: ../../Zotlabs/Module/Settings/Channel.php:267 +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:54 +#: ../../extend/addon/hzaddons/piwik/piwik.php:116 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:82 +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:93 +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171 +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:54 +#: ../../extend/addon/hzaddons/twitter/twitter.php:494 +#: ../../extend/addon/hzaddons/logrot/logrot.php:54 +msgid "Settings updated." +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:190 +msgid "Default Permissions App" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:191 +msgid "Set custom default permissions for new connections" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:255 ../../Zotlabs/Module/Connedit.php:859 +msgid "Connection Default Permissions" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:256 ../../Zotlabs/Module/Connedit.php:860 +msgid "Apply these permissions automatically" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:256 +#: ../../Zotlabs/Module/Settings/Channel.php:472 +msgid "" +"If enabled, connection requests will be approved without your interaction" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:257 ../../Zotlabs/Module/Connedit.php:861 +msgid "Permission role" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:257 +#: ../../Zotlabs/Module/New_channel.php:157 +#: ../../Zotlabs/Module/New_channel.php:164 +#: ../../Zotlabs/Module/Connedit.php:861 +#: ../../Zotlabs/Widget/Notifications.php:182 ../../include/nav.php:324 +msgid "Loading" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:258 ../../Zotlabs/Module/Connedit.php:862 +msgid "Add permission role" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:262 ../../Zotlabs/Module/Connedit.php:875 +msgid "" +"The permissions indicated on this page will be applied to all new " +"connections." +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:263 +msgid "Automatic approval settings" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Connedit.php:895 +#: ../../Zotlabs/Module/Tokens.php:183 ../../Zotlabs/Module/Permcats.php:124 +msgid "inherited" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:267 ../../Zotlabs/Module/Connedit.php:900 +#: ../../Zotlabs/Module/Tokens.php:181 ../../Zotlabs/Module/Permcats.php:122 +msgid "My Settings" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:270 ../../Zotlabs/Module/Connedit.php:902 +#: ../../Zotlabs/Module/Tokens.php:186 ../../Zotlabs/Module/Permcats.php:127 +msgid "Individual Permissions" +msgstr "" + +#: ../../Zotlabs/Module/Defperms.php:271 +msgid "" +"Some individual permissions may have been preset or locked based on your " +"channel type and privacy settings." +msgstr "" + +#: ../../Zotlabs/Module/Layouts.php:129 ../../Zotlabs/Module/Layouts.php:189 +#: ../../Zotlabs/Module/Editlayout.php:128 +msgid "Layout Name" +msgstr "" + +#: ../../Zotlabs/Module/Layouts.php:132 ../../Zotlabs/Module/Editlayout.php:129 +msgid "Layout Description (Optional)" +msgstr "" + +#: ../../Zotlabs/Module/Layouts.php:184 ../../include/text.php:2700 +msgid "Layouts" +msgstr "" + +#: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:348 +#: ../../include/nav.php:174 ../../include/nav.php:320 +#: ../../include/help.php:117 ../../include/help.php:125 +msgid "Help" +msgstr "" + +#: ../../Zotlabs/Module/Layouts.php:186 +msgid "Comanche page description language help" +msgstr "" + +#: ../../Zotlabs/Module/Layouts.php:190 +msgid "Layout Description" +msgstr "" + +#: ../../Zotlabs/Module/Layouts.php:195 +msgid "Download PDL file" +msgstr "" + +#: ../../Zotlabs/Module/Pubstream.php:20 +msgid "Public Stream App" +msgstr "" + +#: ../../Zotlabs/Module/Pubstream.php:21 +msgid "The unmoderated public stream of this hub" +msgstr "" + +#: ../../Zotlabs/Module/Pubstream.php:95 ../../Zotlabs/Module/Display.php:76 +#: ../../Zotlabs/Module/Channel.php:224 ../../Zotlabs/Module/Hq.php:125 +#: ../../Zotlabs/Module/Network.php:205 +msgid "Reset form" +msgstr "" + +#: ../../Zotlabs/Module/Pubstream.php:105 ../../Zotlabs/Lib/Apps.php:375 +#: ../../Zotlabs/Widget/Notifications.php:162 +msgid "Public Stream" +msgstr "" + +#: ../../Zotlabs/Module/Sse_bs.php:540 ../../Zotlabs/Module/Ping.php:672 +msgid "Private forum" +msgstr "" + +#: ../../Zotlabs/Module/Sse_bs.php:540 ../../Zotlabs/Module/Ping.php:672 +msgid "Public forum" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:46 +msgid "Privacy group created." +msgstr "" + +#: ../../Zotlabs/Module/Group.php:49 +msgid "Could not create privacy group." +msgstr "" + +#: ../../Zotlabs/Module/Group.php:62 ../../Zotlabs/Module/Group.php:214 +#: ../../include/items.php:4491 +msgid "Privacy group not found." +msgstr "" + +#: ../../Zotlabs/Module/Group.php:81 +msgid "Privacy group updated." +msgstr "" + +#: ../../Zotlabs/Module/Group.php:107 +msgid "Privacy Groups App" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:108 +msgid "Management of privacy groups" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:142 ../../Zotlabs/Module/Group.php:154 +#: ../../Zotlabs/Lib/Group.php:324 ../../Zotlabs/Lib/Apps.php:364 +#: ../../Zotlabs/Widget/Activity_filter.php:82 ../../include/group.php:321 +#: ../../include/acl_selectors.php:86 ../../include/nav.php:101 +msgid "Privacy Groups" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:143 +msgid "Add Group" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:147 +msgid "Privacy group name" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:148 ../../Zotlabs/Module/Group.php:257 +msgid "Members are visible to other channels" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:183 +msgid "Privacy group removed." +msgstr "" + +#: ../../Zotlabs/Module/Group.php:186 +msgid "Unable to remove privacy group." +msgstr "" + +#: ../../Zotlabs/Module/Group.php:252 +#, php-format +msgid "Privacy Group: %s" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:254 +msgid "Privacy group name: " +msgstr "" + +#: ../../Zotlabs/Module/Group.php:259 +msgid "Delete Group" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:270 +msgid "Group members" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:272 +msgid "Not in this group" +msgstr "" + +#: ../../Zotlabs/Module/Group.php:304 +msgid "Click a channel to toggle membership" +msgstr "" + +#: ../../Zotlabs/Module/Removeme.php:35 +msgid "" +"Channel removals are not allowed within 48 hours of changing the account " +"password." +msgstr "" + +#: ../../Zotlabs/Module/Removeme.php:60 +msgid "Remove This Channel" +msgstr "" + +#: ../../Zotlabs/Module/Removeme.php:61 ../../Zotlabs/Module/Changeaddr.php:78 +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "WARNING: " +msgstr "" + +#: ../../Zotlabs/Module/Removeme.php:61 +msgid "This channel will be completely removed from the network. " +msgstr "" + +#: ../../Zotlabs/Module/Removeme.php:61 +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "This action is permanent and can not be undone!" +msgstr "" + +#: ../../Zotlabs/Module/Removeme.php:62 ../../Zotlabs/Module/Changeaddr.php:79 +#: ../../Zotlabs/Module/Removeaccount.php:59 +msgid "Please enter your password for verification:" +msgstr "" + +#: ../../Zotlabs/Module/Removeme.php:64 +#: ../../Zotlabs/Module/Settings/Channel.php:596 +msgid "Remove Channel" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:39 ../../Zotlabs/Module/Appman.php:56 +msgid "App installed." +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:49 +msgid "Malformed app." +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:132 +msgid "Embed code" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:138 +msgid "Edit App" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:138 +msgid "Create App" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:143 +msgid "Name of app" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:144 +msgid "Location (URL) of app" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:146 +msgid "Photo icon URL" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:146 +msgid "80 x 80 pixels - optional" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:147 +msgid "Categories (optional, comma separated list)" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:148 +msgid "Version ID" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:149 +msgid "Price of app" +msgstr "" + +#: ../../Zotlabs/Module/Appman.php:150 +msgid "Location (URL) to purchase app" +msgstr "" + +#: ../../Zotlabs/Module/Changeaddr.php:35 +msgid "" +"Channel name changes are not allowed within 48 hours of changing the account " +"password." +msgstr "" + +#: ../../Zotlabs/Module/Changeaddr.php:46 ../../include/channel.php:225 +#: ../../include/channel.php:706 +msgid "Reserved nickname. Please choose another." +msgstr "" + +#: ../../Zotlabs/Module/Changeaddr.php:51 ../../include/channel.php:230 +#: ../../include/channel.php:711 +msgid "" +"Nickname has unsupported characters or is already being used on this site." +msgstr "" + +#: ../../Zotlabs/Module/Changeaddr.php:77 +msgid "Change channel nickname/address" +msgstr "" + +#: ../../Zotlabs/Module/Changeaddr.php:78 +msgid "Any/all connections on other networks will be lost!" +msgstr "" + +#: ../../Zotlabs/Module/Changeaddr.php:80 +msgid "New channel address" +msgstr "" + +#: ../../Zotlabs/Module/Changeaddr.php:81 +msgid "Rename Channel" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:45 +msgid "Name is required" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:49 +msgid "Key and Secret are required" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:100 +msgid "OAuth Apps Manager App" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:101 +msgid "OAuth authentication tokens for mobile and remote apps" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:110 ../../Zotlabs/Module/Oauth.php:136 +#: ../../Zotlabs/Module/Oauth.php:172 ../../Zotlabs/Module/Oauth2.php:143 +#: ../../Zotlabs/Module/Oauth2.php:193 +msgid "Add application" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth2.php:118 +#: ../../Zotlabs/Module/Oauth2.php:146 +msgid "Name of application" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:140 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:596 +#: ../../extend/addon/hzaddons/twitter/twitter.php:505 +msgid "Consumer Key" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:115 +#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 +msgid "Automatically generated - change if desired. Max length 20" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:115 ../../Zotlabs/Module/Oauth.php:141 +#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:595 +#: ../../extend/addon/hzaddons/twitter/twitter.php:506 +msgid "Consumer Secret" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth.php:142 +#: ../../Zotlabs/Module/Oauth2.php:120 ../../Zotlabs/Module/Oauth2.php:148 +msgid "Redirect" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth2.php:120 +#: ../../Zotlabs/Module/Oauth2.php:148 +msgid "" +"Redirect URI - leave blank unless your application specifically requires this" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Oauth.php:143 +msgid "Icon url" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Sources.php:123 +#: ../../Zotlabs/Module/Sources.php:158 +msgid "Optional" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:128 +msgid "Application not found." +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:171 +msgid "Connected OAuth Apps" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:175 ../../Zotlabs/Module/Oauth2.php:196 +msgid "Client key starts with" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:176 ../../Zotlabs/Module/Oauth2.php:197 +msgid "No name" +msgstr "" + +#: ../../Zotlabs/Module/Oauth.php:177 ../../Zotlabs/Module/Oauth2.php:198 +msgid "Remove authorization" +msgstr "" + +#: ../../Zotlabs/Module/Email_resend.php:12 +#: ../../Zotlabs/Module/Email_validation.php:24 +msgid "Token verification failed." +msgstr "" + +#: ../../Zotlabs/Module/Email_resend.php:30 +msgid "Email verification resent" +msgstr "" + +#: ../../Zotlabs/Module/Email_resend.php:33 +msgid "Unable to resend email verification message." +msgstr "" + +#: ../../Zotlabs/Module/Search.php:17 +#: ../../Zotlabs/Module/Viewconnections.php:23 +#: ../../Zotlabs/Module/Display.php:26 ../../Zotlabs/Module/Photos.php:519 +#: ../../Zotlabs/Module/Directory.php:73 ../../Zotlabs/Module/Directory.php:78 +#: ../../Zotlabs/Module/Ratings.php:83 +msgid "Public access denied." +msgstr "" + +#: ../../Zotlabs/Module/Search.php:41 ../../Zotlabs/Module/Connections.php:378 +#: ../../Zotlabs/Lib/Apps.php:353 ../../Zotlabs/Widget/Sitesearch.php:31 +#: ../../Zotlabs/Widget/Activity_filter.php:193 ../../include/text.php:1150 +#: ../../include/text.php:1162 ../../include/acl_selectors.php:148 +#: ../../include/nav.php:188 +msgid "Search" +msgstr "" + +#: ../../Zotlabs/Module/Search.php:222 +#, php-format +msgid "Items tagged with: %s" +msgstr "" + +#: ../../Zotlabs/Module/Search.php:224 +#, php-format +msgid "Search results for: %s" +msgstr "" + +#: ../../Zotlabs/Module/Moderate.php:67 +msgid "Comment approved" +msgstr "" + +#: ../../Zotlabs/Module/Moderate.php:71 +msgid "Comment deleted" +msgstr "" + +#: ../../Zotlabs/Module/Rpost.php:150 ../../Zotlabs/Module/Editpost.php:109 +msgid "Edit post" +msgstr "" + +#: ../../Zotlabs/Module/Oexchange.php:27 +msgid "Unable to find your hub." +msgstr "" + +#: ../../Zotlabs/Module/Oexchange.php:41 +msgid "Post successful." +msgstr "" + +#: ../../Zotlabs/Module/Chanview.php:95 ../../Zotlabs/Module/Card_edit.php:44 +#: ../../Zotlabs/Module/Wall_upload.php:31 ../../Zotlabs/Module/Page.php:75 +#: ../../Zotlabs/Module/Block.php:41 ../../Zotlabs/Module/Article_edit.php:44 +#: ../../Zotlabs/Module/Attach.php:21 ../../Zotlabs/Module/Cal.php:31 +#: ../../Zotlabs/Module/Attach_edit.php:52 +msgid "Channel not found." +msgstr "" + +#: ../../Zotlabs/Module/Chanview.php:132 +msgid "toggle full screen mode" +msgstr "" + +#: ../../Zotlabs/Module/Tagger.php:50 +msgid "Post not found." +msgstr "" + +#: ../../Zotlabs/Module/Tagger.php:79 ../../Zotlabs/Lib/Activity.php:2971 +#: ../../include/conversation.php:158 ../../include/text.php:2258 +#: ../../include/markdown.php:204 ../../include/bbcode.php:523 +msgid "post" +msgstr "" + +#: ../../Zotlabs/Module/Tagger.php:81 ../../include/conversation.php:160 +#: ../../include/text.php:2260 +msgid "comment" +msgstr "" + +#: ../../Zotlabs/Module/Tagger.php:121 +#, php-format +msgid "%1$s tagged %2$s's %3$s with %4$s" +msgstr "" + +#: ../../Zotlabs/Module/Import_items.php:93 +#, php-format +msgid "Warning: Database versions differ by %1$d updates." +msgstr "" + +#: ../../Zotlabs/Module/Import_items.php:108 +msgid "Import completed" +msgstr "" + +#: ../../Zotlabs/Module/Import_items.php:125 +msgid "Import Items" +msgstr "" + +#: ../../Zotlabs/Module/Import_items.php:126 +msgid "Use this form to import existing posts and content from an export file." +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:65 ../../Zotlabs/Module/Connect.php:118 +msgid "Continue" +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:99 +msgid "Premium Channel Setup" +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:101 +msgid "Enable premium channel connection restrictions" +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:102 +msgid "" +"Please enter your restrictions or conditions, such as paypal receipt, usage " +"guidelines, etc." +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:104 ../../Zotlabs/Module/Connect.php:124 +msgid "" +"This channel may require additional steps or acknowledgement of the " +"following conditions prior to connecting:" +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:105 +msgid "" +"Potential connections will then see the following text before proceeding:" +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:106 ../../Zotlabs/Module/Connect.php:127 +msgid "" +"By continuing, I certify that I have complied with any instructions provided " +"on this page." +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:115 +msgid "(No specific instructions have been provided by the channel owner.)" +msgstr "" + +#: ../../Zotlabs/Module/Connect.php:123 +msgid "Restricted or Premium Channel" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:147 ../../Zotlabs/Module/Manage.php:138 +#, php-format +msgid "You have created %1$.0f of %2$.0f allowed channels." +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:159 +msgid "Your real name is recommended." +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:160 +msgid "" +"Examples: \"Bob Jameson\", \"Lisa and her Horses\", \"Soccer\", \"Aviation " +"Group\"" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:165 +msgid "" +"This will be used to create a unique network address (like an email address)." +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:167 +msgid "Allowed characters are a-z 0-9, - and _" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:175 +msgid "Channel name" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:177 +#: ../../Zotlabs/Module/Register.php:263 +msgid "Choose a short nickname" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:178 +#: ../../Zotlabs/Module/Register.php:264 +#: ../../Zotlabs/Module/Settings/Channel.php:537 +msgid "Channel role and privacy" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:178 +msgid "" +"Select a channel permission role compatible with your usage needs and " +"privacy requirements." +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:178 +#: ../../Zotlabs/Module/Register.php:264 +msgid "Read more about channel permission roles" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:181 +msgid "Create a Channel" +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:182 +msgid "" +"A channel is a unique network identity. It can represent a person (social " +"network profile), a forum (group), a business or celebrity page, a newsfeed, " +"and many other things." +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:183 +msgid "" +"or import an existing channel from another location." +msgstr "" + +#: ../../Zotlabs/Module/New_channel.php:188 +msgid "Validate" +msgstr "" + +#: ../../Zotlabs/Module/Apps.php:50 ../../Zotlabs/Widget/Appstore.php:14 +msgid "Available Apps" +msgstr "" + +#: ../../Zotlabs/Module/Apps.php:50 +msgid "Installed Apps" +msgstr "" + +#: ../../Zotlabs/Module/Apps.php:53 +msgid "Manage Apps" +msgstr "" + +#: ../../Zotlabs/Module/Apps.php:54 +msgid "Create Custom App" +msgstr "" + +#: ../../Zotlabs/Module/Removeaccount.php:35 +msgid "" +"Account removals are not allowed within 48 hours of changing the account " +"password." +msgstr "" + +#: ../../Zotlabs/Module/Removeaccount.php:57 +msgid "Remove This Account" +msgstr "" + +#: ../../Zotlabs/Module/Removeaccount.php:58 +msgid "" +"This account and all its channels will be completely removed from the " +"network. " +msgstr "" + +#: ../../Zotlabs/Module/Removeaccount.php:61 +#: ../../Zotlabs/Module/Settings/Account.php:105 +msgid "Remove Account" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:14 +#: ../../Zotlabs/Module/Filestorage.php:53 +msgid "Deprecated!" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:29 ../../Zotlabs/Module/Display.php:42 +#: ../../Zotlabs/Module/Display.php:429 ../../Zotlabs/Module/Admin.php:62 +#: ../../Zotlabs/Module/Admin/Themes.php:72 +#: ../../Zotlabs/Module/Admin/Addons.php:260 ../../Zotlabs/Module/Thing.php:96 +#: ../../Zotlabs/Module/Viewsrc.php:25 ../../include/items.php:3919 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:284 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:285 +msgid "Item not found." +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:109 +#: ../../Zotlabs/Module/Attach_edit.php:69 +msgid "File not found." +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:157 +msgid "Permission Denied." +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:190 +msgid "Edit file permissions" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:195 +#: ../../Zotlabs/Module/Connedit.php:682 ../../Zotlabs/Module/Chat.php:241 +#: ../../Zotlabs/Module/Photos.php:678 ../../Zotlabs/Module/Photos.php:1047 +#: ../../Zotlabs/Module/Thing.php:321 ../../Zotlabs/Module/Thing.php:374 +#: ../../include/acl_selectors.php:153 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:254 +msgid "Permissions" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:202 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:261 +msgid "Set/edit permissions" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:203 +msgid "Include all files and sub folders" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:204 +msgid "Return to file list" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:206 +#: ../../Zotlabs/Storage/Browser.php:386 +msgid "Copy/paste this code to attach file to a post" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:207 +#: ../../Zotlabs/Storage/Browser.php:387 +msgid "Copy/paste this URL to link file from a web page" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:209 +msgid "Share this file" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:210 +msgid "Show URL to this file" +msgstr "" + +#: ../../Zotlabs/Module/Filestorage.php:211 +#: ../../Zotlabs/Storage/Browser.php:552 +msgid "Show in your contacts shared folder" +msgstr "" + +#: ../../Zotlabs/Module/Card_edit.php:17 ../../Zotlabs/Module/Card_edit.php:33 +#: ../../Zotlabs/Module/Editlayout.php:79 ../../Zotlabs/Module/Editblock.php:79 +#: ../../Zotlabs/Module/Editblock.php:95 ../../Zotlabs/Module/Editpost.php:24 +#: ../../Zotlabs/Module/Editwebpage.php:80 +#: ../../Zotlabs/Module/Article_edit.php:17 +#: ../../Zotlabs/Module/Article_edit.php:33 +msgid "Item not found" +msgstr "" + +#: ../../Zotlabs/Module/Card_edit.php:101 +#: ../../Zotlabs/Module/Editblock.php:116 ../../Zotlabs/Module/Chat.php:220 +#: ../../Zotlabs/Module/Editwebpage.php:143 +#: ../../Zotlabs/Module/Article_edit.php:100 +#: ../../include/conversation.php:1341 +#: ../../extend/addon/hzaddons/hsse/hsse.php:95 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:166 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:309 +msgid "Insert web link" +msgstr "" + +#: ../../Zotlabs/Module/Card_edit.php:117 +#: ../../Zotlabs/Module/Editblock.php:129 ../../Zotlabs/Module/Photos.php:674 +#: ../../Zotlabs/Module/Photos.php:1044 +#: ../../Zotlabs/Module/Article_edit.php:116 +#: ../../include/conversation.php:1474 +#: ../../extend/addon/hzaddons/hsse/hsse.php:221 +msgid "Title (optional)" +msgstr "" + +#: ../../Zotlabs/Module/Card_edit.php:128 +msgid "Edit Card" +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:65 +msgid "No connections." +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:80 +#: ../../Zotlabs/Module/Connections.php:288 ../../include/text.php:1044 +msgid "Accepts" +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:83 +#: ../../Zotlabs/Module/Connections.php:291 ../../include/text.php:1047 +msgid "Comments" +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:88 +#: ../../Zotlabs/Module/Connections.php:296 ../../include/text.php:1052 +msgid "Stream items" +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:93 +#: ../../Zotlabs/Module/Connections.php:301 ../../include/text.php:1057 +msgid "Wall posts" +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:97 +#: ../../Zotlabs/Module/Connections.php:305 ../../include/text.php:1061 +msgid "Nothing" +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:105 +#, php-format +msgid "Visit %s's profile [%s]" +msgstr "" + +#: ../../Zotlabs/Module/Viewconnections.php:135 +msgid "View Connections" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:54 +msgid "Name and Secret are required" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:106 +msgid "OAuth2 Apps Manager App" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:107 +msgid "OAuth2 authenticatication tokens for mobile and remote apps" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:115 +msgid "Add OAuth2 application" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:149 +msgid "Grant Types" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:122 +msgid "leave blank unless your application sepcifically requires this" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:122 ../../Zotlabs/Module/Oauth2.php:150 +msgid "Authorization scope" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:134 +msgid "OAuth2 Application not found." +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:149 ../../Zotlabs/Module/Oauth2.php:150 +msgid "leave blank unless your application specifically requires this" +msgstr "" + +#: ../../Zotlabs/Module/Oauth2.php:192 +msgid "Connected OAuth2 Apps" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:35 +#: ../../extend/addon/hzaddons/cart/cart.php:1410 +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:51 +msgid "Profile Unavailable." +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:52 +msgid "Wiki App" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:53 +msgid "Provide a wiki for your channel" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:77 +#: ../../extend/addon/hzaddons/cart/cart.php:1556 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:478 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:456 +#: ../../extend/addon/hzaddons/cart/myshop.php:37 +#: ../../extend/addon/hzaddons/cart/manual_payments.php:93 +msgid "Invalid channel" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:133 +msgid "Error retrieving wiki" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:140 +msgid "Error creating zip file export folder" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:191 +msgid "Error downloading wiki: " +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:206 ../../Zotlabs/Widget/Wiki_list.php:15 +#: ../../include/nav.php:536 +msgid "Wikis" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:212 ../../Zotlabs/Storage/Browser.php:404 +msgid "Download" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:216 +msgid "Wiki name" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:217 +msgid "Content type" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2116 +#: ../../extend/addon/hzaddons/mdpost/mdpost.php:41 +msgid "Markdown" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2114 +msgid "BBcode" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2117 +msgid "Text" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:219 ../../Zotlabs/Storage/Browser.php:378 +msgid "Type" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:220 +msgid "Any type" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:227 +msgid "Lock content type" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:228 +msgid "Create a status post for this wiki" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:229 +msgid "Edit Wiki Name" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:274 +msgid "Wiki not found" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:300 +msgid "Rename page" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:321 +msgid "Error retrieving page content" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:329 ../../Zotlabs/Module/Wiki.php:331 +msgid "New page" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:366 +msgid "Revision Comparison" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:367 ../../Zotlabs/Lib/NativeWikiPage.php:567 +#: ../../Zotlabs/Widget/Wiki_page_history.php:25 +msgid "Revert" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:374 +msgid "Short description of your changes (optional)" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:384 +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:134 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:69 +#: ../../extend/addon/hzaddons/dwpost/dwpost.php:134 +#: ../../extend/addon/hzaddons/wppost/wppost.php:173 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:98 +msgid "Source" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:394 +msgid "New page name" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:399 +msgid "Embed image from photo albums" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:400 ../../include/conversation.php:1457 +#: ../../extend/addon/hzaddons/hsse/hsse.php:208 +msgid "Embed an image from your albums" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:402 ../../Zotlabs/Module/Profile_photo.php:508 +#: ../../Zotlabs/Module/Cover_photo.php:429 ../../include/conversation.php:1459 +#: ../../include/conversation.php:1510 +#: ../../extend/addon/hzaddons/hsse/hsse.php:210 +#: ../../extend/addon/hzaddons/hsse/hsse.php:257 +msgid "OK" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:403 ../../Zotlabs/Module/Profile_photo.php:509 +#: ../../Zotlabs/Module/Cover_photo.php:430 ../../include/conversation.php:1385 +#: ../../extend/addon/hzaddons/hsse/hsse.php:139 +msgid "Choose images to embed" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:404 ../../Zotlabs/Module/Profile_photo.php:510 +#: ../../Zotlabs/Module/Cover_photo.php:431 ../../include/conversation.php:1386 +#: ../../extend/addon/hzaddons/hsse/hsse.php:140 +msgid "Choose an album" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:405 ../../Zotlabs/Module/Profile_photo.php:511 +#: ../../Zotlabs/Module/Cover_photo.php:432 +msgid "Choose a different album" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:406 ../../Zotlabs/Module/Profile_photo.php:512 +#: ../../Zotlabs/Module/Cover_photo.php:433 ../../include/conversation.php:1388 +#: ../../extend/addon/hzaddons/hsse/hsse.php:142 +msgid "Error getting album list" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:407 ../../Zotlabs/Module/Profile_photo.php:513 +#: ../../Zotlabs/Module/Cover_photo.php:434 ../../include/conversation.php:1389 +#: ../../extend/addon/hzaddons/hsse/hsse.php:143 +msgid "Error getting photo link" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:408 ../../Zotlabs/Module/Profile_photo.php:514 +#: ../../Zotlabs/Module/Cover_photo.php:435 ../../include/conversation.php:1390 +#: ../../extend/addon/hzaddons/hsse/hsse.php:144 +msgid "Error getting album" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:410 +msgid "History" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:488 +msgid "Error creating wiki. Invalid name." +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:495 +msgid "A wiki with this name already exists." +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:508 +msgid "Wiki created, but error creating Home page." +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:515 +msgid "Error creating wiki" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:539 +msgid "Error updating wiki. Invalid name." +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:559 +msgid "Error updating wiki" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:574 +msgid "Wiki delete permission denied." +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:584 +msgid "Error deleting wiki" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:617 +msgid "New page created" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:739 +msgid "Cannot delete Home" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:803 +msgid "Current Revision" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:803 +msgid "Selected Revision" +msgstr "" + +#: ../../Zotlabs/Module/Wiki.php:853 +msgid "You must be authenticated." +msgstr "" + +#: ../../Zotlabs/Module/Blocks.php:97 ../../Zotlabs/Module/Blocks.php:155 +#: ../../Zotlabs/Module/Editblock.php:113 +msgid "Block Name" +msgstr "" + +#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2698 +msgid "Blocks" +msgstr "" + +#: ../../Zotlabs/Module/Blocks.php:156 +msgid "Block Title" +msgstr "" + +#: ../../Zotlabs/Module/Dircensor.php:42 +msgid "Entry censored" +msgstr "" + +#: ../../Zotlabs/Module/Dircensor.php:45 +msgid "Entry uncensored" +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:27 ../../Zotlabs/Module/Locs.php:66 +msgid "Location not found." +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:75 +msgid "Location lookup failed." +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:79 +msgid "" +"Please select another location to become primary before removing the primary " +"location." +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:108 +msgid "Syncing locations" +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:117 +msgid "No locations found." +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:127 +msgid "Manage Channel Locations" +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:130 +#: ../../extend/addon/hzaddons/workflow/workflow.php:285 +msgid "Primary" +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:131 ../../Zotlabs/Module/Menu.php:177 +msgid "Drop" +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:133 +msgid "Sync Now" +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:134 +msgid "Please wait several minutes between consecutive operations." +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:135 +msgid "" +"When possible, drop a location by logging into that website/hub and removing " +"your channel." +msgstr "" + +#: ../../Zotlabs/Module/Locs.php:136 +msgid "Use this form to drop the location if the hub is no longer operating." +msgstr "" + +#: ../../Zotlabs/Module/Chatsvc.php:131 +msgid "Away" +msgstr "" + +#: ../../Zotlabs/Module/Chatsvc.php:136 +msgid "Online" +msgstr "" + +#: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:345 +#: ../../include/features.php:369 ../../include/nav.php:444 +msgid "Photos" +msgstr "" + +#: ../../Zotlabs/Module/Fbrowser.php:85 ../../Zotlabs/Storage/Browser.php:351 +#: ../../Zotlabs/Lib/Apps.php:340 ../../include/nav.php:452 +msgid "Files" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:120 +msgid "Could not locate selected profile." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:264 +msgid "Connection updated." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:266 +msgid "Failed to update connection record." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:309 +msgid "is now connected to" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:434 +msgid "Could not access address book record." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:482 ../../Zotlabs/Module/Connedit.php:486 +msgid "Refresh failed - channel is currently unavailable." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:501 ../../Zotlabs/Module/Connedit.php:510 +#: ../../Zotlabs/Module/Connedit.php:519 ../../Zotlabs/Module/Connedit.php:528 +#: ../../Zotlabs/Module/Connedit.php:541 +msgid "Unable to set address book parameters." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:560 +msgid "Connection has been removed." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:600 ../../Zotlabs/Lib/Apps.php:344 +#: ../../include/conversation.php:1080 ../../include/nav.php:112 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:57 +msgid "View Profile" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:603 +#, php-format +msgid "View %s's profile" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:607 +msgid "Refresh Permissions" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:610 +msgid "Fetch updated permissions" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:614 +msgid "Refresh Photo" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:617 +msgid "Fetch updated photo" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:621 ../../include/conversation.php:1090 +msgid "Recent Activity" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:624 +msgid "View recent posts and comments" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:628 +#: ../../Zotlabs/Module/Admin/Accounts.php:177 +msgid "Unblock" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:628 +#: ../../Zotlabs/Module/Admin/Accounts.php:176 +msgid "Block" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:631 +msgid "Block (or Unblock) all communications with this connection" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:632 +msgid "This connection is blocked!" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:636 +msgid "Unignore" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:636 +#: ../../Zotlabs/Module/Connections.php:344 +msgid "Ignore" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:639 +msgid "Ignore (or Unignore) all inbound communications from this connection" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:640 +msgid "This connection is ignored!" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:644 +msgid "Unarchive" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:644 +msgid "Archive" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:647 +msgid "" +"Archive (or Unarchive) this connection - mark channel dead but keep content" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:648 +msgid "This connection is archived!" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:652 +msgid "Unhide" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:652 +msgid "Hide" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:655 +msgid "Hide or Unhide this connection from your other connections" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:656 +msgid "This connection is hidden!" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:663 +msgid "Delete this connection" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:671 +msgid "Fetch Vcard" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:674 +msgid "Fetch electronic calling card for this connection" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:685 +msgid "Open Individual Permissions section by default" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:708 +msgid "Affinity" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:711 +msgid "Open Set Affinity section by default" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:715 ../../Zotlabs/Widget/Affinity.php:30 +msgid "Me" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:716 ../../Zotlabs/Widget/Affinity.php:31 +msgid "Family" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:717 +#: ../../Zotlabs/Module/Settings/Channel.php:71 +#: ../../Zotlabs/Module/Settings/Channel.php:75 +#: ../../Zotlabs/Module/Settings/Channel.php:76 +#: ../../Zotlabs/Module/Settings/Channel.php:79 +#: ../../Zotlabs/Module/Settings/Channel.php:90 +#: ../../Zotlabs/Widget/Affinity.php:32 ../../include/channel.php:505 +#: ../../include/channel.php:506 ../../include/channel.php:513 +#: ../../include/selectors.php:134 +msgid "Friends" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:718 ../../Zotlabs/Widget/Affinity.php:33 +msgid "Acquaintances" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:719 +#: ../../Zotlabs/Module/Connections.php:97 +#: ../../Zotlabs/Module/Connections.php:111 +#: ../../Zotlabs/Widget/Affinity.php:34 +msgid "All" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:748 +msgid "Filter" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:751 +msgid "Open Custom Filter section by default" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:788 +msgid "Approve this connection" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:788 +msgid "Accept connection to allow communication" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:793 +msgid "Set Affinity" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:796 +msgid "Set Profile" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:799 +msgid "Set Affinity & Profile" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:847 +msgid "This connection is unreachable from this location." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:848 +msgid "This connection may be unreachable from other channel locations." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:850 +msgid "Location independence is not supported by their network." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:856 +msgid "" +"This connection is unreachable from this location. Location independence is " +"not supported by their network." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:859 ../../include/items.php:4524 +#, php-format +msgid "Connection: %s" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:860 +msgid "Connection requests will be approved without your interaction" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:869 +msgid "This connection's primary address is" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:870 +msgid "Available locations:" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:876 +msgid "Connection Tools" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:878 +msgid "Slide to adjust your degree of friendship" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:879 ../../Zotlabs/Module/Rate.php:155 +#: ../../include/js_strings.php:20 +msgid "Rating" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:880 +msgid "Slide to adjust your rating" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:881 ../../Zotlabs/Module/Connedit.php:886 +msgid "Optionally explain your rating" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:883 +msgid "Custom Filter" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:884 +msgid "Only import posts with this text" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:884 ../../Zotlabs/Module/Connedit.php:885 +#: ../../Zotlabs/Module/Admin/Site.php:327 +#: ../../Zotlabs/Module/Admin/Site.php:328 +msgid "" +"words one per line or #tags or /patterns/ or lang=xx, leave blank to import " +"all posts" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:885 +msgid "Do not import posts with this text" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:887 +msgid "This information is public!" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:892 +msgid "Connection Pending Approval" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:897 +#, php-format +msgid "" +"Please choose the profile you would like to display to %s when viewing your " +"profile securely." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:899 ../../Zotlabs/Module/Tokens.php:180 +msgid "Their Settings" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:903 ../../Zotlabs/Module/Tokens.php:187 +#: ../../Zotlabs/Module/Permcats.php:128 +msgid "" +"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " +"individual settings. You can not change those settings here." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:904 +msgid "" +"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " +"individual settings. You can change those settings here but they wont have " +"any impact unless the inherited setting changes." +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:905 +msgid "Last update:" +msgstr "" + +#: ../../Zotlabs/Module/Connedit.php:913 +msgid "Details" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:93 +#: ../../Zotlabs/Module/Cover_photo.php:85 +msgid "Image uploaded but image cropping failed." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:147 +#: ../../Zotlabs/Module/Profile_photo.php:284 +#: ../../include/photo/photo_driver.php:417 +msgid "Profile Photos" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:166 +#: ../../Zotlabs/Module/Cover_photo.php:212 +msgid "Image resize failed." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:254 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:298 +msgid "" +"Shift-reload the page or clear browser cache if the new photo does not " +"display immediately." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:261 +#: ../../Zotlabs/Module/Cover_photo.php:241 ../../include/photos.php:196 +msgid "Unable to process image" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:296 +#: ../../Zotlabs/Module/Cover_photo.php:265 +msgid "Image upload failed." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:315 +#: ../../Zotlabs/Module/Cover_photo.php:282 +msgid "Unable to process image." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:379 +#: ../../Zotlabs/Module/Profile_photo.php:431 +#: ../../Zotlabs/Module/Cover_photo.php:367 +#: ../../Zotlabs/Module/Cover_photo.php:382 +msgid "Photo not available." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:495 +msgid "" +"Your default profile photo is visible to anybody on the internet. Profile " +"photos for alternate profiles will inherit the permissions of the profile" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:495 +msgid "" +"Your profile photo is visible to anybody on the internet and may be " +"distributed to other websites." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:497 +#: ../../Zotlabs/Module/Cover_photo.php:420 +msgid "Upload File:" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:498 +#: ../../Zotlabs/Module/Cover_photo.php:421 +msgid "Select a profile:" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:499 +msgid "Use Photo for Profile" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:499 +msgid "Change Profile Photo" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:500 +msgid "Use" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:500 +#: ../../Zotlabs/Module/Photos.php:688 ../../Zotlabs/Module/Cover_photo.php:423 +#: ../../Zotlabs/Module/Embedphotos.php:188 +#: ../../Zotlabs/Storage/Browser.php:540 ../../Zotlabs/Widget/Cdav.php:146 +#: ../../Zotlabs/Widget/Cdav.php:182 ../../Zotlabs/Widget/Portfolio.php:110 +#: ../../Zotlabs/Widget/Album.php:97 +msgid "Upload" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:501 +#: ../../Zotlabs/Module/Photos.php:996 ../../Zotlabs/Module/Tagrm.php:137 +#: ../../Zotlabs/Module/Admin/Addons.php:459 +#: ../../Zotlabs/Module/Cover_photo.php:424 +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:91 +msgid "Remove" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:505 +#: ../../Zotlabs/Module/Profile_photo.php:506 +#: ../../Zotlabs/Module/Cover_photo.php:426 +#: ../../Zotlabs/Module/Cover_photo.php:427 +msgid "Use a photo from your albums" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:516 +#: ../../Zotlabs/Module/Cover_photo.php:438 +msgid "Select existing photo" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:535 +#: ../../Zotlabs/Module/Cover_photo.php:455 +msgid "Crop Image" +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:536 +#: ../../Zotlabs/Module/Cover_photo.php:456 +msgid "Please adjust the image cropping for optimum viewing." +msgstr "" + +#: ../../Zotlabs/Module/Profile_photo.php:538 +#: ../../Zotlabs/Module/Cover_photo.php:458 +msgid "Done Editing" +msgstr "" + +#: ../../Zotlabs/Module/Sharedwithme.php:105 +msgid "Files: shared with me" +msgstr "" + +#: ../../Zotlabs/Module/Sharedwithme.php:107 +msgid "NEW" +msgstr "" + +#: ../../Zotlabs/Module/Sharedwithme.php:108 +#: ../../Zotlabs/Storage/Browser.php:379 ../../include/text.php:1562 +msgid "Size" +msgstr "" + +#: ../../Zotlabs/Module/Sharedwithme.php:109 +#: ../../Zotlabs/Storage/Browser.php:380 +msgid "Last Modified" +msgstr "" + +#: ../../Zotlabs/Module/Sharedwithme.php:110 +msgid "Remove all files" +msgstr "" + +#: ../../Zotlabs/Module/Sharedwithme.php:111 +msgid "Remove this file" +msgstr "" + +#: ../../Zotlabs/Module/Editlayout.php:137 +msgid "Edit Layout" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:145 +msgid "Create a new channel" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:170 ../../Zotlabs/Lib/Apps.php:337 +#: ../../include/nav.php:98 +msgid "Channel Manager" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:171 +msgid "Current Channel" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:173 +msgid "Switch to one of your channels by selecting it." +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:174 +msgid "Default Channel" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:175 +msgid "Make Default" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:178 +#, php-format +msgid "%d new messages" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:179 +#, php-format +msgid "%d new introductions" +msgstr "" + +#: ../../Zotlabs/Module/Manage.php:181 +msgid "Delegated Channel" +msgstr "" + +#: ../../Zotlabs/Module/Follow.php:93 +msgid "Connection added." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:450 ../../Zotlabs/Module/Pin.php:35 +msgid "Unable to locate original post." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:736 +msgid "Empty post discarded." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:1187 +msgid "Duplicate post suppressed." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:1332 +msgid "System error. Post not saved." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:1366 +msgid "Your comment is awaiting approval." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:1496 +msgid "Unable to obtain post information from database." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:1503 +#, php-format +msgid "You have reached your limit of %1$.0f top level posts." +msgstr "" + +#: ../../Zotlabs/Module/Item.php:1510 +#, php-format +msgid "You have reached your limit of %1$.0f webpages." +msgstr "" + +#: ../../Zotlabs/Module/Rate.php:156 +msgid "Website:" +msgstr "" + +#: ../../Zotlabs/Module/Rate.php:159 +#, php-format +msgid "Remote Channel [%s] (not yet known on this site)" +msgstr "" + +#: ../../Zotlabs/Module/Rate.php:160 +msgid "Rating (this information is public)" +msgstr "" + +#: ../../Zotlabs/Module/Rate.php:161 +msgid "Optionally explain your rating (this information is public)" +msgstr "" + +#: ../../Zotlabs/Module/Page.php:39 ../../Zotlabs/Module/Block.php:29 +msgid "Invalid item." +msgstr "" + +#: ../../Zotlabs/Module/Page.php:136 ../../Zotlabs/Module/Display.php:136 +#: ../../Zotlabs/Module/Display.php:153 ../../Zotlabs/Module/Display.php:173 +#: ../../Zotlabs/Module/Display.php:179 ../../Zotlabs/Module/Block.php:77 +#: ../../Zotlabs/Web/Router.php:185 ../../Zotlabs/Lib/NativeWikiPage.php:521 +#: ../../include/help.php:132 +msgid "Page not found." +msgstr "" + +#: ../../Zotlabs/Module/Page.php:173 +msgid "" +"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " +"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, " +"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo " +"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse " +"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " +"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +msgstr "" + +#: ../../Zotlabs/Module/Xchan.php:10 +msgid "Xchan Lookup" +msgstr "" + +#: ../../Zotlabs/Module/Xchan.php:13 +msgid "Lookup xchan beginning with (or webbie): " +msgstr "" + +#: ../../Zotlabs/Module/Xchan.php:41 ../../Zotlabs/Module/Mitem.php:134 +#: ../../Zotlabs/Module/Menu.php:232 +msgid "Not found." +msgstr "" + +#: ../../Zotlabs/Module/Achievements.php:38 +msgid "Some blurb about what to do when you're new here" +msgstr "" + +#: ../../Zotlabs/Module/Subthread.php:143 +#, php-format +msgid "%1$s is following %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Subthread.php:145 +#, php-format +msgid "%1$s stopped following %2$s's %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Regmod.php:15 +msgid "Please login." +msgstr "" + +#: ../../Zotlabs/Module/Editblock.php:138 +msgid "Edit Block" +msgstr "" + +#: ../../Zotlabs/Module/Impel.php:43 ../../include/bbcode.php:316 +msgid "webpage" +msgstr "" + +#: ../../Zotlabs/Module/Impel.php:48 ../../include/bbcode.php:322 +msgid "block" +msgstr "" + +#: ../../Zotlabs/Module/Impel.php:53 ../../include/bbcode.php:319 +msgid "layout" +msgstr "" + +#: ../../Zotlabs/Module/Impel.php:60 ../../include/bbcode.php:325 +msgid "menu" +msgstr "" + +#: ../../Zotlabs/Module/Impel.php:185 +#, php-format +msgid "%s element installed" +msgstr "" + +#: ../../Zotlabs/Module/Impel.php:188 +#, php-format +msgid "%s element installation failed" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:25 ../../Zotlabs/Widget/Pubsites.php:12 +msgid "Public Hubs" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:28 +msgid "" +"The listed hubs allow public registration for the $Projectname network. All " +"hubs in the network are interlinked so membership on any of them conveys " +"membership in the network as a whole. Some hubs may require subscription or " +"provide tiered service plans. The hub itself may provide " +"additional details." +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Hub URL" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Access Type" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Registration Policy" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Stats" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:34 +msgid "Software" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:36 ../../Zotlabs/Module/Ratings.php:97 +#: ../../include/conversation.php:1130 +msgid "Ratings" +msgstr "" + +#: ../../Zotlabs/Module/Pubsites.php:50 +msgid "Rate" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:29 ../../Zotlabs/Module/Channel.php:42 +#: ../../Zotlabs/Module/Ochannel.php:32 +msgid "You must be logged in to see this page." +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:100 +msgid "Chatrooms App" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:101 +msgid "Access Controlled Chatrooms" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:194 +msgid "Room not found" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:210 +msgid "Leave Room" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:211 +msgid "Delete Room" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:212 +msgid "I am away right now" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:213 +msgid "I am online" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:215 +msgid "Bookmark this room" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:218 ../../include/conversation.php:1380 +#: ../../extend/addon/hzaddons/hsse/hsse.php:134 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:119 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:240 +msgid "Please enter a link URL:" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:219 ../../Zotlabs/Lib/ThreadItem.php:839 +#: ../../include/conversation.php:1508 +#: ../../extend/addon/hzaddons/hsse/hsse.php:255 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:172 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:315 +msgid "Encrypt text" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:238 +msgid "New Chatroom" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:239 +msgid "Chatroom name" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:240 +msgid "Expiration of chats (minutes)" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:256 +#, php-format +msgid "%1$s's Chatrooms" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:261 +msgid "No chatrooms available" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:265 +msgid "Expiration" +msgstr "" + +#: ../../Zotlabs/Module/Chat.php:266 +msgid "min" +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:61 +msgid "Channel Export App" +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:62 +msgid "Export your channel" +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:72 ../../Zotlabs/Module/Uexport.php:73 +msgid "Export Channel" +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:74 +msgid "" +"Export your basic channel information to a file. This acts as a backup of " +"your connections, permissions, profile and basic data, which can be used to " +"import your data to a new server hub, but does not contain your content." +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:75 +msgid "Export Content" +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:76 +msgid "" +"Export your channel information and recent content to a JSON backup that can " +"be restored or imported to another server hub. This backs up all of your " +"connections, permissions, profile data and several months of posts. This " +"file may be VERY large. Please be patient - it may take several minutes for " +"this download to begin." +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:78 +msgid "Export your posts from a given year." +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:80 +msgid "" +"You may also export your posts and conversations for a particular year or " +"month. Adjust the date in your browser location bar to select other dates. " +"If the export fails (possibly due to memory exhaustion on your server hub), " +"please try again selecting a more limited date range." +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:81 +#, php-format +msgid "" +"To select all posts for a given year, such as this year, visit %2$s" +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:82 +#, php-format +msgid "" +"To select all posts for a given month, such as January of this year, visit " +"%2$s" +msgstr "" + +#: ../../Zotlabs/Module/Uexport.php:83 +#, php-format +msgid "" +"These content files may be imported or restored by visiting " +"%2$s on any site containing your channel. For best results please import " +"or restore these in date order (oldest first)." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:19 +msgid "No valid account found." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:33 +msgid "Password reset request issued. Check your email." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108 +#, php-format +msgid "Site Member (%s)" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49 +#, php-format +msgid "Password reset requested at %s" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:68 +msgid "" +"Request could not be verified. (You may have previously submitted it.) " +"Password reset failed." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:91 ../../boot.php:1714 +msgid "Password Reset" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:92 +msgid "Your password has been reset as requested." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:93 +msgid "Your new password is" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:94 +msgid "Save or copy your new password - and then" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:95 +msgid "click here to login" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:96 +msgid "" +"Your password may be changed from the Settings page after " +"successful login." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:117 +#, php-format +msgid "Your password has changed at %s" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:130 +msgid "Forgot your Password?" +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:131 +msgid "" +"Enter your email address and submit to have your password reset. Then check " +"your email for further instructions." +msgstr "" + +#: ../../Zotlabs/Module/Lostpass.php:132 +msgid "Email Address" +msgstr "" + +#: ../../Zotlabs/Module/Vote.php:40 +msgid "Poll not found." +msgstr "" + +#: ../../Zotlabs/Module/Vote.php:71 +msgid "Invalid response." +msgstr "" + +#: ../../Zotlabs/Module/Vote.php:132 +msgid "Response submitted. Updates may not appear instantly." +msgstr "" + +#: ../../Zotlabs/Module/Ping.php:337 ../../Zotlabs/Lib/Enotify.php:948 +msgid "sent you a private message" +msgstr "" + +#: ../../Zotlabs/Module/Ping.php:393 ../../Zotlabs/Lib/Enotify.php:914 +msgid "added your channel" +msgstr "" + +#: ../../Zotlabs/Module/Ping.php:418 ../../Zotlabs/Lib/Enotify.php:986 +msgid "requires approval" +msgstr "" + +#: ../../Zotlabs/Module/Ping.php:428 ../../Zotlabs/Lib/Enotify.php:957 +msgid "g A l F d" +msgstr "" + +#: ../../Zotlabs/Module/Ping.php:446 ../../Zotlabs/Lib/Enotify.php:960 +msgid "[today]" +msgstr "" + +#: ../../Zotlabs/Module/Ping.php:456 +msgid "posted an event" +msgstr "" + +#: ../../Zotlabs/Module/Ping.php:490 ../../Zotlabs/Lib/Enotify.php:829 +#: ../../Zotlabs/Lib/Enotify.php:931 +msgid "shared a file with you" +msgstr "" + +#: ../../Zotlabs/Module/Display.php:359 ../../Zotlabs/Module/Channel.php:449 +msgid "" +"You must enable javascript for your browser to be able to view this content." +msgstr "" + +#: ../../Zotlabs/Module/Display.php:377 +msgid "Article" +msgstr "" + +#: ../../Zotlabs/Module/Display.php:422 +msgid "Item has been removed." +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:96 +#: ../../Zotlabs/Module/Admin/Accounts.php:167 +#: ../../Zotlabs/Module/Admin/Accounts.php:180 +#: ../../Zotlabs/Widget/Admin.php:23 +msgid "Accounts" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:97 +msgid "Blocked accounts" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:98 +msgid "Expired accounts" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:99 +msgid "Expiring accounts" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:114 +#: ../../Zotlabs/Module/Admin/Channels.php:146 +#: ../../Zotlabs/Widget/Admin.php:24 +msgid "Channels" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:120 +msgid "Message queues" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:134 +msgid "Your software should be updated" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:138 ../../Zotlabs/Module/Admin/Themes.php:122 +#: ../../Zotlabs/Module/Admin/Themes.php:156 +#: ../../Zotlabs/Module/Admin/Security.php:98 +#: ../../Zotlabs/Module/Admin/Accounts.php:166 +#: ../../Zotlabs/Module/Admin/Channels.php:145 +#: ../../Zotlabs/Module/Admin/Logs.php:82 +#: ../../Zotlabs/Module/Admin/Addons.php:342 +#: ../../Zotlabs/Module/Admin/Addons.php:440 +#: ../../Zotlabs/Module/Admin/Site.php:291 +msgid "Administration" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:139 +msgid "Summary" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:142 +msgid "Registered accounts" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:143 +msgid "Pending registrations" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:144 +msgid "Registered channels" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:145 +msgid "Active addons" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:146 +msgid "Version" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:147 +msgid "Repository version (master)" +msgstr "" + +#: ../../Zotlabs/Module/Admin.php:148 +msgid "Repository version (dev)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:80 +msgid "Page owner information could not be retrieved." +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:96 ../../Zotlabs/Module/Photos.php:115 +msgid "Album not found." +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:105 +msgid "Delete Album" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:176 ../../Zotlabs/Module/Photos.php:1059 +msgid "Delete Photo" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:530 +msgid "No photos selected" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:579 +msgid "Access to this item is restricted." +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:622 +#, php-format +msgid "%1$.2f MB of %2$.2f MB photo storage used." +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:625 +#, php-format +msgid "%1$.2f MB photo storage used." +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:667 +msgid "Upload Photos" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:671 +msgid "Enter an album name" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:672 +msgid "or select an existing album (doubleclick)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:673 +msgid "Create a status post for this upload" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:675 +msgid "Description (optional)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:761 +msgid "Show Newest First" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:763 +msgid "Show Oldest First" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:787 ../../Zotlabs/Module/Photos.php:1333 +#: ../../Zotlabs/Module/Embedphotos.php:170 +#: ../../Zotlabs/Widget/Portfolio.php:87 ../../Zotlabs/Widget/Album.php:78 +msgid "View Photo" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:793 ../../Zotlabs/Module/Photos.php:1255 +#: ../../Zotlabs/Module/Embedphotos.php:176 ../../Zotlabs/Lib/Apps.php:1112 +#: ../../Zotlabs/Lib/Apps.php:1196 ../../Zotlabs/Lib/Activity.php:1508 +#: ../../Zotlabs/Widget/Portfolio.php:95 ../../Zotlabs/Widget/Pinned.php:270 +#: ../../Zotlabs/Widget/Album.php:84 ../../include/conversation.php:1211 +#: ../../include/cdav.php:158 ../../include/cdav.php:159 +#: ../../include/cdav.php:167 ../../extend/addon/hzaddons/pubcrawl/as.php:1187 +msgid "Unknown" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:818 ../../Zotlabs/Module/Embedphotos.php:186 +#: ../../Zotlabs/Widget/Portfolio.php:108 ../../Zotlabs/Widget/Album.php:95 +msgid "Edit Album" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:820 ../../Zotlabs/Module/Photos.php:1364 +msgid "Add Photos" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:868 +msgid "Permission denied. Access to this item may be restricted." +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:870 +msgid "Photo not available" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:928 +msgid "Use as profile photo" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:929 +msgid "Use as cover photo" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:936 +msgid "Private Photo" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:951 +msgid "View Full Size" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1033 +msgid "Edit photo" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1035 +msgid "Rotate CW (right)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1036 +msgid "Rotate CCW (left)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1039 +msgid "Move photo to album" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1040 +msgid "Enter a new album name" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1041 +msgid "or select an existing one (doubleclick)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1046 +msgid "Add a Tag" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1054 +msgid "Example: @bob, @Barbara_Jensen, @jim@example.com" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1057 +msgid "Flag as adult in album view" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1076 ../../Zotlabs/Lib/ThreadItem.php:317 +msgid "I like this (toggle)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1077 ../../Zotlabs/Lib/ThreadItem.php:318 +msgid "I don't like this (toggle)" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1079 ../../Zotlabs/Lib/ThreadItem.php:501 +#: ../../include/conversation.php:827 +msgid "Please wait" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1095 ../../Zotlabs/Module/Photos.php:1213 +#: ../../Zotlabs/Lib/ThreadItem.php:822 +msgid "This is you" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1097 ../../Zotlabs/Module/Photos.php:1215 +#: ../../Zotlabs/Lib/ThreadItem.php:824 ../../include/js_strings.php:6 +msgid "Comment" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1113 ../../include/conversation.php:652 +msgctxt "title" +msgid "Likes" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1113 ../../include/conversation.php:653 +msgctxt "title" +msgid "Dislikes" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:77 +#: ../../include/conversation.php:654 +msgctxt "title" +msgid "Agree" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:78 +#: ../../include/conversation.php:655 +msgctxt "title" +msgid "Disagree" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1114 ../../Zotlabs/Widget/Pinned.php:79 +#: ../../include/conversation.php:656 +msgctxt "title" +msgid "Abstain" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:66 +#: ../../include/conversation.php:657 +msgctxt "title" +msgid "Attending" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:67 +#: ../../include/conversation.php:658 +msgctxt "title" +msgid "Not attending" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Widget/Pinned.php:68 +#: ../../include/conversation.php:659 +msgctxt "title" +msgid "Might attend" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1132 ../../Zotlabs/Module/Photos.php:1144 +#: ../../Zotlabs/Lib/ThreadItem.php:238 ../../Zotlabs/Lib/ThreadItem.php:250 +msgid "View all" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1136 ../../Zotlabs/Lib/ThreadItem.php:242 +#: ../../include/conversation.php:1749 ../../include/channel.php:1781 +#: ../../include/taxonomy.php:668 +msgctxt "noun" +msgid "Like" +msgid_plural "Likes" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Photos.php:1141 ../../Zotlabs/Lib/ThreadItem.php:247 +#: ../../include/conversation.php:1752 +msgctxt "noun" +msgid "Dislike" +msgid_plural "Dislikes" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Photos.php:1247 +msgid "Photo Tools" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1256 +msgid "In This Photo:" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1261 +msgid "Map" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1269 ../../Zotlabs/Lib/ThreadItem.php:489 +msgctxt "noun" +msgid "Likes" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1270 ../../Zotlabs/Lib/ThreadItem.php:490 +msgctxt "noun" +msgid "Dislikes" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1275 ../../Zotlabs/Storage/Browser.php:411 +#: ../../Zotlabs/Lib/ThreadItem.php:495 ../../Zotlabs/Widget/Pinned.php:160 +#: ../../include/acl_selectors.php:155 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:233 +msgid "Close" +msgstr "" + +#: ../../Zotlabs/Module/Photos.php:1348 ../../Zotlabs/Module/Photos.php:1361 +#: ../../Zotlabs/Module/Photos.php:1362 ../../include/photos.php:667 +msgid "Recent Photos" +msgstr "" + +#: ../../Zotlabs/Module/Channel.php:99 ../../Zotlabs/Module/Profile.php:45 +#: ../../Zotlabs/Module/Hcard.php:37 +msgid "Posts and comments" +msgstr "" + +#: ../../Zotlabs/Module/Channel.php:106 ../../Zotlabs/Module/Profile.php:52 +#: ../../Zotlabs/Module/Hcard.php:44 +msgid "Only posts" +msgstr "" + +#: ../../Zotlabs/Module/Channel.php:174 +msgid "Insufficient permissions. Request redirected to profile page." +msgstr "" + +#: ../../Zotlabs/Module/Channel.php:189 ../../Zotlabs/Module/Network.php:164 +msgid "Search Results For:" +msgstr "" + +#: ../../Zotlabs/Module/Cards.php:51 +msgid "Cards App" +msgstr "" + +#: ../../Zotlabs/Module/Cards.php:52 +msgid "Create personal planning cards" +msgstr "" + +#: ../../Zotlabs/Module/Cards.php:112 +msgid "Add Card" +msgstr "" + +#: ../../Zotlabs/Module/Cards.php:207 ../../Zotlabs/Lib/Apps.php:326 +#: ../../include/nav.php:501 +msgid "Cards" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:21 +msgid "This page is available only to site members" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:27 +msgid "Welcome" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:29 +msgid "What would you like to do?" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:31 +msgid "" +"Please bookmark this page if you would like to return to it in the future" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:35 +msgid "Upload a profile photo" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:36 +msgid "Upload a cover photo" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:37 +msgid "Edit your default profile" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:38 ../../Zotlabs/Widget/Newmember.php:41 +msgid "View friend suggestions" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:39 +msgid "View the channel directory" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:40 +msgid "View/edit your channel settings" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:41 +msgid "View the site or project documentation" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:42 +msgid "Visit your channel homepage" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:43 +msgid "" +"View your connections and/or add somebody whose address you already know" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:44 +msgid "" +"View your personal stream (this may be empty until you add some connections)" +msgstr "" + +#: ../../Zotlabs/Module/Go.php:52 +msgid "View the public stream. Warning: this content is not moderated" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:58 +#: ../../Zotlabs/Module/Connections.php:115 +#: ../../Zotlabs/Module/Connections.php:273 +msgid "Active" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:63 +#: ../../Zotlabs/Module/Connections.php:181 +#: ../../Zotlabs/Module/Connections.php:278 +msgid "Blocked" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:68 +#: ../../Zotlabs/Module/Connections.php:188 +#: ../../Zotlabs/Module/Connections.php:277 +msgid "Ignored" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:73 +#: ../../Zotlabs/Module/Connections.php:202 +#: ../../Zotlabs/Module/Connections.php:276 +msgid "Hidden" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:78 +#: ../../Zotlabs/Module/Connections.php:195 +msgid "Archived/Unreachable" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:83 +#: ../../Zotlabs/Module/Connections.php:92 +#: ../../Zotlabs/Module/Notifications.php:50 ../../Zotlabs/Module/Menu.php:180 +msgid "New" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:157 +msgid "Active Connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:160 +msgid "Show active connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:164 +#: ../../Zotlabs/Widget/Notifications.php:104 +msgid "New Connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:167 +msgid "Show pending (new) connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:184 +msgid "Only show blocked connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:191 +msgid "Only show ignored connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:198 +msgid "Only show archived/unreachable connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:205 +msgid "Only show hidden connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:220 +msgid "Show all connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:274 +msgid "Pending approval" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:275 +msgid "Archived" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:279 +msgid "Not connected at this location" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:318 +#, php-format +msgid "%1$s [%2$s]" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:319 +msgid "Edit connection" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:321 +msgid "Delete connection" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:330 +msgid "Channel address" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:332 ../../include/features.php:291 +msgid "Network" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:335 +msgid "Call" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:337 +msgid "Status" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:339 +msgid "Connected" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:341 +msgid "Approve connection" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:342 +#: ../../Zotlabs/Module/Admin/Accounts.php:173 +#: ../../include/conversation.php:774 +msgid "Approve" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:343 +msgid "Ignore connection" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:345 +msgid "Recent activity" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:349 ../../Zotlabs/Module/Suggest.php:71 +#: ../../Zotlabs/Module/Directory.php:370 ../../Zotlabs/Widget/Follow.php:32 +#: ../../Zotlabs/Widget/Suggestions.php:46 ../../include/conversation.php:1100 +#: ../../include/channel.php:1618 ../../include/connections.php:110 +msgid "Connect" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:351 +msgid "Connect at this location" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:374 ../../Zotlabs/Lib/Apps.php:333 +#: ../../include/features.php:133 ../../include/text.php:1036 +msgid "Connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:379 +msgid "Search your connections" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:380 +msgid "Connections search" +msgstr "" + +#: ../../Zotlabs/Module/Connections.php:381 +#: ../../Zotlabs/Module/Directory.php:433 +#: ../../Zotlabs/Module/Directory.php:438 ../../include/contact_widgets.php:23 +msgid "Find" +msgstr "" + +#: ../../Zotlabs/Module/Editpost.php:38 ../../Zotlabs/Module/Editpost.php:43 +msgid "Item is not editable" +msgstr "" + +#: ../../Zotlabs/Module/Tagrm.php:48 ../../Zotlabs/Module/Tagrm.php:98 +msgid "Tag removed" +msgstr "" + +#: ../../Zotlabs/Module/Tagrm.php:123 +msgid "Remove Item Tag" +msgstr "" + +#: ../../Zotlabs/Module/Tagrm.php:125 +msgid "Select a tag to remove: " +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:35 +msgid "Affinity Tool settings updated." +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:47 +msgid "" +"This app presents a slider control in your connection editor and also on " +"your network page. The slider represents your degree of friendship " +"(affinity) with each connection. It allows you to zoom in or out and display " +"conversations from only your closest friends or everybody in your stream." +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:52 +msgid "Affinity Tool App" +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:57 +msgid "" +"The numbers below represent the minimum and maximum slider default positions " +"for your network/stream page as a percentage." +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:64 +msgid "Default maximum affinity level" +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:64 +msgid "0-99 default 99" +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:70 +msgid "Default minimum affinity level" +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:70 +msgid "0-99 - default 0" +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:76 +msgid "Persistent affinity levels" +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:76 +msgid "" +"If disabled the max and min levels will be reset to default after page reload" +msgstr "" + +#: ../../Zotlabs/Module/Affinity.php:84 +msgid "Affinity Tool Settings" +msgstr "" + +#: ../../Zotlabs/Module/Common.php:14 +msgid "No channel." +msgstr "" + +#: ../../Zotlabs/Module/Common.php:45 +msgid "No connections in common." +msgstr "" + +#: ../../Zotlabs/Module/Common.php:65 +msgid "View Common Connections" +msgstr "" + +#: ../../Zotlabs/Module/Share.php:104 ../../Zotlabs/Lib/Activity.php:2133 +#, php-format +msgid "🔁 Repeated %1$s's %2$s" +msgstr "" + +#: ../../Zotlabs/Module/Share.php:120 +msgid "Post repeated" +msgstr "" + +#: ../../Zotlabs/Module/Editwebpage.php:139 +msgid "Page link" +msgstr "" + +#: ../../Zotlabs/Module/Editwebpage.php:166 +msgid "Edit Webpage" +msgstr "" + +#: ../../Zotlabs/Module/Profile.php:93 +msgid "vcard" +msgstr "" + +#: ../../Zotlabs/Module/Article_edit.php:127 +msgid "Edit Article" +msgstr "" + +#: ../../Zotlabs/Module/Rmagic.php:46 +msgid "Authentication failed." +msgstr "" + +#: ../../Zotlabs/Module/Rmagic.php:96 ../../include/channel.php:2597 +#: ../../boot.php:1706 +msgid "Remote Authentication" +msgstr "" + +#: ../../Zotlabs/Module/Rmagic.php:97 ../../include/channel.php:2598 +msgid "Enter your channel address (e.g. channel@example.com)" +msgstr "" + +#: ../../Zotlabs/Module/Rmagic.php:98 ../../include/channel.php:2599 +msgid "Authenticate" +msgstr "" + +#: ../../Zotlabs/Module/Attach.php:67 +msgid "Item not available." +msgstr "" + +#: ../../Zotlabs/Module/Pconfig.php:32 ../../Zotlabs/Module/Pconfig.php:68 +msgid "This setting requires special processing and editing has been blocked." +msgstr "" + +#: ../../Zotlabs/Module/Pconfig.php:57 +msgid "Configuration Editor" +msgstr "" + +#: ../../Zotlabs/Module/Pconfig.php:58 +msgid "" +"Warning: Changing some settings could render your channel inoperable. Please " +"leave this page unless you are comfortable with and knowledgeable about how " +"to correctly use this feature." +msgstr "" + +#: ../../Zotlabs/Module/Randprof.php:29 +msgid "Random Channel App" +msgstr "" + +#: ../../Zotlabs/Module/Randprof.php:30 +msgid "Visit a random channel in the $Projectname network" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:26 +msgid "Theme settings updated." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:61 +msgid "No themes found." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:95 +#: ../../Zotlabs/Module/Admin/Addons.php:311 +msgid "Disable" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:97 +#: ../../Zotlabs/Module/Admin/Addons.php:314 +msgid "Enable" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:116 +msgid "Screenshot" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:123 +#: ../../Zotlabs/Module/Admin/Themes.php:157 ../../Zotlabs/Widget/Admin.php:28 +msgid "Themes" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:124 +#: ../../Zotlabs/Module/Admin/Addons.php:344 +msgid "Toggle" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:125 +#: ../../Zotlabs/Module/Admin/Addons.php:345 ../../Zotlabs/Lib/Apps.php:339 +#: ../../Zotlabs/Widget/Settings_menu.php:61 +#: ../../Zotlabs/Widget/Newmember.php:53 ../../include/nav.php:103 +msgid "Settings" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:134 +#: ../../Zotlabs/Module/Admin/Addons.php:352 +msgid "Author: " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:135 +#: ../../Zotlabs/Module/Admin/Addons.php:353 +msgid "Maintainer: " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:162 +msgid "[Experimental]" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Themes.php:163 +msgid "[Unsupported]" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:89 +msgid "" +"By default, unfiltered HTML is allowed in embedded media. This is inherently " +"insecure." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:92 +msgid "" +"The recommended setting is to only allow unfiltered HTML from the following " +"sites:" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:93 +msgid "" +"https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/" +"
      https://vimeo.com/
      https://soundcloud.com/
      " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:94 +msgid "" +"All other embedded content will be filtered, unless " +"embedded content from that site is explicitly blocked." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:99 ../../Zotlabs/Widget/Admin.php:25 +msgid "Security" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:101 +msgid "Block public" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:101 +msgid "" +"Check to block public access to all otherwise public personal pages on this " +"site unless you are currently authenticated." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:102 +msgid "Provide a cloud root directory" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:102 +msgid "" +"The cloud root directory lists all channel names which provide public files" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:103 +msgid "Show total disk space available to cloud uploads" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:104 +msgid "Set \"Transport Security\" HTTP header" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:105 +msgid "Set \"Content Security Policy\" HTTP header" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:106 +msgid "Allowed email domains" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:106 +msgid "" +"Comma separated list of domains which are allowed in email addresses for " +"registrations to this site. Wildcards are accepted. Empty to allow any " +"domains" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:107 +msgid "Not allowed email domains" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:107 +msgid "" +"Comma separated list of domains which are not allowed in email addresses for " +"registrations to this site. Wildcards are accepted. Empty to allow any " +"domains, unless allowed domains have been defined." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:108 +msgid "Allow communications only from these sites" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:108 +msgid "" +"One site per line. Leave empty to allow communication from anywhere by " +"default" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:109 +msgid "Block communications from these sites" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:110 +msgid "Allow communications only from these channels" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:110 +msgid "" +"One channel (hash) per line. Leave empty to allow from any channel by default" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:111 +msgid "Block communications from these channels" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:112 +msgid "Only allow embeds from secure (SSL) websites and links." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:113 +msgid "Allow unfiltered embedded HTML content only from these domains" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:113 +msgid "One site per line. By default embedded content is filtered." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:114 +msgid "Block embedded HTML from these domains" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:115 +msgid "Allow SVG thumbnails in file browser" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:115 +msgid "WARNING: SVG images may contain malicious code." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Security.php:116 +msgid "Allow embedded (inline) PDF files" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:37 +#, php-format +msgid "%s account blocked/unblocked" +msgid_plural "%s account blocked/unblocked" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:44 +#, php-format +msgid "%s account deleted" +msgid_plural "%s accounts deleted" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:80 +msgid "Account not found" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:91 ../../include/channel.php:2757 +#, php-format +msgid "Account '%s' deleted" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:99 +#, php-format +msgid "Account '%s' blocked" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:107 +#, php-format +msgid "Account '%s' unblocked" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:169 +#: ../../Zotlabs/Module/Admin/Channels.php:148 +msgid "select all" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:170 +msgid "Registrations waiting for confirm" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:171 +msgid "Request date" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:172 +msgid "No registrations." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:182 +msgid "ID" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:184 +msgid "All Channels" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:185 +msgid "Register date" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:186 +msgid "Last login" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:187 +msgid "Expires" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:188 +msgid "Service Class" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:190 +msgid "" +"Selected accounts will be deleted!\\n\\nEverything these accounts had posted " +"on this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Accounts.php:191 +msgid "" +"The account {0} will be deleted!\\n\\nEverything this account has posted on " +"this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Features.php:55 +#: ../../Zotlabs/Module/Admin/Features.php:56 +#: ../../Zotlabs/Module/Settings/Features.php:38 ../../include/features.php:55 +msgid "Off" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Features.php:55 +#: ../../Zotlabs/Module/Admin/Features.php:56 +#: ../../Zotlabs/Module/Settings/Features.php:38 ../../include/features.php:55 +msgid "On" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Features.php:56 +#, php-format +msgid "Lock feature %s" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Features.php:64 +msgid "Manage Additional Features" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Queue.php:35 +msgid "Queue Statistics" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Queue.php:36 +msgid "Total Entries" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Queue.php:37 +msgid "Priority" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Queue.php:38 +msgid "Destination URL" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Queue.php:39 +msgid "Mark hub permanently offline" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Queue.php:40 +msgid "Empty queue for this hub" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Queue.php:41 +msgid "Last known contact" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:19 +#: ../../Zotlabs/Module/Admin/Dbsync.php:59 +msgid "Update has been marked successful" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:32 +#, php-format +msgid "Verification of update %s failed. Check system logs." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:35 +#: ../../Zotlabs/Module/Admin/Dbsync.php:74 +#, php-format +msgid "Update %s was successfully applied." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:39 +#, php-format +msgid "Verifying update %s did not return a status. Unknown if it succeeded." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:42 +#, php-format +msgid "Update %s does not contain a verification function." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:46 +#: ../../Zotlabs/Module/Admin/Dbsync.php:81 +#, php-format +msgid "Update function %s could not be found." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:71 +#, php-format +msgid "Executing update procedure %s failed. Check system logs." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:78 +#, php-format +msgid "" +"Update %s did not return a status. It cannot be determined if it was " +"successful." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:99 +msgid "Failed Updates" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:101 +msgid "Mark success (if update was manually applied)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:102 +msgid "Attempt to verify this update if a verification procedure exists" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:103 +msgid "Attempt to execute this update step automatically" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Dbsync.php:108 +msgid "No failed updates." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:31 +#, php-format +msgid "%s channel censored/uncensored" +msgid_plural "%s channels censored/uncensored" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Channels.php:40 +#, php-format +msgid "%s channel code allowed/disallowed" +msgid_plural "%s channels code allowed/disallowed" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Channels.php:46 +#, php-format +msgid "%s channel deleted" +msgid_plural "%s channels deleted" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Admin/Channels.php:65 +msgid "Channel not found" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:75 +#, php-format +msgid "Channel '%s' deleted" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:87 +#, php-format +msgid "Channel '%s' censored" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:87 +#, php-format +msgid "Channel '%s' uncensored" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:98 +#, php-format +msgid "Channel '%s' code allowed" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:98 +#, php-format +msgid "Channel '%s' code disallowed" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:150 +#: ../../Zotlabs/Module/Directory.php:362 +msgid "Censor" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:151 +#: ../../Zotlabs/Module/Directory.php:362 +msgid "Uncensor" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:152 +msgid "Allow Code" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:153 +msgid "Disallow Code" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:421 +msgid "Channel" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:158 +msgid "UID" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:162 +msgid "" +"Selected channels will be deleted!\\n\\nEverything that was posted in these " +"channels on this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Channels.php:163 +msgid "" +"The channel {0} will be deleted!\\n\\nEverything that was posted in this " +"channel on this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Logs.php:28 +msgid "Log settings updated." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Logs.php:83 ../../Zotlabs/Widget/Admin.php:48 +#: ../../Zotlabs/Widget/Admin.php:58 +msgid "Logs" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Logs.php:85 +msgid "Clear" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Logs.php:91 +msgid "Debugging" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Logs.php:92 +msgid "Log file" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Logs.php:92 +msgid "" +"Must be writable by web server. Relative to your top-level webserver " +"directory." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Logs.php:93 +msgid "Log level" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:29 +#, php-format +msgid "Password changed for account %d." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:46 +msgid "Account settings updated." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:61 +msgid "Account not found." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:68 +msgid "Account Edit" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:69 +msgid "New Password" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:70 +msgid "New Password again" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:71 +msgid "Account language (for emails)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Account_edit.php:72 +msgid "Service class" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:290 +#, php-format +msgid "Plugin %s disabled." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:295 +#, php-format +msgid "Plugin %s enabled." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:343 +#: ../../Zotlabs/Module/Admin/Addons.php:441 ../../Zotlabs/Widget/Admin.php:27 +msgid "Addons" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:354 +msgid "Minimum project version: " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:355 +msgid "Maximum project version: " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:356 +msgid "Minimum PHP version: " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:357 +msgid "Compatible Server Roles: " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:358 +msgid "Requires: " +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:359 +#: ../../Zotlabs/Module/Admin/Addons.php:446 +msgid "Disabled - version incompatibility" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:415 +msgid "Enter the public git repository URL of the addon repo." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:416 +msgid "Addon repo git URL" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:417 +msgid "Custom repo name" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:417 +msgid "(optional)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:418 +msgid "Download Addon Repo" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:425 +msgid "Install new repo" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:426 ../../Zotlabs/Lib/Apps.php:536 +msgid "Install" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:449 +msgid "Manage Repos" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:450 +msgid "Installed Addon Repositories" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:451 +msgid "Install a New Addon Repository" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Addons.php:458 +msgid "Switch branch" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:165 +msgid "Site settings updated." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:191 ../../include/text.php:3381 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:335 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:359 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:435 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:459 +#: ../../view/theme/redbasic/php/config.php:15 +msgid "Default" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:202 +#: ../../Zotlabs/Module/Settings/Display.php:118 +#, php-format +msgid "%s - (Incompatible)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:209 +msgid "mobile" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:211 +msgid "experimental" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:213 +msgid "unsupported" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:260 +msgid "Yes - with approval" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:266 +msgid "My site is not a public server" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:267 +msgid "My site has paid access only" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:268 +msgid "My site has free access only" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:269 +msgid "My site offers free accounts with optional paid upgrades" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:283 +msgid "Default permission role for new accounts" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:283 +msgid "" +"This role will be used for the first channel created after registration." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:292 ../../Zotlabs/Widget/Admin.php:22 +msgid "Site" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:294 +#: ../../Zotlabs/Module/Register.php:277 +msgid "Registration" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:295 +msgid "File upload" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:296 +msgid "Policies" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:297 ../../include/contact_widgets.php:16 +#: ../../include/acl_selectors.php:144 +msgid "Advanced" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:301 +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:593 +msgid "Site name" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:303 +msgid "Banner/Logo" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:303 +msgid "Unfiltered HTML/CSS/JS is allowed" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:304 +msgid "Administrator Information" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:304 +msgid "" +"Contact information for site administrators. Displayed on siteinfo page. " +"BBCode can be used here" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:305 ../../Zotlabs/Module/Siteinfo.php:24 +msgid "Site Information" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:305 +msgid "" +"Publicly visible description of this site. Displayed on siteinfo page. " +"BBCode can be used here" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:306 +msgid "System language" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:307 +msgid "System theme" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:307 +msgid "" +"Default system theme - may be over-ridden by user profiles - change theme settings" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:310 +msgid "Allow Feeds as Connections" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:310 +msgid "(Heavy system resource usage)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:311 +msgid "Maximum image size" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:311 +msgid "" +"Maximum size in bytes of uploaded images. Default is 0, which means no " +"limits." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:312 +msgid "Does this site allow new member registration?" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:313 +msgid "Invitation only" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:313 +msgid "" +"Only allow new member registrations with an invitation code. Above register " +"policy must be set to Yes." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:314 +msgid "Minimum age" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:314 +msgid "Minimum age (in years) for who may register on this site." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:315 +msgid "Which best describes the types of account offered by this hub?" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:315 +msgid "This is displayed on the public server site list." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:316 +msgid "Register text" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:316 +msgid "Will be displayed prominently on the registration page." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:318 +msgid "Site homepage to show visitors (default: login box)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:318 +msgid "" +"example: 'pubstream' to show public stream, 'page/sys/home' to show a system " +"webpage called 'home' or 'include:home.html' to include a file." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:319 +msgid "Preserve site homepage URL" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:319 +msgid "" +"Present the site homepage in a frame at the original location instead of " +"redirecting" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:320 +msgid "Accounts abandoned after x days" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:320 +msgid "" +"Will not waste system resources polling external sites for abandonded " +"accounts. Enter 0 for no time limit." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:321 +msgid "Allowed friend domains" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:321 +msgid "" +"Comma separated list of domains which are allowed to establish friendships " +"with this site. Wildcards are accepted. Empty to allow any domains" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:322 +msgid "Verify Email Addresses" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:322 +msgid "" +"Check to verify email addresses used in account registration (recommended)." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:323 +msgid "Force publish" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:323 +msgid "" +"Check to force all profiles on this site to be listed in the site directory." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:324 +msgid "Import Public Streams" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:324 +msgid "" +"Import and allow access to public content pulled from other sites. Warning: " +"this content is unmoderated." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:325 +msgid "Site only Public Streams" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:325 +msgid "" +"Allow access to public content originating only from this site if Imported " +"Public Streams are disabled." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:326 +msgid "Allow anybody on the internet to access the Public streams" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:326 +msgid "" +"Disable to require authentication before viewing. Warning: this content is " +"unmoderated." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:327 +msgid "Only import Public stream posts with this text" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:328 +msgid "Do not import Public stream posts with this text" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:331 +msgid "Login on Homepage" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:331 +msgid "" +"Present a login box to visitors on the home page if no other content has " +"been configured." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:332 +msgid "Enable context help" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:332 +msgid "" +"Display contextual help for the current page when the help button is pressed." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:334 +msgid "Reply-to email address for system generated email." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:335 +msgid "Sender (From) email address for system generated email." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:336 +msgid "Name of email sender for system generated email." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:338 +msgid "Directory Server URL" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:338 +msgid "Default directory server" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:340 +msgid "Enable SSE Notifications" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:340 +msgid "" +"If disabled, traditional polling will be used. Warning: this setting might " +"not be suited for shared hosting" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:342 +msgid "Proxy user" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:343 +msgid "Proxy URL" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:344 +msgid "Network timeout" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:344 +msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:345 +msgid "Delivery interval" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:345 +msgid "" +"Delay background delivery processes by this many seconds to reduce system " +"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 " +"for large dedicated servers." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:346 +msgid "Deliveries per process" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:346 +msgid "" +"Number of deliveries to attempt in a single operating system process. Adjust " +"if necessary to tune system performance. Recommend: 1-5." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:347 +msgid "Queue Threshold" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:347 +msgid "" +"Always defer immediate delivery if queue contains more than this number of " +"entries." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:348 +msgid "Poll interval" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:348 +msgid "" +"Delay background polling processes by this many seconds to reduce system " +"load. If 0, use delivery interval." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:349 +msgid "Path to ImageMagick convert program" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:349 +msgid "" +"If set, use this program to generate photo thumbnails for huge images ( > " +"4000 pixels in either dimension), otherwise memory exhaustion may occur. " +"Example: /usr/bin/convert" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:350 +msgid "Maximum Load Average" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:350 +msgid "" +"Maximum system load before delivery and poll processes are deferred - " +"default 50." +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:351 +msgid "Expiration period in days for imported (grid/network) content" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:351 +msgid "0 for no expiration of imported content" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:352 +msgid "" +"Do not expire any posts which have comments less than this many days ago" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:354 +msgid "" +"Public servers: Optional landing (marketing) webpage for new registrants" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:354 +#, php-format +msgid "Create this page first. Default is %s/register" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:355 +msgid "Page to display after creating a new channel" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:355 +msgid "Default: profiles" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:357 +msgid "Optional: site location" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Site.php:357 +msgid "Region or country" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:89 +msgid "New Profile Field" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:90 +#: ../../Zotlabs/Module/Admin/Profs.php:110 +msgid "Field nickname" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:90 +#: ../../Zotlabs/Module/Admin/Profs.php:110 +msgid "System name of field" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:91 +#: ../../Zotlabs/Module/Admin/Profs.php:111 +msgid "Input type" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:92 +#: ../../Zotlabs/Module/Admin/Profs.php:112 +msgid "Field Name" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:92 +#: ../../Zotlabs/Module/Admin/Profs.php:112 +msgid "Label on profile pages" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:93 +#: ../../Zotlabs/Module/Admin/Profs.php:113 +msgid "Help text" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:93 +#: ../../Zotlabs/Module/Admin/Profs.php:113 +msgid "Additional info (optional)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:103 +msgid "Field definition not found" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:109 +msgid "Edit Profile Field" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:168 ../../Zotlabs/Widget/Admin.php:30 +msgid "Profile Fields" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:169 +msgid "Basic Profile Fields" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:170 +msgid "Advanced Profile Fields" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:170 +msgid "(In addition to basic fields)" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:172 +msgid "All available fields" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:173 +msgid "Custom Fields" +msgstr "" + +#: ../../Zotlabs/Module/Admin/Profs.php:177 +msgid "Create Custom Field" +msgstr "" + +#: ../../Zotlabs/Module/Notify.php:61 ../../Zotlabs/Module/Notifications.php:55 +msgid "No more system notifications." +msgstr "" + +#: ../../Zotlabs/Module/Notify.php:65 ../../Zotlabs/Module/Notifications.php:59 +msgid "System Notifications" +msgstr "" + +#: ../../Zotlabs/Module/Cal.php:64 +msgid "Permissions denied." +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:122 +msgid "Thing updated" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:174 +msgid "Object store: failed" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:178 +msgid "Thing added" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:204 +#, php-format +msgid "OBJ: %1$s %2$s %3$s" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:267 +msgid "Show Thing" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:274 +msgid "item not found." +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:307 +msgid "Edit Thing" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:309 ../../Zotlabs/Module/Thing.php:366 +msgid "Select a profile" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 +msgid "Post an activity" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:369 +msgid "Only sends to viewers of the applicable profile" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:315 ../../Zotlabs/Module/Thing.php:371 +msgid "Name of thing e.g. something" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:317 ../../Zotlabs/Module/Thing.php:372 +msgid "URL of thing (optional)" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:319 ../../Zotlabs/Module/Thing.php:373 +msgid "URL for photo of thing (optional)" +msgstr "" + +#: ../../Zotlabs/Module/Thing.php:364 +msgid "Add Thing to your Profile" +msgstr "" + +#: ../../Zotlabs/Module/Suggest.php:40 +msgid "Suggest Channels App" +msgstr "" + +#: ../../Zotlabs/Module/Suggest.php:41 +msgid "" +"Suggestions for channels in the $Projectname network you might be interested " +"in" +msgstr "" + +#: ../../Zotlabs/Module/Suggest.php:54 +msgid "" +"No suggestions available. If this is a new site, please try again in 24 " +"hours." +msgstr "" + +#: ../../Zotlabs/Module/Suggest.php:73 ../../Zotlabs/Widget/Suggestions.php:48 +msgid "Ignore/Hide" +msgstr "" + +#: ../../Zotlabs/Module/Suggest.php:79 ../../Zotlabs/Module/Directory.php:437 +#: ../../include/contact_widgets.php:24 +msgid "Channel Suggestions" +msgstr "" + +#: ../../Zotlabs/Module/Email_validation.php:36 +msgid "Email Verification Required" +msgstr "" + +#: ../../Zotlabs/Module/Email_validation.php:37 +#, php-format +msgid "" +"A verification token was sent to your email address [%s]. Enter that token " +"here to complete the account verification step. Please allow a few minutes " +"for delivery, and check your spam folder if you do not see the message." +msgstr "" + +#: ../../Zotlabs/Module/Email_validation.php:38 +msgid "Resend Email" +msgstr "" + +#: ../../Zotlabs/Module/Email_validation.php:41 +msgid "Validation token" +msgstr "" + +#: ../../Zotlabs/Module/Notes.php:57 +msgid "Notes App" +msgstr "" + +#: ../../Zotlabs/Module/Notes.php:58 +msgid "A simple notes app with a widget (note: notes are not encrypted)" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:39 +#, php-format +msgid "This channel is limited to %d tokens" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:45 +msgid "Name and Password are required." +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:85 +msgid "Token saved." +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:99 +msgid "Guest Access App" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:100 +msgid "Create access tokens so that non-members can access private content" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:133 +msgid "" +"Use this form to create temporary access identifiers to share things with " +"non-members. These identities may be used in Access Control Lists and " +"visitors may login using these credentials to access private content." +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:135 +msgid "" +"You may also provide dropbox style access links to friends and " +"associates by adding the Login Password to any specific site URL as shown. " +"Examples:" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:170 +msgid "Guest Access Tokens" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:177 +msgid "Login Name" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:178 +msgid "Login Password" +msgstr "" + +#: ../../Zotlabs/Module/Tokens.php:179 +msgid "Expires (yyyy-mm-dd)" +msgstr "" + +#: ../../Zotlabs/Module/Apporder.php:47 +msgid "Change Order of Pinned Navbar Apps" +msgstr "" + +#: ../../Zotlabs/Module/Apporder.php:47 +msgid "Change Order of App Tray Apps" +msgstr "" + +#: ../../Zotlabs/Module/Apporder.php:48 +msgid "" +"Use arrows to move the corresponding app left (top) or right (bottom) in the " +"navbar" +msgstr "" + +#: ../../Zotlabs/Module/Apporder.php:48 +msgid "Use arrows to move the corresponding app up or down in the app tray" +msgstr "" + +#: ../../Zotlabs/Module/Notifications.php:60 +#: ../../Zotlabs/Lib/ThreadItem.php:482 +msgid "Mark all seen" +msgstr "" + +#: ../../Zotlabs/Module/Home.php:72 ../../Zotlabs/Module/Home.php:80 +#: ../../Zotlabs/Lib/Enotify.php:66 +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:42 +msgid "$Projectname" +msgstr "" + +#: ../../Zotlabs/Module/Home.php:90 +#, php-format +msgid "Welcome to %s" +msgstr "" + +#: ../../Zotlabs/Module/Articles.php:52 +msgid "Articles App" +msgstr "" + +#: ../../Zotlabs/Module/Articles.php:53 +msgid "Create interactive articles" +msgstr "" + +#: ../../Zotlabs/Module/Articles.php:116 +msgid "Add Article" +msgstr "" + +#: ../../Zotlabs/Module/Articles.php:226 ../../Zotlabs/Lib/Apps.php:325 +#: ../../include/nav.php:512 +msgid "Articles" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:167 +msgid "$Projectname Server - Setup" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:171 +msgid "Could not connect to database." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:175 +msgid "" +"Could not connect to specified site URL. Possible SSL certificate or DNS " +"issue." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:182 +msgid "Could not create table." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:188 +msgid "Your site database has been installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:194 +msgid "" +"You may need to import the file \"install/schema_xxx.sql\" manually using a " +"database client." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:195 ../../Zotlabs/Module/Setup.php:259 +#: ../../Zotlabs/Module/Setup.php:766 +msgid "Please see the file \"install/INSTALL.txt\"." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:256 +msgid "System check" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:261 +msgid "Check again" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:282 +msgid "Database connection" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:283 +msgid "" +"In order to install $Projectname we need to know how to connect to your " +"database." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:284 +msgid "" +"Please contact your hosting provider or site administrator if you have " +"questions about these settings." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:285 +msgid "" +"The database you specify below should already exist. If it does not, please " +"create it before continuing." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:289 +msgid "Database Server Name" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:289 +msgid "Default is 127.0.0.1" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:290 +msgid "Database Port" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:290 +msgid "Communication port number - use 0 for default" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:291 +msgid "Database Login Name" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:292 +msgid "Database Login Password" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:293 +msgid "Database Name" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:294 +msgid "Database Type" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 +msgid "Site administrator email address" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336 +msgid "" +"Your account email address must match this in order to use the web admin " +"panel." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 +msgid "Website URL" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338 +msgid "Please use SSL (https) URL if available." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:298 ../../Zotlabs/Module/Setup.php:340 +msgid "Please select a default timezone for your website" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:325 +msgid "Site settings" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:379 +msgid "PHP version 7.1 or greater is required." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:380 +msgid "PHP version" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:396 +msgid "Could not find a command line version of PHP in the web server PATH." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:397 +msgid "" +"If you don't have a command line version of PHP installed on server, you " +"will not be able to run background polling via cron." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:401 +msgid "PHP executable path" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:401 +msgid "" +"Enter full path to php executable. You can leave this blank to continue the " +"installation." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:406 +msgid "Command line PHP" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:416 +msgid "" +"Unable to check command line PHP, as shell_exec() is disabled. This is " +"required." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:420 +msgid "" +"The command line version of PHP on your system does not have " +"\"register_argc_argv\" enabled." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:421 +msgid "This is required for message delivery to work." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:424 +msgid "PHP register_argc_argv" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:444 +msgid "" +"This is not sufficient to upload larger images or files. You should be able " +"to upload at least 4 MB at once." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:446 +#, php-format +msgid "" +"Your max allowed total upload size is set to %s. Maximum size of one file to " +"upload is set to %s. You are allowed to upload up to %d files at once." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:452 +msgid "You can adjust these settings in the server php.ini file." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:454 +msgid "PHP upload limits" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:477 +msgid "" +"Error: the \"openssl_pkey_new\" function on this system is not able to " +"generate encryption keys" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:478 +msgid "" +"If running under Windows, please see \"http://www.php.net/manual/en/openssl." +"installation.php\"." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:481 +msgid "Generate encryption keys" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:498 +msgid "libCurl PHP module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:499 +msgid "GD graphics PHP module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:500 +msgid "OpenSSL PHP module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:501 +msgid "PDO database PHP module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:502 +msgid "mb_string PHP module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:503 +msgid "xml PHP module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:504 +msgid "zip PHP module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:508 ../../Zotlabs/Module/Setup.php:510 +msgid "Apache mod_rewrite module" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:508 +msgid "" +"Error: Apache webserver mod-rewrite module is required but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:514 ../../Zotlabs/Module/Setup.php:517 +msgid "exec" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:514 +msgid "" +"Error: exec is required but is either not installed or has been disabled in " +"php.ini" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:520 ../../Zotlabs/Module/Setup.php:523 +msgid "shell_exec" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:520 +msgid "" +"Error: shell_exec is required but is either not installed or has been " +"disabled in php.ini" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:528 +msgid "Error: libCURL PHP module required but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:532 +msgid "" +"Error: GD PHP module with JPEG support or ImageMagick graphics library " +"required but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:536 +msgid "Error: openssl PHP module required but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:542 +msgid "" +"Error: PDO database PHP module missing a driver for either mysql or pgsql." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:547 +msgid "Error: PDO database PHP module required but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:551 +msgid "Error: mb_string PHP module required but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:555 +msgid "Error: xml PHP module required for DAV but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:559 +msgid "Error: zip PHP module required but not installed." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:578 ../../Zotlabs/Module/Setup.php:587 +msgid ".htconfig.php is writable" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:583 +msgid "" +"The web installer needs to be able to create a file called \".htconfig.php\" " +"in the top folder of your web server and it is unable to do so." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:584 +msgid "" +"This is most often a permission setting, as the web server may not be able " +"to write files in your folder - even if you can." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:585 +msgid "Please see install/INSTALL.txt for additional information." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:601 +msgid "" +"This software uses the Smarty3 template engine to render its web views. " +"Smarty3 compiles templates to PHP to speed up rendering." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:602 +#, php-format +msgid "" +"In order to store these compiled templates, the web server needs to have " +"write access to the directory %s under the top level web folder." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:603 ../../Zotlabs/Module/Setup.php:624 +msgid "" +"Please ensure that the user that your web server runs as (e.g. www-data) has " +"write access to this folder." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:604 +#, php-format +msgid "" +"Note: as a security measure, you should give the web server write access to " +"%s only--not the template files (.tpl) that it contains." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:607 +#, php-format +msgid "%s is writable" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:623 +msgid "" +"This software uses the store directory to save uploaded files. The web " +"server needs to have write access to the store directory under the top level " +"web folder" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:627 +msgid "store is writable" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:659 +msgid "" +"SSL certificate cannot be validated. Fix certificate or disable https access " +"to this site." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:660 +msgid "" +"If you have https access to your website or allow connections to TCP port " +"443 (the https: port), you MUST use a browser-valid certificate. You MUST " +"NOT use self-signed certificates!" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:661 +msgid "" +"This restriction is incorporated because public posts from you may for " +"example contain references to images on your own hub." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:662 +msgid "" +"If your certificate is not recognized, members of other sites (who may " +"themselves have valid certificates) will get a warning message on their own " +"site complaining about security issues." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:663 +msgid "" +"This can cause usability issues elsewhere (not just on your own site) so we " +"must insist on this requirement." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:664 +msgid "" +"Providers are available that issue free certificates which are browser-valid." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:665 +msgid "" +"If you are confident that the certificate is valid and signed by a trusted " +"authority, check to see if you have failed to install an intermediate cert. " +"These are not normally required by browsers, but are required for server-to-" +"server communications." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:667 +msgid "SSL certificate validation" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:673 +msgid "" +"Url rewrite in .htaccess is not working. Check your server configuration." +"Test: " +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:676 +msgid "Url rewrite is working" +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:689 +msgid "" +"The database configuration file \".htconfig.php\" could not be written. " +"Please use the enclosed text to create a configuration file in your web " +"server root." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:718 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:401 +msgid "Errors encountered creating database tables." +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:764 +msgid "

      What next?

      " +msgstr "" + +#: ../../Zotlabs/Module/Setup.php:765 +msgid "" +"IMPORTANT: You will need to [manually] setup a scheduled task for the poller." +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:122 +msgid "No default suggestions were found." +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:282 +#, php-format +msgid "%d rating" +msgid_plural "%d ratings" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Directory.php:293 +msgid "Gender: " +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:295 +msgid "Status: " +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:297 +msgid "Homepage: " +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:349 ../../include/channel.php:1806 +msgid "Age:" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:354 ../../include/channel.php:1633 +#: ../../include/event.php:63 ../../include/event.php:134 +msgid "Location:" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:360 +msgid "Description:" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:367 ../../include/channel.php:1835 +msgid "Hometown:" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:369 ../../include/channel.php:1841 +msgid "About:" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:371 +msgid "Public Forum:" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:374 +msgid "Keywords: " +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:377 +msgid "Don't suggest" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:379 +msgid "Common connections (estimated):" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:428 +msgid "Global Directory" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:428 +msgid "Local Directory" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:434 +msgid "Finding:" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:439 +msgid "next page" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:439 +msgid "previous page" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:440 +msgid "Sort options" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:441 +msgid "Alphabetic" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:442 +msgid "Reverse Alphabetic" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:443 +msgid "Newest to Oldest" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:444 +msgid "Oldest to Newest" +msgstr "" + +#: ../../Zotlabs/Module/Directory.php:461 +msgid "No entries (some entries may be hidden)." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:31 ../../Zotlabs/Module/Menu.php:209 +msgid "Menu not found." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:63 +msgid "Unable to create element." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:87 +msgid "Unable to update menu element." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:103 +msgid "Unable to add menu element." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:167 ../../Zotlabs/Module/Mitem.php:246 +msgid "Menu Item Permissions" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247 +#: ../../Zotlabs/Module/Settings/Channel.php:528 +msgid "(click to open/close)" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:174 ../../Zotlabs/Module/Mitem.php:191 +msgid "Link Name" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:175 ../../Zotlabs/Module/Mitem.php:255 +msgid "Link or Submenu Target" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:175 +msgid "Enter URL of the link or select a menu name to create a submenu" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:256 +msgid "Use magic-auth if available" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:257 +msgid "Open link in new window" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 +msgid "Order in list" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258 +msgid "Higher numbers will sink to bottom of listing" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:179 +msgid "Submit and finish" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:180 +msgid "Submit and continue" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:189 +msgid "Menu:" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:192 +msgid "Link Target" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:195 +msgid "Edit menu" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:198 +msgid "Edit element" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:199 +msgid "Drop element" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:200 +msgid "New element" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:201 +msgid "Edit this menu container" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:202 +msgid "Add menu element" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:203 +msgid "Delete this menu item" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:204 +msgid "Edit this menu item" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:222 +msgid "Menu item not found." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:235 +msgid "Menu item deleted." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:237 +msgid "Menu item could not be deleted." +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:244 +msgid "Edit Menu Element" +msgstr "" + +#: ../../Zotlabs/Module/Mitem.php:254 +msgid "Link text" +msgstr "" + +#: ../../Zotlabs/Module/Mood.php:76 ../../include/conversation.php:286 +#, php-format +msgctxt "mood" +msgid "%1$s is %2$s" +msgstr "" + +#: ../../Zotlabs/Module/Mood.php:134 +msgid "Mood App" +msgstr "" + +#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Module/Mood.php:155 +msgid "Set your current mood and tell your friends" +msgstr "" + +#: ../../Zotlabs/Module/Mood.php:154 ../../Zotlabs/Lib/Apps.php:350 +msgid "Mood" +msgstr "" + +#: ../../Zotlabs/Module/Permcats.php:29 +msgid "Permission category name is required." +msgstr "" + +#: ../../Zotlabs/Module/Permcats.php:48 +msgid "Permission category saved." +msgstr "" + +#: ../../Zotlabs/Module/Permcats.php:63 +msgid "Permission Categories App" +msgstr "" + +#: ../../Zotlabs/Module/Permcats.php:64 +msgid "Create custom connection permission limits" +msgstr "" + +#: ../../Zotlabs/Module/Permcats.php:80 +msgid "" +"Use this form to create permission rules for various classes of people or " +"connections." +msgstr "" + +#: ../../Zotlabs/Module/Permcats.php:113 ../../Zotlabs/Lib/Apps.php:374 +msgid "Permission Categories" +msgstr "" + +#: ../../Zotlabs/Module/Permcats.php:121 +msgid "Permission category name" +msgstr "" + +#: ../../Zotlabs/Module/Ratings.php:70 +msgid "No ratings" +msgstr "" + +#: ../../Zotlabs/Module/Ratings.php:98 +msgid "Rating: " +msgstr "" + +#: ../../Zotlabs/Module/Ratings.php:99 +msgid "Website: " +msgstr "" + +#: ../../Zotlabs/Module/Ratings.php:101 +msgid "Description: " +msgstr "" + +#: ../../Zotlabs/Module/Register.php:52 +msgid "Maximum daily site registrations exceeded. Please try again tomorrow." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:58 +msgid "" +"Please indicate acceptance of the Terms of Service. Registration failed." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:92 +msgid "Passwords do not match." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:135 +msgid "Registration successful. Continue to create your first channel..." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:138 +msgid "" +"Registration successful. Please check your email for validation instructions." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:145 +msgid "Your registration is pending approval by the site owner." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:148 +msgid "Your registration can not be processed." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:195 +msgid "Registration on this hub is disabled." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:204 +msgid "Registration on this hub is by approval only." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:205 ../../Zotlabs/Module/Register.php:214 +msgid "Register at another affiliated hub." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:213 +msgid "Registration on this hub is by invitation only." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:224 +msgid "" +"This site has exceeded the number of allowed daily account registrations. " +"Please try again tomorrow." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:239 ../../Zotlabs/Module/Siteinfo.php:28 +msgid "Terms of Service" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:245 +#, php-format +msgid "I accept the %s for this website" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:252 +#, php-format +msgid "I am over %s years of age and accept the %s for this website" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:257 +msgid "Your email address" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:258 +msgid "Choose a password" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:259 +msgid "Please re-enter your password" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:260 +msgid "Please enter your invitation code" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:261 +msgid "Your Name" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:261 +msgid "Real names are preferred." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:263 +#, php-format +msgid "" +"Your nickname will be used to create an easy to remember channel address e." +"g. nickname%s" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:264 +msgid "" +"Select a channel permission role for your usage needs and privacy " +"requirements." +msgstr "" + +#: ../../Zotlabs/Module/Register.php:265 +msgid "no" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:265 +msgid "yes" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:293 ../../include/nav.php:162 +#: ../../boot.php:1685 +msgid "Register" +msgstr "" + +#: ../../Zotlabs/Module/Register.php:294 +msgid "" +"This site requires email verification. After completing this form, please " +"check your email for further instructions." +msgstr "" + +#: ../../Zotlabs/Module/Acl.php:123 ../../Zotlabs/Module/Lockview.php:117 +#: ../../Zotlabs/Module/Lockview.php:153 +msgctxt "acl" +msgid "Profile" +msgstr "" + +#: ../../Zotlabs/Module/Acl.php:370 +msgid "network" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Featured.php:25 +msgid "No feature settings configured" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Featured.php:34 +msgid "Addon Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Featured.php:35 +msgid "Please save/submit changes to any panel before opening another." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:19 +msgid "Not valid email." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:22 +msgid "Protected email address. Cannot change to that email." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:31 +msgid "System failure storing new email. Please try again." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:48 +msgid "Password verification failed." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:55 +msgid "Passwords do not match. Password unchanged." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:59 +msgid "Empty passwords are not allowed. Password unchanged." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:73 +msgid "Password changed." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:75 +msgid "Password update failed. Please try again." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:99 +msgid "Account Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:100 +msgid "Current Password" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:101 +msgid "Enter New Password" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:102 +msgid "Confirm New Password" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:102 +msgid "Leave password fields blank unless changing" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:104 +#: ../../Zotlabs/Module/Settings/Channel.php:502 +msgid "Email Address:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Account.php:106 +msgid "Remove this account including all its channels" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Events.php:40 +msgid "Events Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Profiles.php:49 +msgid "Profiles Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Editor.php:40 +msgid "Editor Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Features.php:45 +msgid "Additional Features" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Manage.php:41 +msgid "Channel Manager Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:127 +#, php-format +msgid "%s - (Experimental)" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:183 +msgid "Display Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:184 +msgid "Theme Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:185 +msgid "Custom Theme Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:186 +msgid "Content Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:192 +msgid "Display Theme:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:193 +msgid "Select scheme" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:195 +msgid "Preload images before rendering the page" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:195 +msgid "" +"The subjective page load time will be longer but the page will be ready when " +"displayed" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:196 +msgid "Enable user zoom on mobile devices" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:197 +msgid "Update browser every xx seconds" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:197 +msgid "Minimum of 10 seconds, no maximum" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:198 +msgid "Maximum number of conversations to load at any time:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:198 +msgid "Maximum of 30 items" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:199 +msgid "Show emoticons (smilies) as images" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:200 +msgid "Provide channel menu in navigation bar" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:200 +msgid "Default: channel menu located in app menu" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:201 +msgid "Link post titles to source" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:203 +#: ../../Zotlabs/Widget/Newmember.php:75 +msgid "New Member Links" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Display.php:203 +msgid "Display new member quick links menu" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Photos.php:40 +msgid "Photos Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:329 +msgid "Nobody except yourself" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:330 +msgid "Only those you specifically allow" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:331 +msgid "Approved connections" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:332 +msgid "Any connections" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:333 +msgid "Anybody on this website" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:334 +msgid "Anybody in this network" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:335 +msgid "Anybody authenticated" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:336 +msgid "Anybody on the internet" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:411 +msgid "Publish your default profile in the network directory" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:416 +msgid "Allow us to suggest you as a potential friend to new members?" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:420 +msgid "or" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:429 +msgid "Your channel address is" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:432 +msgid "Your files/photos are accessible via WebDAV at" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:472 +msgid "Automatic membership approval" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:493 +msgid "Channel Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:500 +msgid "Basic Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:501 ../../include/channel.php:1763 +msgid "Full Name:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:503 +msgid "Your Timezone:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:504 +msgid "Default Post Location:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:504 +msgid "Geographical location to display on your posts" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:505 +msgid "Use Browser Location:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:507 +msgid "Adult Content" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:507 +msgid "" +"This channel frequently or regularly publishes adult content. (Please tag " +"any adult material and/or nudity with #NSFW)" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:509 +msgid "Security and Privacy Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:511 +msgid "Your permissions are already configured. Click to view/adjust" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:513 +msgid "Hide my online presence" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:513 +msgid "Prevents displaying in your profile that you are online" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:515 +msgid "Simple Privacy Settings:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:516 +msgid "" +"Very Public - extremely permissive (should be used with caution)" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:517 +msgid "" +"Typical - default public, privacy when desired (similar to social " +"network permissions but with improved privacy)" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:518 +msgid "Private - default private, never open or public" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:519 +msgid "Blocked - default blocked to/from everybody" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:521 +msgid "Allow others to tag your posts" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:521 +msgid "" +"Often used by the community to retro-actively flag inappropriate content" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:523 +msgid "Channel Permission Limits" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "Expire other channel content after this many days" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "0 or blank to use the website limit." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +#, php-format +msgid "This website expires after %d days." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "This website does not expire imported content." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:525 +msgid "The website limit takes precedence if lower than your limit." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:526 +msgid "Maximum Friend Requests/Day:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:526 +msgid "May reduce spam activity" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:527 +msgid "Default Privacy Group" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:529 +msgid "Use my default audience setting for the type of object published" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:538 +msgid "Default permissions category" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:544 +msgid "Maximum private messages per day from unknown people:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:544 +msgid "Useful to reduce spamming" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:547 +#: ../../Zotlabs/Lib/Enotify.php:68 +msgid "Notification Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:548 +msgid "By default post a status message when:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:549 +msgid "accepting a friend request" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:550 +msgid "joining a forum/community" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:551 +msgid "making an interesting profile change" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:552 +msgid "Send a notification email when:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:553 +msgid "You receive a connection request" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:554 +msgid "Your connections are confirmed" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:555 +msgid "Someone writes on your profile wall" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:556 +msgid "Someone writes a followup comment" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:557 +msgid "You receive a private message" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:558 +msgid "You receive a friend suggestion" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:559 +msgid "You are tagged in a post" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:560 +msgid "You are poked/prodded/etc. in a post" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:562 +msgid "Someone likes your post/comment" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:565 +msgid "Show visual notifications including:" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:567 +msgid "Unseen stream activity" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:568 +msgid "Unseen channel activity" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:569 +msgid "Unseen private messages" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:569 +#: ../../Zotlabs/Module/Settings/Channel.php:574 +#: ../../Zotlabs/Module/Settings/Channel.php:575 +#: ../../Zotlabs/Module/Settings/Channel.php:576 +msgid "Recommended" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:570 +msgid "Upcoming events" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:571 +msgid "Events today" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:572 +msgid "Upcoming birthdays" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:572 +msgid "Not available in all themes" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:573 +msgid "System (personal) notifications" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:574 +msgid "System info messages" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:575 +msgid "System critical alerts" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:576 +msgid "New connections" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:577 +msgid "System Registrations" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:578 +msgid "Unseen shared files" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:579 +msgid "Unseen public stream activity" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:580 +msgid "Unseen likes and dislikes" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:581 +msgid "Unseen forum posts" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:582 +msgid "Email notification hub (hostname)" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:582 +#, php-format +msgid "" +"If your channel is mirrored to multiple hubs, set this to your preferred " +"location. This will prevent duplicate email notifications. Example: %s" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:583 +msgid "Show new wall posts, private messages and connections under Notices" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:585 +msgid "Notify me of events this many days in advance" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:585 +msgid "Must be greater than 0" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:590 +msgid "Advanced Account/Page Type Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:591 +msgid "Change the behaviour of this account for special situations" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:593 +msgid "Miscellaneous Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:594 +msgid "Default photo upload folder" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:594 +#: ../../Zotlabs/Module/Settings/Channel.php:595 +msgid "%Y - current year, %m - current month" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:595 +msgid "Default file upload folder" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel.php:597 +msgid "Remove this channel." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Connections.php:40 +msgid "Connections Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Calendar.php:40 +msgid "Calendar Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Directory.php:40 +msgid "Directory Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:46 +#: ../../Zotlabs/Module/Settings/Network.php:42 +msgid "Max height of content (in pixels)" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:48 +#: ../../Zotlabs/Module/Settings/Network.php:44 +msgid "Click to expand content exceeding this height" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:61 +msgid "Personal menu to display in your channel pages" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:88 +msgid "Channel Home Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Network.php:59 +msgid "Stream Settings" +msgstr "" + +#: ../../Zotlabs/Module/Settings/Conversation.php:23 +msgid "Settings saved." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Conversation.php:25 +msgid "Settings saved. Reload page please." +msgstr "" + +#: ../../Zotlabs/Module/Settings/Conversation.php:47 +msgid "Conversation Settings" +msgstr "" + +#: ../../Zotlabs/Module/Probe.php:18 +msgid "Remote Diagnostics App" +msgstr "" + +#: ../../Zotlabs/Module/Probe.php:19 +msgid "Perform diagnostics on remote channels" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:37 +msgid "Total invitation limit exceeded." +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:61 +#, php-format +msgid "%s : Not a valid email address." +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:75 +msgid "Please join us on $Projectname" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:85 +msgid "Invitation limit exceeded. Please contact your site administrator." +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:90 +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:40 +#, php-format +msgid "%s : Message delivery failed." +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:94 +#, php-format +msgid "%d message sent." +msgid_plural "%d messages sent." +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Module/Invite.php:110 +msgid "Invite App" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:111 +msgid "Send email invitations to join this network" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:124 +msgid "You have no more invitations available" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:155 +msgid "Send invitations" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:156 +msgid "Enter email addresses, one per line:" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:157 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:163 +msgid "Your message:" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:158 +msgid "Please join my community on $Projectname." +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:160 +msgid "You will need to supply this invitation code:" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:161 +msgid "1. Register at any $Projectname location (they are all inter-connected)" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:163 +msgid "2. Enter my $Projectname network address into the site searchbar." +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:164 +msgid "or visit" +msgstr "" + +#: ../../Zotlabs/Module/Invite.php:166 +msgid "3. Click [Connect]" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:21 +msgid "About this site" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:22 +msgid "Site Name" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:26 +msgid "Administrator" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:29 +msgid "Software and Project information" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:30 +msgid "This site is powered by $Projectname" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:31 +msgid "" +"Federated and decentralised networking and identity services provided by Zot" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:34 +msgid "Additional federated transport protocols:" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:36 +#, php-format +msgid "Version %s" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:37 +msgid "Project homepage" +msgstr "" + +#: ../../Zotlabs/Module/Siteinfo.php:38 +msgid "Developer homepage" +msgstr "" + +#: ../../Zotlabs/Module/Service_limits.php:23 +msgid "No service class restrictions found." +msgstr "" + +#: ../../Zotlabs/Module/Rbmark.php:94 +msgid "Select a bookmark folder" +msgstr "" + +#: ../../Zotlabs/Module/Rbmark.php:99 +msgid "Save Bookmark" +msgstr "" + +#: ../../Zotlabs/Module/Rbmark.php:100 +msgid "URL of bookmark" +msgstr "" + +#: ../../Zotlabs/Module/Rbmark.php:105 +msgid "Or enter new bookmark folder name" +msgstr "" + +#: ../../Zotlabs/Module/Lang.php:17 +msgid "Language App" +msgstr "" + +#: ../../Zotlabs/Module/Lang.php:18 +msgid "Change UI language" +msgstr "" + +#: ../../Zotlabs/Module/Hq.php:131 +msgid "Welcome to Hubzilla!" +msgstr "" + +#: ../../Zotlabs/Module/Hq.php:131 +msgid "You have got no unseen posts..." +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:196 +#: ../../Zotlabs/Module/Cover_photo.php:254 +msgid "Cover Photos" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:297 ../../include/items.php:4860 +msgid "female" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:298 ../../include/items.php:4861 +#, php-format +msgid "%1$s updated her %2$s" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:299 ../../include/items.php:4862 +msgid "male" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:300 ../../include/items.php:4863 +#, php-format +msgid "%1$s updated his %2$s" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:302 ../../include/items.php:4865 +#, php-format +msgid "%1$s updated their %2$s" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:304 ../../include/channel.php:2328 +msgid "cover photo" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:418 +msgid "Your cover photo may be visible to anybody on the internet" +msgstr "" + +#: ../../Zotlabs/Module/Cover_photo.php:422 +msgid "Change Cover Photo" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:68 +msgid "Unable to update menu." +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:79 +msgid "Unable to create menu." +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:161 ../../Zotlabs/Module/Menu.php:174 +msgid "Menu Name" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:161 +msgid "Unique name (not visible on webpage) - required" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:162 ../../Zotlabs/Module/Menu.php:175 +msgid "Menu Title" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:162 +msgid "Visible on webpage - leave empty for no title" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:163 +msgid "Allow Bookmarks" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 +msgid "Menu may be used to store saved bookmarks" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:164 ../../Zotlabs/Module/Menu.php:225 +msgid "Submit and proceed" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:171 ../../include/text.php:2699 +msgid "Menus" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:181 +msgid "Bookmarks allowed" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:183 +msgid "Delete this menu" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:184 ../../Zotlabs/Module/Menu.php:219 +msgid "Edit menu contents" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:185 +msgid "Edit this menu" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:201 +msgid "Menu could not be deleted." +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:214 +msgid "Edit Menu" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:218 +msgid "Add or remove entries to this menu" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:220 +msgid "Menu name" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:220 +msgid "Must be unique, only seen by you" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:221 +msgid "Menu title" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:221 +msgid "Menu title as seen by others" +msgstr "" + +#: ../../Zotlabs/Module/Menu.php:222 +msgid "Allow bookmarks" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:41 +msgid "Failed to create source. No channel selected." +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:57 +msgid "Source created." +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:70 +msgid "Source updated." +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:88 +msgid "Sources App" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:89 +msgid "Automatically import channel content from other channels or feeds" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:101 +msgid "*" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:107 ../../Zotlabs/Lib/Apps.php:368 +msgid "Channel Sources" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:108 +msgid "Manage remote sources of content for your channel." +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:119 +msgid "New Source" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:120 ../../Zotlabs/Module/Sources.php:154 +msgid "" +"Import all or selected content from the following channel into this channel " +"and distribute it according to your channel settings." +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 +msgid "Only import content with these words (one per line)" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155 +msgid "Leave blank to import all public content" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:161 +msgid "Channel Name" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:123 ../../Zotlabs/Module/Sources.php:158 +msgid "" +"Add the following categories to posts imported from this source (comma " +"separated)" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +msgid "Resend posts with this channel as author" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159 +msgid "Copyrights may apply" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:144 ../../Zotlabs/Module/Sources.php:174 +msgid "Source not found." +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:151 +msgid "Edit Source" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:152 +msgid "Delete Source" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:182 +msgid "Source removed" +msgstr "" + +#: ../../Zotlabs/Module/Sources.php:184 +msgid "Unable to remove source." +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:165 +msgid "Poke App" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:166 +msgid "Poke somebody in your addressbook" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:199 ../../Zotlabs/Lib/Apps.php:351 +#: ../../include/conversation.php:1140 +msgid "Poke" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:200 +msgid "Poke somebody" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:203 +msgid "Poke/Prod" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:204 +msgid "Poke, prod or do other things to somebody" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:211 +msgid "Recipient" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:212 +msgid "Choose what you wish to do to recipient" +msgstr "" + +#: ../../Zotlabs/Module/Poke.php:215 ../../Zotlabs/Module/Poke.php:216 +msgid "Make this post private" +msgstr "" + +#: ../../Zotlabs/Module/Network.php:105 +msgid "No such group" +msgstr "" + +#: ../../Zotlabs/Module/Network.php:152 +msgid "No such channel" +msgstr "" + +#: ../../Zotlabs/Module/Network.php:239 +msgid "Privacy group is empty" +msgstr "" + +#: ../../Zotlabs/Module/Network.php:249 +msgid "Privacy group: " +msgstr "" + +#: ../../Zotlabs/Module/Network.php:322 +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:29 +msgid "Invalid channel." +msgstr "" + +#: ../../Zotlabs/Module/Attach_edit.php:118 +msgid "Can not copy folder into itself." +msgstr "" + +#: ../../Zotlabs/Module/Attach_edit.php:131 +#, php-format +msgid "Can not move folder \"%s\" into itself." +msgstr "" + +#: ../../Zotlabs/Module/Viewsrc.php:43 +msgid "item" +msgstr "" + +#: ../../Zotlabs/Module/Lockview.php:75 +msgid "Remote privacy information not available." +msgstr "" + +#: ../../Zotlabs/Module/Lockview.php:96 +msgid "Visible to:" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:292 +msgid "Change filename to" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:309 ../../Zotlabs/Storage/Browser.php:390 +msgid "Select a target location" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:310 ../../Zotlabs/Storage/Browser.php:391 +msgid "Copy to target location" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:311 ../../Zotlabs/Storage/Browser.php:389 +msgid "Set permissions for all files and sub folders" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:312 +msgid "Notify your contacts about this file" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:351 +msgid "File category" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:362 +msgid "Total" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:364 +msgid "Shared" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:366 +msgid "Add Files" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:369 ../../Zotlabs/Lib/ThreadItem.php:174 +msgid "Admin Delete" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:381 +msgid "parent" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:399 +msgid "Select All" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:400 +msgid "Bulk Actions" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:401 +msgid "Adjust Permissions" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:402 +msgid "Move or Copy" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:405 +msgid "Info" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:406 +msgid "Rename" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:407 ../../Zotlabs/Lib/Apps.php:360 +msgid "Post" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:408 +msgid "Attachment BBcode" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:409 +msgid "Embed BBcode" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:410 +msgid "Link BBcode" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:480 +#, php-format +msgid "You are using %1$s of your available file storage." +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:485 +#, php-format +msgid "You are using %1$s of %2$s available file storage. (%3$s%)" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:496 +msgid "WARNING:" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:537 +msgid "Create new folder" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:539 +msgid "Upload file" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:551 +msgid "Drop files here to immediately upload" +msgstr "" + +#: ../../Zotlabs/Storage/Browser.php:554 +msgid "" +"You can select files via the upload button or drop them right here or into " +"an existing folder." +msgstr "" + +#: ../../Zotlabs/Zot/Auth.php:152 +msgid "" +"Remote authentication blocked. You are logged into this site locally. Please " +"logout and retry." +msgstr "" + +#: ../../Zotlabs/Zot/Auth.php:264 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:76 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:178 +#, php-format +msgid "Welcome %s. Remote authentication successful." +msgstr "" + +#: ../../Zotlabs/Lib/Group.php:28 ../../include/group.php:23 +msgid "" +"A deleted group with this name was revived. Existing item permissions " +"may apply to this group and any future members. If this is " +"not what you intended, please create another group with a different name." +msgstr "" + +#: ../../Zotlabs/Lib/Group.php:270 ../../include/group.php:265 +msgid "Add new connections to this privacy group" +msgstr "" + +#: ../../Zotlabs/Lib/Group.php:302 ../../Zotlabs/Lib/AccessList.php:311 +#: ../../include/group.php:299 +msgid "edit" +msgstr "" + +#: ../../Zotlabs/Lib/Group.php:325 ../../include/group.php:322 +msgid "Edit group" +msgstr "" + +#: ../../Zotlabs/Lib/Group.php:326 ../../include/group.php:323 +msgid "Add privacy group" +msgstr "" + +#: ../../Zotlabs/Lib/Group.php:327 ../../include/group.php:324 +msgid "Channels not in any privacy group" +msgstr "" + +#: ../../Zotlabs/Lib/Group.php:329 ../../Zotlabs/Lib/AccessList.php:336 +#: ../../Zotlabs/Widget/Savedsearch.php:84 ../../include/group.php:326 +msgid "add" +msgstr "" + +#: ../../Zotlabs/Lib/Connect.php:46 ../../Zotlabs/Lib/Connect.php:143 +#: ../../include/follow.php:37 +msgid "Channel is blocked on this site." +msgstr "" + +#: ../../Zotlabs/Lib/Connect.php:51 ../../include/follow.php:42 +msgid "Channel location missing." +msgstr "" + +#: ../../Zotlabs/Lib/Connect.php:103 ../../include/follow.php:166 +msgid "Remote channel or protocol unavailable." +msgstr "" + +#: ../../Zotlabs/Lib/Connect.php:137 ../../include/follow.php:190 +msgid "Channel discovery failed." +msgstr "" + +#: ../../Zotlabs/Lib/Connect.php:155 ../../include/follow.php:202 +msgid "Protocol disabled." +msgstr "" + +#: ../../Zotlabs/Lib/Connect.php:167 ../../include/follow.php:213 +msgid "Cannot connect to yourself." +msgstr "" + +#: ../../Zotlabs/Lib/Connect.php:271 +msgid "error saving data" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:323 +msgid "Apps" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:324 +msgid "Affinity Tool" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:327 +msgid "Site Admin" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:328 +#: ../../extend/addon/hzaddons/buglink/buglink.php:16 +msgid "Report Bug" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:329 ../../include/nav.php:490 +msgid "Bookmarks" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:330 ../../Zotlabs/Widget/Chatroom_list.php:16 +#: ../../include/nav.php:477 ../../include/nav.php:480 +msgid "Chatrooms" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:331 +msgid "Content Filter" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:332 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:135 +msgid "Content Import" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:334 +msgid "Remote Diagnostics" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:335 +msgid "Suggest Channels" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:336 ../../include/nav.php:124 +#: ../../include/nav.php:128 ../../boot.php:1705 +msgid "Login" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:338 +msgid "Stream" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:342 ../../include/nav.php:539 +msgid "Wiki" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:343 ../../include/features.php:104 +msgid "Channel Home" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:346 ../../include/features.php:82 +#: ../../include/nav.php:463 ../../include/nav.php:466 +msgid "Calendar" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:347 ../../include/features.php:192 +msgid "Directory" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:349 +msgid "Mail" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:352 +msgid "Chat" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:354 +msgid "Probe" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:355 +msgid "Suggest" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:356 +msgid "Random Channel" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:357 +msgid "Invite" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:358 ../../Zotlabs/Widget/Admin.php:26 +msgid "Features" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:359 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:69 +msgid "Language" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:361 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:58 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:59 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:60 +msgid "Profile Photo" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:363 ../../include/features.php:383 +msgid "Profiles" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:365 +msgid "Notifications" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:366 +msgid "Order Apps" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:367 +msgid "CardDAV" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:369 +msgid "Guest Access" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:370 ../../Zotlabs/Widget/Notes.php:21 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2625 +msgid "Notes" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:371 +msgid "OAuth Apps Manager" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:372 +msgid "OAuth2 Apps Manager" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:373 +msgid "PDL Editor" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:376 +msgid "My Chatrooms" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:377 +msgid "Channel Export" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:554 +msgid "Purchase" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:559 +msgid "Undelete" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:569 +msgid "Add to app-tray" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:570 +msgid "Remove from app-tray" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:571 +msgid "Pin to navbar" +msgstr "" + +#: ../../Zotlabs/Lib/Apps.php:572 +msgid "Unpin from navbar" +msgstr "" + +#: ../../Zotlabs/Lib/DB_Upgrade.php:67 +msgid "Source code of failed update: " +msgstr "" + +#: ../../Zotlabs/Lib/DB_Upgrade.php:88 +#, php-format +msgid "Update Error at %s" +msgstr "" + +#: ../../Zotlabs/Lib/DB_Upgrade.php:94 +#, php-format +msgid "Update %s failed. See error logs." +msgstr "" + +#: ../../Zotlabs/Lib/AccessList.php:28 +msgid "" +"A deleted list with this name was revived. Existing item permissions " +"may apply to this list and any future members. If this is " +"not what you intended, please create another list with a different name." +msgstr "" + +#: ../../Zotlabs/Lib/AccessList.php:286 +msgid "Add new connections to this access list" +msgstr "" + +#: ../../Zotlabs/Lib/AccessList.php:331 +msgid "Lists" +msgstr "" + +#: ../../Zotlabs/Lib/AccessList.php:332 +msgid "Edit list" +msgstr "" + +#: ../../Zotlabs/Lib/AccessList.php:333 +msgid "Create new list" +msgstr "" + +#: ../../Zotlabs/Lib/AccessList.php:334 +msgid "Channels not in any access list" +msgstr "" + +#: ../../Zotlabs/Lib/Chatroom.php:25 +msgid "Missing room name" +msgstr "" + +#: ../../Zotlabs/Lib/Chatroom.php:34 +msgid "Duplicate room name" +msgstr "" + +#: ../../Zotlabs/Lib/Chatroom.php:84 ../../Zotlabs/Lib/Chatroom.php:92 +msgid "Invalid room specifier." +msgstr "" + +#: ../../Zotlabs/Lib/Chatroom.php:124 +msgid "Room not found." +msgstr "" + +#: ../../Zotlabs/Lib/Chatroom.php:145 +msgid "Room is full" +msgstr "" + +#: ../../Zotlabs/Lib/Techlevels.php:10 +msgid "0. Beginner/Basic" +msgstr "" + +#: ../../Zotlabs/Lib/Techlevels.php:11 +msgid "1. Novice - not skilled but willing to learn" +msgstr "" + +#: ../../Zotlabs/Lib/Techlevels.php:12 +msgid "2. Intermediate - somewhat comfortable" +msgstr "" + +#: ../../Zotlabs/Lib/Techlevels.php:13 +msgid "3. Advanced - very comfortable" +msgstr "" + +#: ../../Zotlabs/Lib/Techlevels.php:14 +msgid "4. Expert - I can write computer code" +msgstr "" + +#: ../../Zotlabs/Lib/Techlevels.php:15 +msgid "5. Wizard - I probably know more than you do" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:60 +msgid "$Projectname Notification" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:61 +#: ../../extend/addon/hzaddons/diaspora/util.php:336 +#: ../../extend/addon/hzaddons/diaspora/util.php:349 +#: ../../extend/addon/hzaddons/diaspora/p.php:48 +msgid "$projectname" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:63 +msgid "Thank You," +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:65 +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:33 +#, php-format +msgid "%s Administrator" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:66 +#, php-format +msgid "This email was sent by %1$s at %2$s." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:67 +#, php-format +msgid "" +"To stop receiving these messages, please adjust your Notification Settings " +"at %s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:68 +#, php-format +msgid "To stop receiving these messages, please adjust your %s." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:123 +#, php-format +msgid "%s " +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:127 +#, php-format +msgid "[$Projectname:Notify] New mail received at %s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:129 +#, php-format +msgid "%1$s sent you a new private message at %2$s." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:130 +#, php-format +msgid "%1$s sent you %2$s." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:130 +msgid "a private message" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:131 +#, php-format +msgid "Please visit %s to view and/or reply to your private messages." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:144 +msgid "commented on" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:157 +msgid "liked" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:160 +msgid "disliked" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:165 +msgid "voted on" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:208 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]a %4$s[/zrl]" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:216 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]%4$s's %5$s[/zrl]" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:225 +#, php-format +msgid "%1$s %2$s [zrl=%3$s]your %4$s[/zrl]" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:237 +#, php-format +msgid "[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:239 +#, php-format +msgid "[$Projectname:Notify] Comment to conversation #%1$d by %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:240 +#, php-format +msgid "%1$s commented on an item/conversation you have been following." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:243 ../../Zotlabs/Lib/Enotify.php:324 +#: ../../Zotlabs/Lib/Enotify.php:340 ../../Zotlabs/Lib/Enotify.php:365 +#: ../../Zotlabs/Lib/Enotify.php:382 ../../Zotlabs/Lib/Enotify.php:395 +#, php-format +msgid "Please visit %s to view and/or reply to the conversation." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:247 ../../Zotlabs/Lib/Enotify.php:248 +#, php-format +msgid "Please visit %s to approve or reject this comment." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:306 +#, php-format +msgid "%1$s liked [zrl=%2$s]your %3$s[/zrl]" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:320 +#, php-format +msgid "[$Projectname:Notify] Like received to conversation #%1$d by %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:321 +#, php-format +msgid "%1$s liked an item/conversation you created." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:332 +#, php-format +msgid "[$Projectname:Notify] %s posted to your profile wall" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:334 +#, php-format +msgid "%1$s posted to your profile wall at %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:336 +#, php-format +msgid "%1$s posted to [zrl=%2$s]your wall[/zrl]" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:359 +#, php-format +msgid "[$Projectname:Notify] %s tagged you" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:360 +#, php-format +msgid "%1$s tagged you at %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:361 +#, php-format +msgid "%1$s [zrl=%2$s]tagged you[/zrl]." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:372 +#, php-format +msgid "[$Projectname:Notify] %1$s poked you" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:373 +#, php-format +msgid "%1$s poked you at %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:374 +#, php-format +msgid "%1$s [zrl=%2$s]poked you[/zrl]." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:389 +#, php-format +msgid "[$Projectname:Notify] %s tagged your post" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:390 +#, php-format +msgid "%1$s tagged your post at %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:391 +#, php-format +msgid "%1$s tagged [zrl=%2$s]your post[/zrl]" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:402 +msgid "[$Projectname:Notify] Introduction received" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:403 +#, php-format +msgid "You've received an new connection request from '%1$s' at %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:404 +#, php-format +msgid "You've received [zrl=%1$s]a new connection request[/zrl] from %2$s." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:407 ../../Zotlabs/Lib/Enotify.php:425 +#, php-format +msgid "You may visit their profile at %s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:409 +#, php-format +msgid "Please visit %s to approve or reject the connection request." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:416 +msgid "[$Projectname:Notify] Friend suggestion received" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:417 +#, php-format +msgid "You've received a friend suggestion from '%1$s' at %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:418 +#, php-format +msgid "You've received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:423 +msgid "Name:" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:424 +msgid "Photo:" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:427 +#, php-format +msgid "Please visit %s to approve or reject the suggestion." +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:652 +msgid "[$Projectname:Notify]" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:820 +msgid "created a new poll" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:820 +msgid "created a new post" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:821 +#, php-format +msgid "voted on %s's poll" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:821 +#, php-format +msgid "commented on %s's post" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:825 +#, php-format +msgid "repeated %s's post" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:837 +#, php-format +msgid "edited a post dated %s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:841 +#, php-format +msgid "edited a comment dated %s" +msgstr "" + +#: ../../Zotlabs/Lib/Enotify.php:970 +msgid "created an event" +msgstr "" + +#: ../../Zotlabs/Lib/Libsync.php:740 ../../include/zot.php:2657 +#, php-format +msgid "Unable to verify site signature for %s" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:42 +#: ../../Zotlabs/Lib/NativeWikiPage.php:94 +msgid "(No Title)" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:109 +msgid "Wiki page create failed." +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:122 +msgid "Wiki not found." +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:133 +msgid "Destination name already exists" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:166 +#: ../../Zotlabs/Lib/NativeWikiPage.php:362 +msgid "Page not found" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:197 +msgid "Error reading page content" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:353 +#: ../../Zotlabs/Lib/NativeWikiPage.php:402 +#: ../../Zotlabs/Lib/NativeWikiPage.php:469 +#: ../../Zotlabs/Lib/NativeWikiPage.php:510 +msgid "Error reading wiki" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:390 +msgid "Page update failed." +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:424 +msgid "Nothing deleted" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:490 +msgid "Compare: object not found." +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:496 +msgid "Page updated" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:499 +msgid "Untitled" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:505 +msgid "Wiki resource_id required for git commit" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:565 +#: ../../Zotlabs/Widget/Wiki_page_history.php:23 +msgctxt "wiki_history" +msgid "Message" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:566 +#: ../../Zotlabs/Widget/Wiki_page_history.php:24 +msgid "Date" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:568 +#: ../../Zotlabs/Widget/Wiki_page_history.php:26 +msgid "Compare" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWikiPage.php:606 ../../include/bbcode.php:1018 +#: ../../include/bbcode.php:1190 +msgid "Different viewers will see this text differently" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:103 ../../include/conversation.php:739 +msgid "Private Message" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:130 +msgid "Privacy conflict. Discretion advised." +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:180 ../../include/conversation.php:729 +msgid "Select" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I will attend" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I will not attend" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:205 ../../Zotlabs/Widget/Pinned.php:70 +msgid "I might attend" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I agree" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I disagree" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:219 ../../Zotlabs/Widget/Pinned.php:81 +msgid "I abstain" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:273 ../../include/conversation.php:734 +msgid "Toggle Star Status" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:284 ../../Zotlabs/Widget/Pinned.php:88 +#: ../../include/conversation.php:746 +msgid "Message signature validated" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:285 ../../Zotlabs/Widget/Pinned.php:89 +#: ../../include/conversation.php:747 +msgid "Message signature incorrect" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:301 ../../include/conversation.php:933 +msgid "Conversation Tools" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:317 ../../include/taxonomy.php:582 +msgid "like" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:318 ../../include/taxonomy.php:583 +msgid "dislike" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "Reply on this comment" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "reply" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:319 +msgid "Reply to" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Widget/Pinned.php:99 +msgid "Share This" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Widget/Pinned.php:99 +msgid "share" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:339 +msgid "Delivery Report" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:358 +#, php-format +msgid "%d comment" +msgid_plural "%d comments" +msgstr[0] "" +msgstr[1] "" + +#: ../../Zotlabs/Lib/ThreadItem.php:359 +#, php-format +msgid "%d unseen" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:412 +msgid "to" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:413 ../../Zotlabs/Widget/Pinned.php:128 +msgid "via" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:414 +msgid "Wall-to-Wall" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:415 +msgid "via Wall-To-Wall:" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:429 ../../Zotlabs/Widget/Pinned.php:133 +#: ../../include/conversation.php:806 +#, php-format +msgid "from %s" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:432 ../../Zotlabs/Widget/Pinned.php:136 +#: ../../include/conversation.php:809 +#, php-format +msgid "last edited: %s" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:433 ../../Zotlabs/Widget/Pinned.php:137 +#: ../../include/conversation.php:810 +#, php-format +msgid "Expires: %s" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:442 +msgid "Attend" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:443 ../../Zotlabs/Widget/Pinned.php:143 +msgid "Attendance Options" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:444 ../../include/text.php:1922 +msgid "Vote" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:445 ../../Zotlabs/Widget/Pinned.php:144 +msgid "Voting Options" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:460 +msgid "Go to previous comment" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:469 ../../Zotlabs/Widget/Pinned.php:156 +msgid "Pinned post" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:471 ../../Zotlabs/Widget/Pinned.php:157 +#: ../../include/js_strings.php:39 +msgid "Unpin from the top" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:471 ../../include/js_strings.php:38 +msgid "Pin to the top" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:472 +#: ../../extend/addon/hzaddons/bookmarker/bookmarker.php:38 +msgid "Save Bookmarks" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:473 +msgid "Add to Calendar" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:500 ../../include/conversation.php:516 +msgid "This is an unsaved preview" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:533 ../../include/js_strings.php:7 +#, php-format +msgid "%s show all" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:826 ../../include/conversation.php:1449 +#: ../../extend/addon/hzaddons/hsse/hsse.php:200 +msgid "Bold" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:827 ../../include/conversation.php:1450 +#: ../../extend/addon/hzaddons/hsse/hsse.php:201 +msgid "Italic" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:828 ../../include/conversation.php:1451 +#: ../../extend/addon/hzaddons/hsse/hsse.php:202 +msgid "Underline" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:829 ../../include/conversation.php:1452 +#: ../../extend/addon/hzaddons/hsse/hsse.php:203 +msgid "Quote" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:830 ../../include/conversation.php:1453 +#: ../../extend/addon/hzaddons/hsse/hsse.php:204 +msgid "Code" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:831 +msgid "Image" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:832 ../../include/conversation.php:1454 +#: ../../extend/addon/hzaddons/hsse/hsse.php:205 +msgid "Attach/Upload file" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:833 +msgid "Insert Link" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:834 +msgid "Video" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:844 +msgid "Your full name (required)" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:845 +msgid "Your email address (required)" +msgstr "" + +#: ../../Zotlabs/Lib/ThreadItem.php:846 +msgid "Your website URL (optional)" +msgstr "" + +#: ../../Zotlabs/Lib/Activity.php:2110 +#, php-format +msgid "Likes %1$s's %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Activity.php:2113 +#, php-format +msgid "Doesn't like %1$s's %2$s" +msgstr "" + +#: ../../Zotlabs/Lib/Activity.php:2119 +#, php-format +msgid "Will attend %s's event" +msgstr "" + +#: ../../Zotlabs/Lib/Activity.php:2122 +#, php-format +msgid "Will not attend %s's event" +msgstr "" + +#: ../../Zotlabs/Lib/Activity.php:2125 +#, php-format +msgid "May attend %s's event" +msgstr "" + +#: ../../Zotlabs/Lib/Activity.php:2128 +#, php-format +msgid "May not attend %s's event" +msgstr "" + +#: ../../Zotlabs/Lib/Activity.php:2821 ../../Zotlabs/Lib/Activity.php:3015 +#: ../../include/network.php:1736 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1479 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1733 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1941 +msgid "ActivityPub" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWiki.php:145 +msgid "Wiki updated successfully" +msgstr "" + +#: ../../Zotlabs/Lib/NativeWiki.php:199 +msgid "Wiki files deleted successfully" +msgstr "" + +#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../include/dir_fns.php:141 +msgid "Directory Options" +msgstr "" + +#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../include/dir_fns.php:143 +msgid "Safe Mode" +msgstr "" + +#: ../../Zotlabs/Lib/Libzotdir.php:166 ../../include/dir_fns.php:144 +msgid "Public Forums Only" +msgstr "" + +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/dir_fns.php:145 +msgid "This Website Only" +msgstr "" + +#: ../../Zotlabs/Lib/Permcat.php:82 +msgctxt "permcat" +msgid "default" +msgstr "" + +#: ../../Zotlabs/Lib/Permcat.php:133 +msgctxt "permcat" +msgid "follower" +msgstr "" + +#: ../../Zotlabs/Lib/Permcat.php:137 +msgctxt "permcat" +msgid "contributor" +msgstr "" + +#: ../../Zotlabs/Lib/Permcat.php:141 +msgctxt "permcat" +msgid "publisher" +msgstr "" + +#: ../../Zotlabs/Lib/Libzot.php:656 ../../include/zot.php:802 +msgid "Unable to verify channel signature" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:34 +#: ../../include/acl_selectors.php:33 +msgid "Visible to your default audience" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:107 +#: ../../include/acl_selectors.php:135 +msgid "Only me" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:108 +msgid "Public" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:109 +msgid "Anybody in the $Projectname network" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:110 +#, php-format +msgid "Any account on %s" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:111 +msgid "Any of my connections" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:112 +msgid "Only connections I specifically allow" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:113 +msgid "Anybody authenticated (could include visitors from other networks)" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:114 +msgid "Any connections including those who haven't yet been approved" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:150 +msgid "" +"This is your default setting for the audience of your normal stream, and " +"posts." +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:151 +msgid "" +"This is your default setting for who can view your default channel profile" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:152 +msgid "This is your default setting for who can view your connections" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:153 +msgid "" +"This is your default setting for who can view your file storage and photos" +msgstr "" + +#: ../../Zotlabs/Lib/PermissionDescription.php:154 +msgid "This is your default setting for the audience of your webpages" +msgstr "" + +#: ../../Zotlabs/Widget/Appcategories.php:46 ../../Zotlabs/Widget/Filer.php:31 +#: ../../include/contact_widgets.php:56 ../../include/contact_widgets.php:111 +#: ../../include/contact_widgets.php:155 ../../include/contact_widgets.php:200 +#: ../../include/contact_widgets.php:235 +msgid "Everything" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:37 +msgid "Select Channel" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:42 +msgid "Read-write" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:43 +msgid "Read-only" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:127 +msgid "Channel Calendar" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:131 +msgid "Shared CalDAV Calendars" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:135 +msgid "Share this calendar" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:137 +msgid "Calendar name and color" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:139 +msgid "Create new CalDAV calendar" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:141 +msgid "Calendar Name" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:142 +msgid "Calendar Tools" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:144 +msgid "Import calendar" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:145 +msgid "Select a calendar to import to" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:172 +msgid "Addressbooks" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:174 +msgid "Addressbook name" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:176 +msgid "Create new addressbook" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:177 +msgid "Addressbook Name" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:179 +msgid "Addressbook Tools" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:180 +msgid "Import addressbook" +msgstr "" + +#: ../../Zotlabs/Widget/Cdav.php:181 +msgid "Select an addressbook to import to" +msgstr "" + +#: ../../Zotlabs/Widget/Filer.php:28 +#: ../../Zotlabs/Widget/Activity_filter.php:179 +#: ../../include/contact_widgets.php:53 ../../include/features.php:319 +msgid "Saved Folders" +msgstr "" + +#: ../../Zotlabs/Widget/Tagcloud.php:22 ../../include/taxonomy.php:323 +#: ../../include/taxonomy.php:458 ../../include/taxonomy.php:479 +msgid "Tags" +msgstr "" + +#: ../../Zotlabs/Widget/Archive.php:43 +msgid "Archives" +msgstr "" + +#: ../../Zotlabs/Widget/Chatroom_members.php:11 +msgid "Chat Members" +msgstr "" + +#: ../../Zotlabs/Widget/Rating.php:51 +msgid "Rating Tools" +msgstr "" + +#: ../../Zotlabs/Widget/Rating.php:55 ../../Zotlabs/Widget/Rating.php:57 +msgid "Rate Me" +msgstr "" + +#: ../../Zotlabs/Widget/Rating.php:60 +msgid "View Ratings" +msgstr "" + +#: ../../Zotlabs/Widget/Wiki_pages.php:34 +#: ../../Zotlabs/Widget/Wiki_pages.php:91 +msgid "Add new page" +msgstr "" + +#: ../../Zotlabs/Widget/Wiki_pages.php:85 +msgid "Wiki Pages" +msgstr "" + +#: ../../Zotlabs/Widget/Wiki_pages.php:96 +msgid "Page name" +msgstr "" + +#: ../../Zotlabs/Widget/Bookmarkedchats.php:24 +msgid "Bookmarked Chatrooms" +msgstr "" + +#: ../../Zotlabs/Widget/Photo.php:48 ../../Zotlabs/Widget/Photo_rand.php:58 +msgid "photo/image" +msgstr "" + +#: ../../Zotlabs/Widget/Forums.php:100 +#: ../../Zotlabs/Widget/Activity_filter.php:115 +#: ../../Zotlabs/Widget/Notifications.php:139 +#: ../../Zotlabs/Widget/Notifications.php:140 +#: ../../include/acl_selectors.php:124 +msgid "Forums" +msgstr "" + +#: ../../Zotlabs/Widget/Savedsearch.php:75 +msgid "Remove term" +msgstr "" + +#: ../../Zotlabs/Widget/Savedsearch.php:83 ../../include/features.php:311 +msgid "Saved Searches" +msgstr "" + +#: ../../Zotlabs/Widget/Follow.php:22 +#, php-format +msgid "You have %1$.0f of %2$.0f allowed connections." +msgstr "" + +#: ../../Zotlabs/Widget/Follow.php:29 +msgid "Add New Connection" +msgstr "" + +#: ../../Zotlabs/Widget/Follow.php:30 +msgid "Enter channel address" +msgstr "" + +#: ../../Zotlabs/Widget/Follow.php:31 +msgid "Examples: bob@example.com, https://example.com/barbara" +msgstr "" + +#: ../../Zotlabs/Widget/Suggestions.php:53 +msgid "Suggestions" +msgstr "" + +#: ../../Zotlabs/Widget/Suggestions.php:54 +msgid "See more..." +msgstr "" + +#: ../../Zotlabs/Widget/Tasklist.php:23 +msgid "Tasks" +msgstr "" + +#: ../../Zotlabs/Widget/Admin.php:23 ../../Zotlabs/Widget/Admin.php:60 +msgid "Member registrations waiting for confirmation" +msgstr "" + +#: ../../Zotlabs/Widget/Admin.php:29 +msgid "Inspect queue" +msgstr "" + +#: ../../Zotlabs/Widget/Admin.php:31 +msgid "DB updates" +msgstr "" + +#: ../../Zotlabs/Widget/Admin.php:55 ../../include/nav.php:194 +msgid "Admin" +msgstr "" + +#: ../../Zotlabs/Widget/Admin.php:56 +msgid "Addon Features" +msgstr "" + +#: ../../Zotlabs/Widget/Chatroom_list.php:20 +msgid "Overview" +msgstr "" + +#: ../../Zotlabs/Widget/Appstore.php:11 +msgid "App Collections" +msgstr "" + +#: ../../Zotlabs/Widget/Appstore.php:13 +msgid "Installed apps" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_order.php:90 +msgid "Commented Date" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_order.php:94 +msgid "Order by last commented date" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_order.php:97 +msgid "Posted Date" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_order.php:101 +msgid "Order by last posted date" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_order.php:104 +msgid "Date Unthreaded" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_order.php:108 +msgid "Order unthreaded by date" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_order.php:123 +msgid "Stream Order" +msgstr "" + +#: ../../Zotlabs/Widget/Mailmenu.php:13 +msgid "Private Mail Menu" +msgstr "" + +#: ../../Zotlabs/Widget/Mailmenu.php:15 +msgid "Combined View" +msgstr "" + +#: ../../Zotlabs/Widget/Mailmenu.php:20 +msgid "Inbox" +msgstr "" + +#: ../../Zotlabs/Widget/Mailmenu.php:25 +msgid "Outbox" +msgstr "" + +#: ../../Zotlabs/Widget/Mailmenu.php:30 +msgid "New Message" +msgstr "" + +#: ../../Zotlabs/Widget/Affinity.php:54 +msgid "Refresh" +msgstr "" + +#: ../../Zotlabs/Widget/Hq_controls.php:14 +msgid "HQ Control Panel" +msgstr "" + +#: ../../Zotlabs/Widget/Hq_controls.php:17 +msgid "Create a new post" +msgstr "" + +#: ../../Zotlabs/Widget/Eventstools.php:13 +msgid "Events Tools" +msgstr "" + +#: ../../Zotlabs/Widget/Eventstools.php:14 +msgid "Export Calendar" +msgstr "" + +#: ../../Zotlabs/Widget/Eventstools.php:15 +msgid "Import Calendar" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:33 +msgid "Direct Messages" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:37 +msgid "Show direct (private) messages" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:42 +msgid "Events" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:46 +msgid "Show posts that include events" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:52 +msgid "Polls" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:56 +msgid "Show posts that include polls" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:77 +#, php-format +msgid "Show posts related to the %s privacy group" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:86 +msgid "Show my privacy groups" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:108 +msgid "Show posts to this forum" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:119 +msgid "Show forums" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:133 +msgid "Starred Posts" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:137 +msgid "Show posts that I have starred" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:148 +msgid "Personal Posts" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:152 +msgid "Show posts that mention or involve me" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:173 +#, php-format +msgid "Show posts that I have filed to %s" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:183 +msgid "Show filed post categories" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:197 +msgid "Panel search" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:207 +msgid "Filter by name" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:222 +msgid "Remove active filter" +msgstr "" + +#: ../../Zotlabs/Widget/Activity_filter.php:238 +msgid "Stream Filters" +msgstr "" + +#: ../../Zotlabs/Widget/Activity.php:50 +msgctxt "widget" +msgid "Activity" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:16 +msgid "New Network Activity" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:17 +msgid "New Network Activity Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:20 +msgid "View your network activity" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:23 +#: ../../Zotlabs/Widget/Notifications.php:62 +msgid "Mark all notifications read" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:26 +#: ../../Zotlabs/Widget/Notifications.php:46 +#: ../../Zotlabs/Widget/Notifications.php:65 +#: ../../Zotlabs/Widget/Notifications.php:172 +msgid "Show new posts only" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:27 +#: ../../Zotlabs/Widget/Notifications.php:47 +#: ../../Zotlabs/Widget/Notifications.php:66 +#: ../../Zotlabs/Widget/Notifications.php:142 +#: ../../Zotlabs/Widget/Notifications.php:173 +msgid "Filter by name or address" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:36 +msgid "New Home Activity" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:37 +msgid "New Home Activity Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:40 +msgid "View your home activity" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:43 +#: ../../Zotlabs/Widget/Notifications.php:169 +msgid "Mark all notifications seen" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:55 +msgid "New Direct Messages" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:56 +msgid "New Direct Messages Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:59 +msgid "View your direct messages" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:74 +msgid "New Mails" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:75 +msgid "New Mails Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:78 +msgid "View your private mails" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:81 +msgid "Mark all messages seen" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:89 +msgid "New Events" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:90 +msgid "New Events Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:93 +msgid "View events" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:96 +msgid "Mark all events seen" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:105 +msgid "New Connections Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:108 +msgid "View all connections" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:116 +msgid "New Files" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:117 +msgid "New Files Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:124 +#: ../../Zotlabs/Widget/Notifications.php:125 +msgid "Notices" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:128 +msgid "View all notices" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:131 +msgid "Mark all notices seen" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:152 +msgid "New Registrations" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:153 +msgid "New Registrations Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:163 +msgid "Public Stream Notifications" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:166 +msgid "View the public stream" +msgstr "" + +#: ../../Zotlabs/Widget/Notifications.php:181 +msgid "Sorry, you have got no notifications at the moment" +msgstr "" + +#: ../../Zotlabs/Widget/Pinned.php:123 ../../Zotlabs/Widget/Pinned.php:124 +#, php-format +msgid "View %s's profile - %s" +msgstr "" + +#: ../../Zotlabs/Widget/Pinned.php:158 +msgid "Don't show" +msgstr "" + +#: ../../Zotlabs/Widget/Settings_menu.php:32 +msgid "Account settings" +msgstr "" + +#: ../../Zotlabs/Widget/Settings_menu.php:38 +msgid "Channel settings" +msgstr "" + +#: ../../Zotlabs/Widget/Settings_menu.php:46 +msgid "Display settings" +msgstr "" + +#: ../../Zotlabs/Widget/Settings_menu.php:53 +msgid "Manage locations" +msgstr "" + +#: ../../Zotlabs/Widget/Suggestedchats.php:32 +msgid "Suggested Chatrooms" +msgstr "" + +#: ../../Zotlabs/Widget/Conversations.php:17 +msgid "Received Messages" +msgstr "" + +#: ../../Zotlabs/Widget/Conversations.php:21 +msgid "Sent Messages" +msgstr "" + +#: ../../Zotlabs/Widget/Conversations.php:25 +msgid "Conversations" +msgstr "" + +#: ../../Zotlabs/Widget/Conversations.php:37 +msgid "No messages." +msgstr "" + +#: ../../Zotlabs/Widget/Conversations.php:57 +msgid "Delete conversation" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:31 +msgid "Profile Creation" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:33 +msgid "Upload profile photo" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:34 +msgid "Upload cover photo" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:35 ../../include/nav.php:117 +msgid "Edit your profile" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:38 +msgid "Find and Connect with others" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:40 +msgid "View the directory" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:42 +msgid "Manage your connections" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:45 +msgid "Communicate" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:47 +msgid "View your channel homepage" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:48 +msgid "View your network stream" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:54 +msgid "Documentation" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:57 +msgid "Missing Features?" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:59 +msgid "Pin apps to navigation bar" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:60 +msgid "Install more apps" +msgstr "" + +#: ../../Zotlabs/Widget/Newmember.php:71 +msgid "View public stream" +msgstr "" + +#: ../../Zotlabs/Widget/Cover_photo.php:65 +msgid "Click to show more" +msgstr "" + +#: ../../util/nconfig.php:34 +msgid "Source channel not found." +msgstr "" + +#: ../../include/contact_widgets.php:11 +#, php-format +msgid "%d invitation available" +msgid_plural "%d invitations available" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/contact_widgets.php:19 +msgid "Find Channels" +msgstr "" + +#: ../../include/contact_widgets.php:20 +msgid "Enter name or interest" +msgstr "" + +#: ../../include/contact_widgets.php:21 +msgid "Connect/Follow" +msgstr "" + +#: ../../include/contact_widgets.php:22 +msgid "Examples: Robert Morgenstein, Fishing" +msgstr "" + +#: ../../include/contact_widgets.php:26 +msgid "Random Profile" +msgstr "" + +#: ../../include/contact_widgets.php:27 +msgid "Invite Friends" +msgstr "" + +#: ../../include/contact_widgets.php:29 +msgid "Advanced example: name=fred and country=iceland" +msgstr "" + +#: ../../include/contact_widgets.php:265 +msgid "Common Connections" +msgstr "" + +#: ../../include/contact_widgets.php:269 +#, php-format +msgid "View all %d common connections" +msgstr "" + +#: ../../include/conversation.php:183 +#, php-format +msgid "likes %1$s's %2$s" +msgstr "" + +#: ../../include/conversation.php:186 +#, php-format +msgid "doesn't like %1$s's %2$s" +msgstr "" + +#: ../../include/conversation.php:226 ../../include/conversation.php:228 +#, php-format +msgid "%1$s is now connected with %2$s" +msgstr "" + +#: ../../include/conversation.php:263 +#, php-format +msgid "%1$s poked %2$s" +msgstr "" + +#: ../../include/conversation.php:267 ../../include/text.php:1242 +#: ../../include/text.php:1246 +msgid "poked" +msgstr "" + +#: ../../include/conversation.php:779 +#, php-format +msgid "View %s's profile @ %s" +msgstr "" + +#: ../../include/conversation.php:799 +msgid "Categories:" +msgstr "" + +#: ../../include/conversation.php:800 +msgid "Filed under:" +msgstr "" + +#: ../../include/conversation.php:825 +msgid "View in context" +msgstr "" + +#: ../../include/conversation.php:928 +msgid "remove" +msgstr "" + +#: ../../include/conversation.php:932 +msgid "Loading..." +msgstr "" + +#: ../../include/conversation.php:934 +msgid "Delete Selected Items" +msgstr "" + +#: ../../include/conversation.php:977 +msgid "View Source" +msgstr "" + +#: ../../include/conversation.php:987 +msgid "Follow Thread" +msgstr "" + +#: ../../include/conversation.php:996 +msgid "Unfollow Thread" +msgstr "" + +#: ../../include/conversation.php:1110 +msgid "Edit Connection" +msgstr "" + +#: ../../include/conversation.php:1120 +msgid "Message" +msgstr "" + +#: ../../include/conversation.php:1262 +#, php-format +msgid "%s likes this." +msgstr "" + +#: ../../include/conversation.php:1262 +#, php-format +msgid "%s doesn't like this." +msgstr "" + +#: ../../include/conversation.php:1266 +#, php-format +msgid "%2$d people like this." +msgid_plural "%2$d people like this." +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1268 +#, php-format +msgid "%2$d people don't like this." +msgid_plural "%2$d people don't like this." +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1274 +msgid "and" +msgstr "" + +#: ../../include/conversation.php:1277 +#, php-format +msgid ", and %d other people" +msgid_plural ", and %d other people" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1278 +#, php-format +msgid "%s like this." +msgstr "" + +#: ../../include/conversation.php:1278 +#, php-format +msgid "%s don't like this." +msgstr "" + +#: ../../include/conversation.php:1328 +#: ../../extend/addon/hzaddons/hsse/hsse.php:82 +msgid "Set your location" +msgstr "" + +#: ../../include/conversation.php:1329 +#: ../../extend/addon/hzaddons/hsse/hsse.php:83 +msgid "Clear browser location" +msgstr "" + +#: ../../include/conversation.php:1345 +#: ../../extend/addon/hzaddons/hsse/hsse.php:99 +msgid "Embed (existing) photo from your photo albums" +msgstr "" + +#: ../../include/conversation.php:1381 +#: ../../extend/addon/hzaddons/hsse/hsse.php:135 +msgid "Tag term:" +msgstr "" + +#: ../../include/conversation.php:1382 +#: ../../extend/addon/hzaddons/hsse/hsse.php:136 +msgid "Where are you right now?" +msgstr "" + +#: ../../include/conversation.php:1387 +#: ../../extend/addon/hzaddons/hsse/hsse.php:141 +msgid "Choose a different album..." +msgstr "" + +#: ../../include/conversation.php:1391 +#: ../../extend/addon/hzaddons/hsse/hsse.php:145 +msgid "Comments enabled" +msgstr "" + +#: ../../include/conversation.php:1392 +#: ../../extend/addon/hzaddons/hsse/hsse.php:146 +msgid "Comments disabled" +msgstr "" + +#: ../../include/conversation.php:1444 +#: ../../extend/addon/hzaddons/hsse/hsse.php:195 +msgid "Page link name" +msgstr "" + +#: ../../include/conversation.php:1447 +#: ../../extend/addon/hzaddons/hsse/hsse.php:198 +msgid "Post as" +msgstr "" + +#: ../../include/conversation.php:1461 +#: ../../extend/addon/hzaddons/hsse/hsse.php:212 +msgid "Toggle voting" +msgstr "" + +#: ../../include/conversation.php:1462 +msgid "Toggle poll" +msgstr "" + +#: ../../include/conversation.php:1463 +msgid "Option" +msgstr "" + +#: ../../include/conversation.php:1464 +msgid "Add option" +msgstr "" + +#: ../../include/conversation.php:1465 +msgid "Minutes" +msgstr "" + +#: ../../include/conversation.php:1465 +msgid "Hours" +msgstr "" + +#: ../../include/conversation.php:1465 +msgid "Days" +msgstr "" + +#: ../../include/conversation.php:1466 +msgid "Allow multiple answers" +msgstr "" + +#: ../../include/conversation.php:1468 +#: ../../extend/addon/hzaddons/hsse/hsse.php:215 +msgid "Disable comments" +msgstr "" + +#: ../../include/conversation.php:1469 +#: ../../extend/addon/hzaddons/hsse/hsse.php:216 +msgid "Toggle comments" +msgstr "" + +#: ../../include/conversation.php:1477 +#: ../../extend/addon/hzaddons/hsse/hsse.php:224 +msgid "Categories (optional, comma-separated list)" +msgstr "" + +#: ../../include/conversation.php:1500 +#: ../../extend/addon/hzaddons/hsse/hsse.php:247 +msgid "Other networks and post services" +msgstr "" + +#: ../../include/conversation.php:1503 +#: ../../extend/addon/hzaddons/hsse/hsse.php:250 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:170 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:313 +msgid "Set expiration date" +msgstr "" + +#: ../../include/conversation.php:1506 +#: ../../extend/addon/hzaddons/hsse/hsse.php:253 +msgid "Set publish date" +msgstr "" + +#: ../../include/conversation.php:1755 +msgctxt "noun" +msgid "Attending" +msgid_plural "Attending" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1758 +msgctxt "noun" +msgid "Not Attending" +msgid_plural "Not Attending" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1761 +msgctxt "noun" +msgid "Undecided" +msgid_plural "Undecided" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1764 +msgctxt "noun" +msgid "Agree" +msgid_plural "Agrees" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1767 +msgctxt "noun" +msgid "Disagree" +msgid_plural "Disagrees" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/conversation.php:1770 +msgctxt "noun" +msgid "Abstain" +msgid_plural "Abstains" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/channel.php:46 +msgid "Unable to obtain identity information from database" +msgstr "" + +#: ../../include/channel.php:79 +msgid "Empty name" +msgstr "" + +#: ../../include/channel.php:82 +msgid "Name too long" +msgstr "" + +#: ../../include/channel.php:199 +msgid "No account identifier" +msgstr "" + +#: ../../include/channel.php:211 +msgid "Nickname is required." +msgstr "" + +#: ../../include/channel.php:294 +msgid "Unable to retrieve created identity" +msgstr "" + +#: ../../include/channel.php:441 +msgid "Default Profile" +msgstr "" + +#: ../../include/channel.php:639 ../../include/channel.php:728 +msgid "Unable to retrieve modified identity" +msgstr "" + +#: ../../include/channel.php:1385 +msgid "Requested channel is not available." +msgstr "" + +#: ../../include/channel.php:1539 +msgid "Create New Profile" +msgstr "" + +#: ../../include/channel.php:1542 ../../include/nav.php:117 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:58 +msgid "Edit Profile" +msgstr "" + +#: ../../include/channel.php:1560 +msgid "Visible to everybody" +msgstr "" + +#: ../../include/channel.php:1637 ../../include/channel.php:1765 +msgid "Gender:" +msgstr "" + +#: ../../include/channel.php:1638 ../../include/channel.php:1809 +msgid "Status:" +msgstr "" + +#: ../../include/channel.php:1639 ../../include/channel.php:1833 +msgid "Homepage:" +msgstr "" + +#: ../../include/channel.php:1640 +msgid "Online Now" +msgstr "" + +#: ../../include/channel.php:1693 +msgid "Change your profile photo" +msgstr "" + +#: ../../include/channel.php:1720 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:87 +msgid "Female" +msgstr "" + +#: ../../include/channel.php:1722 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 +#: ../../extend/addon/hzaddons/openid/Mod_Id.php:85 +msgid "Male" +msgstr "" + +#: ../../include/channel.php:1724 +msgid "Trans" +msgstr "" + +#: ../../include/channel.php:1726 ../../include/selectors.php:60 +msgid "Neuter" +msgstr "" + +#: ../../include/channel.php:1728 ../../include/selectors.php:60 +msgid "Non-specific" +msgstr "" + +#: ../../include/channel.php:1770 +msgid "Like this channel" +msgstr "" + +#: ../../include/channel.php:1794 +msgid "j F, Y" +msgstr "" + +#: ../../include/channel.php:1795 +msgid "j F" +msgstr "" + +#: ../../include/channel.php:1802 +msgid "Birthday:" +msgstr "" + +#: ../../include/channel.php:1815 +#, php-format +msgid "for %1$d %2$s" +msgstr "" + +#: ../../include/channel.php:1827 +msgid "Tags:" +msgstr "" + +#: ../../include/channel.php:1831 +msgid "Sexual Preference:" +msgstr "" + +#: ../../include/channel.php:1837 +msgid "Political Views:" +msgstr "" + +#: ../../include/channel.php:1839 +msgid "Religion:" +msgstr "" + +#: ../../include/channel.php:1843 +msgid "Hobbies/Interests:" +msgstr "" + +#: ../../include/channel.php:1845 +msgid "Likes:" +msgstr "" + +#: ../../include/channel.php:1847 +msgid "Dislikes:" +msgstr "" + +#: ../../include/channel.php:1849 +msgid "Contact information and Social Networks:" +msgstr "" + +#: ../../include/channel.php:1851 +msgid "My other channels:" +msgstr "" + +#: ../../include/channel.php:1853 +msgid "Musical interests:" +msgstr "" + +#: ../../include/channel.php:1855 +msgid "Books, literature:" +msgstr "" + +#: ../../include/channel.php:1857 +msgid "Television:" +msgstr "" + +#: ../../include/channel.php:1859 +msgid "Film/dance/culture/entertainment:" +msgstr "" + +#: ../../include/channel.php:1861 +msgid "Love/Romance:" +msgstr "" + +#: ../../include/channel.php:1863 +msgid "Work/employment:" +msgstr "" + +#: ../../include/channel.php:1865 +msgid "School/education:" +msgstr "" + +#: ../../include/channel.php:1888 +msgid "Like this thing" +msgstr "" + +#: ../../include/features.php:86 +msgid "Start calendar week on Monday" +msgstr "" + +#: ../../include/features.php:87 +msgid "Default is Sunday" +msgstr "" + +#: ../../include/features.php:94 +msgid "Event Timezone Selection" +msgstr "" + +#: ../../include/features.php:95 +msgid "Allow event creation in timezones other than your own." +msgstr "" + +#: ../../include/features.php:108 +msgid "Search by Date" +msgstr "" + +#: ../../include/features.php:109 +msgid "Ability to select posts by date ranges" +msgstr "" + +#: ../../include/features.php:116 +msgid "Tag Cloud" +msgstr "" + +#: ../../include/features.php:117 +msgid "Provide a personal tag cloud on your channel page" +msgstr "" + +#: ../../include/features.php:124 ../../include/features.php:359 +msgid "Use blog/list mode" +msgstr "" + +#: ../../include/features.php:125 ../../include/features.php:360 +msgid "Comments will be displayed separately" +msgstr "" + +#: ../../include/features.php:137 +msgid "Connection Filtering" +msgstr "" + +#: ../../include/features.php:138 +msgid "Filter incoming posts from connections based on keywords/content" +msgstr "" + +#: ../../include/features.php:146 +msgid "Conversation" +msgstr "" + +#: ../../include/features.php:158 +msgid "Emoji Reactions" +msgstr "" + +#: ../../include/features.php:159 +msgid "Add emoji reaction ability to posts" +msgstr "" + +#: ../../include/features.php:166 +msgid "Dislike Posts" +msgstr "" + +#: ../../include/features.php:167 +msgid "Ability to dislike posts/comments" +msgstr "" + +#: ../../include/features.php:174 +msgid "Star Posts" +msgstr "" + +#: ../../include/features.php:175 +msgid "Ability to mark special posts with a star indicator" +msgstr "" + +#: ../../include/features.php:182 +msgid "Reply on comment" +msgstr "" + +#: ../../include/features.php:183 +msgid "Ability to reply on selected comment" +msgstr "" + +#: ../../include/features.php:196 +msgid "Advanced Directory Search" +msgstr "" + +#: ../../include/features.php:197 +msgid "Allows creation of complex directory search queries" +msgstr "" + +#: ../../include/features.php:206 +msgid "Editor" +msgstr "" + +#: ../../include/features.php:210 +msgid "Post Categories" +msgstr "" + +#: ../../include/features.php:211 +msgid "Add categories to your posts" +msgstr "" + +#: ../../include/features.php:219 +msgid "Large Photos" +msgstr "" + +#: ../../include/features.php:220 +msgid "" +"Include large (1024px) photo thumbnails in posts. If not enabled, use small " +"(640px) photo thumbnails" +msgstr "" + +#: ../../include/features.php:227 +msgid "Even More Encryption" +msgstr "" + +#: ../../include/features.php:228 +msgid "" +"Allow optional encryption of content end-to-end with a shared secret key" +msgstr "" + +#: ../../include/features.php:235 +msgid "Disable Comments" +msgstr "" + +#: ../../include/features.php:236 +msgid "Provide the option to disable comments for a post" +msgstr "" + +#: ../../include/features.php:243 +msgid "Delayed Posting" +msgstr "" + +#: ../../include/features.php:244 +msgid "Allow posts to be published at a later date" +msgstr "" + +#: ../../include/features.php:251 +msgid "Content Expiration" +msgstr "" + +#: ../../include/features.php:252 +msgid "Remove posts/comments and/or private messages at a future time" +msgstr "" + +#: ../../include/features.php:259 +msgid "Suppress Duplicate Posts/Comments" +msgstr "" + +#: ../../include/features.php:260 +msgid "" +"Prevent posts with identical content to be published with less than two " +"minutes in between submissions." +msgstr "" + +#: ../../include/features.php:267 +msgid "Auto-save drafts of posts and comments" +msgstr "" + +#: ../../include/features.php:268 +msgid "" +"Automatically saves post and comment drafts in local browser storage to help " +"prevent accidental loss of compositions" +msgstr "" + +#: ../../include/features.php:277 +msgid "Manage" +msgstr "" + +#: ../../include/features.php:281 +msgid "Navigation Channel Select" +msgstr "" + +#: ../../include/features.php:282 +msgid "Change channels directly from within the navigation dropdown menu" +msgstr "" + +#: ../../include/features.php:295 +msgid "Events Filter" +msgstr "" + +#: ../../include/features.php:296 +msgid "Ability to display only events" +msgstr "" + +#: ../../include/features.php:303 +msgid "Polls Filter" +msgstr "" + +#: ../../include/features.php:304 +msgid "Ability to display only polls" +msgstr "" + +#: ../../include/features.php:312 +msgid "Save search terms for re-use" +msgstr "" + +#: ../../include/features.php:320 +msgid "Ability to file posts under folders" +msgstr "" + +#: ../../include/features.php:327 +msgid "Alternate Stream Order" +msgstr "" + +#: ../../include/features.php:328 +msgid "" +"Ability to order the stream by last post date, last comment date or " +"unthreaded activities" +msgstr "" + +#: ../../include/features.php:335 +msgid "Contact Filter" +msgstr "" + +#: ../../include/features.php:336 +msgid "Ability to display only posts of a selected contact" +msgstr "" + +#: ../../include/features.php:343 +msgid "Forum Filter" +msgstr "" + +#: ../../include/features.php:344 +msgid "Ability to display only posts of a specific forum" +msgstr "" + +#: ../../include/features.php:351 +msgid "Personal Posts Filter" +msgstr "" + +#: ../../include/features.php:352 +msgid "Ability to display only posts that you've interacted on" +msgstr "" + +#: ../../include/features.php:373 +msgid "Photo Location" +msgstr "" + +#: ../../include/features.php:374 +msgid "If location data is available on uploaded photos, link this to a map." +msgstr "" + +#: ../../include/features.php:387 +msgid "Advanced Profiles" +msgstr "" + +#: ../../include/features.php:388 +msgid "Additional profile sections and selections" +msgstr "" + +#: ../../include/features.php:395 +msgid "Profile Import/Export" +msgstr "" + +#: ../../include/features.php:396 +msgid "Save and load profile details across sites/channels" +msgstr "" + +#: ../../include/features.php:403 +msgid "Multiple Profiles" +msgstr "" + +#: ../../include/features.php:404 +msgid "Ability to create multiple profiles" +msgstr "" + +#: ../../include/auth.php:194 +msgid "Delegation session ended." +msgstr "" + +#: ../../include/auth.php:198 +msgid "Logged out." +msgstr "" + +#: ../../include/auth.php:294 +msgid "Email validation is incomplete. Please check your email." +msgstr "" + +#: ../../include/auth.php:310 +msgid "Failed authentication" +msgstr "" + +#: ../../include/auth.php:320 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:188 +msgid "Login failed." +msgstr "" + +#: ../../include/text.php:522 +msgid "prev" +msgstr "" + +#: ../../include/text.php:524 +msgid "first" +msgstr "" + +#: ../../include/text.php:553 +msgid "last" +msgstr "" + +#: ../../include/text.php:556 +msgid "next" +msgstr "" + +#: ../../include/text.php:574 +msgid "older" +msgstr "" + +#: ../../include/text.php:576 +msgid "newer" +msgstr "" + +#: ../../include/text.php:1024 +msgid "No connections" +msgstr "" + +#: ../../include/text.php:1076 +#, php-format +msgid "View all %s connections" +msgstr "" + +#: ../../include/text.php:1139 +#, php-format +msgid "Network: %s" +msgstr "" + +#: ../../include/text.php:1242 ../../include/text.php:1246 +msgid "poke" +msgstr "" + +#: ../../include/text.php:1247 +msgid "ping" +msgstr "" + +#: ../../include/text.php:1247 +msgid "pinged" +msgstr "" + +#: ../../include/text.php:1248 +msgid "prod" +msgstr "" + +#: ../../include/text.php:1248 +msgid "prodded" +msgstr "" + +#: ../../include/text.php:1249 +msgid "slap" +msgstr "" + +#: ../../include/text.php:1249 +msgid "slapped" +msgstr "" + +#: ../../include/text.php:1250 +msgid "finger" +msgstr "" + +#: ../../include/text.php:1250 +msgid "fingered" +msgstr "" + +#: ../../include/text.php:1251 +msgid "rebuff" +msgstr "" + +#: ../../include/text.php:1251 +msgid "rebuffed" +msgstr "" + +#: ../../include/text.php:1274 +msgid "happy" +msgstr "" + +#: ../../include/text.php:1275 +msgid "sad" +msgstr "" + +#: ../../include/text.php:1276 +msgid "mellow" +msgstr "" + +#: ../../include/text.php:1277 +msgid "tired" +msgstr "" + +#: ../../include/text.php:1278 +msgid "perky" +msgstr "" + +#: ../../include/text.php:1279 +msgid "angry" +msgstr "" + +#: ../../include/text.php:1280 +msgid "stupefied" +msgstr "" + +#: ../../include/text.php:1281 +msgid "puzzled" +msgstr "" + +#: ../../include/text.php:1282 +msgid "interested" +msgstr "" + +#: ../../include/text.php:1283 +msgid "bitter" +msgstr "" + +#: ../../include/text.php:1284 +msgid "cheerful" +msgstr "" + +#: ../../include/text.php:1285 +msgid "alive" +msgstr "" + +#: ../../include/text.php:1286 +msgid "annoyed" +msgstr "" + +#: ../../include/text.php:1287 +msgid "anxious" +msgstr "" + +#: ../../include/text.php:1288 +msgid "cranky" +msgstr "" + +#: ../../include/text.php:1289 +msgid "disturbed" +msgstr "" + +#: ../../include/text.php:1290 +msgid "frustrated" +msgstr "" + +#: ../../include/text.php:1291 +msgid "depressed" +msgstr "" + +#: ../../include/text.php:1292 +msgid "motivated" +msgstr "" + +#: ../../include/text.php:1293 +msgid "relaxed" +msgstr "" + +#: ../../include/text.php:1294 +msgid "surprised" +msgstr "" + +#: ../../include/text.php:1482 ../../include/js_strings.php:99 +msgid "Monday" +msgstr "" + +#: ../../include/text.php:1482 ../../include/js_strings.php:100 +msgid "Tuesday" +msgstr "" + +#: ../../include/text.php:1482 ../../include/js_strings.php:101 +msgid "Wednesday" +msgstr "" + +#: ../../include/text.php:1482 ../../include/js_strings.php:102 +msgid "Thursday" +msgstr "" + +#: ../../include/text.php:1482 ../../include/js_strings.php:103 +msgid "Friday" +msgstr "" + +#: ../../include/text.php:1482 ../../include/js_strings.php:104 +msgid "Saturday" +msgstr "" + +#: ../../include/text.php:1482 ../../include/js_strings.php:98 +msgid "Sunday" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:74 +msgid "January" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:75 +msgid "February" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:76 +msgid "March" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:77 +msgid "April" +msgstr "" + +#: ../../include/text.php:1486 +msgid "May" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:79 +msgid "June" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:80 +msgid "July" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:81 +msgid "August" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:82 +msgid "September" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:83 +msgid "October" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:84 +msgid "November" +msgstr "" + +#: ../../include/text.php:1486 ../../include/js_strings.php:85 +msgid "December" +msgstr "" + +#: ../../include/text.php:1560 +msgid "Unknown Attachment" +msgstr "" + +#: ../../include/text.php:1562 ../../include/feedutils.php:873 +msgid "unknown" +msgstr "" + +#: ../../include/text.php:1598 +msgid "remove category" +msgstr "" + +#: ../../include/text.php:1674 +msgid "remove from file" +msgstr "" + +#: ../../include/text.php:1843 ../../include/message.php:13 +msgid "Download binary/encrypted content" +msgstr "" + +#: ../../include/text.php:1914 +msgid "Poll has ended." +msgstr "" + +#: ../../include/text.php:1917 +#, php-format +msgid "Poll ends: %s" +msgstr "" + +#: ../../include/text.php:2096 ../../include/language.php:424 +msgid "default" +msgstr "" + +#: ../../include/text.php:2104 +msgid "Page layout" +msgstr "" + +#: ../../include/text.php:2104 +msgid "You can create your own with the layouts tool" +msgstr "" + +#: ../../include/text.php:2115 +msgid "HTML" +msgstr "" + +#: ../../include/text.php:2118 +msgid "Comanche Layout" +msgstr "" + +#: ../../include/text.php:2123 +msgid "PHP" +msgstr "" + +#: ../../include/text.php:2132 +msgid "Page content type" +msgstr "" + +#: ../../include/text.php:2265 +msgid "activity" +msgstr "" + +#: ../../include/text.php:2268 +msgid "poll" +msgstr "" + +#: ../../include/text.php:2369 +msgid "a-z, 0-9, -, and _ only" +msgstr "" + +#: ../../include/text.php:2695 +msgid "Design Tools" +msgstr "" + +#: ../../include/text.php:2701 +msgid "Pages" +msgstr "" + +#: ../../include/text.php:2713 +msgid "Import" +msgstr "" + +#: ../../include/text.php:2714 +msgid "Import website..." +msgstr "" + +#: ../../include/text.php:2715 +msgid "Select folder to import" +msgstr "" + +#: ../../include/text.php:2716 +msgid "Import from a zipped folder:" +msgstr "" + +#: ../../include/text.php:2717 +msgid "Import from cloud files:" +msgstr "" + +#: ../../include/text.php:2718 +msgid "/cloud/channel/path/to/folder" +msgstr "" + +#: ../../include/text.php:2719 +msgid "Enter path to website files" +msgstr "" + +#: ../../include/text.php:2720 +msgid "Select folder" +msgstr "" + +#: ../../include/text.php:2721 +msgid "Export website..." +msgstr "" + +#: ../../include/text.php:2722 +msgid "Export to a zip file" +msgstr "" + +#: ../../include/text.php:2723 +msgid "website.zip" +msgstr "" + +#: ../../include/text.php:2724 +msgid "Enter a name for the zip file." +msgstr "" + +#: ../../include/text.php:2725 +msgid "Export to cloud files" +msgstr "" + +#: ../../include/text.php:2726 +msgid "/path/to/export/folder" +msgstr "" + +#: ../../include/text.php:2727 +msgid "Enter a path to a cloud files destination." +msgstr "" + +#: ../../include/text.php:2728 +msgid "Specify folder" +msgstr "" + +#: ../../include/message.php:41 +msgid "Unable to determine sender." +msgstr "" + +#: ../../include/message.php:80 +msgid "No recipient provided." +msgstr "" + +#: ../../include/message.php:85 +msgid "[no subject]" +msgstr "" + +#: ../../include/message.php:214 +msgid "Stored post could not be verified." +msgstr "" + +#: ../../include/markdown.php:202 ../../include/bbcode.php:527 +#, php-format +msgid "%1$s wrote the following %2$s %3$s" +msgstr "" + +#: ../../include/markdown.php:251 ../../include/bbcode.php:612 +msgid "spoiler" +msgstr "" + +#: ../../include/acl_selectors.php:99 +msgid "Profile-Based Privacy Groups" +msgstr "" + +#: ../../include/acl_selectors.php:118 +msgid "Private Forum" +msgstr "" + +#: ../../include/acl_selectors.php:142 +msgid "Share with" +msgstr "" + +#: ../../include/acl_selectors.php:143 +msgid "Custom selection" +msgstr "" + +#: ../../include/acl_selectors.php:145 +msgid "" +"Select \"Allow\" to allow viewing. \"Don't allow\" lets you override and " +"limit the scope of \"Allow\"." +msgstr "" + +#: ../../include/acl_selectors.php:147 +msgid "Don't allow" +msgstr "" + +#: ../../include/acl_selectors.php:180 +#, php-format +msgid "" +"Post permissions %s cannot be changed %s after a post is shared.
      These " +"permissions set who is allowed to view the post." +msgstr "" + +#: ../../include/opengraph.php:56 +#, php-format +msgid "This is the home page of %s." +msgstr "" + +#: ../../include/taxonomy.php:323 +msgid "Trending" +msgstr "" + +#: ../../include/taxonomy.php:559 +msgid "Keywords" +msgstr "" + +#: ../../include/taxonomy.php:580 +msgid "have" +msgstr "" + +#: ../../include/taxonomy.php:580 +msgid "has" +msgstr "" + +#: ../../include/taxonomy.php:581 +msgid "want" +msgstr "" + +#: ../../include/taxonomy.php:581 +msgid "wants" +msgstr "" + +#: ../../include/taxonomy.php:582 +msgid "likes" +msgstr "" + +#: ../../include/taxonomy.php:583 +msgid "dislikes" +msgstr "" + +#: ../../include/import.php:29 +msgid "Unable to import a removed channel." +msgstr "" + +#: ../../include/import.php:55 +msgid "" +"Cannot create a duplicate channel identifier on this system. Import failed." +msgstr "" + +#: ../../include/import.php:76 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:44 +msgid "Unable to create a unique channel address. Import failed." +msgstr "" + +#: ../../include/import.php:121 +msgid "Cloned channel not found. Import failed." +msgstr "" + +#: ../../include/nav.php:92 +msgid "Remote authentication" +msgstr "" + +#: ../../include/nav.php:92 +msgid "Click to authenticate to your home hub" +msgstr "" + +#: ../../include/nav.php:98 +msgid "Manage your channels" +msgstr "" + +#: ../../include/nav.php:101 +msgid "Manage your privacy groups" +msgstr "" + +#: ../../include/nav.php:103 +msgid "Account/Channel Settings" +msgstr "" + +#: ../../include/nav.php:109 ../../include/nav.php:138 +#: ../../include/nav.php:157 ../../boot.php:1704 +msgid "Logout" +msgstr "" + +#: ../../include/nav.php:109 ../../include/nav.php:138 +msgid "End this session" +msgstr "" + +#: ../../include/nav.php:112 +msgid "Your profile page" +msgstr "" + +#: ../../include/nav.php:115 +msgid "Manage/Edit profiles" +msgstr "" + +#: ../../include/nav.php:124 ../../include/nav.php:128 +msgid "Sign in" +msgstr "" + +#: ../../include/nav.php:155 +msgid "Take me home" +msgstr "" + +#: ../../include/nav.php:157 +msgid "Log me out of this site" +msgstr "" + +#: ../../include/nav.php:162 +msgid "Create an account" +msgstr "" + +#: ../../include/nav.php:174 +msgid "Help and documentation" +msgstr "" + +#: ../../include/nav.php:188 +msgid "Search site @name, !forum, #tag, ?docs, content" +msgstr "" + +#: ../../include/nav.php:194 +msgid "Site Setup and Configuration" +msgstr "" + +#: ../../include/nav.php:330 +msgid "@name, !forum, #tag, ?doc, content" +msgstr "" + +#: ../../include/nav.php:331 +msgid "Please wait..." +msgstr "" + +#: ../../include/nav.php:337 +msgid "Add Apps" +msgstr "" + +#: ../../include/nav.php:338 +msgid "Arrange Apps" +msgstr "" + +#: ../../include/nav.php:339 +msgid "Toggle System Apps" +msgstr "" + +#: ../../include/nav.php:424 +msgid "Status Messages and Posts" +msgstr "" + +#: ../../include/nav.php:437 +msgid "Profile Details" +msgstr "" + +#: ../../include/nav.php:447 ../../include/photos.php:666 +msgid "Photo Albums" +msgstr "" + +#: ../../include/nav.php:455 +msgid "Files and Storage" +msgstr "" + +#: ../../include/nav.php:493 +msgid "Saved Bookmarks" +msgstr "" + +#: ../../include/nav.php:504 +msgid "View Cards" +msgstr "" + +#: ../../include/nav.php:515 +msgid "View Articles" +msgstr "" + +#: ../../include/nav.php:527 +msgid "View Webpages" +msgstr "" + +#: ../../include/language.php:437 +msgid "Select an alternate language" +msgstr "" + +#: ../../include/zid.php:360 +#, php-format +msgid "OpenWebAuth: %1$s welcomes %2$s" +msgstr "" + +#: ../../include/bookmarks.php:34 +#, php-format +msgid "%1$s's bookmarks" +msgstr "" + +#: ../../include/activities.php:42 +msgid " and " +msgstr "" + +#: ../../include/activities.php:50 +msgid "public profile" +msgstr "" + +#: ../../include/activities.php:59 +#, php-format +msgid "%1$s changed %2$s to “%3$s”" +msgstr "" + +#: ../../include/activities.php:60 +#, php-format +msgid "Visit %1$s's %2$s" +msgstr "" + +#: ../../include/activities.php:63 +#, php-format +msgid "%1$s has an updated %2$s, changing %3$s." +msgstr "" + +#: ../../include/cdav.php:157 +msgid "INVALID EVENT DISMISSED!" +msgstr "" + +#: ../../include/cdav.php:158 +msgid "Summary: " +msgstr "" + +#: ../../include/cdav.php:159 +msgid "Date: " +msgstr "" + +#: ../../include/cdav.php:160 ../../include/cdav.php:168 +msgid "Reason: " +msgstr "" + +#: ../../include/cdav.php:166 +msgid "INVALID CARD DISMISSED!" +msgstr "" + +#: ../../include/cdav.php:167 +msgid "Name: " +msgstr "" + +#: ../../include/photos.php:151 +#, php-format +msgid "Image exceeds website size limit of %lu bytes" +msgstr "" + +#: ../../include/photos.php:162 +msgid "Image file is empty." +msgstr "" + +#: ../../include/photos.php:324 +msgid "Photo storage failed." +msgstr "" + +#: ../../include/photos.php:373 +msgid "a new photo" +msgstr "" + +#: ../../include/photos.php:377 +#, php-format +msgctxt "photo_upload" +msgid "%1$s posted %2$s to %3$s" +msgstr "" + +#: ../../include/photos.php:671 +msgid "Upload New Photos" +msgstr "" + +#: ../../include/js_strings.php:5 +msgid "Delete this item?" +msgstr "" + +#: ../../include/js_strings.php:8 +#, php-format +msgid "%s show less" +msgstr "" + +#: ../../include/js_strings.php:9 +#, php-format +msgid "%s expand" +msgstr "" + +#: ../../include/js_strings.php:10 +#, php-format +msgid "%s collapse" +msgstr "" + +#: ../../include/js_strings.php:11 +msgid "Password too short" +msgstr "" + +#: ../../include/js_strings.php:12 +msgid "Passwords do not match" +msgstr "" + +#: ../../include/js_strings.php:13 +msgid "everybody" +msgstr "" + +#: ../../include/js_strings.php:14 +msgid "Secret Passphrase" +msgstr "" + +#: ../../include/js_strings.php:15 +msgid "Passphrase hint" +msgstr "" + +#: ../../include/js_strings.php:16 +msgid "Notice: Permissions have changed but have not yet been submitted." +msgstr "" + +#: ../../include/js_strings.php:17 +msgid "close all" +msgstr "" + +#: ../../include/js_strings.php:18 +msgid "Nothing new here" +msgstr "" + +#: ../../include/js_strings.php:19 +msgid "Rate This Channel (this is public)" +msgstr "" + +#: ../../include/js_strings.php:21 +msgid "Describe (optional)" +msgstr "" + +#: ../../include/js_strings.php:23 +msgid "Please enter a link URL" +msgstr "" + +#: ../../include/js_strings.php:24 +msgid "Unsaved changes. Are you sure you wish to leave this page?" +msgstr "" + +#: ../../include/js_strings.php:26 +msgid "lovely" +msgstr "" + +#: ../../include/js_strings.php:27 +msgid "wonderful" +msgstr "" + +#: ../../include/js_strings.php:28 +msgid "fantastic" +msgstr "" + +#: ../../include/js_strings.php:29 +msgid "great" +msgstr "" + +#: ../../include/js_strings.php:30 +msgid "" +"Your chosen nickname was either already taken or not valid. Please use our " +"suggestion (" +msgstr "" + +#: ../../include/js_strings.php:31 +msgid ") or enter a new one." +msgstr "" + +#: ../../include/js_strings.php:32 +msgid "Thank you, this nickname is valid." +msgstr "" + +#: ../../include/js_strings.php:33 +msgid "A channel name is required." +msgstr "" + +#: ../../include/js_strings.php:34 +msgid "This is a " +msgstr "" + +#: ../../include/js_strings.php:35 +msgid " channel name" +msgstr "" + +#: ../../include/js_strings.php:36 +msgid "Back to reply" +msgstr "" + +#: ../../include/js_strings.php:37 +msgid "Pinned" +msgstr "" + +#: ../../include/js_strings.php:45 +#, php-format +msgid "%d minutes" +msgid_plural "%d minutes" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:46 +#, php-format +msgid "about %d hours" +msgid_plural "about %d hours" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:47 +#, php-format +msgid "%d days" +msgid_plural "%d days" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:48 +#, php-format +msgid "%d months" +msgid_plural "%d months" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:49 +#, php-format +msgid "%d years" +msgid_plural "%d years" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/js_strings.php:54 +msgid "timeago.prefixAgo" +msgstr "" + +#: ../../include/js_strings.php:55 +msgid "timeago.prefixFromNow" +msgstr "" + +#: ../../include/js_strings.php:56 +msgid "timeago.suffixAgo" +msgstr "" + +#: ../../include/js_strings.php:57 +msgid "timeago.suffixFromNow" +msgstr "" + +#: ../../include/js_strings.php:60 +msgid "less than a minute" +msgstr "" + +#: ../../include/js_strings.php:61 +msgid "about a minute" +msgstr "" + +#: ../../include/js_strings.php:63 +msgid "about an hour" +msgstr "" + +#: ../../include/js_strings.php:65 +msgid "a day" +msgstr "" + +#: ../../include/js_strings.php:67 +msgid "about a month" +msgstr "" + +#: ../../include/js_strings.php:69 +msgid "about a year" +msgstr "" + +#: ../../include/js_strings.php:71 +msgid " " +msgstr "" + +#: ../../include/js_strings.php:72 +msgid "timeago.numbers" +msgstr "" + +#: ../../include/js_strings.php:78 +msgctxt "long" +msgid "May" +msgstr "" + +#: ../../include/js_strings.php:86 +msgid "Jan" +msgstr "" + +#: ../../include/js_strings.php:87 +msgid "Feb" +msgstr "" + +#: ../../include/js_strings.php:88 +msgid "Mar" +msgstr "" + +#: ../../include/js_strings.php:89 +msgid "Apr" +msgstr "" + +#: ../../include/js_strings.php:90 +msgctxt "short" +msgid "May" +msgstr "" + +#: ../../include/js_strings.php:91 +msgid "Jun" +msgstr "" + +#: ../../include/js_strings.php:92 +msgid "Jul" +msgstr "" + +#: ../../include/js_strings.php:93 +msgid "Aug" +msgstr "" + +#: ../../include/js_strings.php:94 +msgid "Sep" +msgstr "" + +#: ../../include/js_strings.php:95 +msgid "Oct" +msgstr "" + +#: ../../include/js_strings.php:96 +msgid "Nov" +msgstr "" + +#: ../../include/js_strings.php:97 +msgid "Dec" +msgstr "" + +#: ../../include/js_strings.php:105 +msgid "Sun" +msgstr "" + +#: ../../include/js_strings.php:106 +msgid "Mon" +msgstr "" + +#: ../../include/js_strings.php:107 +msgid "Tue" +msgstr "" + +#: ../../include/js_strings.php:108 +msgid "Wed" +msgstr "" + +#: ../../include/js_strings.php:109 +msgid "Thu" +msgstr "" + +#: ../../include/js_strings.php:110 +msgid "Fri" +msgstr "" + +#: ../../include/js_strings.php:111 +msgid "Sat" +msgstr "" + +#: ../../include/js_strings.php:112 +msgctxt "calendar" +msgid "today" +msgstr "" + +#: ../../include/js_strings.php:113 +msgctxt "calendar" +msgid "month" +msgstr "" + +#: ../../include/js_strings.php:114 +msgctxt "calendar" +msgid "week" +msgstr "" + +#: ../../include/js_strings.php:115 +msgctxt "calendar" +msgid "day" +msgstr "" + +#: ../../include/js_strings.php:116 +msgctxt "calendar" +msgid "All day" +msgstr "" + +#: ../../include/js_strings.php:119 +msgid "Please stand by while your download is being prepared." +msgstr "" + +#: ../../include/security.php:609 +msgid "" +"The form security token was not correct. This probably happened because the " +"form has been opened for too long (>3 hours) before submitting it." +msgstr "" + +#: ../../include/selectors.php:18 +msgid "Profile to assign new connections" +msgstr "" + +#: ../../include/selectors.php:41 +msgid "Frequently" +msgstr "" + +#: ../../include/selectors.php:42 +msgid "Hourly" +msgstr "" + +#: ../../include/selectors.php:43 +msgid "Twice daily" +msgstr "" + +#: ../../include/selectors.php:44 +msgid "Daily" +msgstr "" + +#: ../../include/selectors.php:45 +msgid "Weekly" +msgstr "" + +#: ../../include/selectors.php:46 +msgid "Monthly" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Currently Male" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Currently Female" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Mostly Male" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Mostly Female" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Transgender" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Intersex" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Transsexual" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Hermaphrodite" +msgstr "" + +#: ../../include/selectors.php:60 +msgid "Undecided" +msgstr "" + +#: ../../include/selectors.php:96 ../../include/selectors.php:115 +msgid "Males" +msgstr "" + +#: ../../include/selectors.php:96 ../../include/selectors.php:115 +msgid "Females" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Gay" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Lesbian" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "No Preference" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Bisexual" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Autosexual" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Abstinent" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Virgin" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Deviant" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Fetish" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Oodles" +msgstr "" + +#: ../../include/selectors.php:96 +msgid "Nonsexual" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Single" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Lonely" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Available" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Unavailable" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Has crush" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Infatuated" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Dating" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Unfaithful" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Sex Addict" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Friends/Benefits" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Casual" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Engaged" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Married" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Imaginarily married" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Partners" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Cohabiting" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Common law" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Happy" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Not looking" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Swinger" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Betrayed" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Separated" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Unstable" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Divorced" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Imaginarily divorced" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "Widowed" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Uncertain" +msgstr "" + +#: ../../include/selectors.php:134 ../../include/selectors.php:151 +msgid "It's complicated" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Don't care" +msgstr "" + +#: ../../include/selectors.php:134 +msgid "Ask me" +msgstr "" + +#: ../../include/network.php:1731 ../../include/network.php:1732 +msgid "Friendica" +msgstr "" + +#: ../../include/network.php:1733 +msgid "OStatus" +msgstr "" + +#: ../../include/network.php:1734 +msgid "GNU-Social" +msgstr "" + +#: ../../include/network.php:1735 +msgid "RSS/Atom" +msgstr "" + +#: ../../include/network.php:1738 +msgid "Diaspora" +msgstr "" + +#: ../../include/network.php:1739 +msgid "Facebook" +msgstr "" + +#: ../../include/network.php:1740 +msgid "Zot" +msgstr "" + +#: ../../include/network.php:1741 +msgid "LinkedIn" +msgstr "" + +#: ../../include/network.php:1742 +msgid "XMPP/IM" +msgstr "" + +#: ../../include/network.php:1743 +msgid "MySpace" +msgstr "" + +#: ../../include/account.php:36 +msgid "Not a valid email address" +msgstr "" + +#: ../../include/account.php:38 +msgid "Your email domain is not among those allowed on this site" +msgstr "" + +#: ../../include/account.php:44 +msgid "Your email address is already registered at this site." +msgstr "" + +#: ../../include/account.php:76 +msgid "An invitation is required." +msgstr "" + +#: ../../include/account.php:80 +msgid "Invitation could not be verified." +msgstr "" + +#: ../../include/account.php:156 +msgid "Please enter the required information." +msgstr "" + +#: ../../include/account.php:223 +msgid "Failed to store account information." +msgstr "" + +#: ../../include/account.php:311 +#, php-format +msgid "Registration confirmation for %s" +msgstr "" + +#: ../../include/account.php:380 +#, php-format +msgid "Registration request at %s" +msgstr "" + +#: ../../include/account.php:402 +msgid "your registration password" +msgstr "" + +#: ../../include/account.php:408 ../../include/account.php:471 +#, php-format +msgid "Registration details for %s" +msgstr "" + +#: ../../include/account.php:482 +msgid "Account approved." +msgstr "" + +#: ../../include/account.php:522 +#, php-format +msgid "Registration revoked for %s" +msgstr "" + +#: ../../include/account.php:805 ../../include/account.php:807 +msgid "Click here to upgrade." +msgstr "" + +#: ../../include/account.php:813 +msgid "This action exceeds the limits set by your subscription plan." +msgstr "" + +#: ../../include/account.php:818 +msgid "This action is not available under your subscription plan." +msgstr "" + +#: ../../include/help.php:80 +msgid "Help:" +msgstr "" + +#: ../../include/help.php:129 +msgid "Not Found" +msgstr "" + +#: ../../include/attach.php:273 ../../include/attach.php:324 +#: ../../include/attach.php:419 +msgid "Item was not found." +msgstr "" + +#: ../../include/attach.php:290 +msgid "Unknown error." +msgstr "" + +#: ../../include/attach.php:612 +msgid "No source file." +msgstr "" + +#: ../../include/attach.php:634 +msgid "Cannot locate file to replace" +msgstr "" + +#: ../../include/attach.php:653 +msgid "Cannot locate file to revise/update" +msgstr "" + +#: ../../include/attach.php:795 +#, php-format +msgid "File exceeds size limit of %d" +msgstr "" + +#: ../../include/attach.php:816 +#, php-format +msgid "You have reached your limit of %1$.0f Mbytes attachment storage." +msgstr "" + +#: ../../include/attach.php:1004 +msgid "File upload failed. Possible system limit or action terminated." +msgstr "" + +#: ../../include/attach.php:1033 +msgid "Stored file could not be verified. Upload failed." +msgstr "" + +#: ../../include/attach.php:1105 ../../include/attach.php:1121 +msgid "Path not available." +msgstr "" + +#: ../../include/attach.php:1169 ../../include/attach.php:1332 +msgid "Empty pathname" +msgstr "" + +#: ../../include/attach.php:1195 +msgid "duplicate filename or path" +msgstr "" + +#: ../../include/attach.php:1220 +msgid "Path not found." +msgstr "" + +#: ../../include/attach.php:1288 +msgid "mkdir failed." +msgstr "" + +#: ../../include/attach.php:1292 +msgid "database storage failed." +msgstr "" + +#: ../../include/attach.php:1338 +msgid "Empty path" +msgstr "" + +#: ../../include/attach.php:2099 +#, php-format +msgid "%s shared a %s with you" +msgstr "" + +#: ../../include/attach.php:2099 +#: ../../extend/addon/hzaddons/redfiles/redfilehelper.php:64 +msgid "file" +msgstr "" + +#: ../../include/connections.php:134 +msgid "New window" +msgstr "" + +#: ../../include/connections.php:135 +msgid "Open the selected location in a different window or browser tab" +msgstr "" + +#: ../../include/connections.php:736 ../../include/event.php:1424 +msgid "Home, Voice" +msgstr "" + +#: ../../include/connections.php:737 ../../include/event.php:1425 +msgid "Home, Fax" +msgstr "" + +#: ../../include/connections.php:739 ../../include/event.php:1427 +msgid "Work, Voice" +msgstr "" + +#: ../../include/connections.php:740 ../../include/event.php:1428 +msgid "Work, Fax" +msgstr "" + +#: ../../include/oembed.php:153 +msgid "View PDF" +msgstr "" + +#: ../../include/oembed.php:357 +msgid " by " +msgstr "" + +#: ../../include/oembed.php:358 +msgid " on " +msgstr "" + +#: ../../include/oembed.php:387 +msgid "Embedded content" +msgstr "" + +#: ../../include/oembed.php:396 +msgid "Embedding disabled" +msgstr "" + +#: ../../include/event.php:33 ../../include/event.php:110 +msgid "l F d, Y \\@ g:i A" +msgstr "" + +#: ../../include/event.php:41 +msgid "Starts:" +msgstr "" + +#: ../../include/event.php:51 +msgid "Finishes:" +msgstr "" + +#: ../../include/event.php:110 +msgid "l F d, Y" +msgstr "" + +#: ../../include/event.php:114 +msgid "Start:" +msgstr "" + +#: ../../include/event.php:118 +msgid "End:" +msgstr "" + +#: ../../include/event.php:123 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:67 +msgid "Timezone" +msgstr "" + +#: ../../include/event.php:1106 +msgid "This event has been added to your calendar." +msgstr "" + +#: ../../include/event.php:1337 +msgid "Not specified" +msgstr "" + +#: ../../include/event.php:1338 +msgid "Needs Action" +msgstr "" + +#: ../../include/event.php:1339 +msgid "Completed" +msgstr "" + +#: ../../include/event.php:1340 +msgid "In Process" +msgstr "" + +#: ../../include/event.php:1341 +msgid "Cancelled" +msgstr "" + +#: ../../include/datetime.php:140 +msgid "Birthday" +msgstr "" + +#: ../../include/datetime.php:140 +msgid "Age: " +msgstr "" + +#: ../../include/datetime.php:140 +msgid "YYYY-MM-DD or MM-DD" +msgstr "" + +#: ../../include/datetime.php:238 ../../boot.php:2709 +msgid "never" +msgstr "" + +#: ../../include/datetime.php:244 +msgid "less than a second ago" +msgstr "" + +#: ../../include/datetime.php:262 +#, php-format +msgctxt "e.g. 22 hours ago, 1 minute ago" +msgid "%1$d %2$s ago" +msgstr "" + +#: ../../include/datetime.php:273 +msgctxt "relative_date" +msgid "year" +msgid_plural "years" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:276 +msgctxt "relative_date" +msgid "month" +msgid_plural "months" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:279 +msgctxt "relative_date" +msgid "week" +msgid_plural "weeks" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:282 +msgctxt "relative_date" +msgid "day" +msgid_plural "days" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:285 +msgctxt "relative_date" +msgid "hour" +msgid_plural "hours" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:288 +msgctxt "relative_date" +msgid "minute" +msgid_plural "minutes" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:291 +msgctxt "relative_date" +msgid "second" +msgid_plural "seconds" +msgstr[0] "" +msgstr[1] "" + +#: ../../include/datetime.php:520 +#, php-format +msgid "%1$s's birthday" +msgstr "" + +#: ../../include/datetime.php:521 +#, php-format +msgid "Happy Birthday %1$s" +msgstr "" + +#: ../../include/items.php:999 ../../include/items.php:1059 +msgid "(Unknown)" +msgstr "" + +#: ../../include/items.php:1247 +msgid "Visible to anybody on the internet." +msgstr "" + +#: ../../include/items.php:1249 +msgid "Visible to you only." +msgstr "" + +#: ../../include/items.php:1251 +msgid "Visible to anybody in this network." +msgstr "" + +#: ../../include/items.php:1253 +msgid "Visible to anybody authenticated." +msgstr "" + +#: ../../include/items.php:1255 +#, php-format +msgid "Visible to anybody on %s." +msgstr "" + +#: ../../include/items.php:1257 +msgid "Visible to all connections." +msgstr "" + +#: ../../include/items.php:1259 +msgid "Visible to approved connections." +msgstr "" + +#: ../../include/items.php:1261 +msgid "Visible to specific connections." +msgstr "" + +#: ../../include/items.php:4507 +msgid "Privacy group is empty." +msgstr "" + +#: ../../include/items.php:4514 +#, php-format +msgid "Privacy group: %s" +msgstr "" + +#: ../../include/items.php:4526 +msgid "Connection not found." +msgstr "" + +#: ../../include/items.php:4867 +msgid "profile photo" +msgstr "" + +#: ../../include/items.php:5059 +#, php-format +msgid "[Edited %s]" +msgstr "" + +#: ../../include/items.php:5059 +msgctxt "edit_activity" +msgid "Post" +msgstr "" + +#: ../../include/items.php:5059 +msgctxt "edit_activity" +msgid "Comment" +msgstr "" + +#: ../../include/follow.php:84 +msgid "Response from remote channel was incomplete." +msgstr "" + +#: ../../include/follow.php:96 +msgid "Premium channel - please visit:" +msgstr "" + +#: ../../include/follow.php:110 +msgid "Channel was deleted and no longer exists." +msgstr "" + +#: ../../include/zot.php:775 +msgid "Invalid data packet" +msgstr "" + +#: ../../include/zot.php:4372 +msgid "invalid target signature" +msgstr "" + +#: ../../include/bbcode.php:221 ../../include/bbcode.php:896 +#: ../../include/bbcode.php:1486 ../../include/bbcode.php:1494 +msgid "Image/photo" +msgstr "" + +#: ../../include/bbcode.php:268 ../../include/bbcode.php:1511 +msgid "Encrypted content" +msgstr "" + +#: ../../include/bbcode.php:302 +#, php-format +msgid "Install %1$s element %2$s" +msgstr "" + +#: ../../include/bbcode.php:306 +#, php-format +msgid "" +"This post contains an installable %s element, however you lack permissions " +"to install it on this site." +msgstr "" + +#: ../../include/bbcode.php:519 +msgid "card" +msgstr "" + +#: ../../include/bbcode.php:521 +msgid "article" +msgstr "" + +#: ../../include/bbcode.php:604 ../../include/bbcode.php:612 +msgid "Click to open/close" +msgstr "" + +#: ../../include/bbcode.php:625 +msgid "View article" +msgstr "" + +#: ../../include/bbcode.php:625 +msgid "View summary" +msgstr "" + +#: ../../include/bbcode.php:1474 +msgid "$1 wrote:" +msgstr "" + +#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:451 +msgid "Follow" +msgstr "" + +#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:454 +#, php-format +msgid "%1$s is now following %2$s" +msgstr "" + +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:16 +msgid "" +"The GNU-Social protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." +msgstr "" + +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22 +msgid "GNU-Social Protocol App" +msgstr "" + +#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:34 +msgid "GNU-Social Protocol" +msgstr "" + +#: ../../extend/addon/hzaddons/qrator/qrator.php:48 +msgid "QR code" +msgstr "" + +#: ../../extend/addon/hzaddons/qrator/qrator.php:63 +msgid "QR Generator" +msgstr "" + +#: ../../extend/addon/hzaddons/qrator/qrator.php:64 +msgid "Enter some text" +msgstr "" + +#: ../../extend/addon/hzaddons/irc/Mod_Irc.php:23 +#: ../../extend/addon/hzaddons/irc/irc.php:41 +msgid "Popular Channels" +msgstr "" + +#: ../../extend/addon/hzaddons/irc/irc.php:37 +msgid "Channels to auto connect" +msgstr "" + +#: ../../extend/addon/hzaddons/irc/irc.php:37 +#: ../../extend/addon/hzaddons/irc/irc.php:41 +msgid "Comma separated list" +msgstr "" + +#: ../../extend/addon/hzaddons/irc/irc.php:45 +msgid "IRC Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/irc/irc.php:54 +msgid "IRC settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/irc/irc.php:58 +msgid "IRC Chatroom" +msgstr "" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:19 +msgid "Send email to all members" +msgstr "" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:50 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:50 +msgid "No recipients found." +msgstr "" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:73 +#, php-format +msgid "%1$d of %2$d messages sent." +msgstr "" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:81 +msgid "Send email to all hub members." +msgstr "" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:92 +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:96 +msgid "Message subject" +msgstr "" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:93 +msgid "Sender Email address" +msgstr "" + +#: ../../extend/addon/hzaddons/hubwall/hubwall.php:94 +msgid "Test mode (only send to hub administrator)" +msgstr "" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:51 +msgid "Your Webbie:" +msgstr "" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:54 +msgid "Fontsize (px):" +msgstr "" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:68 +msgid "Link:" +msgstr "" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:70 +msgid "Like us on Hubzilla" +msgstr "" + +#: ../../extend/addon/hzaddons/likebanner/likebanner.php:72 +msgid "Embed:" +msgstr "" + +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:46 +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:43 +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:150 +msgid "Save Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:47 +msgid "text to include in all outgoing posts from this site" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:19 +msgid "lonely" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:20 +msgid "drunk" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:21 +msgid "horny" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:22 +msgid "stoned" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:23 +msgid "fucked up" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:24 +msgid "clusterfucked" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:25 +msgid "crazy" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:26 +msgid "hurt" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:27 +msgid "sleepy" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:28 +msgid "grumpy" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:29 +msgid "high" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:30 +msgid "semi-conscious" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:31 +msgid "in love" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:32 +msgid "in lust" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:33 +msgid "naked" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:34 +msgid "stinky" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:35 +msgid "sweaty" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:36 +msgid "bleeding out" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:37 +msgid "victorious" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:38 +msgid "defeated" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:39 +msgid "envious" +msgstr "" + +#: ../../extend/addon/hzaddons/moremoods/moremoods.php:40 +msgid "jealous" +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:85 +msgid "" +"This website is tracked using the Piwik " +"analytics tool." +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:88 +#, php-format +msgid "" +"If you do not want that your visits are logged this way you can " +"set a cookie to prevent Piwik from tracking further visits of the site " +"(opt-out)." +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:96 +msgid "Piwik Base URL" +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:96 +msgid "" +"Absolute path to your Piwik installation. (without protocol (http/s), with " +"trailing slash)" +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:97 +msgid "Site ID" +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:98 +msgid "Show opt-out cookie link?" +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:99 +msgid "Asynchronous tracking" +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:100 +msgid "Enable frontend JavaScript error tracking" +msgstr "" + +#: ../../extend/addon/hzaddons/piwik/piwik.php:100 +msgid "This feature requires Piwik >= 2.2.0" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:101 +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:102 +#: ../../extend/addon/hzaddons/cart/myshop.php:144 +#: ../../extend/addon/hzaddons/cart/myshop.php:180 +#: ../../extend/addon/hzaddons/cart/myshop.php:214 +#: ../../extend/addon/hzaddons/cart/myshop.php:261 +#: ../../extend/addon/hzaddons/cart/myshop.php:296 +#: ../../extend/addon/hzaddons/cart/myshop.php:319 +msgid "Access Denied" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:109 +msgid "Enable Community Moderation" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:117 +msgid "Reputation automatically given to new members" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:118 +msgid "Reputation will never fall below this value" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:119 +msgid "Minimum reputation before posting is allowed" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:120 +msgid "Minimum reputation before commenting is allowed" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:121 +msgid "Minimum reputation before a member is able to moderate other posts" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:122 +msgid "" +"Max ratio of moderator's reputation that can be added to/deducted from " +"reputation of person being moderated" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:123 +msgid "Reputation \"cost\" to post" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:124 +msgid "Reputation \"cost\" to comment" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:125 +msgid "" +"Reputation automatically recovers at this rate per hour until it reaches " +"minimum_to_post" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:126 +msgid "" +"When minimum_to_moderate > reputation > minimum_to_post reputation recovers " +"at this rate per hour" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:140 +msgid "Community Moderation Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:232 +msgid "Channel Reputation" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:236 +msgid "An Error has occurred." +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:254 +msgid "Upvote" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:255 +msgid "Downvote" +msgstr "" + +#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:414 +msgid "Can moderate reputation on my channel." +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:57 +msgid "Errors encountered deleting database table " +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:95 +#: ../../extend/addon/hzaddons/twitter/twitter.php:503 +msgid "Submit Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96 +msgid "Drop tables when uninstalling?" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96 +msgid "" +"If checked, the Rendezvous database tables will be deleted when the plugin " +"is uninstalled." +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97 +msgid "Mapbox Access Token" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97 +msgid "" +"If you enter a Mapbox access token, it will be used to retrieve map tiles " +"from Mapbox instead of the default OpenStreetMap tile server." +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:162 +msgid "Rendezvous" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:167 +msgid "" +"This identity has been deleted by another member due to inactivity. Please " +"press the \"New identity\" button or refresh the page to register a new " +"identity. You may use the same name." +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:168 +msgid "Welcome to Rendezvous!" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:169 +msgid "" +"Enter your name to join this rendezvous. To begin sharing your location with " +"the other members, tap the GPS control. When your location is discovered, a " +"red dot will appear and others will be able to see you on the map." +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:171 +msgid "Let's meet here" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:174 +msgid "New marker" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:175 +msgid "Edit marker" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:176 +msgid "New identity" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:177 +msgid "Delete marker" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:178 +msgid "Delete member" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:179 +msgid "Edit proximity alert" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180 +msgid "" +"A proximity alert will be issued when this member is within a certain radius " +"of you.

      Enter a radius in meters (0 to disable):" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:185 +msgid "distance" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:181 +msgid "Proximity alert distance (meters)" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:182 +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:184 +msgid "" +"A proximity alert will be issued when you are within a certain radius of the " +"marker location.

      Enter a radius in meters (0 to disable):" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:183 +msgid "Marker proximity alert" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:186 +msgid "Reminder note" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:187 +msgid "" +"Enter a note to be displayed when you are within the specified proximity..." +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:199 +msgid "Add new rendezvous" +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:200 +msgid "" +"Create a new rendezvous and share the access link with those you wish to " +"invite to the group. Those who open the link become members of the " +"rendezvous. They can view other member locations, add markers to the map, or " +"share their own locations with the group." +msgstr "" + +#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:232 +msgid "You have no rendezvous. Press the button above to create a rendezvous!" +msgstr "" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32 +msgid "Skeleton App" +msgstr "" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:33 +msgid "A skeleton for addons, you can copy/paste" +msgstr "" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40 +msgid "Some setting" +msgstr "" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40 +msgid "A setting" +msgstr "" + +#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:48 +msgid "Skeleton Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/redred.php:50 +msgid "Post to Hubzilla" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:24 +msgid "Channel is required." +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:38 +msgid "Hubzilla Crosspost Connector Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50 +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146 +msgid "Hubzilla Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:51 +msgid "Relay public postings to another Hubzilla channel" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63 +msgid "Send public postings to Hubzilla channel by default" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67 +msgid "Hubzilla API Path" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67 +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53 +msgid "https://{sitename}/api" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71 +msgid "Hubzilla login name" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75 +msgid "Hubzilla channel name" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75 +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:54 +msgid "Nickname" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:79 +msgid "Hubzilla password" +msgstr "" + +#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:87 +msgid "Hubzilla Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:23 +msgid "TOTP Two-Step Verification" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:24 +msgid "Enter the 2-step verification generated by your authenticator app:" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:25 +msgid "Success!" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:26 +msgid "Invalid code, please try again." +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:27 +msgid "Too many invalid codes..." +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:28 +msgid "Verify" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:90 +msgid "" +"You haven't set a TOTP secret yet.\n" +"Please click the button below to generate one and register this site\n" +"with your preferred authenticator app." +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:93 +msgid "Your TOTP secret is" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:94 +msgid "" +"Be sure to save it somewhere in case you lose or replace your mobile " +"device.\n" +"Use your mobile device to scan the QR code below to register this site\n" +"with your preferred authenticator app." +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:99 +msgid "Test" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:100 +msgid "Generate New Secret" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:101 +msgid "Go" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:102 +msgid "Enter your password" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:103 +msgid "enter TOTP code from your device" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:104 +msgid "Pass!" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:105 +msgid "Fail" +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:106 +msgid "Incorrect password, try again." +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:107 +msgid "Record your new TOTP secret and rescan the QR code above." +msgstr "" + +#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:115 +msgid "TOTP Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/testdrive/testdrive.php:104 +#, php-format +msgid "Your account on %s will expire in a few days." +msgstr "" + +#: ../../extend/addon/hzaddons/testdrive/testdrive.php:105 +msgid "Your $Productname test account is about to expire." +msgstr "" + +#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:70 +msgid "An account has been created for you." +msgstr "" + +#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:77 +msgid "Authentication successful but rejected: account creation is disabled." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:252 +msgid "DB Cleanup Failure" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:674 +msgid "[cart] Item Added" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1063 +msgid "Order already checked out." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1368 +msgid "Drop database tables when uninstalling." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1375 +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:129 +msgid "Cart Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1387 +#: ../../extend/addon/hzaddons/cart/cart.php:1390 +msgid "Shop" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1446 +#: ../../extend/addon/hzaddons/cart/myshop.php:112 +msgid "Order Not Found" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1507 +msgid "Cart utilities for orders and payments" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1545 +msgid "You must be logged into the Grid to shop." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1578 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:409 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:392 +#: ../../extend/addon/hzaddons/cart/manual_payments.php:68 +msgid "Order not found." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1592 +msgid "Access denied." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1644 +#: ../../extend/addon/hzaddons/cart/cart.php:1787 +msgid "No Order Found" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1653 +msgid "An unknown error has occurred Please start again." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1796 +msgid "Requirements not met." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1796 +msgid "Review your order and complete any needed requirements." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1822 +msgid "Invalid Payment Type. Please start again." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/cart.php:1829 +msgid "Order not found" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:70 +msgid "Enable Order/Item Options" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:333 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:357 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:433 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:457 +msgid "Label" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:336 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:360 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:436 +#: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:460 +msgid "Instructions" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:63 +msgid "Enable Hubzilla Services Module" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:162 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:172 +msgid "New Sku" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:197 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:208 +msgid "Cannot save edits to locked item." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:246 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:333 +msgid "SKU not found." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:299 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:303 +msgid "Invalid Activation Directive." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:374 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:378 +msgid "Invalid Deactivation Directive." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:564 +msgid "Add to this privacy group" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:580 +msgid "Set user service class" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:607 +msgid "You must be using a local account to purchase this service." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:647 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:252 +msgid "Changes Locked" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:651 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:256 +msgid "Item available for purchase." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:658 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:263 +#: ../../extend/addon/hzaddons/cart/widgets/catalogitem.php:57 +msgid "Price" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:661 +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:266 +msgid "Photo URL" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:665 +msgid "Add buyer to privacy group" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:670 +msgid "Add buyer as connection" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:678 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:720 +msgid "Set Service Class" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:151 +msgid "Enable Subscription Management Module" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:223 +msgid "" +"Cannot include subscription items with different terms in the same order." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:372 +msgid "Select Subscription to Edit" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:380 +msgid "Edit Subscriptions" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:414 +msgid "Subscription SKU" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:419 +msgid "Catalog Description" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:423 +msgid "Subscription available for purchase." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:428 +msgid "Maximum active subscriptions to this item per account." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:431 +msgid "Subscription price." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:435 +msgid "Quantity" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:439 +msgid "Term" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:86 +msgid "Enable Paypal Button Module (API-v2)" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:94 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:93 +msgid "Use Production Key" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:101 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:100 +msgid "Paypal Sandbox Client Key" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:108 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:107 +msgid "Paypal Sandbox Secret Key" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:114 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:113 +msgid "Paypal Production Client Key" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:121 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:120 +msgid "Paypal Production Secret Key" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:264 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:252 +msgid "Paypal button payments are not enabled." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbuttonV2.php:282 +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:270 +msgid "" +"Paypal button payments are not properly configured. Please choose another " +"payment option." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:85 +msgid "Enable Paypal Button Module" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:61 +msgid "Enable Manual Cart Module" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/myshop.php:30 +msgid "Access Denied." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/myshop.php:189 +#: ../../extend/addon/hzaddons/cart/myshop.php:223 +#: ../../extend/addon/hzaddons/cart/myshop.php:271 +#: ../../extend/addon/hzaddons/cart/myshop.php:329 +msgid "Invalid Item" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/manual_payments.php:7 +msgid "Error: order mismatch. Please try again." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/manual_payments.php:61 +msgid "Manual payments are not enabled." +msgstr "" + +#: ../../extend/addon/hzaddons/cart/manual_payments.php:77 +msgid "Finished" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:58 +msgid "Enable Test Catalog" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:70 +msgid "Enable Manual Payments" +msgstr "" + +#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:90 +msgid "Base Merchant Currency" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/openid.php:49 +msgid "" +"We encountered a problem while logging in with the OpenID you provided. " +"Please check the correct spelling of the ID." +msgstr "" + +#: ../../extend/addon/hzaddons/openid/openid.php:49 +msgid "The error message was:" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:52 +msgid "First Name" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:53 +msgid "Last Name" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:55 +msgid "Full Name" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:61 +msgid "Profile Photo 16px" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:62 +msgid "Profile Photo 32px" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:63 +msgid "Profile Photo 48px" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:64 +msgid "Profile Photo 64px" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:65 +msgid "Profile Photo 80px" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:66 +msgid "Profile Photo 128px" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:70 +msgid "Birth Year" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:71 +msgid "Birth Month" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:72 +msgid "Birth Day" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:73 +msgid "Birthdate" +msgstr "" + +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:30 +msgid "OpenID protocol error. No ID returned." +msgstr "" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:81 +msgid "Hubzilla File Storage Import" +msgstr "" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:82 +msgid "This will import all your cloud files from another server." +msgstr "" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:83 +msgid "Hubzilla Server base URL" +msgstr "" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:84 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:140 +msgid "Since modified date yyyy-mm-dd" +msgstr "" + +#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:85 +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:141 +msgid "Until modified date yyyy-mm-dd" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:43 +msgid "Diaspora Protocol Settings updated." +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:52 +msgid "" +"The diaspora protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:58 +msgid "Diaspora Protocol App" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:75 +msgid "Allow any Diaspora member to comment on your public posts" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:79 +msgid "Prevent your hashtags from being redirected to other sites" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:83 +msgid "Sign and forward posts and comments with no existing Diaspora signature" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:88 +msgid "Followed hashtags (comma separated, do not include the #)" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:97 +msgid "Diaspora Protocol" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:19 +msgid "No username found in import file." +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1541 +#, php-format +msgid "%1$s dislikes %2$s's %3$s" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:66 +msgid "" +"Please install the statistics addon to be able to configure a diaspora relay" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:76 +msgid "Diaspora Relay Handle" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:76 +msgid "Address of a diaspora relay. Example: relay@diasporarelay.tld" +msgstr "" + +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:96 +msgid "Diaspora relay could not be imported" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:94 +msgid "Hubzilla Directory Stats" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:95 +msgid "Total Hubs" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:97 +msgid "Hubzilla Hubs" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:99 +msgid "Friendica Hubs" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:101 +msgid "Diaspora Pods" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:103 +msgid "Hubzilla Channels" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:105 +msgid "Friendica Channels" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:107 +msgid "Diaspora Channels" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:109 +msgid "Aged 35 and above" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:111 +msgid "Aged 34 and under" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:113 +msgid "Average Age" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:115 +msgid "Known Chatrooms" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:117 +msgid "Known Tags" +msgstr "" + +#: ../../extend/addon/hzaddons/dirstats/dirstats.php:119 +msgid "" +"Please note Diaspora and Friendica statistics are merely those **this " +"directory** is aware of, and not all those known in the network. This also " +"applies to chatrooms," +msgstr "" + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:25 +msgid "Show Upload Limits" +msgstr "" + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:27 +msgid "Hubzilla configured maximum size: " +msgstr "" + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:28 +msgid "PHP upload_max_filesize: " +msgstr "" + +#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:29 +msgid "PHP post_max_size (must be larger than upload_max_filesize): " +msgstr "" + +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:23 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:27 +msgid "Hide Aside App" +msgstr "" + +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:24 +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:28 +msgid "Fade out aside areas after a while when using endless scroll" +msgstr "" + +#: ../../extend/addon/hzaddons/hideaside/Mod_Hideaside.php:27 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26 +msgid "Installed" +msgstr "" + +#: ../../extend/addon/hzaddons/randpost/randpost.php:97 +msgid "You're welcome." +msgstr "" + +#: ../../extend/addon/hzaddons/randpost/randpost.php:98 +msgid "Ah shucks..." +msgstr "" + +#: ../../extend/addon/hzaddons/randpost/randpost.php:99 +msgid "Don't mention it." +msgstr "" + +#: ../../extend/addon/hzaddons/randpost/randpost.php:100 +msgid "<blush>" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:133 +msgid "View Larger" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:156 +msgid "Tile Server URL" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:156 +msgid "" +"A list of public tile servers" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:157 +msgid "Nominatim (reverse geocoding) Server URL" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:157 +msgid "" +"A list of Nominatim servers" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:158 +msgid "Default zoom" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:158 +msgid "" +"The default zoom level. (1:world, 18:highest, also depends on tile server)" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:159 +msgid "Include marker on map" +msgstr "" + +#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:159 +msgid "Include a marker on the map." +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:38 +msgid "Livejournal Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:39 +msgid "Relay public posts to Livejournal" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:55 +msgid "Livejournal username" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:59 +msgid "Livejournal password" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:63 +msgid "Post to Livejournal by default" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:67 +msgid "Send wall-to-wall posts to Livejournal" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:71 +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:65 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94 +msgid "Add link to original post" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:79 +msgid "Livejournal Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:49 +msgid "Post to Livejournal" +msgstr "" + +#: ../../extend/addon/hzaddons/ljpost/ljpost.php:127 +msgid "Posted by" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:222 +msgid "Workflow user." +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:272 +msgid "This channel" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:541 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1437 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1456 +msgid "Workflow" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:1425 +msgid "No Workflows Available" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:1455 +msgid "Add item to which workflow" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:1515 +#: ../../extend/addon/hzaddons/workflow/workflow.php:1634 +msgid "Create Workflow Item" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2596 +msgid "Link" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2598 +msgid "Web link." +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2619 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2680 +msgid "Brief description or title" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2627 +#: ../../extend/addon/hzaddons/workflow/workflow.php:2688 +msgid "Notes and Info" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/workflow.php:2686 +msgid "Body" +msgstr "" + +#: ../../extend/addon/hzaddons/workflow/Settings/Mod_WorkflowSettings.php:101 +msgid "Workflow Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:44 +msgid "Jabber BOSH host" +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45 +msgid "Use central userbase" +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45 +msgid "" +"If enabled, members will automatically login to an ejabberd server that has " +"to be installed on this machine with synchronized credentials via the " +"\"auth_ejabberd.php\" script." +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:23 +msgid "XMPP settings updated." +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35 +msgid "XMPP App" +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:36 +msgid "Embedded XMPP (Jabber) client" +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:52 +msgid "Individual credentials" +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:58 +msgid "Jabber BOSH server" +msgstr "" + +#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:67 +msgid "XMPP Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20 +msgid "Superblock App" +msgstr "" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:21 +msgid "Block channels" +msgstr "" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:63 +msgid "superblock settings updated" +msgstr "" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:87 +msgid "Currently blocked" +msgstr "" + +#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:89 +msgid "No channels currently blocked" +msgstr "" + +#: ../../extend/addon/hzaddons/superblock/superblock.php:337 +msgid "Block Completely" +msgstr "" + +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20 +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23 +msgid "Random Planet App" +msgstr "" + +#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:25 +msgid "" +"Set a random planet from the Star Wars Empire as your location when posting" +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/nsfw.php:152 +msgid "Possible adult content" +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/nsfw.php:167 +#, php-format +msgid "%s - view" +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:22 +msgid "NSFW Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33 +msgid "NSFW App" +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:34 +msgid "Collapse content that contains predefined words" +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:44 +msgid "" +"This app looks in posts for the words/text you specify below, and collapses " +"any content containing those keywords so it is not displayed at " +"inappropriate times, such as sexual innuendo that may be improper in a work " +"setting. It is polite and recommended to tag any content containing nudity " +"with #NSFW. This filter can also match any other word/text you specify, and " +"can thereby be used as a general purpose content filter." +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49 +msgid "Comma separated list of keywords to hide" +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49 +msgid "Word, /regular-expression/, lang=xx, lang!=xx" +msgstr "" + +#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:58 +msgid "NSFW" +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:21 +msgid "Three Dimensional Tic-Tac-Toe" +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:54 +msgid "3D Tic-Tac-Toe" +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:59 +msgid "New game" +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:60 +msgid "New game with handicap" +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:61 +msgid "" +"Three dimensional tic-tac-toe is just like the traditional game except that " +"it is played on multiple levels simultaneously. " +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:62 +msgid "" +"In this case there are three levels. You win by getting three in a row on " +"any level, as well as up, down, and diagonally across the different levels." +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:64 +msgid "" +"The handicap game disables the center position on the middle level because " +"the player claiming this square often has an unfair advantage." +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:183 +msgid "You go first..." +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:188 +msgid "I'm going first this time..." +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:194 +msgid "You won!" +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:200 +#: ../../extend/addon/hzaddons/tictac/tictac.php:225 +msgid "\"Cat\" game!" +msgstr "" + +#: ../../extend/addon/hzaddons/tictac/tictac.php:223 +msgid "I won!" +msgstr "" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:27 +msgid "Photo Cache settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:36 +msgid "" +"Photo Cache addon saves a copy of images from external sites locally to " +"increase your anonymity in the web." +msgstr "" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42 +msgid "Photo Cache App" +msgstr "" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:53 +msgid "Minimal photo size for caching" +msgstr "" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:55 +msgid "In pixels. From 1 up to 1024, 0 will be replaced with system default." +msgstr "" + +#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:64 +msgid "Photo Cache" +msgstr "" + +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:26 +#, php-format +msgctxt "opensearch" +msgid "Search %1$s (%2$s)" +msgstr "" + +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:28 +msgctxt "opensearch" +msgid "$Projectname" +msgstr "" + +#: ../../extend/addon/hzaddons/opensearch/opensearch.php:43 +msgid "Search $Projectname" +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:25 +msgid "Libertree Crosspost Connector Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35 +msgid "Libertree Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:36 +msgid "Relay public posts to Libertree" +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:51 +msgid "Libertree API token" +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:55 +msgid "Libertree site URL" +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59 +msgid "Post to Libertree by default" +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:67 +msgid "Libertree Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/libertree/libertree.php:43 +msgid "Post to Libertree" +msgstr "" + +#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:24 +msgid "Flag Adult Photos" +msgstr "" + +#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:25 +msgid "" +"Provide photo edit option to hide inappropriate photos from default album " +"view" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:145 +msgid "Post to GNU social" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:594 +msgid "API URL" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/statusnet.php:597 +msgid "Application name" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:61 +msgid "" +"Please contact your site administrator.
      The provided API URL is not " +"valid." +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:98 +msgid "We could not contact the GNU social API with the Path you entered." +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:130 +msgid "GNU social settings updated." +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:147 +msgid "" +"Relay public postings to a connected GNU social account (formerly StatusNet)" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:181 +msgid "Globally Available GNU social OAuthKeys" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:183 +msgid "" +"There are preconfigured OAuth key pairs for some GNU social servers " +"available. If you are using one of them, please use these credentials.
      If not feel free to connect to any other GNU social instance (see below)." +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:198 +msgid "Provide your own OAuth Credentials" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:200 +msgid "" +"No consumer key pair for GNU social found. Register your Hubzilla Account as " +"an desktop client on your GNU social account, copy the consumer key pair " +"here and enter the API base root.
      Before you register your own OAuth " +"key pair ask the administrator if there is already a key pair for this " +"Hubzilla installation at your favourite GNU social installation." +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:204 +msgid "OAuth Consumer Key" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:208 +msgid "OAuth Consumer Secret" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212 +msgid "Base API Path" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212 +msgid "Remember the trailing /" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:216 +msgid "GNU social application name" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:239 +msgid "" +"To connect to your GNU social account click the button below to get a " +"security code from GNU social which you have to copy into the input box " +"below and submit the form. Only your public posts will be " +"posted to GNU social." +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:241 +msgid "Log in with GNU social" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:244 +msgid "Copy the security code from GNU social here" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:254 +msgid "Cancel Connection Process" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:256 +msgid "Current GNU social API is" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260 +msgid "Cancel GNU social Connection" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:272 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:147 +msgid "Currently connected to: " +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:277 +msgid "" +"Note: Due your privacy settings (Hide your profile " +"details from unknown viewers?) the link potentially included in public " +"postings relayed to GNU social will lead the visitor to a blank page " +"informing the visitor that the access to your profile has been restricted." +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +msgid "Post to GNU social by default" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282 +msgid "" +"If enabled your public postings will be posted to the associated GNU-social " +"account by default" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291 +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171 +msgid "Clear OAuth configuration" +msgstr "" + +#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:303 +msgid "GNU-Social Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/wholikesme/wholikesme.php:29 +msgid "Who likes me?" +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:25 +msgid "ActivityPub Protocol Settings updated." +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:34 +msgid "" +"The activitypub protocol does not support location independence. Connections " +"you make within that network may be unreachable from alternate channel " +"locations." +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40 +msgid "Activitypub Protocol App" +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50 +msgid "Deliver to ActivityPub recipients in privacy groups" +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50 +msgid "" +"May result in a large number of mentions and expose all the members of your " +"privacy group" +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54 +msgid "Send multi-media HTML articles" +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54 +msgid "Not supported by some microblog services such as Mastodon" +msgstr "" + +#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:62 +msgid "Activitypub Protocol" +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/ijpost.php:44 +msgid "Post to Insane Journal" +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:23 +msgid "Insane Journal Crosspost Connector Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35 +msgid "Insane Journal Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:36 +msgid "Relay public postings to Insane Journal" +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:53 +msgid "InsaneJournal username" +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:57 +msgid "InsaneJournal password" +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61 +msgid "Post to InsaneJournal by default" +msgstr "" + +#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:69 +msgid "Insane Journal Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:77 +msgid "Max queueworker threads" +msgstr "" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:91 +msgid "Assume workers dead after ___ seconds" +msgstr "" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:105 +msgid "" +"Pause before starting next task: (microseconds. Minimum 100 = .0001 seconds)" +msgstr "" + +#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:116 +msgid "Queueworker Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:218 +msgid "Not allowed." +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:123 +msgid "generic profile image" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:124 +msgid "random geometric pattern" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:125 +msgid "monster face" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:126 +msgid "computer generated face" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:127 +msgid "retro arcade style face" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:128 +msgid "Hub default profile photo" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143 +msgid "Information" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143 +msgid "" +"Libravatar addon is installed, too. Please disable Libravatar addon or this " +"Gravatar addon.
      The Libravatar addon will fall back to Gravatar if " +"nothing was found at Libravatar." +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151 +msgid "Default avatar image" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151 +msgid "Select default avatar image if none was found at Gravatar. See README" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152 +msgid "Rating of images" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152 +msgid "Select the appropriate avatar rating for your site. See README" +msgstr "" + +#: ../../extend/addon/hzaddons/gravatar/gravatar.php:165 +msgid "Gravatar settings updated." +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:104 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:176 +msgid "Network error" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:108 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:180 +msgid "API error" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:112 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:184 +msgid "Unknown issue" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:168 +msgid "Unable to login using email address " +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:202 +msgid "Sign in to Hubzilla using a social account" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:207 +msgid "Social Authentication using your social media account" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:211 +msgid "" +"This app enables one or more social provider sign-in buttons on the login " +"page." +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:229 +msgid "Add an identity provider" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:256 +msgid "Enable " +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:263 +msgid "Key" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:263 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:268 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:284 +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:297 +msgid "Word" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:268 +msgid "Secret" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:297 +msgid "Add a custom provider" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:317 +msgid "Remove an identity provider" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:327 +msgid "Social authentication" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:366 +msgid "Error while saving provider settings" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:382 +msgid "Custom provider already exists" +msgstr "" + +#: ../../extend/addon/hzaddons/socialauth/Mod_SocialAuth.php:399 +msgid "Social authentication settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:14 +msgid "Send your identity to all websites" +msgstr "" + +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20 +msgid "Sendzid App" +msgstr "" + +#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:32 +msgid "Send ZID" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:106 +msgid "Photos imported" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:129 +msgid "Redmatrix Photo Album Import" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:130 +msgid "This will import all your Redmatrix photo albums to this channel." +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:131 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:121 +msgid "Redmatrix Server base URL" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:132 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:122 +msgid "Redmatrix Login Username" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:133 +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:123 +msgid "Redmatrix Login Password" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134 +msgid "Import just this album" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134 +msgid "Leave blank to import all albums" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135 +msgid "Maximum count to import" +msgstr "" + +#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135 +msgid "0 or blank to import all available" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:65 +msgid "Twitter settings updated." +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78 +msgid "Twitter Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:79 +msgid "Relay public posts to Twitter" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:103 +msgid "" +"No consumer key pair for Twitter found. Please contact your site " +"administrator." +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:125 +msgid "" +"At this Hubzilla instance the Twitter plugin was enabled but you have not " +"yet connected your account to your Twitter account. To do so click the " +"button below to get a PIN from Twitter which you have to copy into the input " +"box below and submit the form. Only your public posts will " +"be posted to Twitter." +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:127 +msgid "Log in with Twitter" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:130 +msgid "Copy the PIN from Twitter here" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:152 +msgid "" +"Note: Due your privacy settings (Hide your profile " +"details from unknown viewers?) the link potentially included in public " +"postings relayed to Twitter will lead the visitor to a blank page informing " +"the visitor that the access to your profile has been restricted." +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157 +msgid "Twitter post length" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157 +msgid "Maximum tweet length" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +msgid "Send public postings to Twitter by default" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162 +msgid "" +"If enabled your public postings will be posted to the associated Twitter " +"account by default" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:181 +msgid "Twitter Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/twitter/twitter.php:109 +msgid "Post to Twitter" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:21 +msgid "Project Servers and Resources" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:22 +msgid "Project Creator and Tech Lead" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:49 +msgid "" +"And the hundreds of other people and organisations who helped make the " +"Hubzilla possible." +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:52 +msgid "" +"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving " +"their time and expertise - and often paying out of pocket for services they " +"share with others." +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:53 +msgid "" +"There is no corporate funding and no ads, and we do not collect and sell " +"your personal information. (We don't control your personal information - " +"you do.)" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:54 +msgid "" +"Help support our ground-breaking work in decentralisation, web identity, and " +"privacy." +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:56 +msgid "" +"Your donations keep servers and services running and also helps us to " +"provide innovative new features and continued development." +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:59 +msgid "Donate" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:61 +msgid "" +"Choose a project, developer, or public hub to support with a one-time " +"donation" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:62 +msgid "Donate Now" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:63 +msgid "" +"Or become a project sponsor (Hubzilla Project only)" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:64 +msgid "" +"Please indicate if you would like your first name or full name (or nothing) " +"to appear in our sponsor listing" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:65 +msgid "Sponsor" +msgstr "" + +#: ../../extend/addon/hzaddons/donate/donate.php:68 +msgid "Special thanks to: " +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:26 +msgid "Dreamwidth Crosspost Connector Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:39 +msgid "Dreamwidth Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:40 +msgid "Relay public posts to Dreamwidth" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:53 +msgid "Dreamwidth username" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:57 +msgid "Dreamwidth password" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:61 +msgid "Post to Dreamwidth by default" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:69 +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:98 +msgid "Link description (default:" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:77 +msgid "Dreamwidth Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/dwpost/dwpost.php:49 +msgid "Post to Dreamwidth" +msgstr "" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:21 +msgid "nofed Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33 +msgid "No Federation App" +msgstr "" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:34 +msgid "" +"Prevent posting from being federated to anybody. It will exist only on your " +"channel page." +msgstr "" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42 +msgid "Federate posts by default" +msgstr "" + +#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:50 +msgid "No Federation" +msgstr "" + +#: ../../extend/addon/hzaddons/nofed/nofed.php:47 +msgid "Federate" +msgstr "" + +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:15 +msgid "WYSIWYG status editor" +msgstr "" + +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21 +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26 +msgid "WYSIWYG Status App" +msgstr "" + +#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:34 +msgid "WYSIWYG Status" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:27 +msgid "No server specified" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:73 +msgid "Posts imported" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:113 +msgid "Files imported" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:122 +msgid "" +"This addon app copies existing content and file storage to a cloned/copied " +"channel. Once the app is installed, visit the newly installed app. This will " +"allow you to set the location of your original channel and an optional date " +"range of files/conversations to copy." +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:136 +msgid "" +"This will import all your conversations and cloud files from a cloned " +"channel on another server. This may take a while if you have lots of posts " +"and or files." +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +msgid "Include posts" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137 +msgid "Conversations, Articles, Cards, and other posted content" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +msgid "Include files" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138 +msgid "Files, Photos and other cloud storage" +msgstr "" + +#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:139 +msgid "Original Server base URL" +msgstr "" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:48 +msgid "Your channel has been upgraded to $Projectname version" +msgstr "" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:50 +msgid "Please have a look at the" +msgstr "" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:52 +msgid "git history" +msgstr "" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:54 +msgid "change log" +msgstr "" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:55 +msgid "for further info." +msgstr "" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:60 +msgid "Upgrade Info" +msgstr "" + +#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:64 +msgid "Do not show this again" +msgstr "" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:22 +msgid "pageheader Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34 +msgid "Page Header App" +msgstr "" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:35 +msgid "Inserts a page header" +msgstr "" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:43 +msgid "Message to display on every page on this server" +msgstr "" + +#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:51 +msgid "Page Header" +msgstr "" + +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:21 +msgid "Who viewed my channel/profile" +msgstr "" + +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:25 +msgid "Recent Channel/Profile Viewers" +msgstr "" + +#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:36 +msgid "No entries." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:39 +msgid "Messages" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:52 +msgid "message" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:92 +msgid "Message recalled." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:105 +msgid "Conversation removed." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:120 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:241 +msgid "Expires YYYY-MM-DD HH:MM" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:148 +msgid "Requested channel is not in this network" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:156 +msgid "Send Private Message" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:157 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:300 +msgid "To:" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:160 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:302 +msgid "Subject:" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:165 +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:308 +msgid "Attach file" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:167 +msgid "Send" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:271 +msgid "Delete message" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:272 +msgid "Delivery report" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:273 +msgid "Recall message" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:275 +msgid "Message has been recalled." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:293 +msgid "Delete Conversation" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:295 +msgid "" +"No secure communications available. You may be able to " +"respond from the sender's profile page." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:299 +msgid "Send Reply" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:304 +#, php-format +msgid "Your message for %s (%s):" +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:384 +msgid "Unable to lookup recipient." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:391 +msgid "Unable to communicate with requested channel." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:398 +msgid "Cannot verify requested channel." +msgstr "" + +#: ../../extend/addon/hzaddons/mail/Mod_Mail.php:416 +msgid "Selected channel has private message restrictions. Send failed." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:50 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:128 +msgid "System defaults:" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54 +msgid "Preferred Clipart IDs" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54 +msgid "List of preferred clipart ids. These will be shown first." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55 +msgid "Default Search Term" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55 +msgid "The default search term. These will be shown second." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56 +msgid "Return After" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56 +msgid "Page to load after image selection." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:59 +msgid "Profile List" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61 +msgid "Order of Preferred" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61 +msgid "Sort order of preferred clipart ids." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:62 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:68 +msgid "Newest first" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:65 +msgid "As entered" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67 +msgid "Order of other" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67 +msgid "Sort order of other clipart ids." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:69 +msgid "Most downloaded first" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:70 +msgid "Most liked first" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72 +msgid "Preferred IDs Message" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72 +msgid "Message to display above preferred results." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78 +msgid "Uploaded by: " +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78 +msgid "Drawn by: " +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:182 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:194 +msgid "Use this image" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:192 +msgid "Or select from a free OpenClipart.org image:" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:195 +msgid "Search Term" +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:232 +msgid "Unknown error. Please try again later." +msgstr "" + +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:308 +msgid "Profile photo updated successfully." +msgstr "" + +#: ../../extend/addon/hzaddons/gallery/gallery.php:43 +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:136 +msgid "Gallery" +msgstr "" + +#: ../../extend/addon/hzaddons/gallery/gallery.php:46 +msgid "Photo Gallery" +msgstr "" + +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58 +msgid "Gallery App" +msgstr "" + +#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:59 +msgid "A simple gallery for your photo albums" +msgstr "" + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35 +msgid "Smileybutton App" +msgstr "" + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:36 +msgid "Adds a smileybutton to the jot editor" +msgstr "" + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44 +msgid "Hide the button and show the smilies directly." +msgstr "" + +#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:52 +msgid "Smileybutton Settings" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/rtof.php:51 +msgid "Post to Friendica" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:24 +msgid "Friendica Crosspost Connector Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36 +msgid "Friendica Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:37 +msgid "Relay public postings to a connected Friendica account" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49 +msgid "Send public postings to Friendica by default" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53 +msgid "Friendica API Path" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57 +msgid "Friendica login name" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:61 +msgid "Friendica password" +msgstr "" + +#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:69 +msgid "Friendica Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:36 +msgid "Logfile archive directory" +msgstr "" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:36 +msgid "Directory to store rotated logs" +msgstr "" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:37 +msgid "Logfile size in bytes before rotating" +msgstr "" + +#: ../../extend/addon/hzaddons/logrot/logrot.php:38 +msgid "Number of logfiles to retain" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/wppost.php:46 +msgid "Post to WordPress" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:30 +msgid "Wordpress Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:43 +msgid "Wordpress Post App" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:44 +msgid "Post to WordPress or anything else which uses the wordpress XMLRPC API" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:69 +msgid "WordPress username" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:73 +msgid "WordPress password" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:77 +msgid "WordPress API URL" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:78 +msgid "Typically https://your-blog.tld/xmlrpc.php" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:81 +msgid "WordPress blogid" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82 +msgid "For multi-user sites such as wordpress.com, otherwise leave blank" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86 +msgid "Post to WordPress by default" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:90 +msgid "Forward comments (requires hubzilla_wp plugin)" +msgstr "" + +#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:106 +msgid "Wordpress Post" +msgstr "" + +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:22 +msgid "" +"Allow magic authentication only to websites of your immediate connections" +msgstr "" + +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28 +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33 +msgid "Authchoose App" +msgstr "" + +#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:39 +msgid "Authchoose" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19 +msgid "bitchslap" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19 +msgid "bitchslapped" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20 +msgid "shag" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20 +msgid "shagged" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21 +msgid "patent" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21 +msgid "patented" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22 +msgid "hug" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22 +msgid "hugged" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23 +msgid "murder" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23 +msgid "murdered" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24 +msgid "worship" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24 +msgid "worshipped" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25 +msgid "kiss" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25 +msgid "kissed" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26 +msgid "tempt" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26 +msgid "tempted" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27 +msgid "raise eyebrows at" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27 +msgid "raised their eyebrows at" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28 +msgid "insult" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28 +msgid "insulted" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29 +msgid "praise" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29 +msgid "praised" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30 +msgid "be dubious of" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30 +msgid "was dubious of" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31 +msgid "eat" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31 +msgid "ate" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32 +msgid "giggle and fawn at" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32 +msgid "giggled and fawned at" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33 +msgid "doubt" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33 +msgid "doubted" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34 +msgid "glare" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34 +msgid "glared at" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35 +msgid "fuck" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35 +msgid "fucked" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36 +msgid "bonk" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36 +msgid "bonked" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37 +msgid "declare undying love for" +msgstr "" + +#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37 +msgid "declared undying love for" +msgstr "" + +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:34 +msgid "New registration" +msgstr "" + +#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:42 +#, php-format +msgid "Message sent to %s. New account registration: %s" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:40 +msgid "Pump.io Settings saved." +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53 +msgid "Pump.io Crosspost Connector App" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:54 +msgid "Relay public posts to pump.io" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73 +msgid "Pump.io servername" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73 +msgid "Without \"http://\" or \"https://\"" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77 +msgid "Pump.io username" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77 +msgid "Without the servername" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:88 +msgid "You are not authenticated to pumpio" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:90 +msgid "(Re-)Authenticate your pump.io connection" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94 +msgid "Post to pump.io by default" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98 +msgid "Should posts be public" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102 +msgid "Mirror all public posts" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:112 +msgid "Pump.io Crosspost Connector" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:152 +msgid "You are now authenticated to pumpio." +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:153 +msgid "return to the featured settings page" +msgstr "" + +#: ../../extend/addon/hzaddons/pumpio/pumpio.php:168 +msgid "Post to Pump.io" +msgstr "" + +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20 +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24 +msgid "NSA Bait App" +msgstr "" + +#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:26 +msgid "Make yourself a political target" +msgstr "" + +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:15 +msgid "Add some colour to tag clouds" +msgstr "" + +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21 +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26 +msgid "Rainbow Tag App" +msgstr "" + +#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:34 +msgid "Rainbow Tag" +msgstr "" + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:19 +msgid "Send test email" +msgstr "" + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:66 +msgid "Mail sent." +msgstr "" + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:68 +msgid "Sending of mail failed." +msgstr "" + +#: ../../extend/addon/hzaddons/mailtest/mailtest.php:77 +msgid "Mail Test" +msgstr "" + +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:119 +msgid "Redmatrix File Storage Import" +msgstr "" + +#: ../../extend/addon/hzaddons/redfiles/redfiles.php:120 +msgid "This will import all your Redmatrix cloud files to this channel." +msgstr "" + +#: ../../extend/addon/hzaddons/mdpost/mdpost.php:42 +msgid "Use markdown for editing posts" +msgstr "" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:22 +msgid "Fuzzloc Settings updated." +msgstr "" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34 +msgid "Fuzzy Location App" +msgstr "" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:35 +msgid "" +"Blur your precise location if your channel uses browser location mapping" +msgstr "" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:40 +msgid "Minimum offset in meters" +msgstr "" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:44 +msgid "Maximum offset in meters" +msgstr "" + +#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:53 +msgid "Fuzzy Location" +msgstr "" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50 +msgid "Startpage App" +msgstr "" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:51 +msgid "Set a preferred page to load on login from home page" +msgstr "" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62 +msgid "Page to load after login" +msgstr "" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62 +msgid "" +"Examples: "apps", "network?f=&gid=37" (privacy " +"collection), "channel" or "notifications/system" (leave " +"blank for default network page (grid)." +msgstr "" + +#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:70 +msgid "Startpage" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:16 +#: ../../view/theme/redbasic/php/config.php:19 +msgid "Focus (Hubzilla default)" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:98 +msgid "Theme settings" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:99 +msgid "Narrow navbar" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:100 +msgid "Navigation bar background color" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:101 +msgid "Navigation bar icon color " +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:102 +msgid "Navigation bar active icon color " +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:103 +msgid "Link color" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:104 +msgid "Set font-color for banner" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:105 +msgid "Set the background color" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:106 +msgid "Set the background image" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:107 +msgid "Set the background color of items" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:108 +msgid "Set the background color of comments" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:109 +msgid "Set font-size for the entire application" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:109 +msgid "Examples: 1rem, 100%, 16px" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:110 +msgid "Set font-color for posts and comments" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:111 +msgid "Set radius of corners" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:111 +msgid "Example: 4px" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:112 +msgid "Set shadow depth of photos" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:113 +msgid "Set maximum width of content region in pixel" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:113 +msgid "Leave empty for default width" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:114 +msgid "Set size of conversation author photo" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:115 +msgid "Set size of followup author photos" +msgstr "" + +#: ../../view/theme/redbasic/php/config.php:116 +msgid "Show advanced settings" +msgstr "" + +#: ../../boot.php:1684 +msgid "Create an account to access services and applications" +msgstr "" + +#: ../../boot.php:1708 +msgid "Login/Email" +msgstr "" + +#: ../../boot.php:1709 +msgid "Password" +msgstr "" + +#: ../../boot.php:1710 +msgid "Remember me" +msgstr "" + +#: ../../boot.php:1713 +msgid "Forgot your password?" +msgstr "" + +#: ../../boot.php:2582 +#, php-format +msgid "[$Projectname] Website SSL error for %s" +msgstr "" + +#: ../../boot.php:2587 +msgid "Website SSL certificate is not valid. Please correct." +msgstr "" + +#: ../../boot.php:2703 +#, php-format +msgid "[$Projectname] Cron tasks not running on %s" +msgstr "" + +#: ../../boot.php:2708 +msgid "Cron/Scheduled tasks not running." +msgstr "" diff --git a/view/pl/hstrings.php b/view/pl/hstrings.php new file mode 100644 index 000000000..6eaf8d4fe --- /dev/null +++ b/view/pl/hstrings.php @@ -0,0 +1,3575 @@ +=2 && $n%10<=4 && ($n%100<12)) +; +}} +App::$rtl = 0; +App::$strings["plural_function_code"] = "(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12)) +"; +App::$strings["Can view my channel stream and posts"] = "Może wyświetlać strumień i posty z mojego kanału"; +App::$strings["Can send me their channel stream and posts"] = "Może przesyłać mi strumień swojego kanału i posty"; +App::$strings["Can view my default channel profile"] = "Może wyświetlać mój domyślny profil kanału"; +App::$strings["Can view my connections"] = "Może wyświetlać moje połączenia"; +App::$strings["Can view my file storage and photos"] = "Może wyświetlać moje przechowywane pliki i zdjęcia"; +App::$strings["Can upload/modify my file storage and photos"] = "Może przesyłać/modyfikować moje przechowywane pliki i zdjęcia"; +App::$strings["Can view my channel webpages"] = "Może wyświetlać strony internetowe mojego kanału"; +App::$strings["Can view my wiki pages"] = "Może przeglądać moje strony wiki"; +App::$strings["Can create/edit my channel webpages"] = "Może tworzyć/edytować strony internetowe mojego kanału"; +App::$strings["Can write to my wiki pages"] = "Może pisać na moich stronach wiki"; +App::$strings["Can post on my channel (wall) page"] = "Może publikować na stronie mojego kanału (tablicy)"; +App::$strings["Can comment on or like my posts"] = "Może komentować lub polubić moje posty"; +App::$strings["Can send me private mail messages"] = "Może wysyłać mi prywatne wiadomości e-mail"; +App::$strings["Can like/dislike profiles and profile things"] = "Może polubiać/dezaprobować profile i rzeczy w profilach"; +App::$strings["Can forward to all my channel connections via ! mentions in posts"] = "Może przekazywać informacje do wszystkich moich połączeń kanałowych za pośrednictwem! wzmianki w postach"; +App::$strings["Can chat with me"] = "Może ze mną rozmawiać"; +App::$strings["Can source my public posts in derived channels"] = "Może pozyskiwać moje publiczne posty w kanałach pochodnych"; +App::$strings["Can administer my channel"] = "Może zarządzać moim kanałem"; +App::$strings["Social Networking"] = "Sieć społecznościowa"; +App::$strings["Social - Federation"] = "Społecznościowy - federacyjny"; +App::$strings["Social - Mostly Public"] = "Społecznościowy - głównie publiczny"; +App::$strings["Social - Restricted"] = "Społecznościowy - ograniczony"; +App::$strings["Social - Private"] = "Społecznościowy - prywatny"; +App::$strings["Community Forum"] = "Forum społecznościowe"; +App::$strings["Forum - Mostly Public"] = "Forum - głównie publiczne"; +App::$strings["Forum - Restricted"] = "Forum - ograniczone"; +App::$strings["Forum - Private"] = "Forum - prywatne"; +App::$strings["Feed Republish"] = "Opublikuj ponownie kanał RSS"; +App::$strings["Feed - Mostly Public"] = "Kanał RSS - głównie publiczny"; +App::$strings["Feed - Restricted"] = "Kanał RSS - ograniczony"; +App::$strings["Special Purpose"] = "Specjalnego celu"; +App::$strings["Special - Celebrity/Soapbox"] = "Specjalne - celebryckie i mównice"; +App::$strings["Special - Group Repository"] = "Specjalne - repozytorium grupowe"; +App::$strings["Other"] = "Inny"; +App::$strings["Custom/Expert Mode"] = "Tryb niestandardowy/ekspercki"; +App::$strings["Permission denied."] = "Dostęp zabroniony."; +App::$strings["Layout updated."] = "Zaktualizowano układ."; +App::$strings["PDL Editor App"] = "Aplikacja PDL Editor"; +App::$strings["Not Installed"] = "Nie zainstalowano"; +App::$strings["Provides the ability to edit system page layouts"] = "Zapewnia możliwość edycji układów stron systemowych"; +App::$strings["Edit System Page Description"] = "Edytuj opis strony systemowej"; +App::$strings["(modified)"] = "(zmodyfikowany)"; +App::$strings["Reset"] = "Resetuj"; +App::$strings["Layout not found."] = "Nie znaleziono układu."; +App::$strings["Module Name:"] = "Nazwa modułu:"; +App::$strings["Layout Help"] = "Pomoc dotycząca układu"; +App::$strings["Edit another layout"] = "Edytuj inny układ"; +App::$strings["System layout"] = "Układ systemowy"; +App::$strings["Submit"] = "Zatwierdź"; +App::$strings["Update to Hubzilla 5.0 step 2"] = "Zaktualizuj do Hubzilli 5.0 krok 2"; +App::$strings["To complete the update please run"] = "Uruchom, aby zakończyć aktualizację"; +App::$strings["php util/z6convert.php"] = "php util/z6convert.php"; +App::$strings["from the terminal."] = "z terminala."; +App::$strings["Permission denied"] = "Dostęp zabroniony"; +App::$strings["Invalid message"] = "Nieprawidłowa wiadomość"; +App::$strings["no results"] = "brak wyników"; +App::$strings["channel sync processed"] = "synchronizacja kanałów została przetworzona"; +App::$strings["queued"] = "w kolejce"; +App::$strings["posted"] = "opublikowane"; +App::$strings["accepted for delivery"] = "przyjęty do dostawy"; +App::$strings["updated"] = "zaktualizowany"; +App::$strings["update ignored"] = "aktualizacja zignorowana"; +App::$strings["permission denied"] = "dostęp zabroniony"; +App::$strings["recipient not found"] = "nie znaleziono odbiorcy"; +App::$strings["mail recalled"] = "mail odwołany"; +App::$strings["duplicate mail received"] = "otrzymano powieloną wiadomość"; +App::$strings["mail delivered"] = "dostarczono pocztę"; +App::$strings["Delivery report for %1\$s"] = "Raport dostarczenia dla %1\$s"; +App::$strings["Options"] = "Opcje"; +App::$strings["Redeliver"] = "Dostarcz ponownie"; +App::$strings["Invalid profile identifier."] = "Nieprawidłowy identyfikator profilu."; +App::$strings["Profile Visibility Editor"] = "Edytor widoczności profilu"; +App::$strings["Profile"] = "Profil"; +App::$strings["Click on a contact to add or remove."] = "Kliknij kontakt, który chcesz dodać lub usunąć."; +App::$strings["Visible To"] = "Widoczne dla"; +App::$strings["All Connections"] = "Wszystkie połączenia"; +App::$strings["Not found"] = "Nie znaleziono"; +App::$strings["Please refresh page"] = "Odśwież stronę"; +App::$strings["Unknown error"] = "Nieznany błąd"; +App::$strings["Unknown App"] = "Aplikacja nieznana"; +App::$strings["Authorize"] = "Autoryzuj"; +App::$strings["Do you authorize the app %s to access your channel data?"] = "Czy zezwalasz aplikacji %s na dostęp do danych Twojego kanału?"; +App::$strings["Allow"] = "Zezwól"; +App::$strings["Deny"] = "Zabroń"; +App::$strings["Calendar entries imported."] = "Zaimportowano wpisy kalendarza."; +App::$strings["No calendar entries found."] = "Nie znaleziono wpisów kalendarza."; +App::$strings["CardDAV App"] = "Aplikacja CardDAV"; +App::$strings["CalDAV capable addressbook"] = "Książka adresowa z obsługą CalDAV"; +App::$strings["Link to source"] = "Link do źródła"; +App::$strings["Event title"] = "Tytuł wydarzenia"; +App::$strings["Start date and time"] = "Data i godzina rozpoczęcia"; +App::$strings["End date and time"] = "Data i godzina zakończenia"; +App::$strings["Timezone:"] = "Strefa czasowa:"; +App::$strings["Description"] = "Opis"; +App::$strings["Location"] = "Lokalizacja"; +App::$strings["Previous"] = "Poprzedni"; +App::$strings["Next"] = "Nastęþny"; +App::$strings["Today"] = "Dzisiaj"; +App::$strings["Month"] = "Miesiąc"; +App::$strings["Week"] = "Tydzień"; +App::$strings["Day"] = "Dzień"; +App::$strings["List month"] = "Wymień miesiąc"; +App::$strings["List week"] = "Wymień tydzień"; +App::$strings["List day"] = "Wymień dzień"; +App::$strings["More"] = "Więcej"; +App::$strings["Less"] = "Mniej"; +App::$strings["Update"] = "Zaktualizuj"; +App::$strings["Select calendar"] = "Wybierz kalendarz"; +App::$strings["Channel Calendars"] = "Kalendarze kanału"; +App::$strings["CalDAV Calendars"] = "Kalendarze CalDAV"; +App::$strings["Delete"] = "Usuń"; +App::$strings["Delete all"] = "Usuń wszystko"; +App::$strings["Cancel"] = "Anuluj"; +App::$strings["Create"] = "Utwórz"; +App::$strings["Sorry! Editing of recurrent events is not yet implemented."] = "Przepraszamy! Edycja powtarzających się wydarzeń nie została jeszcze zaimplementowana."; +App::$strings["Categories"] = "Kategorie"; +App::$strings["Name"] = "Nazwa"; +App::$strings["Organisation"] = "Organizacja"; +App::$strings["Title"] = "Tytuł"; +App::$strings["Phone"] = "Numer telefonu"; +App::$strings["Email"] = "Adres e-mail"; +App::$strings["Instant messenger"] = "Komunikator internetowy"; +App::$strings["Website"] = "Strona internetowa"; +App::$strings["Address"] = "Adres"; +App::$strings["Note"] = "Uwagi"; +App::$strings["Mobile"] = "Komórka"; +App::$strings["Home"] = "Domowy"; +App::$strings["Work"] = "Praca"; +App::$strings["Add Contact"] = "Dodaj kontakt"; +App::$strings["Add Field"] = "Dodaj pole"; +App::$strings["P.O. Box"] = "Skrytka pocztowa"; +App::$strings["Additional"] = "Dodatkowe informacje"; +App::$strings["Street"] = "Ulica"; +App::$strings["Locality"] = "Miejscowość"; +App::$strings["Region"] = "Region"; +App::$strings["ZIP Code"] = "Kod pocztowy"; +App::$strings["Country"] = "Państwo"; +App::$strings["Default Calendar"] = "Domyślny kalendarz"; +App::$strings["Default Addressbook"] = "Domyślna książka adresowa"; +App::$strings["Authorize application connection"] = "Autoryzuj połączenie aplikacji"; +App::$strings["Return to your app and insert this Security Code:"] = "Wróć do aplikacji i wprowadź ten kod bezpieczeństwa:"; +App::$strings["Please login to continue."] = "Proszę się zalogować, aby kontynuować."; +App::$strings["Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?"] = "Czy chcesz zezwolić tej aplikacji na dostęp do Twoich postów i kontaktów albo tworzenie dla Ciebie nowych postów ?"; +App::$strings["Yes"] = "Tak"; +App::$strings["No"] = "Nie"; +App::$strings["This site is not a directory server"] = "Ta witryna nie jest serwerem katalogów"; +App::$strings["This directory server requires an access token"] = "Ten serwer katalogowy wymaga tokenu dostępu"; +App::$strings["Enter a folder name"] = "Wprowadź nazwę folderu"; +App::$strings["or select an existing folder (doubleclick)"] = "lub wybierz istniejący folder (kliknij dwukrotnie)"; +App::$strings["Save"] = "Zapisz"; +App::$strings["Save to Folder"] = "Zapisz do folderu"; +App::$strings["Event can not end before it has started."] = "Wydarzenie nie może zakończyć się przed rozpoczęciem."; +App::$strings["Unable to generate preview."] = "Nie można wygenerować podglądu."; +App::$strings["Event title and start time are required."] = "Wymaga się wprowadzenie tytułu wydarzenia i godziny rozpoczęcia."; +App::$strings["Event not found."] = "Nie znaleziono wydarzenia."; +App::$strings["event"] = "wydarzenie"; +App::$strings["Edit event title"] = "Edytuj tytuł wydarzenia"; +App::$strings["Required"] = "Wymagane"; +App::$strings["Categories (comma-separated list)"] = "Kategorie (lista rozdzielana przecinkami)"; +App::$strings["Edit Category"] = "Edytuj kategorię"; +App::$strings["Category"] = "Kategoria"; +App::$strings["Edit start date and time"] = "Edytuj datę i godzinę rozpoczęcia"; +App::$strings["Finish date and time are not known or not relevant"] = "Data i godzina zakończenia nie są znane lub nie mają znaczenia"; +App::$strings["Edit finish date and time"] = "Edytuj datę i godzinę zakończenia"; +App::$strings["Finish date and time"] = "Data i godzina zakończenia"; +App::$strings["Adjust for viewer timezone"] = "Dostosuj do strefy czasowej widza"; +App::$strings["Important for events that happen in a particular place. Not practical for global holidays."] = "Ważne dla wydarzeń, które mają miejsce w określonym miejscu. Niepraktyczne na globalne święta."; +App::$strings["Edit Description"] = "Edytuj opis"; +App::$strings["Edit Location"] = "Edytuj lokalizację"; +App::$strings["Preview"] = "Podgląd"; +App::$strings["Permission settings"] = "Ustawienia dostępu"; +App::$strings["Advanced Options"] = "Zaawansowane opcje"; +App::$strings["l, F j"] = "l, F j"; +App::$strings["Edit event"] = "Edytuj wydarzenie"; +App::$strings["Delete event"] = "Usuń wydarzenie"; +App::$strings["Link to Source"] = "Link do źródła"; +App::$strings["calendar"] = "kalendarz"; +App::$strings["Edit Event"] = "Edytuj wydarzenie"; +App::$strings["Create Event"] = "Utwórz wydarzenie"; +App::$strings["Export"] = "Eksport"; +App::$strings["View"] = "Widok"; +App::$strings["Event removed"] = "Wydarzenie usunięte"; +App::$strings["Failed to remove event"] = "Nie udało się usunąć wydarzenia"; +App::$strings["Documentation Search"] = "Przeszukaj dokumentację"; +App::$strings["About"] = "O platformie Hubzilla"; +App::$strings["Members"] = "Dla członków"; +App::$strings["Administrators"] = "Dla administratorów"; +App::$strings["Developers"] = "Dla deweloperów"; +App::$strings["Tutorials"] = "Poradniki"; +App::$strings["\$Projectname Documentation"] = "Dokumentacja \$Projectname"; +App::$strings["Contents"] = "Spis treści"; +App::$strings["Bookmark added"] = "Dodano zakładkę"; +App::$strings["Bookmarks App"] = "Aplikacja Bookmarks"; +App::$strings["Bookmark links from posts and manage them"] = "Dodaj do zakładek linki z postów i zarządzaj nimi"; +App::$strings["My Bookmarks"] = "Moje zakładki"; +App::$strings["My Connections Bookmarks"] = "Moje zakładki połączeń"; +App::$strings["Requested profile is not available."] = "Żądany profil nie jest dostępny."; +App::$strings["Webpages App"] = "Aplikacja Webpages"; +App::$strings["Provide managed web pages on your channel"] = "Udostępnij zarządzane strony internetowe na swoim kanale"; +App::$strings["Import Webpage Elements"] = "Importuj elementy strony internetowej"; +App::$strings["Import selected"] = "Importuj wybrane"; +App::$strings["Export Webpage Elements"] = "Eksportuj elementy strony internetowej"; +App::$strings["Export selected"] = "Eksportuj wybrane"; +App::$strings["Webpages"] = "Witryny internetowe"; +App::$strings["Edit"] = "Edytuj"; +App::$strings["Share"] = "Udostępnij"; +App::$strings["Actions"] = "Akcje"; +App::$strings["Page Link"] = "Link do strony"; +App::$strings["Page Title"] = "Tytuł strony"; +App::$strings["Created"] = "Utworzono"; +App::$strings["Edited"] = "Edytowano"; +App::$strings["Invalid file type."] = "Zły typ pliku."; +App::$strings["Error opening zip file"] = "Błąd podczas otwierania pliku zip"; +App::$strings["Invalid folder path."] = "Nieprawidłowa ścieżka folderu."; +App::$strings["No webpage elements detected."] = "Nie wykryto żadnych elementów strony internetowej."; +App::$strings["Import complete."] = "Import zakończony."; +App::$strings["Profile not found."] = "Nie znaleziono profilu."; +App::$strings["Profile deleted."] = "Profil usunięty."; +App::$strings["Profile-"] = "Profil-"; +App::$strings["New profile created."] = "Utworzono nowy profil."; +App::$strings["Profile unavailable to clone."] = "Profil niedostępny do sklonowania."; +App::$strings["Profile unavailable to export."] = "Profil niedostępny do wyeksportowania."; +App::$strings["Profile Name is required."] = "Wymaga się podania nazwy profilu."; +App::$strings["Marital Status"] = "Stan cywilny"; +App::$strings["Romantic Partner"] = "Partner romantyczny"; +App::$strings["Likes"] = "Polubienia"; +App::$strings["Dislikes"] = "Dezaprobaty"; +App::$strings["Work/Employment"] = "Praca/Zatrudnienie"; +App::$strings["Religion"] = "Religia"; +App::$strings["Political Views"] = "Poglądy polityczny"; +App::$strings["Gender"] = "Płeć"; +App::$strings["Sexual Preference"] = "Prefernecje seksualne"; +App::$strings["Homepage"] = "Strona domowa"; +App::$strings["Interests"] = "Zainteresowania"; +App::$strings["Profile updated."] = "Profil został zaktualizowany."; +App::$strings["Hide your connections list from viewers of this profile"] = "Ukryj swoją listę kontaktów przed przeglądającymi ten profil"; +App::$strings["Edit Profile Details"] = "Edytuj szczegóły profilu"; +App::$strings["View this profile"] = "Zobacz ten profil"; +App::$strings["Edit visibility"] = "Edytuj dostępność"; +App::$strings["Profile Tools"] = "Narzędzia profili"; +App::$strings["Change cover photo"] = "Zmień zdjęcie okładkowe"; +App::$strings["Change profile photo"] = "Zmień zdjęcie profilowe"; +App::$strings["Create a new profile using these settings"] = "Utwórz nowy profil, korzystając z tych ustawień"; +App::$strings["Clone this profile"] = "Sklonuj ten profil"; +App::$strings["Delete this profile"] = "Usuń ten profil"; +App::$strings["Add profile things"] = "Dodaj elementy profilu"; +App::$strings["Personal"] = "Osobisty"; +App::$strings["Relationship"] = "Relacja"; +App::$strings["Miscellaneous"] = "Różne"; +App::$strings["Import profile from file"] = "Importuj profil z pliku"; +App::$strings["Export profile to file"] = "Eksportuj profil do pliku"; +App::$strings["Your gender"] = "Twoja płeć"; +App::$strings["Marital status"] = "Stan cywilny"; +App::$strings["Sexual preference"] = "Preferencje seksualne"; +App::$strings["Profile name"] = "Nazwa profilu"; +App::$strings["This is your default profile."] = "To jest Twój profil domyślny."; +App::$strings["Your full name"] = "Twoje imię i nazwisko lub pełna nazwa"; +App::$strings["Short title/tescription"] = "Krótki tytuł/opis"; +App::$strings["Maximal 190 characters"] = "Maksymalnie 190 znaków"; +App::$strings["Street address"] = "Ulica"; +App::$strings["Locality/City"] = "Miejscowość"; +App::$strings["Region/State"] = "Region/Stan"; +App::$strings["Postal/Zip code"] = "Kod pocztowy"; +App::$strings["Who (if applicable)"] = "Kto (jeśli dotyczy)"; +App::$strings["Examples: cathy123, Cathy Williams, cathy@example.com"] = "Przykłady: jan123, Jan Kowalski, jan@example.com"; +App::$strings["Since (date)"] = "Od (data)"; +App::$strings["Tell us about yourself"] = "Opowiedz nam o sobie"; +App::$strings["Homepage URL"] = "Adres URL strony domowej"; +App::$strings["Hometown"] = "Miejscowość zamieszkania"; +App::$strings["Political views"] = "Poglądy polityczne"; +App::$strings["Religious views"] = "Poglądy religijne"; +App::$strings["Keywords used in directory listings"] = "Słowa kluczowe używane w wykazach katalogów"; +App::$strings["Example: fishing photography software"] = "Przykład: oprogramowanie do fotografii wędkarskiej"; +App::$strings["Musical interests"] = "Zainteresowania muzyczne"; +App::$strings["Books, literature"] = "Ksiązki, literatura"; +App::$strings["Television"] = "Telewizja"; +App::$strings["Film/Dance/Culture/Entertainment"] = "Film/Dance/Culture/Entertainment"; +App::$strings["Hobbies/Interests"] = "Zainteresowania"; +App::$strings["Love/Romance"] = "Miłość/romans"; +App::$strings["School/Education"] = "Edukacja szkolna"; +App::$strings["Contact information and social networks"] = "Informacje kontaktowe i sieci społecznościowe"; +App::$strings["My other channels"] = "Moje inne kanały"; +App::$strings["Communications"] = "Komunikacja"; +App::$strings["Profile Image"] = "Obraz profilowy"; +App::$strings["Edit Profiles"] = "Edytuj profile"; +App::$strings["Create New"] = "Utwórz nowy"; +App::$strings["Nothing to import."] = "Nie ma nic do zaimportowania."; +App::$strings["Unable to download data from old server"] = "Nie można pobrać danych ze starego serwera"; +App::$strings["Imported file is empty."] = "Zaimportowany plik jest pusty."; +App::$strings["Your service plan only allows %d channels."] = "Twój plan usług obejmuje tylko %d kanał(y)/kanałów."; +App::$strings["No channel. Import failed."] = "Brak kanału. Import nieudany."; +App::$strings["Import completed."] = "Import zakończony."; +App::$strings["You must be logged in to use this feature."] = "Trzeba się zalogować, aby korzystać z tej funkcji."; +App::$strings["Import Channel"] = "Importuj kanał"; +App::$strings["Use this form to import an existing channel from a different server/hub. You may retrieve the channel identity from the old server/hub via the network or provide an export file."] = "Użyj tego formularza, aby zaimportować istniejący kanał z innego serwera/huba. Możesz pobrać tożsamość kanału ze starego serwera/huba przez sieć lub dostarczyć plik eksportu."; +App::$strings["File to Upload"] = "Plik do przesłania"; +App::$strings["Or provide the old server/hub details"] = "Lub podaj szczegóły starego serwera/huba"; +App::$strings["Your old identity address (xyz@example.com)"] = "Twój stary adres tożsamości (xyz@example.com)"; +App::$strings["Your old login email address"] = "Twój stary adres e-mail logowania"; +App::$strings["Your old login password"] = "Twoje stare hasło logowania"; +App::$strings["Import a few months of posts if possible (limited by available memory"] = "Zaimportuj posty z kilku miesięcy, jeśli to możliwe (ograniczone dostępną pamięcią"; +App::$strings["For either option, please choose whether to make this hub your new primary address, or whether your old location should continue this role. You will be able to post from either location, but only one can be marked as the primary location for files, photos, and media."] = "W obu przypadkach wybierz, czy chcesz ustawić ten hub jako nowy adres podstawowy, czy też rolę tą powinna pełnić Twoja stara lokalizacja. Będziesz mógł/mogła publikować z dowolnej lokalizacji, ale tylko jedna z nich może być oznaczona jako główna lokalizacja plików, zdjęć i multimediów."; +App::$strings["Make this hub my primary location"] = "Ustaw ten hub ako moją główną lokalizację"; +App::$strings["Move this channel (disable all previous locations)"] = "Przenieś ten kanał (wyłącz wszystkie poprzednie lokalizacje)"; +App::$strings["Use this channel nickname instead of the one provided"] = "Użyj tego pseudonimu kanału zamiast podanego"; +App::$strings["Leave blank to keep your existing channel nickname. You will be randomly assigned a similar nickname if either name is already allocated on this site."] = "Pozostaw puste, aby zachować istniejący pseudonim kanału. Otrzymasz losowo podobny pseudonim, jeśli któryś z nich jest już przydzielony na tej stronie."; +App::$strings["This process may take several minutes to complete. Please submit the form only once and leave this page open until finished."] = "Ten proces może zająć kilka minut. Prześlij formularz tylko raz i pozostaw tę stronę otwartą do zakończenia procedury."; +App::$strings["Like/Dislike"] = "Polub/Dezaprobuj"; +App::$strings["This action is restricted to members."] = "Ta akcja jest ograniczona do członków."; +App::$strings["Please login with your \$Projectname ID or register as a new \$Projectname member to continue."] = "Aby kontynuować, zaloguj się za pomocą ID \$Projectname lub zarejestruj się jako nowy członek \$Projectname."; +App::$strings["Invalid request."] = "Nieprawidłowe żądanie."; +App::$strings["channel"] = "kanał"; +App::$strings["thing"] = "rzecz"; +App::$strings["Channel unavailable."] = "Kanał niedostępny."; +App::$strings["Previous action reversed."] = "Poprzednia czynność została cofnięta."; +App::$strings["photo"] = "zdjecie"; +App::$strings["status"] = "stan"; +App::$strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s polubień %2\$s %3\$s"; +App::$strings["%1\$s doesn't like %2\$s's %3\$s"] = "%1\$s sezaprobat %2\$s %3\$s"; +App::$strings["%1\$s agrees with %2\$s's %3\$s"] = "%1\$s zgadza się z %3\$s dla %2\$s"; +App::$strings["%1\$s doesn't agree with %2\$s's %3\$s"] = "%1\$s nie zgadza się z %3\$s dla %2\$s"; +App::$strings["%1\$s abstains from a decision on %2\$s's %3\$s"] = "%1\$s wstrzymuje się od decyzji w sprawie %3\$s dla %2\$s"; +App::$strings["%1\$s is attending %2\$s's %3\$s"] = "%1\$s uczesticzy %2\$s %3\$s"; +App::$strings["%1\$s is not attending %2\$s's %3\$s"] = "%1\$s nie uczestniczy %2\$s %3\$s"; +App::$strings["%1\$s may attend %2\$s's %3\$s"] = "%1\$s może uczestniczyć %2\$s %3\$s"; +App::$strings["Action completed."] = "Akcja zakończona."; +App::$strings["Thank you."] = "Dziękujemy."; +App::$strings["Could not access contact record."] = "Brak dostępu do rekordu kontaktu."; +App::$strings["Settings updated."] = "Zaktualizowano ustawienia."; +App::$strings["Default Permissions App"] = "Aplikacja Default Permissions"; +App::$strings["Set custom default permissions for new connections"] = "Ustaw niestandardowe uprawnienia domyślne dla nowych połączeń"; +App::$strings["Connection Default Permissions"] = "Domyślne uprawnienia połączenia"; +App::$strings["Apply these permissions automatically"] = "Zastosuj te uprawnienia automatycznie"; +App::$strings["If enabled, connection requests will be approved without your interaction"] = "Jeśli jest włączone, prośby o połączenie będą zatwierdzane bez Twojej interakcji"; +App::$strings["Permission role"] = "Rola uprawnień"; +App::$strings["Loading"] = "Ładowanie"; +App::$strings["Add permission role"] = "Dodaj rolę uprawnień"; +App::$strings["The permissions indicated on this page will be applied to all new connections."] = "Uprawnienia wskazane na tej stronie zostaną zastosowane do wszystkich nowych połączeń."; +App::$strings["Automatic approval settings"] = "Ustawienia automatycznego zatwierdzania"; +App::$strings["inherited"] = "dziedziczone"; +App::$strings["My Settings"] = "Moje ustawienia"; +App::$strings["Individual Permissions"] = "Uprawnienia indywidualne"; +App::$strings["Some individual permissions may have been preset or locked based on your channel type and privacy settings."] = "Niektóre indywidualne uprawnienia mogły zostać wstępnie ustawione lub zablokowane w zależności od typu kanału i ustawień prywatności."; +App::$strings["Layout Name"] = "Nazwa układu"; +App::$strings["Layout Description (Optional)"] = "Opis układu (opcjonalnie)"; +App::$strings["Layouts"] = "Układy"; +App::$strings["Help"] = "Pomoc"; +App::$strings["Comanche page description language help"] = "Pomoc w zakresie języka opisu strony Comanche"; +App::$strings["Layout Description"] = "Opis układu"; +App::$strings["Download PDL file"] = "Pobierz plik PDL"; +App::$strings["Public Stream App"] = "Aplikacja Public Stream"; +App::$strings["The unmoderated public stream of this hub"] = "Niemoderowany strumień publiczny tego huba"; +App::$strings["Reset form"] = "Resetuj formularz"; +App::$strings["Public Stream"] = "Strumień publiczny"; +App::$strings["Private forum"] = "Prywatne forum"; +App::$strings["Public forum"] = "Publiczne forum"; +App::$strings["Privacy group created."] = "Utworzono grupę prywatności."; +App::$strings["Could not create privacy group."] = "Nie udało się utworzyć grupy prywatności."; +App::$strings["Privacy group not found."] = "Nie znaleziono grupy prywatności."; +App::$strings["Privacy group updated."] = "Grupa prywatności została zaktualizowana."; +App::$strings["Privacy Groups App"] = "Aplikacja Privacy Groups"; +App::$strings["Management of privacy groups"] = "Zarządzanie grupami prywatności"; +App::$strings["Privacy Groups"] = "Grupy prywatności"; +App::$strings["Add Group"] = "Dodaj grupę"; +App::$strings["Privacy group name"] = "Nazwa grupy prywatności"; +App::$strings["Members are visible to other channels"] = "Członkowie są widoczni dla innych kanałów"; +App::$strings["Privacy group removed."] = "Grupa prywatności została usunięta."; +App::$strings["Unable to remove privacy group."] = "Nie można usunąć grupy prywatności."; +App::$strings["Privacy Group: %s"] = "Grupa prywatności: %s"; +App::$strings["Privacy group name: "] = "Nazwa grupy prywatności: "; +App::$strings["Delete Group"] = "Usuń grupę"; +App::$strings["Group members"] = "Członkowie grupy"; +App::$strings["Not in this group"] = "Nie w tej grupie"; +App::$strings["Click a channel to toggle membership"] = "Kliknij kanał, aby przełączyć członkostwo"; +App::$strings["Channel removals are not allowed within 48 hours of changing the account password."] = "Usunięcie kanału nie jest dozwolone w ciągu 48 godzin od zmiany hasła do konta."; +App::$strings["Remove This Channel"] = "Usuń ten kanał"; +App::$strings["WARNING: "] = "UWAGA: "; +App::$strings["This channel will be completely removed from the network. "] = "Ten kanał zostanie całkowicie usunięty z sieci. "; +App::$strings["This action is permanent and can not be undone!"] = "Ta akcja jest bezpowrotna i nie można jej cofnąć!"; +App::$strings["Please enter your password for verification:"] = "Wprowadź hasło do weryfikacji:"; +App::$strings["Remove Channel"] = "Usuń kanał"; +App::$strings["App installed."] = "Aplikacja została zainstalowana."; +App::$strings["Malformed app."] = "Nieprawidłowa aplikacja."; +App::$strings["Embed code"] = "Osadzony kod"; +App::$strings["Edit App"] = "Edutuj aplikację"; +App::$strings["Create App"] = "Utwórz aplikację"; +App::$strings["Name of app"] = "Nazwa aplikacji"; +App::$strings["Location (URL) of app"] = "Lokalizacja (URL) aplikacji"; +App::$strings["Photo icon URL"] = "Adres URL ikony zdjęcia"; +App::$strings["80 x 80 pixels - optional"] = "80 x 80 pikseli - opcjonalnie"; +App::$strings["Categories (optional, comma separated list)"] = "Kategorie (opcjonalne, lista rozdzielana przecinkami)"; +App::$strings["Version ID"] = "ID wesji"; +App::$strings["Price of app"] = "Cena aplikacji"; +App::$strings["Location (URL) to purchase app"] = "Lokalizacja (URL) do zakupu aplikacji"; +App::$strings["Channel name changes are not allowed within 48 hours of changing the account password."] = "Zmiana nazwy kanału jest niedozwolona w ciągu 48 godzin od zmiany hasła do konta."; +App::$strings["Reserved nickname. Please choose another."] = "Zarezerwowany pseudonim. Proszę wybrać inny."; +App::$strings["Nickname has unsupported characters or is already being used on this site."] = "Pseudonim zawiera nieobsługiwane znaki lub jest już używany w tym serwisie."; +App::$strings["Change channel nickname/address"] = "Zmień krótką nazwę/adres kanału"; +App::$strings["Any/all connections on other networks will be lost!"] = "Wszystkie połączenia w innych sieciach zostaną utracone!"; +App::$strings["New channel address"] = "Nowy adres kanału"; +App::$strings["Rename Channel"] = "Zmień nazwę kanału"; +App::$strings["Name is required"] = "Wymaga się podania nazwy"; +App::$strings["Key and Secret are required"] = "Wymaga się wprowadzenia klucza i sekretu"; +App::$strings["OAuth Apps Manager App"] = "Aplikacja OAuth Apps Manager"; +App::$strings["OAuth authentication tokens for mobile and remote apps"] = "Tokeny uwierzytelniania OAuth dla aplikacji mobilnych i zdalnych"; +App::$strings["Add application"] = "Dodaj aplikację"; +App::$strings["Name of application"] = "Nazwa aplikacji"; +App::$strings["Consumer Key"] = "Klucz konsumenta"; +App::$strings["Automatically generated - change if desired. Max length 20"] = "Wygenerowane automatycznie - w razie potrzeby zmień. Maksymalna długość 20"; +App::$strings["Consumer Secret"] = "Hasło konsumenta"; +App::$strings["Redirect"] = "Przekierowanie"; +App::$strings["Redirect URI - leave blank unless your application specifically requires this"] = "Identyfikator URI przekierowania - pozostaw puste, chyba że aplikacja tego wymaga"; +App::$strings["Icon url"] = "URL ikony"; +App::$strings["Optional"] = "Opcjonalne"; +App::$strings["Application not found."] = "Aplikacji nie znaleziono."; +App::$strings["Connected OAuth Apps"] = "Połączone aplikacje OAuth"; +App::$strings["Client key starts with"] = "Klucz klienta zaczyna się od"; +App::$strings["No name"] = "Brak nazwy"; +App::$strings["Remove authorization"] = "Usuń autoryzację"; +App::$strings["Token verification failed."] = "Weryfikacja tokena nie powiodła się."; +App::$strings["Email verification resent"] = "Weryfikacja adresu e-mail została wysłana ponownie"; +App::$strings["Unable to resend email verification message."] = "Nie można ponownie wysłać weryfikacyjną wiadomość e-mail."; +App::$strings["Public access denied."] = "Odmowa dostępu publicznego."; +App::$strings["Search"] = "Szukaj"; +App::$strings["Items tagged with: %s"] = "Elementy oznaczone tagiem: %s"; +App::$strings["Search results for: %s"] = "Wyniki wyszukiwania dla: %s"; +App::$strings["Comment approved"] = "Komentarz zatwierdzony"; +App::$strings["Comment deleted"] = "Komentarz usuniety"; +App::$strings["Edit post"] = "Edytuj post"; +App::$strings["Unable to find your hub."] = "Nie można znaleźć Twojego huba."; +App::$strings["Post successful."] = "Opublikowanie powiodło się."; +App::$strings["Channel not found."] = "Nie znaleziono kanału."; +App::$strings["toggle full screen mode"] = "przełącz tryb pełnego ekranu"; +App::$strings["Post not found."] = "Nie znaleziono postu."; +App::$strings["post"] = "post"; +App::$strings["comment"] = "komentarz"; +App::$strings["%1\$s tagged %2\$s's %3\$s with %4\$s"] = "%1\$s oznaczono tagiem %3\$s %2\$s w %4\$s"; +App::$strings["Warning: Database versions differ by %1\$d updates."] = "Ostrzeżenie: wersje baz danych różnią się o %1\$d aktualizacji."; +App::$strings["Import completed"] = "Import zakończony"; +App::$strings["Import Items"] = "Importuj elementy"; +App::$strings["Use this form to import existing posts and content from an export file."] = "Użyj tego formularza, aby zaimportować istniejące posty i treść z pliku eksportu."; +App::$strings["Continue"] = "Kontynuj"; +App::$strings["Premium Channel Setup"] = "Konfiguracja kanału Premium"; +App::$strings["Enable premium channel connection restrictions"] = "Włącz ograniczenia połączeń z kanałem premium"; +App::$strings["Please enter your restrictions or conditions, such as paypal receipt, usage guidelines, etc."] = "Podaj swoje ograniczenia lub warunki, takie jak pokwitowanie PayPal, wytyczne dotyczące użytkowania itp."; +App::$strings["This channel may require additional steps or acknowledgement of the following conditions prior to connecting:"] = "Ten kanał, przed podłączeniem, może wymagać dodatkowych kroków lub potwierdzenia następujących warunków:"; +App::$strings["Potential connections will then see the following text before proceeding:"] = "Potencjalne połączenia zobaczą następujący tekst przed kontynuowaniem:"; +App::$strings["By continuing, I certify that I have complied with any instructions provided on this page."] = "Kontynuując, oświadczam, że postępowałem zgodnie z instrukcjami podanymi na tej stronie."; +App::$strings["(No specific instructions have been provided by the channel owner.)"] = "(Właściciel kanału nie przekazał żadnych szczegółowych instrukcji.)"; +App::$strings["Restricted or Premium Channel"] = "Kanał z ograniczeniami lub premium"; +App::$strings["You have created %1$.0f of %2$.0f allowed channels."] = "Utworzno %1$ .0f z %2$.0f dozwolonych kanałów."; +App::$strings["Your real name is recommended."] = "Zalecane jest podania prawdziwego imienia i nazwiska lub nazwy."; +App::$strings["Examples: \"Bob Jameson\", \"Lisa and her Horses\", \"Soccer\", \"Aviation Group\""] = "Przykłady: \"Bob Jameson\", \"Lisa i jej konie\", \"Piłka nożna\", \"Grupa lotnicza\""; +App::$strings["This will be used to create a unique network address (like an email address)."] = "Zostanie to zastosowane do utworzenia unikalnego adresu sieciowego (podobnego do adresu e-mail)."; +App::$strings["Allowed characters are a-z 0-9, - and _"] = "Dozwolone znaki, to a-z 0-9, - oraz _"; +App::$strings["Channel name"] = "Nazwa kanału"; +App::$strings["Choose a short nickname"] = "Wybierz krótki pseudonim"; +App::$strings["Channel role and privacy"] = "Rola kanału i prywatność"; +App::$strings["Select a channel permission role compatible with your usage needs and privacy requirements."] = "Wybierz rolę uprawnień do kanału, zgodną z Twoimi potrzebami użytkowania i wymaganiami dotyczącymi prywatności."; +App::$strings["Read more about channel permission roles"] = "Przeczytaj więcej o rolach uprawnień do kanału"; +App::$strings["Create a Channel"] = "Utwórz kanał"; +App::$strings["A channel is a unique network identity. It can represent a person (social network profile), a forum (group), a business or celebrity page, a newsfeed, and many other things."] = "Kanał to unikalna tożsamość sieciowa. Może reprezentować osobę (profil sieci społecznościowej), forum (grupę), stronę biznesową lub celebrycką, kanał informacyjny i wiele innych rzeczy."; +App::$strings["or import an existing channel from another location."] = "lub zaimportuj istniejący kanał z innej lokalizacji."; +App::$strings["Validate"] = "Zalegalizuj"; +App::$strings["Available Apps"] = "Dostępne aplikacje"; +App::$strings["Installed Apps"] = "Zainstalowane aplikacje"; +App::$strings["Manage Apps"] = "Zarządzaj aplikacjami"; +App::$strings["Create Custom App"] = "Utwórz własną aplikację"; +App::$strings["Account removals are not allowed within 48 hours of changing the account password."] = "Usunięcie konta nie jest dozwolone w ciągu 48 godzin od zmiany hasła do konta."; +App::$strings["Remove This Account"] = "Usuń to konto"; +App::$strings["This account and all its channels will be completely removed from the network. "] = "To konto i wszystkie jego kanały zostaną całkowicie usunięte z sieci. "; +App::$strings["Remove Account"] = "Usuń konto"; +App::$strings["Deprecated!"] = "Przestarzałe!"; +App::$strings["Item not found."] = "Nie znaleziono elementu."; +App::$strings["File not found."] = "Nie znaleziono pliku."; +App::$strings["Permission Denied."] = "Odmowa dostępu."; +App::$strings["Edit file permissions"] = "Edytuj uprawnienia do plików"; +App::$strings["Permissions"] = "Uprawnienia"; +App::$strings["Set/edit permissions"] = "Ustaw/edytuj uprawnienia"; +App::$strings["Include all files and sub folders"] = "Uwzględnij wszystkie pliki i podfoldery"; +App::$strings["Return to file list"] = "Wróć do listy plików"; +App::$strings["Copy/paste this code to attach file to a post"] = "Skopiuj/wklej ten kod, aby dołączyć plik do postu"; +App::$strings["Copy/paste this URL to link file from a web page"] = "Skopiuj/wklej ten adres URL, aby zlinkować plik na stron internetowej"; +App::$strings["Share this file"] = "Udostępnij ten plik"; +App::$strings["Show URL to this file"] = "Pokaż adres URL do tego pliku"; +App::$strings["Show in your contacts shared folder"] = "Pokaż w folderze udostępnionym kontaktów"; +App::$strings["Item not found"] = "Nie znaleziono elementu"; +App::$strings["Insert web link"] = "Wstaw link internetowy"; +App::$strings["Title (optional)"] = "Tytuł (opcjonalnie)"; +App::$strings["Edit Card"] = "Edytuj kartę"; +App::$strings["No connections."] = "Brak połączeń."; +App::$strings["Accepts"] = "Akceptacje"; +App::$strings["Comments"] = "Komentarze"; +App::$strings["Stream items"] = "Elementy strumienia"; +App::$strings["Wall posts"] = "Ściana postów"; +App::$strings["Nothing"] = "Nic"; +App::$strings["Visit %s's profile [%s]"] = "Odwiedź profil %s [%s]"; +App::$strings["View Connections"] = "Pokaż połączenia"; +App::$strings["Name and Secret are required"] = "Wymagane jest ustawienie imienia i sekretu"; +App::$strings["OAuth2 Apps Manager App"] = "Aplikacja OAuth2 Apps Manager"; +App::$strings["OAuth2 authenticatication tokens for mobile and remote apps"] = "Tokeny uwierzytelniające OAuth2 dla aplikacji mobilnych i zdalnych"; +App::$strings["Add OAuth2 application"] = "Dodaj aplikację OAuth2"; +App::$strings["Grant Types"] = "Rodzaje dofinansowań"; +App::$strings["leave blank unless your application sepcifically requires this"] = "pozostaw puste, chyba że Twoja aplikacja wyraźnie tego wymaga"; +App::$strings["Authorization scope"] = "Zakres uprawnień"; +App::$strings["OAuth2 Application not found."] = "Nie znaleziono aplikacji OAuth2."; +App::$strings["leave blank unless your application specifically requires this"] = "pozostaw puste, chyba że Twoja aplikacja wyraźnie tego wymaga"; +App::$strings["Connected OAuth2 Apps"] = "Aplikacje połączeń OAuth2"; +App::$strings["Profile Unavailable."] = "Profil niedostępny."; +App::$strings["Wiki App"] = "Aplikacja Wiki"; +App::$strings["Provide a wiki for your channel"] = "Udostępnij wiki dla swojego kanału"; +App::$strings["Invalid channel"] = "Zły kanał"; +App::$strings["Error retrieving wiki"] = "Błąd podczas pobierania wiki"; +App::$strings["Error creating zip file export folder"] = "Błąd podczas tworzenia folderu eksportu pliku ZIP"; +App::$strings["Error downloading wiki: "] = "Błąd podczas pobierania wiki: "; +App::$strings["Wikis"] = "Wiki"; +App::$strings["Download"] = "Pobierz"; +App::$strings["Wiki name"] = "Nazwa wiki"; +App::$strings["Content type"] = "Rodzaj treści"; +App::$strings["Markdown"] = "Markdown"; +App::$strings["BBcode"] = "BBcode"; +App::$strings["Text"] = "Text"; +App::$strings["Type"] = "Rodzaj"; +App::$strings["Any type"] = "Dwolny rodzaj"; +App::$strings["Lock content type"] = "Zablokuj rodzaj treści"; +App::$strings["Create a status post for this wiki"] = "Utwórz post statusu dla tego wiki"; +App::$strings["Edit Wiki Name"] = "Edytuj nazwę wiki"; +App::$strings["Wiki not found"] = "Nie znaleziono wiki"; +App::$strings["Rename page"] = "Zień nazwę strony"; +App::$strings["Error retrieving page content"] = "Błąd podczas pobierania treści strony"; +App::$strings["New page"] = "Nowa strona"; +App::$strings["Revision Comparison"] = "Porównanie wersji"; +App::$strings["Revert"] = "Odwróć"; +App::$strings["Short description of your changes (optional)"] = "Krótki opis zmian (opcjonalnie)"; +App::$strings["Source"] = "Źródło"; +App::$strings["New page name"] = "Nowa nazwa strony"; +App::$strings["Embed image from photo albums"] = "Osadź obraz z albumów fotograficznych"; +App::$strings["Embed an image from your albums"] = "Osadź obraz ze swoich albumów"; +App::$strings["OK"] = "Dobrze"; +App::$strings["Choose images to embed"] = "Wybierz zdjęcie do osadzenia"; +App::$strings["Choose an album"] = "Wybierz album"; +App::$strings["Choose a different album"] = "Wybierz inny album"; +App::$strings["Error getting album list"] = "Błąd podczas pobierania listy albumów"; +App::$strings["Error getting photo link"] = "Błąd podczas pobierania linku do zdjęcia"; +App::$strings["Error getting album"] = "Błąd podczas pobierania albumu"; +App::$strings["History"] = "Historia"; +App::$strings["Error creating wiki. Invalid name."] = "Błąd podczas tworzenia wiki. nieprawidłowa nazwa."; +App::$strings["A wiki with this name already exists."] = "Wiki o tej nazwie już istnieje."; +App::$strings["Wiki created, but error creating Home page."] = "Utworzono wiki, ale podczas tworzenia strony głównej wystąpił błąd."; +App::$strings["Error creating wiki"] = "Błąd podczas tworzenia wiki"; +App::$strings["Error updating wiki. Invalid name."] = "Błąd podczas aktualizowania wiki. Błędna nazwa."; +App::$strings["Error updating wiki"] = "Błąd podczas aktualizowania wiki"; +App::$strings["Wiki delete permission denied."] = "Odmowa pozwolenia na usunięcie Wiki."; +App::$strings["Error deleting wiki"] = "Błąd podczas usuwania wiki"; +App::$strings["New page created"] = "Utworzono nową stronę"; +App::$strings["Cannot delete Home"] = "Nie można usunąć strony głównej"; +App::$strings["Current Revision"] = "Bieżąca wersja"; +App::$strings["Selected Revision"] = "Wybrana wersja"; +App::$strings["You must be authenticated."] = "Trzeba być uwierzytelnionym."; +App::$strings["Block Name"] = "Nazwa bloku"; +App::$strings["Blocks"] = "Bloki"; +App::$strings["Block Title"] = "Tytuł bloku"; +App::$strings["Entry censored"] = "Wpis ocenzurowany"; +App::$strings["Entry uncensored"] = "Wpis nieocenzurowany"; +App::$strings["Location not found."] = "Nie znaleziono lokalizacjid."; +App::$strings["Location lookup failed."] = "Wyszukiwanie lokalizacji nie powiodło się."; +App::$strings["Please select another location to become primary before removing the primary location."] = "Przed usunięciem lokalizacji podstawowej wybierz inną lokalizację jako główną."; +App::$strings["Syncing locations"] = "Synchronizuję lokalizacje"; +App::$strings["No locations found."] = "Nie znaleziono żadnych lokalizacji."; +App::$strings["Manage Channel Locations"] = "Zarządzaj lokalizacjami kanałów"; +App::$strings["Primary"] = "Podstawowy"; +App::$strings["Drop"] = "Upuść"; +App::$strings["Sync Now"] = "Synchronizuj teraz"; +App::$strings["Please wait several minutes between consecutive operations."] = "Poczekaj kilka minut między kolejnymi operacjami."; +App::$strings["When possible, drop a location by logging into that website/hub and removing your channel."] = "Jeśli to możliwe, upuść lokalizację, logując się do tego huba i usuwając swój kanał."; +App::$strings["Use this form to drop the location if the hub is no longer operating."] = "Użyj tego formularza, aby usunąć lokalizację, jeśli hub już nie działa."; +App::$strings["Away"] = "Z dala"; +App::$strings["Online"] = "Na linii"; +App::$strings["Photos"] = "Zdjęcia"; +App::$strings["Files"] = "Pliki"; +App::$strings["Could not locate selected profile."] = "Nie udało się znaleźć wybranego profilu."; +App::$strings["Connection updated."] = "Zaktualizowano połączenie."; +App::$strings["Failed to update connection record."] = "Nie udało się zaktualizować rekordu połączenia."; +App::$strings["is now connected to"] = "jest teraz połączony z"; +App::$strings["Could not access address book record."] = "Nie można uzyskać dostępu do rekordu książki adresowej."; +App::$strings["Refresh failed - channel is currently unavailable."] = "Odświeżenie nie powiodło się - kanał jest obecnie niedostępny."; +App::$strings["Unable to set address book parameters."] = "Nie można ustawić parametrów książki adresowej."; +App::$strings["Connection has been removed."] = "Połączenie zostało usunięte."; +App::$strings["View Profile"] = "Wyświetl profil"; +App::$strings["View %s's profile"] = "Wyświetl profil %s"; +App::$strings["Refresh Permissions"] = "Odśwież uprawnienia"; +App::$strings["Fetch updated permissions"] = "Pobierz zaktualizowane uprawnienia"; +App::$strings["Refresh Photo"] = "Odśwież zdjęcie"; +App::$strings["Fetch updated photo"] = "Pobierz zaktualizowane zdjęcie"; +App::$strings["Recent Activity"] = "Ostatnia aktywność"; +App::$strings["View recent posts and comments"] = "Wyświetl najnowsze posty i komentarze"; +App::$strings["Unblock"] = "Odblokuj"; +App::$strings["Block"] = "Zablokuj"; +App::$strings["Block (or Unblock) all communications with this connection"] = "Zablokuj (lub odblokuj) całą komunikację z tym połączeniem"; +App::$strings["This connection is blocked!"] = "To połączenie jest zablokowane!"; +App::$strings["Unignore"] = "Nie ignoruj"; +App::$strings["Ignore"] = "Ignoruj"; +App::$strings["Ignore (or Unignore) all inbound communications from this connection"] = "Ignoruj (lub przywróć) całą komunikację przychodzącą z tego połączenia"; +App::$strings["This connection is ignored!"] = "To połączenie jest ignorowane!"; +App::$strings["Unarchive"] = "Przywróć z archiwum"; +App::$strings["Archive"] = "Archiwizuj"; +App::$strings["Archive (or Unarchive) this connection - mark channel dead but keep content"] = "Archiwizuj (lub przywróć) to połączenie - zaznacz kanał jako martwy, ale zachowaj zawartość"; +App::$strings["This connection is archived!"] = "To połączenie zostało zarchiwizowane!"; +App::$strings["Unhide"] = "Odkryj"; +App::$strings["Hide"] = "Ukryj"; +App::$strings["Hide or Unhide this connection from your other connections"] = "Ukryj lub odkryj to połączenie przed innymi kontaktami"; +App::$strings["This connection is hidden!"] = "To połączenie jest ukryte!"; +App::$strings["Delete this connection"] = "Usuń to połączenie"; +App::$strings["Fetch Vcard"] = "Pobierz Vcard"; +App::$strings["Fetch electronic calling card for this connection"] = "Pobierz elektroniczną kartę telefoniczną dla tego połączenia"; +App::$strings["Open Individual Permissions section by default"] = "Otwórz domyślnie sekcję Uprawnienia indywidualne"; +App::$strings["Affinity"] = "Koligacja"; +App::$strings["Open Set Affinity section by default"] = "Otwieraj domyślnie sekcję Ustaw koligację"; +App::$strings["Me"] = "Ja"; +App::$strings["Family"] = "Rodzina"; +App::$strings["Friends"] = "Przyjaciele"; +App::$strings["Acquaintances"] = "Znajomi"; +App::$strings["All"] = "Wszyscy"; +App::$strings["Filter"] = "Filtr"; +App::$strings["Open Custom Filter section by default"] = "Otwieraj domyślnie sekcję Filtr niestandardowy"; +App::$strings["Approve this connection"] = "Zatwierdź to połączenie"; +App::$strings["Accept connection to allow communication"] = "Zaakceptuj połączenie, aby umożliwić komunikację"; +App::$strings["Set Affinity"] = "Ustaw skoligacenie"; +App::$strings["Set Profile"] = "Ustaw profil"; +App::$strings["Set Affinity & Profile"] = "Ustaw skoligacenie i profil"; +App::$strings["This connection is unreachable from this location."] = "To połączenie jest nieosiągalne z tej lokalizacji."; +App::$strings["This connection may be unreachable from other channel locations."] = "To połączenie może być nieosiągalne z innych lokalizacji kanału."; +App::$strings["Location independence is not supported by their network."] = "Niezależność lokalizacji nie jest obsługiwana przez ich sieć."; +App::$strings["This connection is unreachable from this location. Location independence is not supported by their network."] = "To połączenie jest nieosiągalne z tej lokalizacji. Niezależność lokalizacji nie jest obsługiwana przez ich sieć."; +App::$strings["Connection: %s"] = "Połączenie: %s"; +App::$strings["Connection requests will be approved without your interaction"] = "Prośby o połączenie zostaną zatwierdzone bez Twojej interakcji"; +App::$strings["This connection's primary address is"] = "Podstawowy adres tego połączenia to"; +App::$strings["Available locations:"] = "Dostępne lokalizacje:"; +App::$strings["Connection Tools"] = "Narzędzia połączeń"; +App::$strings["Slide to adjust your degree of friendship"] = "Przesuń, aby dostosować stopień przyjaźni"; +App::$strings["Rating"] = "Ocena"; +App::$strings["Slide to adjust your rating"] = "Przesuń, aby dostosować swoją ocenę"; +App::$strings["Optionally explain your rating"] = "Ewentualnie wyjaśnij swoją ocenę"; +App::$strings["Custom Filter"] = "Własny filtr"; +App::$strings["Only import posts with this text"] = "Importuj tylko posty z tym tekstem"; +App::$strings["words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts"] = "słowa po jednym w wierszu lub #tags lub /patterns/ lub lang=xx, pozostaw puste, aby zaimportować wszystkie posty"; +App::$strings["Do not import posts with this text"] = "Nie importuj postów z tym tekstem"; +App::$strings["This information is public!"] = "Ta informacja jest publiczna!"; +App::$strings["Connection Pending Approval"] = "Połączenie oczekujące na zatwierdzenie"; +App::$strings["Please choose the profile you would like to display to %s when viewing your profile securely."] = "Wybierz profil, który chcesz wyświetlić dla %s, podczas bezpiecznego przeglądania swojego profilu."; +App::$strings["Their Settings"] = "Ich ustawienia"; +App::$strings["Some permissions may be inherited from your channel's privacy settings, which have higher priority than individual settings. You can not change those settings here."] = "Niektóre uprawnienia mogą być dziedziczone z ustawień prywatności Twojego kanału, które mają wyższy priorytet niż indywidualne ustawienia. Nie możesz tutaj zmienić tych ustawień."; +App::$strings["Some permissions may be inherited from your channel's privacy settings, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes."] = "Niektóre uprawnienia mogą być dziedziczone z ustawień prywatności Twojego kanału, te które mają wyższy priorytet niż indywidualne ustawienia. Możesz zmienić te ustawienia tutaj, ale nie będą one miały żadnego wpływu, chyba że odziedziczone ustawienie ulegnie zmianie."; +App::$strings["Last update:"] = "Ostatnia aktualizacja:"; +App::$strings["Details"] = "Szczegóły"; +App::$strings["Image uploaded but image cropping failed."] = "Obraz został przesłany, ale przycinanie obrazu nie powiodło się."; +App::$strings["Profile Photos"] = "Zdjęcia profilowe"; +App::$strings["Image resize failed."] = "Zmiana rozmiaru obrazu nie powiodła się."; +App::$strings["Shift-reload the page or clear browser cache if the new photo does not display immediately."] = "Shift-przeładuj stronę lub wyczyść pamięć podręczną przeglądarki, jeśli nowe zdjęcie nie zostanie wyświetlone od razu."; +App::$strings["Unable to process image"] = "Nie można przetworzyć obrazu"; +App::$strings["Image upload failed."] = "Przesyłanie obrazu nie powiodło się."; +App::$strings["Unable to process image."] = "Nie można przetworzyć obrazu."; +App::$strings["Photo not available."] = "Zdjęcie nie jest dostępne."; +App::$strings["Your default profile photo is visible to anybody on the internet. Profile photos for alternate profiles will inherit the permissions of the profile"] = "Twoje domyślne zdjęcie profilowe jest widoczne dla każdego w internecie. Zdjęcia profilowe dla profili alternatywnych odziedziczą uprawnienia profilu"; +App::$strings["Your profile photo is visible to anybody on the internet and may be distributed to other websites."] = "Twoje zdjęcie profilowe jest widoczne dla każdego w internecie i może być rozpowszechniane na innych stronach internetowych."; +App::$strings["Upload File:"] = "Przesłanie pliku:"; +App::$strings["Select a profile:"] = "Wybierz profil:"; +App::$strings["Use Photo for Profile"] = "Użyj zdjęcia do profilu"; +App::$strings["Change Profile Photo"] = "Zmień zdjęcie profilowe"; +App::$strings["Use"] = "Użyj"; +App::$strings["Upload"] = "Prześlij"; +App::$strings["Remove"] = "Usuń"; +App::$strings["Use a photo from your albums"] = "Użyj zdjęcia ze swoich albumów"; +App::$strings["Select existing photo"] = "Wybierz istniejące zdjęcie"; +App::$strings["Crop Image"] = "Przytnij zdjęcie"; +App::$strings["Please adjust the image cropping for optimum viewing."] = "Dostosuj kadrowanie obrazu, aby uzyskać optymalne wyświetlanie."; +App::$strings["Done Editing"] = "Zakończono edycję"; +App::$strings["Files: shared with me"] = "Pliki: udostępnione mi"; +App::$strings["NEW"] = "NOWY"; +App::$strings["Size"] = "Rozmiar"; +App::$strings["Last Modified"] = "Ostatnio zmodyfikowane"; +App::$strings["Remove all files"] = "Usuń wszystkie pliki"; +App::$strings["Remove this file"] = "Usuń ten plik"; +App::$strings["Edit Layout"] = "Edytuj układ"; +App::$strings["Create a new channel"] = "Utwórz nowy kanał"; +App::$strings["Channel Manager"] = "Menadżer kanałów"; +App::$strings["Current Channel"] = "Bieżący kanał"; +App::$strings["Switch to one of your channels by selecting it."] = "Przełącz się na jeden ze swoich kanałów, wybierając go."; +App::$strings["Default Channel"] = "Domyślny kanał"; +App::$strings["Make Default"] = "Ustaw jako domyślny"; +App::$strings["%d new messages"] = "%d nowych wiadomości"; +App::$strings["%d new introductions"] = "%d nowych wprowadzeń"; +App::$strings["Delegated Channel"] = "Deleguj kanał"; +App::$strings["Connection added."] = "Dodano połączenie."; +App::$strings["Unable to locate original post."] = "Nie można znaleźć oryginalnego postu."; +App::$strings["Empty post discarded."] = "Pusty post został odrzucony."; +App::$strings["Duplicate post suppressed."] = "Powielony post został wyłączony."; +App::$strings["System error. Post not saved."] = "Błąd systemu. Post nie został zapisany."; +App::$strings["Your comment is awaiting approval."] = "Twój komentarz oczekuje na zatwierdzenie."; +App::$strings["Unable to obtain post information from database."] = "Nie można uzyskać z bazy danych informacji o tym poście."; +App::$strings["You have reached your limit of %1$.0f top level posts."] = "Osiągnięty został limit %1$.0f postów najwyższego poziomu."; +App::$strings["You have reached your limit of %1$.0f webpages."] = "Osiągnięty został limit %1$.0f stron internetowych."; +App::$strings["Website:"] = "Serwis internetowy:"; +App::$strings["Remote Channel [%s] (not yet known on this site)"] = "Kanał zdalny [% s] (jeszcze nieznany w tym serwisie)"; +App::$strings["Rating (this information is public)"] = "Ocena (ta informacja jest publiczna)"; +App::$strings["Optionally explain your rating (this information is public)"] = "Ewentualnie wyjaśnij swoją ocenę (ta informacja jest publiczna)"; +App::$strings["Invalid item."] = "Nieprawidłowy element."; +App::$strings["Page not found."] = "Nie znaleziono strony."; +App::$strings["Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; +App::$strings["Xchan Lookup"] = "Wyszukiwanie xchan"; +App::$strings["Lookup xchan beginning with (or webbie): "] = "Wyszukaj xchan (lub webbie) zaczynając od: "; +App::$strings["Not found."] = "Nie znaleziono."; +App::$strings["Some blurb about what to do when you're new here"] = "Kilka uwag o tym, co robisz, gdy jesteś tu nowy"; +App::$strings["%1\$s is following %2\$s's %3\$s"] = "%1\$s obserwuje %3\$s %2\$s"; +App::$strings["%1\$s stopped following %2\$s's %3\$s"] = "%1\$s przestał obserwować %3\$s %2\$s"; +App::$strings["Please login."] = "Proszę się zalogować."; +App::$strings["Edit Block"] = "Edytuj blok"; +App::$strings["webpage"] = "strona internetowa"; +App::$strings["block"] = "blok"; +App::$strings["layout"] = "układ"; +App::$strings["menu"] = "menu"; +App::$strings["%s element installed"] = "Element %s zainstalowany"; +App::$strings["%s element installation failed"] = "Instalacja elementu %s nie powiodła się"; +App::$strings["Public Hubs"] = "Huby publiczne"; +App::$strings["The listed hubs allow public registration for the \$Projectname network. All hubs in the network are interlinked so membership on any of them conveys membership in the network as a whole. Some hubs may require subscription or provide tiered service plans. The hub itself may provide additional details."] = "Wymienione huby umożliwiają publiczną rejestrację w sieci \$Projectname. Wszystkie huby w sieci są ze sobą połączone, więc członkostwo w którymkolwiek z nich oznacza członkostwo w całej sieci. Niektóre huby mogą wymagać subskrypcji lub oferować warstwowe plany usług. Sam hub może podać dodatkowe szczegóły."; +App::$strings["Hub URL"] = "Adres URL huba"; +App::$strings["Access Type"] = "Typ dostępu"; +App::$strings["Registration Policy"] = "Zasady rejestracji"; +App::$strings["Stats"] = "Statystyki"; +App::$strings["Software"] = "Oprogramowanie"; +App::$strings["Ratings"] = "Oceny"; +App::$strings["Rate"] = "Ocena"; +App::$strings["You must be logged in to see this page."] = "Musisz być zalogowany, aby zobaczyć tę stronę."; +App::$strings["Chatrooms App"] = "Aplikacja Chatrooms"; +App::$strings["Access Controlled Chatrooms"] = "Dostęp do kontrolowanych czatów"; +App::$strings["Room not found"] = "Nie znaleziono pokoju"; +App::$strings["Leave Room"] = "Opuść pokój"; +App::$strings["Delete Room"] = "Usuń pokój"; +App::$strings["I am away right now"] = "Nie ma mnie teraz"; +App::$strings["I am online"] = "Jestem dostępny"; +App::$strings["Bookmark this room"] = "Zaznacz ten pokój"; +App::$strings["Please enter a link URL:"] = "Proszę wprowadzić adres URL linku:"; +App::$strings["Encrypt text"] = "Szyfruj tekst"; +App::$strings["New Chatroom"] = "Nowy czat"; +App::$strings["Chatroom name"] = "Nazwa czatu"; +App::$strings["Expiration of chats (minutes)"] = "Wygaśnięcie czatów (minuty)"; +App::$strings["%1\$s's Chatrooms"] = "Czaty %1\$s"; +App::$strings["No chatrooms available"] = "Brak dostępnych czatów"; +App::$strings["Expiration"] = "Wygaśnięcie"; +App::$strings["min"] = "min"; +App::$strings["Channel Export App"] = "Aplikacja Channel Export"; +App::$strings["Export your channel"] = "Wyeksportuj swój kanał"; +App::$strings["Export Channel"] = "Eksport kanału"; +App::$strings["Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content."] = "Wyeksportuj do pliku podstawowe informacje o kanale. Działa to jako kopia zapasowa połączeń, uprawnień, profilu i podstawowych danych, których można użyć do zaimportowania danych do nowego huba, ale nie zawiera treści."; +App::$strings["Export Content"] = "Eksport treści"; +App::$strings["Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin."] = "Wyeksportuj informacje o kanale i najnowsze treści do kopii zapasowej JSON, którą można przywrócić lub zaimportować do innego huba. Tworzy to kopie zapasowe wszystkich połączeń, uprawnień, danych profilu i kilku miesięcy postów. Ten plik może być BARDZO duży. Prosimy o cierpliwość - rozpoczęcie pobierania może zająć kilka minut."; +App::$strings["Export your posts from a given year."] = "Eksportuj swoje posty z danego roku."; +App::$strings["You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range."] = "Można także wyeksportować swoje posty i rozmowy z określonego rok lub miesiąca. Dostosuj datę na pasku adresu przeglądarki, aby wybrać inne daty. Jeśli eksport się nie powiedzie (prawdopodobnie z powodu wyczerpania pamięci w serwera huba), spróbuj ponownie, wybierając bardziej ograniczony zakres dat."; +App::$strings["To select all posts for a given year, such as this year, visit %2\$s"] = "Aby wybrać wszystkie posty z danego roku, na przykład tego roku, odwiedź %2\$s"; +App::$strings["To select all posts for a given month, such as January of this year, visit %2\$s"] = "Aby wybrać wszystkie posty z danego miesiąca, np. stycznia tego roku, odwiedź %2\$s"; +App::$strings["These content files may be imported or restored by visiting %2\$s on any site containing your channel. For best results please import or restore these in date order (oldest first)."] = "Te pliki treści można zaimportować lub przywrócić, odwiedzając stronę %2\$s w dowolnym serwisie zawierającym Twój kanał. Aby uzyskać najlepsze wyniki, zaimportuj lub przywróć je w kolejności (od najstarszych)."; +App::$strings["No valid account found."] = "Nie znaleziono prawidłowego konta."; +App::$strings["Password reset request issued. Check your email."] = "Wysłano prośbę o zresetowanie hasła. Sprawdź swoją skrzynkę e-mail."; +App::$strings["Site Member (%s)"] = "Członek serwisu (%s)"; +App::$strings["Password reset requested at %s"] = "Zresetowano hasło na %s"; +App::$strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "Nie można zweryfikować żądania. (Możliwe, że zostało już przesłane). Resetowanie hasła nie powiodło się."; +App::$strings["Password Reset"] = "Resetowanie hasła"; +App::$strings["Your password has been reset as requested."] = "Twoje hasło zostało zresetowane zgodnie z żądaniem."; +App::$strings["Your new password is"] = "Twoje nowe hasło to"; +App::$strings["Save or copy your new password - and then"] = "Zapisz lub skopiuj nowe hasło - a następnie"; +App::$strings["click here to login"] = "kliknij tutaj aby się zalogować"; +App::$strings["Your password may be changed from the Settings page after successful login."] = "Twoje hasło może zostać zmienione na stronie Ustawienia po pomyślnym zalogowaniu."; +App::$strings["Your password has changed at %s"] = "Twoje hasło zostało zmienione na %s"; +App::$strings["Forgot your Password?"] = "Zapomniałeś hasła?"; +App::$strings["Enter your email address and submit to have your password reset. Then check your email for further instructions."] = "Wpisz swój adres e-mail i prześlij, aby zresetować hasło. Następnie sprawdź swoja skrzynkę e-mail, aby uzyskać dalsze instrukcje."; +App::$strings["Email Address"] = "Adres e-mail"; +App::$strings["Poll not found."] = "Nie znaleziono ankiety."; +App::$strings["Invalid response."] = "Nieprawidłowa odpowiedź."; +App::$strings["Response submitted. Updates may not appear instantly."] = "Odpowiedź przesłana. Aktualizacje mogą nie pojawiać się natychmiast."; +App::$strings["sent you a private message"] = "wysłał Ci prywatną wiadomość"; +App::$strings["added your channel"] = "dodał Twój kanał"; +App::$strings["requires approval"] = "wymaga zatwierdzenia"; +App::$strings["g A l F d"] = "g A l F d"; +App::$strings["[today]"] = "[dzisiaj]"; +App::$strings["posted an event"] = "opublikował wydarzenie"; +App::$strings["shared a file with you"] = "udostępnił Ci plik"; +App::$strings["You must enable javascript for your browser to be able to view this content."] = "Aby przeglądać te treści, musisz włączyć obsługę JavaScript w swojej przeglądarce."; +App::$strings["Article"] = "Artykuł"; +App::$strings["Item has been removed."] = "Element został usunięty."; +App::$strings["Accounts"] = "Konta"; +App::$strings["Blocked accounts"] = "Zablokowane konta"; +App::$strings["Expired accounts"] = "Wygasłe konta"; +App::$strings["Expiring accounts"] = "Wygasające konta"; +App::$strings["Channels"] = "Kanały"; +App::$strings["Message queues"] = "Kolejki wiadomości"; +App::$strings["Your software should be updated"] = "Twoje oprogramowanie powinno zostać zaktualizowane"; +App::$strings["Administration"] = "Administracja"; +App::$strings["Summary"] = "Posumowanie"; +App::$strings["Registered accounts"] = "Zarejestrowane konta"; +App::$strings["Pending registrations"] = "Rejestracja oczekująca"; +App::$strings["Registered channels"] = "Zarejestrowane kanały"; +App::$strings["Active addons"] = "Aktywne dodatki"; +App::$strings["Version"] = "Wersja"; +App::$strings["Repository version (master)"] = "Wersja repozytorium (master)"; +App::$strings["Repository version (dev)"] = "Wersja repozytorium (dev)"; +App::$strings["Page owner information could not be retrieved."] = "Nie można pobrać informacji o właścicielu strony."; +App::$strings["Album not found."] = "Nie znaleziono albumu."; +App::$strings["Delete Album"] = "Usuń album"; +App::$strings["Delete Photo"] = "Usuń zdjęcie"; +App::$strings["No photos selected"] = "Nie wybrano zdjęć"; +App::$strings["Access to this item is restricted."] = "Dostęp do tego elementu jest ograniczony."; +App::$strings["%1$.2f MB of %2$.2f MB photo storage used."] = "Wykorzystane miejsce na zdjęcia: %1$.2f MB z %2$.2f MB."; +App::$strings["%1$.2f MB photo storage used."] = "Wykorzystane miejsce na zdjęcia: %1$.2f MB."; +App::$strings["Upload Photos"] = "Prześlij zdjęcia"; +App::$strings["Enter an album name"] = "Wpisz nazwę albumu"; +App::$strings["or select an existing album (doubleclick)"] = "lub wybierz istniejący album (podwójne kliknięcie)"; +App::$strings["Create a status post for this upload"] = "Utwórz post o stanie tego przesyłania"; +App::$strings["Description (optional)"] = "Opis (opcjonalnie)"; +App::$strings["Show Newest First"] = "Pokaż najpierw najnowsze"; +App::$strings["Show Oldest First"] = "Pokaż najpierw najstarsze"; +App::$strings["View Photo"] = "Zobacz zdjęcie"; +App::$strings["Unknown"] = "Nieznane"; +App::$strings["Edit Album"] = "Edytuj album"; +App::$strings["Add Photos"] = "Dodaj zdjęcia"; +App::$strings["Permission denied. Access to this item may be restricted."] = "Odmowa dostęþu. Dostęp do tej pozycji może być ograniczony."; +App::$strings["Photo not available"] = "Zdjęcie niedostępne"; +App::$strings["Use as profile photo"] = "Użyj jako zdjęcie profilowe"; +App::$strings["Use as cover photo"] = "Użyj jako zdjęcia okładkowe"; +App::$strings["Private Photo"] = "Zdjęcie prywatne"; +App::$strings["View Full Size"] = "Zobacz pełny rozmiar"; +App::$strings["Edit photo"] = "Edutuj zdjęcie"; +App::$strings["Rotate CW (right)"] = "Obróć w prawo"; +App::$strings["Rotate CCW (left)"] = "Obróć w lewo"; +App::$strings["Move photo to album"] = "Przenieś zdjęcie do albumu"; +App::$strings["Enter a new album name"] = "Wpisz nową nazwę albumu"; +App::$strings["or select an existing one (doubleclick)"] = "lub wybierz istniejący (podwójne kliknięcie)"; +App::$strings["Add a Tag"] = "Dodaj tag"; +App::$strings["Example: @bob, @Barbara_Jensen, @jim@example.com"] = "Przykład: @bob, @Barbara_Jensen, @jim@example.com"; +App::$strings["Flag as adult in album view"] = "Oznacz jako \"dla dorosłych\" w widoku albumu"; +App::$strings["I like this (toggle)"] = "Lubię to (przełącz)"; +App::$strings["I don't like this (toggle)"] = "Nie podoba mi się to (przełącz)"; +App::$strings["Please wait"] = "Proszę czekać"; +App::$strings["This is you"] = "To jesteś ty"; +App::$strings["Comment"] = "Komentarz"; +App::$strings["__ctx:title__ Likes"] = "Polubienia"; +App::$strings["__ctx:title__ Dislikes"] = "Dezaprobaty"; +App::$strings["__ctx:title__ Agree"] = "Zgoda"; +App::$strings["__ctx:title__ Disagree"] = "Sprzeciw"; +App::$strings["__ctx:title__ Abstain"] = "Wstrzymuję się"; +App::$strings["__ctx:title__ Attending"] = "Uczestniczę"; +App::$strings["__ctx:title__ Not attending"] = "Nie uczestniczę"; +App::$strings["__ctx:title__ Might attend"] = "Mogę uczestniczyć"; +App::$strings["View all"] = "Pokaż wszystkie"; +App::$strings["__ctx:noun__ Like"] = array( + 0 => "Lubi", + 1 => "Lubią", + 2 => "Lubi", +); +App::$strings["__ctx:noun__ Dislike"] = array( + 0 => "Nie lubi", + 1 => "Nie lubią", + 2 => "Nie lubi", +); +App::$strings["Photo Tools"] = "Narzędzia fotograficzne"; +App::$strings["In This Photo:"] = "Na tym zdjęciu:"; +App::$strings["Map"] = "Mapa"; +App::$strings["__ctx:noun__ Likes"] = "Polubienia"; +App::$strings["__ctx:noun__ Dislikes"] = "Dezaprobaty"; +App::$strings["Close"] = "Zamknięte"; +App::$strings["Recent Photos"] = "Najnowsze zdjęcia"; +App::$strings["Posts and comments"] = "Posty i komentarze"; +App::$strings["Only posts"] = "Tylko posty"; +App::$strings["Insufficient permissions. Request redirected to profile page."] = "Niewystarczające uprawnienia. Żądanie zostało przekierowane na stronę profilu."; +App::$strings["Search Results For:"] = "Wyniki wyszukiwania dla:"; +App::$strings["Cards App"] = "Aplikacja Cards"; +App::$strings["Create personal planning cards"] = "Twórz osobiste karty planowania"; +App::$strings["Add Card"] = "Dodaj kartę"; +App::$strings["Cards"] = "Karty"; +App::$strings["This page is available only to site members"] = "Ta strona jest dostępna tylko dla członków serwisu"; +App::$strings["Welcome"] = "Witamy"; +App::$strings["What would you like to do?"] = "Co chciałbyś zrobić?"; +App::$strings["Please bookmark this page if you would like to return to it in the future"] = "Dodaj tę stronę do zakładek, jeśli chcesz wrócić do niej w przyszłości"; +App::$strings["Upload a profile photo"] = "Prześlij zdjęcie profilowe"; +App::$strings["Upload a cover photo"] = "Prześlij zdjęcie na okładkę"; +App::$strings["Edit your default profile"] = "Edytuj swój domyślny profil"; +App::$strings["View friend suggestions"] = "Zobacz propozycje znajomości"; +App::$strings["View the channel directory"] = "Wyświetl katalog kanałów"; +App::$strings["View/edit your channel settings"] = "Wyświetl/edytuj ustawienia swojego kanału"; +App::$strings["View the site or project documentation"] = "Wyświetl witrynę lub dokumentację projektu"; +App::$strings["Visit your channel homepage"] = "Odwiedź stronę główną swojego kanału"; +App::$strings["View your connections and/or add somebody whose address you already know"] = "Wyświetl swoje kontakty albo dodaj osobę, której adres już znasz"; +App::$strings["View your personal stream (this may be empty until you add some connections)"] = "Wyświetl swój osobisty strumień (może być pusty, dopóki nie dodasz niektórych połączeń)"; +App::$strings["View the public stream. Warning: this content is not moderated"] = "Wyświetl strumień publiczny. Ostrzeżenie: ta zawartość nie jest moderowana"; +App::$strings["Active"] = "Aktywny"; +App::$strings["Blocked"] = "Zablokowany"; +App::$strings["Ignored"] = "Ignorowany"; +App::$strings["Hidden"] = "Ukryty"; +App::$strings["Archived/Unreachable"] = "Zarchiwizowane/Nieosiągalne"; +App::$strings["New"] = "Nowy"; +App::$strings["Active Connections"] = "Aktywne połączenia"; +App::$strings["Show active connections"] = "Pokaż aktywne połączenia"; +App::$strings["New Connections"] = "Nowe połączenia"; +App::$strings["Show pending (new) connections"] = "Pokaż oczekujące (nowe) połączenia"; +App::$strings["Only show blocked connections"] = "Pokaż tylko zablokowane połączenia"; +App::$strings["Only show ignored connections"] = "Pokaż tylko ignorowane połączenia"; +App::$strings["Only show archived/unreachable connections"] = "Pokaż tylko zarchiwizowane/nieosiągalne połączenia"; +App::$strings["Only show hidden connections"] = "Pokaż tylko ukryte połączenia"; +App::$strings["Show all connections"] = "Pokaż wszystkie połączenia"; +App::$strings["Pending approval"] = "W oczekiwaniu na zatwierdzenie"; +App::$strings["Archived"] = "Zarchiwizowane"; +App::$strings["Not connected at this location"] = "Brak połączenia w tej lokalizacji"; +App::$strings["%1\$s [%2\$s]"] = "%1\$s [%2\$s]"; +App::$strings["Edit connection"] = "Edytuj połączenie"; +App::$strings["Delete connection"] = "Usuń połączenie"; +App::$strings["Channel address"] = "Adres kanału"; +App::$strings["Network"] = "Sieć"; +App::$strings["Call"] = "Połączenie"; +App::$strings["Status"] = "Stan"; +App::$strings["Connected"] = "Połączene"; +App::$strings["Approve connection"] = "Zatwierdź połączenie"; +App::$strings["Approve"] = "Zatwierdź"; +App::$strings["Ignore connection"] = "Ignoruj połączenie"; +App::$strings["Recent activity"] = "Ostatnia aktywność"; +App::$strings["Connect"] = "Połączenie"; +App::$strings["Connect at this location"] = "Połącz w tej lokalizacji"; +App::$strings["Connections"] = "Połączenia"; +App::$strings["Search your connections"] = "Wyszukaj swoje połączenia"; +App::$strings["Connections search"] = "Wyszukiwanie połączeń"; +App::$strings["Find"] = "Znajdź"; +App::$strings["Item is not editable"] = "Elementu nie można edytować"; +App::$strings["Tag removed"] = "Tag został usunięty"; +App::$strings["Remove Item Tag"] = "Usuń tag elementy"; +App::$strings["Select a tag to remove: "] = "Wybierz tag do usunięcia: "; +App::$strings["Affinity Tool settings updated."] = "Zaktualizowano ustawienia narzędzia Affinity."; +App::$strings["This app presents a slider control in your connection editor and also on your network page. The slider represents your degree of friendship (affinity) with each connection. It allows you to zoom in or out and display conversations from only your closest friends or everybody in your stream."] = "Ta aplikacja przedstawia suwak w edytorze połączeń, a także na stronie internetowej. Suwak przedstawia stopień przyjaźni (koligacji) z każdym połączeniem. Umożliwia powiększanie i pomniejszanie oraz wyświetlanie rozmów tylko od najbliższych znajomych lub wszystkich w strumieniu."; +App::$strings["Affinity Tool App"] = "Aplikacja Affinity Tool"; +App::$strings["The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage."] = "Poniższe liczby przedstawiają minimalne i maksymalne domyślne pozycje suwaków na stronie sieci/strumienia w procentach."; +App::$strings["Default maximum affinity level"] = "Domyślny maksymalny poziom więzi"; +App::$strings["0-99 default 99"] = "0-99, domyślnie 99"; +App::$strings["Default minimum affinity level"] = "Domyślny minimalny poziom więzi"; +App::$strings["0-99 - default 0"] = "0-99, domyślnie 0"; +App::$strings["Persistent affinity levels"] = "Trwałe poziomy więzi"; +App::$strings["If disabled the max and min levels will be reset to default after page reload"] = "Jeśli wyłączone, maksymalne i minimalne poziomy zostaną zresetowane do wartości domyślnych po ponownym załadowaniu strony"; +App::$strings["Affinity Tool Settings"] = "Ustawienia Affinity Tool"; +App::$strings["No channel."] = "Brak kanału."; +App::$strings["No connections in common."] = "Brak wspólnych połączeń."; +App::$strings["View Common Connections"] = "Wyświetl typowe połączenia"; +App::$strings["🔁 Repeated %1\$s's %2\$s"] = "🔁 Powtórzony %2\$s %1\$s"; +App::$strings["Post repeated"] = "Post powtórzony"; +App::$strings["Page link"] = "Link do strony"; +App::$strings["Edit Webpage"] = "Edytuj stronę internetową"; +App::$strings["vcard"] = "vcard"; +App::$strings["Edit Article"] = "Edutuj artykuł"; +App::$strings["Authentication failed."] = "Uwierzytelnianie nie powiodło się."; +App::$strings["Remote Authentication"] = "Zdalne uwierzytelnianie"; +App::$strings["Enter your channel address (e.g. channel@example.com)"] = "Wpisz adres swojego kanału (np. kanał@example.com)"; +App::$strings["Authenticate"] = "Uwierzytelnianie"; +App::$strings["Item not available."] = "Element nie jest dostępny."; +App::$strings["This setting requires special processing and editing has been blocked."] = "To ustawienie wymaga specjalnego przetwarzania, a edycja została zablokowana."; +App::$strings["Configuration Editor"] = "Edytor konfiguracji"; +App::$strings["Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature."] = "Ostrzeżenie: zmiana niektórych ustawień może spowodować, że Twój kanał przestanie działać. Opuść tę stronę, chyba że czujesz się komfortowo i nie wiesz, jak prawidłowo korzystać z tej funkcji."; +App::$strings["Random Channel App"] = "Aplikacja Random Channel"; +App::$strings["Visit a random channel in the \$Projectname network"] = "Odwiedź losowy kanał w sieci \$Projectname"; +App::$strings["Theme settings updated."] = "Zaktualizowano ustawienia motywu."; +App::$strings["No themes found."] = "Nie znaleziono motywów."; +App::$strings["Disable"] = "Wyłącz"; +App::$strings["Enable"] = "Włącz"; +App::$strings["Screenshot"] = "Zrzut ekranu"; +App::$strings["Themes"] = "Motywy"; +App::$strings["Toggle"] = "Przełącz"; +App::$strings["Settings"] = "Ustawienia"; +App::$strings["Author: "] = "Autor: "; +App::$strings["Maintainer: "] = "Opiekun: "; +App::$strings["[Experimental]"] = "[Eksperymentalne]"; +App::$strings["[Unsupported]"] = "[Nieobsługiwane]"; +App::$strings["By default, unfiltered HTML is allowed in embedded media. This is inherently insecure."] = "Domyślnie, w osadzonych mediach jest dozwolony niefiltrowany HTML. Jest to z natury niebezpieczne."; +App::$strings["The recommended setting is to only allow unfiltered HTML from the following sites:"] = "Zalecane ustawienie to zezwalanie na niefiltrowany kodu HTML tylko z następujących serwisów:"; +App::$strings["https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/
      https://vimeo.com/
      https://soundcloud.com/
      "] = "https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/
      https://vimeo.com/
      https://soundcloud.com/
      "; +App::$strings["All other embedded content will be filtered, unless embedded content from that site is explicitly blocked."] = "Wszystkie inne osadzone treści będą filtrowane, chyba że osadzone treści z tego serwisu są jawnie zablokowane."; +App::$strings["Security"] = "Bezpieczeństwo"; +App::$strings["Block public"] = "Zablokuj publiczny dstęp"; +App::$strings["Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated."] = "Zaznacz, aby zablokować publiczny dostęp do wszystkich innych publicznych stron osobistych w tej witrynie, chyba że jesteś obecnie uwierzytelniony."; +App::$strings["Provide a cloud root directory"] = "Podaj katalog główny w chmurze"; +App::$strings["The cloud root directory lists all channel names which provide public files"] = "Katalog główny w chmurze zawiera listę wszystkich nazw kanałów, które udostępniają pliki publiczne"; +App::$strings["Show total disk space available to cloud uploads"] = "Pokaż całkowitą przestrzeń dyskową dostępną do przesyłania plików do chmury"; +App::$strings["Set \"Transport Security\" HTTP header"] = "Ustaw nagłówek HTTP \"Transport Security\""; +App::$strings["Set \"Content Security Policy\" HTTP header"] = "Ustaw nagłówek HTTP \"Content Security Policy\""; +App::$strings["Allowed email domains"] = "Dozwolone domeny e-mail"; +App::$strings["Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains"] = "Rozdzielana przecinkami lista domen, które są dozwolone w adresach e-mail podczas rejestracji w tym serwisie. Akceptowane są symbole wieloznaczne. Puste pole oznacza zezwolenie na dowolne domeny"; +App::$strings["Not allowed email domains"] = "Niedozwolone domeny e-mail"; +App::$strings["Comma separated list of domains which are not allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains, unless allowed domains have been defined."] = "Rozdzielana przecinkami lista domen, które nie są dozwolone w adresach e-mail podczas rejestracji w tym serwisie. Akceptowane są symbole wieloznaczne. Puste pole oznacza zezwolenie na wszystkie domeny, chyba że zostały uprzednio zdefiniowane jakieś dozwolone domeny."; +App::$strings["Allow communications only from these sites"] = "Zezwalaj na komunikację tylko z tych serwisów"; +App::$strings["One site per line. Leave empty to allow communication from anywhere by default"] = "Jeden serwis w wierszu. Pozostaw puste, aby domyślnie zezwolić na komunikację z dowolnego miejsca"; +App::$strings["Block communications from these sites"] = "Blokuj komunikację z tych serwisów"; +App::$strings["Allow communications only from these channels"] = "Zezwalaj na komunikację tylko z tych kanałów"; +App::$strings["One channel (hash) per line. Leave empty to allow from any channel by default"] = "Jeden kanał (hash) na linię. Pozostaw puste, aby domyślnie zezwolić z dowolnego kanału"; +App::$strings["Block communications from these channels"] = "Blokuj komunikację z tych kanałów"; +App::$strings["Only allow embeds from secure (SSL) websites and links."] = "Zezwalaj na osadzanie tylko z bezpiecznych (SSL) witryn i linków ."; +App::$strings["Allow unfiltered embedded HTML content only from these domains"] = "Zezwalaj na niefiltrowaną osadzony kod HTML tylko z tych domen"; +App::$strings["One site per line. By default embedded content is filtered."] = "Jedna witryna w wierszu. Domyślnie, treść osadzona jest filtrowana."; +App::$strings["Block embedded HTML from these domains"] = "Zablokuj osadzony kod HTML z tych domen"; +App::$strings["Allow SVG thumbnails in file browser"] = "Zezwalaj na miniatury SVG w przeglądarce plików"; +App::$strings["WARNING: SVG images may contain malicious code."] = "OSTRZEŻENIE: obrazy SVG mogą zawierać złośliwy kod."; +App::$strings["Allow embedded (inline) PDF files"] = "Zezwalaj na osadzone (międzywierszowe) pliki PDF"; +App::$strings["%s account blocked/unblocked"] = array( + 0 => "%s konto jest zablokowane/odblokowane", + 1 => "%s konto są zablokowane/odblokowane", + 2 => "%s kont jest zablokowanych/odblokowanych", +); +App::$strings["%s account deleted"] = array( + 0 => "%s konto jest usunięte", + 1 => "%s konta są usunięte", + 2 => "%s kont jest usuniętych", +); +App::$strings["Account not found"] = "Konto nie znalezione"; +App::$strings["Account '%s' deleted"] = "Usunieto konto '%s'"; +App::$strings["Account '%s' blocked"] = "Konto '%s' zostało zablokowane"; +App::$strings["Account '%s' unblocked"] = "Konto '%s' zostało odblokowane"; +App::$strings["select all"] = "wybierz wszystkie"; +App::$strings["Registrations waiting for confirm"] = "Rejestracje czekają na potwierdzenie"; +App::$strings["Request date"] = "Data wniosku"; +App::$strings["No registrations."] = "Brak rejestracji."; +App::$strings["ID"] = "ID"; +App::$strings["All Channels"] = "Wszytskie kanały"; +App::$strings["Register date"] = "Data rejestracji"; +App::$strings["Last login"] = "Ostatnie logowanie"; +App::$strings["Expires"] = "Wygasa"; +App::$strings["Service Class"] = "Klasa usługi"; +App::$strings["Selected accounts will be deleted!\\n\\nEverything these accounts had posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Wybrane konta zostaną usunięte!\\n\\nWszystko, co z tych kont zostało opublikowane na tym serwisie, zostanie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?"; +App::$strings["The account {0} will be deleted!\\n\\nEverything this account has posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Konto {0} zostanie usuniete!\\n\\nWszystko co opublikowano z tego konta na tym serwisie zostanie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?"; +App::$strings["Off"] = "Off"; +App::$strings["On"] = "On"; +App::$strings["Lock feature %s"] = "Funkcja blokady %s"; +App::$strings["Manage Additional Features"] = "Zarządzaj dodatkowymi funkcjami"; +App::$strings["Queue Statistics"] = "Statystyki kolejki"; +App::$strings["Total Entries"] = "Ogółem postów"; +App::$strings["Priority"] = "Priorytet"; +App::$strings["Destination URL"] = "Docelowy URL"; +App::$strings["Mark hub permanently offline"] = "Oznacz hub na stałe w trybie offline"; +App::$strings["Empty queue for this hub"] = "Pusta kolejka dla tego huba"; +App::$strings["Last known contact"] = "Ostatni znany kontakt"; +App::$strings["Update has been marked successful"] = "Aktualizacja została oznaczona jako pomyślna"; +App::$strings["Verification of update %s failed. Check system logs."] = "Weryfikacja aktualizacji %s nie zakończyła się pomyślnie. Sprawdź dzienniki systemowe."; +App::$strings["Update %s was successfully applied."] = "Aktualizacja %s została pomyślnie zastosowana."; +App::$strings["Verifying update %s did not return a status. Unknown if it succeeded."] = "Weryfikacja aktualizacji %s nie zwróciła stanu. Nie wiadomo, czy się udało."; +App::$strings["Update %s does not contain a verification function."] = "Aktualizacja %s nie zawiera funkcji weryfikacji."; +App::$strings["Update function %s could not be found."] = "Nie można znaleźć funkcji aktualizacji %s."; +App::$strings["Executing update procedure %s failed. Check system logs."] = "Wykonanie procedury aktualizacji %s nie powiodło się. Sprawdź dzienniki systemowe."; +App::$strings["Update %s did not return a status. It cannot be determined if it was successful."] = "Aktualizacja %s nie zwróciła stanu. Nie można ustalić, czy się udało."; +App::$strings["Failed Updates"] = "Nieudane aktualizacje"; +App::$strings["Mark success (if update was manually applied)"] = "Oznacz sukces (jeśli aktualizacja została wykonana ręcznie)"; +App::$strings["Attempt to verify this update if a verification procedure exists"] = "Spróbuj zweryfikować tą aktualizację, jeśli istnieje procedura weryfikacji"; +App::$strings["Attempt to execute this update step automatically"] = "Spróbuj automatycznie wykonać ten krok aktualizacji"; +App::$strings["No failed updates."] = "Nie ma nieudanych aktualizacji."; +App::$strings["%s channel censored/uncensored"] = array( + 0 => "%s kanał jest ocenzurowany/nieocenzurowany", + 1 => "%s kanały są ocenzurowane/nieocenzurowane", + 2 => "%s kanałów jest ocenzurowanych/nieocenzurowanych", +); +App::$strings["%s channel code allowed/disallowed"] = array( + 0 => "Kod %s kanału jest dozwolony /niedozwolony", + 1 => "Kod %s kanałów jest dozwolony/niedozwolony", + 2 => "Kod %s kanałów jest dozwolony/niedozwolony", +); +App::$strings["%s channel deleted"] = array( + 0 => "%s kanał został usunięty", + 1 => "%s kanały zostały usunięte", + 2 => "%s kanałów został usuniętych", +); +App::$strings["Channel not found"] = "Kanał nie został znaleziony"; +App::$strings["Channel '%s' deleted"] = "Kanał '%s' został usunięty"; +App::$strings["Channel '%s' censored"] = "Kanał '%s' został ocenzurowany"; +App::$strings["Channel '%s' uncensored"] = "Kanał '%s' jest nieocenzurowany"; +App::$strings["Channel '%s' code allowed"] = "Dozwolony kod kanału '%s'"; +App::$strings["Channel '%s' code disallowed"] = "Niedozwolony kod kanału '%s'"; +App::$strings["Censor"] = "Cezoruj"; +App::$strings["Uncensor"] = "Usuń cenzurę"; +App::$strings["Allow Code"] = "Zezwalaj na kod"; +App::$strings["Disallow Code"] = "Nie zezwalaj na kod"; +App::$strings["Channel"] = "Kanał"; +App::$strings["UID"] = "UID"; +App::$strings["Selected channels will be deleted!\\n\\nEverything that was posted in these channels on this site will be permanently deleted!\\n\\nAre you sure?"] = "Wybrane kanały zostaną usunięte!\\n\\nWszystko co zostało w nich opublikowane będzie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?"; +App::$strings["The channel {0} will be deleted!\\n\\nEverything that was posted in this channel on this site will be permanently deleted!\\n\\nAre you sure?"] = "Kanał {0} zostanie usunięty!\\n\\nWszystko co opublikowano na tym kanale będzie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?"; +App::$strings["Log settings updated."] = "Zaktualizowano ustawienia dziennika."; +App::$strings["Logs"] = "Logi"; +App::$strings["Clear"] = "Wyczyść"; +App::$strings["Debugging"] = "Debugowanie"; +App::$strings["Log file"] = "Plik dziennika"; +App::$strings["Must be writable by web server. Relative to your top-level webserver directory."] = "Musi mieć możliwość zapisu przez serwer WWW. Względnie do katalogu głównego serwera WWW."; +App::$strings["Log level"] = "Poziom rejestrowania zdarzeń"; +App::$strings["Password changed for account %d."] = "Hasło zostało zmienione do konta%d."; +App::$strings["Account settings updated."] = "Zaktualizowano ustawienia konta."; +App::$strings["Account not found."] = "Konto nie zostało znalezione."; +App::$strings["Account Edit"] = "Edycja konta"; +App::$strings["New Password"] = "Nowe hasło"; +App::$strings["New Password again"] = "Powtórz nowe hasło"; +App::$strings["Account language (for emails)"] = "Język konta (dla wiadomości e-mail)"; +App::$strings["Service class"] = "Klasa usługi"; +App::$strings["Plugin %s disabled."] = "Wtyczka %s jest wyłączona."; +App::$strings["Plugin %s enabled."] = "Wtyczka %s jest włączona."; +App::$strings["Addons"] = "Dodatki"; +App::$strings["Minimum project version: "] = "Minimalna wersja projektu: "; +App::$strings["Maximum project version: "] = "Maksymalna wersja projektu: "; +App::$strings["Minimum PHP version: "] = "Minimalna wersja PHP: "; +App::$strings["Compatible Server Roles: "] = "Zgodne role serwera: "; +App::$strings["Requires: "] = "Wymaga: "; +App::$strings["Disabled - version incompatibility"] = "Wyłączone - niezgodność wersji"; +App::$strings["Enter the public git repository URL of the addon repo."] = "Wprowadź adres URL publicznego repozytorium Git dodatków."; +App::$strings["Addon repo git URL"] = "Adres URL repozytorium Git dodatków"; +App::$strings["Custom repo name"] = "Własna nazwa repozytorium"; +App::$strings["(optional)"] = "(opcjonalnie)"; +App::$strings["Download Addon Repo"] = "Pobierz repozytorium dodatków"; +App::$strings["Install new repo"] = "Zainstaluj nowe repozytorium"; +App::$strings["Install"] = "Zainstaluj"; +App::$strings["Manage Repos"] = "Zarządzaj repozytoriami"; +App::$strings["Installed Addon Repositories"] = "Zainstalowane repozytoria dodatków"; +App::$strings["Install a New Addon Repository"] = "Zainstaluj nowe repozytorium dodatków"; +App::$strings["Switch branch"] = "Przełącz gałąź"; +App::$strings["Site settings updated."] = "Zaktualizowano ustawienia serwisu."; +App::$strings["Default"] = "Domyślnie"; +App::$strings["%s - (Incompatible)"] = "%s - (niekompatybilne)"; +App::$strings["mobile"] = "urządzenie przenośne"; +App::$strings["experimental"] = "eksperymentalne"; +App::$strings["unsupported"] = "nieobsługiwane"; +App::$strings["Yes - with approval"] = "Tak - za zgodą"; +App::$strings["My site is not a public server"] = "Mój sewis nie jest serwerem publicznym"; +App::$strings["My site has paid access only"] = "Mój serwis ma tylko płatny dostęp"; +App::$strings["My site has free access only"] = "Mój serwis ma tylko bezpłatny dostęp"; +App::$strings["My site offers free accounts with optional paid upgrades"] = "Mój serwis oferuje darmowe konta z opcjonalnymi płatnymi aktualizacjami"; +App::$strings["Default permission role for new accounts"] = "Domyślna rola uprawnień dla nowych kont"; +App::$strings["This role will be used for the first channel created after registration."] = "Ta rola będzie używana dla pierwszego kanału utworzonego po rejestracji."; +App::$strings["Site"] = "Witryna"; +App::$strings["Registration"] = "Rejestracja"; +App::$strings["File upload"] = "Udostępnianie pliku"; +App::$strings["Policies"] = "Zasady"; +App::$strings["Advanced"] = "Zaawansowane"; +App::$strings["Site name"] = "Nazwa witryny internetowej"; +App::$strings["Banner/Logo"] = "Baner/Logo"; +App::$strings["Unfiltered HTML/CSS/JS is allowed"] = "Dozwolony jest niefiltrowany kodd HTML/CSS /JS"; +App::$strings["Administrator Information"] = "Informacje administratora"; +App::$strings["Contact information for site administrators. Displayed on siteinfo page. BBCode can be used here"] = "Informacje kontaktowe dla administratorów serwisu. Wyświetlane na stronie informacji o serwisie. Tutaj można użyć BBCode"; +App::$strings["Site Information"] = "Informacje o serwisie"; +App::$strings["Publicly visible description of this site. Displayed on siteinfo page. BBCode can be used here"] = "Publicznie widoczny opis tego serwisu. Wyświetlane na stronie informacji o serwisie. Tutaj można użyć BBCode"; +App::$strings["System language"] = "Język systemu"; +App::$strings["System theme"] = "Motyw systemu"; +App::$strings["Default system theme - may be over-ridden by user profiles - change theme settings"] = "Domyślny motyw systemu - może zostać zastąpiony przez profile użytkowników - zmień ustawienia motywu"; +App::$strings["Allow Feeds as Connections"] = "Zezwalaj na kanały jako połączenia"; +App::$strings["(Heavy system resource usage)"] = "(Duże zużycie zasobów systemowych)"; +App::$strings["Maximum image size"] = "Maksymalny rozmiar obrazu"; +App::$strings["Maximum size in bytes of uploaded images. Default is 0, which means no limits."] = "Maksymalny rozmiar przesłanych obrazów w bajtach. Wartość domyślna to 0, co oznacza brak ograniczeń."; +App::$strings["Does this site allow new member registration?"] = "Czy ta witryna umożliwia rejestrację nowych członków?"; +App::$strings["Invitation only"] = "Tylko z zaproszeniem"; +App::$strings["Only allow new member registrations with an invitation code. Above register policy must be set to Yes."] = "Zezwalaj tylko na rejestracje nowych członków za pomocą kodu zaproszenia. Powyższe zasady rejestrów muszą być ustawione na Tak."; +App::$strings["Minimum age"] = "Minimalny wiek"; +App::$strings["Minimum age (in years) for who may register on this site."] = "Minimalny wiek (w latach) dla osób, które mogą zarejestrować się na tej stronie."; +App::$strings["Which best describes the types of account offered by this hub?"] = "Które z poniższych stwierdzeń najlepiej opisuje rodzaje kont oferowanych przez ten hub?"; +App::$strings["This is displayed on the public server site list."] = "Jest to wyświetlane na liście witryn publicznych serwerów."; +App::$strings["Register text"] = "Tekst rejestracyjny"; +App::$strings["Will be displayed prominently on the registration page."] = "Zostanie on wyświetlony w widocznym miejscu na stronie rejestracji."; +App::$strings["Site homepage to show visitors (default: login box)"] = "Strona główna serwisu do wyświetlania odwiedzającym (domyślnie: formularz logowania)"; +App::$strings["example: 'pubstream' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file."] = "przykład: 'pubstream', aby pokazać strumień publiczny, 'page/sys/home', aby wyświetlić systemową stronę internetową o nazwie 'home' lub 'include: home.html', aby dołączyć plik."; +App::$strings["Preserve site homepage URL"] = "Zachowaj adres URL strony głównej serwisu"; +App::$strings["Present the site homepage in a frame at the original location instead of redirecting"] = "Przedstaw stronę główną serwisu w ramce w oryginalnej lokalizacji zamiast przekierowywania"; +App::$strings["Accounts abandoned after x days"] = "Konta porzucone po x dniach"; +App::$strings["Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit."] = "Nie marnuje zasobów systemowych na odpytywanie zewnętrznych witryn w poszukiwaniu porzuconych kont. Wpisz 0, aby nie mieć limitu czasu."; +App::$strings["Allowed friend domains"] = "Dozwolone domeny znajomych"; +App::$strings["Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains"] = "Rozdzielana przecinkami lista domen, które mogą zawierać przyjaźnie z tą witryną. Akceptowane są symbole wieloznaczne. Puste oznacza zezwolenie na dowolne domeny"; +App::$strings["Verify Email Addresses"] = "Zweryfikuj adresy e-mail"; +App::$strings["Check to verify email addresses used in account registration (recommended)."] = "Zaznacz, aby zweryfikować adresy e-mail użyte podczas rejestracji konta (zalecane)."; +App::$strings["Force publish"] = "Wymuś publikację"; +App::$strings["Check to force all profiles on this site to be listed in the site directory."] = "Zaznacz, aby wymusić wyświetlanie wszystkich profili w tym serwisie w katalogu witryn."; +App::$strings["Import Public Streams"] = "Importuj strumienie publiczne"; +App::$strings["Import and allow access to public content pulled from other sites. Warning: this content is unmoderated."] = "Importuj i zezwalaj na dostęp do treści publicznych pobranych z innych serwisów. Ostrzeżenie: ta zawartość jest niemoderowana."; +App::$strings["Site only Public Streams"] = "W serwisie tylko strumienie publiczne"; +App::$strings["Allow access to public content originating only from this site if Imported Public Streams are disabled."] = "Zezwalaj na dostęp do treści publicznych pochodzących tylko z tego serwisu, jeśli importowane strumienie publiczne są wyłączone."; +App::$strings["Allow anybody on the internet to access the Public streams"] = "Zezwól każdemu w internecie na dostęp do strumieni publicznych"; +App::$strings["Disable to require authentication before viewing. Warning: this content is unmoderated."] = "Wyłącz, aby wymagać uwierzytelnienia przed przeglądaniem. Ostrzeżenie: ta zawartość jest niemoderowana."; +App::$strings["Only import Public stream posts with this text"] = "Importuj tylko posty ze strumienia publicznego z tym tekstem"; +App::$strings["Do not import Public stream posts with this text"] = "Nie importuj postów ze strumienia publicznego z tym tekstem"; +App::$strings["Login on Homepage"] = "Zaloguj się na stronie głównej"; +App::$strings["Present a login box to visitors on the home page if no other content has been configured."] = "Przedstaw formularz logowania odwiedzającym na stronie głównej, jeśli nie skonfigurowano żadnych innych treści."; +App::$strings["Enable context help"] = "Włącz pomoc kontekstową"; +App::$strings["Display contextual help for the current page when the help button is pressed."] = "Wyświetlanie pomocy kontekstowej dla bieżącej strony po naciśnięciu przycisku pomocy."; +App::$strings["Reply-to email address for system generated email."] = "Zwrotny adres e-mail dla wiadomości wygenerowanych przez system."; +App::$strings["Sender (From) email address for system generated email."] = "Adres e-mail nadawcy (Od) wiadomości e-mail wygenerowanej przez system."; +App::$strings["Name of email sender for system generated email."] = "Nazwa nadawcy wiadomości e-mail wygenerowanej przez system."; +App::$strings["Directory Server URL"] = "Adres URL serwera katalogowego"; +App::$strings["Default directory server"] = "Domyślny serwer katalogowy"; +App::$strings["Enable SSE Notifications"] = "Włącz powiadomienia SSE"; +App::$strings["If disabled, traditional polling will be used. Warning: this setting might not be suited for shared hosting"] = "Jeśli wyłączone, będzie używane tradycyjne odpytywanie. Ostrzeżenie: to ustawienie może nie być odpowiednie dla hostingu współdzielonego"; +App::$strings["Proxy user"] = "Użytkownik proxy"; +App::$strings["Proxy URL"] = "URL proxy"; +App::$strings["Network timeout"] = "Limit czasu sieci"; +App::$strings["Value is in seconds. Set to 0 for unlimited (not recommended)."] = "Wartość w sekundach. Ustaw na 0 dla nieograniczonej liczby (niezalecane)."; +App::$strings["Delivery interval"] = "Interwał dostaw"; +App::$strings["Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers."] = "Opóźnij procesy dostarczania w tle o kilka sekund, aby zmniejszyć obciążenie systemu. Zalecane: 4-5 dla hostów współdzielonych, 2-3 dla wirtualnych serwerów prywatnych. 0-1 dla dużych serwerów dedykowanych."; +App::$strings["Deliveries per process"] = "Dostawy na proces"; +App::$strings["Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5."] = "Liczba dostaw do podjęcia w ramach jednego procesu systemu operacyjnego. W razie potrzeby dostosuj, aby dostroić wydajność systemu. Polecam: 1-5."; +App::$strings["Queue Threshold"] = "Próg kolejki"; +App::$strings["Always defer immediate delivery if queue contains more than this number of entries."] = "Zawsze odraczaj natychmiastowe dostarczenie, jeśli kolejka zawiera więcej pozycji niż ta."; +App::$strings["Poll interval"] = "Okres odpytywania"; +App::$strings["Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval."] = "Opóźnij procesy sondowania w tle o kilka sekund, aby zmniejszyć obciążenie systemu. Jeśli 0, użyty będzie interwał dostawy."; +App::$strings["Path to ImageMagick convert program"] = "Ścieżka do programu konwertującego ImageMagick"; +App::$strings["If set, use this program to generate photo thumbnails for huge images ( > 4000 pixels in either dimension), otherwise memory exhaustion may occur. Example: /usr/bin/convert"] = "Jeśli jest ustawiona, użyj tego programu do generowania miniatur zdjęć dla dużych obrazów (> 4000 pikseli w każdym wymiarze), w przeciwnym razie może wystąpić wyczerpanie pamięci. Przykład: /usr/bin/convert"; +App::$strings["Maximum Load Average"] = "Maksymalne średnie obciążenie"; +App::$strings["Maximum system load before delivery and poll processes are deferred - default 50."] = "Maksymalne obciążenie systemu przed odroczeniem procesów dostarczania i odpytywania - domyślnie 50."; +App::$strings["Expiration period in days for imported (grid/network) content"] = "Okres ważności w dniach dla zaimportowanej treści (siatki/sieci)"; +App::$strings["0 for no expiration of imported content"] = "0 dla braku wygaśnięcia zaimportowanej treści"; +App::$strings["Do not expire any posts which have comments less than this many days ago"] = "Nie wygasaj żadnych postów, które mają komentarze z datami mniejszymi niż ta wartość dni temu"; +App::$strings["Public servers: Optional landing (marketing) webpage for new registrants"] = "Serwery publiczne: opcjonalna strona lądowania (marketingowa) dla nowych rejestrujących"; +App::$strings["Create this page first. Default is %s/register"] = "Utwórz najpierw tą stronę. Domyślnie %s/ register"; +App::$strings["Page to display after creating a new channel"] = "Strona do wyświetlenia po utworzeniu nowego kanału"; +App::$strings["Default: profiles"] = "Domyślnie: profile"; +App::$strings["Optional: site location"] = "Opcjonalnie: lokalizacja serwisu"; +App::$strings["Region or country"] = "Region lub kraj"; +App::$strings["New Profile Field"] = "Nowe pole profilu"; +App::$strings["Field nickname"] = "Krótka nazwa pola"; +App::$strings["System name of field"] = "Systemowa nazwa pola"; +App::$strings["Input type"] = "Typ wejścia"; +App::$strings["Field Name"] = "Nazwa Pola"; +App::$strings["Label on profile pages"] = "Etykieta na stronach profilu"; +App::$strings["Help text"] = "Tekst pomocy"; +App::$strings["Additional info (optional)"] = "Dodatkowe informacje (opcjonalnie)"; +App::$strings["Field definition not found"] = "Nie znaleziono definicji pola"; +App::$strings["Edit Profile Field"] = "Edytuj pole profilu"; +App::$strings["Profile Fields"] = "Pola profilu"; +App::$strings["Basic Profile Fields"] = "Podstawowe pola profilu"; +App::$strings["Advanced Profile Fields"] = "Zaawansowane pola profilu"; +App::$strings["(In addition to basic fields)"] = "(Oprócz podstawowych pól)"; +App::$strings["All available fields"] = "Wszystkie dostępne pola"; +App::$strings["Custom Fields"] = "Pola niestandardowe"; +App::$strings["Create Custom Field"] = "Utwórz własne pole"; +App::$strings["No more system notifications."] = "Nigdy więcej powiadomień systemowych."; +App::$strings["System Notifications"] = "Powiadomienia systemowe"; +App::$strings["Permissions denied."] = "Odmowa dostępu."; +App::$strings["Thing updated"] = "Rzecz zaktualizowana"; +App::$strings["Object store: failed"] = "Magazyn obiektów: błąd"; +App::$strings["Thing added"] = "Rzecz dodana"; +App::$strings["OBJ: %1\$s %2\$s %3\$s"] = "OBJ: %1\$s %2\$s %3\$s"; +App::$strings["Show Thing"] = "Wyświetl rzecz"; +App::$strings["item not found."] = "pozycja nie została znaleziona."; +App::$strings["Edit Thing"] = "Edytuj rzecz"; +App::$strings["Select a profile"] = "Wybierz profile"; +App::$strings["Post an activity"] = "Opublikuj aktywność"; +App::$strings["Only sends to viewers of the applicable profile"] = "Wysyłane tylko do osób przeglądających odpowiedni profil"; +App::$strings["Name of thing e.g. something"] = "Nazwa rzeczy, np. coś"; +App::$strings["URL of thing (optional)"] = "URL rzeczy (opcjonalnie)"; +App::$strings["URL for photo of thing (optional)"] = "URL do zdjęcia rzeczy (opcjonalnie)"; +App::$strings["Add Thing to your Profile"] = "Dodaj rzecz do swojego profilu"; +App::$strings["Suggest Channels App"] = "Aplikacja Suggest Channels"; +App::$strings["Suggestions for channels in the \$Projectname network you might be interested in"] = "Propozycje dotyczące kanałów w sieci \$Projectname, które mogą Cię zainteresować"; +App::$strings["No suggestions available. If this is a new site, please try again in 24 hours."] = "Brak dostępnych prpozycji. Jeśli to jest nowy serwis, spróbuj ponownie za 24 godziny."; +App::$strings["Ignore/Hide"] = "Ignoruj/Ukryj"; +App::$strings["Channel Suggestions"] = "Sugerowane kanały"; +App::$strings["Email Verification Required"] = "Wymagana jest weryfikacja adresu e-mail"; +App::$strings["A verification token was sent to your email address [%s]. Enter that token here to complete the account verification step. Please allow a few minutes for delivery, and check your spam folder if you do not see the message."] = "Token weryfikacyjny został wysłany na Twój adres e-mail [% s]. Wprowadź tuta ten token, aby zakończyć etap weryfikacji konta. Poczekaj kilka minut na dostarczenie i jeśli nie widzisz wiadomości, sprawdź folder ze spamem."; +App::$strings["Resend Email"] = "Wyślij ponownie wiadomość e-mail"; +App::$strings["Validation token"] = "Token walidacyjny"; +App::$strings["Notes App"] = "Aplikacja Notes"; +App::$strings["A simple notes app with a widget (note: notes are not encrypted)"] = "Prosta aplikacja do notatek z widżetem (uwaga: notatki nie są szyfrowane)"; +App::$strings["This channel is limited to %d tokens"] = "Ten kanał jest ograniczony do %d tokenów"; +App::$strings["Name and Password are required."] = "Wymagane są Imię i hasło."; +App::$strings["Token saved."] = "Token został zapisany."; +App::$strings["Guest Access App"] = "Aplikacja Guest Access"; +App::$strings["Create access tokens so that non-members can access private content"] = "Utwórz tokeny dostępu, aby osoby niebędące członkami mogły uzyskać dostęp do treści prywatnych"; +App::$strings["Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access private content."] = "Użyj tego formularza, aby utworzyć tymczasowe identyfikatory dostępu, aby udostępniać rzeczy osobom niebędącym członkami. Tożsamości te mogą być używane na listach kontroli dostępu, a odwiedzający mogą logować się przy użyciu tych poświadczeń, aby uzyskać dostęp do treści prywatnych."; +App::$strings["You may also provide dropbox style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:"] = "Możesz także udostępnić znajomym i współpracownikom łącza dostępu w stylu dropbox, dodając hasło logowania do dowolnego adresu URL witryny, jak pokazano na ilustracji. Przykłady:"; +App::$strings["Guest Access Tokens"] = "Tokent Guest Access"; +App::$strings["Login Name"] = "Nazwa logowania"; +App::$strings["Login Password"] = "Hasło logowania"; +App::$strings["Expires (yyyy-mm-dd)"] = "Wygasa (rrrr-mm-dd)"; +App::$strings["Change Order of Pinned Navbar Apps"] = "Zmień kolejność aplikacji przypiętych do paska nawigacyjnego"; +App::$strings["Change Order of App Tray Apps"] = "Zmień kolejność aplikacji na pasku aplikacji"; +App::$strings["Use arrows to move the corresponding app left (top) or right (bottom) in the navbar"] = "Użyj strzałek, aby przesunąć odpowiednią aplikację w lewo (u góry) lub w prawo (u dołu) na pasku nawigacyjnym"; +App::$strings["Use arrows to move the corresponding app up or down in the app tray"] = "Użyj strzałek, aby przesunąć odpowiednią aplikację w górę lub w dół w zasobniku aplikacji"; +App::$strings["Mark all seen"] = "Oznacz wszystkie jako oglądnięte"; +App::$strings["\$Projectname"] = "Hubzilla"; +App::$strings["Welcome to %s"] = "Witamy w %s"; +App::$strings["Articles App"] = "Aplikacja Articles"; +App::$strings["Create interactive articles"] = "Twórz interaktywne artykuły"; +App::$strings["Add Article"] = "Dodaj artykuł"; +App::$strings["Articles"] = "Artykuły"; +App::$strings["\$Projectname Server - Setup"] = "Serwer \$Projectname - Konfiguracja"; +App::$strings["Could not connect to database."] = "Nie można połączyć się z bazą danych."; +App::$strings["Could not connect to specified site URL. Possible SSL certificate or DNS issue."] = "Nie można połączyć się z określonym adresem URL serwisu. Możliwy problem z certyfikatem SSL lub DNS."; +App::$strings["Could not create table."] = "Nie udało się utworzyć tabeli."; +App::$strings["Your site database has been installed."] = "Baza danych serwisu została zainstalowana."; +App::$strings["You may need to import the file \"install/schema_xxx.sql\" manually using a database client."] = "Może być konieczne ręczne zaimportowanie pliku „install/schema_xxx.sql” za pomocą klienta bazy danych."; +App::$strings["Please see the file \"install/INSTALL.txt\"."] = "Zobacz plik \"install/INSTALL.txt\"."; +App::$strings["System check"] = "Sprawdzanie systemu"; +App::$strings["Check again"] = "Sprawdź ponownie"; +App::$strings["Database connection"] = "Połączenie z bazą danych"; +App::$strings["In order to install \$Projectname we need to know how to connect to your database."] = "Aby zainstalować \$Projectname, musimy wiedzieć, jak połączyć się z twoją bazą danych."; +App::$strings["Please contact your hosting provider or site administrator if you have questions about these settings."] = "Jeśli masz pytania dotyczące tych ustawień, skontaktuj się z dostawcą usług hostingowych lub administratorem serwisu."; +App::$strings["The database you specify below should already exist. If it does not, please create it before continuing."] = "Baza danych, którą określisz poniżej, powinna już istnieć. Jeśli tak się nie stało, utwórz ją przed kontynuowaniem."; +App::$strings["Database Server Name"] = "Nazwa serwera bazy danych"; +App::$strings["Default is 127.0.0.1"] = "Domyślnie, 127.0.0.1"; +App::$strings["Database Port"] = "Port bazy danych"; +App::$strings["Communication port number - use 0 for default"] = "Numer portu komunikacyjnego - dla wartości domyślnej użyj 0"; +App::$strings["Database Login Name"] = "Nazwa logowania do bazy danych"; +App::$strings["Database Login Password"] = "Hasło logowania do bazy danych"; +App::$strings["Database Name"] = "Nazwa bazy danych"; +App::$strings["Database Type"] = "Typ bazy danych"; +App::$strings["Site administrator email address"] = "Adres e-mail administratora serwisu"; +App::$strings["Your account email address must match this in order to use the web admin panel."] = "Adres e-mail Twojego konta będzie musi być zgodny z tym adresem, aby móc korzystać z panelu administratora sieci."; +App::$strings["Website URL"] = "Adres URL serwisu"; +App::$strings["Please use SSL (https) URL if available."] = "Użyj adresu URL z SSL (https), jeśli jest dostępny."; +App::$strings["Please select a default timezone for your website"] = "Wybierz domyślną strefę czasową dla swojego serwisu"; +App::$strings["Site settings"] = "Ustawienia serwisu"; +App::$strings["PHP version 7.1 or greater is required."] = "Wymagany jest PHP w wersji 7.1 lub wyższej."; +App::$strings["PHP version"] = "Wersja PHP"; +App::$strings["Could not find a command line version of PHP in the web server PATH."] = "Nie można znaleźć wersji CLI PHP w zmiennej PATH serwerze WWW."; +App::$strings["If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron."] = "Jeśli nie masz wersji CLI PHP zainstalowanej na serwerze, nie będzie można uruchomić odpytywania w tle przez cron."; +App::$strings["PHP executable path"] = "Ścieżka do pliku wykonywalnego PHP"; +App::$strings["Enter full path to php executable. You can leave this blank to continue the installation."] = "Wpisz pełną ścieżkę do pliku wykonywalnego php. Możesz pozostawić to pole puste, aby kontynuować instalację."; +App::$strings["Command line PHP"] = "PHP CLI"; +App::$strings["Unable to check command line PHP, as shell_exec() is disabled. This is required."] = "Nie można sprawdzić PHP CLI, ponieważ funkcja shell_exec() jest wyłączona. To jest wymagane."; +App::$strings["The command line version of PHP on your system does not have \"register_argc_argv\" enabled."] = "PHP CLI w Twoim systemie nie ma włączonego \"register_argc_argv\"."; +App::$strings["This is required for message delivery to work."] = "Jest to konieczne,, aby dostarczanie wiadomości działało."; +App::$strings["PHP register_argc_argv"] = "PHP register_argc_argv"; +App::$strings["This is not sufficient to upload larger images or files. You should be able to upload at least 4 MB at once."] = "To nie wystarczy, aby przesłać większe obrazy lub pliki. Powinieneś móc przesłać co najmniej 4 MB na raz."; +App::$strings["Your max allowed total upload size is set to %s. Maximum size of one file to upload is set to %s. You are allowed to upload up to %d files at once."] = "Twój maksymalny dopuszczalny łączny rozmiar przesyłanych plików to %s. Maksymalny rozmiar jednego pliku do przesłania to %s. Możesz przesłać jednocześnie do %d plików."; +App::$strings["You can adjust these settings in the server php.ini file."] = "Możesz dostosować te ustawienia w pliku php.ini na serwerze."; +App::$strings["PHP upload limits"] = "Limity wysyłania PHP"; +App::$strings["Error: the \"openssl_pkey_new\" function on this system is not able to generate encryption keys"] = "Błąd: funkcja \"openssl_pkey_new\" w tym systemie nie jest w stanie wygenerować kluczy szyfrujących"; +App::$strings["If running under Windows, please see \"http://www.php.net/manual/en/openssl.installation.php\"."] = "Jeśli pracujesz w systemie Windows, przeczytaj \"http://www.php.net/manual/en/openssl.installation.php\"."; +App::$strings["Generate encryption keys"] = "Wygeneruj klucze szyfrowania"; +App::$strings["libCurl PHP module"] = "moduł PHP libCurl"; +App::$strings["GD graphics PHP module"] = "Moduł PHP GD graphics"; +App::$strings["OpenSSL PHP module"] = "Moduł PHP OpenSSL"; +App::$strings["PDO database PHP module"] = "Moduł PHP PDO"; +App::$strings["mb_string PHP module"] = "moduł PHP mb_string PHP"; +App::$strings["xml PHP module"] = "moduł PHP xml"; +App::$strings["zip PHP module"] = "moduł PHP zip"; +App::$strings["Apache mod_rewrite module"] = "Moduł Apache mod_rewrite"; +App::$strings["Error: Apache webserver mod-rewrite module is required but not installed."] = "Błąd: wymagany jest moduł mod-rewrite serwera Apache, ale nie jest zainstalowany."; +App::$strings["exec"] = "exec"; +App::$strings["Error: exec is required but is either not installed or has been disabled in php.ini"] = "Błąd: wymagany jest program exec ale nie jest on zainstalowany lub został wyłączony w php.ini"; +App::$strings["shell_exec"] = "shell_exec"; +App::$strings["Error: shell_exec is required but is either not installed or has been disabled in php.ini"] = "Błąd: wymagany jest shell_exec, ale nie jest zainstalowany lub został wyłączony w php.ini"; +App::$strings["Error: libCURL PHP module required but not installed."] = "Błąd: wymagany jest moduł PHP libCURL, ale nie jest zainstalowany."; +App::$strings["Error: GD PHP module with JPEG support or ImageMagick graphics library required but not installed."] = "Błąd: wymagany jest moduł PHP GD z obsługą formatu JPEG lub biblioteką graficzną ImageMagick, ale nie jest on zainstalowany."; +App::$strings["Error: openssl PHP module required but not installed."] = "Błąd: wymagany jest moduł PHP openssl, ale niezainstalowany."; +App::$strings["Error: PDO database PHP module missing a driver for either mysql or pgsql."] = "Błąd: w module PHP PDO brakuje sterownika dla mysql lub pgsql."; +App::$strings["Error: PDO database PHP module required but not installed."] = "Błąd: wymagany jest moduł PHP PDO, ale nie jest zainstalowany."; +App::$strings["Error: mb_string PHP module required but not installed."] = "Błąd: wymagany, ale niezainstalowany moduł mb_string PHP."; +App::$strings["Error: xml PHP module required for DAV but not installed."] = "Błąd: moduł XML PHP wymagany dla DAV, ale nie jest zainstalowany."; +App::$strings["Error: zip PHP module required but not installed."] = "Błąd: wymagany jest moduł PHP zip, ale nie jest on zainstalowany."; +App::$strings[".htconfig.php is writable"] = ".htconfig.php jest możliwy do zapisu"; +App::$strings["The web installer needs to be able to create a file called \".htconfig.php\" in the top folder of your web server and it is unable to do so."] = "Instalator internetowy musi mieć możliwość utworzenia pliku o nazwie \".htconfig.php\" w głównym folderze serwera WWW a nie może tego zrobić."; +App::$strings["This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can."] = "Najczęściej jest to ustawienie uprawnień, ponieważ serwer WWW może nie być w stanie zapisywać plików w Twoim folderze - nawet jeśli możesz."; +App::$strings["Please see install/INSTALL.txt for additional information."] = "Dodatkowe informacje można znaleźć w pliku install/INSTALL.txt."; +App::$strings["This software uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering."] = "To oprogramowanie wykorzystuje silnik szablonów Smarty3 do renderowania widoków internetowych. Smarty3 kompiluje szablony do PHP, aby przyspieszyć renderowanie."; +App::$strings["In order to store these compiled templates, the web server needs to have write access to the directory %s under the top level web folder."] = "Aby przechowywać te skompilowane szablony, serwer sieciowy musi mieć dostęp do zapisu w katalogu %s zlokalizowanym w folderze głównym serwera WWW."; +App::$strings["Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder."] = "Upewnij się, że właściciel procesu serwer WWW (np. www-data), ma prawo do zapisu w tym folderze."; +App::$strings["Note: as a security measure, you should give the web server write access to %s only--not the template files (.tpl) that it contains."] = "Uwaga: ze względów bezpieczeństwa powinno się dać serwerowi WWW prawo zapisu tylko do %s - nie do plików szablonów (.tpl), które on zawiera."; +App::$strings["%s is writable"] = "%s jest możliwy do zapisu"; +App::$strings["This software uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the top level web folder"] = "To oprogramowanie używa katalogu store do zapisywania przesyłanych plików. Serwer WWW musi mieć dostęp do zapisu w katalogu store, znajdującego się w folderze serwera WWW najwyższego poziomu"; +App::$strings["store is writable"] = "katalog store jest możliwy do zapisu"; +App::$strings["SSL certificate cannot be validated. Fix certificate or disable https access to this site."] = "Nie można zweryfikować certyfikatu SSL. Napraw certyfikat lub wyłącz dostęp https do tej witryny."; +App::$strings["If you have https access to your website or allow connections to TCP port 443 (the https: port), you MUST use a browser-valid certificate. You MUST NOT use self-signed certificates!"] = "Jeśli masz dostęp https do swojego serwisu internetowego lub zezwalasz na połączenia z portem TCP 443 (port https:), MUSISZ użyć certyfikatu akceptowanego przez przeglądarki. NIE WOLNO używać certyfikatów z podpisem własnym!"; +App::$strings["This restriction is incorporated because public posts from you may for example contain references to images on your own hub."] = "To ograniczenie zostało wprowadzone, ponieważ Twoje publiczne posty mogą na przykład zawierać odniesienia do obrazów na Twoim hubie."; +App::$strings["If your certificate is not recognized, members of other sites (who may themselves have valid certificates) will get a warning message on their own site complaining about security issues."] = "Jeśli Twój certyfikat nie zostanie rozpoznany, członkowie innych witryn (którzy sami mogą mieć ważne certyfikaty) otrzymają komunikat ostrzegawczy we własnej witrynie, ostrzegający o problemie z bezpieczeństwem."; +App::$strings["This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement."] = "Może to powodować problemy z użytecznością w innym serwisie (nie tylko na Twoim), więc musimy nalegać na to wymaganie."; +App::$strings["Providers are available that issue free certificates which are browser-valid."] = "Są dostępni dostawcy, którzy wydają bezpłatne certyfikaty akceptowane przez przeglądarki."; +App::$strings["If you are confident that the certificate is valid and signed by a trusted authority, check to see if you have failed to install an intermediate cert. These are not normally required by browsers, but are required for server-to-server communications."] = "Jeśli masz pewność, że certyfikat jest ważny i podpisany przez zaufany urząd, sprawdź, czy nie udało się zainstalować certyfikatu pośredniego. Zwykle nie są one wymagane przez przeglądarki, ale są wymagane do komunikacji między serwerami."; +App::$strings["SSL certificate validation"] = "Walidacja certyfikatu SSL"; +App::$strings["Url rewrite in .htaccess is not working. Check your server configuration.Test: "] = "Przepisywanie adresu URL w .htaccess nie działa. Sprawdź konfigurację serwera. Test: "; +App::$strings["Url rewrite is working"] = "Przepisywanie adresu URL działa"; +App::$strings["The database configuration file \".htconfig.php\" could not be written. Please use the enclosed text to create a configuration file in your web server root."] = "Nie można zapisać pliku konfiguracyjnego bazy danych \".htconfig.php\". Użyj załączonego tekstu, aby utworzyć plik konfiguracyjny w katalogu głównym serwera WWW."; +App::$strings["Errors encountered creating database tables."] = "Napotkano błędy podczas tworzenia tabel bazy danych."; +App::$strings["

      What next?

      "] = "

      Co następnie?

      "; +App::$strings["IMPORTANT: You will need to [manually] setup a scheduled task for the poller."] = "WAŻNE: Będziesz musiał [ręcznie] ustawić zaplanowane zadanie dla ankietera."; +App::$strings["No default suggestions were found."] = "Nie znaleziono domyślnych prpozycji."; +App::$strings["%d rating"] = array( + 0 => "%d ocen", + 1 => "%d oceny", + 2 => "%d ocen", +); +App::$strings["Gender: "] = "Płeć: "; +App::$strings["Status: "] = "Status: "; +App::$strings["Homepage: "] = "Strona główna: "; +App::$strings["Age:"] = "Wiek:"; +App::$strings["Location:"] = "Lokalizacja:"; +App::$strings["Description:"] = "Opis:"; +App::$strings["Hometown:"] = "Miasto pobytu:"; +App::$strings["About:"] = "O mnie:"; +App::$strings["Public Forum:"] = "Forum publiczne:"; +App::$strings["Keywords: "] = "Słowa kluczowe: "; +App::$strings["Don't suggest"] = "Nie sugeruj"; +App::$strings["Common connections (estimated):"] = "Popularne połączenia (oszacowanie):"; +App::$strings["Global Directory"] = "Katalog globalny"; +App::$strings["Local Directory"] = "Katalog lokalny"; +App::$strings["Finding:"] = "Odnaleziono:"; +App::$strings["next page"] = "następna strona"; +App::$strings["previous page"] = "poprzednia strona"; +App::$strings["Sort options"] = "Opcje sortowania"; +App::$strings["Alphabetic"] = "Alfabetycznie"; +App::$strings["Reverse Alphabetic"] = "Odwróć alfabetycznie"; +App::$strings["Newest to Oldest"] = "Od najnowszych do najstarszych"; +App::$strings["Oldest to Newest"] = "Od najstarszych do najnowszych"; +App::$strings["No entries (some entries may be hidden)."] = "Brak postów (niektóre posty mogą być ukryte)."; +App::$strings["Menu not found."] = "Nie znaleziono menu."; +App::$strings["Unable to create element."] = "Nie można utworzyć elementu."; +App::$strings["Unable to update menu element."] = "Nie można zaktualizować elementu menu."; +App::$strings["Unable to add menu element."] = "Nie można dodać elementu menu."; +App::$strings["Menu Item Permissions"] = "Uprawnienia do pozycji menu"; +App::$strings["(click to open/close)"] = "(kliknij, aby otworzyć/zamknąć)"; +App::$strings["Link Name"] = "Nazwa linku"; +App::$strings["Link or Submenu Target"] = "Link lub element docelowy podmenu"; +App::$strings["Enter URL of the link or select a menu name to create a submenu"] = "Wprowadź adres URL linku lub wybierz nazwę menu, aby utworzyć podmenu"; +App::$strings["Use magic-auth if available"] = "Użyj magicznego uwierzytelniania, jeśli jest dostępne"; +App::$strings["Open link in new window"] = "Otwórz link w nowym oknie"; +App::$strings["Order in list"] = "Porządek listy"; +App::$strings["Higher numbers will sink to bottom of listing"] = "Wyższe liczby spadną na koniec listy"; +App::$strings["Submit and finish"] = "Prześlij i zakończ"; +App::$strings["Submit and continue"] = "Prześlij i kontynuuj"; +App::$strings["Menu:"] = "Menu:"; +App::$strings["Link Target"] = "Cel linku"; +App::$strings["Edit menu"] = "Edytuj menu"; +App::$strings["Edit element"] = "Edytuj element"; +App::$strings["Drop element"] = "Upuść element"; +App::$strings["New element"] = "Nowy element"; +App::$strings["Edit this menu container"] = "Edytuj ten kontener menu"; +App::$strings["Add menu element"] = "Dodaj element menu"; +App::$strings["Delete this menu item"] = "Usuń tę pozycję menu"; +App::$strings["Edit this menu item"] = "Edytuj tę pozycję menu"; +App::$strings["Menu item not found."] = "Nie znaleziono elementu menu."; +App::$strings["Menu item deleted."] = "Usunieto element menu."; +App::$strings["Menu item could not be deleted."] = "Nie można usunąć elementu menu."; +App::$strings["Edit Menu Element"] = "Edytuj element menu"; +App::$strings["Link text"] = "Tekst linku"; +App::$strings["__ctx:mood__ %1\$s is %2\$s"] = "%1\$s jest %2\$s"; +App::$strings["Mood App"] = "Aplikacja Mood"; +App::$strings["Set your current mood and tell your friends"] = "Ustaw swój aktualny nastrój i podziel się tym ze znajomymi"; +App::$strings["Mood"] = "Mood"; +App::$strings["Permission category name is required."] = "Wymaga się podania nazwy kategorii uprawnień."; +App::$strings["Permission category saved."] = "Kategoria uprawnień została zapisana."; +App::$strings["Permission Categories App"] = "Aplikacja Permission Categories"; +App::$strings["Create custom connection permission limits"] = "Utwórz własne limity uprawnień do połączeń"; +App::$strings["Use this form to create permission rules for various classes of people or connections."] = "Użyj tego formularza, aby utworzyć reguły uprawnień dla różnych klas osób lub połączeń."; +App::$strings["Permission Categories"] = "Kategorie uprawnień"; +App::$strings["Permission category name"] = "Nazwa kategorii uprawnień"; +App::$strings["No ratings"] = "Brak ocen"; +App::$strings["Rating: "] = "Ocena: "; +App::$strings["Website: "] = "Serwis: "; +App::$strings["Description: "] = "Opis: "; +App::$strings["Maximum daily site registrations exceeded. Please try again tomorrow."] = "Przekroczono maksymalną dzienną liczbę rejestracji witryn. Proszę spróbuj ponownie jutro."; +App::$strings["Please indicate acceptance of the Terms of Service. Registration failed."] = "Proszę zaznaczyć akceptację Warunków korzystania z usługi. Rejestracja nieudana."; +App::$strings["Passwords do not match."] = "Hasła niezgodne."; +App::$strings["Registration successful. Continue to create your first channel..."] = "Rejestracja pomyślna. Kontynuuj tworzenie swojego pierwszego kanału ..."; +App::$strings["Registration successful. Please check your email for validation instructions."] = "Rejestracja oomyślna. Sprawdź pocztę e-mail, aby uzyskać instrukcje dotyczące weryfikacji."; +App::$strings["Your registration is pending approval by the site owner."] = "Twoja rejestracja oczekuje na zatwierdzenie przez właściciela serwisu."; +App::$strings["Your registration can not be processed."] = "Twoja rejestracja oczekuje na zatwierdzenie przez właściciela witryny."; +App::$strings["Registration on this hub is disabled."] = "Rejestracja na tym hubie jest wyłączona."; +App::$strings["Registration on this hub is by approval only."] = "Rejestracja na tym hubie wymaga zatwierdzenia."; +App::$strings["Register at another affiliated hub."] = "Zarejestruj się na innym stowarzyszonym hubie. "; +App::$strings["Registration on this hub is by invitation only."] = "Rejestracja na tym hubie wumaga uprzedniego zaproszenia."; +App::$strings["This site has exceeded the number of allowed daily account registrations. Please try again tomorrow."] = "Na tym serwisie przekroczono dozwoloną liczbę dziennych rejestracji kont. Proszę spróbuj ponownie jutro."; +App::$strings["Terms of Service"] = "Regulamin"; +App::$strings["I accept the %s for this website"] = "Akceptuję % s dla tego serwisu"; +App::$strings["I am over %s years of age and accept the %s for this website"] = "Mam ponad % s lat i akceptuję % s dla tego serwisu"; +App::$strings["Your email address"] = "Twój adres e-mail"; +App::$strings["Choose a password"] = "Wybierz hasło"; +App::$strings["Please re-enter your password"] = "Wprowadź ponownie swoje hasło"; +App::$strings["Please enter your invitation code"] = "Wprowadź kod zaproszenia"; +App::$strings["Your Name"] = "Twoja nazwa"; +App::$strings["Real names are preferred."] = "Preferowane są prawdziwe imiona."; +App::$strings["Your nickname will be used to create an easy to remember channel address e.g. nickname%s"] = "Twój pseudonim posłuży do stworzenia łatwego do zapamiętania adresu kanału, np. pseudonim%s"; +App::$strings["Select a channel permission role for your usage needs and privacy requirements."] = "Wybierz rolę uprawnień do kanału zgodnie z potrzebami użytkowania i wymaganiami dotyczącymi prywatności."; +App::$strings["no"] = "nie"; +App::$strings["yes"] = "tak"; +App::$strings["Register"] = "Zarejestruj się"; +App::$strings["This site requires email verification. After completing this form, please check your email for further instructions."] = "Ta witryna wymaga weryfikację adresu e-mail. Po wypełnieniu tego formularza sprawdź swoją pocztę e-mail, aby uzyskać dalsze instrukcje."; +App::$strings["__ctx:acl__ Profile"] = "Profil"; +App::$strings["network"] = "sieć"; +App::$strings["No feature settings configured"] = "Brak skonfigurowanych ustawień funkcji"; +App::$strings["Addon Settings"] = "Ustawienia dodatków"; +App::$strings["Please save/submit changes to any panel before opening another."] = "Zapisz/prześlij zmiany do dowolnego panelu przed otwarciem kolejnego."; +App::$strings["Not valid email."] = "Nieprawidłowy adres e-mail."; +App::$strings["Protected email address. Cannot change to that email."] = "Chroniony adres e-mail. Nie można zmienić tego adresu e-mail."; +App::$strings["System failure storing new email. Please try again."] = "Błąd systemu podczas zapisywania nowej wiadomości e-mail. Proszę spróbuj ponownie."; +App::$strings["Password verification failed."] = "Weryfikacja hasła nie powiodła się."; +App::$strings["Passwords do not match. Password unchanged."] = "Hasła nie pasują do siebie. Nie zmieniono hasła."; +App::$strings["Empty passwords are not allowed. Password unchanged."] = "Puste hasła są niedozwolone. Nie zmieniono hasła."; +App::$strings["Password changed."] = "Hasło zostało zmienione."; +App::$strings["Password update failed. Please try again."] = "Aktualizacja hasła nie powiodła się. Proszę spróbuj ponownie."; +App::$strings["Account Settings"] = "Ustawienia konta"; +App::$strings["Current Password"] = "Bieżące hasło"; +App::$strings["Enter New Password"] = "Wprowadź nowe hasło"; +App::$strings["Confirm New Password"] = "Potwierdź nowe hasło"; +App::$strings["Leave password fields blank unless changing"] = "Pozostaw pola hasła puste, chyba że je zmieniasz"; +App::$strings["Email Address:"] = "Adres e-mail:"; +App::$strings["Remove this account including all its channels"] = "Usuń to konto wraz ze wszystkimi jego kanałami"; +App::$strings["Events Settings"] = "Ustawienia wydarzeń"; +App::$strings["Profiles Settings"] = "Ustawienia profili"; +App::$strings["Editor Settings"] = "Editor Settings"; +App::$strings["Additional Features"] = "Dodatkowe funkcjonalności"; +App::$strings["Channel Manager Settings"] = "Ustawienia menadżera kanałów"; +App::$strings["%s - (Experimental)"] = "%s - (eksperymentalne)"; +App::$strings["Display Settings"] = "Ustawienia wyświetlania"; +App::$strings["Theme Settings"] = "Ustawienia motywu"; +App::$strings["Custom Theme Settings"] = "Ustawienia własnego motywu"; +App::$strings["Content Settings"] = "Ustawienia treści"; +App::$strings["Display Theme:"] = "Wyświetl motyw:"; +App::$strings["Select scheme"] = "Wybierz schemat"; +App::$strings["Preload images before rendering the page"] = "Przeładuj obrazy przed renderowaniem strony"; +App::$strings["The subjective page load time will be longer but the page will be ready when displayed"] = "Subiektywny czas ładowania strony będzie dłuższy, ale strona będzie gotowa po wyświetleniu"; +App::$strings["Enable user zoom on mobile devices"] = "Włącz zoom użytkownika na urządzeniach mobilnych"; +App::$strings["Update browser every xx seconds"] = "Aktualizuj przeglądarkę co xx sekund"; +App::$strings["Minimum of 10 seconds, no maximum"] = "Co najmniej 10 sekund, nie maksimum"; +App::$strings["Maximum number of conversations to load at any time:"] = "Maksymalna liczba rozmów do załadowania w dowolnym momencie:"; +App::$strings["Maximum of 30 items"] = "Maksymalnie 30 pozycji"; +App::$strings["Show emoticons (smilies) as images"] = "Pokaż emotikony (uśmieszki) jako obrazy"; +App::$strings["Provide channel menu in navigation bar"] = "Podaj menu kanału na pasku nawigacji"; +App::$strings["Default: channel menu located in app menu"] = "Domyślnie: menu kanału znajduje się w menu aplikacji"; +App::$strings["Link post titles to source"] = "Połącz tytuły postów ze źródłem"; +App::$strings["New Member Links"] = "Linki dla nowych członków"; +App::$strings["Display new member quick links menu"] = "Wyświetl menu szybkich łączy dla nowych członków"; +App::$strings["Photos Settings"] = "Ustawienia zdjęć"; +App::$strings["Nobody except yourself"] = "Nikt oprócz ciebie"; +App::$strings["Only those you specifically allow"] = "Tylko te, na które jawnie zezwalasz"; +App::$strings["Approved connections"] = "Zatwierdzone połączenia"; +App::$strings["Any connections"] = "Wszelkie połączenia"; +App::$strings["Anybody on this website"] = "Każdy w tym serwisie"; +App::$strings["Anybody in this network"] = "Każdy w tej sieci"; +App::$strings["Anybody authenticated"] = "Każda uwierzytelniona osoba"; +App::$strings["Anybody on the internet"] = "Każdy w internecie"; +App::$strings["Publish your default profile in the network directory"] = "Opublikuj swój domyślny profil w katalogu sieciowym"; +App::$strings["Allow us to suggest you as a potential friend to new members?"] = "Czy pozwalasz nam sugerować Ciebie jako potencjalnego przyjaciela nowym członkom?"; +App::$strings["or"] = "lub"; +App::$strings["Your channel address is"] = "Twój adres kanału to"; +App::$strings["Your files/photos are accessible via WebDAV at"] = "Twoje pliki/zdjęcia są dostępne przez WebDAV pod adresem"; +App::$strings["Automatic membership approval"] = "Automatyczne zatwierdzanie członkostwa"; +App::$strings["Channel Settings"] = "Ustawienia kanału"; +App::$strings["Basic Settings"] = "Podstawowe ustawienia"; +App::$strings["Full Name:"] = "Pełna nazwa:"; +App::$strings["Your Timezone:"] = "Twoja strefa czasowa:"; +App::$strings["Default Post Location:"] = "Domyślna lokalizacja postu:"; +App::$strings["Geographical location to display on your posts"] = "Lokalizacja geograficzna do wyświetlania w Twoich postach"; +App::$strings["Use Browser Location:"] = "Użyj lokalizacji przeglądarki:"; +App::$strings["Adult Content"] = "Treść dla dorosłych"; +App::$strings["This channel frequently or regularly publishes adult content. (Please tag any adult material and/or nudity with #NSFW)"] = "Ten kanał często lub regularnie publikuje treści dla dorosłych. (Oznacz wszelkie materiały dla dorosłych albo nagość tagiem #NSFW)"; +App::$strings["Security and Privacy Settings"] = "Ustawienia bezpieczeństwa i prywatności"; +App::$strings["Your permissions are already configured. Click to view/adjust"] = "Twoje uprawnienia są już skonfigurowane. Kliknij, aby wyświetlić/dostosować"; +App::$strings["Hide my online presence"] = "Ukryj moją obecność w Internecie"; +App::$strings["Prevents displaying in your profile that you are online"] = "Zapobiega wyświetlaniu w Twoim profilu, że jesteś online"; +App::$strings["Simple Privacy Settings:"] = "Proste ustawienia prywatności:"; +App::$strings["Very Public - extremely permissive (should be used with caution)"] = "Bardzo publiczne - wyjątkowo pobłażliwe (należy używać ostrożnie)"; +App::$strings["Typical - default public, privacy when desired (similar to social network permissions but with improved privacy)"] = "Typowe - domyślne publiczne, prywatność w razie potrzeby (podobne do uprawnień w popularnych sieciach społecznościowych, ale z podwyższoną prywatnością)"; +App::$strings["Private - default private, never open or public"] = "Prywatne - domyślnie prywatne, nigdy otwarte ani publiczne"; +App::$strings["Blocked - default blocked to/from everybody"] = "Zablokowane - domyślnie zablokowane dla/od wszystkich"; +App::$strings["Allow others to tag your posts"] = "Pozwól innym oznaczać Twoje posty"; +App::$strings["Often used by the community to retro-actively flag inappropriate content"] = "Często używany przez społeczność do oznaczania nieodpowiednich treści z mocą wsteczną"; +App::$strings["Channel Permission Limits"] = "Limity uprawnień kanału"; +App::$strings["Expire other channel content after this many days"] = "Po tej ilości dni wygasają inne treści w kanale"; +App::$strings["0 or blank to use the website limit."] = "0 lub puste, aby użyć limitu serwisu."; +App::$strings["This website expires after %d days."] = "Ta strona wygasa po %d dniach."; +App::$strings["This website does not expire imported content."] = "Na tym serwis internetowym importowanej zawartości nie jest wygaszana."; +App::$strings["The website limit takes precedence if lower than your limit."] = "Limit serwisu ma pierwszeństwo, jeśli jest niższy niż Twój limit."; +App::$strings["Maximum Friend Requests/Day:"] = "Maksymalna liczba zaproszeń do znajomych, dziennie:"; +App::$strings["May reduce spam activity"] = "Może zmniejszyć aktywność spamu"; +App::$strings["Default Privacy Group"] = "Domyślna grupa prywatności"; +App::$strings["Use my default audience setting for the type of object published"] = "Użyj mojego domyślnego ustawienia odbiorców dla typu publikowanego obiektu"; +App::$strings["Default permissions category"] = "Domyślna kategoria uprawnień"; +App::$strings["Maximum private messages per day from unknown people:"] = "Maksymalna liczba prywatnych wiadomości dziennie od nieznanych osób:"; +App::$strings["Useful to reduce spamming"] = "Przydatne do ograniczenia spamowania"; +App::$strings["Notification Settings"] = "Ustawienia powiadomień"; +App::$strings["By default post a status message when:"] = "Domyślnie publikuj komunikat o stanie, gdy:"; +App::$strings["accepting a friend request"] = "zaakceptowano zaproszenia do znajomych"; +App::$strings["joining a forum/community"] = "dołączoni do forum/społeczności"; +App::$strings["making an interesting profile change"] = "dokonano interesującej zmiany profilu"; +App::$strings["Send a notification email when:"] = "Wyślij e-mail z powiadomieniem, gdy:"; +App::$strings["You receive a connection request"] = "Otrzymujesz żądanie połączenia"; +App::$strings["Your connections are confirmed"] = "Twoje połączenia są potwierdzone"; +App::$strings["Someone writes on your profile wall"] = "Ktoś pisze na Twojej ścianie profilu"; +App::$strings["Someone writes a followup comment"] = "Ktoś pisze komentarz uzupełniający"; +App::$strings["You receive a private message"] = "Otrzymujesz prywatną wiadomość"; +App::$strings["You receive a friend suggestion"] = "Otrzymasz propozycję znajomości"; +App::$strings["You are tagged in a post"] = "Oznaczono Ciebie tagiem w poście"; +App::$strings["You are poked/prodded/etc. in a post"] = "Szturchnięto Ciebie w poście"; +App::$strings["Someone likes your post/comment"] = "Ktoś polubił Twój post/komentarz"; +App::$strings["Show visual notifications including:"] = "Pokaż powiadomienia wizualne, w tym:"; +App::$strings["Unseen stream activity"] = "Niewidoczną aktywność na strumieniu"; +App::$strings["Unseen channel activity"] = "Niewidoczną aktywność w kanale"; +App::$strings["Unseen private messages"] = "Niewidoczną wiadomości prywatne"; +App::$strings["Recommended"] = "Zalecane"; +App::$strings["Upcoming events"] = "Nadchodzące wydarzenia"; +App::$strings["Events today"] = "Wydarzenia dzisiejsze"; +App::$strings["Upcoming birthdays"] = "Nadchodzące urodziny"; +App::$strings["Not available in all themes"] = "Niedostępne we wszystkich motywach"; +App::$strings["System (personal) notifications"] = "Powiadomienia systemowe (osobiste)"; +App::$strings["System info messages"] = "Systemowe komunikaty informacyjne"; +App::$strings["System critical alerts"] = "Systemowe alerty krytyczne"; +App::$strings["New connections"] = "Nowe połączenia"; +App::$strings["System Registrations"] = "Rejestracje systemowe"; +App::$strings["Unseen shared files"] = "Niewidoczne udostępnione pliki"; +App::$strings["Unseen public stream activity"] = "Niewidoczna aktywność na publicznym strumieniu"; +App::$strings["Unseen likes and dislikes"] = "Niewidoczne polubienia i dezaprobaty"; +App::$strings["Unseen forum posts"] = "Niewidoczne posty na forum"; +App::$strings["Email notification hub (hostname)"] = "Hub powiadomień e-mail (nazwa hosta)"; +App::$strings["If your channel is mirrored to multiple hubs, set this to your preferred location. This will prevent duplicate email notifications. Example: %s"] = "Jeśli twój kanał jest powielany na wielu hubach, ustaw to na preferowaną lokalizację. Zapobiegnie to powielaniu powiadomień e-mail. Przykład: % s"; +App::$strings["Show new wall posts, private messages and connections under Notices"] = "Pokaż w powiadomieniach nowe posty na ścianie, prywatne wiadomości i połączenia"; +App::$strings["Notify me of events this many days in advance"] = "Informuj mnie o wydarzeniach z tak wielodniowym wyprzedzeniem"; +App::$strings["Must be greater than 0"] = "Musi być większa od 0"; +App::$strings["Advanced Account/Page Type Settings"] = "Zaawansowane ustawienia konta/typu strony"; +App::$strings["Change the behaviour of this account for special situations"] = "Zmień zachowanie tego konta w szczególnych sytuacjach"; +App::$strings["Miscellaneous Settings"] = "Różne ustawienia"; +App::$strings["Default photo upload folder"] = "Domyślny folder przesyłania zdjęć"; +App::$strings["%Y - current year, %m - current month"] = "%Y - bieżący rok, %m - bieżący miesiąc"; +App::$strings["Default file upload folder"] = "Domyślny folder przesyłania plików"; +App::$strings["Remove this channel."] = "Usuń ten kanał."; +App::$strings["Connections Settings"] = "Ustawienia połączeń"; +App::$strings["Calendar Settings"] = "Ustawienia kalendarza"; +App::$strings["Directory Settings"] = "Ustawienia katalogu"; +App::$strings["Max height of content (in pixels)"] = "Maksymalna wysokość pola treści (w pikselach)"; +App::$strings["Click to expand content exceeding this height"] = "Kliknij, aby rozwinąć treść przekraczającą tę wysokość"; +App::$strings["Personal menu to display in your channel pages"] = "Menu osobiste do wyświetlania na stronach Twojego kanał"; +App::$strings["Channel Home Settings"] = "Ustawienia strony głównej kanału"; +App::$strings["Stream Settings"] = "Ustawienia strumienia"; +App::$strings["Settings saved."] = "Ustawienia zapisane."; +App::$strings["Settings saved. Reload page please."] = "Ustawienia zapisane. Proszę ponownie załadować stronę."; +App::$strings["Conversation Settings"] = "Ustawienia rozmów"; +App::$strings["Remote Diagnostics App"] = "Aplikacja Remote Diagnostics"; +App::$strings["Perform diagnostics on remote channels"] = "Przeprowadź diagnostykę zdalnych kanałów"; +App::$strings["Total invitation limit exceeded."] = "Przekroczono łączny limit zaproszeń."; +App::$strings["%s : Not a valid email address."] = "% s: nieprawidłowy adres e-mail."; +App::$strings["Please join us on \$Projectname"] = "Dołącz do nas na \$Projectname"; +App::$strings["Invitation limit exceeded. Please contact your site administrator."] = "Przekroczono limit zaproszeń. Skontaktuj się z administratorem serwisu."; +App::$strings["%s : Message delivery failed."] = "%s: dostarczenie wiadomości nie powiodło się."; +App::$strings["%d message sent."] = array( + 0 => "Wysłano %d wiadomość.", + 1 => "Wysłano %d wiadomości.", + 2 => "Wysłano %d wiadomości.", +); +App::$strings["Invite App"] = "Aplikacja Invite"; +App::$strings["Send email invitations to join this network"] = "Wyślij wiadomości e-mail z zaproszeniami do przyłączenia się do tej sieci"; +App::$strings["You have no more invitations available"] = "Nie masz więcej dostępnych zaproszeń"; +App::$strings["Send invitations"] = "Wysyłać zaproszenia"; +App::$strings["Enter email addresses, one per line:"] = "Wprowadź adresy e-mail, po jednym w każdym wierszu:"; +App::$strings["Your message:"] = "Twoja wiadomość:"; +App::$strings["Please join my community on \$Projectname."] = "Dołącz do mojej społeczności w \$Projectname."; +App::$strings["You will need to supply this invitation code:"] = "Trzeba będzie podać ten kod zaproszenia:"; +App::$strings["1. Register at any \$Projectname location (they are all inter-connected)"] = "1. Zarejestruj się w dowolnej lokalizacji \$Projectname (wszystkie są ze sobą połączone)"; +App::$strings["2. Enter my \$Projectname network address into the site searchbar."] = "2. Wpisz mój adres sieciowy \$Projectname w pasku wyszukiwania serwisu."; +App::$strings["or visit"] = "lub odwiedź"; +App::$strings["3. Click [Connect]"] = "3. Kliknij [Połącz]"; +App::$strings["About this site"] = "O tym serwisie"; +App::$strings["Site Name"] = "Nazwa witryny"; +App::$strings["Administrator"] = "Administrator"; +App::$strings["Software and Project information"] = "Informacje o oprogramowaniu i projekcie"; +App::$strings["This site is powered by \$Projectname"] = "Ta witryna jest oparta na \$Projectname"; +App::$strings["Federated and decentralised networking and identity services provided by Zot"] = "Sfederowane i zdecentralizowane usługi sieciowe i tożsamości wykorzystujące protokół Zot"; +App::$strings["Additional federated transport protocols:"] = "Dodatkowe protokoły transportu federacyjnego:"; +App::$strings["Version %s"] = "Wersja %s"; +App::$strings["Project homepage"] = "Strona główna projektu"; +App::$strings["Developer homepage"] = "Strona główna developerów"; +App::$strings["No service class restrictions found."] = "Nie znaleziono ograniczeń klasy usług."; +App::$strings["Select a bookmark folder"] = "Wybierz folder zakładek"; +App::$strings["Save Bookmark"] = "Zapisz zakładkę"; +App::$strings["URL of bookmark"] = "URL zakładki"; +App::$strings["Or enter new bookmark folder name"] = "Lub wprowadź nową nazwę folderu zakładek"; +App::$strings["Language App"] = "Aplikacja Language"; +App::$strings["Change UI language"] = "Zmień język interfejsu użytkownika"; +App::$strings["Welcome to Hubzilla!"] = "Witamy w Hubzilla!"; +App::$strings["You have got no unseen posts..."] = "Nie masz żadnych nieoglądniętych postów..."; +App::$strings["Cover Photos"] = "Zdjęcia na okładkę"; +App::$strings["female"] = "kobieta"; +App::$strings["%1\$s updated her %2\$s"] = "%1\$s zaktualizował ją %2\$s"; +App::$strings["male"] = "mężczyzna"; +App::$strings["%1\$s updated his %2\$s"] = "%1\$s zaktualizował go %2\$s"; +App::$strings["%1\$s updated their %2\$s"] = "%1\$s zaktualizował ich %2\$s"; +App::$strings["cover photo"] = "zdjęcie okładkowe"; +App::$strings["Your cover photo may be visible to anybody on the internet"] = "Twoje zdjęcie okładkowe może być widoczne dla każdego w internecie"; +App::$strings["Change Cover Photo"] = "Zmień zdjęcie na okładkę"; +App::$strings["Unable to update menu."] = "Nie można zaktualizować menu."; +App::$strings["Unable to create menu."] = "Nie można utworzyć menu."; +App::$strings["Menu Name"] = "Nazwa menu"; +App::$strings["Unique name (not visible on webpage) - required"] = "Unikalna nazwa (niewidoczna na stronie) - wymagana"; +App::$strings["Menu Title"] = "Tytuł menu"; +App::$strings["Visible on webpage - leave empty for no title"] = "Widoczne na stronie - pozostaw puste bez tytułu"; +App::$strings["Allow Bookmarks"] = "Zezwalaj na zakładki"; +App::$strings["Menu may be used to store saved bookmarks"] = "Menu może służyć do przechowywania zapisanych zakładek"; +App::$strings["Submit and proceed"] = "Prześlij i kontynuuj"; +App::$strings["Menus"] = "Menu"; +App::$strings["Bookmarks allowed"] = "Zakładki są dozwolone"; +App::$strings["Delete this menu"] = "Usuń to menu"; +App::$strings["Edit menu contents"] = "Edytuj zawartość menu"; +App::$strings["Edit this menu"] = "Edytuj to menu"; +App::$strings["Menu could not be deleted."] = "Nie udało się usunąć menu."; +App::$strings["Edit Menu"] = "Edytuj menu"; +App::$strings["Add or remove entries to this menu"] = "Dodaj lub usuń posty w tym menu"; +App::$strings["Menu name"] = "Nazwa menu"; +App::$strings["Must be unique, only seen by you"] = "Musi być wyjątkowy, widoczny tylko dla Ciebie"; +App::$strings["Menu title"] = "Tytuł menu"; +App::$strings["Menu title as seen by others"] = "Tytuł menu widziany przez innych"; +App::$strings["Allow bookmarks"] = "Zezwalaj na zakładki"; +App::$strings["Failed to create source. No channel selected."] = "Nie udało się utworzyć źródła. Nie wybrano kanału."; +App::$strings["Source created."] = "Utworzono źródło."; +App::$strings["Source updated."] = "Źródło zaktualizowane."; +App::$strings["Sources App"] = "Aplikacja Sources"; +App::$strings["Automatically import channel content from other channels or feeds"] = "Automatycznie importuj zawartość kanału z innych kanałów lub źródeł"; +App::$strings["*"] = "*"; +App::$strings["Channel Sources"] = "Źródła kanałów"; +App::$strings["Manage remote sources of content for your channel."] = "Zarządzaj zdalnymi źródłami treści na swoim kanale."; +App::$strings["New Source"] = "Nowe źródło"; +App::$strings["Import all or selected content from the following channel into this channel and distribute it according to your channel settings."] = "Zaimportuj wszystkie lub wybrane treści z następującego kanału do tego kanału i rozpowszechniaj je zgodnie z ustawieniami kanału."; +App::$strings["Only import content with these words (one per line)"] = "Importuj tylko zawartość z tymi słowami (po jednym w każdym wierszu)"; +App::$strings["Leave blank to import all public content"] = "Pozostaw puste, aby zaimportować całą zawartość publiczną"; +App::$strings["Channel Name"] = "Nazwa kanału"; +App::$strings["Add the following categories to posts imported from this source (comma separated)"] = "Dodaj następujące kategorie do postów zaimportowanych z tego źródła (oddzielone przecinkami)"; +App::$strings["Resend posts with this channel as author"] = "Wyślij ponownie posty z tym kanałem jako autorem"; +App::$strings["Copyrights may apply"] = "Copyrights may apply"; +App::$strings["Source not found."] = "Nie znaleziono źródła."; +App::$strings["Edit Source"] = "Edytuj źródło"; +App::$strings["Delete Source"] = "Usuń źródło"; +App::$strings["Source removed"] = "Źródło zostało usunięte"; +App::$strings["Unable to remove source."] = "Nie można usunąć źródła."; +App::$strings["Poke App"] = "Aplikacja Poke"; +App::$strings["Poke somebody in your addressbook"] = "Szturchij kogoś w swojej książce adresowej"; +App::$strings["Poke"] = "Szturchnij"; +App::$strings["Poke somebody"] = "Szturchnij kogoś"; +App::$strings["Poke/Prod"] = "Szturchnij"; +App::$strings["Poke, prod or do other things to somebody"] = "Szturchać, badać, testować lub robić z kimś podobne rzeczy"; +App::$strings["Recipient"] = "Odbiorca"; +App::$strings["Choose what you wish to do to recipient"] = "Wybierz, co chcesz zrobić odbiorcy"; +App::$strings["Make this post private"] = "Ustaw ten post jako prywatny"; +App::$strings["No such group"] = "Nie ma takiej grupy"; +App::$strings["No such channel"] = "Nie ma takiego kanału"; +App::$strings["Privacy group is empty"] = "Grupa prywatności jest pusta"; +App::$strings["Privacy group: "] = "Grupa prywatności: "; +App::$strings["Invalid channel."] = "Zły kanał."; +App::$strings["Can not copy folder into itself."] = "Nie można skopiować folderu do siebie."; +App::$strings["Can not move folder \"%s\" into itself."] = "Nie można przenieść folderu \"%s\" do samego siebie."; +App::$strings["item"] = "element"; +App::$strings["Remote privacy information not available."] = "Zdalne informacje o prywatności nie są dostępne."; +App::$strings["Visible to:"] = "Widoczne dla:"; +App::$strings["Change filename to"] = "Zmień nazwę pliku na"; +App::$strings["Select a target location"] = "Wybierz lokalizację docelową"; +App::$strings["Copy to target location"] = "Skopiuj do lokalizacji docelowej"; +App::$strings["Set permissions for all files and sub folders"] = "Ustaw uprawnienia dla wszystkich plików i podfolderów"; +App::$strings["Notify your contacts about this file"] = "Powiadom swoje kontakty o tym pliku"; +App::$strings["File category"] = "Kategoria plików"; +App::$strings["Total"] = "Ogólnie"; +App::$strings["Shared"] = "Udostępnione"; +App::$strings["Add Files"] = "Dodaj pliki"; +App::$strings["Admin Delete"] = "Usuń przez administratora"; +App::$strings["parent"] = "rodzic"; +App::$strings["Select All"] = "Zaznacz wszystko"; +App::$strings["Bulk Actions"] = "Działania masowe"; +App::$strings["Adjust Permissions"] = "Dostosuj uprawnienia"; +App::$strings["Move or Copy"] = "Przenieś lub skopiuj"; +App::$strings["Info"] = "Informacje"; +App::$strings["Rename"] = "Zień nazwę"; +App::$strings["Post"] = "Post"; +App::$strings["Attachment BBcode"] = "Attachment BBcode"; +App::$strings["Embed BBcode"] = "Osadź BBcode"; +App::$strings["Link BBcode"] = "Połącz BBcode"; +App::$strings["You are using %1\$s of your available file storage."] = "Używasz %1\$s dostępnego miejsca na pliki."; +App::$strings["You are using %1\$s of %2\$s available file storage. (%3\$s%)"] = "Używasz %1\$s z %2\$s dostępnego miejsca na pliki. (%3\$s %)"; +App::$strings["WARNING:"] = "OSTRZEŻENIE:"; +App::$strings["Create new folder"] = "Stwórz nowy folder"; +App::$strings["Upload file"] = "Przesyłanie pliku"; +App::$strings["Drop files here to immediately upload"] = "Upuść pliki tutaj, aby natychmiast przesłać"; +App::$strings["You can select files via the upload button or drop them right here or into an existing folder."] = "Możesz wybrać pliki za pomocą przycisku przesyłania lub upuścić je tutaj lub do istniejącego folderu."; +App::$strings["Remote authentication blocked. You are logged into this site locally. Please logout and retry."] = "Zdalne uwierzytelnianie zablokowane. Jesteś zalogowany lokalnie na tej stronie. Wyloguj się i spróbuj ponownie."; +App::$strings["Welcome %s. Remote authentication successful."] = "Witaj %s. Zdalne uwierzytelnianie powiodło się."; +App::$strings["A deleted group with this name was revived. Existing item permissions may apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Przywrócono usuniętą grupę o tej nazwie. Istniejące uprawnienia dotyczące elementów mogą dotyczyć tej grupy i wszystkich przyszłych członków. Jeśli nie tego chciałeś, utwórz kolejną grupę o innej nazwie."; +App::$strings["Add new connections to this privacy group"] = "Dodaj nowe połączenia do tej grupy prywatności"; +App::$strings["edit"] = "edutuj"; +App::$strings["Edit group"] = "Edytuj grupę"; +App::$strings["Add privacy group"] = "Dodaj grupę prywatności"; +App::$strings["Channels not in any privacy group"] = "Kanały spoza jakiejkolwiek grupy prywatności"; +App::$strings["add"] = "dodaj"; +App::$strings["Channel is blocked on this site."] = "Kanał jest zablokowany na tej stronie."; +App::$strings["Channel location missing."] = "Brak lokalizacji kanału."; +App::$strings["Remote channel or protocol unavailable."] = "Zdalny kanał lub protokół jest niedostępny."; +App::$strings["Channel discovery failed."] = "Wyszukanie kanału nie powiodło się."; +App::$strings["Protocol disabled."] = "Protokół wyłączony."; +App::$strings["Cannot connect to yourself."] = "Nie można połączyć się ze sobą."; +App::$strings["error saving data"] = "błąd podczas zapisywania danych"; +App::$strings["Apps"] = "Aplikacje"; +App::$strings["Affinity Tool"] = "Narzędzie koligacji"; +App::$strings["Site Admin"] = "Administrator serwisu"; +App::$strings["Report Bug"] = "Raport błędów"; +App::$strings["Bookmarks"] = "Zakładki"; +App::$strings["Chatrooms"] = "Czaty"; +App::$strings["Content Filter"] = "Filtr treści"; +App::$strings["Content Import"] = "Import treści"; +App::$strings["Remote Diagnostics"] = "Zdalna diagnostyka"; +App::$strings["Suggest Channels"] = "Zaproponuj kanały"; +App::$strings["Login"] = "Zaloguj się"; +App::$strings["Stream"] = "Strumień"; +App::$strings["Wiki"] = "Wiki"; +App::$strings["Channel Home"] = "Strona główna kanału"; +App::$strings["Calendar"] = "Kalendarz"; +App::$strings["Directory"] = "Katalog"; +App::$strings["Mail"] = "Poczta"; +App::$strings["Chat"] = "Czat"; +App::$strings["Probe"] = "Sonda"; +App::$strings["Suggest"] = "Prpozycja"; +App::$strings["Random Channel"] = "Losowy kanał"; +App::$strings["Invite"] = "Zaproszenie"; +App::$strings["Features"] = "Funkcje"; +App::$strings["Language"] = "Język"; +App::$strings["Profile Photo"] = "Zdjęcie profilowe"; +App::$strings["Profiles"] = "Profile"; +App::$strings["Notifications"] = "Powiadomienie"; +App::$strings["Order Apps"] = "Kolejność aplikacji"; +App::$strings["CardDAV"] = "CardDAV"; +App::$strings["Guest Access"] = "Dostęp gościa"; +App::$strings["Notes"] = "Uwagi"; +App::$strings["OAuth Apps Manager"] = "Menadżer aplikacji OAuth"; +App::$strings["OAuth2 Apps Manager"] = "Menadżer aplikacji OAuth2"; +App::$strings["PDL Editor"] = "Edytor PDL"; +App::$strings["My Chatrooms"] = "Moje czaty"; +App::$strings["Channel Export"] = "Eksport kanału"; +App::$strings["Purchase"] = "Zakup"; +App::$strings["Undelete"] = "Cofnij usunięcie"; +App::$strings["Add to app-tray"] = "Dodaj do zasobnika aplikacji"; +App::$strings["Remove from app-tray"] = "Usuń z zasobnika aplikacji"; +App::$strings["Pin to navbar"] = "Przypnij do paska nawigacyjnego"; +App::$strings["Unpin from navbar"] = "Odepnij od paska nawigacyjnego"; +App::$strings["Source code of failed update: "] = "Kod źródłowy nieudanej aktualizacji: "; +App::$strings["Update Error at %s"] = "Błąd aktualizacji na %s"; +App::$strings["Update %s failed. See error logs."] = "Aktualizacja %s nie powiodła się. Zobacz dzienniki błędów."; +App::$strings["A deleted list with this name was revived. Existing item permissions may apply to this list and any future members. If this is not what you intended, please create another list with a different name."] = "Przywrócono usuniętą listę o tej nazwie. Istniejące uprawnienia dotyczące elementów mogą dotyczyć tej listy i wszystkich przyszłych członków. Jeśli nie tego chciałeś, utwórz kolejną listę z inną nazwą."; +App::$strings["Add new connections to this access list"] = "Dodaj nowe połączenia do tej listy dostępu"; +App::$strings["Lists"] = "Listy"; +App::$strings["Edit list"] = "Edytuj listę"; +App::$strings["Create new list"] = "Utwórz nową listę"; +App::$strings["Channels not in any access list"] = "Kanały, których nie ma na żadnej liście dostępu"; +App::$strings["Missing room name"] = "Brak nazwy pokoju"; +App::$strings["Duplicate room name"] = "Zduplikowana nazwa pokoju"; +App::$strings["Invalid room specifier."] = "Nieprawidłowy specyfikator sali."; +App::$strings["Room not found."] = "Nie znaleziono pokoju."; +App::$strings["Room is full"] = "Pokój jest pełny"; +App::$strings["0. Beginner/Basic"] = "0. Poczatkujący/Podstawowy"; +App::$strings["1. Novice - not skilled but willing to learn"] = "1. Nowicjusz - nie ma umiejętności, ale chętnie się uczy"; +App::$strings["2. Intermediate - somewhat comfortable"] = "2. Średniozaawansowany - dość wygodne"; +App::$strings["3. Advanced - very comfortable"] = "3. Zaawansowany - bardzo wygodne"; +App::$strings["4. Expert - I can write computer code"] = "4. Ekspert - umiem pisać kod komputerowy"; +App::$strings["5. Wizard - I probably know more than you do"] = "5. Czarodziej - prawdopodobnie wiem więcej niż Ty"; +App::$strings["\$Projectname Notification"] = "Powiadomienie \$Projectname"; +App::$strings["\$projectname"] = "Hubzilla"; +App::$strings["Thank You,"] = "Dziękujemy,"; +App::$strings["%s Administrator"] = "Administrator %s"; +App::$strings["This email was sent by %1\$s at %2\$s."] = "Ta wiadomość e-mail została wysłana przez %1\$s na numer %2\$s."; +App::$strings["To stop receiving these messages, please adjust your Notification Settings at %s"] = "Aby nie otrzymywać tych wiadomości, zmień ustawienia powiadomień na %s"; +App::$strings["To stop receiving these messages, please adjust your %s."] = "Aby nie otrzymywać tych wiadomości, zmień %s."; +App::$strings["%s "] = "%s "; +App::$strings["[\$Projectname:Notify] New mail received at %s"] = "[\$Projectname:Notify] Otrzymano nową pocztę na %s"; +App::$strings["%1\$s sent you a new private message at %2\$s."] = "%1\$s wysłał Ci nową prywatną wiadomość na %2\$s."; +App::$strings["%1\$s sent you %2\$s."] = "%1\$s wysłał Ci %2\$s."; +App::$strings["a private message"] = "prywatna wiadomość"; +App::$strings["Please visit %s to view and/or reply to your private messages."] = "Odwiedź %s, aby wyświetlić albo odpowiedzieć na swoje prywatne wiadomości."; +App::$strings["commented on"] = "skomentował"; +App::$strings["liked"] = "polubił"; +App::$strings["disliked"] = "dezaprobował"; +App::$strings["voted on"] = "głosował"; +App::$strings["%1\$s %2\$s [zrl=%3\$s]a %4\$s[/zrl]"] = "%1\$s %2\$s [zrl=%3\$s]%4\$s[/zrl]"; +App::$strings["%1\$s %2\$s [zrl=%3\$s]%4\$s's %5\$s[/zrl]"] = "%1\$s %2\$s [zrl=%3\$s]%5\$s %4\$s[/zrl]"; +App::$strings["%1\$s %2\$s [zrl=%3\$s]your %4\$s[/zrl]"] = "%1\$s %2\$s [zrl=%3\$s]Twój %4\$s[/zrl]"; +App::$strings["[\$Projectname:Notify] Moderated Comment to conversation #%1\$d by %2\$s"] = "[\$Projectname:Notify] Moderowany komentarz do rozmowy #%1\$d przez %2\$s"; +App::$strings["[\$Projectname:Notify] Comment to conversation #%1\$d by %2\$s"] = "[\$Projectname:Notify] Komentarz do roz,owy #%1\$d przez %2\$s"; +App::$strings["%1\$s commented on an item/conversation you have been following."] = "%1\$s skomentował obserwowany element/rozmowę."; +App::$strings["Please visit %s to view and/or reply to the conversation."] = "Odwiedź %s, aby wyświetlić rozmowę albo odpowiedzieć na nią."; +App::$strings["Please visit %s to approve or reject this comment."] = "Odwiedź %s, aby zaakceptować lub odrzucić ten komentarz."; +App::$strings["%1\$s liked [zrl=%2\$s]your %3\$s[/zrl]"] = "%1\$s polubił [zrl=%2\$s]Twój %3\$s[/zrl]"; +App::$strings["[\$Projectname:Notify] Like received to conversation #%1\$d by %2\$s"] = "[\$Projectname:Notify] Polubienie wysłane dla rozmowy #%1\$d przez %2\$s"; +App::$strings["%1\$s liked an item/conversation you created."] = "%1\$s polubił utworzony przez Ciebie element/rozmowę."; +App::$strings["[\$Projectname:Notify] %s posted to your profile wall"] = "[\$Projectname:Notify]%s opublikowany na Twojej ścianie profilu"; +App::$strings["%1\$s posted to your profile wall at %2\$s"] = "%1\$s opublikowano na ścianie Twojego profilu pod adresem %2\$s"; +App::$strings["%1\$s posted to [zrl=%2\$s]your wall[/zrl]"] = "%1\$s opublikował na [zrl=%2\$s]Twojej ścianie[/zrl]"; +App::$strings["[\$Projectname:Notify] %s tagged you"] = "[\$Projectname:Notify]%s oznaczył Cię tagiem"; +App::$strings["%1\$s tagged you at %2\$s"] = "%1\$s oznaczył Cię tagiem %2\$s"; +App::$strings["%1\$s [zrl=%2\$s]tagged you[/zrl]."] = "%1\$s [zrl=%2\$s]oznaczył Cię tagiem[/zrl]."; +App::$strings["[\$Projectname:Notify] %1\$s poked you"] = "[\$Projectname:Notify] %1\$s szturchnął Cię"; +App::$strings["%1\$s poked you at %2\$s"] = "%1\$s szturchnął Cię %2\$s"; +App::$strings["%1\$s [zrl=%2\$s]poked you[/zrl]."] = "%1\$s [zrl=%2\$s]szturchnął Cię[/zrl]."; +App::$strings["[\$Projectname:Notify] %s tagged your post"] = "[\$Projectname:Notify] %s oznaczył tagiem Twój post"; +App::$strings["%1\$s tagged your post at %2\$s"] = "%1\$s oznaczył tagiem Twój post na %2\$s"; +App::$strings["%1\$s tagged [zrl=%2\$s]your post[/zrl]"] = "%1\$s tagged [zrl=%2\$s]Twój post[/zrl]"; +App::$strings["[\$Projectname:Notify] Introduction received"] = "[\$Projectname:Notify] Otrzymano wprowadzenie"; +App::$strings["You've received an new connection request from '%1\$s' at %2\$s"] = "Otrzymałeś nowe żądanie połączenia od „%1\$s” na %2\$s"; +App::$strings["You've received [zrl=%1\$s]a new connection request[/zrl] from %2\$s."] = "Otrzymałeś [zrl=%1\$s]nowe żądanie połączenia [/zrl] od %2\$s."; +App::$strings["You may visit their profile at %s"] = "Możesz odwiedzić ich profil na %s"; +App::$strings["Please visit %s to approve or reject the connection request."] = "Odwiedź %s, aby zatwierdzić lub odrzucić prośbę o połączenie."; +App::$strings["[\$Projectname:Notify] Friend suggestion received"] = "[\$Projectname:Notify] Otrzymano propozycję znajomości"; +App::$strings["You've received a friend suggestion from '%1\$s' at %2\$s"] = "Otrzymałeś propozycję znajomości od „%1\$s” na %2\$s"; +App::$strings["You've received [zrl=%1\$s]a friend suggestion[/zrl] for %2\$s from %3\$s."] = "Otrzymałeś [zrl=%1\$s] prpozycję znajomości[/ zrl] dla %2\$s od %3\$s."; +App::$strings["Name:"] = "Nazwa:"; +App::$strings["Photo:"] = "Zdjęcie:"; +App::$strings["Please visit %s to approve or reject the suggestion."] = "Odwiedź %s, aby zaakceptować lub odrzucić popozycję."; +App::$strings["[\$Projectname:Notify]"] = "[\$Projectname:Notify]"; +App::$strings["created a new poll"] = "utworzył nową ankietę"; +App::$strings["created a new post"] = "utworzył nowy post"; +App::$strings["voted on %s's poll"] = "głosował w ankiecie %s"; +App::$strings["commented on %s's post"] = "skomentował post %s"; +App::$strings["repeated %s's post"] = "powtórzony post %s"; +App::$strings["edited a post dated %s"] = "edytował post z dnia %s"; +App::$strings["edited a comment dated %s"] = "edytował komentarz z dnia %s"; +App::$strings["created an event"] = "utworzono wydarzenie"; +App::$strings["Unable to verify site signature for %s"] = "Nie można zweryfikować podpisu witryny dla %s"; +App::$strings["(No Title)"] = "(Brak tytułu)"; +App::$strings["Wiki page create failed."] = "Tworzenie strony Wiki nie powiodło się."; +App::$strings["Wiki not found."] = "Nie znaleziono wiki."; +App::$strings["Destination name already exists"] = "Nazwa celu już istnieje"; +App::$strings["Page not found"] = "Strona nie znaleziona"; +App::$strings["Error reading page content"] = "Błąd podczas odczytu zawartości strony"; +App::$strings["Error reading wiki"] = "Błąd podczas odczytu wiki"; +App::$strings["Page update failed."] = "Aktualizacja strony nie powiodła się."; +App::$strings["Nothing deleted"] = "Nic nie zostało usunięte"; +App::$strings["Compare: object not found."] = "Porównaj: nie znaleziono obiektu."; +App::$strings["Page updated"] = "Strona została zaktualizowana"; +App::$strings["Untitled"] = "Bez tytułu"; +App::$strings["Wiki resource_id required for git commit"] = "Identyfikator zasobu Wiki wymagany do zatwierdzenia przez Git"; +App::$strings["__ctx:wiki_history__ Message"] = "Wiadomość"; +App::$strings["Date"] = "Data"; +App::$strings["Compare"] = "Porównaj"; +App::$strings["Different viewers will see this text differently"] = "Różni widzowie będą inaczej widzieć ten tekst"; +App::$strings["Private Message"] = "Wiadomość prywatna"; +App::$strings["Privacy conflict. Discretion advised."] = "Konflikt prywatności. Zalecana dyskrecja."; +App::$strings["Select"] = "Wybierz"; +App::$strings["I will attend"] = "Będę uczestniczył"; +App::$strings["I will not attend"] = "Nie będę uczestniczył"; +App::$strings["I might attend"] = "Mogę wziąć udział"; +App::$strings["I agree"] = "Zgadzam się"; +App::$strings["I disagree"] = "Nie zgadzam się"; +App::$strings["I abstain"] = "Wstrzymuję się"; +App::$strings["Toggle Star Status"] = "Przełącz stan gwiazdki"; +App::$strings["Message signature validated"] = "Podpis wiadomości został zatwierdzony"; +App::$strings["Message signature incorrect"] = "Niepoprawny podpis wiadomości"; +App::$strings["Conversation Tools"] = "Narzędzia do konwersacji"; +App::$strings["like"] = "lubi"; +App::$strings["dislike"] = "nie lubi"; +App::$strings["Reply on this comment"] = "Odpowiedz na ten komentarz"; +App::$strings["reply"] = "odpowiedz"; +App::$strings["Reply to"] = "Odpowiedź dla"; +App::$strings["Share This"] = "Udostępnij to"; +App::$strings["share"] = "udostępnij"; +App::$strings["Delivery Report"] = "Raport dostawy"; +App::$strings["%d comment"] = array( + 0 => "%d komentarz", + 1 => "%d komentarze", + 2 => "%d komentarzy", +); +App::$strings["%d unseen"] = "%d niezobaczone"; +App::$strings["to"] = "do"; +App::$strings["via"] = "poprzez"; +App::$strings["Wall-to-Wall"] = "Wall-to-Wall"; +App::$strings["via Wall-To-Wall:"] = "poprzez Wall-To-Wall:"; +App::$strings["from %s"] = "od %s"; +App::$strings["last edited: %s"] = "ostatnio edytowane: %s"; +App::$strings["Expires: %s"] = "Wygasa: %s"; +App::$strings["Attend"] = "Uczestnicz"; +App::$strings["Attendance Options"] = "Opcje obecności"; +App::$strings["Vote"] = "Głosuj"; +App::$strings["Voting Options"] = "Opcje głosowania"; +App::$strings["Go to previous comment"] = "Przejdź do poprzedniego komentarza"; +App::$strings["Pinned post"] = "Posty przypięte"; +App::$strings["Unpin from the top"] = "Odepnij z góry"; +App::$strings["Pin to the top"] = "Przypnij u góry"; +App::$strings["Save Bookmarks"] = "Zapisz zakładki"; +App::$strings["Add to Calendar"] = "Dodaj do kalendarza"; +App::$strings["This is an unsaved preview"] = "Ten podgląd nie został zapisany"; +App::$strings["%s show all"] = "%s pokaż wszystko"; +App::$strings["Bold"] = "Gruby"; +App::$strings["Italic"] = "Pochyły"; +App::$strings["Underline"] = "Podkreślony"; +App::$strings["Quote"] = "Cytat"; +App::$strings["Code"] = "Kod"; +App::$strings["Image"] = "Obraz"; +App::$strings["Attach/Upload file"] = "Załącz / prześlij plik"; +App::$strings["Insert Link"] = "Wstaw link"; +App::$strings["Video"] = "Wideo"; +App::$strings["Your full name (required)"] = "Twoja imię i nazwisko lub pełna nazwa (wymagane)"; +App::$strings["Your email address (required)"] = "Twój adres email (wymagane)"; +App::$strings["Your website URL (optional)"] = "Adres URL Twojej witryny (opcjonalnie)"; +App::$strings["Likes %1\$s's %2\$s"] = "Polibień %2\$s %1\$s"; +App::$strings["Doesn't like %1\$s's %2\$s"] = "Dezaprobat %2\$s %1\$s"; +App::$strings["Will attend %s's event"] = "Weźmie udział w wydarzeniu %s"; +App::$strings["Will not attend %s's event"] = "Nie weźmie udziału w wydarzeniu %s"; +App::$strings["May attend %s's event"] = "Może uczestniczyć w wydarzeniu %s"; +App::$strings["May not attend %s's event"] = "Nie może uczestniczyć w wydarzeniu %s"; +App::$strings["ActivityPub"] = "ActivityPub"; +App::$strings["Wiki updated successfully"] = "Wiki zaktualizowane pomyślnie"; +App::$strings["Wiki files deleted successfully"] = "Pliki Wiki zostały pomyślnie usunięte"; +App::$strings["Directory Options"] = "Opcje katalogu"; +App::$strings["Safe Mode"] = "Tryb bezpieczny"; +App::$strings["Public Forums Only"] = "Tylko fora publiczne"; +App::$strings["This Website Only"] = "Tylko ten serwis"; +App::$strings["__ctx:permcat__ default"] = "domyślnie"; +App::$strings["__ctx:permcat__ follower"] = "obserwujący"; +App::$strings["__ctx:permcat__ contributor"] = "współpracownik"; +App::$strings["__ctx:permcat__ publisher"] = "wydawca"; +App::$strings["Unable to verify channel signature"] = "Nie można zweryfikować podpisu kanału"; +App::$strings["Visible to your default audience"] = "Widoczne dla domyślnych odbiorców"; +App::$strings["Only me"] = "Tylko ja"; +App::$strings["Public"] = "Publiczny"; +App::$strings["Anybody in the \$Projectname network"] = "Każdy w sieci \$Projectname"; +App::$strings["Any account on %s"] = "Dowolne konto na %s"; +App::$strings["Any of my connections"] = "Wszystkie moje połączenia"; +App::$strings["Only connections I specifically allow"] = "Tylko połączenia, na które wyraźnie zezwalam"; +App::$strings["Anybody authenticated (could include visitors from other networks)"] = "Każdy uwierzytelniony (może obejmować odwiedzających z innych sieci)"; +App::$strings["Any connections including those who haven't yet been approved"] = "Wszelkie połączenia, w tym te, które nie zostały jeszcze zatwierdzone"; +App::$strings["This is your default setting for the audience of your normal stream, and posts."] = "To jest domyślne ustawienie odbiorców Twojego normalnego strumienia i postów."; +App::$strings["This is your default setting for who can view your default channel profile"] = "To jest domyślne ustawienie określające, kto może wyświetlać Twój domyślny profil kanału"; +App::$strings["This is your default setting for who can view your connections"] = "To jest domyślne ustawienie określające, kto może wyświetlać Twoje połączenia"; +App::$strings["This is your default setting for who can view your file storage and photos"] = "Jest to domyślne ustawienie określające, kto może wyświetlać miejsce na pliki i zdjęcia"; +App::$strings["This is your default setting for the audience of your webpages"] = "To jest domyślne ustawienie dotyczące odbiorców Twoich stron internetowych"; +App::$strings["Everything"] = "Wszystko"; +App::$strings["Select Channel"] = "Wybierz kanał"; +App::$strings["Read-write"] = "Czytanie i zapis"; +App::$strings["Read-only"] = "Tylko odczyt"; +App::$strings["Channel Calendar"] = "Kalendarz kanału"; +App::$strings["Shared CalDAV Calendars"] = "Udostępnione kalendarze CalDAV"; +App::$strings["Share this calendar"] = "Udostępnij ten kalendarz"; +App::$strings["Calendar name and color"] = "Nazwa kalendarza i kolor"; +App::$strings["Create new CalDAV calendar"] = "Utwórz nowy kalendarz CalDAV"; +App::$strings["Calendar Name"] = "Nazwa kalendarza"; +App::$strings["Calendar Tools"] = "Narzędzia kalendarza"; +App::$strings["Import calendar"] = "Importuj kalendarz"; +App::$strings["Select a calendar to import to"] = "Wybierz kalendarz do zaimportowania"; +App::$strings["Addressbooks"] = "Książki adresowe"; +App::$strings["Addressbook name"] = "Nazwa książki adresowej"; +App::$strings["Create new addressbook"] = "Utwórz nową książkę adresową"; +App::$strings["Addressbook Name"] = "Nazwa książki adresowej"; +App::$strings["Addressbook Tools"] = "Narzędzia książki adresowej"; +App::$strings["Import addressbook"] = "Importuj książkę adresową"; +App::$strings["Select an addressbook to import to"] = "Wybierz książkę adresową do zaimportowania"; +App::$strings["Saved Folders"] = "Zapisywanie foldery"; +App::$strings["Tags"] = "Tagi"; +App::$strings["Archives"] = "Archiwa"; +App::$strings["Chat Members"] = "Członkowie czatu"; +App::$strings["Rating Tools"] = "Narzędzia"; +App::$strings["Rate Me"] = "Oceń mnie"; +App::$strings["View Ratings"] = "Pokaż oceny"; +App::$strings["Add new page"] = "Dodaj nową stronę"; +App::$strings["Wiki Pages"] = "Strony wiki"; +App::$strings["Page name"] = "Nazwa strony"; +App::$strings["Bookmarked Chatrooms"] = "Czaty dodane do zakładek"; +App::$strings["photo/image"] = "zdjęcie/obraz"; +App::$strings["Forums"] = "Fora"; +App::$strings["Remove term"] = "Usuń termin"; +App::$strings["Saved Searches"] = "Zapisywanie wyszukiwania"; +App::$strings["You have %1$.0f of %2$.0f allowed connections."] = "Masz %1$.0f z %2$.0f dozwolonych połączeń."; +App::$strings["Add New Connection"] = "Dodaj nowe połączenie"; +App::$strings["Enter channel address"] = "Wprowadź adres kanału"; +App::$strings["Examples: bob@example.com, https://example.com/barbara"] = "Przykłady: bob@example.com, https://example.com/barbara"; +App::$strings["Suggestions"] = "Prpozycje"; +App::$strings["See more..."] = "Zobacz więcej..."; +App::$strings["Tasks"] = "Zadania"; +App::$strings["Member registrations waiting for confirmation"] = "Rejestracja członków czeka na potwierdzenie"; +App::$strings["Inspect queue"] = "Sprawdź kolejkę"; +App::$strings["DB updates"] = "Aktualizacje bazy danych"; +App::$strings["Admin"] = "Admin"; +App::$strings["Addon Features"] = "Funkcje dodatków"; +App::$strings["Overview"] = "Przegląd"; +App::$strings["App Collections"] = "Kolekcja aplikacji"; +App::$strings["Installed apps"] = "Zainstalowane aplikacje"; +App::$strings["Commented Date"] = "Data skomentowania"; +App::$strings["Order by last commented date"] = "Sortuj według najnowszej daty skomentowania"; +App::$strings["Posted Date"] = "Data opublikowania"; +App::$strings["Order by last posted date"] = "Sortuj według najnowszej daty publikacji"; +App::$strings["Date Unthreaded"] = "Data zakończenia wątku"; +App::$strings["Order unthreaded by date"] = "Sortuj według daty zakończenia wątku"; +App::$strings["Stream Order"] = "Kolejność strumienia"; +App::$strings["Private Mail Menu"] = "Menu prywatnej poczty"; +App::$strings["Combined View"] = "Widok łączony"; +App::$strings["Inbox"] = "Skrzynka odbiorcza"; +App::$strings["Outbox"] = "Skrzynka nadawcza"; +App::$strings["New Message"] = "Nowy komunikat"; +App::$strings["Refresh"] = "Odśwież"; +App::$strings["HQ Control Panel"] = "Panel kontrolny HQ"; +App::$strings["Create a new post"] = "Utwórz nowy post"; +App::$strings["Events Tools"] = "Narzędzia wydarzeń"; +App::$strings["Export Calendar"] = "Eksport kalendarza"; +App::$strings["Import Calendar"] = "Import kalendarza"; +App::$strings["Direct Messages"] = "Bezpośrednie wiadomości"; +App::$strings["Show direct (private) messages"] = "Pokaż bezpośrednie (prywatne) wiadomości"; +App::$strings["Events"] = "Wydarzenia"; +App::$strings["Show posts that include events"] = "Pokaż posty zawierające wydarzenia"; +App::$strings["Polls"] = "Ankiety"; +App::$strings["Show posts that include polls"] = "Pokaż posty zawierające ankiety"; +App::$strings["Show posts related to the %s privacy group"] = "Pokaż posty związane z grupą prywatności %s"; +App::$strings["Show my privacy groups"] = "Pokaż moje grupy prywatności"; +App::$strings["Show posts to this forum"] = "Pokaż posty na tym forum"; +App::$strings["Show forums"] = "Pokaż fora"; +App::$strings["Starred Posts"] = "Wyróżnione posty"; +App::$strings["Show posts that I have starred"] = "Pokaż posty, które oznaczyłem gwiazdką"; +App::$strings["Personal Posts"] = "Posty osobiste"; +App::$strings["Show posts that mention or involve me"] = "Pokaż posty, które wspominają o mnie lub mnie dotyczą"; +App::$strings["Show posts that I have filed to %s"] = "Pokaż posty przesłane przeze mnie do %s"; +App::$strings["Show filed post categories"] = "Pokaż wprowadzone kategorie postów"; +App::$strings["Panel search"] = "Przeszukiwanie panelu"; +App::$strings["Filter by name"] = "Filtruj wg nazwy"; +App::$strings["Remove active filter"] = "Usuń aktywny filtr"; +App::$strings["Stream Filters"] = "Filtry strumienia"; +App::$strings["__ctx:widget__ Activity"] = "Aktywność"; +App::$strings["New Network Activity"] = "Nowa aktywność sieciowa"; +App::$strings["New Network Activity Notifications"] = "Powiadomienia o nowej aktywności sieciowej"; +App::$strings["View your network activity"] = "Wyświetl swoją aktywność w sieci"; +App::$strings["Mark all notifications read"] = "Oznacz wszystkie powiadomienia jako przeczytane"; +App::$strings["Show new posts only"] = "Pokaż tylko nowe posty"; +App::$strings["Filter by name or address"] = "Filtruj według nazwy lub adresu"; +App::$strings["New Home Activity"] = "Nowa aktywność domowa"; +App::$strings["New Home Activity Notifications"] = "Powiadomienia o nowej aktywności domowej"; +App::$strings["View your home activity"] = "Wyświetl swoją aktywność domową"; +App::$strings["Mark all notifications seen"] = "Oznacz wszystkie powiadomienia jako oglądnięte"; +App::$strings["New Direct Messages"] = "Nowe bezpośrednie wiadomości"; +App::$strings["New Direct Messages Notifications"] = "Powiadomienia o nowych wiadomościach bezpośrednich"; +App::$strings["View your direct messages"] = "Wyświetl swoje bezpośrednie wiadomości"; +App::$strings["New Mails"] = "Nowe wiadomości e-mail"; +App::$strings["New Mails Notifications"] = "Powiadomienia o nowych wiadomościach e-mail"; +App::$strings["View your private mails"] = "Zobacz swoje prywatne wiadomości"; +App::$strings["Mark all messages seen"] = "Oznacz wszystkie wiadomości jako oglądnięte"; +App::$strings["New Events"] = "Nowe wydarzenia"; +App::$strings["New Events Notifications"] = "Powiadomienia o nowych wydarzeniach"; +App::$strings["View events"] = "Pokaż wydarzenia"; +App::$strings["Mark all events seen"] = "Oznacza wydarzenia jako oglądnięte"; +App::$strings["New Connections Notifications"] = "Powiadomienia o nowych połączeniach"; +App::$strings["View all connections"] = "Pokaż wszystkie połączenia"; +App::$strings["New Files"] = "Nowe pliki"; +App::$strings["New Files Notifications"] = "Powiadomienia o nowych plikach"; +App::$strings["Notices"] = "Powiadomienia"; +App::$strings["View all notices"] = "Pokaż wszystkie powiadomienia"; +App::$strings["Mark all notices seen"] = "Oznacza wszystkie powiadomienia jako oglądnięte"; +App::$strings["New Registrations"] = "Nowe rejestracje"; +App::$strings["New Registrations Notifications"] = "Powiadomienia o nowych rejestracjach"; +App::$strings["Public Stream Notifications"] = "Powiadomienia o strimieniu publicznym"; +App::$strings["View the public stream"] = "Pokaż strumień publiczny"; +App::$strings["Sorry, you have got no notifications at the moment"] = "W tej chwili nie masz żadnych powiadomień"; +App::$strings["View %s's profile - %s"] = "Pokaż profile %s - %s"; +App::$strings["Don't show"] = "Nie pokazuj"; +App::$strings["Account settings"] = "Ustawienia konta"; +App::$strings["Channel settings"] = "Ustawienia kanału"; +App::$strings["Display settings"] = "Ustawienia wyświetlania"; +App::$strings["Manage locations"] = "Zarządzaj lokalizacjami"; +App::$strings["Suggested Chatrooms"] = "Sugerowane czaty"; +App::$strings["Received Messages"] = "Otrzymane wiadomości"; +App::$strings["Sent Messages"] = "Wysłane wiadomości"; +App::$strings["Conversations"] = "Rozmowy"; +App::$strings["No messages."] = "Brak wiadomości."; +App::$strings["Delete conversation"] = "Usuń rozmowę"; +App::$strings["Profile Creation"] = "Tworzenie profilu"; +App::$strings["Upload profile photo"] = "Prześlij zdjęcie profilowe"; +App::$strings["Upload cover photo"] = "Prześlij zdjęcie okładkowe"; +App::$strings["Edit your profile"] = "Edytuj swój profil"; +App::$strings["Find and Connect with others"] = "Znajdź i połącz się z innymi"; +App::$strings["View the directory"] = "Pokaż katalog"; +App::$strings["Manage your connections"] = "Zarządzaj swoimi połączeniami"; +App::$strings["Communicate"] = "Komunikuj się"; +App::$strings["View your channel homepage"] = "Wyświetl stronę główną swojego kanału"; +App::$strings["View your network stream"] = "Wyświetl swój strumień sieciowy"; +App::$strings["Documentation"] = "Dokumentacja"; +App::$strings["Missing Features?"] = "Brakuje funkcji?"; +App::$strings["Pin apps to navigation bar"] = "Przypinaj aplikacje do paska nawigacji"; +App::$strings["Install more apps"] = "Zainstaluj więcej aplikacji"; +App::$strings["View public stream"] = "Pokaż publiczny strumień"; +App::$strings["Click to show more"] = "Kliknij, aby pokazać więcej"; +App::$strings["Source channel not found."] = "Nie znaleziono kanału źródłowego."; +App::$strings["%d invitation available"] = array( + 0 => "%d dostępne zaproszenie", + 1 => "%d dostępne zaproszenia", + 2 => "%d dostępnych zaproszeń", +); +App::$strings["Find Channels"] = "Znajdź kanały"; +App::$strings["Enter name or interest"] = "Wpisz nazwę lub zainteresowanie"; +App::$strings["Connect/Follow"] = "Połącz/Obserwuj"; +App::$strings["Examples: Robert Morgenstein, Fishing"] = "Przykłady: Robert Morgenstein, łowienie ryb"; +App::$strings["Random Profile"] = "Losowy profil"; +App::$strings["Invite Friends"] = "Zaproś przyjaciół"; +App::$strings["Advanced example: name=fred and country=iceland"] = "Zaawansowany przykład: name=fred i country=iceland"; +App::$strings["Common Connections"] = "Popularne połączenia"; +App::$strings["View all %d common connections"] = "Wyświetl wszystkie %d popularne połączenia"; +App::$strings["likes %1\$s's %2\$s"] = "polubień %1\$s %2\$s"; +App::$strings["doesn't like %1\$s's %2\$s"] = "dezaprobat %1\$s %2\$s"; +App::$strings["%1\$s is now connected with %2\$s"] = "%1\$s jest teraz połączony z %2\$s"; +App::$strings["%1\$s poked %2\$s"] = "%1\$s szturchnął %2\$s"; +App::$strings["poked"] = "szturchnięty"; +App::$strings["View %s's profile @ %s"] = "Pokaż profil %s @ %s"; +App::$strings["Categories:"] = "Kategorie:"; +App::$strings["Filed under:"] = "Złożone pod:"; +App::$strings["View in context"] = "Zobacz w kontekście"; +App::$strings["remove"] = "usuń"; +App::$strings["Loading..."] = "Ładowanie ..."; +App::$strings["Delete Selected Items"] = "Usuń wybrane elementy"; +App::$strings["View Source"] = "Pokaż źródło"; +App::$strings["Follow Thread"] = "Obserwuj wątek"; +App::$strings["Unfollow Thread"] = "Przestań obserwować wątek"; +App::$strings["Edit Connection"] = "Edytuj połączenie"; +App::$strings["Message"] = "Wiadowmość"; +App::$strings["%s likes this."] = "%s lubi to."; +App::$strings["%s doesn't like this."] = "%s nie lubi tego."; +App::$strings["%2\$d people like this."] = array( + 0 => "%2\$d osoba lubi to.", + 1 => "%2\$d osoby lubią tego.", + 2 => "%2\$d osób lubi tego.", +); +App::$strings["%2\$d people don't like this."] = array( + 0 => "%2\$d osoba nie lubi to.", + 1 => "%2\$d osoby nie lubią tego.", + 2 => "%2\$d osób nie lubią tego.", +); +App::$strings["and"] = "i"; +App::$strings[", and %d other people"] = array( + 0 => ", i %d inna osoba", + 1 => ", i %d inne osoby", + 2 => ", i %d innych osób", +); +App::$strings["%s like this."] = "%s lubi to."; +App::$strings["%s don't like this."] = "%s nie lubi tego."; +App::$strings["Set your location"] = "Ustaw swoją lokalizację"; +App::$strings["Clear browser location"] = "Wyczyść lokalizację przeglądarki"; +App::$strings["Embed (existing) photo from your photo albums"] = "Osadź (istniejące) zdjęcie z albumów ze zdjęciami"; +App::$strings["Tag term:"] = "Termin tagu:"; +App::$strings["Where are you right now?"] = "Gdzie teraz jesteś?"; +App::$strings["Choose a different album..."] = "Wybierz inny album..."; +App::$strings["Comments enabled"] = "Włączone komentowanie"; +App::$strings["Comments disabled"] = "Wyłączone komentowanie"; +App::$strings["Page link name"] = "Nazwa linku do strony"; +App::$strings["Post as"] = "Opublikuj jako"; +App::$strings["Toggle voting"] = "Przełącz głosowanie"; +App::$strings["Toggle poll"] = "Przełącz ankietę"; +App::$strings["Option"] = "Opcja"; +App::$strings["Add option"] = "Dodaj opcję"; +App::$strings["Minutes"] = "Minuty"; +App::$strings["Hours"] = "Godziny"; +App::$strings["Days"] = "Dni"; +App::$strings["Allow multiple answers"] = "Zezwalaj na wiele odpowiedzi"; +App::$strings["Disable comments"] = "Wyłącz komentarze"; +App::$strings["Toggle comments"] = "Przełącz komentarze"; +App::$strings["Categories (optional, comma-separated list)"] = "Kategorie (opcjonalnie, lista rozdzielana przecinkami)"; +App::$strings["Other networks and post services"] = "Inne sieci i usługi społecznościowe"; +App::$strings["Set expiration date"] = "Ustaw datę wygaśnięcia"; +App::$strings["Set publish date"] = "Ustaw datę publikacji"; +App::$strings["__ctx:noun__ Attending"] = array( + 0 => "Uczestniczy", + 1 => "Uczestnictwa", + 2 => "Uczestnictw", +); +App::$strings["__ctx:noun__ Not Attending"] = array( + 0 => "Nie uczesticzy", + 1 => "Nie uczestniczą", + 2 => "Nie uczestniczy", +); +App::$strings["__ctx:noun__ Undecided"] = array( + 0 => "Niezdecydowany", + 1 => "Niezdecydowane", + 2 => "Niezdecydowanych", +); +App::$strings["__ctx:noun__ Agree"] = array( + 0 => "Zgadza się", + 1 => "Zgadają się", + 2 => "Zgadza się", +); +App::$strings["__ctx:noun__ Disagree"] = array( + 0 => "Nie zgadza się", + 1 => "Nie zgadzają się", + 2 => "Nie zgadza się", +); +App::$strings["__ctx:noun__ Abstain"] = array( + 0 => "Wstrzymuje się", + 1 => "Wstrzymują się", + 2 => "Wstrzymuje się", +); +App::$strings["Unable to obtain identity information from database"] = "Nie można uzyskać informacji z bazy danych o tożsamości"; +App::$strings["Empty name"] = "Pusta nazwa"; +App::$strings["Name too long"] = "Nazwa jest za długa"; +App::$strings["No account identifier"] = "Brak identyfikatora konta"; +App::$strings["Nickname is required."] = "Pseudonim jest wymagany."; +App::$strings["Unable to retrieve created identity"] = "Nie można pobrać utworzonej tożsamości"; +App::$strings["Default Profile"] = "Domyślny profil"; +App::$strings["Unable to retrieve modified identity"] = "Nie można pobrać zmodyfikowanej tożsamości"; +App::$strings["Requested channel is not available."] = "Żądany kanał nie jest dostępny."; +App::$strings["Create New Profile"] = "Utwórz nowy profil"; +App::$strings["Edit Profile"] = "Edytuj profil"; +App::$strings["Visible to everybody"] = "Widoczne dla każdego"; +App::$strings["Gender:"] = "Płeć:"; +App::$strings["Status:"] = "Status:"; +App::$strings["Homepage:"] = "Strona domowa:"; +App::$strings["Online Now"] = "Teraz online"; +App::$strings["Change your profile photo"] = "Zmień swoje zdjęcie profilowe"; +App::$strings["Female"] = "Kobieta"; +App::$strings["Male"] = "Mężczyzna"; +App::$strings["Trans"] = "Trans"; +App::$strings["Neuter"] = "Neutralne"; +App::$strings["Non-specific"] = "Nie określone"; +App::$strings["Like this channel"] = "Polub ten kanał"; +App::$strings["j F, Y"] = "d M, R"; +App::$strings["j F"] = "d M"; +App::$strings["Birthday:"] = "Urodziny:"; +App::$strings["for %1\$d %2\$s"] = "dla %1\$d %2\$s"; +App::$strings["Tags:"] = "Tagi:"; +App::$strings["Sexual Preference:"] = "Preferencje seksualne:"; +App::$strings["Political Views:"] = "Poglądy polityczne:"; +App::$strings["Religion:"] = "Religia:"; +App::$strings["Hobbies/Interests:"] = "Hobby/Zainteresowania:"; +App::$strings["Likes:"] = "Polubień:"; +App::$strings["Dislikes:"] = "Dezaprobat:"; +App::$strings["Contact information and Social Networks:"] = "Informacje kontaktowe i sieci społecznościowe:"; +App::$strings["My other channels:"] = "Moje inne kanały:"; +App::$strings["Musical interests:"] = "Zainteresowania muzyczne:"; +App::$strings["Books, literature:"] = "Książki, literatura:"; +App::$strings["Television:"] = "Telewizja:"; +App::$strings["Film/dance/culture/entertainment:"] = "Film/taniec/kultura/rozrywka:"; +App::$strings["Love/Romance:"] = "Miłość/romans:"; +App::$strings["Work/employment:"] = "Praca/zatrudnienie:"; +App::$strings["School/education:"] = "Szkoła/edukacja:"; +App::$strings["Like this thing"] = "Jak ta rzecz"; +App::$strings["Start calendar week on Monday"] = "Rozpocznij tydzień kalendarzowy w poniedziałek"; +App::$strings["Default is Sunday"] = "Domyślnie jest to niedziela"; +App::$strings["Event Timezone Selection"] = "Wybór strefy czasowej wydarzenia"; +App::$strings["Allow event creation in timezones other than your own."] = "Zezwalaj na tworzenie wydarzeń w strefach czasowych innych niż Twoja."; +App::$strings["Search by Date"] = "Wyszukaj po dacie"; +App::$strings["Ability to select posts by date ranges"] = "Możliwość wyboru postów według zakresów dat"; +App::$strings["Tag Cloud"] = "Chmura tagów"; +App::$strings["Provide a personal tag cloud on your channel page"] = "Udostępnij osobistą chmurę tagów na stronie swojego kanału"; +App::$strings["Use blog/list mode"] = "Użyj trybu bloga/listy"; +App::$strings["Comments will be displayed separately"] = "Komentarze będą wyświetlane osobno"; +App::$strings["Connection Filtering"] = "Filtrowanie połączeń"; +App::$strings["Filter incoming posts from connections based on keywords/content"] = "Filtruj przychodzące posty z połączeń, na podstawie słów kluczowych lub treści"; +App::$strings["Conversation"] = "Rozmowa"; +App::$strings["Emoji Reactions"] = "Reakcje emoji"; +App::$strings["Add emoji reaction ability to posts"] = "Dodaj możliwość reakcji emoji do postów"; +App::$strings["Dislike Posts"] = "Nielubienie postów"; +App::$strings["Ability to dislike posts/comments"] = "Możliwość postów i komentarzy jako nielubiane"; +App::$strings["Star Posts"] = "Wyróżnianie postów"; +App::$strings["Ability to mark special posts with a star indicator"] = "Możliwość oznaczania wyróżnionych postów wskaźnikiem gwiazdki"; +App::$strings["Reply on comment"] = "Odpowiedanie na komentarze"; +App::$strings["Ability to reply on selected comment"] = "Możliwość udzielenia odpowiedzi na wybrany komentarz"; +App::$strings["Advanced Directory Search"] = "Zaawansowane przeszukiwanie katalogu"; +App::$strings["Allows creation of complex directory search queries"] = "Umożliwia tworzenie złożonych zapytań wyszukiwania w katalogu"; +App::$strings["Editor"] = "Edytor"; +App::$strings["Post Categories"] = "Kategorie postów"; +App::$strings["Add categories to your posts"] = "Dodaj kategorie do swoich postów"; +App::$strings["Large Photos"] = "Duże zdjęcia"; +App::$strings["Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails"] = "Dołączaj duże miniatury zdjęć (1024px) do postów. Jeśli nie jest to włączone, będzie można używać małych miniatur (640 px)"; +App::$strings["Even More Encryption"] = "Jeszcze więcej szyfrowania"; +App::$strings["Allow optional encryption of content end-to-end with a shared secret key"] = "Zezwalaj na opcjonalne szyfrowanie zawartości od końca do końca za pomocą wspólnego tajnego klucza"; +App::$strings["Disable Comments"] = "Wyłącz komentarze"; +App::$strings["Provide the option to disable comments for a post"] = "Zapewnia możliwość wyłączenia komentowania postu"; +App::$strings["Delayed Posting"] = "Opóźnione publikowanie"; +App::$strings["Allow posts to be published at a later date"] = "Pozwal na publikację postów w późniejszym terminie"; +App::$strings["Content Expiration"] = "Wygaśnięcie treści"; +App::$strings["Remove posts/comments and/or private messages at a future time"] = "Usuwanie postów i komentarzy lub prywatnych wiadomości w przyszłości"; +App::$strings["Suppress Duplicate Posts/Comments"] = "Pomiń zduplikowane posty i komentarze"; +App::$strings["Prevent posts with identical content to be published with less than two minutes in between submissions."] = "Zapobiegaj publikowaniu postów o identycznej treści, mających mniej niż dwie minuty między przesłaniami."; +App::$strings["Auto-save drafts of posts and comments"] = "Automatyczne zapisywanie wersji roboczych postów i komentarzy"; +App::$strings["Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions"] = "Automatycznie zapisuje wersje robocze postów i komentarzy w lokalnej pamięci przeglądarki, aby zapobiec przypadkowej utracie kompozycji"; +App::$strings["Manage"] = "Zarządzaj"; +App::$strings["Navigation Channel Select"] = "Wybór kanału przez nawigację"; +App::$strings["Change channels directly from within the navigation dropdown menu"] = "Zmiana kanału bezpośrednio z rozwijanego menu nawigacji"; +App::$strings["Events Filter"] = "Filtr wydarzeń"; +App::$strings["Ability to display only events"] = "Możliwość wyświetlania tylko wydarzeń"; +App::$strings["Polls Filter"] = "Filtr ankiet"; +App::$strings["Ability to display only polls"] = "Możliwość wyświetlania tylko ankiet"; +App::$strings["Save search terms for re-use"] = "Zapisywanie wyszukiwanych haseł do ponownego wykorzystania"; +App::$strings["Ability to file posts under folders"] = "Możliwość umieszczania postów w folderach"; +App::$strings["Alternate Stream Order"] = "Alternatywna kolejność strumienia"; +App::$strings["Ability to order the stream by last post date, last comment date or unthreaded activities"] = "Możliwość uporządkowania strumienia według daty ostatniego postu, daty ostatniego komentarza lub nieprzeczytanych aktywności"; +App::$strings["Contact Filter"] = "Filtr kontaktów"; +App::$strings["Ability to display only posts of a selected contact"] = "Możliwość wyświetlania postów autorstwa tylko wybranego kontaktu"; +App::$strings["Forum Filter"] = "Filtr forów"; +App::$strings["Ability to display only posts of a specific forum"] = "Możliwość wyświetlania postów tylko z określonego forum"; +App::$strings["Personal Posts Filter"] = "Filtr postów osobistych"; +App::$strings["Ability to display only posts that you've interacted on"] = "Możliwość wyświetlania tylko tych postów, z którymi miało się interakcję"; +App::$strings["Photo Location"] = "Lokalizacja zdjęcia"; +App::$strings["If location data is available on uploaded photos, link this to a map."] = "Jeśli dane lokalizacji są dostępne na przesłanych zdjęciach, połącz je z mapą."; +App::$strings["Advanced Profiles"] = "Profile zaawansowane"; +App::$strings["Additional profile sections and selections"] = "Dodatkowe sekcje profilu i pól wyborów"; +App::$strings["Profile Import/Export"] = "Profile Import/Export"; +App::$strings["Save and load profile details across sites/channels"] = "Zapisz i wczytaj szczegóły profilu w różnych witrynach i kanałach"; +App::$strings["Multiple Profiles"] = "Wiele profili"; +App::$strings["Ability to create multiple profiles"] = "Możliwość tworzenia wielu profili"; +App::$strings["Delegation session ended."] = "Sesja delegacji zakończyła się."; +App::$strings["Logged out."] = "Wylogowano."; +App::$strings["Email validation is incomplete. Please check your email."] = "Weryfikacja adresu e-mail jest niekompletna. Proszę sprawdzić swój adres email."; +App::$strings["Failed authentication"] = "Uwierzytelnianie nie powiodło się"; +App::$strings["Login failed."] = "Logowanie nie powiodło się."; +App::$strings["prev"] = "poprzedni"; +App::$strings["first"] = "pierwszy"; +App::$strings["last"] = "ostatni"; +App::$strings["next"] = "następny"; +App::$strings["older"] = "starszy"; +App::$strings["newer"] = "nowszy"; +App::$strings["No connections"] = "Brak połączeń"; +App::$strings["View all %s connections"] = "Wyświetl wszystkie połączenia %s"; +App::$strings["Network: %s"] = "Sieć: %s"; +App::$strings["poke"] = "szturchać"; +App::$strings["ping"] = "ping"; +App::$strings["pinged"] = "spingowany"; +App::$strings["prod"] = "szturchać"; +App::$strings["prodded"] = "szturchać"; +App::$strings["slap"] = "spoliczkować"; +App::$strings["slapped"] = "spoliczkowany"; +App::$strings["finger"] = "dotknąć"; +App::$strings["fingered"] = "dotknięty"; +App::$strings["rebuff"] = "odprawiać"; +App::$strings["rebuffed"] = "odprawiony"; +App::$strings["happy"] = "szczęśliwy"; +App::$strings["sad"] = "smutny"; +App::$strings["mellow"] = "łagodny"; +App::$strings["tired"] = "zmęczony"; +App::$strings["perky"] = "dziarski"; +App::$strings["angry"] = "gniewny"; +App::$strings["stupefied"] = "oszołomiony"; +App::$strings["puzzled"] = "zdziwiony"; +App::$strings["interested"] = "zainteresowany"; +App::$strings["bitter"] = "gorzki"; +App::$strings["cheerful"] = "wesoły"; +App::$strings["alive"] = "żywy"; +App::$strings["annoyed"] = "zirytowany"; +App::$strings["anxious"] = "niespokojny"; +App::$strings["cranky"] = "zepsuty"; +App::$strings["disturbed"] = "zaniepokojony"; +App::$strings["frustrated"] = "sfrustrowany"; +App::$strings["depressed"] = "przygnębiony"; +App::$strings["motivated"] = "zmotywowany"; +App::$strings["relaxed"] = "zThese permissions set who is allowed to view the post."] = "Uprawnienia do publikowania %s nie mogą być zmieniane %s po udostępnieniu postu.
      Te uprawnienia określają, kto może oglądać post."; +App::$strings["This is the home page of %s."] = "To jest strona główna %s."; +App::$strings["Trending"] = "Trendy"; +App::$strings["Keywords"] = "Słowa kluczowe"; +App::$strings["have"] = "ma"; +App::$strings["has"] = "mają"; +App::$strings["want"] = "chce"; +App::$strings["wants"] = "chcą"; +App::$strings["likes"] = "lubią"; +App::$strings["dislikes"] = "nie lubią"; +App::$strings["Unable to import a removed channel."] = "Nie można zaimportować usuniętego kanału."; +App::$strings["Cannot create a duplicate channel identifier on this system. Import failed."] = "Nie można utworzyć zduplikowanego identyfikatora kanału w tym systemie. Import nieudany."; +App::$strings["Unable to create a unique channel address. Import failed."] = "Nie można utworzyć unikalnego adresu kanału. Import nieudany."; +App::$strings["Cloned channel not found. Import failed."] = "Nie znaleziono sklonowanego kanału. Import nieudany."; +App::$strings["Remote authentication"] = "Zdalne uwierzytelnianie"; +App::$strings["Click to authenticate to your home hub"] = "Kliknij, aby uwierzytelnić się na swoim głównym hubie"; +App::$strings["Manage your channels"] = "Zarządzaj swoimi kanałami"; +App::$strings["Manage your privacy groups"] = "Zarządzaj swoimi grupami prywatności"; +App::$strings["Account/Channel Settings"] = "Ustawienia kanału/konta"; +App::$strings["Logout"] = "Wyloguj się"; +App::$strings["End this session"] = "Zakończ tą sesję"; +App::$strings["Your profile page"] = "Strona Twojego profilu"; +App::$strings["Manage/Edit profiles"] = "Zarządzaj/edytuj profile"; +App::$strings["Sign in"] = "Zaloguj się"; +App::$strings["Take me home"] = "Zabierz mnie do domu"; +App::$strings["Log me out of this site"] = "Wyloguj mnie z tej witryny"; +App::$strings["Create an account"] = "Utwórz konto"; +App::$strings["Help and documentation"] = "Pomoc i dokumentacja"; +App::$strings["Search site @name, !forum, #tag, ?docs, content"] = "Szukaj w witrynie @name, !forum, #tag, ?docs, content"; +App::$strings["Site Setup and Configuration"] = "Instalacja i konfiguracja witryny"; +App::$strings["@name, !forum, #tag, ?doc, content"] = "@name, !forum, #tag, ?doc, content"; +App::$strings["Please wait..."] = "Proszę czekać ..."; +App::$strings["Add Apps"] = "Dodaj aplikacje"; +App::$strings["Arrange Apps"] = "Rozmieść aplikacje"; +App::$strings["Toggle System Apps"] = "Przełącz aplikacje systemowe"; +App::$strings["Status Messages and Posts"] = "Komunikaty o stanie i posty"; +App::$strings["Profile Details"] = "Szczegóły profilu"; +App::$strings["Photo Albums"] = "Albumy zdjęć"; +App::$strings["Files and Storage"] = "Pliki i ich magazyn"; +App::$strings["Saved Bookmarks"] = "Zapisane zakładki"; +App::$strings["View Cards"] = "Wyświetl karty"; +App::$strings["View Articles"] = "Wyświetl artykuły"; +App::$strings["View Webpages"] = "Wyświetl witryny internetowe"; +App::$strings["Select an alternate language"] = "Wybierz alternatywny język"; +App::$strings["OpenWebAuth: %1\$s welcomes %2\$s"] = "OpenWebAuth: %1\$s wita %2\$s"; +App::$strings["%1\$s's bookmarks"] = "zakładki %1\$s"; +App::$strings[" and "] = " i "; +App::$strings["public profile"] = "profil publiczny"; +App::$strings["%1\$s changed %2\$s to “%3\$s”"] = "%1\$s zmienił %2\$s na „%3\$s”"; +App::$strings["Visit %1\$s's %2\$s"] = "Odwiedzin %1\$s %2\$s"; +App::$strings["%1\$s has an updated %2\$s, changing %3\$s."] = "%1\$s ma zaktualizowane %2\$s, zmieniając %3\$s."; +App::$strings["INVALID EVENT DISMISSED!"] = "ODRZUCONO NIEPRAWIDŁOWE WYDARZENIE!"; +App::$strings["Summary: "] = "Podsumowanie: "; +App::$strings["Date: "] = "Data: "; +App::$strings["Reason: "] = "Powód: "; +App::$strings["INVALID CARD DISMISSED!"] = "ODRZUCONO NIEPRAWIDŁOWĄ KARTĘ!"; +App::$strings["Name: "] = "Nazwa: "; +App::$strings["Image exceeds website size limit of %lu bytes"] = "Obraz przekracza limit rozmiaru witryny wynoszący %lu bajtów"; +App::$strings["Image file is empty."] = "Plik obrazu jest pusty."; +App::$strings["Photo storage failed."] = "Zapis zdjęcia nie powiódł się."; +App::$strings["a new photo"] = "nowe zdjęcie"; +App::$strings["__ctx:photo_upload__ %1\$s posted %2\$s to %3\$s"] = "%1\$s wysłał %2\$s do %3\$s"; +App::$strings["Upload New Photos"] = "Prześlij nowe zdjęcia"; +App::$strings["Delete this item?"] = "Usunąć tą pozycjęD?"; +App::$strings["%s show less"] = "%s pokaż mniej"; +App::$strings["%s expand"] = "%s rozwiń"; +App::$strings["%s collapse"] = "%s zwiń"; +App::$strings["Password too short"] = "Hasło jest za krótkie"; +App::$strings["Passwords do not match"] = "Hasła nie pasują do siebie"; +App::$strings["everybody"] = "wszyscy"; +App::$strings["Secret Passphrase"] = "Tajna hasło"; +App::$strings["Passphrase hint"] = "Wskazówka dotycząca hasła"; +App::$strings["Notice: Permissions have changed but have not yet been submitted."] = "Uwaga: uprawnienia uległy zmianie, ale nie zostały jeszcze przesłane."; +App::$strings["close all"] = "zamknij wszystko"; +App::$strings["Nothing new here"] = "Nic nowego tutaj"; +App::$strings["Rate This Channel (this is public)"] = "Oceń ten kanał (to jest publiczne)"; +App::$strings["Describe (optional)"] = "Opisz (opcjonalnie)"; +App::$strings["Please enter a link URL"] = "Proszę wprowadzić URL linku"; +App::$strings["Unsaved changes. Are you sure you wish to leave this page?"] = "Niezapisane zmiany. Czy na pewno chcesz opuścić tę stronę?"; +App::$strings["lovely"] = "śliczne"; +App::$strings["wonderful"] = "wspaniałe"; +App::$strings["fantastic"] = "fantastyczne"; +App::$strings["great"] = "świetne"; +App::$strings["Your chosen nickname was either already taken or not valid. Please use our suggestion ("] = "Twój wybrany pseudonim jest już zajęty lub nieważny. Skorzystaj z naszej prpozycji ("; +App::$strings[") or enter a new one."] = ") lub wprowadź nowy."; +App::$strings["Thank you, this nickname is valid."] = "Dziękuję, ten pseudonim jest prawidłowy."; +App::$strings["A channel name is required."] = "Wymagana jest nazwa kanału."; +App::$strings["This is a "] = "To jest "; +App::$strings[" channel name"] = " nazwa kanału"; +App::$strings["Back to reply"] = "Wróć do odpowiedzi"; +App::$strings["Pinned"] = "Przypięte"; +App::$strings["%d minutes"] = array( + 0 => "%d minuta", + 1 => "%d minuty", + 2 => "%d minut", +); +App::$strings["about %d hours"] = array( + 0 => "około %d godziny", + 1 => "około %d godzin", + 2 => "około %d godzin", +); +App::$strings["%d days"] = array( + 0 => "%d dzień", + 1 => "%d dni", + 2 => "%d dni", +); +App::$strings["%d months"] = array( + 0 => "%d miesiąc", + 1 => "%d miesięcy", + 2 => "%d miesięcy", +); +App::$strings["%d years"] = array( + 0 => "%d rok", + 1 => "%d lata", + 2 => "%d lat", +); +App::$strings["timeago.prefixAgo"] = "temu"; +App::$strings["timeago.prefixFromNow"] = "od teraz"; +App::$strings["timeago.suffixAgo"] = "temu"; +App::$strings["timeago.suffixFromNow"] = "od teraz"; +App::$strings["less than a minute"] = "mniej niż minutę"; +App::$strings["about a minute"] = "około minuty"; +App::$strings["about an hour"] = "około godziny"; +App::$strings["a day"] = "dzień"; +App::$strings["about a month"] = "około miesiąca"; +App::$strings["about a year"] = "około roku"; +App::$strings[" "] = " "; +App::$strings["timeago.numbers"] = "timeago.numbers"; +App::$strings["__ctx:long__ May"] = "Maj"; +App::$strings["Jan"] = "Sty"; +App::$strings["Feb"] = "Lut"; +App::$strings["Mar"] = "Mar"; +App::$strings["Apr"] = "Kwi"; +App::$strings["__ctx:short__ May"] = "Maj"; +App::$strings["Jun"] = "Cze"; +App::$strings["Jul"] = "Lop"; +App::$strings["Aug"] = "Sie"; +App::$strings["Sep"] = "Wrz"; +App::$strings["Oct"] = "Paź"; +App::$strings["Nov"] = "Lis"; +App::$strings["Dec"] = "Gru"; +App::$strings["Sun"] = "Nie"; +App::$strings["Mon"] = "Pon"; +App::$strings["Tue"] = "Wto"; +App::$strings["Wed"] = "Śro"; +App::$strings["Thu"] = "Czw"; +App::$strings["Fri"] = "Pią"; +App::$strings["Sat"] = "Sob"; +App::$strings["__ctx:calendar__ today"] = "dzisiaj"; +App::$strings["__ctx:calendar__ month"] = "miesiąc"; +App::$strings["__ctx:calendar__ week"] = "tydzień"; +App::$strings["__ctx:calendar__ day"] = "dzień"; +App::$strings["__ctx:calendar__ All day"] = "Cały dzień"; +App::$strings["Please stand by while your download is being prepared."] = "Proszę czekać, aż pobieranie jest przygotowywane."; +App::$strings["The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it."] = "Token bezpieczeństwa formularza był nieprawidłowy. Prawdopodobnie stało się tak, ponieważ formularz był otwarty zbyt długo (> 3 godziny) przed wysłaniem."; +App::$strings["Profile to assign new connections"] = "Profil do przypisywania nowych połączeń"; +App::$strings["Frequently"] = "Często"; +App::$strings["Hourly"] = "Co godzinnę"; +App::$strings["Twice daily"] = "Dwa razy dziennie"; +App::$strings["Daily"] = "Co dzień"; +App::$strings["Weekly"] = "Co tydzień"; +App::$strings["Monthly"] = "Co miesiąc"; +App::$strings["Currently Male"] = "Obecnie mężczyzna"; +App::$strings["Currently Female"] = "Obecnie kobieta"; +App::$strings["Mostly Male"] = "Głównie mężczyźna"; +App::$strings["Mostly Female"] = "Głównie kobieta"; +App::$strings["Transgender"] = "Transgender"; +App::$strings["Intersex"] = "Interpłciowość"; +App::$strings["Transsexual"] = "Transseksualność"; +App::$strings["Hermaphrodite"] = "Hermafrodyta"; +App::$strings["Undecided"] = "Niezdecydowano"; +App::$strings["Males"] = "Mężczyżni"; +App::$strings["Females"] = "Kobiety"; +App::$strings["Gay"] = "Homoseksualista"; +App::$strings["Lesbian"] = "Lesbijka"; +App::$strings["No Preference"] = "Bez preferencji"; +App::$strings["Bisexual"] = "Biseksualne"; +App::$strings["Autosexual"] = "Autoseksualne"; +App::$strings["Abstinent"] = "Abstyncja"; +App::$strings["Virgin"] = "Dziewice"; +App::$strings["Deviant"] = "Dewiant"; +App::$strings["Fetish"] = "Fetysz"; +App::$strings["Oodles"] = "Oodles"; +App::$strings["Nonsexual"] = "Nonsexual"; +App::$strings["Single"] = "Singiel"; +App::$strings["Lonely"] = "Samotny/Samotna"; +App::$strings["Available"] = "Dostępny/Dostęnna"; +App::$strings["Unavailable"] = "Niedostępny/Niedostęþna"; +App::$strings["Has crush"] = "Zadużony/Zadużona"; +App::$strings["Infatuated"] = "Zakochany/Zakochana"; +App::$strings["Dating"] = "Randki"; +App::$strings["Unfaithful"] = "Niewierny"; +App::$strings["Sex Addict"] = "Uzależniony/Uzależniona od seksu"; +App::$strings["Friends/Benefits"] = "Przyjaciele/Korzyści"; +App::$strings["Casual"] = "Przygodnie"; +App::$strings["Engaged"] = "Zaręczony/Zaręczona"; +App::$strings["Married"] = "Zaślubiony/Zaślubiona"; +App::$strings["Imaginarily married"] = "Zaślubiony/Zaślubiona w myślach"; +App::$strings["Partners"] = "Patner/Partnerka"; +App::$strings["Cohabiting"] = "Konkubent/Konkubina"; +App::$strings["Common law"] = "Prawo zwyczajowe"; +App::$strings["Happy"] = "Szczęsliwy/Szczęśliwa"; +App::$strings["Not looking"] = "Nie szukający/Nie szukająca"; +App::$strings["Swinger"] = "Swinger"; +App::$strings["Betrayed"] = "Zdradzony/Zdradzona"; +App::$strings["Separated"] = "W separacji"; +App::$strings["Unstable"] = "Niestabilny/Niestabilna"; +App::$strings["Divorced"] = "Rozwiedziony/Rozwiedziona"; +App::$strings["Imaginarily divorced"] = "Rozwiedziony/Rozwiedziona w myślach"; +App::$strings["Widowed"] = "Wdowiec/Wdowa"; +App::$strings["Uncertain"] = "Niezdecydowany/Niezdecydowana"; +App::$strings["It's complicated"] = "To skomplikowane"; +App::$strings["Don't care"] = "Nie obchodzi mnie to"; +App::$strings["Ask me"] = "Zapytaj mnie"; +App::$strings["Friendica"] = "Friendica"; +App::$strings["OStatus"] = "OStatus"; +App::$strings["GNU-Social"] = "GNU-Social"; +App::$strings["RSS/Atom"] = "RSS/Atom"; +App::$strings["Diaspora"] = "Diaspora"; +App::$strings["Facebook"] = "Facebook"; +App::$strings["Zot"] = "Zot"; +App::$strings["LinkedIn"] = "LinkedIn"; +App::$strings["XMPP/IM"] = "XMPP/IM"; +App::$strings["MySpace"] = "MySpace"; +App::$strings["Not a valid email address"] = "Nieprawidłowy adres e-mail"; +App::$strings["Your email domain is not among those allowed on this site"] = "Twoja domena e-mail nie należy do domen dozwolonych w tym serwisie"; +App::$strings["Your email address is already registered at this site."] = "Twój adres e-mail jest już zarejestrowany w tym serwisie."; +App::$strings["An invitation is required."] = "Wymagane jest zaproszenie."; +App::$strings["Invitation could not be verified."] = "Nie udało się zweryfikować zaproszenia."; +App::$strings["Please enter the required information."] = "Proszę wprowadzić wymagane informacje."; +App::$strings["Failed to store account information."] = "Nie udało się zapisać informacji o koncie."; +App::$strings["Registration confirmation for %s"] = "Potwierdzenie rejestracji dla %s"; +App::$strings["Registration request at %s"] = "Wniosek o rejestrację na %s"; +App::$strings["your registration password"] = "hasło rejestracyjne"; +App::$strings["Registration details for %s"] = "Szczegóły rejestracji dla %s"; +App::$strings["Account approved."] = "Konto zostało zatwierdzone."; +App::$strings["Registration revoked for %s"] = "Rejestracja cofnięta dla %s"; +App::$strings["Click here to upgrade."] = "Kliknij tutaj, aby zaktualizować."; +App::$strings["This action exceeds the limits set by your subscription plan."] = "Ta czynność wykracza poza limity określone w planie subskrypcji."; +App::$strings["This action is not available under your subscription plan."] = "Ta czynność nie jest dostępna w ramach Twojego planu subskrypcji."; +App::$strings["Help:"] = "Pomoc:"; +App::$strings["Not Found"] = "Nie znaleziono"; +App::$strings["Item was not found."] = "Nie znaleziono elementu."; +App::$strings["Unknown error."] = "Nieznany błąd."; +App::$strings["No source file."] = "Brak pliku źródłowego."; +App::$strings["Cannot locate file to replace"] = "Nie można znaleźć pliku do zastąpienia"; +App::$strings["Cannot locate file to revise/update"] = "Nie można zlokalizować pliku do poprawienia/aktualizacji"; +App::$strings["File exceeds size limit of %d"] = "Plik przekracza limit rozmiaru %d"; +App::$strings["You have reached your limit of %1$.0f Mbytes attachment storage."] = "Osiągnęty został limit %1$.0f MB miejsca na załączniki."; +App::$strings["File upload failed. Possible system limit or action terminated."] = "Przesyłanie pliku nie powiodło się. Możliwe ograniczenie systemowe lub działanie zakończone."; +App::$strings["Stored file could not be verified. Upload failed."] = "Nie można zweryfikować zapisanego pliku. Przesyłanie nie powiodło się."; +App::$strings["Path not available."] = "Ścieżka niedostępna."; +App::$strings["Empty pathname"] = "Pusta ścieżka"; +App::$strings["duplicate filename or path"] = "zduplikowana nazwa pliku lub ścieżka"; +App::$strings["Path not found."] = "Ścieżka nie znaleziona."; +App::$strings["mkdir failed."] = "mkdir zakończył sie błędem."; +App::$strings["database storage failed."] = "zapis w bazie danych nie powiódł się."; +App::$strings["Empty path"] = "Pusta ścieżka"; +App::$strings["%s shared a %s with you"] = "%s udostępnił Ci %s"; +App::$strings["file"] = "plik"; +App::$strings["New window"] = "Nowe okno"; +App::$strings["Open the selected location in a different window or browser tab"] = "Otwórz wybraną lokalizację w innym oknie lub karcie przeglądarki"; +App::$strings["Home, Voice"] = "Dom, głosowy"; +App::$strings["Home, Fax"] = "Dom, fax"; +App::$strings["Work, Voice"] = "Praca, głosowy"; +App::$strings["Work, Fax"] = "Praca, fax"; +App::$strings["View PDF"] = "Wyświetl PDF"; +App::$strings[" by "] = " przez "; +App::$strings[" on "] = " na "; +App::$strings["Embedded content"] = "Osadzone treści"; +App::$strings["Embedding disabled"] = "Osadzanie wyłączone"; +App::$strings["l F d, Y \\@ g:i A"] = "l F d, Y \\@ g:i A"; +App::$strings["Starts:"] = "Rozpoczętych:"; +App::$strings["Finishes:"] = "Zakończonych:"; +App::$strings["l F d, Y"] = "l F d, Y"; +App::$strings["Start:"] = "Rozpoczęto:"; +App::$strings["End:"] = "Zakończono:"; +App::$strings["Timezone"] = "Strefa czasowa"; +App::$strings["This event has been added to your calendar."] = "To wydarzenie zostało dodane do Twojego kalendarza."; +App::$strings["Not specified"] = "Nieokreślone"; +App::$strings["Needs Action"] = "Wymaga działania"; +App::$strings["Completed"] = "Zakończone"; +App::$strings["In Process"] = "W trakcie"; +App::$strings["Cancelled"] = "Usuniete"; +App::$strings["Birthday"] = "Urodziny"; +App::$strings["Age: "] = "Wiek: "; +App::$strings["YYYY-MM-DD or MM-DD"] = "RRRR-MM-DD lub MM-DD"; +App::$strings["never"] = "nigdy"; +App::$strings["less than a second ago"] = "mniej niż sekundę temu"; +App::$strings["__ctx:e.g. 22 hours ago, 1 minute ago__ %1\$d %2\$s ago"] = "%1\$d %2\$s temu"; +App::$strings["__ctx:relative_date__ year"] = array( + 0 => "rok", + 1 => "lata", + 2 => "lat", +); +App::$strings["__ctx:relative_date__ month"] = array( + 0 => "miesiąc", + 1 => "miesiące", + 2 => "miesięcy", +); +App::$strings["__ctx:relative_date__ week"] = array( + 0 => "tydzień", + 1 => "tygodnie", + 2 => "tygodni", +); +App::$strings["__ctx:relative_date__ day"] = array( + 0 => "dzień", + 1 => "dni", + 2 => "dni", +); +App::$strings["__ctx:relative_date__ hour"] = array( + 0 => "godzina", + 1 => "godziny", + 2 => "godzin", +); +App::$strings["__ctx:relative_date__ minute"] = array( + 0 => "minuta", + 1 => "minuty", + 2 => "minut", +); +App::$strings["__ctx:relative_date__ second"] = array( + 0 => "sekunda", + 1 => "sekundy", + 2 => "sekund", +); +App::$strings["%1\$s's birthday"] = "urodziny %1\$s"; +App::$strings["Happy Birthday %1\$s"] = "%1\$s, wszystkiego najlepszego z okazji urodzin"; +App::$strings["(Unknown)"] = "(Nieznane)"; +App::$strings["Visible to anybody on the internet."] = "Widoczne dla każdego w internecie."; +App::$strings["Visible to you only."] = "Widoczne tylko dla Ciebie."; +App::$strings["Visible to anybody in this network."] = "Widoczne dla każdego w tej sieci."; +App::$strings["Visible to anybody authenticated."] = "Widoczne dla każdego uwierzytelnionego."; +App::$strings["Visible to anybody on %s."] = "Widoczne dla wszystkich na %s."; +App::$strings["Visible to all connections."] = "Widoczny dla wszystkich połączeń."; +App::$strings["Visible to approved connections."] = "Widoczny dla zatwierdzonych połączeń."; +App::$strings["Visible to specific connections."] = "Widoczny dla określonych połączeń."; +App::$strings["Privacy group is empty."] = "Grupa prywatności jest pusta."; +App::$strings["Privacy group: %s"] = "Grupa prywatności: %s"; +App::$strings["Connection not found."] = "Nie znaleziono połączenia."; +App::$strings["profile photo"] = "zdjęcie profilowe"; +App::$strings["[Edited %s]"] = "[Edytowane %s]"; +App::$strings["__ctx:edit_activity__ Post"] = "Post"; +App::$strings["__ctx:edit_activity__ Comment"] = "Komentarz"; +App::$strings["Response from remote channel was incomplete."] = "Odpowiedź z kanału zdalnego była niekompletna."; +App::$strings["Premium channel - please visit:"] = "Kanał premium - odwiedź:"; +App::$strings["Channel was deleted and no longer exists."] = "Kanał został usunięty i już nie istnieje."; +App::$strings["Invalid data packet"] = "Nieprawidłowy pakiet danych"; +App::$strings["invalid target signature"] = "nieprawidłowy podpis docelowy"; +App::$strings["Image/photo"] = "Obraz/zdjęcie"; +App::$strings["Encrypted content"] = "Zaszyfrowana treść"; +App::$strings["Install %1\$s element %2\$s"] = "Zainstaluj element %1\$s %2\$s"; +App::$strings["This post contains an installable %s element, however you lack permissions to install it on this site."] = "Ten post zawiera możliwy do zainstalowania element %s, jednak nie masz uprawnień do zainstalowania go w tym serwisie."; +App::$strings["card"] = "karta"; +App::$strings["article"] = "artykuł"; +App::$strings["Click to open/close"] = "Kliknij, any otworzyć/zamknąć"; +App::$strings["View article"] = "Wyświetl artykuł"; +App::$strings["View summary"] = "Wyświetl podsumowanie"; +App::$strings["$1 wrote:"] = "$1 napisał:"; +App::$strings["Follow"] = "Obserwuj"; +App::$strings["%1\$s is now following %2\$s"] = "%1\$s obserwujesz teraz %2\$s"; +App::$strings["The GNU-Social protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Protokół GNU-Social nie obsługuje niezależności od lokalizacji. Połączenia nawiązane w tej sieci mogą być niedostępne z innych lokalizacji kanałów."; +App::$strings["GNU-Social Protocol App"] = "Aplikacja Protokół GNU-Social"; +App::$strings["GNU-Social Protocol"] = "GNU-Social Protocol"; +App::$strings["QR code"] = "Kod QR"; +App::$strings["QR Generator"] = "Generator QR"; +App::$strings["Enter some text"] = "Wprowadź jakiś tekst"; +App::$strings["Popular Channels"] = "Popularne kanały"; +App::$strings["Channels to auto connect"] = "Kanały do automatycznego podłączenia"; +App::$strings["Comma separated list"] = "Lista rozdzielana przecinkami"; +App::$strings["IRC Settings"] = "Ustawienia IRC"; +App::$strings["IRC settings saved."] = "Zapisano ustawienia IRC."; +App::$strings["IRC Chatroom"] = "Pokój rozmów IRC"; +App::$strings["Send email to all members"] = "Wyślij e-mail do wszystkich członków"; +App::$strings["No recipients found."] = "Nie znaleziono adresatów."; +App::$strings["%1\$d of %2\$d messages sent."] = "Wysłano %1\$d wiadomości z %2\$d zadysponowanych."; +App::$strings["Send email to all hub members."] = "Wyślij wiadomość e-mail do wszystkich członków huba."; +App::$strings["Message subject"] = "Temat wiadomości"; +App::$strings["Sender Email address"] = "Adres e-mail nadawcy"; +App::$strings["Test mode (only send to hub administrator)"] = "Tryb testowy (wysyłaj tylko do administratora huba)"; +App::$strings["Your Webbie:"] = "Twój Webbie:"; +App::$strings["Fontsize (px):"] = "Wielkość czcionki (px):"; +App::$strings["Link:"] = "Link:"; +App::$strings["Like us on Hubzilla"] = "Polub nas na Hubzilli"; +App::$strings["Embed:"] = "Osadzone:"; +App::$strings["Save Settings"] = "Zapisz ustawienia"; +App::$strings["text to include in all outgoing posts from this site"] = "tekst do umieszczania we wszystkich postach wychodzących z tej witryny"; +App::$strings["lonely"] = "samotny"; +App::$strings["drunk"] = "pijany"; +App::$strings["horny"] = "seksualnie podniecony"; +App::$strings["stoned"] = "zjarany"; +App::$strings["fucked up"] = "spieprzone"; +App::$strings["clusterfucked"] = "klasterfucked"; +App::$strings["crazy"] = "zwariowany"; +App::$strings["hurt"] = "ból"; +App::$strings["sleepy"] = "senny"; +App::$strings["grumpy"] = "gderliwy"; +App::$strings["high"] = "wysoki"; +App::$strings["semi-conscious"] = "półprzytomny"; +App::$strings["in love"] = "zakochany"; +App::$strings["in lust"] = "w pożądaniu"; +App::$strings["naked"] = "nagi"; +App::$strings["stinky"] = "śmierdzący"; +App::$strings["sweaty"] = "spocony"; +App::$strings["bleeding out"] = "wykrwawiać się"; +App::$strings["victorious"] = "zwycięski"; +App::$strings["defeated"] = "pokonany"; +App::$strings["envious"] = "zazdrosny"; +App::$strings["jealous"] = "zazdrosny"; +App::$strings["This website is tracked using the Piwik analytics tool."] = "Ta witryna jest śledzona za pomocą narzędzia analitycznego Piwik."; +App::$strings["If you do not want that your visits are logged this way you can set a cookie to prevent Piwik from tracking further visits of the site (opt-out)."] = "Jeśli nie chcesz, aby Twoje wizyty były rejestrowane w ten sposób, możesz ustawić plik cookie, aby uniemożliwić Piwik śledzenie dalszych wizyt na stronie (rezygnacja)."; +App::$strings["Piwik Base URL"] = "Bazowy adres URL Piwik"; +App::$strings["Absolute path to your Piwik installation. (without protocol (http/s), with trailing slash)"] = "Absolutna ścieżka do instalacji Piwika. (bez protokołu (http/s), z końcowym ukośnikiem)"; +App::$strings["Site ID"] = "ID witryny"; +App::$strings["Show opt-out cookie link?"] = "Pokazać link do rezygnacji z pliku cookie?"; +App::$strings["Asynchronous tracking"] = "Śledzenie asynchroniczne"; +App::$strings["Enable frontend JavaScript error tracking"] = "Włącz śledzenie błędów JavaScript w interfejsie użytkownika"; +App::$strings["This feature requires Piwik >= 2.2.0"] = "Ta funkcjonalność wymaga Piwik >= 2.2.0"; +App::$strings["Access Denied"] = "Dostęp zabroniony"; +App::$strings["Enable Community Moderation"] = "Włącz moderację społecznościową"; +App::$strings["Reputation automatically given to new members"] = "Reputacja przyznawana automatycznie nowym członkom"; +App::$strings["Reputation will never fall below this value"] = "Reputacja nigdy nie spadnie poniżej tej wartości"; +App::$strings["Minimum reputation before posting is allowed"] = "Dozwolona jest minimalna reputacja przed rozpoczęciem postów"; +App::$strings["Minimum reputation before commenting is allowed"] = "Dozwolona jest minimalna reputacja przed rozpoczęciem komentowania"; +App::$strings["Minimum reputation before a member is able to moderate other posts"] = "Minimalna reputacja, zanim członek będzie mógł moderować inne posty"; +App::$strings["Max ratio of moderator's reputation that can be added to/deducted from reputation of person being moderated"] = "Maksymalny współczynnik reputacji moderatora, który można dodać do reputacji moderowanej osoby lub od niej odjąć"; +App::$strings["Reputation \"cost\" to post"] = "\"Koszt\" reputacji dla postu"; +App::$strings["Reputation \"cost\" to comment"] = "\"Koszt\" reputacji dla komentarza"; +App::$strings["Reputation automatically recovers at this rate per hour until it reaches minimum_to_post"] = "Reputacja automatycznie odświeżana jest w tym tempie co godzinę, dopóki nie osiągnie minimum_to_post"; +App::$strings["When minimum_to_moderate > reputation > minimum_to_post reputation recovers at this rate per hour"] = "Kiedy minimum_to_moderate > reputation> minimum_to_post reputacja odświeża na jest z taką szybkością na godzinę"; +App::$strings["Community Moderation Settings"] = "Ustawienia moderowania społecznościowego"; +App::$strings["Channel Reputation"] = "Reputacja kanału"; +App::$strings["An Error has occurred."] = "Wystąpił błąd."; +App::$strings["Upvote"] = "Głosuj za"; +App::$strings["Downvote"] = "Głosuj przeciw"; +App::$strings["Can moderate reputation on my channel."] = "Mogę moderować reputację na moim kanale."; +App::$strings["Errors encountered deleting database table "] = "Napotkano błędy podczas usuwania tabeli bazy danych "; +App::$strings["Submit Settings"] = "Prześlij ustawienia"; +App::$strings["Drop tables when uninstalling?"] = "Usunąć tabele podczas odinstalowywania?"; +App::$strings["If checked, the Rendezvous database tables will be deleted when the plugin is uninstalled."] = "Jeśli zaznaczone, po odinstalowaniu wtyczki zostaną usunięte wszystkie tabele z bazy danych Rendezvous."; +App::$strings["Mapbox Access Token"] = "Token Mapbox Access"; +App::$strings["If you enter a Mapbox access token, it will be used to retrieve map tiles from Mapbox instead of the default OpenStreetMap tile server."] = "Jeśli wprowadzisz token dostępu Mapbox, będzie on używany do pobierania fragmentów mapy z Mapbox, zamiast z domyślnego serwera kafelków OpenStreetMap."; +App::$strings["Rendezvous"] = "Rendezvous"; +App::$strings["This identity has been deleted by another member due to inactivity. Please press the \"New identity\" button or refresh the page to register a new identity. You may use the same name."] = "Ta tożsamość została usunięta przez innego członka z powodu braku aktywności. Proszę nacisnąć przycisk \"Nowa tożsamość\" lub odświeżyć stronę, aby zarejestrować nową tożsamość. Możesz użyć tej samej nazwy."; +App::$strings["Welcome to Rendezvous!"] = "Witamy w Rendezvous!"; +App::$strings["Enter your name to join this rendezvous. To begin sharing your location with the other members, tap the GPS control. When your location is discovered, a red dot will appear and others will be able to see you on the map."] = "Wpisz swoje imię i nazwisko, aby dołączyć do tego spotkania. W celu rozpoczęcia udostępniania swojej lokalizacji innym członkom, dotknij elementu sterującego GPS. Gdy Twoja lokalizacja zostanie odkryta, pojawi się czerwona kropka i inni będą mogli Cię zobaczyć na mapie."; +App::$strings["Let's meet here"] = "Spotkajmy się tutaj"; +App::$strings["New marker"] = "Nowy znacznik"; +App::$strings["Edit marker"] = "Edytuj znacznik"; +App::$strings["New identity"] = "Nowa tożsamość"; +App::$strings["Delete marker"] = "Usuń znacznik"; +App::$strings["Delete member"] = "Usuń członka"; +App::$strings["Edit proximity alert"] = "Edytuj alert zbliżeniowy"; +App::$strings["A proximity alert will be issued when this member is within a certain radius of you.

      Enter a radius in meters (0 to disable):"] = "Alert zbliżeniowy zostanie wygenerowany, gdy ten członek znajdzie się w określonym promieniu od Ciebie.

      Wprowadź promień w metrach (0, aby wyłączyć):"; +App::$strings["distance"] = "odległość"; +App::$strings["Proximity alert distance (meters)"] = "Odległość ostrzeżenia o bliskości (metry)"; +App::$strings["A proximity alert will be issued when you are within a certain radius of the marker location.

      Enter a radius in meters (0 to disable):"] = "Alert zbliżeniowy zostanie wygenerowany, gdy znajdziesz się w określonym promieniu od lokalizacji znacznika.

      Wprowadź promień w metrach (0, aby wyłączyć):"; +App::$strings["Marker proximity alert"] = "Ostrzeżenie o bliskości znacznika"; +App::$strings["Reminder note"] = "Notatka przypominająca"; +App::$strings["Enter a note to be displayed when you are within the specified proximity..."] = "Wprowadź notatkę, która będzie wyświetlana, gdy będziesz w określonej odległości ..."; +App::$strings["Add new rendezvous"] = "Dodaj nowe spotkanie"; +App::$strings["Create a new rendezvous and share the access link with those you wish to invite to the group. Those who open the link become members of the rendezvous. They can view other member locations, add markers to the map, or share their own locations with the group."] = "Utwórz nowe spotkanie i udostępnij łącze dostępu tym, których chcesz zaprosić do grupy. Osoby, które otworzą łącze, stają się członkami spotkania. Mogą wyświetlać lokalizacje innych członków, dodawać znaczniki do mapy lub udostępniać własne lokalizacje grupie."; +App::$strings["You have no rendezvous. Press the button above to create a rendezvous!"] = "Nie masz spotkania. Naciśnij przycisk powyżej, aby utworzyć spotkanie!"; +App::$strings["Skeleton App"] = "Aplikacja Szkielet"; +App::$strings["A skeleton for addons, you can copy/paste"] = "Szkielet dodatków, który można skopiować i wkleić"; +App::$strings["Some setting"] = "Jakieś ustawienie"; +App::$strings["A setting"] = "Ustawienie"; +App::$strings["Skeleton Settings"] = "Ustawienia Skeleton"; +App::$strings["Post to Hubzilla"] = "Wyślij do Hubzilli"; +App::$strings["Channel is required."] = "Kanał jest wymagany."; +App::$strings["Hubzilla Crosspost Connector Settings saved."] = "Ustawienia Hubzilla Crosspost Connector zostały zapisane."; +App::$strings["Hubzilla Crosspost Connector App"] = "Aplikacja Hubzilla Crosspost Connector"; +App::$strings["Relay public postings to another Hubzilla channel"] = "Przekaż publiczne posty na inny kanał Hubzilla"; +App::$strings["Send public postings to Hubzilla channel by default"] = "Domyślnie wysyłaj publiczne posty na kanał Hubzilla"; +App::$strings["Hubzilla API Path"] = "Ścieżka API Hubzilla"; +App::$strings["https://{sitename}/api"] = "https://{sitename}/api"; +App::$strings["Hubzilla login name"] = "Nazwa logowania Hubzilla"; +App::$strings["Hubzilla channel name"] = "Nazwa kanału Hubzilla"; +App::$strings["Nickname"] = "Pseudonim"; +App::$strings["Hubzilla password"] = "Hasło Hubzilla"; +App::$strings["Hubzilla Crosspost Connector"] = "Hubzilla Crosspost Connector"; +App::$strings["TOTP Two-Step Verification"] = "Weryfikacja dwuetapowa TOTP"; +App::$strings["Enter the 2-step verification generated by your authenticator app:"] = "Wprowadź dwuetapową weryfikację wygenerowaną przez aplikację uwierzytelniającą:"; +App::$strings["Success!"] = "Powodzenie!"; +App::$strings["Invalid code, please try again."] = "Nieprawidłowy kod, proszę spróbować ponownie."; +App::$strings["Too many invalid codes..."] = "Za dużo nieprawidłowych kodów ..."; +App::$strings["Verify"] = "Zweryfikuj"; +App::$strings["You haven't set a TOTP secret yet.\nPlease click the button below to generate one and register this site\nwith your preferred authenticator app."] = "Nie ustawiłeś jeszcze sekretu TOTP.\nKliknij przycisk poniżej, aby to wygenerować i zarejestrować witrynę\nw preferowanej aplikacji uwierzytelniającej."; +App::$strings["Your TOTP secret is"] = "Twój sekret TOTP to"; +App::$strings["Be sure to save it somewhere in case you lose or replace your mobile device.\nUse your mobile device to scan the QR code below to register this site\nwith your preferred authenticator app."] = "Zapisz go gdzieś na wypadek zgubienia lub wymiany urządzenia mobilnego.\nUżyj urządzenia mobilnego, aby zeskanować poniższy kod QR i zarejestrować tą witrynę\nw preferowanej aplikacji uwierzytelniającej."; +App::$strings["Test"] = "Test"; +App::$strings["Generate New Secret"] = "Generowanie nowego sekretu"; +App::$strings["Go"] = "Idź dalej"; +App::$strings["Enter your password"] = "Wprowadź swoje hasło"; +App::$strings["enter TOTP code from your device"] = "wprowadź kod TOTP z urządzenia"; +App::$strings["Pass!"] = "Przeszło!"; +App::$strings["Fail"] = "Błąd"; +App::$strings["Incorrect password, try again."] = "Nieprawidłowe hasło, spróbuj ponownie."; +App::$strings["Record your new TOTP secret and rescan the QR code above."] = "Zapisz swój nowy sekret TOTP i ponownie przeskanuj powyższy kod QR."; +App::$strings["TOTP Settings"] = "Ustawienia TOTP"; +App::$strings["Your account on %s will expire in a few days."] = "Twoje konto na %s wygaśnie za kilka dni."; +App::$strings["Your $Productname test account is about to expire."] = "Twoje konto testowe $Productname wkrótce wygaśnie."; +App::$strings["An account has been created for you."] = "Konto zostało dla Ciebie utworzone."; +App::$strings["Authentication successful but rejected: account creation is disabled."] = "Uwierzytelnianie przebiegło pomyślne, ale zostało odrzucone: tworzenie konta jest wyłączone."; +App::$strings["DB Cleanup Failure"] = "Błąd czyszczenia bazy danych"; +App::$strings["[cart] Item Added"] = "[koszyk] Dodano element"; +App::$strings["Order already checked out."] = "Zamówienie już jest wyrejestrowane."; +App::$strings["Drop database tables when uninstalling."] = "Usuń tabele bazy danych podczas odinstalowywania."; +App::$strings["Cart Settings"] = "Ustawienia koszyka"; +App::$strings["Shop"] = "Sklep"; +App::$strings["Order Not Found"] = "Nie znaleziono zamówienia"; +App::$strings["Cart utilities for orders and payments"] = "Narzędzia koszyka do zamówień i płatności"; +App::$strings["You must be logged into the Grid to shop."] = "Aby robić zakupy, musisz być zalogowany do Siatki."; +App::$strings["Order not found."] = "Nie znaleziono zamówienia."; +App::$strings["Access denied."] = "Dostęp zabroniony."; +App::$strings["No Order Found"] = "Nie znaleziono zamówienia"; +App::$strings["An unknown error has occurred Please start again."] = "Wystąpił nieznany błąd. Zacznij od nowa."; +App::$strings["Requirements not met."] = "Nie spełnia wymagań."; +App::$strings["Review your order and complete any needed requirements."] = "Przejrzyj swoje zamówienie i spełnij wszystkie wymagania."; +App::$strings["Invalid Payment Type. Please start again."] = "Nieprawidłowy typ płatności. Zacznij od nowa."; +App::$strings["Order not found"] = "Nie znaleziono zamówienia"; +App::$strings["Enable Order/Item Options"] = "Włącz opcję Zamówienie/Element"; +App::$strings["Label"] = "Etykieta"; +App::$strings["Instructions"] = "Instukcje"; +App::$strings["Enable Hubzilla Services Module"] = "Włącz moduł usług Hubzilla"; +App::$strings["New Sku"] = "Nowy SKU"; +App::$strings["Cannot save edits to locked item."] = "Nie można zapisać zmian w zablokowanym elemencie."; +App::$strings["SKU not found."] = "Nie znaleziono SKU."; +App::$strings["Invalid Activation Directive."] = "Nieprawidłowa dyrektywa aktywacyjna."; +App::$strings["Invalid Deactivation Directive."] = "Nieprawidłowa dyrektywa dezaktywacyjna."; +App::$strings["Add to this privacy group"] = "Dodaj do tej grupy prywatności"; +App::$strings["Set user service class"] = "Ustaw klasę usług użytkownika"; +App::$strings["You must be using a local account to purchase this service."] = "Aby kupić tę usługę, musisz korzystać z konta lokalnego."; +App::$strings["Changes Locked"] = "Zmiany zablokowane"; +App::$strings["Item available for purchase."] = "Element dostępny do zakupu."; +App::$strings["Price"] = "Cena"; +App::$strings["Photo URL"] = "Adres URL zdjęcia"; +App::$strings["Add buyer to privacy group"] = "Dodaj kupującego do grupy prywatności"; +App::$strings["Add buyer as connection"] = "Dodaj kupującego jako połączenie"; +App::$strings["Set Service Class"] = "Ustaw klasę usługi"; +App::$strings["Enable Subscription Management Module"] = "Włącz moduł zarządzania subskrypcjami"; +App::$strings["Cannot include subscription items with different terms in the same order."] = "Nie może zawierać elementów subskrypcji z różnymi terminami w tej samej kolejności."; +App::$strings["Select Subscription to Edit"] = "Wybierz subskrypcję do edycji"; +App::$strings["Edit Subscriptions"] = "Edytuj subskrypcje"; +App::$strings["Subscription SKU"] = "Subskrypcja SKU"; +App::$strings["Catalog Description"] = "Opis katalogu"; +App::$strings["Subscription available for purchase."] = "Subskrypcja dostępna do zakupu."; +App::$strings["Maximum active subscriptions to this item per account."] = "Maksymalna liczba aktywnych subskrypcji tego elementu na konto."; +App::$strings["Subscription price."] = "Cena subskrypcji."; +App::$strings["Quantity"] = "Ilość"; +App::$strings["Term"] = "Termin"; +App::$strings["Enable Paypal Button Module (API-v2)"] = "Włącz moduł przycisków Paypal (API-v2)"; +App::$strings["Use Production Key"] = "Użyj klucza produkcyjnego"; +App::$strings["Paypal Sandbox Client Key"] = "Klucz klienta Paypal Sandbox"; +App::$strings["Paypal Sandbox Secret Key"] = "Tajny klucz Paypal Sandbox"; +App::$strings["Paypal Production Client Key"] = "Klucz klienta produkcyjny Paypal"; +App::$strings["Paypal Production Secret Key"] = "Tajny klucz produkcyjny Paypal"; +App::$strings["Paypal button payments are not enabled."] = "Płatności za pomocą przycisku PayPal nie są włączone."; +App::$strings["Paypal button payments are not properly configured. Please choose another payment option."] = "Płatności za pomocą przycisku PayPal nie są poprawnie skonfigurowane. Wybierz inną opcję płatności."; +App::$strings["Enable Paypal Button Module"] = "Włącz moduł przycisku Paypal"; +App::$strings["Enable Manual Cart Module"] = "Włącz moduł ręcznego koszyka"; +App::$strings["Access Denied."] = "Dostęp zabroniony."; +App::$strings["Invalid Item"] = "Zła pozycja"; +App::$strings["Error: order mismatch. Please try again."] = "Błąd: niezgodność zamówienia. Proszę spróbuj ponownie."; +App::$strings["Manual payments are not enabled."] = "Płatności ręczne nie są włączone."; +App::$strings["Finished"] = "Zakończone"; +App::$strings["Enable Test Catalog"] = "Włącz katalog testów"; +App::$strings["Enable Manual Payments"] = "Włącz płatności ręczne"; +App::$strings["Base Merchant Currency"] = "Podstawowa waluta sprzedawcy"; +App::$strings["We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."] = "Napotkaliśmy problem podczas logowania za pomocą podanego przez Ciebie identyfikatora OpenID. Sprawdź poprawną pisownię identyfikatora."; +App::$strings["The error message was:"] = "Komunikat o błędzie brzmi:"; +App::$strings["First Name"] = "Imię"; +App::$strings["Last Name"] = "Nazwisko"; +App::$strings["Full Name"] = "Pełna nazwa"; +App::$strings["Profile Photo 16px"] = "Zdjęcie profilowe 16px"; +App::$strings["Profile Photo 32px"] = "Zdjęcie profilowe 32px"; +App::$strings["Profile Photo 48px"] = "Zdjęcie profilowe 48px"; +App::$strings["Profile Photo 64px"] = "Zdjęcie profilowe 64px"; +App::$strings["Profile Photo 80px"] = "Zdjęcie profilowe 80px"; +App::$strings["Profile Photo 128px"] = "Zdjęcie profilowe 128px"; +App::$strings["Birth Year"] = "Rok urodzenia"; +App::$strings["Birth Month"] = "Miesiąc urodzenia"; +App::$strings["Birth Day"] = "Dzień urodzenia"; +App::$strings["Birthdate"] = "Data urodzenia"; +App::$strings["OpenID protocol error. No ID returned."] = "Błąd protokołu OpenID. Brak identyfikatora."; +App::$strings["Hubzilla File Storage Import"] = "Import z magazynu plików Hubzilla"; +App::$strings["This will import all your cloud files from another server."] = "Spowoduje to zaimportowanie wszystkich plików w chmurze z innego huba Hubzilla."; +App::$strings["Hubzilla Server base URL"] = "Bazowy adres URL serwera Hubzilla"; +App::$strings["Since modified date yyyy-mm-dd"] = "Od daty modyfikacji rrrr-mm-dd"; +App::$strings["Until modified date yyyy-mm-dd"] = "Do daty modyfikacji rrrr-mm-dd"; +App::$strings["Diaspora Protocol Settings updated."] = "Zaktualizowano ustawienia protokołu Diaspora."; +App::$strings["The diaspora protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Protokół Diaspora nie obsługuje niezależności lokalizacji. Połączenia nawiązane w tej sieci mogą być niedostępne z innych lokalizacji kanałów."; +App::$strings["Diaspora Protocol App"] = "Aplikacja Diaspora Protocol"; +App::$strings["Allow any Diaspora member to comment on your public posts"] = "Pozwól każdemu członkowi Diaspory komentować Twoje publiczne posty"; +App::$strings["Prevent your hashtags from being redirected to other sites"] = "Zapobiegaj przekierowywaniu hashtagów do innych witryn"; +App::$strings["Sign and forward posts and comments with no existing Diaspora signature"] = "Podpisuj i przesyłaj dalej posty i komentarze bez podpisu Diaspory"; +App::$strings["Followed hashtags (comma separated, do not include the #)"] = "Obserwowane hashtagi (oddzielone przecinkami, nie dodawaj #)"; +App::$strings["Diaspora Protocol"] = "Diaspora Protocol"; +App::$strings["No username found in import file."] = "W pliku importu nie znaleziono nazwy użytkownika."; +App::$strings["%1\$s dislikes %2\$s's %3\$s"] = "%1\$s desaprobat %2\$s %3\$s"; +App::$strings["Please install the statistics addon to be able to configure a diaspora relay"] = "Zainstaluj dodatek do statystyk, aby móc skonfigurować przekaźnik Diaspory"; +App::$strings["Diaspora Relay Handle"] = "Uchwyt przekaźnika Diaspory"; +App::$strings["Address of a diaspora relay. Example: relay@diasporarelay.tld"] = "Adres przekaźnika diaspory. Przykład: relay@diasporarelay.tld"; +App::$strings["Diaspora relay could not be imported"] = "Nie można zaimportować przekaźnika diaspory"; +App::$strings["Hubzilla Directory Stats"] = "Statystyki katalogowe Hubzilla"; +App::$strings["Total Hubs"] = "Razem huby"; +App::$strings["Hubzilla Hubs"] = "Huby Hubzilla"; +App::$strings["Friendica Hubs"] = "Huby Friendica"; +App::$strings["Diaspora Pods"] = "Pody Diaspora"; +App::$strings["Hubzilla Channels"] = "Kanały Hubzilla"; +App::$strings["Friendica Channels"] = "Kanały Friendica"; +App::$strings["Diaspora Channels"] = "Kanały Diaspora"; +App::$strings["Aged 35 and above"] = "W wieku 35 lat i więcej"; +App::$strings["Aged 34 and under"] = "W wieku 34 lat i poniżej"; +App::$strings["Average Age"] = "Średni wiek"; +App::$strings["Known Chatrooms"] = "Znane czaty"; +App::$strings["Known Tags"] = "Znane tagi"; +App::$strings["Please note Diaspora and Friendica statistics are merely those **this directory** is aware of, and not all those known in the network. This also applies to chatrooms,"] = "Proszę mieć na uwadze, że statystyki Diaspory i Friendica to tylko te,które są widoczne dla **tego katalogu**, a nie wszystkie znane w sieci. Dotyczy to również czatów,"; +App::$strings["Show Upload Limits"] = "Pokaż limity przesyłania"; +App::$strings["Hubzilla configured maximum size: "] = "Maksymalny rozmiar skonfigurowany w Hubzilli: "; +App::$strings["PHP upload_max_filesize: "] = "PHP upload_max_filesize: "; +App::$strings["PHP post_max_size (must be larger than upload_max_filesize): "] = "PHP post_max_size (musi być większe od upload_max_filesize): "; +App::$strings["Hide Aside App"] = "Aplikacja Hide Aside"; +App::$strings["Fade out aside areas after a while when using endless scroll"] = "Powoduje zanikanie obszaru po chwili, gdy używasz długiego przewijania"; +App::$strings["Installed"] = "Zainstalowane"; +App::$strings["You're welcome."] = "Proszę bardzo."; +App::$strings["Ah shucks..."] = "O cholera ..."; +App::$strings["Don't mention it."] = "Nie wspominaj o tym."; +App::$strings["<blush>"] = "<rumieniec>"; +App::$strings["View Larger"] = "Zobacz większe"; +App::$strings["Tile Server URL"] = "Adres URL serwera kafelków rastrowych"; +App::$strings["A list of public tile servers"] = "Lista publicznych serwerów kafelków"; +App::$strings["Nominatim (reverse geocoding) Server URL"] = "Adres URL serwera Nominatim (odwrotne geokodowanie)"; +App::$strings["A list of Nominatim servers"] = "Lista serwerów Nominatim"; +App::$strings["Default zoom"] = "Powiększenie domyślne"; +App::$strings["The default zoom level. (1:world, 18:highest, also depends on tile server)"] = "Domyślny poziom powiększenia. (1: świat, 18: najwyższy, zależy również od serwera kafelków)"; +App::$strings["Include marker on map"] = "Uwzględnij znacznik na mapie"; +App::$strings["Include a marker on the map."] = "Umieść znacznik na tej mapie."; +App::$strings["Livejournal Crosspost Connector App"] = "Aplikacja Livejournal Crosspost Connector"; +App::$strings["Relay public posts to Livejournal"] = "Przekazuj publiczne posty do Livejournal"; +App::$strings["Livejournal username"] = "Nazwa użytkownika w Livejournal"; +App::$strings["Livejournal password"] = "Hasło do Livejournal"; +App::$strings["Post to Livejournal by default"] = "Domyślnie wysyłaj do Livejournal"; +App::$strings["Send wall-to-wall posts to Livejournal"] = "Wysyłaj posty \"wall-to-wall\" do Livejournal"; +App::$strings["Add link to original post"] = "Dodaj odnośnik do oryginalnego postu"; +App::$strings["Livejournal Crosspost Connector"] = "Livejournal Crosspost Connector"; +App::$strings["Post to Livejournal"] = "Publikuj w Livejournal"; +App::$strings["Posted by"] = "Wysłane przez"; +App::$strings["Workflow user."] = "Przepływ pracy użytkownika."; +App::$strings["This channel"] = "Ten kanał"; +App::$strings["Workflow"] = "Przepływ pracy"; +App::$strings["No Workflows Available"] = "Żaden przepływ nie jest dostępny"; +App::$strings["Add item to which workflow"] = "Dodaj element do przepływu pracy"; +App::$strings["Create Workflow Item"] = "Utwórz element przepływu pracy"; +App::$strings["Link"] = "Link"; +App::$strings["Web link."] = "Link do strony internetowej."; +App::$strings["Brief description or title"] = "Krótki opis lub tytuł"; +App::$strings["Notes and Info"] = "Uwagi i informacje"; +App::$strings["Body"] = "Ciało"; +App::$strings["Workflow Settings"] = "Ustawienia przepływu pracy"; +App::$strings["Jabber BOSH host"] = "Host Jabber BOSH"; +App::$strings["Use central userbase"] = "Użyj centralnej bazy użytkowników"; +App::$strings["If enabled, members will automatically login to an ejabberd server that has to be installed on this machine with synchronized credentials via the \"auth_ejabberd.php\" script."] = "Jeśli jest włączone, członkowie będą automatycznie logować się do serwera ejabberd, który musi być zainstalowany na tym komputerze z zsynchronizowanymi danymi uwierzytelniającymi za pośrednictwem skryptu „auth_ejabberd.php”."; +App::$strings["XMPP settings updated."] = "Zaktualizowano ustawienia XMPP."; +App::$strings["XMPP App"] = "Aplikacja XMPP"; +App::$strings["Embedded XMPP (Jabber) client"] = "Osadzony klient XMPP (Jabber)"; +App::$strings["Individual credentials"] = "Indywidualne poświadczenia"; +App::$strings["Jabber BOSH server"] = "Serwer Jabber BOSH"; +App::$strings["XMPP Settings"] = "Ustawienia XMPP"; +App::$strings["Superblock App"] = "Aplikacja Superblock"; +App::$strings["Block channels"] = "Blokuj kanał"; +App::$strings["superblock settings updated"] = "zaktualizowano ustawienia superbloku"; +App::$strings["Currently blocked"] = "Obecnie zablokowane"; +App::$strings["No channels currently blocked"] = "Obecnie żadne kanały nie są zablokowane"; +App::$strings["Block Completely"] = "Zablokuj całkowicie"; +App::$strings["Random Planet App"] = "Aplikacja Random Planet"; +App::$strings["Set a random planet from the Star Wars Empire as your location when posting"] = "Podczas wysyłania ustaw, jako lokalizację, losową planetę z Imperium Gwiezdnych Wojen"; +App::$strings["Possible adult content"] = "Możliwe treści dla dorosłych"; +App::$strings["%s - view"] = "%s - widok"; +App::$strings["NSFW Settings saved."] = "Zapisano ustawienia NSFW."; +App::$strings["NSFW App"] = "Aplikacja NSFW"; +App::$strings["Collapse content that contains predefined words"] = "Zwiń zawartość zawierającą predefiniowane słowa"; +App::$strings["This app looks in posts for the words/text you specify below, and collapses any content containing those keywords so it is not displayed at inappropriate times, such as sexual innuendo that may be improper in a work setting. It is polite and recommended to tag any content containing nudity with #NSFW. This filter can also match any other word/text you specify, and can thereby be used as a general purpose content filter."] = "Ta aplikacja wyszukuje słowa lub tekst, określone poniżej i zwija wszelkie treści zawierające te słowa kluczowe, aby nie były wyświetlane w nieodpowiednich momentach, takich jak insynuacje seksualne, które mogą być niewłaściwe w miejscu pracy. Grzecznie jest i zaleca się, oznaczanie wszelkich treści zawierających nagość tagiem #NSFW. Ten filtr może również pasować do dowolnego innego określonego słowa lub tekstu, dzięki czemu może być używany jako filtr treści ogólnego przeznaczenia."; +App::$strings["Comma separated list of keywords to hide"] = "Lista słów kluczowych rozdzielona przecinkami"; +App::$strings["Word, /regular-expression/, lang=xx, lang!=xx"] = "Słowo, /wyrażenie regularne/, lang=xx, lang!=xx"; +App::$strings["NSFW"] = "NSFW"; +App::$strings["Three Dimensional Tic-Tac-Toe"] = "Trójwymiarowy Tic-Tac-Toe"; +App::$strings["3D Tic-Tac-Toe"] = "3D Tic-Tac-Toe"; +App::$strings["New game"] = "Nowa gra"; +App::$strings["New game with handicap"] = "Nowa gra z handicapem"; +App::$strings["Three dimensional tic-tac-toe is just like the traditional game except that it is played on multiple levels simultaneously. "] = "Trójwymiarowa gra w kółko i krzyżyk jest podobna do tradycyjnej gry, z tym wyjątkiem, że gra się w nią na wielu poziomach jednocześnie. "; +App::$strings["In this case there are three levels. You win by getting three in a row on any level, as well as up, down, and diagonally across the different levels."] = "W tym przypadku są trzy poziomy. Wygrywasz, zdobywając trzy z rzędu na dowolnym poziomie, a także w górę, w dół i po przekątnej na różnych poziomach."; +App::$strings["The handicap game disables the center position on the middle level because the player claiming this square often has an unfair advantage."] = "Gra z handicapem wyłącza środkową pozycję na środkowym poziomie, ponieważ gracz zajmujący to pole często ma nieuczciwą przewagę."; +App::$strings["You go first..."] = "Ty pierwszy ..."; +App::$strings["I'm going first this time..."] = "Tym razem idę pierwszy ..."; +App::$strings["You won!"] = "Wygrałeś!"; +App::$strings["\"Cat\" game!"] = "Gra \"Kot\"!"; +App::$strings["I won!"] = "Wygrałem!"; +App::$strings["Photo Cache settings saved."] = "Zapisano ustawienia pamięci podręcznej zdjęć."; +App::$strings["Photo Cache addon saves a copy of images from external sites locally to increase your anonymity in the web."] = "Dodatek Photo Cache zapisuje lokalnie kopie obrazów z zewnętrznych witryn, aby zwiększyć Twoją anonimowość w sieci."; +App::$strings["Photo Cache App"] = "Aplikacja Photo Cache"; +App::$strings["Minimal photo size for caching"] = "Minimalny rozmiar zdjęcia do buforowania"; +App::$strings["In pixels. From 1 up to 1024, 0 will be replaced with system default."] = "W pikselach. Od 1 do 1024, 0 zostanie zastąpione domyślnymi ustawieniami systemowymi."; +App::$strings["Photo Cache"] = "Photo Cache"; +App::$strings["__ctx:opensearch__ Search %1\$s (%2\$s)"] = "Szukaj %1\$s (%2\$s)"; +App::$strings["__ctx:opensearch__ \$Projectname"] = "Hubzilla"; +App::$strings["Search \$Projectname"] = "Szukaj w Hubzilla"; +App::$strings["Libertree Crosspost Connector Settings saved."] = "Zapisano ustawienia Libertree Crosspost Connector."; +App::$strings["Libertree Crosspost Connector App"] = "Aplikacja Libertree Crosspost Connector"; +App::$strings["Relay public posts to Libertree"] = "Przekazuj publiczne posty do Libertree"; +App::$strings["Libertree API token"] = "Token API Libertree"; +App::$strings["Libertree site URL"] = "Adres URL witrny Libertree"; +App::$strings["Post to Libertree by default"] = "Domyślnie publikuj w Libertree"; +App::$strings["Libertree Crosspost Connector"] = "Libertree Crosspost Connector"; +App::$strings["Post to Libertree"] = "Publikuj w Libertree"; +App::$strings["Flag Adult Photos"] = "Oznaczanie zdjęć dla dorosłych"; +App::$strings["Provide photo edit option to hide inappropriate photos from default album view"] = "Dostarcza opcję edycji zdjęć, umożliwiającą ukrywanie nieodpowiednich zdjęć w domyślnym widoku albumu"; +App::$strings["Post to GNU social"] = "Publikuj w serwisie społecznościowym GNU"; +App::$strings["API URL"] = "Adres URL API"; +App::$strings["Application name"] = "Nazwa aplikacji"; +App::$strings["Please contact your site administrator.
      The provided API URL is not valid."] = "Skontaktuj się z administratorem witryny.
      Podany adres URL interfejsu API jest nieprawidłowy."; +App::$strings["We could not contact the GNU social API with the Path you entered."] = "Nie mogliśmy nawiązać połączenia ze społecznościowym API GNU o podanej ścieżce."; +App::$strings["GNU social settings updated."] = "Ustawienia społecznościowe GNU zostały zaktualizowane."; +App::$strings["Relay public postings to a connected GNU social account (formerly StatusNet)"] = "Przekazywanie publicznych postów na połączone konto społecznościowe GNU (dawniej StatusNet)"; +App::$strings["Globally Available GNU social OAuthKeys"] = "Globalnie dostępne klucze OAuthKey społecznościowe GNU"; +App::$strings["There are preconfigured OAuth key pairs for some GNU social servers available. If you are using one of them, please use these credentials.
      If not feel free to connect to any other GNU social instance (see below)."] = "Dostępne są wstępnie skonfigurowane pary kluczy OAuth dla niektórych serwerów społecznościowych GNU. Jeśli używasz jednego z nich, użyj tych poświadczeń.
      Jeśli nie możesz połączyć się z inną instancją społecznościową GNU (patrz poniżej)."; +App::$strings["Provide your own OAuth Credentials"] = "Podaj własne dane logowania OAuth"; +App::$strings["No consumer key pair for GNU social found. Register your Hubzilla Account as an desktop client on your GNU social account, copy the consumer key pair here and enter the API base root.
      Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Hubzilla installation at your favourite GNU social installation."] = "Nie znaleziono pary kluczy konsumenckich dla społeczności GNU. Zarejestruj swoje konto Hubzilla jako klienta stacjonarnego na swoim koncie społecznościowym GNU, skopiuj tutaj parę kluczy klienta i wprowadź podstawowy katalog główny API.
      Przed zarejestrowaniem własnej pary kluczy OAuth zapytaj administratora, czy istnieje już para kluczy dla tej instalacji Hubzilli w Twojej ulubionej instalacji społecznościowej GNU."; +App::$strings["OAuth Consumer Key"] = "Klucz klienta OAuth"; +App::$strings["OAuth Consumer Secret"] = "Tajny klucz klienta OAuth"; +App::$strings["Base API Path"] = "Podstawowa ścieżka API"; +App::$strings["Remember the trailing /"] = "Zapamiętaj końcowy ukośnik /"; +App::$strings["GNU social application name"] = "Nazwa aplikacji społecznościowej GNU"; +App::$strings["To connect to your GNU social account click the button below to get a security code from GNU social which you have to copy into the input box below and submit the form. Only your public posts will be posted to GNU social."] = "W celu połączenia się ze swoim kontem społecznościowym GNU, kliknij poniższy przycisk, aby uzyskać kod zabezpieczający z serwisu społecznościowego GNU, który musisz skopiować do pola wprowadzania poniżej i przesłać formularz. Tylko twoje publiczne posty będą publikowane w społecznościach GNU."; +App::$strings["Log in with GNU social"] = "Zaloguj się za pomocą serwisu społecznościowego GNU"; +App::$strings["Copy the security code from GNU social here"] = "Skopiuj tutaj kod bezpieczeństwa z GNU Social"; +App::$strings["Cancel Connection Process"] = "Anuluj proces łączenia"; +App::$strings["Current GNU social API is"] = "Obecne API społecznościowe GNU to"; +App::$strings["Cancel GNU social Connection"] = "Anuluj połączenie społecznościowe GNU"; +App::$strings["Currently connected to: "] = "Obecnie połączony z: "; +App::$strings["Note: Due your privacy settings (Hide your profile details from unknown viewers?) the link potentially included in public postings relayed to GNU social will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted."] = "Uwaga: Ze względu na Twoje ustawienia prywatności, odnośnik (Ukryj szczegóły swojego profilu przed nieznanymi widzami? ), ewentualnie zawarty w publicznych postach przekazywanych do społeczności GNU, będzie kierował odwiedzającego na pustą stronę z informacją dla odwiedzającego, że dostęp do Twojego profilu został ograniczony."; +App::$strings["Post to GNU social by default"] = "Wysyłaj domyślnie do społeczności GNU"; +App::$strings["If enabled your public postings will be posted to the associated GNU-social account by default"] = "Jeśli ta opcja jest włączona, twoje publiczne posty będą domyślnie wysyłane na powiązane konto społecznościowe GNU"; +App::$strings["Clear OAuth configuration"] = "Wyczyść konfigurację OAuth"; +App::$strings["GNU-Social Crosspost Connector"] = "GNU-Social Crosspost Connector"; +App::$strings["Who likes me?"] = "Kto mnie lubi?"; +App::$strings["ActivityPub Protocol Settings updated."] = "Zaktualizowano ustawienia ActivityPub Protocol."; +App::$strings["The activitypub protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Protokół AactivityPub nie obsługuje niezależności od lokalizacji. Połączenia nawiązane w tej sieci mogą być niedostępne z innych lokalizacji kanałów."; +App::$strings["Activitypub Protocol App"] = "Aplikacja Activitypub Protocol"; +App::$strings["Deliver to ActivityPub recipients in privacy groups"] = "Dostarcz do odbiorców ActivityPub w grupach prywatności"; +App::$strings["May result in a large number of mentions and expose all the members of your privacy group"] = "Może skutkować dużą liczbą wzmianek i ujawnieniem wszystkich członków Twojej grupy prywatności"; +App::$strings["Send multi-media HTML articles"] = "Wysyłaj multimedialne artykuły HTML"; +App::$strings["Not supported by some microblog services such as Mastodon"] = "Nieobsługiwane przez niektóre usługi mikroblogów, takie jak Mastodon"; +App::$strings["Activitypub Protocol"] = "Activitypub Protocol"; +App::$strings["Post to Insane Journal"] = "Publikuj w Insane Journal"; +App::$strings["Insane Journal Crosspost Connector Settings saved."] = "Zapisano ustawienia Insane Journal Crosspost Connector."; +App::$strings["Insane Journal Crosspost Connector App"] = "Aplikacja Insane Journal Crosspost Connector"; +App::$strings["Relay public postings to Insane Journal"] = "Przekaż publiczne posty do Insane Journal"; +App::$strings["InsaneJournal username"] = "Nazwa użytkownika InsaneJournal"; +App::$strings["InsaneJournal password"] = "Hasło InsaneJournal"; +App::$strings["Post to InsaneJournal by default"] = "Domyślnie publikuj w InsaneJournal"; +App::$strings["Insane Journal Crosspost Connector"] = "Insane Journal Crosspost Connector"; +App::$strings["Max queueworker threads"] = "Maksymalna liczba wątków w kolejce"; +App::$strings["Assume workers dead after ___ seconds"] = "Załóż, że workery wygasają po ___ sekundach"; +App::$strings["Pause before starting next task: (microseconds. Minimum 100 = .0001 seconds)"] = "Wstrzymaj przed rozpoczęciem następnego zadania: (w mikrosekundach. Minimum 100 = .0001 sekund)"; +App::$strings["Queueworker Settings"] = "Ustawienia Queueworkera"; +App::$strings["Not allowed."] = "Niedozwolone."; +App::$strings["generic profile image"] = "ogólne zdjęcie profilowe"; +App::$strings["random geometric pattern"] = "losowy wzór geometryczny"; +App::$strings["monster face"] = "twarz potwora"; +App::$strings["computer generated face"] = "wygenerowana komputerowo twarz"; +App::$strings["retro arcade style face"] = "twarz w stylu retro arcade"; +App::$strings["Hub default profile photo"] = "Domyślne zdjęcie profilowe huba"; +App::$strings["Information"] = "Informacje"; +App::$strings["Libravatar addon is installed, too. Please disable Libravatar addon or this Gravatar addon.
      The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar."] = "Dodatek Libravatar jest również zainstalowany. Proszę wyłączyć dodatek Libravatar lub ten dodatek Gravatar.
      Dodatek Libravatar wykorzysta Gravatara, jeśli nic nie zostanie znalezione w bibliotece Libravatara."; +App::$strings["Default avatar image"] = "Domyślny obraz awatara"; +App::$strings["Select default avatar image if none was found at Gravatar. See README"] = "Wybierz domyślny obraz awatara, jeśli nic nie zostało znaleziony w Gravatarze. Zobacz README"; +App::$strings["Rating of images"] = "Ocena zdjęć"; +App::$strings["Select the appropriate avatar rating for your site. See README"] = "Wybierz odpowiednią ocenę awatara dla swojej witryny. Zobacz README"; +App::$strings["Gravatar settings updated."] = "Zaktualizowano ustawienia Gravatara."; +App::$strings["Network error"] = "Błąd sieci"; +App::$strings["API error"] = "Błąd API"; +App::$strings["Unknown issue"] = "Nieznany problem"; +App::$strings["Unable to login using email address "] = "Nie można zalogować się przy użyciu adresu e-mail "; +App::$strings["Sign in to Hubzilla using a social account"] = "Zaloguj się do Hubzilli za pomocą konta społecznościowego"; +App::$strings["Social Authentication using your social media account"] = "Uwierzytelnianie społecznościowe za pomocą konta w mediach społecznościowych"; +App::$strings["This app enables one or more social provider sign-in buttons on the login page."] = "Ta aplikacja umożliwia korzystanie na stronie logowania z co najmniej jednego przycisku logowania dostawcy usług społecznościowych."; +App::$strings["Add an identity provider"] = "Dodaj dostawcę tożsamości"; +App::$strings["Enable "] = "Włącz "; +App::$strings["Key"] = "Klucz"; +App::$strings["Word"] = "Słowo"; +App::$strings["Secret"] = "Sekret"; +App::$strings["Add a custom provider"] = "Dodaj własnego dostawcę"; +App::$strings["Remove an identity provider"] = "Usuń dostawcę tożsamości"; +App::$strings["Social authentication"] = "Uwierzytelnianie społecznościowe"; +App::$strings["Error while saving provider settings"] = "Błąd podczas zapisywania ustawień dostawcy"; +App::$strings["Custom provider already exists"] = "Własny dostawca już istnieje"; +App::$strings["Social authentication settings saved."] = "Zapisano ustawienia uwierzytelniania społecznościowego."; +App::$strings["Send your identity to all websites"] = "Wyślij swoją tożsamość do wszystkich witryn internetowych"; +App::$strings["Sendzid App"] = "Aplikacja Sendzid"; +App::$strings["Send ZID"] = "Wyślij ZID"; +App::$strings["Photos imported"] = "Zdjęcia zaimportowane"; +App::$strings["Redmatrix Photo Album Import"] = "Import albumu fotograficznego Redmatrix"; +App::$strings["This will import all your Redmatrix photo albums to this channel."] = "Spowoduje to zaimportowanie wszystkich albumów ze zdjęciami z Redmatrix do tego kanału."; +App::$strings["Redmatrix Server base URL"] = "Podstawowy adres URL serwera Redmatrix"; +App::$strings["Redmatrix Login Username"] = "Nazwa użytkownika logowania w Redmatrix"; +App::$strings["Redmatrix Login Password"] = "Hasło logowania do Redmatrix"; +App::$strings["Import just this album"] = "Zaimportuj tylko ten album"; +App::$strings["Leave blank to import all albums"] = "Pozostaw puste, aby zaimportować wszystkie albumy"; +App::$strings["Maximum count to import"] = "Maksymalna liczba albumów do zaimportowania"; +App::$strings["0 or blank to import all available"] = "0 lub puste, aby zaimportować wszystkie dostępne"; +App::$strings["Twitter settings updated."] = "Zaktualizowano ustawienia Twittera."; +App::$strings["Twitter Crosspost Connector App"] = "Aplikacja Twitter Crosspost Connector"; +App::$strings["Relay public posts to Twitter"] = "Przekazuj publiczne posty na Twitter"; +App::$strings["No consumer key pair for Twitter found. Please contact your site administrator."] = "Nie znaleziono pary kluczy klienta dla Twittera. Skontaktuj się z administratorem witryny."; +App::$strings["At this Hubzilla instance the Twitter plugin was enabled but you have not yet connected your account to your Twitter account. To do so click the button below to get a PIN from Twitter which you have to copy into the input box below and submit the form. Only your public posts will be posted to Twitter."] = "W tej instancji Hubzilla wtyczka Twittera była włączona, ale nie połączyłeś jeszcze swojego konta z kontem na Twitterze. Aby to zrobić, kliknij poniższy przycisk, aby uzyskać kod PIN z Twittera, który należy skopiować do pola wprowadzania poniżej i przesłać formularz. Na Twitterze będą publikowane tylko Twoje publiczne posty."; +App::$strings["Log in with Twitter"] = "Zaloguj się za pomocą Twittera"; +App::$strings["Copy the PIN from Twitter here"] = "Skopiuj tutaj PIN z Twittera"; +App::$strings["Note: Due your privacy settings (Hide your profile details from unknown viewers?) the link potentially included in public postings relayed to Twitter will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted."] = " Uwaga: Ze względu na Twoje ustawienia prywatności (Ukryj szczegóły swojego profilu przed nieznanymi widzami?) ten link, potencjalnie zawarty w publicznych postach przekazywanych do Twittera, będzie prowadził odwiedzającego do pustej strony informującej gościa, że dostęp do Twojego profilu został ograniczony."; +App::$strings["Twitter post length"] = "Długość postu na Twitterze"; +App::$strings["Maximum tweet length"] = "Maksymalna długość tweeta"; +App::$strings["Send public postings to Twitter by default"] = "Domyślnie wysyłaj publiczne posty na Twitter"; +App::$strings["If enabled your public postings will be posted to the associated Twitter account by default"] = "Jeśli ta opcja jest włączona, Twoje publiczne posty będą domyślnie publikowane na powiązanym koncie Twittera"; +App::$strings["Twitter Crosspost Connector"] = "Twitter Crosspost Connector"; +App::$strings["Post to Twitter"] = "Opublikuj na Twitterze"; +App::$strings["Project Servers and Resources"] = "Serwery projektów i zasoby"; +App::$strings["Project Creator and Tech Lead"] = "Twórca projektu i kierownik techniczny"; +App::$strings["And the hundreds of other people and organisations who helped make the Hubzilla possible."] = "Oraz setki innych osób i organizacji, które pomogły stworzyć Hubzillę."; +App::$strings["The Redmatrix/Hubzilla projects are provided primarily by volunteers giving their time and expertise - and often paying out of pocket for services they share with others."] = "Projekty Redmatrix i Hubzilla są realizowane głównie przez wolontariuszy, którzy poświęcają swój czas i wiedzę i często płacą z własnej kieszeni za usługi, którymi dzielą się z innymi."; +App::$strings["There is no corporate funding and no ads, and we do not collect and sell your personal information. (We don't control your personal information - you do.)"] = "Nie ma żadnych funduszy korporacyjnych ani reklam a my nie zbieramy i nie sprzedajemy Twoich danych osobowych. (Nie kontrolujemy Twoich danych osobowych - Ty tak )."; +App::$strings["Help support our ground-breaking work in decentralisation, web identity, and privacy."] = "Pomóż nam wspierać nasze przełomowe prace w zakresie decentralizacji, tożsamości internetowej i prywatności."; +App::$strings["Your donations keep servers and services running and also helps us to provide innovative new features and continued development."] = "Twoje darowizny zapewniają nieprzerwane działanie serwerów i usług, a także pomagają nam w zapewnianiu innowacyjnych nowych funkcji i ciągłym rozwoju."; +App::$strings["Donate"] = "Wspomóż"; +App::$strings["Choose a project, developer, or public hub to support with a one-time donation"] = "Wybierz projekt, dewelopera lub publiczny hub, aby wesprzeć jednorazową darowizną"; +App::$strings["Donate Now"] = "Wpłać teraz"; +App::$strings["Or become a project sponsor (Hubzilla Project only)"] = "lub zostań sponsorem projektu (tylko Projekt Hubzilla)"; +App::$strings["Please indicate if you would like your first name or full name (or nothing) to appear in our sponsor listing"] = "Wskaż, czy chcesz, aby Twoje imię lub imię i nazwisko pojawiało się na naszej liście sponsorów"; +App::$strings["Sponsor"] = "Sponsor"; +App::$strings["Special thanks to: "] = "Specjalne podziękowania dla: "; +App::$strings["Dreamwidth Crosspost Connector Settings saved."] = "Zapisano ustawienia Dreamwidth Crosspost Connector."; +App::$strings["Dreamwidth Crosspost Connector App"] = "Aplikacja Dreamwidth Crosspost Connector"; +App::$strings["Relay public posts to Dreamwidth"] = "Przekazuj publiczne posty do Dreamwidth"; +App::$strings["Dreamwidth username"] = "Nazwa użytkownika Dreamwidth"; +App::$strings["Dreamwidth password"] = "Hasło Dreamwidth"; +App::$strings["Post to Dreamwidth by default"] = "Domyślnie publikuj na Dreamwidth"; +App::$strings["Link description (default:"] = "Opis odnośnika (domyślnie:"; +App::$strings["Dreamwidth Crosspost Connector"] = "Dreamwidth Crosspost Connector"; +App::$strings["Post to Dreamwidth"] = "Publikuj na Dreamwidth"; +App::$strings["nofed Settings saved."] = "nofed - zapisano ustawienie."; +App::$strings["No Federation App"] = "Brak aplikacji Federation"; +App::$strings["Prevent posting from being federated to anybody. It will exist only on your channel page."] = "Zapobiegaj federowaniu wiadomości do kogokolwiek. Będzie istnieć tylko na stronie Twojego kanału."; +App::$strings["Federate posts by default"] = "Domyślnie, posty Federate"; +App::$strings["No Federation"] = "Brak Federation"; +App::$strings["Federate"] = "Federate"; +App::$strings["WYSIWYG status editor"] = "Edytor aplikacji WYSIWYG Status"; +App::$strings["WYSIWYG Status App"] = "Aplikacja WYSIWYG Status"; +App::$strings["WYSIWYG Status"] = "WYSIWYG Status"; +App::$strings["No server specified"] = "Nie określono serwera"; +App::$strings["Posts imported"] = "Zaimportowano posty"; +App::$strings["Files imported"] = "Zaimportowano pliki"; +App::$strings["This addon app copies existing content and file storage to a cloned/copied channel. Once the app is installed, visit the newly installed app. This will allow you to set the location of your original channel and an optional date range of files/conversations to copy."] = "Ten dodatek kopiuje istniejące treści i magazyn plików do sklonowanego lub skopiowanego kanału. Po zainstalowaniu, odwiedź nowo zainstalowaną aplikację. Umożliwi Ci to ustawienie lokalizacji oryginalnego kanału i opcjonalnego zakresu dat plików lub konwersacji do skopiowania."; +App::$strings["This will import all your conversations and cloud files from a cloned channel on another server. This may take a while if you have lots of posts and or files."] = "Spowoduje to zaimportowanie wszystkich rozmów i plików przechowywanych w chmurze ze sklonowanego kanału na innym serwerze. Może to chwilę potrwać, jeśli masz dużo postów lun plików."; +App::$strings["Include posts"] = "Dołącz posty"; +App::$strings["Conversations, Articles, Cards, and other posted content"] = "Rozmowy, artykuły, karty i inne opublikowane treści"; +App::$strings["Include files"] = "Dołącz pliki"; +App::$strings["Files, Photos and other cloud storage"] = "Pliki, zdjęcia i inne przechowywane w chmurze rzeczy"; +App::$strings["Original Server base URL"] = "Oryginalny podstawowy adres URL serwera"; +App::$strings["Your channel has been upgraded to \$Projectname version"] = "Twój kanał został uaktualniony do wersji \$Projectname"; +App::$strings["Please have a look at the"] = "Proszę spojrzeć na"; +App::$strings["git history"] = "historia repozytorium Git"; +App::$strings["change log"] = "dziennik zmian"; +App::$strings["for further info."] = "po dalsze informacje."; +App::$strings["Upgrade Info"] = "Informacja o aktualizacji"; +App::$strings["Do not show this again"] = "Nie pokazuj tego ponownie"; +App::$strings["pageheader Settings saved."] = "pageheader - zapisano ustawienie."; +App::$strings["Page Header App"] = "Aplikacja Page Header"; +App::$strings["Inserts a page header"] = "Wstawia nagłówek strony"; +App::$strings["Message to display on every page on this server"] = "Wiadomość do wyświetlenia na każdej stronie na tym serwerze"; +App::$strings["Page Header"] = "Page Header"; +App::$strings["Who viewed my channel/profile"] = "Kto oglądał mój kanał lub profil"; +App::$strings["Recent Channel/Profile Viewers"] = "Ostatnio wyświetlający mój kanał lub profil"; +App::$strings["No entries."] = "Brak postów."; +App::$strings["Messages"] = "Wiadomości"; +App::$strings["message"] = "wiadomość"; +App::$strings["Message recalled."] = "Wiadomość przywołana."; +App::$strings["Conversation removed."] = "Rozmowa została usunięta."; +App::$strings["Expires YYYY-MM-DD HH:MM"] = "Wygasa YYYY-MM-DD HH:MM"; +App::$strings["Requested channel is not in this network"] = "Żądanego kanału nie ma w tej sieci"; +App::$strings["Send Private Message"] = "Wyślij prywatną wiadomość"; +App::$strings["To:"] = "Do:"; +App::$strings["Subject:"] = "Temat:"; +App::$strings["Attach file"] = "Dołącz plik"; +App::$strings["Send"] = "Wyślij"; +App::$strings["Delete message"] = "Usuń wiadomość"; +App::$strings["Delivery report"] = "Raport dostawy"; +App::$strings["Recall message"] = "Odwołaj wiadomość"; +App::$strings["Message has been recalled."] = "Wiadomość została odwołana."; +App::$strings["Delete Conversation"] = "Usuń rozmowę"; +App::$strings["No secure communications available. You may be able to respond from the sender's profile page."] = "Brak bezpiecznej komunikacji. Możesz odpowiedzieć ze strony profilu nadawcy."; +App::$strings["Send Reply"] = "Wyślij odpowiedź"; +App::$strings["Your message for %s (%s):"] = "Twoja wiadomość dla %s (%s):"; +App::$strings["Unable to lookup recipient."] = "Nie można znaleźć adresata."; +App::$strings["Unable to communicate with requested channel."] = "Nie można skomunikować się z żądanym kanałem."; +App::$strings["Cannot verify requested channel."] = "Nie można zweryfikować żądanego kanału."; +App::$strings["Selected channel has private message restrictions. Send failed."] = "Wybrany kanał ma ograniczenia dotyczące wiadomości prywatnych. Wysyłanie nie powiodło się."; +App::$strings["System defaults:"] = "Domyślne wartości systemowe:"; +App::$strings["Preferred Clipart IDs"] = "Identyfikatory preferowanych clipartów"; +App::$strings["List of preferred clipart ids. These will be shown first."] = "Lista identyfikatorów preferowanych clipartów."; +App::$strings["Default Search Term"] = "Domyślna fraza wyszukiwania"; +App::$strings["The default search term. These will be shown second."] = "Domyślna fraza wyszukiwania. Będzie ona wyświetlana jako druga."; +App::$strings["Return After"] = "Wróć po"; +App::$strings["Page to load after image selection."] = "Strona do załadowania po wybraniu obrazu."; +App::$strings["Profile List"] = "Lista profili"; +App::$strings["Order of Preferred"] = "Kolejność preferowanych"; +App::$strings["Sort order of preferred clipart ids."] = "Sortuj preferowane identyfikatory clipart."; +App::$strings["Newest first"] = "Od najnowszych"; +App::$strings["As entered"] = "Jak wprowadzono"; +App::$strings["Order of other"] = "Kolejność innych"; +App::$strings["Sort order of other clipart ids."] = "Kolejność sortowania innych identyfikatorów clipartów."; +App::$strings["Most downloaded first"] = "Najczęściej pobierane jako pierwsze"; +App::$strings["Most liked first"] = "Najbardziej lubiane jako pierwsze"; +App::$strings["Preferred IDs Message"] = "Komunikat o preferowanych identyfikatorach"; +App::$strings["Message to display above preferred results."] = "Wiadomość do wyświetlenia powyżej preferowanych wyników."; +App::$strings["Uploaded by: "] = "Przesłane przez: "; +App::$strings["Drawn by: "] = "Narysowane przez: "; +App::$strings["Use this image"] = "Użyj tego obrazu"; +App::$strings["Or select from a free OpenClipart.org image:"] = "Lub wybierz bezpłatny obraz z OpenClipart.org:"; +App::$strings["Search Term"] = "Fraza wyszukiwania"; +App::$strings["Unknown error. Please try again later."] = "Nieznany błąd. Spróbuj ponownie później."; +App::$strings["Profile photo updated successfully."] = "Zdjęcie profilowe zostało pomyślnie zaktualizowane."; +App::$strings["Gallery"] = "Gallery"; +App::$strings["Photo Gallery"] = "Galeria zdjęć"; +App::$strings["Gallery App"] = "Aplikacja Gallery"; +App::$strings["A simple gallery for your photo albums"] = "Prosta galeria dla albumów ze zdjęciami"; +App::$strings["Smileybutton App"] = "Aplikacja Smileybutton"; +App::$strings["Adds a smileybutton to the jot editor"] = "Dodaje przycisk emotikonów do edytora jot"; +App::$strings["Hide the button and show the smilies directly."] = "Ukryj przycisk i bezpośrednio wyświetlaj emotikony."; +App::$strings["Smileybutton Settings"] = "Ustawienia Smileybutton"; +App::$strings["Post to Friendica"] = "Opublikuj w sieci Hubzilla"; +App::$strings["Friendica Crosspost Connector Settings saved."] = "Zapisano ustawienia Friendica Crosspost Connector ."; +App::$strings["Friendica Crosspost Connector App"] = "Aplikacja Hubzilla Crosspost Connector"; +App::$strings["Relay public postings to a connected Friendica account"] = "Przekazywanie publicznych postów do połączonego konta Friendica"; +App::$strings["Send public postings to Friendica by default"] = "Domyślnie wysyłaj publiczne posty na kanał Hubzilla"; +App::$strings["Friendica API Path"] = "Ścieżka API Hubzilla"; +App::$strings["Friendica login name"] = "Nazwa logowania w Hubzilla"; +App::$strings["Friendica password"] = "Hasło Hubzilla"; +App::$strings["Friendica Crosspost Connector"] = "Friendica Crosspost Connector"; +App::$strings["Logfile archive directory"] = "Katalog archiwum plików dziennika zdarzeń"; +App::$strings["Directory to store rotated logs"] = "Katalog do przechowywania rotowanych dzienników zdarzeń"; +App::$strings["Logfile size in bytes before rotating"] = "Rozmiar pliku dziennika w bajtach przed dokonaniem odnowienia"; +App::$strings["Number of logfiles to retain"] = "Liczba plików dziennika do przechowania"; +App::$strings["Post to WordPress"] = "Opubikuj w WordPress"; +App::$strings["Wordpress Settings saved."] = "Zapisano ustawienia Wordpress."; +App::$strings["Wordpress Post App"] = "Aplikacja Wordpress Post"; +App::$strings["Post to WordPress or anything else which uses the wordpress XMLRPC API"] = "Opublikuj na WordPress lub czymkolwiek innym, co używa API XMLRPC WordPress"; +App::$strings["WordPress username"] = "Nazwa użytkownika WordPress"; +App::$strings["WordPress password"] = "Hasło WordPress"; +App::$strings["WordPress API URL"] = "Adres URL API WordPress"; +App::$strings["Typically https://your-blog.tld/xmlrpc.php"] = "Zwykle https://your-blog.tld/xmlrpc.php"; +App::$strings["WordPress blogid"] = "Identyfikator blogu WordPress"; +App::$strings["For multi-user sites such as wordpress.com, otherwise leave blank"] = "Dla serwisów wielowitrynowych, takich jak wordpress.com, w przeciwnym razie pozostaw puste"; +App::$strings["Post to WordPress by default"] = "Domyślnie publikuj na WordPress"; +App::$strings["Forward comments (requires hubzilla_wp plugin)"] = "Przekazywanie komentarzy (wymaga wtyczki hubzilla_wp)"; +App::$strings["Wordpress Post"] = "Wordpress Post"; +App::$strings["Allow magic authentication only to websites of your immediate connections"] = "Zezwalaj na magiczne uwierzytelnianie tylko w witrynach internetowych Twoich bezpośrednich połączeń"; +App::$strings["Authchoose App"] = "APlikacja Authchoose"; +App::$strings["Authchoose"] = "Authchoose"; +App::$strings["bitchslap"] = "bitchslap"; +App::$strings["bitchslapped"] = "bitchslapped"; +App::$strings["shag"] = "shag"; +App::$strings["shagged"] = "shagged"; +App::$strings["patent"] = "patent"; +App::$strings["patented"] = "opatentowany"; +App::$strings["hug"] = "przytulić"; +App::$strings["hugged"] = "przytulony"; +App::$strings["murder"] = "zamordować"; +App::$strings["murdered"] = "zamordowany"; +App::$strings["worship"] = "uwielbiać"; +App::$strings["worshipped"] = "uwielbiany"; +App::$strings["kiss"] = "pocałować"; +App::$strings["kissed"] = "pocałowany"; +App::$strings["tempt"] = "kusić"; +App::$strings["tempted"] = "skuszony"; +App::$strings["raise eyebrows at"] = "unieść brwi"; +App::$strings["raised their eyebrows at"] = "podnieśli brwi"; +App::$strings["insult"] = "zniewaga"; +App::$strings["insulted"] = "znieważony"; +App::$strings["praise"] = "pochwała"; +App::$strings["praised"] = "pochwalony"; +App::$strings["be dubious of"] = "mieć wątpliwości"; +App::$strings["was dubious of"] = "zwątpiony"; +App::$strings["eat"] = "jeść"; +App::$strings["ate"] = "najedzony"; +App::$strings["giggle and fawn at"] = "chichotać i płakać"; +App::$strings["giggled and fawned at"] = "chichotał i łakał"; +App::$strings["doubt"] = "wątpić"; +App::$strings["doubted"] = "zwątpił"; +App::$strings["glare"] = "piorunujące spojrzenie"; +App::$strings["glared at"] = "obrzucił spojrzeniem"; +App::$strings["fuck"] = "pierdolić"; +App::$strings["fucked"] = "przejebane"; +App::$strings["bonk"] = "rżnąć"; +App::$strings["bonked"] = "zerżnięty"; +App::$strings["declare undying love for"] = "deklaruj wieczną miłość"; +App::$strings["declared undying love for"] = "zadeklarował wieczną miłość"; +App::$strings["New registration"] = "Nowa rejestracja"; +App::$strings["Message sent to %s. New account registration: %s"] = "Wiadomość wysłana do%s. Rejestracja nowego konta: %s"; +App::$strings["Pump.io Settings saved."] = "Ustawienia Pump.io zostały zapisane."; +App::$strings["Pump.io Crosspost Connector App"] = "Aplikacja Pump.io Crosspost Connector"; +App::$strings["Relay public posts to pump.io"] = "Przekazuj publiczne posty do Pump.io"; +App::$strings["Pump.io servername"] = "Nazwa serwera Pump.io"; +App::$strings["Without \"http://\" or \"https://\""] = "Bez \"http: //\" lub \"https: //\""; +App::$strings["Pump.io username"] = "Nazwa użytkownika Pump.io"; +App::$strings["Without the servername"] = "Bez nazwy serwera"; +App::$strings["You are not authenticated to pumpio"] = "Nie jesteś uwierzytelniony w pumpio"; +App::$strings["(Re-)Authenticate your pump.io connection"] = "(Ponownie) Uwierzytelnij swoje połączenie pump.io"; +App::$strings["Post to pump.io by default"] = "Piblikuj domyślnie w pump.io"; +App::$strings["Should posts be public"] = "Posty powinny być publiczne"; +App::$strings["Mirror all public posts"] = "Powielaj wszystkie posty publiczne"; +App::$strings["Pump.io Crosspost Connector"] = "Pump.io Crosspost Connector"; +App::$strings["You are now authenticated to pumpio."] = "Jesteś teraz uwierzytelniony w pumpio."; +App::$strings["return to the featured settings page"] = "wróć do polecanej strony ustawień"; +App::$strings["Post to Pump.io"] = "Opublikuj na Pump.io"; +App::$strings["NSA Bait App"] = "Aplikacja NSA Bait"; +App::$strings["Make yourself a political target"] = "Stań się celem politycznym"; +App::$strings["Add some colour to tag clouds"] = "Dodaj jakiś kolor do oznaczania chmur"; +App::$strings["Rainbow Tag App"] = "Aplikacja Rainbow Tag"; +App::$strings["Rainbow Tag"] = "Rainbow Tag"; +App::$strings["Send test email"] = "Wyślij testową wiadomość e-mail"; +App::$strings["Mail sent."] = "Mail wysłany."; +App::$strings["Sending of mail failed."] = "Wysyłanie poczty nie powiodło się."; +App::$strings["Mail Test"] = "Test poczty"; +App::$strings["Redmatrix File Storage Import"] = "Import magazyn plików Redmatrix"; +App::$strings["This will import all your Redmatrix cloud files to this channel."] = "Spowoduje to zaimportowanie wszystkich plików chmury Redmatrix do tego kanału."; +App::$strings["Use markdown for editing posts"] = "Użyj markdown do edycji postów"; +App::$strings["Fuzzloc Settings updated."] = "Zaktualizowano ustawienia Fuzzloc."; +App::$strings["Fuzzy Location App"] = "Aplikacja Fuzzy Location"; +App::$strings["Blur your precise location if your channel uses browser location mapping"] = "Zamaż swoją dokładną lokalizację, jeśli Twój kanał używa mapowania lokalizacji w przeglądarce"; +App::$strings["Minimum offset in meters"] = "Minimalne przesunięcie w metrach"; +App::$strings["Maximum offset in meters"] = "Maksymalne przesunięcie w metrach"; +App::$strings["Fuzzy Location"] = "Fuzzy Location"; +App::$strings["Startpage App"] = "Aplikacja Startpage"; +App::$strings["Set a preferred page to load on login from home page"] = "Ustaw preferowaną stronę do załadowania przy logowaniu ze strony głównej"; +App::$strings["Page to load after login"] = "Strona do załadowania po zalogowaniu"; +App::$strings["Examples: "apps", "network?f=&gid=37" (privacy collection), "channel" or "notifications/system" (leave blank for default network page (grid)."] = "Przykłady: "aplikacje", "sieć?f=&gid=37" (kolekcja prywatności), "kanał" lub "powiadomienie/system" (pozostaw puste dla domyślnej stony sieci (siatki)."; +App::$strings["Startpage"] = "Startpage"; +App::$strings["Focus (Hubzilla default)"] = "Fokus (domyślnie Hubzilla)"; +App::$strings["Theme settings"] = "Ustawienia motywu"; +App::$strings["Narrow navbar"] = "Wąski pasek nawigacyjny"; +App::$strings["Navigation bar background color"] = "Kolor tła paska nawigacji"; +App::$strings["Navigation bar icon color "] = "Kolor ikony paska nawigacji "; +App::$strings["Navigation bar active icon color "] = "Kolor ikony aktywnego paska nawigacji "; +App::$strings["Link color"] = "Kolor odnośnika"; +App::$strings["Set font-color for banner"] = "Ustaw kolor czcionki na banerze"; +App::$strings["Set the background color"] = "Ustaw kolor tła"; +App::$strings["Set the background image"] = "Ustaw obraz tła"; +App::$strings["Set the background color of items"] = "Ustaw kolor tła elementów"; +App::$strings["Set the background color of comments"] = "Ustaw kolor tła komentarzy"; +App::$strings["Set font-size for the entire application"] = "Ustaw rozmiar czcionki dla całej aplikacji"; +App::$strings["Examples: 1rem, 100%, 16px"] = "Przykłady: 1rem, 100%, 16px"; +App::$strings["Set font-color for posts and comments"] = "Ustaw kolor czcionki dla postów i komentarzy"; +App::$strings["Set radius of corners"] = "Ustaw promień narożników"; +App::$strings["Example: 4px"] = "Przykład: 4px"; +App::$strings["Set shadow depth of photos"] = "Ustaw głębię cienia zdjęć"; +App::$strings["Set maximum width of content region in pixel"] = "Ustaw maksymalną szerokość obszaru treści w pikselach"; +App::$strings["Leave empty for default width"] = "Pozostaw puste dla domyślnej szerokości"; +App::$strings["Set size of conversation author photo"] = "Ustaw rozmiar zdjęcia autora rozmowy"; +App::$strings["Set size of followup author photos"] = "Ustaw rozmiar kolejnych zdjęć autora"; +App::$strings["Show advanced settings"] = "Pokaż ustawienia zaawansowane"; +App::$strings["Create an account to access services and applications"] = "Utwórz konto, aby uzyskać dostęp do usług i aplikacji"; +App::$strings["Login/Email"] = "Login/Email"; +App::$strings["Password"] = "Hasło"; +App::$strings["Remember me"] = "Zapamiętaj mnie"; +App::$strings["Forgot your password?"] = "Nie pamiętasz hasła?"; +App::$strings["[\$Projectname] Website SSL error for %s"] = "[\$Projectname] Błąd SSL witryny internetowej dla %s"; +App::$strings["Website SSL certificate is not valid. Please correct."] = "Certyfikat SSL witryny jest nieprawidłowy. Proszę popraw."; +App::$strings["[\$Projectname] Cron tasks not running on %s"] = "[\$Projectname] Zadania Crona nie działają na %s"; +App::$strings["Cron/Scheduled tasks not running."] = "Zadania Crona (zaplanowane) nie działają."; diff --git a/view/pl/htconfig.tpl b/view/pl/htconfig.tpl new file mode 100644 index 000000000..ca8ad6375 --- /dev/null +++ b/view/pl/htconfig.tpl @@ -0,0 +1,111 @@ + Date: Wed, 27 Jan 2021 12:14:30 +0200 Subject: Fix wrong redbasic theme permissions --- view/theme/redbasic/css/blockmode.css | 0 view/theme/redbasic/css/mod_page.css | 0 view/theme/redbasic/css/narrow_navbar.css | 0 view/theme/redbasic/css/sloppy_photos.css | 0 view/theme/redbasic/css/style.css | 0 view/theme/redbasic/js/redbasic.js | 0 view/theme/redbasic/php/config.php | 0 view/theme/redbasic/php/style.php | 0 view/theme/redbasic/php/theme.php | 0 view/theme/redbasic/php/theme_init.php | 0 view/theme/redbasic/schema/Focus-Boxy.css | 0 view/theme/redbasic/schema/Focus-Boxy.php | 0 view/theme/redbasic/schema/Focus-Light.css | 0 view/theme/redbasic/schema/Focus-Light.php | 0 view/theme/redbasic/schema/dark.css | 0 view/theme/redbasic/schema/dark.php | 0 view/theme/redbasic/tpl/theme_settings.tpl | 0 17 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 view/theme/redbasic/css/blockmode.css mode change 100755 => 100644 view/theme/redbasic/css/mod_page.css mode change 100755 => 100644 view/theme/redbasic/css/narrow_navbar.css mode change 100755 => 100644 view/theme/redbasic/css/sloppy_photos.css mode change 100755 => 100644 view/theme/redbasic/css/style.css mode change 100755 => 100644 view/theme/redbasic/js/redbasic.js mode change 100755 => 100644 view/theme/redbasic/php/config.php mode change 100755 => 100644 view/theme/redbasic/php/style.php mode change 100755 => 100644 view/theme/redbasic/php/theme.php mode change 100755 => 100644 view/theme/redbasic/php/theme_init.php mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Boxy.css mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Boxy.php mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Light.css mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Light.php mode change 100755 => 100644 view/theme/redbasic/schema/dark.css mode change 100755 => 100644 view/theme/redbasic/schema/dark.php mode change 100755 => 100644 view/theme/redbasic/tpl/theme_settings.tpl diff --git a/view/theme/redbasic/css/blockmode.css b/view/theme/redbasic/css/blockmode.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/mod_page.css b/view/theme/redbasic/css/mod_page.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/narrow_navbar.css b/view/theme/redbasic/css/narrow_navbar.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/sloppy_photos.css b/view/theme/redbasic/css/sloppy_photos.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/js/redbasic.js b/view/theme/redbasic/js/redbasic.js old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/config.php b/view/theme/redbasic/php/config.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/style.php b/view/theme/redbasic/php/style.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/theme.php b/view/theme/redbasic/php/theme.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/theme_init.php b/view/theme/redbasic/php/theme_init.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Boxy.css b/view/theme/redbasic/schema/Focus-Boxy.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Boxy.php b/view/theme/redbasic/schema/Focus-Boxy.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Light.css b/view/theme/redbasic/schema/Focus-Light.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Light.php b/view/theme/redbasic/schema/Focus-Light.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/dark.css b/view/theme/redbasic/schema/dark.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/dark.php b/view/theme/redbasic/schema/dark.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/tpl/theme_settings.tpl b/view/theme/redbasic/tpl/theme_settings.tpl old mode 100755 new mode 100644 -- cgit v1.2.3 From af719fea406f7acd24f65f7396b58c8654e590c9 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 27 Jan 2021 10:15:26 +0000 Subject: fix file permissions. 755 for dirs, 644 for files --- .gitignore | 0 .homeinstall/zotserver-setup.sh | 0 .openshift/action_hooks/deploy | 0 .openshift/cron/weekly/chronograph | 0 Zotlabs/Daemon/Importdoc.php | 0 Zotlabs/Render/SimpleTemplate.php | 0 Zotlabs/Render/SmartyInterface.php | 0 Zotlabs/Render/SmartyTemplate.php | 0 Zotlabs/Render/TemplateEngine.php | 0 boot.php | 0 include/dba/dba_driver.php | 0 include/dba/dba_pdo.php | 0 include/items.php | 0 include/oembed.php | 0 include/plugin.php | 0 index.php | 0 install/htconfig.sample.php | 0 library/jgrowl/examples/jgrowl.html | 0 library/jgrowl/jquery.jgrowl.js | 0 library/jgrowl/less/jgrowl.core.less | 0 .../kzykhys/git/test/PHPGit/Command/ShortlogCommandTest.php | 0 tests/travis/gen_apidocs.sh | 0 tests/travis/prepare.sh | 0 tests/travis/prepare_mysql.sh | 0 tests/travis/prepare_pgsql.sh | 0 util/add_addon_repo | 0 util/add_theme_repo | 0 util/add_widget_repo | 0 util/addons | 0 util/admins | 0 util/config | 0 util/connect | 0 util/dcp | 0 util/dmkdir | 0 util/fresh | 0 util/friendica-to-smarty-tpl.py | 0 util/hz | 0 util/importdoc | 0 util/makedocs | 0 util/pconfig | 0 util/precompile_smarty3.php | 0 util/run_xgettext.sh | 0 util/safemode | 0 util/schemaspy | 0 util/service_class | 0 util/shredder/JSON.sh | 0 util/shredder/OAuth.sh | 0 util/shredder/ShredOAuth.sh | 0 util/shredder/shredder | 0 util/storageconv.sh | 0 util/thumbrepair | 0 util/udall | 0 util/update_addon_repo | 0 util/update_theme_repo | 0 util/update_widget_repo | 0 util/updatetpl.py | 0 util/zotsh/zotsh.py | 0 vendor/commerceguys/intl/scripts/fetch_data.sh | 0 vendor/league/html-to-markdown/bin/html-to-markdown | 0 vendor/sabre/dav/bin/build.php | 0 vendor/sabre/dav/bin/googlecode_upload.py | 0 vendor/sabre/dav/bin/migrateto20.php | 0 vendor/sabre/dav/bin/migrateto21.php | 0 vendor/sabre/dav/bin/migrateto30.php | 0 vendor/sabre/dav/bin/migrateto32.php | 0 vendor/sabre/dav/bin/naturalselection | 0 vendor/sabre/dav/bin/sabredav | 0 vendor/sabre/dav/bin/sabredav.php | 0 vendor/sabre/vobject/bin/bench.php | 0 vendor/sabre/vobject/bin/fetch_windows_zones.php | 0 vendor/sabre/vobject/bin/generate_vcards | 0 vendor/sabre/vobject/bin/generateicalendardata.php | 0 vendor/sabre/vobject/bin/mergeduplicates.php | 0 vendor/sabre/vobject/bin/vobject | 0 vendor/simplepie/simplepie/.travis.yml | 0 vendor/simplepie/simplepie/library/SimplePie.php | 0 .../simplepie/library/SimplePie/Cache/Memcached.php | 0 vendor/simplepie/simplepie/library/SimplePie/Registry.php | 0 vendor/twbs/bootstrap/build/change-version.js | 0 vendor/twbs/bootstrap/build/ship.sh | 0 view/js/sse_worker.js | 0 view/theme/redbasic/css/blockmode.css | 0 view/theme/redbasic/css/mod_page.css | 0 view/theme/redbasic/css/narrow_navbar.css | 0 view/theme/redbasic/css/sloppy_photos.css | 0 view/theme/redbasic/css/style.css | 0 .../gray_and_black_diagonal_stripes_background_seamless.gif | Bin .../gray_and_white_diagonal_stripes_background_seamless.gif | Bin view/theme/redbasic/img/screenshot.png | Bin view/theme/redbasic/js/redbasic.js | 0 view/theme/redbasic/php/config.php | 0 view/theme/redbasic/php/style.php | 0 view/theme/redbasic/php/theme.php | 0 view/theme/redbasic/php/theme_init.php | 0 view/theme/redbasic/schema/Focus-Boxy.css | 0 view/theme/redbasic/schema/Focus-Boxy.php | 0 view/theme/redbasic/schema/Focus-Light.css | 0 view/theme/redbasic/schema/Focus-Light.php | 0 view/theme/redbasic/schema/dark.css | 0 view/theme/redbasic/schema/dark.php | 0 view/theme/redbasic/tpl/theme_settings.tpl | 0 view/tpl/404.tpl | 0 view/tpl/abook_edit.tpl | 0 view/tpl/acl_selector.tpl | 0 view/tpl/admin_accounts.tpl | 0 view/tpl/admin_aside.tpl | 0 view/tpl/admin_channels.tpl | 0 view/tpl/admin_logs.tpl | 0 view/tpl/admin_plugins.tpl | 0 view/tpl/admin_plugins_details.tpl | 0 view/tpl/admin_security.tpl | 0 view/tpl/admin_site.tpl | 0 view/tpl/admin_summary.tpl | 0 view/tpl/album_edit.tpl | 0 view/tpl/atom_feed.tpl | 0 view/tpl/build_query.tpl | 0 view/tpl/cal_calendar.tpl | 0 view/tpl/cal_event.tpl | 0 view/tpl/categories_widget.tpl | 0 view/tpl/channel.tpl | 0 view/tpl/channel_import.tpl | 0 view/tpl/channel_rename.tpl | 0 view/tpl/channels.tpl | 0 view/tpl/chanview.tpl | 0 view/tpl/comment_item.tpl | 0 view/tpl/common_friends.tpl | 0 view/tpl/common_pills.tpl | 0 view/tpl/common_tabs.tpl | 0 view/tpl/connection_template.tpl | 0 view/tpl/connections.tpl | 0 view/tpl/contact_block.tpl | 0 view/tpl/contact_slider.tpl | 0 view/tpl/contact_template.tpl | 0 view/tpl/conv.tpl | 0 view/tpl/conv_frame.tpl | 0 view/tpl/conv_item.tpl | 0 view/tpl/conv_list.tpl | 0 view/tpl/conversation.tpl | 0 view/tpl/convobj.tpl | 0 view/tpl/cover_photo.tpl | 0 view/tpl/cover_photo_widget.tpl | 0 view/tpl/cropbody.tpl | 0 view/tpl/cropcover.tpl | 0 view/tpl/crophead.tpl | 0 view/tpl/defperms.tpl | 0 view/tpl/directory_header.tpl | 0 view/tpl/direntry.tpl | 0 view/tpl/edpost_head.tpl | 0 view/tpl/email_notify_html.tpl | 0 view/tpl/email_notify_text.tpl | 0 view/tpl/event.tpl | 0 view/tpl/event_form.tpl | 0 view/tpl/event_head.tpl | 0 view/tpl/event_item_header.tpl | 0 view/tpl/events-js.tpl | 0 view/tpl/events_cal-js.tpl | 0 view/tpl/events_tools_side.tpl | 0 view/tpl/failed_updates.tpl | 0 view/tpl/field.tpl | 0 view/tpl/field_acheckbox.tpl | 0 view/tpl/field_checkbox.tpl | 0 view/tpl/field_combobox.tpl | 0 view/tpl/field_custom.tpl | 0 view/tpl/field_input.tpl | 0 view/tpl/field_intcheckbox.tpl | 0 view/tpl/field_password.tpl | 0 view/tpl/field_radio.tpl | 0 view/tpl/field_richtext.tpl | 0 view/tpl/field_select.tpl | 0 view/tpl/field_select_raw.tpl | 0 view/tpl/field_textarea.tpl | 0 view/tpl/field_themeselect.tpl | 0 view/tpl/field_yesno.tpl | 0 view/tpl/fileas_widget.tpl | 0 view/tpl/filebrowser.tpl | 0 view/tpl/filer_dialog.tpl | 0 view/tpl/follow.tpl | 0 view/tpl/generic_links_widget.tpl | 0 view/tpl/group_edit.tpl | 0 view/tpl/group_selection.tpl | 0 view/tpl/group_side.tpl | 0 view/tpl/groupeditor.tpl | 0 view/tpl/head.tpl | 0 view/tpl/hq.tpl | 0 view/tpl/hq_controls.tpl | 0 view/tpl/install.tpl | 0 view/tpl/install_checks.tpl | 0 view/tpl/install_db.tpl | 0 view/tpl/install_settings.tpl | 0 view/tpl/invite.tpl | 0 view/tpl/item_import.tpl | 0 view/tpl/jot-header.tpl | 0 view/tpl/jot.tpl | 0 view/tpl/jot_geotag.tpl | 0 view/tpl/js_strings.tpl | 0 view/tpl/lang_selector.tpl | 0 view/tpl/like_noshare.tpl | 0 view/tpl/login.tpl | 0 view/tpl/logout.tpl | 0 view/tpl/lostpass.tpl | 0 view/tpl/mail_conv.tpl | 0 view/tpl/mail_display.tpl | 0 view/tpl/mail_head.tpl | 0 view/tpl/mail_list.tpl | 0 view/tpl/main_slider.tpl | 0 view/tpl/message_side.tpl | 0 view/tpl/micropro_img.tpl | 0 view/tpl/micropro_txt.tpl | 0 view/tpl/mood_content.tpl | 0 view/tpl/msg-header.tpl | 0 view/tpl/myapps.tpl | 0 view/tpl/navbar_default.tpl | 0 view/tpl/navbar_tucson.tpl | 0 view/tpl/new_channel.tpl | 0 view/tpl/notifications.tpl | 0 view/tpl/notify.tpl | 0 view/tpl/oauth.tpl | 0 view/tpl/oauth2.tpl | 0 view/tpl/oauth2_edit.tpl | 0 view/tpl/oauth_authorize.tpl | 0 view/tpl/oauth_authorize_done.tpl | 0 view/tpl/oauth_edit.tpl | 0 view/tpl/oembed_video.tpl | 0 view/tpl/oexchange_xrd.tpl | 0 view/tpl/page_display.tpl | 0 view/tpl/peoplefind.tpl | 0 view/tpl/photo_album.tpl | 0 view/tpl/photo_album_portfolio.tpl | 0 view/tpl/photo_albums.tpl | 0 view/tpl/photo_drop.tpl | 0 view/tpl/photo_item.tpl | 0 view/tpl/photo_portfolio.tpl | 0 view/tpl/photo_top.tpl | 0 view/tpl/photo_view.tpl | 0 view/tpl/photos_recent.tpl | 0 view/tpl/photos_upload.tpl | 0 view/tpl/photosajax.tpl | 0 view/tpl/poco_entry_xml.tpl | 0 view/tpl/poco_xml.tpl | 0 view/tpl/poke_content.tpl | 0 view/tpl/posted_date_widget.tpl | 0 view/tpl/profed_head.tpl | 0 view/tpl/profile_advanced.tpl | 0 view/tpl/profile_edit.tpl | 0 view/tpl/profile_entry.tpl | 0 view/tpl/profile_listing_header.tpl | 0 view/tpl/profile_photo.tpl | 0 view/tpl/profile_vcard.tpl | 0 view/tpl/profile_vcard_short.tpl | 0 view/tpl/prv_message.tpl | 0 view/tpl/pwdreset.tpl | 0 view/tpl/register.tpl | 0 view/tpl/remote_friends_common.tpl | 0 view/tpl/removeme.tpl | 0 view/tpl/rmagic.tpl | 0 view/tpl/search_item.tpl | 0 view/tpl/settings.tpl | 0 view/tpl/settings_account.tpl | 0 view/tpl/settings_addons.tpl | 0 view/tpl/settings_display.tpl | 0 view/tpl/settings_features.tpl | 0 view/tpl/settings_module.tpl | 0 view/tpl/settings_nick_set.tpl | 0 view/tpl/siteinfo.tpl | 0 view/tpl/suggest_friends.tpl | 0 view/tpl/suggest_page.tpl | 0 view/tpl/threaded_conversation.tpl | 0 view/tpl/viewcontact_template.tpl | 0 view/tpl/xchan_vcard.tpl | 0 view/tpl/xrd_host.tpl | 0 view/tpl/xrd_person.tpl | 0 271 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 .gitignore mode change 100755 => 100644 .homeinstall/zotserver-setup.sh mode change 100755 => 100644 .openshift/action_hooks/deploy mode change 100755 => 100644 .openshift/cron/weekly/chronograph mode change 100755 => 100644 Zotlabs/Daemon/Importdoc.php mode change 100755 => 100644 Zotlabs/Render/SimpleTemplate.php mode change 100755 => 100644 Zotlabs/Render/SmartyInterface.php mode change 100755 => 100644 Zotlabs/Render/SmartyTemplate.php mode change 100755 => 100644 Zotlabs/Render/TemplateEngine.php mode change 100755 => 100644 boot.php mode change 100755 => 100644 include/dba/dba_driver.php mode change 100755 => 100644 include/dba/dba_pdo.php mode change 100755 => 100644 include/items.php mode change 100755 => 100644 include/oembed.php mode change 100755 => 100644 include/plugin.php mode change 100755 => 100644 index.php mode change 100755 => 100644 install/htconfig.sample.php mode change 100755 => 100644 library/jgrowl/examples/jgrowl.html mode change 100755 => 100644 library/jgrowl/jquery.jgrowl.js mode change 100755 => 100644 library/jgrowl/less/jgrowl.core.less mode change 100755 => 100644 library/kzykhys/git/test/PHPGit/Command/ShortlogCommandTest.php mode change 100755 => 100644 tests/travis/gen_apidocs.sh mode change 100755 => 100644 tests/travis/prepare.sh mode change 100755 => 100644 tests/travis/prepare_mysql.sh mode change 100755 => 100644 tests/travis/prepare_pgsql.sh mode change 100755 => 100644 util/add_addon_repo mode change 100755 => 100644 util/add_theme_repo mode change 100755 => 100644 util/add_widget_repo mode change 100755 => 100644 util/addons mode change 100755 => 100644 util/admins mode change 100755 => 100644 util/config mode change 100755 => 100644 util/connect mode change 100755 => 100644 util/dcp mode change 100755 => 100644 util/dmkdir mode change 100755 => 100644 util/fresh mode change 100755 => 100644 util/friendica-to-smarty-tpl.py mode change 100755 => 100644 util/hz mode change 100755 => 100644 util/importdoc mode change 100755 => 100644 util/makedocs mode change 100755 => 100644 util/pconfig mode change 100755 => 100644 util/precompile_smarty3.php mode change 100755 => 100644 util/run_xgettext.sh mode change 100755 => 100644 util/safemode mode change 100755 => 100644 util/schemaspy mode change 100755 => 100644 util/service_class mode change 100755 => 100644 util/shredder/JSON.sh mode change 100755 => 100644 util/shredder/OAuth.sh mode change 100755 => 100644 util/shredder/ShredOAuth.sh mode change 100755 => 100644 util/shredder/shredder mode change 100755 => 100644 util/storageconv.sh mode change 100755 => 100644 util/thumbrepair mode change 100755 => 100644 util/udall mode change 100755 => 100644 util/update_addon_repo mode change 100755 => 100644 util/update_theme_repo mode change 100755 => 100644 util/update_widget_repo mode change 100755 => 100644 util/updatetpl.py mode change 100755 => 100644 util/zotsh/zotsh.py mode change 100755 => 100644 vendor/commerceguys/intl/scripts/fetch_data.sh mode change 100755 => 100644 vendor/league/html-to-markdown/bin/html-to-markdown mode change 100755 => 100644 vendor/sabre/dav/bin/build.php mode change 100755 => 100644 vendor/sabre/dav/bin/googlecode_upload.py mode change 100755 => 100644 vendor/sabre/dav/bin/migrateto20.php mode change 100755 => 100644 vendor/sabre/dav/bin/migrateto21.php mode change 100755 => 100644 vendor/sabre/dav/bin/migrateto30.php mode change 100755 => 100644 vendor/sabre/dav/bin/migrateto32.php mode change 100755 => 100644 vendor/sabre/dav/bin/naturalselection mode change 100755 => 100644 vendor/sabre/dav/bin/sabredav mode change 100755 => 100644 vendor/sabre/dav/bin/sabredav.php mode change 100755 => 100644 vendor/sabre/vobject/bin/bench.php mode change 100755 => 100644 vendor/sabre/vobject/bin/fetch_windows_zones.php mode change 100755 => 100644 vendor/sabre/vobject/bin/generate_vcards mode change 100755 => 100644 vendor/sabre/vobject/bin/generateicalendardata.php mode change 100755 => 100644 vendor/sabre/vobject/bin/mergeduplicates.php mode change 100755 => 100644 vendor/sabre/vobject/bin/vobject mode change 100755 => 100644 vendor/simplepie/simplepie/.travis.yml mode change 100755 => 100644 vendor/simplepie/simplepie/library/SimplePie.php mode change 100755 => 100644 vendor/simplepie/simplepie/library/SimplePie/Cache/Memcached.php mode change 100755 => 100644 vendor/simplepie/simplepie/library/SimplePie/Registry.php mode change 100755 => 100644 vendor/twbs/bootstrap/build/change-version.js mode change 100755 => 100644 vendor/twbs/bootstrap/build/ship.sh mode change 100755 => 100644 view/js/sse_worker.js mode change 100755 => 100644 view/theme/redbasic/css/blockmode.css mode change 100755 => 100644 view/theme/redbasic/css/mod_page.css mode change 100755 => 100644 view/theme/redbasic/css/narrow_navbar.css mode change 100755 => 100644 view/theme/redbasic/css/sloppy_photos.css mode change 100755 => 100644 view/theme/redbasic/css/style.css mode change 100755 => 100644 view/theme/redbasic/img/gray_and_black_diagonal_stripes_background_seamless.gif mode change 100755 => 100644 view/theme/redbasic/img/gray_and_white_diagonal_stripes_background_seamless.gif mode change 100755 => 100644 view/theme/redbasic/img/screenshot.png mode change 100755 => 100644 view/theme/redbasic/js/redbasic.js mode change 100755 => 100644 view/theme/redbasic/php/config.php mode change 100755 => 100644 view/theme/redbasic/php/style.php mode change 100755 => 100644 view/theme/redbasic/php/theme.php mode change 100755 => 100644 view/theme/redbasic/php/theme_init.php mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Boxy.css mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Boxy.php mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Light.css mode change 100755 => 100644 view/theme/redbasic/schema/Focus-Light.php mode change 100755 => 100644 view/theme/redbasic/schema/dark.css mode change 100755 => 100644 view/theme/redbasic/schema/dark.php mode change 100755 => 100644 view/theme/redbasic/tpl/theme_settings.tpl mode change 100755 => 100644 view/tpl/404.tpl mode change 100755 => 100644 view/tpl/abook_edit.tpl mode change 100755 => 100644 view/tpl/acl_selector.tpl mode change 100755 => 100644 view/tpl/admin_accounts.tpl mode change 100755 => 100644 view/tpl/admin_aside.tpl mode change 100755 => 100644 view/tpl/admin_channels.tpl mode change 100755 => 100644 view/tpl/admin_logs.tpl mode change 100755 => 100644 view/tpl/admin_plugins.tpl mode change 100755 => 100644 view/tpl/admin_plugins_details.tpl mode change 100755 => 100644 view/tpl/admin_security.tpl mode change 100755 => 100644 view/tpl/admin_site.tpl mode change 100755 => 100644 view/tpl/admin_summary.tpl mode change 100755 => 100644 view/tpl/album_edit.tpl mode change 100755 => 100644 view/tpl/atom_feed.tpl mode change 100755 => 100644 view/tpl/build_query.tpl mode change 100755 => 100644 view/tpl/cal_calendar.tpl mode change 100755 => 100644 view/tpl/cal_event.tpl mode change 100755 => 100644 view/tpl/categories_widget.tpl mode change 100755 => 100644 view/tpl/channel.tpl mode change 100755 => 100644 view/tpl/channel_import.tpl mode change 100755 => 100644 view/tpl/channel_rename.tpl mode change 100755 => 100644 view/tpl/channels.tpl mode change 100755 => 100644 view/tpl/chanview.tpl mode change 100755 => 100644 view/tpl/comment_item.tpl mode change 100755 => 100644 view/tpl/common_friends.tpl mode change 100755 => 100644 view/tpl/common_pills.tpl mode change 100755 => 100644 view/tpl/common_tabs.tpl mode change 100755 => 100644 view/tpl/connection_template.tpl mode change 100755 => 100644 view/tpl/connections.tpl mode change 100755 => 100644 view/tpl/contact_block.tpl mode change 100755 => 100644 view/tpl/contact_slider.tpl mode change 100755 => 100644 view/tpl/contact_template.tpl mode change 100755 => 100644 view/tpl/conv.tpl mode change 100755 => 100644 view/tpl/conv_frame.tpl mode change 100755 => 100644 view/tpl/conv_item.tpl mode change 100755 => 100644 view/tpl/conv_list.tpl mode change 100755 => 100644 view/tpl/conversation.tpl mode change 100755 => 100644 view/tpl/convobj.tpl mode change 100755 => 100644 view/tpl/cover_photo.tpl mode change 100755 => 100644 view/tpl/cover_photo_widget.tpl mode change 100755 => 100644 view/tpl/cropbody.tpl mode change 100755 => 100644 view/tpl/cropcover.tpl mode change 100755 => 100644 view/tpl/crophead.tpl mode change 100755 => 100644 view/tpl/defperms.tpl mode change 100755 => 100644 view/tpl/directory_header.tpl mode change 100755 => 100644 view/tpl/direntry.tpl mode change 100755 => 100644 view/tpl/edpost_head.tpl mode change 100755 => 100644 view/tpl/email_notify_html.tpl mode change 100755 => 100644 view/tpl/email_notify_text.tpl mode change 100755 => 100644 view/tpl/event.tpl mode change 100755 => 100644 view/tpl/event_form.tpl mode change 100755 => 100644 view/tpl/event_head.tpl mode change 100755 => 100644 view/tpl/event_item_header.tpl mode change 100755 => 100644 view/tpl/events-js.tpl mode change 100755 => 100644 view/tpl/events_cal-js.tpl mode change 100755 => 100644 view/tpl/events_tools_side.tpl mode change 100755 => 100644 view/tpl/failed_updates.tpl mode change 100755 => 100644 view/tpl/field.tpl mode change 100755 => 100644 view/tpl/field_acheckbox.tpl mode change 100755 => 100644 view/tpl/field_checkbox.tpl mode change 100755 => 100644 view/tpl/field_combobox.tpl mode change 100755 => 100644 view/tpl/field_custom.tpl mode change 100755 => 100644 view/tpl/field_input.tpl mode change 100755 => 100644 view/tpl/field_intcheckbox.tpl mode change 100755 => 100644 view/tpl/field_password.tpl mode change 100755 => 100644 view/tpl/field_radio.tpl mode change 100755 => 100644 view/tpl/field_richtext.tpl mode change 100755 => 100644 view/tpl/field_select.tpl mode change 100755 => 100644 view/tpl/field_select_raw.tpl mode change 100755 => 100644 view/tpl/field_textarea.tpl mode change 100755 => 100644 view/tpl/field_themeselect.tpl mode change 100755 => 100644 view/tpl/field_yesno.tpl mode change 100755 => 100644 view/tpl/fileas_widget.tpl mode change 100755 => 100644 view/tpl/filebrowser.tpl mode change 100755 => 100644 view/tpl/filer_dialog.tpl mode change 100755 => 100644 view/tpl/follow.tpl mode change 100755 => 100644 view/tpl/generic_links_widget.tpl mode change 100755 => 100644 view/tpl/group_edit.tpl mode change 100755 => 100644 view/tpl/group_selection.tpl mode change 100755 => 100644 view/tpl/group_side.tpl mode change 100755 => 100644 view/tpl/groupeditor.tpl mode change 100755 => 100644 view/tpl/head.tpl mode change 100755 => 100644 view/tpl/hq.tpl mode change 100755 => 100644 view/tpl/hq_controls.tpl mode change 100755 => 100644 view/tpl/install.tpl mode change 100755 => 100644 view/tpl/install_checks.tpl mode change 100755 => 100644 view/tpl/install_db.tpl mode change 100755 => 100644 view/tpl/install_settings.tpl mode change 100755 => 100644 view/tpl/invite.tpl mode change 100755 => 100644 view/tpl/item_import.tpl mode change 100755 => 100644 view/tpl/jot-header.tpl mode change 100755 => 100644 view/tpl/jot.tpl mode change 100755 => 100644 view/tpl/jot_geotag.tpl mode change 100755 => 100644 view/tpl/js_strings.tpl mode change 100755 => 100644 view/tpl/lang_selector.tpl mode change 100755 => 100644 view/tpl/like_noshare.tpl mode change 100755 => 100644 view/tpl/login.tpl mode change 100755 => 100644 view/tpl/logout.tpl mode change 100755 => 100644 view/tpl/lostpass.tpl mode change 100755 => 100644 view/tpl/mail_conv.tpl mode change 100755 => 100644 view/tpl/mail_display.tpl mode change 100755 => 100644 view/tpl/mail_head.tpl mode change 100755 => 100644 view/tpl/mail_list.tpl mode change 100755 => 100644 view/tpl/main_slider.tpl mode change 100755 => 100644 view/tpl/message_side.tpl mode change 100755 => 100644 view/tpl/micropro_img.tpl mode change 100755 => 100644 view/tpl/micropro_txt.tpl mode change 100755 => 100644 view/tpl/mood_content.tpl mode change 100755 => 100644 view/tpl/msg-header.tpl mode change 100755 => 100644 view/tpl/myapps.tpl mode change 100755 => 100644 view/tpl/navbar_default.tpl mode change 100755 => 100644 view/tpl/navbar_tucson.tpl mode change 100755 => 100644 view/tpl/new_channel.tpl mode change 100755 => 100644 view/tpl/notifications.tpl mode change 100755 => 100644 view/tpl/notify.tpl mode change 100755 => 100644 view/tpl/oauth.tpl mode change 100755 => 100644 view/tpl/oauth2.tpl mode change 100755 => 100644 view/tpl/oauth2_edit.tpl mode change 100755 => 100644 view/tpl/oauth_authorize.tpl mode change 100755 => 100644 view/tpl/oauth_authorize_done.tpl mode change 100755 => 100644 view/tpl/oauth_edit.tpl mode change 100755 => 100644 view/tpl/oembed_video.tpl mode change 100755 => 100644 view/tpl/oexchange_xrd.tpl mode change 100755 => 100644 view/tpl/page_display.tpl mode change 100755 => 100644 view/tpl/peoplefind.tpl mode change 100755 => 100644 view/tpl/photo_album.tpl mode change 100755 => 100644 view/tpl/photo_album_portfolio.tpl mode change 100755 => 100644 view/tpl/photo_albums.tpl mode change 100755 => 100644 view/tpl/photo_drop.tpl mode change 100755 => 100644 view/tpl/photo_item.tpl mode change 100755 => 100644 view/tpl/photo_portfolio.tpl mode change 100755 => 100644 view/tpl/photo_top.tpl mode change 100755 => 100644 view/tpl/photo_view.tpl mode change 100755 => 100644 view/tpl/photos_recent.tpl mode change 100755 => 100644 view/tpl/photos_upload.tpl mode change 100755 => 100644 view/tpl/photosajax.tpl mode change 100755 => 100644 view/tpl/poco_entry_xml.tpl mode change 100755 => 100644 view/tpl/poco_xml.tpl mode change 100755 => 100644 view/tpl/poke_content.tpl mode change 100755 => 100644 view/tpl/posted_date_widget.tpl mode change 100755 => 100644 view/tpl/profed_head.tpl mode change 100755 => 100644 view/tpl/profile_advanced.tpl mode change 100755 => 100644 view/tpl/profile_edit.tpl mode change 100755 => 100644 view/tpl/profile_entry.tpl mode change 100755 => 100644 view/tpl/profile_listing_header.tpl mode change 100755 => 100644 view/tpl/profile_photo.tpl mode change 100755 => 100644 view/tpl/profile_vcard.tpl mode change 100755 => 100644 view/tpl/profile_vcard_short.tpl mode change 100755 => 100644 view/tpl/prv_message.tpl mode change 100755 => 100644 view/tpl/pwdreset.tpl mode change 100755 => 100644 view/tpl/register.tpl mode change 100755 => 100644 view/tpl/remote_friends_common.tpl mode change 100755 => 100644 view/tpl/removeme.tpl mode change 100755 => 100644 view/tpl/rmagic.tpl mode change 100755 => 100644 view/tpl/search_item.tpl mode change 100755 => 100644 view/tpl/settings.tpl mode change 100755 => 100644 view/tpl/settings_account.tpl mode change 100755 => 100644 view/tpl/settings_addons.tpl mode change 100755 => 100644 view/tpl/settings_display.tpl mode change 100755 => 100644 view/tpl/settings_features.tpl mode change 100755 => 100644 view/tpl/settings_module.tpl mode change 100755 => 100644 view/tpl/settings_nick_set.tpl mode change 100755 => 100644 view/tpl/siteinfo.tpl mode change 100755 => 100644 view/tpl/suggest_friends.tpl mode change 100755 => 100644 view/tpl/suggest_page.tpl mode change 100755 => 100644 view/tpl/threaded_conversation.tpl mode change 100755 => 100644 view/tpl/viewcontact_template.tpl mode change 100755 => 100644 view/tpl/xchan_vcard.tpl mode change 100755 => 100644 view/tpl/xrd_host.tpl mode change 100755 => 100644 view/tpl/xrd_person.tpl diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/.homeinstall/zotserver-setup.sh b/.homeinstall/zotserver-setup.sh old mode 100755 new mode 100644 diff --git a/.openshift/action_hooks/deploy b/.openshift/action_hooks/deploy old mode 100755 new mode 100644 diff --git a/.openshift/cron/weekly/chronograph b/.openshift/cron/weekly/chronograph old mode 100755 new mode 100644 diff --git a/Zotlabs/Daemon/Importdoc.php b/Zotlabs/Daemon/Importdoc.php old mode 100755 new mode 100644 diff --git a/Zotlabs/Render/SimpleTemplate.php b/Zotlabs/Render/SimpleTemplate.php old mode 100755 new mode 100644 diff --git a/Zotlabs/Render/SmartyInterface.php b/Zotlabs/Render/SmartyInterface.php old mode 100755 new mode 100644 diff --git a/Zotlabs/Render/SmartyTemplate.php b/Zotlabs/Render/SmartyTemplate.php old mode 100755 new mode 100644 diff --git a/Zotlabs/Render/TemplateEngine.php b/Zotlabs/Render/TemplateEngine.php old mode 100755 new mode 100644 diff --git a/boot.php b/boot.php old mode 100755 new mode 100644 diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php old mode 100755 new mode 100644 diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php old mode 100755 new mode 100644 diff --git a/include/items.php b/include/items.php old mode 100755 new mode 100644 diff --git a/include/oembed.php b/include/oembed.php old mode 100755 new mode 100644 diff --git a/include/plugin.php b/include/plugin.php old mode 100755 new mode 100644 diff --git a/index.php b/index.php old mode 100755 new mode 100644 diff --git a/install/htconfig.sample.php b/install/htconfig.sample.php old mode 100755 new mode 100644 diff --git a/library/jgrowl/examples/jgrowl.html b/library/jgrowl/examples/jgrowl.html old mode 100755 new mode 100644 diff --git a/library/jgrowl/jquery.jgrowl.js b/library/jgrowl/jquery.jgrowl.js old mode 100755 new mode 100644 diff --git a/library/jgrowl/less/jgrowl.core.less b/library/jgrowl/less/jgrowl.core.less old mode 100755 new mode 100644 diff --git a/library/kzykhys/git/test/PHPGit/Command/ShortlogCommandTest.php b/library/kzykhys/git/test/PHPGit/Command/ShortlogCommandTest.php old mode 100755 new mode 100644 diff --git a/tests/travis/gen_apidocs.sh b/tests/travis/gen_apidocs.sh old mode 100755 new mode 100644 diff --git a/tests/travis/prepare.sh b/tests/travis/prepare.sh old mode 100755 new mode 100644 diff --git a/tests/travis/prepare_mysql.sh b/tests/travis/prepare_mysql.sh old mode 100755 new mode 100644 diff --git a/tests/travis/prepare_pgsql.sh b/tests/travis/prepare_pgsql.sh old mode 100755 new mode 100644 diff --git a/util/add_addon_repo b/util/add_addon_repo old mode 100755 new mode 100644 diff --git a/util/add_theme_repo b/util/add_theme_repo old mode 100755 new mode 100644 diff --git a/util/add_widget_repo b/util/add_widget_repo old mode 100755 new mode 100644 diff --git a/util/addons b/util/addons old mode 100755 new mode 100644 diff --git a/util/admins b/util/admins old mode 100755 new mode 100644 diff --git a/util/config b/util/config old mode 100755 new mode 100644 diff --git a/util/connect b/util/connect old mode 100755 new mode 100644 diff --git a/util/dcp b/util/dcp old mode 100755 new mode 100644 diff --git a/util/dmkdir b/util/dmkdir old mode 100755 new mode 100644 diff --git a/util/fresh b/util/fresh old mode 100755 new mode 100644 diff --git a/util/friendica-to-smarty-tpl.py b/util/friendica-to-smarty-tpl.py old mode 100755 new mode 100644 diff --git a/util/hz b/util/hz old mode 100755 new mode 100644 diff --git a/util/importdoc b/util/importdoc old mode 100755 new mode 100644 diff --git a/util/makedocs b/util/makedocs old mode 100755 new mode 100644 diff --git a/util/pconfig b/util/pconfig old mode 100755 new mode 100644 diff --git a/util/precompile_smarty3.php b/util/precompile_smarty3.php old mode 100755 new mode 100644 diff --git a/util/run_xgettext.sh b/util/run_xgettext.sh old mode 100755 new mode 100644 diff --git a/util/safemode b/util/safemode old mode 100755 new mode 100644 diff --git a/util/schemaspy b/util/schemaspy old mode 100755 new mode 100644 diff --git a/util/service_class b/util/service_class old mode 100755 new mode 100644 diff --git a/util/shredder/JSON.sh b/util/shredder/JSON.sh old mode 100755 new mode 100644 diff --git a/util/shredder/OAuth.sh b/util/shredder/OAuth.sh old mode 100755 new mode 100644 diff --git a/util/shredder/ShredOAuth.sh b/util/shredder/ShredOAuth.sh old mode 100755 new mode 100644 diff --git a/util/shredder/shredder b/util/shredder/shredder old mode 100755 new mode 100644 diff --git a/util/storageconv.sh b/util/storageconv.sh old mode 100755 new mode 100644 diff --git a/util/thumbrepair b/util/thumbrepair old mode 100755 new mode 100644 diff --git a/util/udall b/util/udall old mode 100755 new mode 100644 diff --git a/util/update_addon_repo b/util/update_addon_repo old mode 100755 new mode 100644 diff --git a/util/update_theme_repo b/util/update_theme_repo old mode 100755 new mode 100644 diff --git a/util/update_widget_repo b/util/update_widget_repo old mode 100755 new mode 100644 diff --git a/util/updatetpl.py b/util/updatetpl.py old mode 100755 new mode 100644 diff --git a/util/zotsh/zotsh.py b/util/zotsh/zotsh.py old mode 100755 new mode 100644 diff --git a/vendor/commerceguys/intl/scripts/fetch_data.sh b/vendor/commerceguys/intl/scripts/fetch_data.sh old mode 100755 new mode 100644 diff --git a/vendor/league/html-to-markdown/bin/html-to-markdown b/vendor/league/html-to-markdown/bin/html-to-markdown old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/build.php b/vendor/sabre/dav/bin/build.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/googlecode_upload.py b/vendor/sabre/dav/bin/googlecode_upload.py old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/migrateto20.php b/vendor/sabre/dav/bin/migrateto20.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/migrateto21.php b/vendor/sabre/dav/bin/migrateto21.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/migrateto30.php b/vendor/sabre/dav/bin/migrateto30.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/migrateto32.php b/vendor/sabre/dav/bin/migrateto32.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/naturalselection b/vendor/sabre/dav/bin/naturalselection old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/sabredav b/vendor/sabre/dav/bin/sabredav old mode 100755 new mode 100644 diff --git a/vendor/sabre/dav/bin/sabredav.php b/vendor/sabre/dav/bin/sabredav.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/vobject/bin/bench.php b/vendor/sabre/vobject/bin/bench.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/vobject/bin/fetch_windows_zones.php b/vendor/sabre/vobject/bin/fetch_windows_zones.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/vobject/bin/generate_vcards b/vendor/sabre/vobject/bin/generate_vcards old mode 100755 new mode 100644 diff --git a/vendor/sabre/vobject/bin/generateicalendardata.php b/vendor/sabre/vobject/bin/generateicalendardata.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/vobject/bin/mergeduplicates.php b/vendor/sabre/vobject/bin/mergeduplicates.php old mode 100755 new mode 100644 diff --git a/vendor/sabre/vobject/bin/vobject b/vendor/sabre/vobject/bin/vobject old mode 100755 new mode 100644 diff --git a/vendor/simplepie/simplepie/.travis.yml b/vendor/simplepie/simplepie/.travis.yml old mode 100755 new mode 100644 diff --git a/vendor/simplepie/simplepie/library/SimplePie.php b/vendor/simplepie/simplepie/library/SimplePie.php old mode 100755 new mode 100644 diff --git a/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcached.php b/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcached.php old mode 100755 new mode 100644 diff --git a/vendor/simplepie/simplepie/library/SimplePie/Registry.php b/vendor/simplepie/simplepie/library/SimplePie/Registry.php old mode 100755 new mode 100644 diff --git a/vendor/twbs/bootstrap/build/change-version.js b/vendor/twbs/bootstrap/build/change-version.js old mode 100755 new mode 100644 diff --git a/vendor/twbs/bootstrap/build/ship.sh b/vendor/twbs/bootstrap/build/ship.sh old mode 100755 new mode 100644 diff --git a/view/js/sse_worker.js b/view/js/sse_worker.js old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/blockmode.css b/view/theme/redbasic/css/blockmode.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/mod_page.css b/view/theme/redbasic/css/mod_page.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/narrow_navbar.css b/view/theme/redbasic/css/narrow_navbar.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/sloppy_photos.css b/view/theme/redbasic/css/sloppy_photos.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/img/gray_and_black_diagonal_stripes_background_seamless.gif b/view/theme/redbasic/img/gray_and_black_diagonal_stripes_background_seamless.gif old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/img/gray_and_white_diagonal_stripes_background_seamless.gif b/view/theme/redbasic/img/gray_and_white_diagonal_stripes_background_seamless.gif old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/img/screenshot.png b/view/theme/redbasic/img/screenshot.png old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/js/redbasic.js b/view/theme/redbasic/js/redbasic.js old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/config.php b/view/theme/redbasic/php/config.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/style.php b/view/theme/redbasic/php/style.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/theme.php b/view/theme/redbasic/php/theme.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/php/theme_init.php b/view/theme/redbasic/php/theme_init.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Boxy.css b/view/theme/redbasic/schema/Focus-Boxy.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Boxy.php b/view/theme/redbasic/schema/Focus-Boxy.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Light.css b/view/theme/redbasic/schema/Focus-Light.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/Focus-Light.php b/view/theme/redbasic/schema/Focus-Light.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/dark.css b/view/theme/redbasic/schema/dark.css old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/schema/dark.php b/view/theme/redbasic/schema/dark.php old mode 100755 new mode 100644 diff --git a/view/theme/redbasic/tpl/theme_settings.tpl b/view/theme/redbasic/tpl/theme_settings.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/404.tpl b/view/tpl/404.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/abook_edit.tpl b/view/tpl/abook_edit.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/acl_selector.tpl b/view/tpl/acl_selector.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_accounts.tpl b/view/tpl/admin_accounts.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_aside.tpl b/view/tpl/admin_aside.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_channels.tpl b/view/tpl/admin_channels.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_logs.tpl b/view/tpl/admin_logs.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_plugins.tpl b/view/tpl/admin_plugins.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_plugins_details.tpl b/view/tpl/admin_plugins_details.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_security.tpl b/view/tpl/admin_security.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_site.tpl b/view/tpl/admin_site.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/admin_summary.tpl b/view/tpl/admin_summary.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/album_edit.tpl b/view/tpl/album_edit.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/atom_feed.tpl b/view/tpl/atom_feed.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/build_query.tpl b/view/tpl/build_query.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/cal_calendar.tpl b/view/tpl/cal_calendar.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/cal_event.tpl b/view/tpl/cal_event.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/categories_widget.tpl b/view/tpl/categories_widget.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/channel.tpl b/view/tpl/channel.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/channel_import.tpl b/view/tpl/channel_import.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/channel_rename.tpl b/view/tpl/channel_rename.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/channels.tpl b/view/tpl/channels.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/chanview.tpl b/view/tpl/chanview.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/comment_item.tpl b/view/tpl/comment_item.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/common_friends.tpl b/view/tpl/common_friends.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/common_pills.tpl b/view/tpl/common_pills.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/common_tabs.tpl b/view/tpl/common_tabs.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/connection_template.tpl b/view/tpl/connection_template.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/connections.tpl b/view/tpl/connections.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/contact_block.tpl b/view/tpl/contact_block.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/contact_slider.tpl b/view/tpl/contact_slider.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/contact_template.tpl b/view/tpl/contact_template.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/conv.tpl b/view/tpl/conv.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/conv_frame.tpl b/view/tpl/conv_frame.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/conv_list.tpl b/view/tpl/conv_list.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/conversation.tpl b/view/tpl/conversation.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/convobj.tpl b/view/tpl/convobj.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/cover_photo.tpl b/view/tpl/cover_photo.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/cover_photo_widget.tpl b/view/tpl/cover_photo_widget.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/cropbody.tpl b/view/tpl/cropbody.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/cropcover.tpl b/view/tpl/cropcover.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/crophead.tpl b/view/tpl/crophead.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/defperms.tpl b/view/tpl/defperms.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/directory_header.tpl b/view/tpl/directory_header.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/direntry.tpl b/view/tpl/direntry.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/edpost_head.tpl b/view/tpl/edpost_head.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/email_notify_html.tpl b/view/tpl/email_notify_html.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/email_notify_text.tpl b/view/tpl/email_notify_text.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/event.tpl b/view/tpl/event.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/event_form.tpl b/view/tpl/event_form.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/event_head.tpl b/view/tpl/event_head.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/event_item_header.tpl b/view/tpl/event_item_header.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/events-js.tpl b/view/tpl/events-js.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/events_cal-js.tpl b/view/tpl/events_cal-js.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/events_tools_side.tpl b/view/tpl/events_tools_side.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/failed_updates.tpl b/view/tpl/failed_updates.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field.tpl b/view/tpl/field.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_acheckbox.tpl b/view/tpl/field_acheckbox.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_checkbox.tpl b/view/tpl/field_checkbox.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_combobox.tpl b/view/tpl/field_combobox.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_custom.tpl b/view/tpl/field_custom.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_input.tpl b/view/tpl/field_input.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_intcheckbox.tpl b/view/tpl/field_intcheckbox.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_password.tpl b/view/tpl/field_password.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_radio.tpl b/view/tpl/field_radio.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_richtext.tpl b/view/tpl/field_richtext.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_select.tpl b/view/tpl/field_select.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_select_raw.tpl b/view/tpl/field_select_raw.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_textarea.tpl b/view/tpl/field_textarea.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_themeselect.tpl b/view/tpl/field_themeselect.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/field_yesno.tpl b/view/tpl/field_yesno.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/fileas_widget.tpl b/view/tpl/fileas_widget.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/filebrowser.tpl b/view/tpl/filebrowser.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/filer_dialog.tpl b/view/tpl/filer_dialog.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/follow.tpl b/view/tpl/follow.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/generic_links_widget.tpl b/view/tpl/generic_links_widget.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/group_edit.tpl b/view/tpl/group_edit.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/group_selection.tpl b/view/tpl/group_selection.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/group_side.tpl b/view/tpl/group_side.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/groupeditor.tpl b/view/tpl/groupeditor.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/head.tpl b/view/tpl/head.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/hq.tpl b/view/tpl/hq.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/hq_controls.tpl b/view/tpl/hq_controls.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/install.tpl b/view/tpl/install.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/install_checks.tpl b/view/tpl/install_checks.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/install_db.tpl b/view/tpl/install_db.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/install_settings.tpl b/view/tpl/install_settings.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/invite.tpl b/view/tpl/invite.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/item_import.tpl b/view/tpl/item_import.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/jot.tpl b/view/tpl/jot.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/jot_geotag.tpl b/view/tpl/jot_geotag.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/js_strings.tpl b/view/tpl/js_strings.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/lang_selector.tpl b/view/tpl/lang_selector.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/like_noshare.tpl b/view/tpl/like_noshare.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/login.tpl b/view/tpl/login.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/logout.tpl b/view/tpl/logout.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/lostpass.tpl b/view/tpl/lostpass.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/mail_conv.tpl b/view/tpl/mail_conv.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/mail_display.tpl b/view/tpl/mail_display.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/mail_head.tpl b/view/tpl/mail_head.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/mail_list.tpl b/view/tpl/mail_list.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/main_slider.tpl b/view/tpl/main_slider.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/message_side.tpl b/view/tpl/message_side.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/micropro_img.tpl b/view/tpl/micropro_img.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/micropro_txt.tpl b/view/tpl/micropro_txt.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/mood_content.tpl b/view/tpl/mood_content.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/msg-header.tpl b/view/tpl/msg-header.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/myapps.tpl b/view/tpl/myapps.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/navbar_default.tpl b/view/tpl/navbar_default.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/navbar_tucson.tpl b/view/tpl/navbar_tucson.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/new_channel.tpl b/view/tpl/new_channel.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/notifications.tpl b/view/tpl/notifications.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/notify.tpl b/view/tpl/notify.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oauth.tpl b/view/tpl/oauth.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oauth2.tpl b/view/tpl/oauth2.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oauth2_edit.tpl b/view/tpl/oauth2_edit.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oauth_authorize.tpl b/view/tpl/oauth_authorize.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oauth_authorize_done.tpl b/view/tpl/oauth_authorize_done.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oauth_edit.tpl b/view/tpl/oauth_edit.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oembed_video.tpl b/view/tpl/oembed_video.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/oexchange_xrd.tpl b/view/tpl/oexchange_xrd.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/page_display.tpl b/view/tpl/page_display.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/peoplefind.tpl b/view/tpl/peoplefind.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_album.tpl b/view/tpl/photo_album.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_album_portfolio.tpl b/view/tpl/photo_album_portfolio.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_albums.tpl b/view/tpl/photo_albums.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_drop.tpl b/view/tpl/photo_drop.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_item.tpl b/view/tpl/photo_item.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_portfolio.tpl b/view/tpl/photo_portfolio.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_top.tpl b/view/tpl/photo_top.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photo_view.tpl b/view/tpl/photo_view.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photos_recent.tpl b/view/tpl/photos_recent.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photos_upload.tpl b/view/tpl/photos_upload.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/photosajax.tpl b/view/tpl/photosajax.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/poco_entry_xml.tpl b/view/tpl/poco_entry_xml.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/poco_xml.tpl b/view/tpl/poco_xml.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/poke_content.tpl b/view/tpl/poke_content.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/posted_date_widget.tpl b/view/tpl/posted_date_widget.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profed_head.tpl b/view/tpl/profed_head.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profile_advanced.tpl b/view/tpl/profile_advanced.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profile_edit.tpl b/view/tpl/profile_edit.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profile_entry.tpl b/view/tpl/profile_entry.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profile_listing_header.tpl b/view/tpl/profile_listing_header.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profile_photo.tpl b/view/tpl/profile_photo.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profile_vcard.tpl b/view/tpl/profile_vcard.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/profile_vcard_short.tpl b/view/tpl/profile_vcard_short.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/prv_message.tpl b/view/tpl/prv_message.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/pwdreset.tpl b/view/tpl/pwdreset.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/register.tpl b/view/tpl/register.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/remote_friends_common.tpl b/view/tpl/remote_friends_common.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/removeme.tpl b/view/tpl/removeme.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/rmagic.tpl b/view/tpl/rmagic.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/search_item.tpl b/view/tpl/search_item.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/settings.tpl b/view/tpl/settings.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/settings_account.tpl b/view/tpl/settings_account.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/settings_addons.tpl b/view/tpl/settings_addons.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/settings_display.tpl b/view/tpl/settings_display.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/settings_features.tpl b/view/tpl/settings_features.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/settings_module.tpl b/view/tpl/settings_module.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/settings_nick_set.tpl b/view/tpl/settings_nick_set.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/siteinfo.tpl b/view/tpl/siteinfo.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/suggest_friends.tpl b/view/tpl/suggest_friends.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/suggest_page.tpl b/view/tpl/suggest_page.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/threaded_conversation.tpl b/view/tpl/threaded_conversation.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/viewcontact_template.tpl b/view/tpl/viewcontact_template.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/xchan_vcard.tpl b/view/tpl/xchan_vcard.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/xrd_host.tpl b/view/tpl/xrd_host.tpl old mode 100755 new mode 100644 diff --git a/view/tpl/xrd_person.tpl b/view/tpl/xrd_person.tpl old mode 100755 new mode 100644 -- cgit v1.2.3 From 6326605c99a207a76626c681964a851b4d7c44cb Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 27 Jan 2021 11:23:59 +0100 Subject: Revert "Fix directory permissions on create" This reverts commit 85c5e1178a57865ad977c260725da2839ebb4d98 --- include/taxonomy.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/taxonomy.php b/include/taxonomy.php index 88d0a9196..7745b6a5b 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -357,10 +357,10 @@ function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) { $key = __FUNCTION__ . "-" . md5($site . $recent . $safemode . $limit . $type); - $content = Cache::get($key, '1 MINUTE'); + $content = Cache::get($key, '5 MINUTE'); if(! $content) { - $content = Cache::get($key, '1 WEEK'); + $content = Cache::get($key, '1 MONTH'); $arr = [ "SELECT term, count(term) AS total FROM term LEFT JOIN item ON term.oid = item.id WHERE term.ttype = %d -- cgit v1.2.3 From 00fe7bb1bbe6c1b49f66bc0e0c2330798608ce95 Mon Sep 17 00:00:00 2001 From: "M. Dent" Date: Wed, 27 Jan 2021 11:25:26 +0100 Subject: Custom "headers" in item creation form. --- include/conversation.php | 1 + view/css/conversation.css | 6 ++++-- view/tpl/jot.tpl | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/conversation.php b/include/conversation.php index 002edef51..08d16a413 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1517,6 +1517,7 @@ function hz_status_editor($a, $x, $popup = false) { '$parent' => ((array_key_exists('parent',$x) && $x['parent']) ? $x['parent'] : 0), '$reset' => $reset, '$is_owner' => ((local_channel() && (local_channel() == $x['profile_uid'])) ? true : false), + '$customjotheaders' => '', '$custommoretoolsdropdown' => '', '$custommoretoolsbuttons' => '', '$customsubmitright' => [] diff --git a/view/css/conversation.css b/view/css/conversation.css index 77e56e200..06da8528c 100644 --- a/view/css/conversation.css +++ b/view/css/conversation.css @@ -18,7 +18,8 @@ #jot-title-wrap, #jot-pagetitle-wrap, -#jot-category-wrap { +#jot-category-wrap, +#jot-customjotheaders-wrap { border-bottom: 1px solid rgba(0, 0, 0, .2); } @@ -28,7 +29,8 @@ } #jot-title-wrap input, -#jot-pagetitle-wrap input { +#jot-pagetitle-wrap input, +#jot-customjotheaders-wrap { padding: 0.5rem; } diff --git a/view/tpl/jot.tpl b/view/tpl/jot.tpl index 36543ccfa..36e71223c 100755 --- a/view/tpl/jot.tpl +++ b/view/tpl/jot.tpl @@ -41,6 +41,11 @@
      {{/if}} + {{if $customjotheaders}} +
      + {{$customjotheaders}} +
      + {{/if}}
      {{if $is_owner}} -- cgit v1.2.3 From 66640a206e03a5f05d88945283064d94fa07c9b8 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 27 Jan 2021 10:35:17 +0000 Subject: fix issue in view/pl/hstrings.php --- view/pl/hstrings.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/view/pl/hstrings.php b/view/pl/hstrings.php index 6eaf8d4fe..e80645bdb 100644 --- a/view/pl/hstrings.php +++ b/view/pl/hstrings.php @@ -6,8 +6,7 @@ function string_plural_select_pl($n){ ; }} App::$rtl = 0; -App::$strings["plural_function_code"] = "(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12)) -"; +App::$strings["plural_function_code"] = "(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12))"; App::$strings["Can view my channel stream and posts"] = "Może wyświetlać strumień i posty z mojego kanału"; App::$strings["Can send me their channel stream and posts"] = "Może przesyłać mi strumień swojego kanału i posty"; App::$strings["Can view my default channel profile"] = "Może wyświetlać mój domyślny profil kanału"; -- cgit v1.2.3 From 8b78e18fb8ade1d04dbf2e5152288f6982a462df Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 27 Jan 2021 11:56:58 +0100 Subject: keep file permissions in util folder at 755 --- util/.htaccess | 0 util/Doxyfile | 0 util/Doxygen.footer | 0 util/Doxygen_phpvarfilter.php | 0 util/README | 0 util/add_addon_repo | 0 util/add_theme_repo | 0 util/add_widget_repo | 0 util/addons | 0 util/admins | 0 util/config | 0 util/config.md | 0 util/connect | 0 util/db_update.php | 0 util/dcp | 0 util/dmkdir | 0 util/docblox_errorchecker.php | 0 util/extract.php | 0 util/fpostit/README | 0 util/fpostit/fpostit.js | 0 util/fpostit/fpostit.php | 0 util/fpostit/friendika-32.png | Bin util/fresh | 0 util/fresh.md | 0 util/friendica-to-smarty-tpl.py | 0 util/generate-hooks-index/.gitignore | 0 util/generate-hooks-index/CHANGELOG.md | 0 util/generate-hooks-index/LICENSE | 0 util/generate-hooks-index/README.md | 0 util/generate-hooks-index/doc/intro.md | 0 util/generate-hooks-index/project.clj | 0 util/generate-hooks-index/src/generate_hooks_index/core.clj | 0 .../test/generate_hooks_index/core_test.clj | 0 util/hmessages.po | 0 util/hstrings.php | 0 util/hubzilla_er/Makefile | 0 util/hz | 0 util/importdoc | 0 util/makedocs | 0 util/messages.po | 0 util/nconfig.php | 0 util/pconfig | 0 util/php2po.php | 0 util/po2php.php | 0 util/precompile_smarty3.php | 0 util/run_xgettext.sh | 0 util/safemode | 0 util/schemaspy | 0 util/service_class | 0 util/shredder/JSON.sh | 0 util/shredder/OAuth.sh | 0 util/shredder/ShredOAuth.sh | 0 util/shredder/jansson-2.6.tar.gz | Bin util/shredder/jshon.tar.gz | Bin util/shredder/readme | 0 util/shredder/shredder | 0 util/storageconv | 0 util/storageconv.sh | 0 util/strings.php | 0 util/thumbrepair | 0 util/tpldebug.php | 0 util/typo.php | 0 util/typohelper.php | 0 util/udall | 0 util/update_addon_repo | 0 util/update_theme_repo | 0 util/update_widget_repo | 0 util/updatetpl.py | 0 util/z6convert.php | 0 util/zotsh/README.txt | 0 util/zotsh/easywebdav/LICENSE | 0 util/zotsh/easywebdav/__init__.py | 0 util/zotsh/easywebdav/__init__.pyc | Bin util/zotsh/easywebdav/__version__.py | 0 util/zotsh/easywebdav/__version__.pyc | Bin util/zotsh/easywebdav/client.py | 0 util/zotsh/easywebdav/client.pyc | Bin util/zotsh/zotsh.py | 0 78 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 util/.htaccess mode change 100644 => 100755 util/Doxyfile mode change 100644 => 100755 util/Doxygen.footer mode change 100644 => 100755 util/Doxygen_phpvarfilter.php mode change 100644 => 100755 util/README mode change 100644 => 100755 util/add_addon_repo mode change 100644 => 100755 util/add_theme_repo mode change 100644 => 100755 util/add_widget_repo mode change 100644 => 100755 util/addons mode change 100644 => 100755 util/admins mode change 100644 => 100755 util/config mode change 100644 => 100755 util/config.md mode change 100644 => 100755 util/connect mode change 100644 => 100755 util/db_update.php mode change 100644 => 100755 util/dcp mode change 100644 => 100755 util/dmkdir mode change 100644 => 100755 util/docblox_errorchecker.php mode change 100644 => 100755 util/extract.php mode change 100644 => 100755 util/fpostit/README mode change 100644 => 100755 util/fpostit/fpostit.js mode change 100644 => 100755 util/fpostit/fpostit.php mode change 100644 => 100755 util/fpostit/friendika-32.png mode change 100644 => 100755 util/fresh mode change 100644 => 100755 util/fresh.md mode change 100644 => 100755 util/friendica-to-smarty-tpl.py mode change 100644 => 100755 util/generate-hooks-index/.gitignore mode change 100644 => 100755 util/generate-hooks-index/CHANGELOG.md mode change 100644 => 100755 util/generate-hooks-index/LICENSE mode change 100644 => 100755 util/generate-hooks-index/README.md mode change 100644 => 100755 util/generate-hooks-index/doc/intro.md mode change 100644 => 100755 util/generate-hooks-index/project.clj mode change 100644 => 100755 util/generate-hooks-index/src/generate_hooks_index/core.clj mode change 100644 => 100755 util/generate-hooks-index/test/generate_hooks_index/core_test.clj mode change 100644 => 100755 util/hmessages.po mode change 100644 => 100755 util/hstrings.php mode change 100644 => 100755 util/hubzilla_er/Makefile mode change 100644 => 100755 util/hz mode change 100644 => 100755 util/importdoc mode change 100644 => 100755 util/makedocs mode change 100644 => 100755 util/messages.po mode change 100644 => 100755 util/nconfig.php mode change 100644 => 100755 util/pconfig mode change 100644 => 100755 util/php2po.php mode change 100644 => 100755 util/po2php.php mode change 100644 => 100755 util/precompile_smarty3.php mode change 100644 => 100755 util/run_xgettext.sh mode change 100644 => 100755 util/safemode mode change 100644 => 100755 util/schemaspy mode change 100644 => 100755 util/service_class mode change 100644 => 100755 util/shredder/JSON.sh mode change 100644 => 100755 util/shredder/OAuth.sh mode change 100644 => 100755 util/shredder/ShredOAuth.sh mode change 100644 => 100755 util/shredder/jansson-2.6.tar.gz mode change 100644 => 100755 util/shredder/jshon.tar.gz mode change 100644 => 100755 util/shredder/readme mode change 100644 => 100755 util/shredder/shredder mode change 100644 => 100755 util/storageconv mode change 100644 => 100755 util/storageconv.sh mode change 100644 => 100755 util/strings.php mode change 100644 => 100755 util/thumbrepair mode change 100644 => 100755 util/tpldebug.php mode change 100644 => 100755 util/typo.php mode change 100644 => 100755 util/typohelper.php mode change 100644 => 100755 util/udall mode change 100644 => 100755 util/update_addon_repo mode change 100644 => 100755 util/update_theme_repo mode change 100644 => 100755 util/update_widget_repo mode change 100644 => 100755 util/updatetpl.py mode change 100644 => 100755 util/z6convert.php mode change 100644 => 100755 util/zotsh/README.txt mode change 100644 => 100755 util/zotsh/easywebdav/LICENSE mode change 100644 => 100755 util/zotsh/easywebdav/__init__.py mode change 100644 => 100755 util/zotsh/easywebdav/__init__.pyc mode change 100644 => 100755 util/zotsh/easywebdav/__version__.py mode change 100644 => 100755 util/zotsh/easywebdav/__version__.pyc mode change 100644 => 100755 util/zotsh/easywebdav/client.py mode change 100644 => 100755 util/zotsh/easywebdav/client.pyc mode change 100644 => 100755 util/zotsh/zotsh.py diff --git a/util/.htaccess b/util/.htaccess old mode 100644 new mode 100755 diff --git a/util/Doxyfile b/util/Doxyfile old mode 100644 new mode 100755 diff --git a/util/Doxygen.footer b/util/Doxygen.footer old mode 100644 new mode 100755 diff --git a/util/Doxygen_phpvarfilter.php b/util/Doxygen_phpvarfilter.php old mode 100644 new mode 100755 diff --git a/util/README b/util/README old mode 100644 new mode 100755 diff --git a/util/add_addon_repo b/util/add_addon_repo old mode 100644 new mode 100755 diff --git a/util/add_theme_repo b/util/add_theme_repo old mode 100644 new mode 100755 diff --git a/util/add_widget_repo b/util/add_widget_repo old mode 100644 new mode 100755 diff --git a/util/addons b/util/addons old mode 100644 new mode 100755 diff --git a/util/admins b/util/admins old mode 100644 new mode 100755 diff --git a/util/config b/util/config old mode 100644 new mode 100755 diff --git a/util/config.md b/util/config.md old mode 100644 new mode 100755 diff --git a/util/connect b/util/connect old mode 100644 new mode 100755 diff --git a/util/db_update.php b/util/db_update.php old mode 100644 new mode 100755 diff --git a/util/dcp b/util/dcp old mode 100644 new mode 100755 diff --git a/util/dmkdir b/util/dmkdir old mode 100644 new mode 100755 diff --git a/util/docblox_errorchecker.php b/util/docblox_errorchecker.php old mode 100644 new mode 100755 diff --git a/util/extract.php b/util/extract.php old mode 100644 new mode 100755 diff --git a/util/fpostit/README b/util/fpostit/README old mode 100644 new mode 100755 diff --git a/util/fpostit/fpostit.js b/util/fpostit/fpostit.js old mode 100644 new mode 100755 diff --git a/util/fpostit/fpostit.php b/util/fpostit/fpostit.php old mode 100644 new mode 100755 diff --git a/util/fpostit/friendika-32.png b/util/fpostit/friendika-32.png old mode 100644 new mode 100755 diff --git a/util/fresh b/util/fresh old mode 100644 new mode 100755 diff --git a/util/fresh.md b/util/fresh.md old mode 100644 new mode 100755 diff --git a/util/friendica-to-smarty-tpl.py b/util/friendica-to-smarty-tpl.py old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/.gitignore b/util/generate-hooks-index/.gitignore old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/CHANGELOG.md b/util/generate-hooks-index/CHANGELOG.md old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/LICENSE b/util/generate-hooks-index/LICENSE old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/README.md b/util/generate-hooks-index/README.md old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/doc/intro.md b/util/generate-hooks-index/doc/intro.md old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/project.clj b/util/generate-hooks-index/project.clj old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/src/generate_hooks_index/core.clj b/util/generate-hooks-index/src/generate_hooks_index/core.clj old mode 100644 new mode 100755 diff --git a/util/generate-hooks-index/test/generate_hooks_index/core_test.clj b/util/generate-hooks-index/test/generate_hooks_index/core_test.clj old mode 100644 new mode 100755 diff --git a/util/hmessages.po b/util/hmessages.po old mode 100644 new mode 100755 diff --git a/util/hstrings.php b/util/hstrings.php old mode 100644 new mode 100755 diff --git a/util/hubzilla_er/Makefile b/util/hubzilla_er/Makefile old mode 100644 new mode 100755 diff --git a/util/hz b/util/hz old mode 100644 new mode 100755 diff --git a/util/importdoc b/util/importdoc old mode 100644 new mode 100755 diff --git a/util/makedocs b/util/makedocs old mode 100644 new mode 100755 diff --git a/util/messages.po b/util/messages.po old mode 100644 new mode 100755 diff --git a/util/nconfig.php b/util/nconfig.php old mode 100644 new mode 100755 diff --git a/util/pconfig b/util/pconfig old mode 100644 new mode 100755 diff --git a/util/php2po.php b/util/php2po.php old mode 100644 new mode 100755 diff --git a/util/po2php.php b/util/po2php.php old mode 100644 new mode 100755 diff --git a/util/precompile_smarty3.php b/util/precompile_smarty3.php old mode 100644 new mode 100755 diff --git a/util/run_xgettext.sh b/util/run_xgettext.sh old mode 100644 new mode 100755 diff --git a/util/safemode b/util/safemode old mode 100644 new mode 100755 diff --git a/util/schemaspy b/util/schemaspy old mode 100644 new mode 100755 diff --git a/util/service_class b/util/service_class old mode 100644 new mode 100755 diff --git a/util/shredder/JSON.sh b/util/shredder/JSON.sh old mode 100644 new mode 100755 diff --git a/util/shredder/OAuth.sh b/util/shredder/OAuth.sh old mode 100644 new mode 100755 diff --git a/util/shredder/ShredOAuth.sh b/util/shredder/ShredOAuth.sh old mode 100644 new mode 100755 diff --git a/util/shredder/jansson-2.6.tar.gz b/util/shredder/jansson-2.6.tar.gz old mode 100644 new mode 100755 diff --git a/util/shredder/jshon.tar.gz b/util/shredder/jshon.tar.gz old mode 100644 new mode 100755 diff --git a/util/shredder/readme b/util/shredder/readme old mode 100644 new mode 100755 diff --git a/util/shredder/shredder b/util/shredder/shredder old mode 100644 new mode 100755 diff --git a/util/storageconv b/util/storageconv old mode 100644 new mode 100755 diff --git a/util/storageconv.sh b/util/storageconv.sh old mode 100644 new mode 100755 diff --git a/util/strings.php b/util/strings.php old mode 100644 new mode 100755 diff --git a/util/thumbrepair b/util/thumbrepair old mode 100644 new mode 100755 diff --git a/util/tpldebug.php b/util/tpldebug.php old mode 100644 new mode 100755 diff --git a/util/typo.php b/util/typo.php old mode 100644 new mode 100755 diff --git a/util/typohelper.php b/util/typohelper.php old mode 100644 new mode 100755 diff --git a/util/udall b/util/udall old mode 100644 new mode 100755 diff --git a/util/update_addon_repo b/util/update_addon_repo old mode 100644 new mode 100755 diff --git a/util/update_theme_repo b/util/update_theme_repo old mode 100644 new mode 100755 diff --git a/util/update_widget_repo b/util/update_widget_repo old mode 100644 new mode 100755 diff --git a/util/updatetpl.py b/util/updatetpl.py old mode 100644 new mode 100755 diff --git a/util/z6convert.php b/util/z6convert.php old mode 100644 new mode 100755 diff --git a/util/zotsh/README.txt b/util/zotsh/README.txt old mode 100644 new mode 100755 diff --git a/util/zotsh/easywebdav/LICENSE b/util/zotsh/easywebdav/LICENSE old mode 100644 new mode 100755 diff --git a/util/zotsh/easywebdav/__init__.py b/util/zotsh/easywebdav/__init__.py old mode 100644 new mode 100755 diff --git a/util/zotsh/easywebdav/__init__.pyc b/util/zotsh/easywebdav/__init__.pyc old mode 100644 new mode 100755 diff --git a/util/zotsh/easywebdav/__version__.py b/util/zotsh/easywebdav/__version__.py old mode 100644 new mode 100755 diff --git a/util/zotsh/easywebdav/__version__.pyc b/util/zotsh/easywebdav/__version__.pyc old mode 100644 new mode 100755 diff --git a/util/zotsh/easywebdav/client.py b/util/zotsh/easywebdav/client.py old mode 100644 new mode 100755 diff --git a/util/zotsh/easywebdav/client.pyc b/util/zotsh/easywebdav/client.pyc old mode 100644 new mode 100755 diff --git a/util/zotsh/zotsh.py b/util/zotsh/zotsh.py old mode 100644 new mode 100755 -- cgit v1.2.3 From 8c2442eca5889a5ece659bdb456403b28285b26b Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 28 Jan 2021 14:57:37 +0000 Subject: AS channel discovery with custom access header --- Zotlabs/Lib/Activity.php | 10 ++++++---- Zotlabs/Lib/ActivityStreams.php | 29 +++++++++++++++++++++++------ Zotlabs/Module/Channel.php | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 388d74d91..3bfdf722a 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -87,14 +87,16 @@ class Activity { } $headers = [ - 'Accept' => 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"', + 'Accept' => ActivityStreams::get_accept_header_string($channel), 'Host' => $m['host'], 'Date' => datetime_convert('UTC', 'UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'), '(request-target)' => 'get ' . get_request_string($url) ]; + if (isset($token)) { $headers['Authorization'] = 'Bearer ' . $token; } + $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), false); $x = z_fetch_url($url, true, $redirects, ['headers' => $h]); } @@ -302,7 +304,7 @@ class Activity { $m = get_iconfig($i['id'], 'activitypub', 'rawmsg'); if ($m) { if (is_string($m)) - $t = json_decode($m,true); + $t = json_decode($m, true); else $t = $m; } @@ -2563,7 +2565,7 @@ class Activity { $allowed = true; // reject public stream comments that weren't sent by the conversation owner - if ($is_sys_channel && $pubstream && $item['owner_xchan'] !== $observer_hash && ! $fetch_parents) { // TODO: check why? This would make it impossible to fetch externals via zotfeed where $observer_hash = sys channel + if ($is_sys_channel && $pubstream && $item['owner_xchan'] !== $observer_hash && !$fetch_parents) { $allowed = false; } } @@ -2963,7 +2965,7 @@ class Activity { break; } - array_unshift($p,[ $a, $item ]); + array_unshift($p, [$a, $item]); if ($item['parent_mid'] === $item['mid']) { break; diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php index f877fbb45..a1d780205 100644 --- a/Zotlabs/Lib/ActivityStreams.php +++ b/Zotlabs/Lib/ActivityStreams.php @@ -409,16 +409,33 @@ class ActivityStreams { return $x; } - static function is_as_request() { + static function is_as_request($channel = null) { - $x = getBestSupportedMimeType([ - 'application/ld+json;profile="https://www.w3.org/ns/activitystreams"', - 'application/activity+json', - 'application/ld+json;profile="http://www.w3.org/ns/activitystreams"' - ]); + $hookdata = []; + if($channel) + $hookdata['channel'] = $channel; + $hookdata['data'] = ['application/x-zot-activity+json']; + + call_hooks('is_as_request', $hookdata); + + $x = getBestSupportedMimeType($hookdata['data']); return(($x) ? true : false); } + static function get_accept_header_string($channel = null) { + + $hookdata = []; + if($channel) + $hookdata['channel'] = $channel; + + $hookdata['data'] = 'application/x-zot-activity+json'; + + call_hooks('get_accept_header_string', $hookdata); + + return $hookdata['data']; + + } + } diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 11f4d3a52..5cfcb623b 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -4,10 +4,12 @@ namespace Zotlabs\Module; use App; -use Zotlabs\Web\Controller; +use Zotlabs\Lib\Activity; +use Zotlabs\Lib\ActivityStreams; +use Zotlabs\Lib\Libzot; use Zotlabs\Lib\PermissionDescription; +use Zotlabs\Web\Controller; use Zotlabs\Web\HTTPSig; -use Zotlabs\Lib\Libzot; require_once('include/items.php'); require_once('include/security.php'); @@ -25,7 +27,7 @@ class Channel extends Controller { function init() { - if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?'])) + if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']) || strpos($_GET['search'], 'https://') === 0) goaway('search' . '?f=&search=' . $_GET['search']); $which = null; @@ -87,6 +89,38 @@ class Channel extends Controller { killme(); } + if (ActivityStreams::is_as_request($channel)) { + + // Somebody may attempt an ActivityStreams fetch on one of our message permalinks + // Make it do the right thing. + + $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); + if ($mid && strpos($mid,'b64.') === 0) { + $decoded = @base64url_decode(substr($mid,4)); + if ($decoded) { + $mid = $decoded; + } + } + if ($mid) { + $obj = null; + if (strpos($mid, z_root() . '/item/') === 0) { + App::$argc = 2; + App::$argv = [ 'item', basename($mid) ]; + $obj = new Item(); + } + if (strpos($mid, z_root() . '/activity/') === 0) { + App::$argc = 2; + App::$argv = [ 'activity', basename($mid) ]; + $obj = new Activity(); + } + if ($obj) { + $obj->init(); + } + } + + as_return_and_die(Activity::encode_person($channel,true),$channel); + } + if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { $which = $channel['channel_address']; $profile = argv(1); -- cgit v1.2.3 From ab4863a2e0fb433784b16abed7df61dc49f749a1 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 28 Jan 2021 15:44:57 +0000 Subject: AS discovery for mod profile --- Zotlabs/Module/Profile.php | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php index 0373630a9..bce067b92 100644 --- a/Zotlabs/Module/Profile.php +++ b/Zotlabs/Module/Profile.php @@ -1,5 +1,12 @@ 'Profile', 'describes' => $p ], $channel); + } + + nav_set_selected('Profile'); + if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { $which = $channel['channel_address']; $profile = argv(1); @@ -59,7 +74,7 @@ class Profile extends \Zotlabs\Web\Controller { dbesc(argv(1)) ); if($x) { - \App::$profile = $x[0]; + App::$profile = $x[0]; } } @@ -81,7 +96,7 @@ class Profile extends \Zotlabs\Web\Controller { $tab = 'profile'; $o = ''; - if(! (perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(), 'view_profile'))) { + if(! (perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(), 'view_profile'))) { notice( t('Permission denied.') . EOL); return; } @@ -90,14 +105,14 @@ class Profile extends \Zotlabs\Web\Controller { if(argc() > 2 && argv(2) === 'vcard') { header('Content-type: text/vcard'); - header('content-disposition: attachment; filename="' . t('vcard') . '-' . \App::$profile['channel_address'] . '.vcf"' ); - echo \App::$profile['profile_vcard']; + header('content-disposition: attachment; filename="' . t('vcard') . '-' . App::$profile['channel_address'] . '.vcf"' ); + echo App::$profile['profile_vcard']; killme(); } - $is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false); + $is_owner = ((local_channel()) && (local_channel() == App::$profile['profile_uid']) ? true : false); - if(\App::$profile['hidewall'] && (! $is_owner) && (! remote_channel())) { + if(App::$profile['hidewall'] && (! $is_owner) && (! remote_channel())) { notice( t('Permission denied.') . EOL); return; } @@ -105,7 +120,7 @@ class Profile extends \Zotlabs\Web\Controller { head_add_link([ 'rel' => 'alternate', 'type' => 'application/json+oembed', - 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string), + 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string), 'title' => 'oembed' ]); -- cgit v1.2.3 From 840dbbe8ba1ad2a42252884466be37376172acbc Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 28 Jan 2021 15:50:34 +0000 Subject: code format only --- Zotlabs/Lib/ActivityStreams.php | 207 ++++++++++++------------ Zotlabs/Module/Channel.php | 346 ++++++++++++++++++++-------------------- Zotlabs/Module/Profile.php | 88 +++++----- 3 files changed, 319 insertions(+), 322 deletions(-) diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php index a1d780205..ba7ec0c65 100644 --- a/Zotlabs/Lib/ActivityStreams.php +++ b/Zotlabs/Lib/ActivityStreams.php @@ -7,25 +7,24 @@ namespace Zotlabs\Lib; * * Parses an ActivityStream JSON string. */ - class ActivityStreams { - public $raw = null; - public $data = null; - public $valid = false; - public $deleted = false; - public $id = ''; - public $parent_id = ''; - public $type = ''; - public $actor = null; - public $obj = null; - public $tgt = null; - public $origin = null; - public $owner = null; - public $signer = null; - public $ldsig = null; - public $sigok = false; - public $recips = null; + public $raw = null; + public $data = null; + public $valid = false; + public $deleted = false; + public $id = ''; + public $parent_id = ''; + public $type = ''; + public $actor = null; + public $obj = null; + public $tgt = null; + public $origin = null; + public $owner = null; + public $signer = null; + public $ldsig = null; + public $sigok = false; + public $recips = null; public $raw_recips = null; /** @@ -37,29 +36,29 @@ class ActivityStreams { */ function __construct($string) { - $this->raw = $string; + $this->raw = $string; - if(is_array($string)) { + if (is_array($string)) { $this->data = $string; } else { $this->data = json_decode($string, true); } - if($this->data) { + if ($this->data) { // verify and unpack JSalmon signature if present - if(is_array($this->data) && array_key_exists('signed',$this->data)) { + if (is_array($this->data) && array_key_exists('signed', $this->data)) { $ret = JSalmon::verify($this->data); $tmp = JSalmon::unpack($this->data['data']); - if($ret && $ret['success']) { - if($ret['signer']) { - $saved = json_encode($this->data,JSON_UNESCAPED_SLASHES); - $this->data = $tmp; - $this->data['signer'] = $ret['signer']; + if ($ret && $ret['success']) { + if ($ret['signer']) { + $saved = json_encode($this->data, JSON_UNESCAPED_SLASHES); + $this->data = $tmp; + $this->data['signer'] = $ret['signer']; $this->data['signed_data'] = $saved; - if($ret['hubloc']) { + if ($ret['hubloc']) { $this->data['hubloc'] = $ret['hubloc']; } } @@ -68,57 +67,57 @@ class ActivityStreams { $this->valid = true; - if(array_key_exists('type',$this->data) && array_key_exists('actor',$this->data) && array_key_exists('object',$this->data)) { - if($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) { + if (array_key_exists('type', $this->data) && array_key_exists('actor', $this->data) && array_key_exists('object', $this->data)) { + if ($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) { $this->deleted = $this->data['actor']; - $this->valid = false; + $this->valid = false; } } } - if($this->is_valid()) { + if ($this->is_valid()) { $this->id = $this->get_property_obj('id'); $this->type = $this->get_primary_type(); - $this->actor = $this->get_actor('actor','',''); + $this->actor = $this->get_actor('actor', '', ''); $this->obj = $this->get_compound_property('object'); $this->tgt = $this->get_compound_property('target'); $this->origin = $this->get_compound_property('origin'); $this->recips = $this->collect_recips(); $this->ldsig = $this->get_compound_property('signature'); - if($this->ldsig) { - $this->signer = $this->get_compound_property('creator',$this->ldsig); - if($this->signer && is_array($this->signer) && array_key_exists('publicKey',$this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) { - $this->sigok = LDSignatures::verify($this->data,$this->signer['publicKey']['publicKeyPem']); + if ($this->ldsig) { + $this->signer = $this->get_compound_property('creator', $this->ldsig); + if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) { + $this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']); } } - if(! $this->obj) { - $this->obj = $this->data; + if (!$this->obj) { + $this->obj = $this->data; $this->type = 'Create'; - if(! $this->actor) { - $this->actor = $this->get_actor('attributedTo',$this->obj); + if (!$this->actor) { + $this->actor = $this->get_actor('attributedTo', $this->obj); } } // fetch recursive or embedded activities - if ($this->obj && is_array($this->obj) && array_key_exists('object',$this->obj)) { + if ($this->obj && is_array($this->obj) && array_key_exists('object', $this->obj)) { $this->obj['object'] = $this->get_compound_property($this->obj['object']); } - if($this->obj && is_array($this->obj) && $this->obj['actor']) - $this->obj['actor'] = $this->get_actor('actor',$this->obj); - if($this->tgt && is_array($this->tgt) && $this->tgt['actor']) - $this->tgt['actor'] = $this->get_actor('actor',$this->tgt); + if ($this->obj && is_array($this->obj) && $this->obj['actor']) + $this->obj['actor'] = $this->get_actor('actor', $this->obj); + if ($this->tgt && is_array($this->tgt) && $this->tgt['actor']) + $this->tgt['actor'] = $this->get_actor('actor', $this->tgt); $this->parent_id = $this->get_property_obj('inReplyTo'); - if((! $this->parent_id) && is_array($this->obj)) { + if ((!$this->parent_id) && is_array($this->obj)) { $this->parent_id = $this->obj['inReplyTo']; } - if((! $this->parent_id) && is_array($this->obj)) { + if ((!$this->parent_id) && is_array($this->obj)) { $this->parent_id = $this->obj['id']; } } @@ -147,19 +146,19 @@ class ActivityStreams { function collect_recips($base = '', $namespace = '') { $x = []; - $fields = [ 'to', 'cc', 'bto', 'bcc', 'audience']; - foreach($fields as $f) { + $fields = ['to', 'cc', 'bto', 'bcc', 'audience']; + foreach ($fields as $f) { $y = $this->get_compound_property($f, $base, $namespace); - if($y) { - if (! is_array($this->raw_recips)) { + if ($y) { + if (!is_array($this->raw_recips)) { $this->raw_recips = []; } - if (! is_array($y)) { - $y = [ $y ]; + if (!is_array($y)) { + $y = [$y]; } $this->raw_recips[$f] = $y; - $x = array_merge($x, $y); + $x = array_merge($x, $y); } } // not yet ready for prime time @@ -167,21 +166,21 @@ class ActivityStreams { return $x; } - function expand($arr,$base = '',$namespace = '') { + function expand($arr, $base = '', $namespace = '') { $ret = []; // right now use a hardwired recursion depth of 5 - for($z = 0; $z < 5; $z ++) { - if(is_array($arr) && $arr) { - foreach($arr as $a) { - if(is_array($a)) { + for ($z = 0; $z < 5; $z++) { + if (is_array($arr) && $arr) { + foreach ($arr as $a) { + if (is_array($a)) { $ret[] = $a; } else { - $x = $this->get_compound_property($a,$base,$namespace); - if($x) { - $ret = array_merge($ret,$x); + $x = $this->get_compound_property($a, $base, $namespace); + if ($x) { + $ret = array_merge($ret, $x); } } } @@ -202,33 +201,33 @@ class ActivityStreams { */ function get_namespace($base, $namespace) { - if(! $namespace) + if (!$namespace) return ''; $key = null; - foreach( [ $this->data, $base ] as $b ) { - if(! $b) + foreach ([$this->data, $base] as $b) { + if (!$b) continue; - if(array_key_exists('@context', $b)) { - if(is_array($b['@context'])) { - foreach($b['@context'] as $ns) { - if(is_array($ns)) { - foreach($ns as $k => $v) { - if($namespace === $v) + if (array_key_exists('@context', $b)) { + if (is_array($b['@context'])) { + foreach ($b['@context'] as $ns) { + if (is_array($ns)) { + foreach ($ns as $k => $v) { + if ($namespace === $v) $key = $k; } } else { - if($namespace === $ns) { + if ($namespace === $ns) { $key = ''; } } } } else { - if($namespace === $b['@context']) { + if ($namespace === $b['@context']) { $key = ''; } } @@ -248,14 +247,14 @@ class ActivityStreams { */ function get_property_obj($property, $base = '', $namespace = '') { $prefix = $this->get_namespace($base, $namespace); - if($prefix === null) + if ($prefix === null) return null; - $base = (($base) ? $base : $this->data); + $base = (($base) ? $base : $this->data); $propname = (($prefix) ? $prefix . ':' : '') . $property; - if(! is_array($base)) { - btlogger('not an array: ' . print_r($base,true)); + if (!is_array($base)) { + btlogger('not an array: ' . print_r($base, true)); return null; } @@ -279,14 +278,14 @@ class ActivityStreams { } static function is_an_actor($s) { - return (in_array($s, [ 'Application','Group','Organization','Person','Service' ])); + return (in_array($s, ['Application', 'Group', 'Organization', 'Person', 'Service'])); } static function is_response_activity($s) { - if (! $s) { + if (!$s) { return false; } - return (in_array($s, [ 'Like', 'Dislike', 'Flag', 'Block', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact' ])); + return (in_array($s, ['Like', 'Dislike', 'Flag', 'Block', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact'])); } /** @@ -298,9 +297,9 @@ class ActivityStreams { * @return NULL|mixed */ - function get_actor($property,$base='',$namespace = '') { + function get_actor($property, $base = '', $namespace = '') { $x = $this->get_property_obj($property, $base, $namespace); - if($this->is_url($x)) { + if ($this->is_url($x)) { // SECURITY: If we have already stored the actor profile, re-generate it // from cached data - don't refetch it from the network @@ -308,15 +307,15 @@ class ActivityStreams { $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1", dbesc($x) ); - if($r) { - $y = Activity::encode_person($r[0]); + if ($r) { + $y = Activity::encode_person($r[0]); $y['cached'] = true; return $y; } } - $actor = $this->get_compound_property($property,$base,$namespace,true); - if(is_array($actor) && self::is_an_actor($actor['type'])) { - if(array_key_exists('id',$actor) && (! array_key_exists('inbox',$actor))) { + $actor = $this->get_compound_property($property, $base, $namespace, true); + if (is_array($actor) && self::is_an_actor($actor['type'])) { + if (array_key_exists('id', $actor) && (!array_key_exists('inbox', $actor))) { $actor = $this->fetch_property($actor['id']); } return $actor; @@ -336,7 +335,7 @@ class ActivityStreams { */ function get_compound_property($property, $base = '', $namespace = '', $first = false) { $x = $this->get_property_obj($property, $base, $namespace); - if($this->is_url($x)) { + if ($this->is_url($x)) { $y = $this->fetch_property($x); if (is_array($y)) { $x = $y; @@ -345,22 +344,22 @@ class ActivityStreams { // verify and unpack JSalmon signature if present - if(is_array($x) && array_key_exists('signed',$x)) { + if (is_array($x) && array_key_exists('signed', $x)) { $ret = JSalmon::verify($x); $tmp = JSalmon::unpack($x['data']); - if($ret && $ret['success']) { - if($ret['signer']) { - $saved = json_encode($x,JSON_UNESCAPED_SLASHES); - $x = $tmp; - $x['signer'] = $ret['signer']; + if ($ret && $ret['success']) { + if ($ret['signer']) { + $saved = json_encode($x, JSON_UNESCAPED_SLASHES); + $x = $tmp; + $x['signer'] = $ret['signer']; $x['signed_data'] = $saved; - if($ret['hubloc']) { + if ($ret['hubloc']) { $x['hubloc'] = $ret['hubloc']; } } } } - if($first && is_array($x) && array_key_exists(0,$x)) { + if ($first && is_array($x) && array_key_exists(0, $x)) { return $x[0]; } @@ -374,7 +373,7 @@ class ActivityStreams { * @return boolean */ function is_url($url) { - if(($url) && (! is_array($url)) && (strpos($url, 'http') === 0)) { + if (($url) && (!is_array($url)) && (strpos($url, 'http') === 0)) { return true; } @@ -389,13 +388,13 @@ class ActivityStreams { * @return NULL|mixed */ function get_primary_type($base = '', $namespace = '') { - if(! $base) + if (!$base) $base = $this->data; $x = $this->get_property_obj('type', $base, $namespace); - if(is_array($x)) { - foreach($x as $y) { - if(strpos($y, ':') === false) { + if (is_array($x)) { + foreach ($x as $y) { + if (strpos($y, ':') === false) { return $y; } } @@ -412,7 +411,7 @@ class ActivityStreams { static function is_as_request($channel = null) { $hookdata = []; - if($channel) + if ($channel) $hookdata['channel'] = $channel; $hookdata['data'] = ['application/x-zot-activity+json']; @@ -420,14 +419,14 @@ class ActivityStreams { call_hooks('is_as_request', $hookdata); $x = getBestSupportedMimeType($hookdata['data']); - return(($x) ? true : false); + return (($x) ? true : false); } static function get_accept_header_string($channel = null) { $hookdata = []; - if($channel) + if ($channel) $hookdata['channel'] = $channel; $hookdata['data'] = 'application/x-zot-activity+json'; diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 5cfcb623b..6b97dc0ef 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -22,68 +22,67 @@ require_once('include/opengraph.php'); * @brief Channel Controller * */ - class Channel extends Controller { function init() { - if(in_array(substr($_GET['search'],0,1),[ '@', '!', '?']) || strpos($_GET['search'], 'https://') === 0) + if (in_array(substr($_GET['search'], 0, 1), ['@', '!', '?']) || strpos($_GET['search'], 'https://') === 0) goaway('search' . '?f=&search=' . $_GET['search']); $which = null; - if(argc() > 1) + if (argc() > 1) $which = argv(1); - if(! $which) { - if(local_channel()) { + if (!$which) { + if (local_channel()) { $channel = App::get_channel(); - if($channel && $channel['channel_address']) - $which = $channel['channel_address']; + if ($channel && $channel['channel_address']) + $which = $channel['channel_address']; } } - if(! $which) { - notice( t('You must be logged in to see this page.') . EOL ); + if (!$which) { + notice(t('You must be logged in to see this page.') . EOL); return; } $profile = 0; $channel = App::get_channel(); - if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { - $which = $channel['channel_address']; + if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; $profile = argv(1); } $channel = channelx_by_nick($which); - if(! $channel) { + if (!$channel) { http_status_exit(404, 'Not found'); } // handle zot6 channel discovery - if(Libzot::is_zot_request()) { + if (Libzot::is_zot_request()) { $sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6'); - if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) { - $data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'], 'target_url' => $sigdata['signer'] ])); - $s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", + if ($sigdata && $sigdata['signer'] && $sigdata['header_valid']) { + $data = json_encode(Libzot::zotinfo(['address' => $channel['channel_address'], 'target_url' => $sigdata['signer']])); + $s = q("select site_crypto, hubloc_sitekey from site left join hubloc on hubloc_url = site_url where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", dbesc($sigdata['signer']) ); - if($s) { - $data = json_encode(crypto_encapsulate($data,$s[0]['hubloc_sitekey'],Libzot::best_algorithm($s[0]['site_crypto']))); + if ($s) { + $data = json_encode(crypto_encapsulate($data, $s[0]['hubloc_sitekey'], Libzot::best_algorithm($s[0]['site_crypto']))); } } else { - $data = json_encode(Libzot::zotinfo([ 'guid_hash' => $channel['channel_hash'] ])); + $data = json_encode(Libzot::zotinfo(['guid_hash' => $channel['channel_hash']])); } $headers = [ 'Content-Type' => 'application/x-zot+json', 'Digest' => HTTPSig::generate_digest_header($data), '(request-target)' => strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'] - ]; - $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel)); + ]; + $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel)); HTTPSig::set_headers($h); echo $data; killme(); @@ -94,9 +93,9 @@ class Channel extends Controller { // Somebody may attempt an ActivityStreams fetch on one of our message permalinks // Make it do the right thing. - $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); - if ($mid && strpos($mid,'b64.') === 0) { - $decoded = @base64url_decode(substr($mid,4)); + $mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : ''); + if ($mid && strpos($mid, 'b64.') === 0) { + $decoded = @base64url_decode(substr($mid, 4)); if ($decoded) { $mid = $decoded; } @@ -105,35 +104,35 @@ class Channel extends Controller { $obj = null; if (strpos($mid, z_root() . '/item/') === 0) { App::$argc = 2; - App::$argv = [ 'item', basename($mid) ]; - $obj = new Item(); + App::$argv = ['item', basename($mid)]; + $obj = new Item(); } if (strpos($mid, z_root() . '/activity/') === 0) { App::$argc = 2; - App::$argv = [ 'activity', basename($mid) ]; - $obj = new Activity(); + App::$argv = ['activity', basename($mid)]; + $obj = new Activity(); } if ($obj) { $obj->init(); } } - as_return_and_die(Activity::encode_person($channel,true),$channel); + as_return_and_die(Activity::encode_person($channel, true), $channel); } - if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { - $which = $channel['channel_address']; + if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; $profile = argv(1); } - head_add_link( [ + head_add_link([ 'rel' => 'alternate', 'type' => 'application/atom+xml', 'title' => t('Posts and comments'), 'href' => z_root() . '/feed/' . $which ]); - head_add_link( [ + head_add_link([ 'rel' => 'alternate', 'type' => 'application/atom+xml', 'title' => t('Only posts'), @@ -143,18 +142,18 @@ class Channel extends Controller { // Run profile_load() here to make sure the theme is set before // we start loading content - profile_load($which,$profile); + profile_load($which, $profile); // Add Opengraph markup - $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); - if(strpos($mid,'b64.') === 0) - $mid = @base64url_decode(substr($mid,4)); - - if($mid) - $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1", - dbesc($mid), - intval($channel['channel_id']) - ); + $mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : ''); + if (strpos($mid, 'b64.') === 0) + $mid = @base64url_decode(substr($mid, 4)); + + if ($mid) + $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1", + dbesc($mid), + intval($channel['channel_id']) + ); opengraph_add_meta($r ? $r[0] : [], $channel); } @@ -165,99 +164,99 @@ class Channel extends Controller { $category = $datequery = $datequery2 = ''; - $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); + $mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : ''); - if(strpos($mid,'b64.') === 0) - $decoded = @base64url_decode(substr($mid,4)); - if($decoded) + if (strpos($mid, 'b64.') === 0) + $decoded = @base64url_decode(substr($mid, 4)); + if ($decoded) $mid = $decoded; - $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : ''); - $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : ''); + $datequery = ((x($_GET, 'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : ''); + $datequery2 = ((x($_GET, 'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : ''); - if(observer_prohibited(true)) { + if (observer_prohibited(true)) { return login(); } - $category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : ''); - $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : ''); - $order = ((x($_GET,'order')) ? notags($_GET['order']) : 'post'); - $search = ((x($_GET,'search')) ? $_GET['search'] : EMPTY_STR); + $category = ((x($_REQUEST, 'cat')) ? $_REQUEST['cat'] : ''); + $hashtags = ((x($_REQUEST, 'tag')) ? $_REQUEST['tag'] : ''); + $order = ((x($_GET, 'order')) ? notags($_GET['order']) : 'post'); + $search = ((x($_GET, 'search')) ? $_GET['search'] : EMPTY_STR); - $groups = array(); + $groups = []; $o = ''; - if($update) { + if ($update) { // Ensure we've got a profile owner if updating. App::$profile['profile_uid'] = App::$profile_uid = $update; } $is_owner = (((local_channel()) && (App::$profile['profile_uid'] == local_channel())) ? true : false); - $channel = App::get_channel(); + $channel = App::get_channel(); $observer = App::get_observer(); - $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - $perms = get_all_perms(App::$profile['profile_uid'],$ob_hash); + $perms = get_all_perms(App::$profile['profile_uid'], $ob_hash); - if(! $perms['view_stream']) { + if (!$perms['view_stream']) { // We may want to make the target of this redirect configurable - if($perms['view_profile']) { - notice( t('Insufficient permissions. Request redirected to profile page.') . EOL); - goaway (z_root() . "/profile/" . App::$profile['channel_address']); + if ($perms['view_profile']) { + notice(t('Insufficient permissions. Request redirected to profile page.') . EOL); + goaway(z_root() . "/profile/" . App::$profile['channel_address']); } - notice( t('Permission denied.') . EOL); + notice(t('Permission denied.') . EOL); return; } - if(! $update) { + if (!$update) { nav_set_selected('Channel Home'); // search terms header - if($search) { - $o .= replace_macros(get_markup_template("section_title.tpl"),array( - '$title' => t('Search Results For:') . ' ' . htmlspecialchars($search, ENT_COMPAT,'UTF-8') - )); + if ($search) { + $o .= replace_macros(get_markup_template("section_title.tpl"), [ + '$title' => t('Search Results For:') . ' ' . htmlspecialchars($search, ENT_COMPAT, 'UTF-8') + ]); } - if($channel && $is_owner) { - $channel_acl = array( + if ($channel && $is_owner) { + $channel_acl = [ 'allow_cid' => $channel['channel_allow_cid'], 'allow_gid' => $channel['channel_allow_gid'], - 'deny_cid' => $channel['channel_deny_cid'], - 'deny_gid' => $channel['channel_deny_gid'] - ); + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'] + ]; } else { - $channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ]; + $channel_acl = ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '']; } - if($perms['post_wall']) { - - $x = array( - 'is_owner' => $is_owner, - 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false), - 'default_location' => (($is_owner) ? App::$profile['channel_location'] : ''), - 'nickname' => App::$profile['channel_address'], - 'lockstate' => (((strlen(App::$profile['channel_allow_cid'])) || (strlen(App::$profile['channel_allow_gid'])) || (strlen(App::$profile['channel_deny_cid'])) || (strlen(App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,true, PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), - 'permissions' => $channel_acl, - 'showacl' => (($is_owner) ? 'yes' : ''), - 'bang' => '', - 'visitor' => (($is_owner || $observer) ? true : false), - 'profile_uid' => App::$profile['profile_uid'], + if ($perms['post_wall']) { + + $x = [ + 'is_owner' => $is_owner, + 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(App::$profile['profile_uid'], 'system', 'use_browser_location')))) ? true : false), + 'default_location' => (($is_owner) ? App::$profile['channel_location'] : ''), + 'nickname' => App::$profile['channel_address'], + 'lockstate' => (((strlen(App::$profile['channel_allow_cid'])) || (strlen(App::$profile['channel_allow_gid'])) || (strlen(App::$profile['channel_deny_cid'])) || (strlen(App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), + 'acl' => (($is_owner) ? populate_acl($channel_acl, true, PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), + 'permissions' => $channel_acl, + 'showacl' => (($is_owner) ? 'yes' : ''), + 'bang' => '', + 'visitor' => (($is_owner || $observer) ? true : false), + 'profile_uid' => App::$profile['profile_uid'], 'editor_autocomplete' => true, - 'bbco_autocomplete' => 'bbcode', - 'bbcode' => true, - 'jotnets' => true, - 'reset' => t('Reset form') - ); + 'bbco_autocomplete' => 'bbcode', + 'bbcode' => true, + 'jotnets' => true, + 'reset' => t('Reset form') + ]; - $o .= status_editor($a,$x,false,'Channel'); + $o .= status_editor($a, $x, false, 'Channel'); } } @@ -267,15 +266,15 @@ class Channel extends Controller { * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups */ - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_pending_remove = 0 and item.item_blocked = 0 "; - if (! $is_owner) - $item_normal .= "and item.item_delayed = 0 "; + if (!$is_owner) + $item_normal .= "and item.item_delayed = 0 "; $item_normal_update = item_normal_update(); - $sql_extra = item_permissions_sql(App::$profile['profile_uid']); + $sql_extra = item_permissions_sql(App::$profile['profile_uid']); - if(feature_enabled(App::$profile['profile_uid'], 'channel_list_mode') && (! $mid)) + if (feature_enabled(App::$profile['profile_uid'], 'channel_list_mode') && (!$mid)) $page_mode = 'list'; else $page_mode = 'client'; @@ -283,13 +282,13 @@ class Channel extends Controller { $abook_uids = " and abook.abook_channel = " . intval(App::$profile['profile_uid']) . " "; $simple_update = ''; - if($update && $_SESSION['loadtime']) - $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) "; + if ($update && $_SESSION['loadtime']) + $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime']) . "' ) "; - if($search) { + if ($search) { $search = escape_tags($search); - if(strpos($search,'#') === 0) { - $sql_extra .= term_query('item',substr($search,1),TERM_HASHTAG,TERM_COMMUNITYTAG); + if (strpos($search, '#') === 0) { + $sql_extra .= term_query('item', substr($search, 1), TERM_HASHTAG, TERM_COMMUNITYTAG); } else { $sql_extra .= sprintf(" AND (item.body like '%s' OR item.title like '%s') ", @@ -306,9 +305,9 @@ class Channel extends Controller { 'title' => 'oembed' ]); - if(($update) && (! $load)) { + if (($update) && (!$load)) { - if($mid) { + if ($mid) { $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update AND item_wall = 1 $simple_update $sql_extra limit 1", dbesc($mid . '%'), @@ -329,40 +328,40 @@ class Channel extends Controller { } else { - if(x($category)) { - $sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $category, TERM_CATEGORY)); + if (x($category)) { + $sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $category, TERM_CATEGORY)); } - if(x($hashtags)) { - $sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); + if (x($hashtags)) { + $sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'], 'item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); } - if($datequery) { - $sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery)))); - $order = 'post'; + if ($datequery) { + $sql_extra2 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery)))); + $order = 'post'; } - if($datequery2) { - $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); + if ($datequery2) { + $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery2)))); } - if($order === 'post') + if ($order === 'post') $ordering = "created"; else $ordering = "commented"; - $itemspage = get_pconfig(local_channel(),'system','itemspage'); + $itemspage = get_pconfig(local_channel(), 'system', 'itemspage'); App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10)); $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); - if($noscript_content || $load) { - if($mid) { + if ($noscript_content || $load) { + if ($mid) { $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal AND item_wall = 1 $sql_extra limit 1", dbesc($mid . '%'), intval(App::$profile['profile_uid']) ); - if (! $r) { - notice( t('Permission denied.') . EOL); + if (!$r) { + notice(t('Permission denied.') . EOL); } } else { @@ -378,12 +377,12 @@ class Channel extends Controller { } } else { - $r = array(); + $r = []; } } - if($r) { + if ($r) { - $parents_str = ids_to_querystr($r,'item_id'); + $parents_str = ids_to_querystr($r, 'item_id'); $r = q("SELECT item.*, item.id AS item_id FROM item @@ -396,37 +395,38 @@ class Channel extends Controller { xchan_query($r); $items = fetch_post_tags($r, true); - $items = conv_sort($items,$ordering); + $items = conv_sort($items, $ordering); - if($load && $mid && (! count($items))) { + if ($load && $mid && (!count($items))) { // This will happen if we don't have sufficient permissions // to view the parent item (or the item itself if it is toplevel) - notice( t('Permission denied.') . EOL); + notice(t('Permission denied.') . EOL); } - } else { - $items = array(); + } + else { + $items = []; } // Add pinned content - if(! x($_REQUEST,'mid') && ! $search) { + if (!x($_REQUEST, 'mid') && !$search) { $pinned = new \Zotlabs\Widget\Pinned; - $r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]); - $o .= $r['html']; + $r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]); + $o .= $r['html']; } $mode = (($search) ? 'search' : 'channel'); - if((! $update) && (! $load)) { + if ((!$update) && (!$load)) { - if($decoded) + if ($decoded) $mid = 'b64.' . base64url_encode($mid); // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. - $maxheight = get_pconfig(App::$profile['profile_uid'],'system','channel_divmore_height'); - if(! $maxheight) + $maxheight = get_pconfig(App::$profile['profile_uid'], 'system', 'channel_divmore_height'); + if (!$maxheight) $maxheight = 400; $o .= '
      ' . "\r\n"; @@ -434,48 +434,48 @@ class Channel extends Controller { . "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; divmore_height = " . intval($maxheight) . ";\r\n"; - App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( - '$baseurl' => z_root(), - '$pgtype' => 'channel', - '$uid' => ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : '0'), - '$gid' => '0', - '$cid' => '0', - '$cmin' => '(-1)', - '$cmax' => '(-1)', - '$star' => '0', - '$liked' => '0', - '$conv' => '0', - '$spam' => '0', - '$nouveau' => '0', - '$wall' => '1', - '$fh' => '0', - '$dm' => '0', - '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1), - '$search' => $search, - '$xchan' => '', - '$order' => (($order) ? urlencode($order) : ''), - '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), - '$file' => '', - '$cats' => (($category) ? urlencode($category) : ''), - '$tags' => (($hashtags) ? urlencode($hashtags) : ''), - '$mid' => (($mid) ? urlencode($mid) : ''), - '$verb' => '', - '$net' => '', - '$dend' => $datequery, - '$dbegin' => $datequery2, + App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), [ + '$baseurl' => z_root(), + '$pgtype' => 'channel', + '$uid' => ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : '0'), + '$gid' => '0', + '$cid' => '0', + '$cmin' => '(-1)', + '$cmax' => '(-1)', + '$star' => '0', + '$liked' => '0', + '$conv' => '0', + '$spam' => '0', + '$nouveau' => '0', + '$wall' => '1', + '$fh' => '0', + '$dm' => '0', + '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1), + '$search' => $search, + '$xchan' => '', + '$order' => (($order) ? urlencode($order) : ''), + '$list' => ((x($_REQUEST, 'list')) ? intval($_REQUEST['list']) : 0), + '$file' => '', + '$cats' => (($category) ? urlencode($category) : ''), + '$tags' => (($hashtags) ? urlencode($hashtags) : ''), + '$mid' => (($mid) ? urlencode($mid) : ''), + '$verb' => '', + '$net' => '', + '$dend' => $datequery, + '$dbegin' => $datequery2, '$conv_mode' => 'channel', '$page_mode' => $page_mode - )); + ]); } - if($update) { - $o .= conversation($items,$mode,$update,$page_mode); + if ($update) { + $o .= conversation($items, $mode, $update, $page_mode); } else { $o .= ''; - $o .= conversation($items,$mode,$update,$page_mode); + $o .= conversation($items, $mode, $update, $page_mode); if ($mid && $items[0]['title']) App::$page['title'] = $items[0]['title'] . " - " . App::$page['title']; } - if($mid) + if ($mid) $o .= '
      '; $_SESSION['loadtime'] = datetime_convert(); diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php index bce067b92..118f11f64 100644 --- a/Zotlabs/Module/Profile.php +++ b/Zotlabs/Module/Profile.php @@ -1,4 +1,5 @@ 1) + + if (argc() > 1) $which = argv(1); else { - notice( t('Requested profile is not available.') . EOL ); + notice(t('Requested profile is not available.') . EOL); App::$error = 404; return; } @@ -32,92 +32,90 @@ class Profile extends Controller { $profile = ''; $channel = App::get_channel(); - if(! $channel) + if (!$channel) http_status_exit(404, 'Not found'); - if(ActivityStreams::is_as_request()) { - $p = Activity::encode_person($channel,true); - as_return_and_die([ 'type' => 'Profile', 'describes' => $p ], $channel); + if (ActivityStreams::is_as_request()) { + $p = Activity::encode_person($channel, true); + as_return_and_die(['type' => 'Profile', 'describes' => $p], $channel); } nav_set_selected('Profile'); - if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { - $which = $channel['channel_address']; - $profile = argv(1); - $r = q("select profile_guid from profile where id = %d and uid = %d limit 1", + if ((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + $r = q("select profile_guid from profile where id = %d and uid = %d limit 1", intval($profile), intval(local_channel()) ); - if(! $r) + if (!$r) $profile = ''; $profile = $r[0]['profile_guid']; } - - head_add_link( [ - 'rel' => 'alternate', + + head_add_link([ + 'rel' => 'alternate', 'type' => 'application/atom+xml', 'title' => t('Posts and comments'), 'href' => z_root() . '/feed/' . $which ]); - head_add_link( [ - 'rel' => 'alternate', + head_add_link([ + 'rel' => 'alternate', 'type' => 'application/atom+xml', 'title' => t('Only posts'), 'href' => z_root() . '/feed/' . $which . '?f=&top=1' ]); - if(! $profile) { + if (!$profile) { $x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1", dbesc(argv(1)) ); - if($x) { + if ($x) { App::$profile = $x[0]; } } - - profile_load($which,$profile); - - + + profile_load($which, $profile); + + } - + function get() { - - if(observer_prohibited(true)) { + + if (observer_prohibited(true)) { return login(); } - - $groups = array(); + $groups = []; $tab = 'profile'; - $o = ''; - - if(! (perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(), 'view_profile'))) { - notice( t('Permission denied.') . EOL); + $o = ''; + + if (!(perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_profile'))) { + notice(t('Permission denied.') . EOL); return; } - - if(argc() > 2 && argv(2) === 'vcard') { + if (argc() > 2 && argv(2) === 'vcard') { header('Content-type: text/vcard'); - header('content-disposition: attachment; filename="' . t('vcard') . '-' . App::$profile['channel_address'] . '.vcf"' ); + header('content-disposition: attachment; filename="' . t('vcard') . '-' . App::$profile['channel_address'] . '.vcf"'); echo App::$profile['profile_vcard']; killme(); } - + $is_owner = ((local_channel()) && (local_channel() == App::$profile['profile_uid']) ? true : false); - - if(App::$profile['hidewall'] && (! $is_owner) && (! remote_channel())) { - notice( t('Permission denied.') . EOL); + + if (App::$profile['hidewall'] && (!$is_owner) && (!remote_channel())) { + notice(t('Permission denied.') . EOL); return; } - - head_add_link([ + + head_add_link([ 'rel' => 'alternate', 'type' => 'application/json+oembed', 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string), @@ -125,9 +123,9 @@ class Profile extends Controller { ]); $o .= advanced_profile(); - call_hooks('profile_advanced',$o); + call_hooks('profile_advanced', $o); return $o; - + } - + } -- cgit v1.2.3 From 7686b48723727a6be8d6f3c3ccd511da690d0014 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 29 Jan 2021 07:36:56 +0000 Subject: code format only --- Zotlabs/Lib/Activity.php | 49 +++++++++++++--------------------------------- Zotlabs/Module/Channel.php | 1 - 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 3bfdf722a..c56d73421 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -113,7 +113,6 @@ class Activity { return null; } - static function fetch_person($x) { return self::fetch_profile($x); } @@ -179,7 +178,6 @@ class Activity { } } - static function fetch_image($x) { $ret = [ 'type' => 'Image', @@ -353,7 +351,6 @@ class Activity { return $ret; } - static function encode_item($i) { $ret = []; @@ -585,7 +582,6 @@ class Activity { return $ret; } - static function encode_taxonomy($item) { $ret = []; @@ -674,7 +670,6 @@ class Activity { return $ret; } - static function decode_attachment($item) { $ret = []; @@ -698,7 +693,6 @@ class Activity { return $ret; } - static function encode_activity($i, $recurse = false) { $ret = []; @@ -960,7 +954,6 @@ class Activity { } // Returns an array of URLS for any mention tags found in the item array $i. - static function map_mentions($i) { if (!$i['term']) { @@ -983,7 +976,6 @@ class Activity { } // Returns an array of all recipients targeted by private item array $i. - static function map_acl($i) { $ret = []; @@ -1066,6 +1058,7 @@ class Activity { if ($p['xchan_addr'] && strpos($p['xchan_addr'], '@')) $ret['preferredUsername'] = substr($p['xchan_addr'], 0, strpos($p['xchan_addr'], '@')); + $ret['name'] = $p['xchan_name']; $ret['updated'] = datetime_convert('UTC', 'UTC', $p['xchan_name_date'], ATOM_TIME); $ret['icon'] = [ @@ -1095,7 +1088,11 @@ class Activity { 'publicKeyPem' => $p['xchan_pubkey'] ]; - $arr = ['xchan' => $p, 'encoded' => $ret]; + $arr = [ + 'xchan' => $p, + 'encoded' => $ret + ]; + call_hooks('encode_person', $arr); $ret = $arr['encoded']; @@ -1103,7 +1100,6 @@ class Activity { return $ret; } - static function activity_mapper($verb) { if (strpos($verb, '/') === false) { @@ -1147,7 +1143,7 @@ class Activity { if (strpos($verb, ACTIVITY_POKE) !== false) return 'Activity'; - // We should return false, however this will trigger an uncaught execption and crash + // We should return false, however this will trigger an uncaught execption and crash // the delivery system if encountered by the JSON-LDSignature library logger('Unmapped activity: ' . $verb); @@ -1155,7 +1151,6 @@ class Activity { // return false; } - static function activity_decode_mapper($verb) { $acts = [ @@ -1227,7 +1222,6 @@ class Activity { return 'Note'; } - static function activity_obj_mapper($obj) { $objs = [ @@ -1274,17 +1268,16 @@ class Activity { } - static function follow($channel, $act) { $contact = null; $their_follow_id = null; /* - * - * if $act->type === 'Follow', actor is now following $channel - * if $act->type === 'Accept', actor has approved a follow request from $channel - * + * + * if $act->type === 'Follow', actor is now following $channel + * if $act->type === 'Accept', actor has approved a follow request from $channel + * */ $person_obj = $act->actor; @@ -1299,7 +1292,7 @@ class Activity { self::actor_store($person_obj['id'], $person_obj); - // Find any existing abook record + // Find any existing abook record $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($person_obj['id']), @@ -1316,7 +1309,7 @@ class Activity { if ($contact && $contact['abook_id']) { - // A relationship of some form already exists on this site. + // A relationship of some form already exists on this site. switch ($act->type) { @@ -1471,7 +1464,6 @@ class Activity { } - static function unfollow($channel, $act) { $contact = null; @@ -1497,7 +1489,6 @@ class Activity { return; } - static function actor_store($url, $person_obj) { if (!is_array($person_obj)) @@ -1603,7 +1594,7 @@ class Activity { else { // Record exists. Cache existing records for one week at most - // then refetch to catch updated profile photos, names, etc. + // then refetch to catch updated profile photos, names, etc. $d = datetime_convert('UTC', 'UTC', 'now - 1 week'); if ($r[0]['xchan_name_date'] > $d) @@ -1665,7 +1656,6 @@ class Activity { } - static function create_action($channel, $observer_hash, $act) { if (in_array($act->obj['type'], ['Note', 'Article', 'Video'])) { @@ -1683,7 +1673,6 @@ class Activity { } - static function like_action($channel, $observer_hash, $act) { if (in_array($act->obj['type'], ['Note', 'Article', 'Video'])) { @@ -1694,7 +1683,6 @@ class Activity { } // sort function width decreasing - static function vid_sort($a, $b) { if ($a['width'] === $b['width']) return 0; @@ -1956,7 +1944,6 @@ class Activity { } - static function update_poll($item, $post) { $multi = false; $mid = $post['mid']; @@ -2049,7 +2036,6 @@ class Activity { return false; } - static function decode_note($act) { $response_activity = false; @@ -3388,7 +3374,6 @@ class Activity { return; } - static function bb_attach($attach, $body) { $ret = false; @@ -3414,9 +3399,7 @@ class Activity { return $ret; } - // check for the existence of existing media link in body - static function media_not_in_body($s, $body) { if ((strpos($body, ']' . $s . '[/img]') === false) && @@ -3428,7 +3411,6 @@ class Activity { return false; } - static function bb_content($content, $field) { require_once('include/html2bbcode.php'); @@ -3457,7 +3439,6 @@ class Activity { return $ret; } - static function get_content($act) { $content = []; @@ -3513,7 +3494,6 @@ class Activity { return $content; } - static function get_textfield($act, $field) { $content = false; @@ -3530,7 +3510,6 @@ class Activity { // Find either an Authorization: Bearer token or 'token' request variable // in the current web request and return it - static function token_from_request() { foreach (['REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION'] as $s) { diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 6b97dc0ef..915e0ea60 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -116,7 +116,6 @@ class Channel extends Controller { $obj->init(); } } - as_return_and_die(Activity::encode_person($channel, true), $channel); } -- cgit v1.2.3 From 89bf71b227d1bb585b69a52be80752bd1cb730af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Budzi=C5=84ski?= Date: Sat, 30 Jan 2021 14:03:39 +0100 Subject: New fixes & translatosns: - doc/pl/tutorials/*: 100% - doc/pl/checking_account_guota_usage.bb: 100% - doc/pl/member/member_guide.bb: fixes - doc/pl/admin/hub_snapshots.md: fixes - view/pl/hmessage.po: fixes - view/pl/hstrings.po: fixes to generated code --- doc/pl/admin/administrator_guide.md | 456 ++++++--------------- doc/pl/admin/hub_snapshots.md | 4 +- doc/pl/checking_account_quota_usage.bb | 20 + doc/pl/member/member_guide.bb | 418 ++++++++++--------- ...38aa5bfedd230d2a7233d3915ac15d629f9dd845854.png | Bin 0 -> 249151 bytes ...035c441631745d16acdb7a44e50d148256c8ad26a67.png | Bin 0 -> 293314 bytes ...7cce3dbd6fc9f7cd832a4c91a4c5dd294b7b219e7d8.png | Bin 0 -> 178913 bytes ...1dd3a00ba17a76ca6db4c246b3c4fa286b390cae7c8.png | Bin 0 -> 43797 bytes ...dc91155b628d9be5f99ab04a78108ec404f53ec7bb5.png | Bin 0 -> 46752 bytes ...0329db6c3814e2975979aff12f873f43d81724c5e61.png | Bin 0 -> 257211 bytes ...4fd61aecd8f216fa8f5dfa0f16a04c8e968fdbc43d0.png | Bin 0 -> 91478 bytes ...515e9089217f2e136d4fcf8babe77bac00ecaad43ce.png | Bin 0 -> 293611 bytes ...7869bb14dfffe1e5be098d1cd6e590bbead25b4cc05.png | Bin 0 -> 318766 bytes ...999a5fe1d07be5af460cda4ba6cde9106ebc1564bb0.png | Bin 0 -> 298857 bytes ...f5630e921756f825ee00f8ee464d3ef9fed971d2852.png | Bin 0 -> 532838 bytes ...d4d3b6ba1364fac8ead173edd39340adaf78be11c9d.png | Bin 0 -> 137827 bytes ...3da8ed0680d1a721c85f2ae2bdd5739a8def466010e.png | Bin 0 -> 466641 bytes ...2d2a849412044cc6a0f8aebeac289d28786f2649d24.png | Bin 0 -> 240495 bytes ...e665961d35affbd053368056f562c58200fb41027b0.png | Bin 0 -> 665755 bytes ...7bb6092c3240b291eca8afa73133b3ac03b86f3302d.png | Bin 0 -> 324092 bytes ...915598c69c17a87c910a39db2cd3b5292e4623ea4c4.png | Bin 0 -> 466584 bytes ...24af42055f0f24ed5e81ba622aca8cac576ccf5930e.png | Bin 0 -> 155763 bytes ...37f6b7b7863da5a8e39a5bc17d2c67fa160efef2056.png | Bin 0 -> 134643 bytes ...27df79bd4dc6d47edf1b66ea243f005b6b452ec366b.png | Bin 0 -> 306069 bytes ...2f460397bb083bf7dc2a2b8f065e64da598b45b4a2b.png | Bin 0 -> 57185 bytes ...3fa39b2084c16a8410de1f7a6559633435817444aef.png | Bin 0 -> 255688 bytes ...4bde52432fdc7b39692a094559aa504de99352940b1.png | Bin 0 -> 83265 bytes ...ce90a60fc416415271d9c51b81ad2a950fb0157222a.png | Bin 0 -> 264916 bytes ...6f353514c907b3fdfe019918fc5553bb3f31388a36f.png | Bin 0 -> 68194 bytes ...de9048cd14b417c0d76de17af476be5f296b78d70e9.png | Bin 0 -> 99210 bytes doc/pl/tutorials/personal_channel.md | 116 ++++++ view/pl/hmessages.mo | Bin 296728 -> 0 bytes view/pl/hmessages.po | 10 +- view/pl/hstrings.php | 10 +- 34 files changed, 479 insertions(+), 555 deletions(-) create mode 100644 doc/pl/checking_account_quota_usage.bb create mode 100644 doc/pl/tutorials/assets/0965ace945f0c95ae38aa5bfedd230d2a7233d3915ac15d629f9dd845854.png create mode 100644 doc/pl/tutorials/assets/1ebe02c205962dd25035c441631745d16acdb7a44e50d148256c8ad26a67.png create mode 100644 doc/pl/tutorials/assets/2243e48ccea25bd907cce3dbd6fc9f7cd832a4c91a4c5dd294b7b219e7d8.png create mode 100644 doc/pl/tutorials/assets/25eaad2435200f72a1dd3a00ba17a76ca6db4c246b3c4fa286b390cae7c8.png create mode 100644 doc/pl/tutorials/assets/2b539d5a8474d6ec6dc91155b628d9be5f99ab04a78108ec404f53ec7bb5.png create mode 100644 doc/pl/tutorials/assets/31f42a02bdbae095e0329db6c3814e2975979aff12f873f43d81724c5e61.png create mode 100644 doc/pl/tutorials/assets/324247680b605fd214fd61aecd8f216fa8f5dfa0f16a04c8e968fdbc43d0.png create mode 100644 doc/pl/tutorials/assets/3656a67dce40a1fc2515e9089217f2e136d4fcf8babe77bac00ecaad43ce.png create mode 100644 doc/pl/tutorials/assets/458a842c2ea0fbe3b7869bb14dfffe1e5be098d1cd6e590bbead25b4cc05.png create mode 100644 doc/pl/tutorials/assets/4aaaf1e124514c8d6999a5fe1d07be5af460cda4ba6cde9106ebc1564bb0.png create mode 100644 doc/pl/tutorials/assets/4cf326152797a8ecdf5630e921756f825ee00f8ee464d3ef9fed971d2852.png create mode 100644 doc/pl/tutorials/assets/75d2927b7ad0d2043d4d3b6ba1364fac8ead173edd39340adaf78be11c9d.png create mode 100644 doc/pl/tutorials/assets/7c976a06662a1357b3da8ed0680d1a721c85f2ae2bdd5739a8def466010e.png create mode 100644 doc/pl/tutorials/assets/99a6efda4df631dfb2d2a849412044cc6a0f8aebeac289d28786f2649d24.png create mode 100644 doc/pl/tutorials/assets/9eae9fad774a4cd29e665961d35affbd053368056f562c58200fb41027b0.png create mode 100644 doc/pl/tutorials/assets/b0bfdf02aef3710a37bb6092c3240b291eca8afa73133b3ac03b86f3302d.png create mode 100644 doc/pl/tutorials/assets/b334915c03a665493915598c69c17a87c910a39db2cd3b5292e4623ea4c4.png create mode 100644 doc/pl/tutorials/assets/b3eece28e8db67f1024af42055f0f24ed5e81ba622aca8cac576ccf5930e.png create mode 100644 doc/pl/tutorials/assets/bdbcf0ffd9004657237f6b7b7863da5a8e39a5bc17d2c67fa160efef2056.png create mode 100644 doc/pl/tutorials/assets/c4cad3e4c356dd2a227df79bd4dc6d47edf1b66ea243f005b6b452ec366b.png create mode 100644 doc/pl/tutorials/assets/c9a880cc82ffa1f7c2f460397bb083bf7dc2a2b8f065e64da598b45b4a2b.png create mode 100644 doc/pl/tutorials/assets/d080e92d797af5e863fa39b2084c16a8410de1f7a6559633435817444aef.png create mode 100644 doc/pl/tutorials/assets/e05248fdc5688d6d24bde52432fdc7b39692a094559aa504de99352940b1.png create mode 100644 doc/pl/tutorials/assets/e5d5674a34e848e2cce90a60fc416415271d9c51b81ad2a950fb0157222a.png create mode 100644 doc/pl/tutorials/assets/ef78bc6aa3fafebd46f353514c907b3fdfe019918fc5553bb3f31388a36f.png create mode 100644 doc/pl/tutorials/assets/facb0bdfdecb4c779de9048cd14b417c0d76de17af476be5f296b78d70e9.png create mode 100644 doc/pl/tutorials/personal_channel.md delete mode 100644 view/pl/hmessages.mo diff --git a/doc/pl/admin/administrator_guide.md b/doc/pl/admin/administrator_guide.md index 540828e0d..86e5fd80c 100644 --- a/doc/pl/admin/administrator_guide.md +++ b/doc/pl/admin/administrator_guide.md @@ -1,11 +1,6 @@ ### Przegląd -$Projectname to więcej niż prosta aplikacja internetowa. Jest to złożony system -komunikacyjny, który bardziej przypomina serwer poczty elektronicznej niż serwer -WWW. Aby zapewnić niezawodność i wydajność, wiadomości są dostarczane w tle i -umieszczane w kolejce do późniejszego dostarczenia, gdy lokacje są wyłączone. -Ten rodzaj funkcjonalności wymaga nieco więcej zasobów hosta niż typowy dziennik. -Nie każdy dostawca hostingu PHP-MySQL będzie w stanie obsługiwać $Projectname. Tak więc, przed instalacją zapoznaj się z wymaganiami i potwierdź je u dostawcy usług hostingowych. +$Projectname to więcej niż prosta aplikacja internetowa. Jest to złożony system komunikacyjny, który bardziej przypomina serwer poczty elektronicznej niż serwer WWW. Aby zapewnić niezawodność i wydajność, wiadomości są dostarczane w tle i umieszczane w kolejce do późniejszego dostarczenia, gdy lokacje są wyłączone. Ten rodzaj funkcjonalności wymaga nieco więcej zasobów hosta niż typowy dziennik. Nie każdy dostawca hostingu PHP-MySQL będzie w stanie obsługiwać $Projectname. Tak więc, przed instalacją zapoznaj się z wymaganiami i potwierdź je u dostawcy usług hostingowych. Bardzo staraliśmy się, aby Hubzilla działała na zwykłych platformach hostingowych, takich jak te używane do hostowania blogów Wordpress i stron internetowych Drupal. Będzie ona działać na większości systemów VPS Linux. Platformy Windows LAMP, takie jak XAMPP i WAMP, nie są obecnie oficjalnie obsługiwane, jednak mile widziane są poprawki, jeśli uda Ci się je uruchomić. @@ -17,50 +12,24 @@ Jeśli napotkasz problemy lub sam masz jakiś problem, które nie zostały opisa #### Wybierz nazwę domeny lub subdomeny dla swojego serwera -Platformę $Projectname można zainstalować tylko w katalogu głównym domeny lub -subdomeny i nie może ona działać na niestandardowych portach TCP. +Platformę $Projectname można zainstalować tylko w katalogu głównym domeny lub subdomeny i nie może ona działać na niestandardowych portach TCP. #### Zdecyduj, czy będziesz używać SSL i uzyskaj certyfikat SSL przed instalacją oprogramowania -POWINNO się używać SSL. Jeśli używasz SSL, MUSISZ użyć certyfikatu uznawanego -przez przeglądarki. **NIE WOLNO używać certyfikatów z podpisem własnym!** - -Przetestuj swój certyfikat przed instalacją. Narzędzie internetowe do testowania -certyfikatu jest dostępne pod adresem `http://www.digicert.com/help/`. -Odwiedzając witrynę po raz pierwszy, użyj adresu URL SSL (`https: //`), jeśli -protokół SSL jest dostępny. Pozwoli to uniknąć późniejszych problemów. Procedura -instalacji nie pozwoli na użycie certyfikatu, który nie jest zaufany dla przeglądarki. - -To ograniczenie zostało wprowadzone, ponieważ Twoje publiczne wpisy mogą zawierać -odniesienia do obrazów na Twoim hubie. Inni członkowie przeglądający swój strumień -w innych centrach otrzymają ostrzeżenia, jeśli Twój certyfikat nie jest zaufany -w ich przeglądarce internetowej. To zmyli wiele osób, ponieważ jest to -zdecentralizowana sieć i otrzymają ostrzeżenie o Twoim hubie podczas przeglądania -własnego huba i mogą pomyśleć, że ich własny hub ma problem. Te ostrzeżenia -są bardzo techniczne i przerażające dla niektórych osób, z których wielu nie -będzie wiedziało, jak postępować, z wyjątkiem przestrzegania zaleceń przeglądarki. -Jest to destrukcyjne dla społeczności. To powiedziawszy, zdajemy sobie sprawę z -problemów związanych z obecną infrastrukturą certyfikatów i zgadzamy się, że -istnieje wiele problemów, ale to nie zmienia wymagania. - -Bezpłatne certyfikaty zgodne z przeglądarkami są dostępne od dostawców, takich -jak StartSSL i LetsEncrypt. - -Jeśli NIE używasz SSL, może wystąpić opóźnienie do minuty dla startowego skryptu -instalacyjnego - podczas sprawdzania portu SSL, aby zobaczyć, czy tam jest wszystko -w porządku. Podczas komunikowania się z nowymi witrynami Hubzilla zawsze najpierw -próbuje połączyć się z portem SSL, zanim powróci do mniej bezpiecznego połączenia. -Jeśli nie używasz SSL, twój serwer WWW NIE MOŻE w ogóle nasłuchiwać na porcie 443. - -Jeśli używasz LetsEncrypt do dostarczania certyfikatów i tworzenia pliku pod -`well-known` lub `acme-challenge`, aby LetsEncrypt mógł zweryfikować własność -domeny, usuń lub zmień nazwę katalogu `.well-known` zaraz po wygenerowaniu -certyfikatu. $Projectname zapewni własną procedurę obsługi usług `.well-know` po -zainstalowaniu, a istniejący katalog w tej lokalizacji może uniemożliwić poprawne -działanie niektórych z tych usług. Nie powinno to stanowić problemu w przypadku -Apache, ale może to być problem z Nginx lub innymi platformami serwera internetowego. +POWINNO się używać SSL. Jeśli używasz SSL, MUSISZ użyć certyfikatu uznawanego przez przeglądarki. **NIE WOLNO używać certyfikatów z podpisem własnym!** + +Przetestuj swój certyfikat przed instalacją. Narzędzie internetowe do testowania certyfikatu jest dostępne pod adresem http://www.digicert.com/help/. Odwiedzając witrynę po raz pierwszy, użyj adresu URL SSL (https://), jeśli protokół SSL jest dostępny. Pozwoli to uniknąć późniejszych problemów. Procedura instalacji nie pozwoli na użycie certyfikatu, który nie jest zaufany dla przeglądarki. + +To ograniczenie zostało wprowadzone, ponieważ Twoje publiczne wpisy mogą zawierać odniesienia do obrazów na Twoim hubie. Inni członkowie przeglądający swój strumień w innych centrach otrzymają ostrzeżenia, jeśli Twój certyfikat nie jest zaufany w ich przeglądarce internetowej. To zmyli wiele osób, ponieważ jest to zdecentralizowana sieć i otrzymają ostrzeżenie o Twoim hubie podczas przeglądania własnego huba i mogą pomyśleć, że ich własny hub ma problem. Te ostrzeżenia są bardzo techniczne i przerażające dla niektórych osób, z których wielu nie będzie wiedziało, jak postępować, z wyjątkiem przestrzegania zaleceń przeglądarki. Jest to destrukcyjne dla społeczności. To powiedziawszy, zdajemy sobie sprawę z problemów związanych z obecną infrastrukturą certyfikatów i zgadzamy się, że istnieje wiele problemów, ale to nie zmienia wymagania. + +Bezpłatne certyfikaty zgodne z przeglądarkami są dostępne od dostawców, takich jak StartSSL i LetsEncrypt. + +Jeśli NIE używasz SSL, może wystąpić opóźnienie do minuty dla startowego skryptu instalacyjnego - podczas sprawdzania portu SSL, aby zobaczyć, czy tam jest wszystko w porządku. Podczas komunikowania się z nowymi witrynami Hubzilla zawsze najpierw próbuje połączyć się z portem SSL, zanim powróci do mniej bezpiecznego połączenia. Jeśli nie używasz SSL, twój serwer WWW NIE MOŻE w ogóle nasłuchiwać na porcie 443. + +Jeśli używasz LetsEncrypt do dostarczania certyfikatów i tworzenia pliku pod _well-known_ lub _acme-challenge_, aby LetsEncrypt mógł zweryfikować własność domeny, usuń lub zmień nazwę katalogu _.well-known_ zaraz po wygenerowaniu certyfikatu. $Projectname zapewni własną procedurę obsługi usług *.well-know* po zainstalowaniu, a istniejący katalog w tej lokalizacji może uniemożliwić poprawne działanie niektórych z tych usług. Nie powinno to stanowić problemu w przypadku Apache, ale może to być problem z Nginx lub innymi platformami serwera internetowego. ### Wdrożenie + Nowy hub można wdrożyć na kilka sposobów: * ręczna inastalaja na istniejącym serwerze; @@ -68,22 +37,15 @@ Nowy hub można wdrożyć na kilka sposobów: * automatyczne wdrożenie przy użyciu prywatnego serwera wirtualnego OpenShift (VPS).) ### Wymagania -* Apache z włączonym modułem `mod-rewrite` i ustawioną dyrektywą "AllowOverride - All", tak aby można było stosować plik `.htaccess`. Niektóre osoby z powodzeniem - stosowały Nginx czy Lighttpd.Przykładowe skrypty konfiguracyjne są dostępne na - tej platformie w [doc/install](). Apache and Nginx mają najlepsze wsparcie. + +* Apache z włączonym modułem _mod-rewrite_ i ustawioną dyrektywą "AllowOverride All", tak aby można było stosować plik _.htaccess_. Niektóre osoby z powodzeniem stosowały Nginx czy Lighttpd.Przykładowe skrypty konfiguracyjne są dostępne na tej platformie w [doc/install](). Apache and Nginx mają najlepsze wsparcie. * PHP 7.1 lub w wersji wyższej. - * _Proszę mieć na uwadze, że w niektórych środowiskach hostinu - współdzielonego, wersja wiersza poleceń PHP różni się od wersji - serwera internetowego_ + * _Proszę mieć na uwadze, że w niektórych środowiskach hostinu współdzielonego, wersja wiersza poleceń PHP różni się od wersji serwera internetowego_ -* Dostęp do wiersza poleceń PHP z ustawionym w pliku php.ini parametrem - `register_argc_argv` na `true` i bez ograniczeń dostawcy hostingu w zakresie - stosowania fumkcji `exec()` i `proc_open()`. +* Dostęp do wiersza poleceń PHP z ustawionym w pliku php.ini parametrem _register_argc_argv_ na true i bez ograniczeń dostawcy hostingu w zakresie stosowania funkcji _exec()_ i _proc_open()_. -* Rozszerzenia curl, gd (z obsługą co najmmniej jpeg i png), mysqli, mbstring, - mcrypt, zip i openssl. Tozszerzenie imagick nie jest wymagane ale jest zalecane. +* Rozszerzenia curl, gd (z obsługą co najmmniej jpeg i png), mysqli, mbstring, mcrypt, zip i openssl. Tozszerzenie imagick nie jest wymagane ale jest zalecane. * Wymagane jest rozszerzenie xml, jeśli chce sie mieć działajacą obsługę webdav. @@ -93,21 +55,15 @@ Nowy hub można wdrożyć na kilka sposobów: * Możliwość planowania zadań dla crona. -* WYMAGANA jest instalacja w katalogu głównym hosta WWW (wirtualnego hosta w - Apache i bloku w Nginx). +* WYMAGANA jest instalacja w katalogu głównym hosta WWW (wirtualnego hosta w Apache i bloku w Nginx). ### Instalacja ręczna ##### Krok 1. -Rozpakuj pliki $Projectname do katalogu głównego obszaru dokumentów serwera WWW. -Jeśli kopiujesz drzewo katalogów na swój serwer WWW, upewnij się, że dołączasz -ukryte pliki, takie jak `.htaccess`. +Rozpakuj pliki $Projectname do katalogu głównego obszaru dokumentów serwera WWW. Jeśli kopiujesz drzewo katalogów na swój serwer WWW, upewnij się, że dołączasz ukryte pliki, takie jak _.htaccess_. -Jeśli możesz to zrobić, zalecamy użycie Git do sklonowania repozytorium źródłowego -zamiast używania spakowanego pliku tar lub zip. To znacznie ułatwia późniejszą -aktualizację oprogramowania. Polecenie Linux do sklonowania repozytorium do katalogu -"mywebsite: wyglądałoby tak: +Jeśli możesz to zrobić, zalecamy użycie Git do sklonowania repozytorium źródłowego zamiast używania spakowanego pliku tar lub zip. To znacznie ułatwia późniejszą aktualizację oprogramowania. Polecenie Linux do sklonowania repozytorium do katalogu "mywebsite: wyglądałoby tak: git clone https://framagit.org/hubzilla/core.git mywebsite @@ -115,111 +71,71 @@ a następnie, w dowolnym momencie, możesz pobrać najnowsze zmiany za pomocą: git pull -upewnij się, że istniejeją foldery `store/[data]/smarty3` i `store` i że są -one możliwe do zapisu przez właściciela procesu serwera WWW: +upewnij się, że istniejeją foldery `store/[data]/smarty3` i `store` i że są one możliwe do zapisu przez właściciela procesu serwera WWW: mkdir -p "store/[data]/smarty3" chmod -R 777 store -To uprawnienie (777) jest bardzo niebezpieczne i jeśli masz wystarczające -uprawnienia i wiedzę powinieneś umożliwić zapisywanie w tych katalogach tylko -przez serwer WWW i użytkownika, który uruchomia crona (patrz poniżej), jeśli jest -taki. W wielu współdzielonych środowiskach hostingowych może to być trudne, bez -zgłoszenia problemu u dostawcy. Powyższe uprawnienia pozwolą oprogramowaniu -działać, ale nie są optymalne. +To uprawnienie (777) jest bardzo niebezpieczne i jeśli masz wystarczające uprawnienia i wiedzę powinieneś umożliwić zapisywanie w tych katalogach tylko przez serwer WWW i użytkownika, który uruchomia crona (patrz poniżej), jeśli jest taki. W wielu współdzielonych środowiskach hostingowych może to być trudne, bez zgłoszenia problemu u dostawcy. Powyższe uprawnienia pozwolą oprogramowaniu działać, ale nie są optymalne. -Aby działały niektóre internetowe narzędzia administracyjne, serwer WWW musi mieć -możliwość zapisu w następujących katalogach: +Aby działały niektóre internetowe narzędzia administracyjne, serwer WWW musi mieć możliwość zapisu w następujących katalogach: -* `addon` -* `extend` -* `view/theme` -* `widget` +* _addon_ +* _extend_ +* _view/theme_ +* _widget_ ##### Krok 2. -Utwórz pustą bazę danych i zanotuj szczegóły dostępu (nazwa hosta, nazwa -użytkownika, hasło, nazwa bazy danych). Biblioteki bazy danych PDO powracają do -komunikacji przez gniazdo uniksowe, gdy nazwą hosta jest `localhost`, ale -niektóre osoby zgłosiły problemy z implementacją gniazda. Użyj gniazd, jeśli -Twoje uprawnienia na to pozwalają. W przeciwnym razie, jeśli baza danych jest -udostępniana na hoście `localhost`, jako nazwę hosta wpisz `127.0.0.1`. +Utwórz pustą bazę danych i zanotuj szczegóły dostępu (nazwa hosta, nazwa użytkownika, hasło, nazwa bazy danych). Biblioteki bazy danych PDO powracają do komunikacji przez gniazdo uniksowe, gdy nazwą hosta jest _localhost_, ale niektóre osoby zgłosiły problemy z implementacją gniazda. Użyj gniazd, jeśli Twoje uprawnienia na to pozwalają. W przeciwnym razie, jeśli baza danych jest udostępniana na hoście _localhost_, jako nazwę hosta wpisz _127.0.0.1_. -Wewnętrznie używamy teraz biblioteki PDO do połączeń z bazą danych. Jeśli masz -do czynienia z konfigyracją bazy danych, którą nie możesz obsłużyć poprzez -formularz konfiguracyjny (ma przykład w przypadku uzywania MySQL z nietypową -lokalizacją gniazd) - możesz podać ciąg połączenia PDO jako nazwę hosta. -Na przykład: +Wewnętrznie używamy teraz biblioteki PDO do połączeń z bazą danych. Jeśli masz do czynienia z konfigyracją bazy danych, którą nie możesz obsłużyć poprzez formularz konfiguracyjny (ma przykład w przypadku uzywania MySQL z nietypową lokalizacją gniazd) - możesz podać ciąg połączenia PDO jako nazwę hosta. Na przykład: :/path/to/socket.file -W razie potrzeby nadal trzeba wypełnić w formularzu konfiguracyjnym wszystkie -inne wartości mające zastosowanie. +W razie potrzeby nadal trzeba wypełnić w formularzu konfiguracyjnym wszystkie inne wartości mające zastosowanie. ##### Krok 3. -Utwórz pusty plik o nazwie `.htconfig.php` i uczyń go możliwymm do zapisania -przez serwer WWW. Krok ten wykonaj, jeśli wiesz, że serwer WWW nie będzie -mógł sam utworzyć tego pliku. +Utwórz pusty plik o nazwie _.htconfig.php_ i uczyń go możliwymm do zapisania przez serwer WWW. Krok ten wykonaj, jeśli wiesz, że serwer WWW nie będzie mógł sam utworzyć tego pliku. ##### Krok 4. -Odwiedź swoją witrynę za pomocą przeglądarki internetowej i postępuj zgodnie z -instrukcjami. Zanotuj wszelkie komunikaty o błędach i popraw je przed -kontynuowaniem. Jeśli używasz protokołu SSL (od znanego urzędu autoryzacyjnego), -użyj schematu `https` w adresie URL swojej witryny. +Odwiedź swoją witrynę za pomocą przeglądarki internetowej i postępuj zgodnie z instrukcjami. Zanotuj wszelkie komunikaty o błędach i popraw je przed kontynuowaniem. Jeśli używasz protokołu SSL (od znanego urzędu autoryzacyjnego), użyj schematu _https_ w adresie URL swojej witryny. ##### Krok 5. -Jeśli automatyczna instalacja nie powiedzie się z jakiegoś powodu, -sprawdź następujące rzeczy: +Jeśli automatyczna instalacja nie powiedzie się z jakiegoś powodu, sprawdź następujące rzeczy: -* Czy istnieje plik `.htconfig.php`? Jeśli nie, edytuj plik `htconfig.php` - i zmień w nim ustawienia systemowe. Następnie zmień jego nazwę na .htconfig.php. -* Czy baza danych jest wypełniona. Jeśli nie, zaimportuj treść skryptu - `install/schema_xxxxx.sql` w phpmyadmin lub wierszu poleceń mysql (zamień - 'xxxxx' na własciwy typ bazy danych). +* Czy istnieje plik _.htconfig.php_? Jeśli nie, edytuj plik _htconfig.php_ i zmień w nim ustawienia systemowe. Następnie zmień jego nazwę na _.htconfig.php_. +* Czy baza danych jest wypełniona. Jeśli nie, zaimportuj treść skryptu _install/schema_xxxxx.sql_ w phpmyadmin lub wierszu poleceń mysql (zamień 'xxxxx' na własciwy typ bazy danych). ##### Krok 6. -Po udanej instalacji odwiedż ponownie swoją witrynę i zarejestruj swoje osobiste -konto. Błędy rejestracji powinny dać sie naprawić automatycznie. +Po udanej instalacji odwiedż ponownie swoją witrynę i zarejestruj swoje osobiste konto. Błędy rejestracji powinny dać sie naprawić automatycznie. -Jeśli w tym momencie wystąpiła jakakolwiek *krytyczna* awaria, to na ogół -przyczyna leży w źle funkcjonującej bazie danych. W takim przypadku, aby zacząć -od nowa, usuń lub zmień nazwę pliku `.htconfig.php` i usuń tabele bazy danych. +Jeśli w tym momencie wystąpiła jakakolwiek *krytyczna* awaria, to na ogół przyczyna leży w źle funkcjonującej bazie danych. W takim przypadku, aby zacząć od nowa, usuń lub zmień nazwę pliku _.htconfig.php_ i usuń tabele bazy danych. -Aby Twoje konto miało dostęp administratora, powinno to być utworzone jako -pierwsze, a adres e-mail podany podczas rejestracji musi być zgodny z adresem -administratora podanym podczas instalacji. Jeśli stało sie inaczej, aby dać -dostęp administracyjny jakiemuś kontu, dodaj `4096` w rekordzie tabeli -`account_roles` tego konta. +Aby Twoje konto miało dostęp administratora, powinno to być utworzone jako pierwsze, a adres e-mail podany podczas rejestracji musi być zgodny z adresem administratora podanym podczas instalacji. Jeśli stało sie inaczej, aby dać dostęp administracyjny jakiemuś kontu, dodaj _4096_ w rekordzie tabeli _account_roles_ tego konta. -Ze względu na bezpieczeństwo witryny, nie ma możliwości zapewnienia dostępu -administracyjnego za pomocą formularzy konfiguracyjnych. +Ze względu na bezpieczeństwo witryny, nie ma możliwości zapewnienia dostępu administracyjnego za pomocą formularzy konfiguracyjnych. ##### Krok 7. BARDZO WAŻNY! -Skonfiguruj zadanie Crona lub *zadanie zaplanowane*, tak aby uruchamiać menedżera -Crona co 10-15 minut w celu przetwarzania i konserwacji w tle. Przykład: +Skonfiguruj zadanie Crona lub *zadanie zaplanowane*, tak aby uruchamiać menedżera Crona co 10-15 minut w celu przetwarzania i konserwacji w tle. Przykład: cd /base/directory; /path/to/php Zotlabs/Daemon/Master.php Cron Zmień tutaj `/base/directory` i `/path/to/php` na właściwe dla siebie ścieżki. -Jeśli używasz serwera linuksowego, uruchom polecenie `crontab -e` i dodaj wiersz -taki jak poniżej, zmieniając odpowiednio ścieżki i ustawienia: +Jeśli używasz serwera linuksowego, uruchom polecenie `crontab -e` i dodaj wiersz taki jak poniżej, zmieniając odpowiednio ścieżki i ustawienia: */10 * * * * cd /home/myname/mywebsite; /usr/bin/php Zotlabs/Daemon/Master.php Cron > /dev/null 2>&1 -Lokalizację PHP na ogół można ustalić wykonując polecenie `which php`. Jeśli -masz problemy z ustawienie Crona, skontaktuj się z dostawcą hostingu w celu -uzyskania pomocy. Hubzilla nie będzie działać prawidłowo bez tego kroku. +Lokalizację PHP na ogół można ustalić wykonując polecenie _which php_. Jeśli masz problemy z ustawienie Crona, skontaktuj się z dostawcą hostingu w celu uzyskania pomocy. Hubzilla nie będzie działać prawidłowo bez tego kroku. -Powinno się również sprawdzić ustawienie parametru -`App::$config['system']['php_path']` w pliku `.htconfig.php`. -Powinno to wyglądać tak (zmień to zgodnie z lokalizacją PHP w swoim systemie): +Powinno się również sprawdzić ustawienie parametru _App::$config['system']['php_path']_ w pliku _.htconfig.php_. Powinno to wyglądać tak (zmień to zgodnie z lokalizacją PHP w swoim systemie): App::$config['system']['php_path'] = '/usr/local/php56/bin/php'; @@ -228,39 +144,30 @@ Powinno to wyglądać tak (zmień to zgodnie z lokalizacją PHP w swoim systemie ##### Instalacja -Przejdź do swojej witryny. Następnie sklonuj repozytorium dodatków (osobno). -Nadamy temu repozytorium pseudonim `hzaddons`. Możesz pobrać inne repozytoria -dodatków Hubzilla, nadając im różne pseudonimy: +Przejdź do swojej witryny. Następnie sklonuj repozytorium dodatków (osobno). Nadamy temu repozytorium pseudonim `hzaddons`. Możesz pobrać inne repozytoria dodatków Hubzilla, nadając im różne pseudonimy: cd mywebsite util/add_addon_repo https://framagit.org/hubzilla/addons.git hzaddons ##### Aktualizacja -W celu aktualizacji drzewa dodatków, powinno się, z poziomu głównego katalogu -witryny, wydać polecenie aktualizacji tego repozytorium: +W celu aktualizacji drzewa dodatków, powinno się, z poziomu głównego katalogu witryny, wydać polecenie aktualizacji tego repozytorium: cd mywebsite util/update_addon_repo hzaddons -Stwórz reprezentację dokumentacji online z możliwością wyszukiwania. Możesz to -zrobić za każdym razem, gdy dokumentacja jest aktualizowana: +Stwórz reprezentację dokumentacji online z możliwością wyszukiwania. Możesz to zrobić za każdym razem, gdy dokumentacja jest aktualizowana: cd mywebsite util/importdoc ### Automatyczna instalacja poprzez skrypt .homeinstall -Istnieje skrypt powłoki `.homeinstall/hubzilla-setup.sh`, który po -uruchomieniu zainstaluje Hubzillę i jego zależności na nowej instalacji stabilnej -dystrybucji Debiana 9 (Stetch). Powinien działać na podobnych systemach Linux, -ale wyniki mogą się różnić. +Istnieje skrypt powłoki _.homeinstall/hubzilla-setup.sh_, który po uruchomieniu zainstaluje Hubzillę i jego zależności na nowej instalacji stabilnej dystrybucji Debiana 9 (Stetch). Powinien działać na podobnych systemach Linux, ale wyniki mogą się różnić. #### Wymagania -Skrypt instalacyjny został pierwotnie zaprojektowany dla małego serwera -sprzętowego za routerem domowym. Jednak został przetestowany też na kilku -systemach z Debian 9: +Skrypt instalacyjny został pierwotnie zaprojektowany dla małego serwera sprzętowego za routerem domowym. Jednak został przetestowany też na kilku systemach z Debian 9: * Home-PC (Debian-9.2-amd64) i Rapberry-Pi 3 (Rasbian = Debian 9.3) * Połączenie z Internetem i domowy router @@ -270,14 +177,15 @@ systemach z Debian 9: * Router z otwartymi portami 80 i 443 dla Debiana #### Etapy instalacji -1. `apt-get install git` -1. `mkdir -p /var/www/html` -1. `cd /var/www/html` -1. `git clone https://framagit.org/hubzilla/core.git .` -1. `nano .homeinstall/hubzilla-config.txt` -1. `cd .homeinstall/` -1. `./hubzilla-setup.sh` -1. `service apache2 reload` + +1. _apt-get install git_ +1. _mkdir -p /var/www/html_ +1. _cd /var/www/html_ +1. _git clone https://framagit.org/hubzilla/core.git ._ +1. _nano .homeinstall/hubzilla-config.txt_ +1. _cd .homeinstall/_ +1. _./hubzilla-setup.sh_ +1. _service apache2 reload_ 1. Open your domain with a browser and step throught the initial configuration of $Projectname. ### Zalecane dodatki @@ -289,31 +197,15 @@ Zalecamy zainstalowanie następujących dodatków we wszystkich publicznych witr ### Dodatki federacyjne -Kilka społeczności internetowych zaczęło łączyć się przy użyciu wspólnych -protokołów. Stosowane protokoły mają nieco ograniczone możliwości. Na przykład -protokół GNU-Social nie oferuje żadnych trybów prywatności, a protokół Diaspora -jest nieco bardziej restrykcyjny w zakresie dozwolonych rodzajów komunikacji. -Wszystkie komentarze muszą być podpisane w bardzo unikalny sposób przez -oryginalnego autora. Rozważany jest również protokół ActivityPub, który może być -obsługiwany w przyszłości. Żaden inny istniejący protokół nie obsługuje -lokalizacji nomadycznej używanej w tym projekcie. Stwarza to pewne problemy z -obsługą, ponieważ niektóre funkcje działają w niektórych sieciach, a w innych nie. -Niemniej jednak protokoły federacyjne umożliwiają nawiązywanie połączeń ze znacznie -większą społecznością ludzi na całym świecie. Są dostarczane jako dodatki. - -* _diaspora_ - protokół diaspory używany przez Diasporę i Friendica. Najpierw - należy włączyć „Diaspora Statistics” (statystyki), aby włączyć wszystkie - dostępne funkcje. - -* _gnusoc_ - protokół społecznościowy GNU, używany przez GNU-Social, Mastodon i - kilka innych społeczności. Ten dodatek wymaga najpierw zainstalowania usługi - `pubsubhubbub` (także dodatku). - -Każdy członek Twojej siatki musi indywidualnie zdecydować, czy zezwolić na te -protokoły, ponieważ mogą one kolidować z kilkoma pożądanymi podstawowymi funkcjami -i możliwościami Hubzilla (takimi jak migracja kanałów i klonowanie). Robi się to -na swojej stronie _Ustawienia_ -> _Ustawienia funkcji i dodatków_. Administrator -może również ustawić: +Kilka społeczności internetowych zaczęło łączyć się przy użyciu wspólnych protokołów. Stosowane protokoły mają nieco ograniczone możliwości. Na przykład protokół GNU-Social nie oferuje żadnych trybów prywatności, a protokół Diaspora +jest nieco bardziej restrykcyjny w zakresie dozwolonych rodzajów komunikacji. Wszystkie komentarze muszą być podpisane w bardzo unikalny sposób przez oryginalnego autora. Rozważany jest również protokół ActivityPub, który może być obsługiwany w przyszłości. Żaden inny istniejący protokół nie obsługuje lokalizacji nomadycznej używanej w tym projekcie. Stwarza to pewne problemy z obsługą, ponieważ niektóre funkcje działają w niektórych sieciach, a w innych nie. Niemniej jednak protokoły federacyjne umożliwiają nawiązywanie połączeń ze znacznie większą społecznością ludzi na całym świecie. Są dostarczane jako dodatki. + +* _diaspora_ - protokół diaspory używany przez Diasporę i Friendica. Najpierw należy włączyć „Diaspora Statistics” (statystyki), aby włączyć wszystkie dostępne funkcje. + +* _gnusoc_ - protokół społecznościowy GNU, używany przez GNU-Social, Mastodon i kilka innych społeczności. Ten dodatek wymaga najpierw zainstalowania usługi _pubsubhubbub_ (także dodatku). + +Każdy członek Twojej siatki musi indywidualnie zdecydować, czy zezwolić na te protokoły, ponieważ mogą one kolidować z kilkoma pożądanymi podstawowymi funkcjami i możliwościami Hubzilla (takimi jak migracja kanałów i klonowanie). Robi się to +na swojej stronie _Ustawienia_ -> _Ustawienia funkcji i dodatków_. Administrator może również ustawić: util/config system.diaspora_allowed 1 util/config system.gnusoc_allowed 1 @@ -322,11 +214,7 @@ i włączać te protokoły automatycznie dla wszystkich nowo tworzonych kanałó ### Klasy usług -Klasy usług pozwalają na ustawienie limitów zasobów systemowych poprzez -ograniczenie tego, co mogą robić poszczególne konta, w tym przechowywania plików -i najwyższych limitów wpisów. Zdefiniuj niestandardowe klasy usług zgodnie ze -swoimi potrzebami w pliku `.htconfig.php`. Na przykład utwórz klasę standard -i premium, używając następujących wierszy: +Klasy usług pozwalają na ustawienie limitów zasobów systemowych poprzez ograniczenie tego, co mogą robić poszczególne konta, w tym przechowywania plików i najwyższych limitów wpisów. Zdefiniuj niestandardowe klasy usług zgodnie ze swoimi potrzebami w pliku _.htconfig.php_. Na przykład utwórz klasę standard i premium, używając następujących wierszy: // Service classes @@ -352,49 +240,48 @@ i premium, używając następujących wierszy: 'attach_upload_limit' =>20000000000, // total attachment storage limit per channel (here 20GB) 'chatters_inroom' =>100); -Aby zastosować klasę usług do istniejącego konta, użyj narzędzia wiersza poleceń -z katalogu głównego instalacji Hubzilla: +Aby zastosować klasę usług do istniejącego konta, użyj narzędzia wiersza poleceń z katalogu głównego instalacji Hubzilla: * uzyskanie listy klas usług: util/service_class -* ustawienie domyślnej klasy usług na `firstclass`: +* ustawienie domyślnej klasy usług na _firstclass_: util/config system default_service_class firstclass -* uzyskanie listy usług, które należą do klasy `firstclass`: +* uzyskanie listy usług, które należą do klasy _firstclass_: util/service_class firstclass -* ustawienie całkowitego użycia dysku ze zdjęciami `firstclass` na 10 milionów bajtów +* ustawienie całkowitego użycia dysku ze zdjęciami _firstclass_ na 10 milionów bajtów util/service_class firstclass photo_upload_limit 10000000 -* ustawienie konta z identyfikatorem 5 na klasę `firstclass` (z potwierdzeniem): +* ustawienie konta z identyfikatorem 5 na klasę _firstclass_ (z potwierdzeniem): util/service_class --account=5 firstclass -* ustawienie konta, które jest właścicielem kanału `bdziennikchan` na klasę `firstclass` (z potwierdzeniem) +* ustawienie konta, które jest właścicielem kanału `bdziennikchan` na klasę _firstclass_ (z potwierdzeniem) util/service_class --channel=bdziennikchan firstclass -**Service class limit options** +**Opcje limitu klas usług** ##### Opcje limitów klas usług: -* `photo_upload_limit` - maksymalna łączna liczba bajtów na zdjęcia -* `total_items` - maksymalna liczba wpisów na najwyższym poziomie -* `total_pages` - maksymalna liczba stron comanche -* `total_identities` - maksymalna liczba kanałów posiadanych na koncie -* `total_channels` - maksymalna liczba kanałów -* `total_feeds` - maksymalna liczba kanałów RSS -* `attach_upload_limit` - maksymalna pojemność przesyłania plików (w bajtach) -* `minimum_feedcheck_minutes` - najniższe ustawienie dozwolone dla odpytywania kanałów RSS -* `chatrooms` - maksymalna liczba czatów -* `chatters_inroom` - maksymalna liczba rozmówców w czacie -* `access_tokens` - maksymalna liczba tokenów dostępu gościa na kanał +* _photo_upload_limit_ - maksymalna łączna liczba bajtów na zdjęcia +* _total_items_ - maksymalna liczba wpisów na najwyższym poziomie +* _total_pages_ - maksymalna liczba stron comanche +* _total_identities_ - maksymalna liczba kanałów posiadanych na koncie +* _total_channels_ - maksymalna liczba kanałów +* _total_feeds_ - maksymalna liczba kanałów RSS +* _attach_upload_limit_ - maksymalna pojemność przesyłania plików (w bajtach) +* _minimum_feedcheck_minutes_ - najniższe ustawienie dozwolone dla odpytywania kanałów RSS +* _chatrooms_ - maksymalna liczba czatów +* _chatters_inroom_ - maksymalna liczba rozmówców w czacie +* _access_tokens_ - maksymalna liczba tokenów dostępu gościa na kanał ### Zarządzanie motywami @@ -421,15 +308,11 @@ z katalogu głównego instalacji Hubzilla: #### Słowa kluczowe -Na stronie katalogu kanałów może pojawiać się „chmura tagów” słów kluczowych. -Jeśli chcesz ukryć te słowa kluczowe, które są pobierane z serwera katalogów, -możesz użyć narzędzia `config`: +Na stronie katalogu kanałów może pojawiać się chmura słów kluczowych. Jeśli chcesz ukryć te słowa kluczowe, które są pobierane z serwera katalogów, możesz użyć narzędzia _config_: util/config system disable_directory_keywords 1 -Jeśli twój hub pracuje w trybie autonomicznym, ponieważ nie chcesz łączyć się -z globalną siecią, możesz zamiast tego ustawić opcję systemową `directory_server` -na wartość pustą: +Jeśli twój hub pracuje w trybie autonomicznym, ponieważ nie chcesz łączyć się z globalną siecią, możesz zamiast tego ustawić opcję systemową _directory_server_ na wartość pustą: util/config system directory_server "" @@ -437,131 +320,53 @@ na wartość pustą: #### Administrowanie witryną -Administracja witryną jest zwykle wykonywana za pośrednictwem strony administratora -znajdującej się na ścieżce `/admin` adresu URL Twojej witryny. Aby uzyskać dostęp -do tej strony, trzeba mieć uprawnienia administratora na serwerze. Prawa -administracyjne są przyznawane pierwszemu kontu, które zostało zarejestrowane w -witrynie, pod warunkiem, że adres e-mail tego konta dokładnie odpowiada adresowi -e-mail podanemu jako adres e-mail administratora podczas konfiguracji. - -Istnieje kilka sposobów, w jakie może to się nie powieść i pozostawić system bez -konta administratora, na przykład jeśli pierwsze konto, które zostało utworzone, -miało inny adres e-mail niż adres e-mail administratora, który został podany -podczas konfiguracji. - -Ze względów bezpieczeństwa w systemie nie ma strony internetowej ani interfejsu, -który daje dostęp administratora. Jeśli potrzebujesz poprawić sytuację, w której -system nie ma konta administratora, musisz to zrobić edytując tabelę kont w bazie -danych. Nie ma innego wyjścia. Aby to zrobić, będziesz musiał zlokalizować wpis -w tabeli kont, który należy do żądanego administratora i ustawić `account_roles` -dla tego wpisu na `4096`. Będziesz wtedy mógł uzyskać dostęp do strony -administratora z menu profilu twojego systemu lub bezpośrednio na ścieżce `/admin`. - -Hub może mieć wielu administratorów i nie ma ograniczeń co do ich liczby. -Powtórz powyższą procedurę dla każdego konta, któremu chcesz przyznać uprawnienia -administracyjne. +Administracja witryną jest zwykle wykonywana za pośrednictwem strony administratora znajdującej się na ścieżce _/admin_ adresu URL Twojej witryny. Aby uzyskać dostęp do tej strony, trzeba mieć uprawnienia administratora na serwerze. Prawa administracyjne są przyznawane pierwszemu kontu, które zostało zarejestrowane w witrynie, pod warunkiem, że adres e-mail tego konta dokładnie odpowiada adresowi e-mail podanemu jako adres e-mail administratora podczas konfiguracji. + +Istnieje kilka sposobów, w jakie może to się nie powieść i pozostawić system bez konta administratora, na przykład jeśli pierwsze konto, które zostało utworzone, miało inny adres e-mail niż adres e-mail administratora, który został podany podczas konfiguracji. + +Ze względów bezpieczeństwa w systemie nie ma strony internetowej ani interfejsu, który daje dostęp administratora. Jeśli potrzebujesz poprawić sytuację, w której system nie ma konta administratora, musisz to zrobić edytując tabelę kont w bazie danych. Nie ma innego wyjścia. Aby to zrobić, będziesz musiał zlokalizować wpis w tabeli kont, który należy do żądanego administratora i ustawić _account_roles_ dla tego wpisu na _4096_. Będziesz wtedy mógł uzyskać dostęp do strony administratora z menu profilu twojego systemu lub bezpośrednio na ścieżce _/admin_. + +Hub może mieć wielu administratorów i nie ma ograniczeń co do ich liczby. Powtórz powyższą procedurę dla każdego konta, któremu chcesz przyznać uprawnienia administracyjne. ### Rozwiązywanie problemów #### Pliki dzienników -Plik dziennika systemowego jest niezwykle przydatnym źródłem informacji do -śledzenia błędów. Można to włączyć na stronie konfiguracji `admin/dziennik`. -Ustawienie poziomu o wartości `dziennikGER_DEBUG` jest preferowany w stabilnej -instalacji produkcyjnej. Większość problemów związanych z komunikacją lub -przechowywaniem jest tutaj wymieniona. Ustawienie na `dziennikGER_DATA` -zapewnia znacznie więcej szczegółów, ale może wypełnić dysk. W obu przypadkach -zalecamy użycie `dziennikrotate` w systemie operacyjnym do cyklicznego tworzenia -dzienników i usuwania starszych wpisów. - -Na dole twojego `.htconfig.php` znajduje się kilka linii (zakomentowanych), -które umożliwiają rejestrowanie błędów PHP. Zgłaszane są problemy ze składnią i -wykonywaniem kodu i jest to też pierwszym miejscem, w którym należy szukać -problemów, które powodują "biały ekran" lub pustą stronę. Zwykle jest to wynikiem -problemów z kodem lub składnią. Błędy bazy danych są zgłaszane do pliku dziennika -systemowego, ale uznaliśmy, że przydatne jest umieszczenie w katalogu najwyższego -poziomu pliku `dbfail.out`, który gromadzi tylko informacje o problemach -związanych z bazą danych. Jeśli plik istnieje i można go zapisać, będą rejestrowane -w nim błędy bazy danych, a także w pliku dziennika systemowego. - -W przypadku błędów "500: problemy mogą być często rejestrowane w dziennikach -serwera internetowego, często w `/var/dziennik/apache2/error.dziennik` lub -podobnym. Zapoznaj się z dokumentacją systemu operacyjnego. +Plik dziennika systemowego jest niezwykle przydatnym źródłem informacji do śledzenia błędów. Można to włączyć na stronie konfiguracji _admin/log_. Ustawienie poziomu o wartości *LOGGER_DEBUG* jest preferowany w stabilnej instalacji produkcyjnej. Większość problemów związanych z komunikacją lub przechowywaniem jest tutaj wymieniona. Ustawienie na *LOGGER_DATA* zapewnia znacznie więcej szczegółów, ale może wypełnić dysk. W obu przypadkach zalecamy użycie *logrotate* w systemie operacyjnym do cyklicznego tworzenia dzienników i usuwania starszych wpisów. + +Na dole twojego *.htconfig.php* znajduje się kilka linii (zakomentowanych), które umożliwiają rejestrowanie błędów PHP. Zgłaszane są problemy ze składnią i wykonywaniem kodu i jest to też pierwszym miejscem, w którym należy szukać problemów, które powodują "biały ekran" lub pustą stronę. Zwykle jest to wynikiem problemów z kodem lub składnią. Błędy bazy danych są zgłaszane do pliku dziennika systemowego, ale uznaliśmy, że przydatne jest umieszczenie w katalogu najwyższego poziomu pliku *dbfail.out*, który gromadzi tylko informacje o problemach związanych z bazą danych. Jeśli plik istnieje i można go zapisać, będą rejestrowane w nim błędy bazy danych, a także w pliku dziennika systemowego. + +W przypadku błędów "500: problemy mogą być często rejestrowane w dziennikach serwera internetowego, często w */var/log/apache2/error.log* lub podobnym. Zapoznaj się z dokumentacją systemu operacyjnego. Istnieją trzy różne obiekty dziennika. -**Pierwsza to dziennik błędów bazy danych**. Jest on używane tylko wtedy, gdy -tworzy ssię plik o specyficznej nazwie `dbfail.out` w folderze głównym swojej -witryny i pozwala się na zapisywanie w nim przez serwer WWW. Jeśli masz -jakiekolwiek zapytania do bazy danych, które nie powiodły się, wszystkie są -zgłaszane tutaj. Zwykle wskazują na literówki w naszych zapytaniach, ale występują -również w przypadku rozłączenia serwera bazy danych lub uszkodzenia tabel. -W rzadkich przypadkach zobaczymy tutaj warunki wyścigu, w których dwa procesy -próbowały utworzyć wpis `xchan` lub `cache`z tym samym identyfikatorem. Należy -zbadać wszelkie inne błędy (zwłaszcza błędy uporczywe). - -**Drugi to dziennik błędów PHP**. Jest tworzony przez procesor języka i zgłasza -tylko problemy powstałe w środowisku językowym. Znowu mogą to być błędy składniowe -lub błędy programistyczne, ale generalnie są one fatalne i skutkują "białym ekranem"; -na przykład PHP kończy działanie. Prawdopodobnie powinieneś zajrzeć do tego pliku -też, jeśli coś pójdzie nie tak, co nie powoduje białego ekranu. Często zdarza się, -że plik ten jest pusty przez wiele dni. - -Na dole dostarczonego pliku `.htconfig.php` znajduje się kilka linii, które, -jeśli nie są zakomentowane, włączają dziennik PHP (niezwykle przydatny do -znajdowania źródła błędów białego ekranu). Nie jest to robione domyślnie ze względu -na potencjalne problemy z własnością pliku dziennika i uprawnieniami do zapisu -oraz fakt, że domyślnie nie ma rotacji pliku dziennika. - -**Trzeci to "dziennik aplikacji"**. Jest to używane przez Hubzillę do zgłaszania -tego, co dzieje się w programie i zwykle zapisywane są tu wszelkie trudności lub -nieoczekiwane dane, które otrzymaliśmy. Czasami zgłasza się tu również komunikaty -o stanie "pulsu", aby wskazać, że osiągnęliśmy określony punkt w skrypcie. Jest -to dla nas najważniejszy plik dziennika, ponieważ tworzymy go samodzielnie -wyłącznie w celu zgłaszania stanu zadań w tle i wszystkiego, co wydaje się dziwne -lub nie na miejscu. To może nie być śmiertelne, ale może po prostu nieoczekiwane. -Jeśli wykonujesz zadanie i występuje problem, daj nam znać, co znajduje się w tym -pliku, gdy wystąpił problem. Proszę nie wysyłaj mi 100 milionów zrzutów, tylko -mnie wkurzysz! Tylko kilka odpowiednich wierszy, abym mógł wykluczyć kilkaset -tysięcy wierszy kodu i skoncentrować się na tym, gdzie zaczyna się pojawiać -problem. - -To są dzienniki Twojej witryny, a nie moje. Zgłaszamy poważne problemy na każdym -poziomie dziennika. Gorąco polecam poziom dziennika `DEBUG` dla większości witryn. -Dostarcza on trochę dodatkowych informacji i nie tworzy dużych plików dziennika. -Kiedy pojawia się problem, który uniemożliwia wszelkie próby śledzenia, możesz -wtedy włączyć na krótki czas poziom `DATA`, aby uchwycić wszystkie szczegóły -struktur, z którymi mieliśmy do czynienia w tym czasie. Ten poziom dziennika -zajmuje dużo miejsca, więc jest zalecany tylko na krótkie okresy lub w przypadku -witryn testowych dla programistów. - -Zalecam skonfigurowanie `logrotate` zarówno dla dziennika php, jak i dziennika -aplikacji. Zazwyczaj co tydzień lub dwa zaglądam do `dbfail.out`, naprawiam -zgłoszone problemy i zaczynam od nowego pliku. Podobnie jest z plikiem dziennika -PHP. Odwołuję się do tego od czasu do czasu, aby sprawdzić, czy jest coś, co -wymaga naprawy. - -Jeśli coś pójdzie nie tak i nie jest to błąd krytyczny, patrzę na plik dziennika -aplikacji. Często robię to: +**Pierwsza to dziennik błędów bazy danych**. Jest on używane tylko wtedy, gdy tworzy się plik o specyficznej nazwie *dbfail.out* w folderze głównym swojej witryny i pozwala na zapisywanie w nim przez serwer WWW. Jeśli masz jakiekolwiek zapytania do bazy danych, które nie powiodły się, wszystkie są zgłaszane tutaj. Zwykle wskazują na literówki w naszych zapytaniach, ale występują również w przypadku rozłączenia serwera bazy danych lub uszkodzenia tabel. W rzadkich przypadkach zobaczymy tutaj warunki wyścigu, w których dwa procesy próbowały utworzyć wpis *xchan* lub *cache* z tym samym identyfikatorem. Należy zbadać wszelkie inne błędy (zwłaszcza błędy uporczywe). + +**Drugi to dziennik błędów PHP**. Jest tworzony przez procesor języka i zgłasza tylko problemy powstałe w środowisku językowym. Znowu mogą to być błędy składniowe lub błędy programistyczne, ale generalnie są one fatalne i skutkują "białym ekranem"; +na przykład PHP kończy działanie. Prawdopodobnie powinieneś zajrzeć do tego pliku też, jeśli coś pójdzie nie tak, co nie powoduje białego ekranu. Często zdarza się, że plik ten jest pusty przez wiele dni. + +Na dole dostarczonego pliku *.htconfig.php* znajduje się kilka linii, które, jeśli nie są zakomentowane, włączają dziennik PHP (niezwykle przydatny do znajdowania źródła błędów białego ekranu). Nie jest to robione domyślnie ze względu na potencjalne problemy z własnością pliku dziennika i uprawnieniami do zapisu oraz fakt, że domyślnie nie ma rotacji pliku dziennika. + +**Trzeci to "dziennik aplikacji"**. Jest to używane przez Hubzillę do zgłaszania tego, co dzieje się w programie i zwykle zapisywane są tu wszelkie trudności lub nieoczekiwane dane, które otrzymaliśmy. Czasami zgłasza się tu również komunikaty +o stanie "pulsu", aby wskazać, że osiągnęliśmy określony punkt w skrypcie. Jest to dla nas najważniejszy plik dziennika, ponieważ tworzymy go samodzielnie wyłącznie w celu zgłaszania stanu zadań w tle i wszystkiego, co wydaje się dziwne lub nie na miejscu. To może nie być śmiertelne, ale może po prostu nieoczekiwane. Jeśli wykonujesz zadanie i występuje problem, daj nam znać, co znajduje się w tym pliku, gdy wystąpił problem. Proszę nie wysyłaj mi 100 milionów zrzutów, tylko mnie wkurzysz! Tylko kilka odpowiednich wierszy, abym mógł wykluczyć kilkaset tysięcy wierszy kodu i skoncentrować się na tym, gdzie zaczyna się pojawiać problem. + +To są dzienniki Twojej witryny, a nie moje. Zgłaszamy poważne problemy na każdym poziomie dziennika. Gorąco polecam poziom dziennika *DEBUG* dla większości witryn. Dostarcza on trochę dodatkowych informacji i nie tworzy dużych plików dziennika. Kiedy pojawia się problem, który uniemożliwia wszelkie próby śledzenia, możesz wtedy włączyć na krótki czas poziom *DATA*, aby uchwycić wszystkie szczegóły struktur, z którymi mieliśmy do czynienia w tym czasie. Ten poziom dziennika zajmuje dużo miejsca, więc jest zalecany tylko na krótkie okresy lub w przypadku witryn testowych dla programistów. + +Zalecam skonfigurowanie *logrotate* zarówno dla dziennika php, jak i dziennika aplikacji. Zazwyczaj co tydzień lub dwa zaglądam do *dbfail.out*, naprawiam zgłoszone problemy i zaczynam od nowego pliku. Podobnie jest z plikiem dziennika PHP. Odwołuję się do tego od czasu do czasu, aby sprawdzić, czy jest coś, co wymaga naprawy. + +Jeśli coś pójdzie nie tak i nie jest to błąd krytyczny, patrzę na plik dziennika aplikacji. Często robię to: ``` tail -f logfile.out ``` -ponieważ powtarza operację, która ma problemy. Często wstawiam w kodzie dodatkowe -instrukcje logowania, jeśli nie ma żadnej wskazówki, co się dzieje. Nawet coś tak -prostego jak "got here" lub drukuję wartości zmiennej, która może być podejrzana. -Ty też możesz to zrobić - wręcz zachęcam Cię do tego. Gdy już znajdziesz to, czego -potrzebujesz, możesz wykonać: +ponieważ powtarza operację, która ma problemy. Często wstawiam w kodzie dodatkowe instrukcje rejestracji, jeśli nie ma żadnej wskazówki, co się dzieje. Nawet coś tak prostego jak "got here" lub drukuję wartości zmiennej, która może być podejrzana. Ty też możesz to zrobić - wręcz zachęcam Cię do tego. Gdy już znajdziesz to, czego potrzebujesz, możesz wykonać: ``` git checkout file.php ``` -aby natychmiast wyczyścić wszystkie dodane elementy rejestrowania. Skorzystaj z -informacji z tego dziennika i wszelkich szczegółów, które możesz podać podczas -badania problemu, aby zgłosić błąd - chyba że analiza wskazuje na źródło problemu. -W takim przypadku po prostu to napraw. +aby natychmiast wyczyścić wszystkie dodane elementy rejestrowania. Skorzystaj z informacji z tego dziennika i wszelkich szczegółów, które możesz podać podczas badania problemu, aby zgłosić błąd - chyba że analiza wskazuje na źródło problemu. W takim przypadku po prostu to napraw. ##### Rotowanie plików dziennika @@ -571,23 +376,10 @@ W takim przypadku po prostu to napraw. #### Zgłaszanie problemów -Zgłaszając problemy, staraj się podać jak najwięcej szczegółów, które mogą być -potrzebne programistom do odtworzenia problemu i podać pełny tekst wszystkich -komunikatów o błędach. - -Zachęcamy do dołożenia wszelkich starań, aby wykorzystać te dzienniki w połączeniu -z posiadanym kodem źródłowym w celu rozwiązywania problemów i znajdowania ich -przyczyn. Społeczność często jest w stanie pomóc, ale tylko Ty masz dostęp do -plików dziennika swojej witryny i ich udostępnianie jest uważane za zagrożenie -bezpieczeństwa. - -Jeśli problem z kodem został odkryty, zgłoś go w bugtrackerze projektu -(https://framagit.org/hubzilla/core/issues). Ponownie podaj jak najwięcej szczegółów, -aby uniknąć ciągłego zadawania pytań o konfigurację lub powielanie problemu, -abyśmy mogli przejść od razu do problemu i dowiedzieć się, co z nim zrobić. -Zapraszamy również do oferowania własnych rozwiązań i przesyłania poprawek. -W rzeczywistości zachęcamy do tego, ponieważ wszyscy jesteśmy wolontariuszami i -mamy mało wolnego czasu. Im więcej osób pomaga, tym łatwiejsze jest obciążenie -pracą dla wszystkich. W porządku, jeśli Twoje rozwiązanie nie jest idealne. -Wszystko pomaga i być może uda nam się to poprawić. +Zgłaszając problemy, staraj się podać jak najwięcej szczegółów, które mogą być potrzebne programistom do odtworzenia problemu i podać pełny tekst wszystkich komunikatów o błędach. + +Zachęcamy do dołożenia wszelkich starań, aby wykorzystać te dzienniki w połączeniu z posiadanym kodem źródłowym w celu rozwiązywania problemów i znajdowania ich przyczyn. Społeczność często jest w stanie pomóc, ale tylko Ty masz dostęp do +plików dziennika swojej witryny i ich udostępnianie jest uważane za zagrożenie bezpieczeństwa. + +Jeśli problem z kodem został odkryty, zgłoś go w bugtrackerze projektu (https://framagit.org/hubzilla/core/issues). Ponownie podaj jak najwięcej szczegółów, aby uniknąć ciągłego zadawania pytań o konfigurację lub powielanie problemu, abyśmy mogli przejść od razu do problemu i dowiedzieć się, co z nim zrobić. Zapraszamy również do oferowania własnych rozwiązań i przesyłania poprawek. W rzeczywistości zachęcamy do tego, ponieważ wszyscy jesteśmy wolontariuszami i mamy mało wolnego czasu. Im więcej osób pomaga, tym łatwiejsze jest obciążenie pracą dla wszystkich. W porządku, jeśli Twoje rozwiązanie nie jest idealne. Wszystko pomaga i być może uda nam się to poprawić. diff --git a/doc/pl/admin/hub_snapshots.md b/doc/pl/admin/hub_snapshots.md index 1a5bd2d4f..fa38be7f8 100644 --- a/doc/pl/admin/hub_snapshots.md +++ b/doc/pl/admin/hub_snapshots.md @@ -4,14 +4,14 @@ Programiści Hubzilli często muszą przełączać się między gałęziami, kt mieć niekompatybilne schematy lub zawartość bazy danych. Poniższe dwa skrypty tworzą i przywracają pełne migawki instancji Hubzilli, w tym zarówno główny katalog sieciowy, jak i stan całej bazy danych. Każdy skrypt wymaga pliku -konfiguracyjnego o nazwie `hub-snapshot.conf` znajdującego się w tym samym +konfiguracyjnego o nazwie *hub-snapshot.conf* znajdującego się w tym samym folderze i zawiera on określone katalogi i szczegóły bazy danych huba. ### Konfiguracja Format pliku konfiguracyjnego jest bardzo ścisły. Między nazwą zmiennej a wartością nie może być spacji. Zastąp tylko treść w cudzysłowach swoją -konfiguracją. Zapisz ten plik jako `hub-snapshot.conf` obok skryptów. +konfiguracją. Zapisz ten plik jako *hub-snapshot.conf* obok skryptów. # Location of hub root. Typically this is the location of the Hubzilla repo clone. HUBROOT="/var/www/" diff --git a/doc/pl/checking_account_quota_usage.bb b/doc/pl/checking_account_quota_usage.bb new file mode 100644 index 000000000..b2cc0075c --- /dev/null +++ b/doc/pl/checking_account_quota_usage.bb @@ -0,0 +1,20 @@ +[b]Sprawdzanie wykorzystania limitu konta (wykorzystanie limitów usług)[/b] + +Na Twoim hubie mogą zostać zaimplementowane limity klas usług, przypisujące ograniczenia do całkowitego rozmiaru miejsca na plików i zdjęci, ilosci kanałów i postów najwyższego poziomu, jakie może utworzyć właściciel konta dla określonego poziomu usług i inne ograniczenia. + +Oto, jak możesz szybko sprawdzić, ile z przydzielonego limitu aktualnie używasz: + +[b]Sprawdenie poziom limitów przechowywania plików[/b] +Odwiedź nastęþujący adres URL w przeglądarce: +[observer=1][observer.baseurl]/filestorage/[observer.webname][/observer] +[observer=0]example.com/filestorage/username[/observer] + +[b]Sprawdenie poziomu limitów miejsca na przesłane zdjęcia[/b] +[observer=1][observer.baseurl]/photos/[observer.webname][/observer] +[observer=0]example.com/photos/username[/observer] + +Przykład: +[observer=1][observer.baseurl]/filestorage/[observer.webname][/observer] +[observer=0]example.com/filestorage/username[/observer] + +#include doc/macros/main_footer.bb; diff --git a/doc/pl/member/member_guide.bb b/doc/pl/member/member_guide.bb index 5a80c6510..d7f559c9e 100644 --- a/doc/pl/member/member_guide.bb +++ b/doc/pl/member/member_guide.bb @@ -443,7 +443,7 @@ wytworzy taki HTML: Istnieją dwie metody importowania elementów strony internetowej: przesyłanie pliku ZIP lub odwoływanie się do lokalnego folderu plików w chmurze. Obie metody wymagają określenia elementów strony sieci internetowej przy użyciu określonej struktury folderów. Narzędzie importu umożliwia zaimportowanie wszystkich elementów niezbędnych do zbudowania całej witryny lub zestawu witryn. Celem jest uwzględnienie zewnętrznego tworzenia stron internetowych, a także narzędzi upraszczających i automatyzujących wdrażanie w hubie. -[h5] Struktura folderu [/h5] +[h5][b] Struktura folderu [/b][/h5] Definicje elementów muszą być przechowywane w katalogu głównym repozytorium w folderach o nazwie odpowiadającej typowi elementu: [code] /pages/ @@ -453,8 +453,8 @@ Definicje elementów muszą być przechowywane w katalogu głównym repozytorium Każdy element tych typów musi być zdefiniowany w osobnym podfolderze przy użyciu dwóch plików: jednego w formacie JSON dla metadanych i drugiego w zwykłym formacie testowym dla zawartości elementu. -[h5] Elementy strony [/h5] -Page element metadata is specified in a JSON-formatted file called [code]page.json[/code] with the following properties: +[h5][b] Elementy strony [/b][/h5] +Metadane elementu strony są zdefiniowane w pliku w formacie JSON o nazwie [code]strona.json[/code] z następującymi właściwościami: [list] [*] title [*] pagelink @@ -462,14 +462,14 @@ Page element metadata is specified in a JSON-formatted file called [code]page.js [*] layout [*] contentfile [/list] -[b]Example[/b] +[b]Przykład[/b] -Files: +Pliki: [code] /pages/my-page/page.json /pages/my-page/my-page.bbcode [/code] -Content of [code]page.json[/code]: +Treść [code]page.json[/code]: [code] { "title": "My Page", @@ -479,22 +479,22 @@ Content of [code]page.json[/code]: "contentfile": "my-page.bbcode" } [/code] -[h5] Layout elements [/h5] +[h5][b] Elementy układu [/b][/h5] -Layout element metadata is specified in a JSON-formatted file called [code]layout.json[/code] with the following properties: +Metadane elementu układu są zdefiniowane w pliku w formacie JSON o nazwie [code]layout.json[/code] z następującymi właściwościami: [list] [*] name [*] description [*] contentfile [/list] -[b]Example[/b] +[b]Przykład[/b] -Files: +Pliki: [code] /layouts/my-layout/layout.json /layouts/my-layout/my-layout.bbcode [/code] -Content of [code]layout.json[/code]: +Treść [code]layout.json[/code]: [code] { "name": "my-layout", @@ -503,23 +503,23 @@ Content of [code]layout.json[/code]: } [/code] -[h5] Block elements [/h5] +[h5][b] Elementy bloku [/b][/h5] -Block element metadata is specified in a JSON-formatted file called [code]block.json[/code] with the following properties: +Metadane elementu bloku są określone w pliku w formacie JSON o nazwie [code]block.json[/code] z następującymi właściwościami: [list] [*] name [*] title [*] mimetype [*] contentfile [/list] -[b]Example[/b] +[b]Przykład[/b] -Files: +Pliki: [code] /blocks/my-block/block.json /blocks/my-block/my-block.html [/code] -Content of [code]block.json[/code]: +Treść [code]block.json[/code]: [code] { @@ -530,112 +530,110 @@ Content of [code]block.json[/code]: } [/code] -[h3]Comanche Page Description Language[/h3] +[h3]Język opisu stron Comanche[/h3] -Comanche is a markup language similar to [url=[baseurl]/help/member/bbcode]BBcode[/url] with which to create elaborate and complex web pages by assembling them from a series of components - some of which are pre-built and others which can be defined on the fly. Comanche uses a Page Decription Language to create these pages. +Comanche to język znaczników podobny do [url=[baseurl]/help/member/bbcode]BBcode[/url], za pomocą którego można tworzyć rozbudowane i złożone strony internetowe, łącząc je z szeregu komponentów - z których niektóre są już wstępnie zbudowane i inne, które można skonstruować w locie. Comanche używa własnego języka opisu strony do tworzenia tych stron. -Comanche primarily chooses what content will appear in various regions of the page. The various regions have names and these names can change depending on what layout template you choose. +Comanche przede wszystkim wybiera, jakie treści pojawią się w różnych [b]regionach[/b] strony. Regiony mają swoje nazwy, które mogą się zmieniać w zależności od wybranego szablonu układu. -[h4]Page Templates[/h4] -Currently there are five layout templates, unless your site provides additional layouts. +[h4][b]Szablony strony[/b][/h4] +Obecnie dostępnych jest pięć szablonów układów, ale w serwisie można udostępniać dodatkowe, własne układy. [dl terms="b"] [*= default] -The default template defines a "nav" region across the top, "aside" as a fixed width sidebar, -"content" for the main content region, and "footer" for a page footer. +Domyślny szablon zawiera definicję regionu "nav" znajdującego się u góry, "aside" jako pasek boczny o stałej szerokości, +"content" dla głównego regionu treści i "footer" dla stopki strony. [*= full] -The full template defines the same as the default template with the exception that there is no "aside" region. +Pełny szablon definiuje to samo, co szablon "default", z tą różnicą, że nie ma regionu "aside". [*= choklet] -The choklet template provides a number of fluid layout styles which can be specified by flavour: +Szablon "choklet" zapewnia kilka płynnych układów, które można wybierać według odmiany: [list] -[*] (default flavour) - a two column layout similar to the "default" template, but more fluid -[*] bannertwo - a two column layout with a banner region, compatible with the "default" template on small displays -[*] three - three column layout (adds a "right_aside" region to the default template) -[*] edgestwo - two column layout with fixed side margins -[*] edgesthree - three column layout with fixed side margins -[*] full - three column layout with fixed side margins and adds a "header" region beneath the navigation bar +[*] (domyślna odmiana) - układ dwukolumnowy, podobny do szaablonu "default", ale jest bardziej płynny +[*] bannertwo - układ dwukolumnowy z regionem "banner", zgodny z szablonem "default" na małych wyświetlaczach +[*] three - układ trzykolumnowy (dodany region "right_aside" do szablonu domyślnego) +[*] edgestwo - układ dwukolumnowy ze stałymi marginesami bocznymi +[*] edgesthree - układ trzykolumnowy ze stałymi marginesami bocznymi +[*] full - układ trzykolumnowy ze stałymi marginesami bocznymi i dodanym obszarem "header" poniżej paska nawigacji [/list] [*= redable] -A template for reading longer texts full screen (so without navigation bar). Three columns: aside, content and right_aside. -For maximum readability it is advised to only use the middle content column. +Szablon do czytania dłuższych tekstów na pełnym ekranie (czyli bez paska nawigacyjnego). Trzy kolumny: "aside", "content" i "right_aside". +Aby zapewnić maksymalną czytelność, zaleca się używanie tylko środkowej kolumny treści. [*= zen] -Gives you the freedom to do everything yourself. Just a blank page with a content region. +Daje swobodę robienia wszystkiego samemu. Tylko pusta strona z obszarem zawartości. [/dl] -To choose a layout template, use the 'template' tag. +Aby wybrać szablon układu, trzeba użyć tagu "template". [code] [template]full[/template] [/code] -To choose the "choklet" template with the "three" flavour: +Wybranie szablonu "choklet" z odmianą "three": [code] [template=three]choklet[/template] [/code] -The default template will be used if no other template is specified. The template can use any names it desires for content regions. You will be using 'region' tags to decide what content to place in the respective regions. +Jeśli nie określono innego szablonu, zostanie użyty szablon domyślny. W szablonie można używać dowolnych nazw dla regionów zawartości. Używa sie też tagów "region", aby zdecydować, jakie treści umieścić w odpowiednich regionach. -Three "macros" have been defined for your use. +Zadefiniowane są też trzy "makra", które można użyć na stronie. [code] - $htmlhead - replaced with the site head content. - $nav - replaced with the site navigation bar content. - $content - replaced with the main page content. + $htmlhead - wstawia zawartość nagłówka strony. + $nav - wstawia zawartość paska nawigacji. + $content - wstawia główną treść strony. [/code] -By default, $nav is placed in the "nav" page region and $content is placed in the "content" region. You only need to use these macros if you wish to re-arrange where these items appear, either to change the order or to move them to other regions. +Domyślnie, makro $nav jest umieszczane w regionie "nav" strony a $content w regionie "content". Tych makr potrzebujesz tylko wtedy, gdy chcesz zmienić rozmieszczenie tych elementów, aby zmienić kolejność lub przenieść je do innych regionów. - -To select a theme for your page, use the 'theme' tag. +Aby wybrać motyw dla swojej strony, użyj tagu "theme". [code] [theme]suckerberg[/theme] [/code] -This will select the theme named "suckerberg". By default your channel's preferred theme will be used. +Spowoduje to wybranie motywu o nazwie "suckerberg". Domyślnie używany jest preferowany motyw Twojego kanału. [code] [theme=passion]suckerberg[/theme] [/code] -This will select the theme named "suckerberg" and select the "passion" schema (theme variant). Alternatively it may be possible to use a condensed theme notation for this. +Spowoduje to wybranie motywu o nazwie "suckerberg" oraz wybór schematu "passion" (wariant motywu). Alternatywnie można użyć do tego zwięzłej notacji motywu. [code] [theme]suckerberg:passion[/theme] [/code] -The condensed notation isn't part of Comanche itself but is recognised by $Projectname platform as a theme specifier. +Notacja zwięzła nie jest częścią samego Comanche, ale jest rozpoznawana przez platformę $Projectname jako specyfikator motywu. -[h4]Navbar[/h4] +[h4][b]Pasek nawigacji[/b][/h4] [code] [navbar]tucson[/navbar] [/code] -Use the 'tucson' navbar template and CSS rules. By default the 'default' navbar template will be used. - +Kod ten powoduje użycie szablonu paska nawigacyjnego "tucson" i reguł CSS. Domyślnie stosowany jest szablon domyślny szablon paska nawigacyjnego. -[h4]Regions[/h4] -Each region has a name, as noted above. You will specify the region of interest using a 'region' tag, which includes the name. Any content you wish placed in this region should be placed between the opening region tag and the closing tag. +[h4][b]Regiony[/b][/h4] +Tak jak wspomniano wyżej, każdy region swoją nazwę. Wybrany eegion określa używając tagu "region", który zawiera nazwę. Wszelkie treści, które chcesz umieścić w tym regionie, powinny być umieszczone między tagiem otwierającego a zamykającym. [code] - [region=htmlhead]....content goes here....[/region] - [region=aside]....content goes here....[/region] - [region=nav]....content goes here....[/region] - [region=content]....content goes here....[/region] + [region=htmlhead]....tutaj jest treść....[/region] + [region=aside]....tutaj jest treść....[/region] + [region=nav]....tutaj jest treść....[/region] + [region=content]....tutaj jest treść....[/region] [/code] -[h4]CSS and Javascript[/h4] -We have the possibility to include javascript and css libraries in the htmlhead region. At present we make use of jquery (js), bootstrap (css/js) and foundation (css/js). -This will overwrite the selected themes htmlhead. +[h4][b]CSS i Javascript[/b][/h4] +Jest możliwość włączenia bibliotek JavaScript i CSS w regionie "htmlhead". Obecnie korzystamy z bibliotek jQuery (JS), Bootstrap (CSS i JS) oraz Foundation (CSS i JS). +Ten kod spowoduje nadpisanie regionu htmlhead wybranego motywu. [code] [region=htmlhead] @@ -646,116 +644,121 @@ This will overwrite the selected themes htmlhead. [/code] -[h4]Menus and Blocks[/h4] -Your webpage creation tools allow you to create menus and blocks, in addition to page content. These provide a chunk of existing content to be placed in whatever regions and whatever order you specify. Each of these has a name which you define when the menu or block is created. +[h4][b]Elementy menu i bloki[/b][/h4] +Narzędzia do tworzenia stron internetowych umożliwiają również tworzenie eleentów menu i bloków. Dostarczają one fragment kodu, który można umieścić w dowolnych regionach i w dowolnej kolejności. Każdy z takich fragmentów ma nazwę, którą definiuje się podczas tworzenia elementów menu lub bloku. +Ten kod: [code] [menu]mymenu[/menu] [/code] -This places the menu called "mymenu" at this location on the page, which must be inside a region. +spowoduje umieszczenie w tym miejscu menu o nazwie "mymenu”, ale miejsce to musi się ono znajdować wewnątrz regionu. +Kod: [code] [menu=horizontal]mymenu[/menu] [/code] -This places the menu called "mymenu" at this location on the page, which must be inside a region. Additionally it applies the "horizontal" class to the menu. "horizontal" is defined in the redbasic theme. It may or may not be available in other themes. +spowoduje umieszczenie w tym miejscu menu o nazwie "mymenu", ale musi się ono znajdować które musi znajdować wewnątrz regionu. Dodatkowo zastosowano tu do menu klasę "horizontal". Klasa "horizontal" jest zdefiniowana w motwie "redbasic". Może być dostępna lub nie w innych motywach. +W tym bloku: [code] [menu][var=wrap]none[/var]mymenu[/menu] [/code] -The variable [var=wrap]none[/var] in a block removes the wrapping div element from the menu. +zmienna [code][var=wrap]none[/var][/code] usuwa z menu element [code]div[/code]. +Ten kod: [code] [block]contributors[/block] [/code] -This places a block named "contributors" in this region. +umieszcza blok o nazwie "contributors" w regionie, w którym został wstawiony. +Kod: [code] [block=someclass]contributors[/block] [/code] -This places a block named "contributors" in this region. Additionally it applies the "someclass" class to the block. This replaces the default block classes "bblock widget". +też umieszcza blok o nazwie "contributors" w tym regionie, ale dodatkowo stosuje dla tego bloku klasę "someclass". Zamienia to domyślną klasę bloku "bblock widget". +W bloku: [code] [block][var=wrap]none[/var]contributors[/block] [/code] -The variable [var=wrap]none[/var] in a block removes the wrapping div element from the block. - -[h4]Widgets[/h4] -Widgets are executable apps provided by the system which you can place on your page. Some widgets take arguments which allows you to tailor the widget to your purpose. System widgets are listed [url=help/Widgets]here[/url]. Widgets can also ve created by plugins, themes, or your site administrator to provide additional functionality. +zmienna [code][var=wrap]none[/var][/code] usuwa z bloku opakowujący go element [code]div[/code]. +[h4][b]Widżety[/b][/h4] +Widżety to wykonywalne aplikacje dostarczane przez system, które można umieścić na swojej stronie. Niektóre widżety przyjmują argumenty, które pozwalają dostosować widżet do własnych potrzeb. Widżety systemowe są wymienione [url=help/Widgets]tutaj[/url]. Widżety mogą być również tworzone w ramach wtyczek, motywów lub przez administratora witryny, aby zapewnić dodatkowe funkcje. -Widgets and arguments are specified with the 'widget' and 'var' tags. +Widżety i ich argumenty są określane za pomocą tagów "widget" i "var". [code] [widget=recent_visitors][var=count]24[/var][/widget] [/code] -This loads the "recent_visitors" widget and supplies it with the argument "count" set to "24". +Spowoduje to załadowanie widżetu „latest_visitors” i dostarcza mu argument "count" ustawiony na „24”. -[h4]Comments[/h4] -The 'comment' tag is used to delimit comments. These comments will not appear on the rendered page. +[h4][b]Komentarze[/b][/h4] +Tag "comment" jest używany do wydzielenia komentarzy. Komentarze te nie pojawią się na renderowanej stronie. [code] [comment]This is a comment[/comment] [/code] -[h4]Conditional Execution[/h4] -You can use an 'if' construct to make decisions. These are currently based on system configuration variable or the current observer. +[h4][b]Wykonanie warunkowe[/b][/h4] +Można użyć konstrukcji [code]if[/code] warunkowego wykonania kodu. Jest to obecnie oparte na zmiennej konfiguracji systemu [code]$config.system[/code] lub zmiennej [code]$observer[/code]. [code] [if $config.system.foo] - ... the configuration variable system.foo evaluates to 'true'. + ... zmienna konfiguracyjna system.foo przyjmuje wartość 'true'. [else] - ... the configuration variable system.foo evaluates to 'false'. + ... zmienna konfiguracyjna system.foo przyjmuje wartość 'false'. [/if] [if $observer] - ... this content will only be show to authenticated viewers + ... ta treść będzie pokazywana tylko uwierzytelnionym użytownikom [/if] [/code] - The 'else' clause is optional. + Klauzula 'else' jest opcjonalna. - Several tests are supported besides boolean evaluation. + Oprócz oceny logicznej obsługiwanych jest też kilka testów. [code] [if $config.system.foo == bar] - ... the configuration variable system.foo is equal to the string 'bar' + ... zmienna konfiguracyjne system.foo jest równa łańcuchowi 'bar' [/if] [if $config.system.foo != bar] - ... the configuration variable system.foo is not equal to the string 'bar' + ... zmienna konfiguracyjne system.foo nie jest równa łańcuchowi 'bar' [/if] [if $config.system.foo {} bar ] - ... the configuration variable system.foo is a simple array containing a value 'bar' + ... zmienna konfiguracyjna system.foo jest prostą tablicą zawierającą zmienną 'bar' [/if] [if $config.system.foo {*} bar] - ... the configuration variable system.foo is a simple array containing a key named 'bar' + ... zmienna konfiguracyjna system.foo jest prostą tablicą zawierającą klucz o nazwie 'bar' [/if] [/code] -[h4]Complex Example[/h4] +[h4][b]Złożony przykład[/b][/h4] [code] - [comment]use an existing page template which provides a banner region plus 3 columns beneath it[/comment] + [comment]użyj istniejący szablon strony, który zawiera obszar banera oraz 3 kolumny poniżej[/comment] [template]3-column-with-header[/template] - [comment]Use the "darknight" theme[/comment] + [comment]Użyj motyw "darknight"[/comment] [theme]darkknight[/theme] - [comment]Use the existing site navigation menu[/comment] + [comment]Użyj istniejące menu nawigacyjne strony[/comment] [region=nav]$nav[/region] [region=side] - [comment]Use my chosen menu and a couple of widgets[/comment] + [comment]Użyj wybranego przeze mnie menu i kilku widżetów[/comment] [menu]myfavouritemenu[/menu] @@ -773,7 +776,7 @@ You can use an 'if' construct to make decisions. These are currently based on sy [region=middle] - [comment]Show the normal page content[/comment] + [comment]Pokaż normalną zawartość strony[/comment] $content @@ -783,7 +786,7 @@ You can use an 'if' construct to make decisions. These are currently based on sy [region=right] - [comment]Show my condensed channel "wall" feed and allow interaction if the observer is allowed to interact[/comment] + [comment]Pokaż mój skondensowany kanał RSS "wal" i zezwól na interakcję, jeśli obserwator ma możliwość interakcji[/comment] [widget]channel[/widget] @@ -792,237 +795,230 @@ You can use an 'if' construct to make decisions. These are currently based on sy [/code] -[h3]Personal Cloud Storage[/h3] +[h3]Osobisty magazyn w chmurze[/h3] -$Projectname provides an ability to store privately and/or share arbitrary files with friends. +$Projectname umożliwia prywatne przechowywanie i udostępnianie znajomym dowolnych plików. Możesz przesłać pliki ze swojego komputera do obszaru przechowywania lub skopiować je bezpośrednio z systemu operacyjnego przy użyciu protokołu WebDAV. -You may either upload files from your computer into your storage area, or copy them directly from the operating system using the WebDAV protocol. +Funkcjonuje to podobnie do usług "chmurowych", takich jak [i]Dopbox[/i], [i]Dysk[/i] Google czy [i]One Drive[/i] Microsoftu. -On many public servers there may be limits on disk usage. +Na wielu serwerach publicznych mogą obowiązywać ograniczenia dotyczące przydzielonej powierzchni dyskowej. -[h4]File Attachments[/h4] +[h4][b]Załączniki plikowe[/b][/h4] -The quickest and easiest way to share files is through file attachments. In the row of icons below the status post editor is a tool to upload attachments. Click the tool, select a file and submit. After the file is uploaded, you will see an attachment code placed inside the text region. Do not edit this line or it may break the ability for your friends to see the attachment. You can use the post permissions dialogue box or privacy hashtags to restrict the visibility of the file - which will be set to match the permissions of the post your are sending. +Najszybszym i najłatwiejszym sposobem udostępniania plików są załączniki. W rzędzie ikon poniżej edytora statusu znajduje się narzędzie do przesyłania załączników. Kliknij narzędzie, wybierz plik i prześlij. Po załadowaniu pliku zobaczysz kod załącznika umieszczony w obszarze tekstowym. Nie edytuj tego kodu, ponieważ może to uniemożliwić Ci udostępnienie tego pliku znajomym. Możesz użyć okna dialogowego uprawnień do publikowania lub hasztagów prywatności, aby ograniczyć widoczność pliku - który zostanie ustawiony zgodnie z uprawnieniami wysyłanego postu. -To delete attachments or change the permissions on the stored files, visit [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username replacing username with the nickname you provided during channel creation[/observer]. +Aby usunąć załączniki lub zmienić uprawnienia do przechowywanych plików, odwiedź [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username, zastępując [code]username[/code] pseudonimem, jaki podałeś podczas tworzenia kanału[/observer]. -[h4]Web Access[/h4] +[h4][b]Dostęp internetowy[/b][/h4] -Your files are visible on the web at the location [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username[/observer] to anybody who is allowed to view them. If the viewer has sufficient privileges, they may also have the ability to create new files and folders/directories. This should only be used for smaller files and photos (up to a few megabytes) as it uses internal memory. For larger files (videos, music, etc.), please upload using WebDAV. These files may still be retrieved via web access. +Twoje pliki są widoczne w sieci pod adresem [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username[/observer] dla każdego, kto ma uprawnienia do ich przeglądania. Jeśli przeglądający ma wystarczające uprawnienia, może mieć również możliwość tworzenia nowych plików i folderów (katalogów) w interfejsie przeglądarki. Dostęp internetowy powinnien być używane tylko w przypadku mniejszych plików i zdjęć (do kilku megabajtów), ponieważ wykorzystuje pamięć wewnętrzną. W przypadku większych plików (filmy, muzyka itp.) przesyłaj je za pomocą protokołu WebDAV, cojest omówione w następnym rozdziale. Takie pliki będzie można nadal pobierać za pośrednictwem dostępu internetowego. -[h4]WebDAV access[/h4] +[h4][b]Dostęp WebDAV[/b][/h4] -WebDAV provides a way to copy files directly to or from your computer's operating system, where your cloud files appear as a virtual disk drive. This should be used to upload large files such as video and audio; as it is not limited to available memory. See [zrl=help/member/member_guide#Cloud_Desktop_Clients]Cloud Desktop Clients[/zrl] below. +WebDAV umożliwia kopiowanie plików bezpośrednio do lub z systemu operacyjnego komputera, gdzie Twój "magazyn chmurze" pojawia się jako wirtualny dysk. Dostęp ten powinien być używany do przesyłania dużych plików, takich jak wideo i audio, ponieważ nie jest ograniczony dostępną pamięcią wewnętrzna. Zobacz [zrl=help/member/member_guide#Cloud_Desktop_Clients]Cloud Desktop Clients[/zrl] poniżej. -[h4]CalDAV and CardDAV access on Android[/h4] +[h4][b]Dostęp CalDAV i CardDAV na Androidzie[/b][/h4] -You can sync you calendar and contacts on Android with your Hub. +Możesz zsynchronizować swój kalendarz i kontakty w systemie Android ze swoim hubem. + +Poniższe kroki zostały przetestowane pod kątem zasosowania [url=https://f-droid.org/en/packages/at.bitfire.davdroid/] DAVdroid [/url]: -The following steps where tested for [url=https://f-droid.org/en/packages/at.bitfire.davdroid/]DAVdroid[/url] [list] -[*] install DAVdroid -[*] add account -[*] use "URL" and "user name" to login +[*] zainstaluj DAVdroid +[*] dodaj konto +[*] użyj "URL" i "user name" do zalogowania się [list] -[*] base url is [baseurl]/cdav -[*] user name is [observer=1][observer.webname][/observer][observer=0]username[/observer] +[*] podstawowy URL to [baseurl]/cdav +[*] Twoja nazwa użytkowka to [observer=1][observer.webname][/observer][observer=0]username[/observer] [/list] [/list] -To share your calendar visit [observer.baseurl]/cdav/calendar - +Aby udostępnić kalendarz odwiedź [observer.baseurl]/cdav/calendar -[h4]Permissions[/h4] +[h4][b]Uprawnienia[/b][/h4] -When using WebDAV, the file is created with your channel's default file permissions and this cannot be changed from within the operating system. It also may not be as restrictive as you would like. What we've found is that the preferred method of making files private is to first create folders or directories; then visit [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username[/observer] select the directory and change the permissions. Do this before you put anything into the directory. The directory permissions take precedence so you can then put files or other folders into that container and they will be protected from unwanted viewers by the directory permissions. It is common for folks to create a "personal" or "private" folder which is restricted to themselves. You can use this as a personal cloud to store anything from anywhere on the web or any computer and it is protected from others. You might also create folders for "family" and "friends" with permission granted to appropriate privacy groups. +W przypadku korzystania z protokołu WebDAV plik jest tworzony z domyślnymi uprawnieniami do plików kanału, których nie można zmienić z poziomu systemu operacyjnego. Może też nie być to tak restrykcyjne, jak byś chciał. Najlepiej, utwórz foldery (katalogi), następnie odwiedź swoją "chmurę" pod aadresem [observer=1][baseurl]/cloud/[observer.webname][/observer][observer=0][baseurl]/cloud/username[/observer], wybierz katalog i zmień uprawnienia. Zrób to zanim umieścisz cokolwiek w katalogu. Uprawnienia do katalogu mają pierwszeństwo, więc możesz następnie umieścić pliki lub inne foldery w tym kontenerze i będą one chronione przed niechcianymi widzami przez ustawienie uprawnienia do katalogu. Często zdarza się, że użytkownicy tworzą folder "osobisty" lub "prywatny", który jest ograniczony do nich samych. Możesz używać tego jako osobistej chmury do przechowywania wszystkiego z dowolnego miejsca w Internecie lub dowolnego komputera i jest to chroniony przed innymi. Możesz także utworzyć foldery dla "rodziny" lub "przyjaciele" za zgodą udzieloną odpowiednim grupom prywatności. -[h3]Cloud Desktop Clients[/h3] +[h3]Klienty desktopowe dla chmury[/h3] +[h4][b]Klienty dla Windows[/b][/h4] -[h4]Cloud Desktop Clients - Windows[/h4] +W Windows 7 połaczenie WebDAV można nawiązać przy użyciu kreatora z graficznym interfejsem: +1. Kliknij lewym przyciskiem myszy na przycisk "Start", aby otworzyc menu "Start". +2. Kliknij prawym przyciskiem myszy na ikone "Mój komputer", aby uzyskac dostęp do tego menu. +3. Kliknij lewym przysiskiem myszy na link "Mapuj dysk sieciowy...", aby otworzyć okno dialogowe kreatora połączeń. +4. Wpisz '[baseurl]/dav/nickname' w polu tekstowym (zamieniając 'nickname' na pseudonim swojego kanału) i kliknij przycisk "Gotowe". +5. Wpisz pseudonim kanału $Projectname. WAŻNE - bez znaku @ lub nazwy domeny +6. Wpisz swoje hasło $Projectname -WebDAV using Windows 7 graphical user interface wizard: -1. Left-click the Start-button to open the start menu. -2. Right-click the My computer icon to access its menu. -3. Left-click Map network drive... to open the connection dialog wizard. -4. Type '[baseurl]/dav/nickname' in the textbox (replace nickname with your channel nickname) and click the Complete button. -5. Type your $Projectname channel nickname. IMPORTANT - NO at-sign or domain name. -6. Type your $Projectname password +[h4][b]Klienty dla Linux[/b][/h4] -[h4]Cloud Desktop Clients - Linux[/h4] +[h5][b]Montowanie katalogu w systemie plików[/b][/h5] -[h5]Mount as a filesystem[/h5] +Aby zainstalować katalog w chmurze jako system plików, musisz najpierw zainstalować davfs2. Dla większości dystrybucji program ten jest dostępny w repozytoriach. Instalacja w Debianie: -[b]Mounting As A Filesystem[/b] +[code]sudo apt-get install davfs2[/code] -To install your cloud directory as a filesystem, you first need davfs2 installed. 99% of the time, this will be included in your distributions repositories. In Debian +Następnie skonfiguruj davfs2: -[code]apt-get install davfs2[/code] +[code]sudo dpkg-reconfigure davfs2[/code] -If you want to let normal users mount the filesystem +i wybierz "yes" przy zapytaniu. -[code] dpkg-reconfigure davfs2[/code] +Teraz musisz dodać użytkownika, który ma mieć możliwość montowania dav, do grupy davfs2: -and select "yes" at the prompt. +[code]sudo usermod -aG davfs2 <DesktopUser>[/code] -Now you need to add any user you want to be able to mount dav to the davfs2 group +[b]Note:[/b] w niektórych systemach grupa użytkowników może być inna, +np. "network" w Arch Linux. W razie wątpliwości sprawdź dokumentację +davfs dla swojego konkretnego systemu operacyjnego. -[code]usermod -aG davfs2 <DesktopUser>[/code] - -[b]Note:[/b] on some systems the user group may be different, i.e. - "network" -on Arch Linux. If in doubt, check the davfs documentation for your -particular OS. - -Edit /etc/fstab +Edytuj /etc/fstab: [code]nano /etc/fstab[/code] - to include your cloud directory by adding +aby uwzględnić katalog w chmurze, dodając: [code] [baseurl]/dav/ /mount/point davfs user,noauto,uid=<DesktopUser>,file_mode=600,dir_mode=700 0 1 [/code] -Where [baseurl] is the URL of your hub, /mount/point is the location you want to mount the cloud, and <DesktopUser> is the user you log in to one your computer. Note that if you are mounting as a normal user (not root) the mount point must be in your home directory. +gdzie [baseurl] jest adresem URL huba, /mount/point to lokalizacja, w której chcesz zamontować chmurę, a <DesktopUser> to użytkownik, którego logujesz się na swoim komputerze. Miej na uwadze, że jeśli montujesz jako zwykły użytkownik (nie root), punkt montowania musi znajdować się w twoim katalogu domowym. -For example, if I wanted to mount my cloud to a directory called 'cloud' in my home directory, and my username was bob, my fstab would be +Na przykład, jeśli chciałbyś zamontować swoją chmurę w katalogu o nazwie 'cloud' w swoim katalogu domowym, a Twoja nazwa użytkownika to 'bob', zapis w fstab będzie następujący: [code][baseurl]/dav/ /home/bob/cloud davfs user,noauto,uid=bob,file_mode=600,dir_mode=700 0 1[/code] -Now, create the mount point. +Teraz utówrz punkt montowania: [code]mkdir /home/bob/cloud[/code] -and also create a directory file to store your credentials +oraz utwórz plik katalogu do przechowywania danych uwierzytelniania: [code]mkdir /home/bob/.davfs2[/code] -Create a file called 'secrets' +Utwórz plik o nazwie 'secrets' [code]nano /home/bob/.davfs2/secrets[/code] -and add your cloud login credentials +i dodaj tam swoje dane uwierzytelniania w chmurze [code] [baseurl]/dav <username> <password> [/code] -Where <username> and <password> are the username and password [i]for your hub[/i]. +gdzie <username> i <password> to nazwa użytkownika i hasło [i]na Twoim kanale w hubie[/i]. -Don't let this file be writeable by anyone who doesn't need it with +Nie pozwól, aby ten plik mógł być zapisywany przez kogoś nieupoważnionego: [code]chmod 600 /home/bob/.davfs2/secrets[/code] -Finally, mount the drive. +Na koniec, zamontuj dysk: [code]mount [baseurl]/dav[/code] -You can now find your cloud at /home/bob/cloud and use it as though it were part of your local filesystem - even if the applications you are using have no dav support themselves. +Możesz teraz znaleźć swoją chmurę w /home/bob/cloud i używać jej tak, jakby była częścią lokalnego systemu plików - nawet jeśli aplikacje, których używasz, same nie obsługują dav. -[b]Troubleshooting[/b] +[b]Rozwiązywanie problemów[/b] -With some webservers and certain configurations, you may find davfs2 creating files with 0 bytes file size where other clients work just fine. This is generally caused by cache and locks. If you are affected by this issue, you need to edit your davfs2 configuration. +W przypadku niektórych serwerów WWW i pewnych konfiguracji może się okazać, że davfs2 tworzy pliki o rozmiarze pliku 0 bajtów, podczas gdy inni klienty działają dobrze. Zwykle jest to spowodowane pamięcią podręczną i blokadami. Jeśli występuje ten problem, musisz edytować konfigurację davfs2. -[code]nano /etc/davfs2/davfs2.conf[/code] +[code]sudo nano /etc/davfs2/davfs2.conf[/code] -Your distribution will provide a sample configuration, and this file should already exist, however, most of it will be commented out with a # at the beginning of the line. +Twoja dystrybucja dostarczy przykładową konfigurację i ten plik powinien już istnieć, jednak większość jego treści jest zakomentowana znakiem # na początku wiersza. -First step is to remove locks. +Pierwszym krokiem jest usunięcie blokad. -Edit the use_locks line so it reads [code]use_locks 0[/code]. +Edytuj wiersz use_locks, tak aby odczytywał [code]use_locks 0[/code]. -Unmount your file system, remount your file system, and try copying over a file from the command line. Note you should copy a new file, and not overwrite an old one for this test. Leave it a minute or two then do [code]ls -l -h[/code] and check the file size of your new file is still greater than 0 bytes. If it is, stop there, and do nothing else. +Odłącz system plików, podłącz go ponownie i spróbuj skopiować plik z wiersza poleceń. Zauważ, że powinieneś skopiować nowy plik a nie nadpisywać starego. który został utwozony na potrzeby tego testu. Poczekaj minutę lub dwie, a następnie wykonaj polecenie [code]ls -l -h[/code] i sprawdź, czy rozmiar nowego pliku jest nadal większy niż 0 bajtów. Jeśli tak, zatrzymaj się na tym i nie rób nic więcej. -If that still doesn't work, disable the cache. Note that this has a performance impact so should only be done if disabling locks didn't solve your problem. Edit the cache_size and set it to [code]cache_size 0[/code] and also set file_refresh to [code]file_refresh 0[/code]. Unmount your filesystem, remount your file system, and test it again. +Jeśli to nadal nie zadziała, wyłącz pamięć podręczną. Pamiętaj, że ma to wpływ na wydajność, więc należy to robić tylko wtedy, gdy wyłączenie blokad nie rozwiązało problemu. Edytuj cache_size i ustaw ją na [code]cache_size 0[/code], a także ustaw file_refresh na [code]file_refresh 0[/code]. Odmontuj system plików, ponownie go podłącz i przetestuj ponownie. -If it [i]still[/i] doesn't work, there is one more thing you can try. (This one is caused by a bug in older versions of dav2fs itself, so updating to a new version may also help). Enable weak etag dropping by setting [code]drop_weak_etags 1[/code]. Unmount and remount your filesystem to apply the changes. +Jeśli [i]nadal[/i] to nie działa, jest jeszcze jedna rzecz, której możesz spróbować. (Ten jest spowodowany błędem w starszych wersjach samego dav2fs, więc aktualizacja do nowej wersji może również pomóc). Włącz słabe usuwanie etagów, ustawiając [code]drop_weak_etags 1[]/code. Odmontuj i ponownie podłącz swój system plików, aby zastosować zmiany. +[h5][b]Dolphin[/b][/h5] +Dolphin Browser to przeglądarka internetowa dla Android i iOS. Odwiedź w niej [code]webdavs://example.com/dav[/code], gdzie [code]example.com[/code] to URL do Twojego huba. -[h5]Dolphin[/h5] -Visit webdavs://example.com/dav where "example.com" is the URL of your hub. +Gdy zostaniesz poproszony o podanie nazwy użytkownika i hasła, wprowadź nazwę swojego kanału (pierwszą część swojej strony internetowej - bez znaku @ i nazwy domeny) i hasło do swojego normalnego konta. -When prompted for a username and password, enter your channel name (the first part of your webbie - no @ or domain name) and password for your normal account. +Pamiętaj, że jeśli jesteś już zalogowany do interfejsu WWW przez Konqueror, nie zostaniesz poproszony o dalsze uwierzytelnianie. -Note, if you are already logged in to the web interface via Konqueror, you will not be prompted for further authentication. +[h5][b]Konqueror[/b][/h5] +Konqueror to przeglądarka internetowa, meadżer plików i przeglądarka dokumentów dla środowiska KDE. Wystarczy odwiedzić w niej serwis [code]webdavs://example.com/dav[/code] po zalogowaniu się do swojego huba, gdzie [code]example.com[/code] to adres URL huba. -[h5]Konqueror[/h5] +Jeśli jesteś zalogowany do swojego huba w normalny sposób, nie jest wymagane dalsze uwierzytelnianie. -Simply visit webdavs://example.com/dav after logging in to your hub, where "example.com" is the URL of your hub. +Ponadto, jeśli ktoś uwierzytelnił się w innym hubie podczas normalnej sesji przeglądarki, Twoja tożsamość zostanie również przekazana do chmury dla tych hubów - co oznacza, że możesz uzyskać dostęp do wszelkich prywatnych plików na dowolnym serwerze, o ile masz uprawnienia do ich przeglądania, pod warunkiem, że odwiedziłeś tę witrynę wcześniej podczas sesji. -No further authentication is required if you are logged in to your hub in the normal manner. +Ta funkcja jest zwykle ograniczona do interfejsu sieciowego i nie jest dostępna dla żadnego innego środowiska graficznego niż KDE. -Additionally, if one has authenticated at a different hub during their normal browser session, your identity will be passed to the cloud for these hubs too - meaning you can access any private files on any server, as long as you have permissions to see them, as long as you have visited that site earlier in your session. +[h5][b]Nautilus[/b][/h5] -This functionality is normally restricted to the web interface, and is not available to any desktop software other than KDE. +Nautilus to popularny menadżer plików dla środowiska GNOME. Jeśli sie nią posługujesz: -[h5]Nautilus[/h5] +1. Otwórz okno przeglądarki plików; +2. Wybierz z menu opcję Plik > Połącz z serwerem...; +3. Wpisz davs://<domain_name>/dav/<your_channelname> i kliknij Połącz; +4. Zostaniesz poproszony o podanie nazwy kanału (tak samo jak poprzednio) i hasło; +5. Twój osobisty katalog DAV zostanie udostęþniony w oknie przeglądarki. -1. Open a File browsing window (that's Nautilus) -2. Select File > Connect to server from the menu -3. Type davs://<domain_name>/dav/<your_channelname> and click Connect -4. You will be prompted for your channel name (same as above) and password -5. Your personal DAV directory will be shown in the window +[h5][b]Nemo[/b][/h5] -[h5]Nemo[/h5] +Pierwszy sposób: -For (file browser) Nemo 1.8.2 under Linux Mint 15, Cinnamon 1.8.8. Nemo ist the standard file browser there. +wpisz w pasku adresowym "davs://<domain_name>/dav/<your_channelname>". -1st way -type "davs://<domain_name>/dav/<your_channelname>" in the address bar. +Drugi sposób: -2nd way -Menu > file > connect to server -Fill the dialog -- Server: hubzilla_domain_name -- Type: Secure WebDAV (https) +1) Menu > Plik > Połącz z serwerem... +2) Wypełnij okna w formatce dialogowej: +- Sewer: hubzilla_domain_name +- Typ: Secure WebDAV (https) - Folder: /dav -- Username: yourchannelname -- Password: yourpassword +- Nazwa użytkownika: twoja_nazwa_kanału +- Hasło: twoje_hasło -Once open you can set a bookmark. +Po otwarciu możesz ustawić zakładkę. -[h5]Server Notes[/h5] +[h5][b]Uwagi dotyczące serwera[/b][/h5] -Note: There have been reported issues with clients that use "chunked transfer encoding", which includes Apple iOS services, and also the "AnyClient" and "CyberDuck" tools. These work fine for downloads, but uploads often end up with files of zero size. This is caused by an incorrect implemention of chunked encoding in some current FCGI (fast-cgi) implementations. Apache running with PHP as a module does not have these issues, but when running under FCGI you may need to use alternative clients or use the web uploader. At the time of this writing the issue has been open and no updates provided for at least a year. If you encounter zero size files with other clients, please check the client notes; as there are occasional configuration issues which can also produce these symptoms. +Zgłoszono problemy z klientami używającymi "chunked transfer encoding", które obejmuje usługi Apple iOS, a także narzędzia "AnyClient" i "CyberDuck". Działają one dobrze w przypadku pobierania, ale przesyłanie często kończy się plikami o zerowym rozmiarze. Jest to spowodowane nieprawidłową implementacją kodowania fragmentarycznego w niektórych obecnych implementacjach FCGI (fast-cgi). Apache działający z PHP jako modułem nie ma tych problemów, ale podczas pracy pod FCGI może być konieczne użycie alternatywnych klientów lub użycie programu do przesyłania internetowego. W chwili pisania tego artykułu problem był otwarty i nie udostępniono żadnych aktualizacji przez co najmniej rok. Jeśli napotkasz pliki o rozmiarze zerowym z innymi klientami, zapoznaj się z uwagami klienta; ponieważ czasami występują problemy z konfiguracją, które również mogą powodować te objawy. -[h3]Saved Searches[/h3] +[h3]Zapisane wyszukiwania[/h3] -In order to quickly find information, the 'saved search' widget may be used. This widget may be presented as a sidebar tool on your network page and possibly from your channel page. It is differentiated from the 'navigation bar' search tool in that it does not search the entire site, but only the subset of information available to your channel. +W celu szybkiego wyszukania informacji można skorzystać z widżetu "saved search". Ten widżet może być prezentowany jako narzędzie paska bocznego na Twojej stronie internetowej i prawdopodobnie na stronie Twojego kanału. Różni się od narzędzia wyszukiwania "paska nawigacji" tym, że nie przeszukuje całej witryny, a jedynie podzbiór informacji dostępnych na Twoim kanale. -Additionally the search terms you provide may activate a one-time search or be saved in a list for re-use. Saving the search item also invokes the search in addition to adding it to the saved list (which is displayed below the search text entry box). Any item in the list may be discarded if it is no longer needed. +Ponadto podane przez Ciebie frazy wyszukiwania mogą aktywować jednorazowe wyszukiwanie lub zostać zapisane na liście do ponownego wykorzystania. Zapisanie elementu wyszukiwania wywołuje również przeszukiwanie, oprócz dodania go do zapisanej listy (która jest wyświetlana poniżej pola wprowadzania tekstu wyszukiwania). Każdy element na liście może zostać odrzucony, jeśli nie jest już potrzebny. -The saved search widget will provide autocompletion of channels (the results are prefixed with '@'), and hashtags (prefixed with '#'). You do not need to enter these tags; although entering the desired tag will reduce the autocomplete results to only hold the relevant information. The behaviour maps as follows: +Zapisany widżet wyszukiwania zapewni automatyczne uzupełnianie kanałów (wyniki są poprzedzone znakiem @) i hashtagami (poprzedzonymi znakiem #). Nie trzeba wprowadzać tych tagów; chociaż wprowadzenie żądanego tagu zmniejszy wyniki autouzupełniania, aby zawierały tylko istotne informacje. Zachowanie odwzorowuje się następująco: [list] -[*]@name - search your network stream for posts or comments written by 'name'. This will also change the post editor permissions to include only 'name'; as if this was a privacy group. -[*]#hashtag - search you network stream for posts containing #hashtag. -[*]text - search your network stream for posts containing 'text'. +[*]@name - przeszukuje strumienia sieci w poszukiwaniu postów lub komentarzy napisanych przez 'name'. Spowoduje to również zmianę uprawnień edytora postów, aby zawierały tylko 'name'; jakby to była grupa prywatności. +[*]#hashtag - przeszukauje strumień sieci w poszukiwaniu postów zawierających #hashtag. +[*]text - przeszukaj strumień sieci w poszukiwaniu postów zawierających 'text'. [/list] -[h3]Remove Channel or Account[/h3] - -[h4]Remove Channel[/h4] - -Select the 'Remove Channel' link on your channel settings page or visit the URL: +[h3]Usunięcie kanału lub konta[/h3] - [baseurl]/removeme +[h4][b]Usuniecie kanału[/b][/h4] -You will need to confirm your password and the channel you are currently logged into will be removed. +Wybierz link 'Usuń kanał' na stronie ustawień kanału lub odwiedź URL [baseurl]/removeme. -[hl][i][b]This is irreversible.[/b][/i][/hl] +Będziesz musiał potwierdzić swoje hasło i kanał, na którym jesteś obecnie zalogowany, zostanie usunięty. -If you have identity clones on other hubs this only removes by default the channel instance which exists on this hub. +[hl][i][b]To jest nieodwracalne.[/b][/i][/hl] -[h4]Remove Account[/h4] +Jeśli masz klony tożsamości na innych hubach, nie zostaną one usuniete. Operacja ta spowoduje tylko usunięcie tej instancji kanału, która istnieje w hubie, na którym dokonujesz usunięcia kanału. -Select 'Remove Account' from your account settings page or visit the URL: +[h4][b]Usuniecie konta[/b][/h4] - [baseurl]/removeaccount +Wybierz link 'Usuń konto' widoczny na stronie ustawień konta lub odwiedź URL: [baseurl]/removeaccount -You will need to confirm your password and the account you are currently logged into will be removed. +Będziesz musiał potwierdzić swoje hasło i konto, na którym jesteś obecnie zalogowany, zostanie usunięte. -[hl][i][b]This is irreversible.[/b][/i][/hl] +[hl][i][b]To jest nieodwracalne.[/b][/i][/hl] -All your channels will be deleted. If you have identity clones on other hubs this only removes by default the channels instances which exists on this hub. +Wszystkie Twoje kanały zostaną usunięte. Jeśli masz klony tożsamości na innych hubach - nie zostaną one usuniete. Operacja ta powoduje tylko usunięcie instancji kanałów, które istnieją hubie, na którym dokonujesz tą operację. diff --git a/doc/pl/tutorials/assets/0965ace945f0c95ae38aa5bfedd230d2a7233d3915ac15d629f9dd845854.png b/doc/pl/tutorials/assets/0965ace945f0c95ae38aa5bfedd230d2a7233d3915ac15d629f9dd845854.png new file mode 100644 index 000000000..d5cf1093f Binary files /dev/null and b/doc/pl/tutorials/assets/0965ace945f0c95ae38aa5bfedd230d2a7233d3915ac15d629f9dd845854.png differ diff --git a/doc/pl/tutorials/assets/1ebe02c205962dd25035c441631745d16acdb7a44e50d148256c8ad26a67.png b/doc/pl/tutorials/assets/1ebe02c205962dd25035c441631745d16acdb7a44e50d148256c8ad26a67.png new file mode 100644 index 000000000..d613925aa Binary files /dev/null and b/doc/pl/tutorials/assets/1ebe02c205962dd25035c441631745d16acdb7a44e50d148256c8ad26a67.png differ diff --git a/doc/pl/tutorials/assets/2243e48ccea25bd907cce3dbd6fc9f7cd832a4c91a4c5dd294b7b219e7d8.png b/doc/pl/tutorials/assets/2243e48ccea25bd907cce3dbd6fc9f7cd832a4c91a4c5dd294b7b219e7d8.png new file mode 100644 index 000000000..c403bf806 Binary files /dev/null and b/doc/pl/tutorials/assets/2243e48ccea25bd907cce3dbd6fc9f7cd832a4c91a4c5dd294b7b219e7d8.png differ diff --git a/doc/pl/tutorials/assets/25eaad2435200f72a1dd3a00ba17a76ca6db4c246b3c4fa286b390cae7c8.png b/doc/pl/tutorials/assets/25eaad2435200f72a1dd3a00ba17a76ca6db4c246b3c4fa286b390cae7c8.png new file mode 100644 index 000000000..ca8ba6fb9 Binary files /dev/null and b/doc/pl/tutorials/assets/25eaad2435200f72a1dd3a00ba17a76ca6db4c246b3c4fa286b390cae7c8.png differ diff --git a/doc/pl/tutorials/assets/2b539d5a8474d6ec6dc91155b628d9be5f99ab04a78108ec404f53ec7bb5.png b/doc/pl/tutorials/assets/2b539d5a8474d6ec6dc91155b628d9be5f99ab04a78108ec404f53ec7bb5.png new file mode 100644 index 000000000..0da2d96e2 Binary files /dev/null and b/doc/pl/tutorials/assets/2b539d5a8474d6ec6dc91155b628d9be5f99ab04a78108ec404f53ec7bb5.png differ diff --git a/doc/pl/tutorials/assets/31f42a02bdbae095e0329db6c3814e2975979aff12f873f43d81724c5e61.png b/doc/pl/tutorials/assets/31f42a02bdbae095e0329db6c3814e2975979aff12f873f43d81724c5e61.png new file mode 100644 index 000000000..2a209b2be Binary files /dev/null and b/doc/pl/tutorials/assets/31f42a02bdbae095e0329db6c3814e2975979aff12f873f43d81724c5e61.png differ diff --git a/doc/pl/tutorials/assets/324247680b605fd214fd61aecd8f216fa8f5dfa0f16a04c8e968fdbc43d0.png b/doc/pl/tutorials/assets/324247680b605fd214fd61aecd8f216fa8f5dfa0f16a04c8e968fdbc43d0.png new file mode 100644 index 000000000..f992672b0 Binary files /dev/null and b/doc/pl/tutorials/assets/324247680b605fd214fd61aecd8f216fa8f5dfa0f16a04c8e968fdbc43d0.png differ diff --git a/doc/pl/tutorials/assets/3656a67dce40a1fc2515e9089217f2e136d4fcf8babe77bac00ecaad43ce.png b/doc/pl/tutorials/assets/3656a67dce40a1fc2515e9089217f2e136d4fcf8babe77bac00ecaad43ce.png new file mode 100644 index 000000000..b656192dc Binary files /dev/null and b/doc/pl/tutorials/assets/3656a67dce40a1fc2515e9089217f2e136d4fcf8babe77bac00ecaad43ce.png differ diff --git a/doc/pl/tutorials/assets/458a842c2ea0fbe3b7869bb14dfffe1e5be098d1cd6e590bbead25b4cc05.png b/doc/pl/tutorials/assets/458a842c2ea0fbe3b7869bb14dfffe1e5be098d1cd6e590bbead25b4cc05.png new file mode 100644 index 000000000..6129195b6 Binary files /dev/null and b/doc/pl/tutorials/assets/458a842c2ea0fbe3b7869bb14dfffe1e5be098d1cd6e590bbead25b4cc05.png differ diff --git a/doc/pl/tutorials/assets/4aaaf1e124514c8d6999a5fe1d07be5af460cda4ba6cde9106ebc1564bb0.png b/doc/pl/tutorials/assets/4aaaf1e124514c8d6999a5fe1d07be5af460cda4ba6cde9106ebc1564bb0.png new file mode 100644 index 000000000..923403fe9 Binary files /dev/null and b/doc/pl/tutorials/assets/4aaaf1e124514c8d6999a5fe1d07be5af460cda4ba6cde9106ebc1564bb0.png differ diff --git a/doc/pl/tutorials/assets/4cf326152797a8ecdf5630e921756f825ee00f8ee464d3ef9fed971d2852.png b/doc/pl/tutorials/assets/4cf326152797a8ecdf5630e921756f825ee00f8ee464d3ef9fed971d2852.png new file mode 100644 index 000000000..f158ad5d9 Binary files /dev/null and b/doc/pl/tutorials/assets/4cf326152797a8ecdf5630e921756f825ee00f8ee464d3ef9fed971d2852.png differ diff --git a/doc/pl/tutorials/assets/75d2927b7ad0d2043d4d3b6ba1364fac8ead173edd39340adaf78be11c9d.png b/doc/pl/tutorials/assets/75d2927b7ad0d2043d4d3b6ba1364fac8ead173edd39340adaf78be11c9d.png new file mode 100644 index 000000000..edc8b01cc Binary files /dev/null and b/doc/pl/tutorials/assets/75d2927b7ad0d2043d4d3b6ba1364fac8ead173edd39340adaf78be11c9d.png differ diff --git a/doc/pl/tutorials/assets/7c976a06662a1357b3da8ed0680d1a721c85f2ae2bdd5739a8def466010e.png b/doc/pl/tutorials/assets/7c976a06662a1357b3da8ed0680d1a721c85f2ae2bdd5739a8def466010e.png new file mode 100644 index 000000000..5b259058b Binary files /dev/null and b/doc/pl/tutorials/assets/7c976a06662a1357b3da8ed0680d1a721c85f2ae2bdd5739a8def466010e.png differ diff --git a/doc/pl/tutorials/assets/99a6efda4df631dfb2d2a849412044cc6a0f8aebeac289d28786f2649d24.png b/doc/pl/tutorials/assets/99a6efda4df631dfb2d2a849412044cc6a0f8aebeac289d28786f2649d24.png new file mode 100644 index 000000000..c03ffd18d Binary files /dev/null and b/doc/pl/tutorials/assets/99a6efda4df631dfb2d2a849412044cc6a0f8aebeac289d28786f2649d24.png differ diff --git a/doc/pl/tutorials/assets/9eae9fad774a4cd29e665961d35affbd053368056f562c58200fb41027b0.png b/doc/pl/tutorials/assets/9eae9fad774a4cd29e665961d35affbd053368056f562c58200fb41027b0.png new file mode 100644 index 000000000..65d4c5f0a Binary files /dev/null and b/doc/pl/tutorials/assets/9eae9fad774a4cd29e665961d35affbd053368056f562c58200fb41027b0.png differ diff --git a/doc/pl/tutorials/assets/b0bfdf02aef3710a37bb6092c3240b291eca8afa73133b3ac03b86f3302d.png b/doc/pl/tutorials/assets/b0bfdf02aef3710a37bb6092c3240b291eca8afa73133b3ac03b86f3302d.png new file mode 100644 index 000000000..45609a7bb Binary files /dev/null and b/doc/pl/tutorials/assets/b0bfdf02aef3710a37bb6092c3240b291eca8afa73133b3ac03b86f3302d.png differ diff --git a/doc/pl/tutorials/assets/b334915c03a665493915598c69c17a87c910a39db2cd3b5292e4623ea4c4.png b/doc/pl/tutorials/assets/b334915c03a665493915598c69c17a87c910a39db2cd3b5292e4623ea4c4.png new file mode 100644 index 000000000..d239d6965 Binary files /dev/null and b/doc/pl/tutorials/assets/b334915c03a665493915598c69c17a87c910a39db2cd3b5292e4623ea4c4.png differ diff --git a/doc/pl/tutorials/assets/b3eece28e8db67f1024af42055f0f24ed5e81ba622aca8cac576ccf5930e.png b/doc/pl/tutorials/assets/b3eece28e8db67f1024af42055f0f24ed5e81ba622aca8cac576ccf5930e.png new file mode 100644 index 000000000..45ed64d00 Binary files /dev/null and b/doc/pl/tutorials/assets/b3eece28e8db67f1024af42055f0f24ed5e81ba622aca8cac576ccf5930e.png differ diff --git a/doc/pl/tutorials/assets/bdbcf0ffd9004657237f6b7b7863da5a8e39a5bc17d2c67fa160efef2056.png b/doc/pl/tutorials/assets/bdbcf0ffd9004657237f6b7b7863da5a8e39a5bc17d2c67fa160efef2056.png new file mode 100644 index 000000000..fcaed8bef Binary files /dev/null and b/doc/pl/tutorials/assets/bdbcf0ffd9004657237f6b7b7863da5a8e39a5bc17d2c67fa160efef2056.png differ diff --git a/doc/pl/tutorials/assets/c4cad3e4c356dd2a227df79bd4dc6d47edf1b66ea243f005b6b452ec366b.png b/doc/pl/tutorials/assets/c4cad3e4c356dd2a227df79bd4dc6d47edf1b66ea243f005b6b452ec366b.png new file mode 100644 index 000000000..0ccfc8995 Binary files /dev/null and b/doc/pl/tutorials/assets/c4cad3e4c356dd2a227df79bd4dc6d47edf1b66ea243f005b6b452ec366b.png differ diff --git a/doc/pl/tutorials/assets/c9a880cc82ffa1f7c2f460397bb083bf7dc2a2b8f065e64da598b45b4a2b.png b/doc/pl/tutorials/assets/c9a880cc82ffa1f7c2f460397bb083bf7dc2a2b8f065e64da598b45b4a2b.png new file mode 100644 index 000000000..1cb4d2d22 Binary files /dev/null and b/doc/pl/tutorials/assets/c9a880cc82ffa1f7c2f460397bb083bf7dc2a2b8f065e64da598b45b4a2b.png differ diff --git a/doc/pl/tutorials/assets/d080e92d797af5e863fa39b2084c16a8410de1f7a6559633435817444aef.png b/doc/pl/tutorials/assets/d080e92d797af5e863fa39b2084c16a8410de1f7a6559633435817444aef.png new file mode 100644 index 000000000..22e4cb5d5 Binary files /dev/null and b/doc/pl/tutorials/assets/d080e92d797af5e863fa39b2084c16a8410de1f7a6559633435817444aef.png differ diff --git a/doc/pl/tutorials/assets/e05248fdc5688d6d24bde52432fdc7b39692a094559aa504de99352940b1.png b/doc/pl/tutorials/assets/e05248fdc5688d6d24bde52432fdc7b39692a094559aa504de99352940b1.png new file mode 100644 index 000000000..5674f5207 Binary files /dev/null and b/doc/pl/tutorials/assets/e05248fdc5688d6d24bde52432fdc7b39692a094559aa504de99352940b1.png differ diff --git a/doc/pl/tutorials/assets/e5d5674a34e848e2cce90a60fc416415271d9c51b81ad2a950fb0157222a.png b/doc/pl/tutorials/assets/e5d5674a34e848e2cce90a60fc416415271d9c51b81ad2a950fb0157222a.png new file mode 100644 index 000000000..e6b4a9974 Binary files /dev/null and b/doc/pl/tutorials/assets/e5d5674a34e848e2cce90a60fc416415271d9c51b81ad2a950fb0157222a.png differ diff --git a/doc/pl/tutorials/assets/ef78bc6aa3fafebd46f353514c907b3fdfe019918fc5553bb3f31388a36f.png b/doc/pl/tutorials/assets/ef78bc6aa3fafebd46f353514c907b3fdfe019918fc5553bb3f31388a36f.png new file mode 100644 index 000000000..8de042ae4 Binary files /dev/null and b/doc/pl/tutorials/assets/ef78bc6aa3fafebd46f353514c907b3fdfe019918fc5553bb3f31388a36f.png differ diff --git a/doc/pl/tutorials/assets/facb0bdfdecb4c779de9048cd14b417c0d76de17af476be5f296b78d70e9.png b/doc/pl/tutorials/assets/facb0bdfdecb4c779de9048cd14b417c0d76de17af476be5f296b78d70e9.png new file mode 100644 index 000000000..cec391fb4 Binary files /dev/null and b/doc/pl/tutorials/assets/facb0bdfdecb4c779de9048cd14b417c0d76de17af476be5f296b78d70e9.png differ diff --git a/doc/pl/tutorials/personal_channel.md b/doc/pl/tutorials/personal_channel.md new file mode 100644 index 000000000..6b96cf14a --- /dev/null +++ b/doc/pl/tutorials/personal_channel.md @@ -0,0 +1,116 @@ + +Ten poradnik trzeba wykonać w kolejności, tak jakbyś konfigurował plik kanału po raz pierwszy. Przedstawia w naturalny sposób niektóre narzędzia i funkcje związane z kanałem osobistym. + +### Tworzenie nowego kanału + +Kiedy logujesz się po raz pierwszy po rejestracji, musisz utworzyć kanał albo odwiedzić później stronę *https://your_website/new_channel*. + +![](assets/c9a880cc82ffa1f7c2f460397bb083bf7dc2a2b8f065e64da598b45b4a2b.png) + +Wprowadź swoje imię i nazwisko oraz pseudonim dla adresu kanału, a następnie wybierz "rolę". Zazwyczaj, jeśli reprezentuje Cię osobisty kanał, wybierz *Społeczność* z domyślnym poziomem prywatności, który Ci odpowiada. Jeśli nie masz pewności, wybierz opcję *Społecznościowe - głównie publiczne*, co umożliwia łatwą interakcję i zapewnia prywatność, gdy jej potrzebujesz. Alternatywnie, ustawienie *Społecznościowe - ograniczone* jest bardzo popularne wśród obrońców prywatności, chociaż poznanie ludzi może wymagać nieco więcej wysiłku. Niezależnie od tego, które ustawienie wybierzesz, możesz zmienić je później, jeśli zajdzie taka potrzeba. + +### Dodanie zdjęcia profilowego + +Po utworzeniu nowego kanału zostaniesz przekierowany na stronę określoną przez administratora witryny. Domyślnie jest to strona * Edytuj profil *. + +Z poziomu rozwijanego menu *Narzędzia profili* wybierz opcję *Zmień zdjęcie profilowe* (lub po prostu kliknij zdjęcie profilowe). + +![](assets/31f42a02bdbae095e0329db6c3814e2975979aff12f873f43d81724c5e61.png) + +Prześlij swoje zdjęcie i jeśli to konieczne, zmień rozmiar za pomocą edytora obrazów. + +![](assets/458a842c2ea0fbe3b7869bb14dfffe1e5be098d1cd6e590bbead25b4cc05.png) + +Po naciśnięciu *Edycja zakończona* nastąpi przekierowanie z powrotem do edytora profili. + +> Jeśli masz problemy z wyświetleniem nowego zdjęcia, może być konieczne +> wyczyszczenie pamięci podręcznej przeglądarki. + +![](assets/d080e92d797af5e863fa39b2084c16a8410de1f7a6559633435817444aef.png) + +Po powrocie na stronę główną kanału zobaczysz, że wpis powiadamiający innych o Twoim nowym zdjęciu profilowym, który został automatycznie opublikowany. + +![](assets/1ebe02c205962dd25035c441631745d16acdb7a44e50d148256c8ad26a67.png) + + +### Tworzenie wpisów + +Przejdź do strony głównej swojego kanału i otwórz edytor wpisów, naciskając pole tekstowe *Udostępnij* u góry "ściany" kanału. Wprowadź wiadomość, a następnie przeciągnij i upuść plik obrazu do do obszaru tekstowego edytora postów. Ewentualnie możesz użyć narzędzie *Załącz plik*, widoczne u dołu. + +![](assets/b0bfdf02aef3710a37bb6092c3240b291eca8afa73133b3ac03b86f3302d.png) + +Plik obrazu zostanie automatycznie przesłany i zapisany w plikach w chmurze, a łącze pojawi się w oknie wpisu. Naciśnięcie przycisku podglądu wpisu umożliwia podgląd wpisu przed opublikowaniem. + +![](assets/7c976a06662a1357b3da8ed0680d1a721c85f2ae2bdd5739a8def466010e.png) + +Naciśnij przycisk kłódki obok przycisku *Prześlij*. SPowoduje to otworzenie się *Listę kontroli dostępu*, gdzie możesz dokładnie określić, kto ma dostęp do tego wpisu. + +![](assets/2b539d5a8474d6ec6dc91155b628d9be5f99ab04a78108ec404f53ec7bb5.png) + + +### Użycie przesłanego obrazu jako zdjęcia na okładkę kanału + +Jednym ze sposobów uatrakcyjnienia wyglądu kanału jest dodanie zdjęcia na okładkę, które będą widzieć użytkownicy po załadowaniu strony kanału. Zintegrowany system plików w chmurze pozwala wybrać w tym celu istniejące zdjęcie. + +Odwiedź swoje zdjęcia w aplikacji *Photos*. + +![](assets/0965ace945f0c95ae38aa5bfedd230d2a7233d3915ac15d629f9dd845854.png) + +Wybierz zdjęcie, którego chcesz użyć i wybierz *Użyj jako zdjęcia na okładkę* z rozwijanego menu *Narzędzia do zdjęć*. + +![](assets/9eae9fad774a4cd29e665961d35affbd053368056f562c58200fb41027b0.png) + +Przytnij obraz za pomocą edytora zdjęć i zapisz zmiany. + +![](assets/b3eece28e8db67f1024af42055f0f24ed5e81ba622aca8cac576ccf5930e.png) + +Gdy załadujesz stronę główną swojego kanału, najpierw zobaczysz zdjęcie okładkowe a strona kanału będzie się pojawiać w miarę przewijania w dół. + +![](assets/4cf326152797a8ecdf5630e921756f825ee00f8ee464d3ef9fed971d2852.png) + + +### Wykonywanie połączeń + +Tworzenie połączeń między kanałami i udostępnianie treści, to istosta komunikacji społecznej. Nawiązanie połączenia jest proste. Jeśli jeszcze nie wiesz, jak dotrzeć do strony domowej kanału, możesz spróbować przeszukać katalog, otwierając łącze *Katalog* z menu po prawej stronie z boku górnego paska nawigacyjnego. + +![](assets/ef78bc6aa3fafebd46f353514c907b3fdfe019918fc5553bb3f31388a36f.png) + +Możesz połączyć się bezpośrednio z poziomu katalogu za pomocą przycisku *Połącz* lub możesz najpierw otworzyć stronę kanału i nacisnąć przycisk *Połącz* widoczny poniżej zdjęcia profilowego. + +![](assets/75d2927b7ad0d2043d4d3b6ba1364fac8ead173edd39340adaf78be11c9d.png) + +Po nawiązaniu połączenia zostaniesz natychmiast przeniesiony do strony edytora połączeń, gdzie podejmujesz ważne decyzje dotyczące tego, co planujesz udostępniać na tym kanale. + +![](assets/b334915c03a665493915598c69c17a87c910a39db2cd3b5292e4623ea4c4.png) + +Dwa ważne ustawienia to + +* Indywidualne uprawnienia dla nowo podłączonego kanału +* Grupy prywatności, do których należy połączenie + +Indywidualne uprawnienia są w większości łatwe do zrozumienia, ale mogą być na początku niejasne. Na przykład *Można wyświetlać mój magazyn plików i zdjęć* nie oznacza, że na podłączonym kanale każdy będzie mógł przeglądać wszystkie Twoje zdjęcia i pliki! Oznacza to, że będziesz mieć możliwość udostępniania zdjęć i plików za pomocą tego kanału. Jest całkiem możliwe, że pozwolisz komuś czytać swoje wpisy, ale nie zezwolisz na oglądanie zdjęć w tym wpisie. + +Grupy prywatności umożliwiają wygodnie udostępniać elementy grupom osób. Można utworzyć dowolne grupy odpowiadające swoim potrzebom, otwierając link *Dodaj grupę prywatności*. + +![](assets/facb0bdfdecb4c779de9048cd14b417c0d76de17af476be5f296b78d70e9.png) + +W tym edytorze można przełączać się między istniejącymi grupami prywatności i od razu sprawdzić, jakie kanały są, a jakie nie są członkami grupy. Wybranie ikony kanału w dowolnym polu spowoduje przeniesienie kanału do tej grupy. + +![](assets/25eaad2435200f72a1dd3a00ba17a76ca6db4c246b3c4fa286b390cae7c8.png) + +Podczas edycji ustawień pojedynczego kanału można ustawić jego członkostwo w grupach prywatności za pomocą widżetu po lewej stronie: + +![](assets/bdbcf0ffd9004657237f6b7b7863da5a8e39a5bc17d2c67fa160efef2056.png) + +Połączenia to wzajemne zaangażowanie. Kanał, z którym się łączysz, może mieć ustawioną opcję zatwierdzenia połączenia z innym kanałem. Zostanie wówczas wysłane do niego powiadomienie o proonowanym połączeniu: + +![](assets/324247680b605fd214fd61aecd8f216fa8f5dfa0f16a04c8e968fdbc43d0.png) + +w którym znajduje się link do strony edytora [*Połączenia*](https://grid.reticu.li/connections), gdzie można zdecydować, czy zezwolić na połączenie, czy nie. + +![](assets/e05248fdc5688d6d24bde52432fdc7b39692a094559aa504de99352940b1.png) + +Po zatwierdzeniu połączenia dobrze jest otworzyć edytor połączeń indywidualnych, naciskając przycisk edycji obok przycisku *Usuń*. + +![](assets/c4cad3e4c356dd2a227df79bd4dc6d47edf1b66ea243f005b6b452ec366b.png) + diff --git a/view/pl/hmessages.mo b/view/pl/hmessages.mo deleted file mode 100644 index cbf6f399c..000000000 Binary files a/view/pl/hmessages.mo and /dev/null differ diff --git a/view/pl/hmessages.po b/view/pl/hmessages.po index 10dfc3b0b..07bba5233 100644 --- a/view/pl/hmessages.po +++ b/view/pl/hmessages.po @@ -74,7 +74,7 @@ msgstr "Może polubiać/dezaprobować profile i rzeczy w profilach" msgid "Can forward to all my channel connections via ! mentions in posts" msgstr "" "Może przekazywać informacje do wszystkich moich połączeń kanałowych za " -"pośrednictwem! wzmianki w postach" +"pośrednictwem !wzmianki w postach" #: ../../Zotlabs/Access/Permissions.php:71 msgid "Can chat with me" @@ -5095,7 +5095,7 @@ msgstr "Bezpieczeństwo" #: ../../Zotlabs/Module/Admin/Security.php:101 msgid "Block public" -msgstr "Zablokuj publiczny dstęp" +msgstr "Zablokuj publiczny dostęp" #: ../../Zotlabs/Module/Admin/Security.php:101 msgid "" @@ -5325,7 +5325,7 @@ msgstr "On" #: ../../Zotlabs/Module/Admin/Features.php:56 #, php-format msgid "Lock feature %s" -msgstr "Funkcja blokady %s" +msgstr "Blokuj funkcję %s" #: ../../Zotlabs/Module/Admin/Features.php:64 msgid "Manage Additional Features" @@ -9984,7 +9984,7 @@ msgstr "Przykłady: bob@example.com, https://example.com/barbara" #: ../../Zotlabs/Widget/Suggestions.php:53 msgid "Suggestions" -msgstr "Prpozycje" +msgstr "Propozycje" #: ../../Zotlabs/Widget/Suggestions.php:54 msgid "See more..." @@ -10943,7 +10943,7 @@ msgstr "Film/taniec/kultura/rozrywka:" #: ../../include/channel.php:1861 msgid "Love/Romance:" -msgstr "Miłość/romans:" +msgstr "Miłość/Romans:" #: ../../include/channel.php:1863 msgid "Work/employment:" diff --git a/view/pl/hstrings.php b/view/pl/hstrings.php index e80645bdb..4a2dd92ae 100644 --- a/view/pl/hstrings.php +++ b/view/pl/hstrings.php @@ -21,7 +21,7 @@ App::$strings["Can post on my channel (wall) page"] = "Może publikować na stro App::$strings["Can comment on or like my posts"] = "Może komentować lub polubić moje posty"; App::$strings["Can send me private mail messages"] = "Może wysyłać mi prywatne wiadomości e-mail"; App::$strings["Can like/dislike profiles and profile things"] = "Może polubiać/dezaprobować profile i rzeczy w profilach"; -App::$strings["Can forward to all my channel connections via ! mentions in posts"] = "Może przekazywać informacje do wszystkich moich połączeń kanałowych za pośrednictwem! wzmianki w postach"; +App::$strings["Can forward to all my channel connections via ! mentions in posts"] = "Może przekazywać informacje do wszystkich moich połączeń kanałowych za pośrednictwem !wzmianki w postach"; App::$strings["Can chat with me"] = "Może ze mną rozmawiać"; App::$strings["Can source my public posts in derived channels"] = "Może pozyskiwać moje publiczne posty w kanałach pochodnych"; App::$strings["Can administer my channel"] = "Może zarządzać moim kanałem"; @@ -987,7 +987,7 @@ App::$strings["The recommended setting is to only allow unfiltered HTML from the App::$strings["https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/
      https://vimeo.com/
      https://soundcloud.com/
      "] = "https://youtube.com/
      https://www.youtube.com/
      https://youtu.be/
      https://vimeo.com/
      https://soundcloud.com/
      "; App::$strings["All other embedded content will be filtered, unless embedded content from that site is explicitly blocked."] = "Wszystkie inne osadzone treści będą filtrowane, chyba że osadzone treści z tego serwisu są jawnie zablokowane."; App::$strings["Security"] = "Bezpieczeństwo"; -App::$strings["Block public"] = "Zablokuj publiczny dstęp"; +App::$strings["Block public"] = "Zablokuj publiczny dostęp"; App::$strings["Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated."] = "Zaznacz, aby zablokować publiczny dostęp do wszystkich innych publicznych stron osobistych w tej witrynie, chyba że jesteś obecnie uwierzytelniony."; App::$strings["Provide a cloud root directory"] = "Podaj katalog główny w chmurze"; App::$strings["The cloud root directory lists all channel names which provide public files"] = "Katalog główny w chmurze zawiera listę wszystkich nazw kanałów, które udostępniają pliki publiczne"; @@ -1039,7 +1039,7 @@ App::$strings["Selected accounts will be deleted!\\n\\nEverything these accounts App::$strings["The account {0} will be deleted!\\n\\nEverything this account has posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Konto {0} zostanie usuniete!\\n\\nWszystko co opublikowano z tego konta na tym serwisie zostanie bezpowrotnie usunięte!\\n\\nCzy na pewno usunąć?"; App::$strings["Off"] = "Off"; App::$strings["On"] = "On"; -App::$strings["Lock feature %s"] = "Funkcja blokady %s"; +App::$strings["Lock feature %s"] = "Blokuj funkcję %s"; App::$strings["Manage Additional Features"] = "Zarządzaj dodatkowymi funkcjami"; App::$strings["Queue Statistics"] = "Statystyki kolejki"; App::$strings["Total Entries"] = "Ogółem postów"; @@ -2057,7 +2057,7 @@ App::$strings["You have %1$.0f of %2$.0f allowed connections."] = "Masz %1$.0f z App::$strings["Add New Connection"] = "Dodaj nowe połączenie"; App::$strings["Enter channel address"] = "Wprowadź adres kanału"; App::$strings["Examples: bob@example.com, https://example.com/barbara"] = "Przykłady: bob@example.com, https://example.com/barbara"; -App::$strings["Suggestions"] = "Prpozycje"; +App::$strings["Suggestions"] = "Propozycje"; App::$strings["See more..."] = "Zobacz więcej..."; App::$strings["Tasks"] = "Zadania"; App::$strings["Member registrations waiting for confirmation"] = "Rejestracja członków czeka na potwierdzenie"; @@ -2314,7 +2314,7 @@ App::$strings["Musical interests:"] = "Zainteresowania muzyczne:"; App::$strings["Books, literature:"] = "Książki, literatura:"; App::$strings["Television:"] = "Telewizja:"; App::$strings["Film/dance/culture/entertainment:"] = "Film/taniec/kultura/rozrywka:"; -App::$strings["Love/Romance:"] = "Miłość/romans:"; +App::$strings["Love/Romance:"] = "Miłość/Romans:"; App::$strings["Work/employment:"] = "Praca/zatrudnienie:"; App::$strings["School/education:"] = "Szkoła/edukacja:"; App::$strings["Like this thing"] = "Jak ta rzecz"; -- cgit v1.2.3 From d2eb10d7fffe3f7265ae8f7b605ea1fe81ac43a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Budzi=C5=84ski?= Date: Sat, 30 Jan 2021 18:42:47 +0100 Subject: Fixes (!1905): - view/pl/hmessages.po - view/pl/hstrings.php --- view/pl/hmessages.po | 3 +-- view/pl/hstrings.php | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/view/pl/hmessages.po b/view/pl/hmessages.po index 07bba5233..bf8c56d73 100644 --- a/view/pl/hmessages.po +++ b/view/pl/hmessages.po @@ -10,8 +10,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 " -"|| n%100>14) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 2.3\n" #: ../../Zotlabs/Access/Permissions.php:56 diff --git a/view/pl/hstrings.php b/view/pl/hstrings.php index 4a2dd92ae..943fe36f3 100644 --- a/view/pl/hstrings.php +++ b/view/pl/hstrings.php @@ -2,8 +2,7 @@ if(! function_exists("string_plural_select_pl")) { function string_plural_select_pl($n){ - return ($n==1 ? 0 : $n%10>=2 && $n%10<=4 && ($n%100<12)) -; + return ($n==1 ? 0 : $n%10>=2 && $n%10<=4 && ($n%100<12)); }} App::$rtl = 0; App::$strings["plural_function_code"] = "(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12))"; -- cgit v1.2.3 From bac87a8aecae9bdca2f320a7d5cb3078da745d75 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sun, 31 Jan 2021 12:04:26 +0100 Subject: Fix polish plurals function --- view/pl/hmessages.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/pl/hmessages.po b/view/pl/hmessages.po index bf8c56d73..5ef34eb5e 100644 --- a/view/pl/hmessages.po +++ b/view/pl/hmessages.po @@ -10,7 +10,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2));\n" "X-Generator: Poedit 2.3\n" #: ../../Zotlabs/Access/Permissions.php:56 -- cgit v1.2.3 From 21b3ba38e710ccf08b95491aa3880548f3e2e866 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sun, 31 Jan 2021 12:05:02 +0100 Subject: Fix polish plurals function --- view/pl/hstrings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/view/pl/hstrings.php b/view/pl/hstrings.php index 943fe36f3..85bb3d0e5 100644 --- a/view/pl/hstrings.php +++ b/view/pl/hstrings.php @@ -2,10 +2,10 @@ if(! function_exists("string_plural_select_pl")) { function string_plural_select_pl($n){ - return ($n==1 ? 0 : $n%10>=2 && $n%10<=4 && ($n%100<12)); + return (n==1 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2)); }} App::$rtl = 0; -App::$strings["plural_function_code"] = "(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12))"; +App::$strings["plural_function_code"] = "(n==1 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2))"; App::$strings["Can view my channel stream and posts"] = "Może wyświetlać strumień i posty z mojego kanału"; App::$strings["Can send me their channel stream and posts"] = "Może przesyłać mi strumień swojego kanału i posty"; App::$strings["Can view my default channel profile"] = "Może wyświetlać mój domyślny profil kanału"; -- cgit v1.2.3 From c0933c90e8b02cf30126a8f7c2866a60d9d3da46 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sun, 31 Jan 2021 15:26:55 +0100 Subject: Fix copypaste --- view/pl/hstrings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/pl/hstrings.php b/view/pl/hstrings.php index 85bb3d0e5..7a58ab97f 100644 --- a/view/pl/hstrings.php +++ b/view/pl/hstrings.php @@ -2,7 +2,7 @@ if(! function_exists("string_plural_select_pl")) { function string_plural_select_pl($n){ - return (n==1 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2)); + return ($n==1 ? 0 : ($n%10>=2 && $n%10<=4 && ($n%100<12 || $n%100>14) ? 1 : 2)); }} App::$rtl = 0; App::$strings["plural_function_code"] = "(n==1 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2))"; -- cgit v1.2.3 From d99611e7dd1648e6a77d48aa612a840941545738 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 31 Jan 2021 20:37:16 +0000 Subject: add fetch_provider hook --- Zotlabs/Lib/Activity.php | 1 - Zotlabs/Module/Search.php | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index c56d73421..bab70997e 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1096,7 +1096,6 @@ class Activity { call_hooks('encode_person', $arr); $ret = $arr['encoded']; - return $ret; } diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php index 95510c349..eeeff9613 100644 --- a/Zotlabs/Module/Search.php +++ b/Zotlabs/Module/Search.php @@ -58,15 +58,13 @@ class Search extends Controller { $o .= search($search, 'search-box', '/search', ((local_channel()) ? true : false)); - if (local_channel() && strpos($search, 'https://') === 0) { + if (local_channel() && strpos($search, 'https://') === 0 && !$update && !$load) { $j = Activity::fetch($search, App::get_channel()); if ($j) { $AS = new ActivityStreams($j); - if ($AS->is_valid()) { // check if is_an_actor, otherwise import activity if (is_array($AS->obj) && !ActivityStreams::is_an_actor($AS->obj)) { - // The boolean flag enables html cache of the item $item = Activity::decode_note($AS); if ($item) { logger('parsed_item: ' . print_r($item, true), LOGGER_DATA); @@ -76,6 +74,14 @@ class Search extends Controller { } } } + else { + // try other fetch providers (e.g. diaspora) + $hookdata = [ + 'channel' => App::get_channel(), + 'data' => $search + ]; + call_hooks('fetch_provider', $hookdata); + } } if (strpos($search, '#') === 0) { @@ -120,7 +126,7 @@ class Search extends Controller { // Here is the way permissions work in the search module... // Only public posts can be shown // OR your own posts if you are a logged in member - // No items will be shown if the member has a blocked profile wall. + // No items will be shown if the member has a blocked profile wall. if ((!$update) && (!$load)) { -- cgit v1.2.3 From de91d2c804085c2a169863e67b38d2ac7da8f9c7 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Mon, 1 Feb 2021 09:53:09 +0100 Subject: Better profile photo fetch processing --- include/photo/photo_driver.php | 59 ++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index 057711f1e..97871e139 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -64,15 +64,23 @@ function photo_factory($data, $type = null) { * * @param string $filename * Image filename - * @param string $headers (optional) - * Headers to check for Content-Type (from curl request) + * @param string $data (optional) + * Data array fetched from cURL with z_fetch_url * @return null|string Guessed mimetype */ -function guess_image_type($filename, $headers = '') { -// logger('Photo: guess_image_type: '.$filename . ($headers?' from curl headers':''), LOGGER_DEBUG); +function guess_image_type($filename, $data = '') { + + if($data) + $headers = (is_array($data) ? $data['header'] : $data); + + // logger('Photo: guess_image_type: '.$filename . ($headers?' from curl headers':''), LOGGER_DEBUG); + $type = null; $m = null; + $ph = photo_factory(''); + $types = $ph->supportedTypes(); + if($headers) { $hdrs = []; $h = explode("\n", $headers); @@ -81,19 +89,14 @@ function guess_image_type($filename, $headers = '') { $hdrs[strtolower($k)] = $v; } logger('Curl headers: ' .var_export($hdrs, true), LOGGER_DEBUG); - if(array_key_exists('content-type', $hdrs)) { - $ph = photo_factory(''); - $types = $ph->supportedTypes(); - - if(array_key_exists($hdrs['content-type'], $types)) - $type = $hdrs['content-type']; - } + if(array_key_exists('content-type', $hdrs) && array_key_exists($hdrs['content-type'], $types)) + $type = $hdrs['content-type']; } if(is_null($type)){ $ignore_imagick = get_config('system', 'ignore_imagick'); // Guessing from extension? Isn't that... dangerous? - if(class_exists('Imagick') && file_exists($filename) && is_readable($filename) && !$ignore_imagick) { + if(class_exists('Imagick') && ! $ignore_imagick) { $v = Imagick::getVersion(); preg_match('/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v['versionString'], $m); if(version_compare($m[1], '6.6.7') >= 0) { @@ -102,8 +105,18 @@ function guess_image_type($filename, $headers = '') { * but at least it comes from the data inside the image, * we won't be tricked by a manipulated extension */ - $image = new Imagick($filename); - $type = $image->getImageMimeType(); + $body = false; + if (strpos($filename, 'http') === false && file_exists($filename) && is_readable($filename)) + $body == file_get_contents($filename); + elseif (is_array($data) && array_key_exists('body', $data)) + $body = $data['body']; + if ($body) { + $image = new Imagick($filename); + $image->readImageBlob($body); + $r = $image->identifyImage(); + if ($r && is_array($r) && array_key_exists($r['mimetype'], $types)) + $type = $r['mimetype']; + } } else { // earlier imagick versions have issues with scaling png's @@ -115,8 +128,6 @@ function guess_image_type($filename, $headers = '') { if(is_null($type)) { $ext = pathinfo($filename, PATHINFO_EXTENSION); - $ph = photo_factory(''); - $types = $ph->supportedTypes(); foreach($types as $m => $e) { if($ext === $e) { $type = $m; @@ -124,12 +135,11 @@ function guess_image_type($filename, $headers = '') { } } - if(is_null($type) && (strpos($filename, 'http') === false)) { + if(is_null($type) && strpos($filename, 'http') === false) { $size = getimagesize($filename); - $ph = photo_factory(''); - $types = $ph->supportedTypes(); $type = ((array_key_exists($size['mime'], $types)) ? $size['mime'] : 'image/jpeg'); } + if(is_null($type)) { if(strpos(strtolower($filename),'jpg') !== false) $type = 'image/jpeg'; @@ -139,8 +149,8 @@ function guess_image_type($filename, $headers = '') { $type = 'image/gif'; elseif(strpos(strtolower($filename),'png') !== false) $type = 'image/png'; - elseif(strpos(strtolower($filename),'webp') !== false) - $type = 'image/webp'; + elseif(strpos(strtolower($filename),'webp') !== false) + $type = 'image/webp'; } } @@ -224,7 +234,7 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) { $photo_failure = false; $img_str = ''; - if($photo) { + if($photo && strpos($photo, z_root() . '/' . get_default_profile_photo()) === false) { if($force || empty($modified)) $result = z_fetch_url($photo, true); @@ -264,7 +274,7 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) { if($result['success']) { $img_str = $result['body']; - $type = guess_image_type($photo, $result['header']); + $type = guess_image_type($photo, $result); if(is_null($type)) $photo_failure = true; } @@ -377,8 +387,7 @@ function import_channel_photo_from_url($photo, $aid, $uid) { if($result['success']) { $img_str = $result['body']; - $type = guess_image_type($photo, $result['header']); - + $type = guess_image_type($photo, $result); import_channel_photo($img_str, $type, $aid, $uid); } } -- cgit v1.2.3 From 197338a72708624eda2a704b5abff4f5695ed7fe Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 1 Feb 2021 09:30:22 +0000 Subject: remove logging --- Zotlabs/Lib/ZotURL.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Zotlabs/Lib/ZotURL.php b/Zotlabs/Lib/ZotURL.php index fa3959f69..6bb01fd7a 100644 --- a/Zotlabs/Lib/ZotURL.php +++ b/Zotlabs/Lib/ZotURL.php @@ -21,12 +21,10 @@ class ZotURL { } $portable_url = substr($url,6); - $u = explode('/',$portable_url); + $u = explode('/',$portable_url); $portable_id = $u[0]; - hz_syslog(print_r($u,true)); - $hosts = self::lookup($portable_id); - hz_syslog(print_r($hosts,true)); + if(! $hosts) { return $ret; } @@ -40,8 +38,8 @@ class ZotURL { if($channel && $m) { - $headers = [ - 'Accept' => 'application/x-zot+json', + $headers = [ + 'Accept' => 'application/x-zot+json', 'Content-Type' => 'application/x-zot+json', 'X-Zot-Token' => random_string(), 'Digest' => HTTPSig::generate_digest_header($data), @@ -51,9 +49,9 @@ class ZotURL { $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false); } else { - $h = [ 'Accept: application/x-zot+json' ]; + $h = [ 'Accept: application/x-zot+json' ]; } - + $result = []; $redirects = 0; -- cgit v1.2.3 From cd081ac077b1c244d8aca37f09f63a7410a54a10 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 1 Feb 2021 14:32:28 +0000 Subject: remove unused/commented out code --- Zotlabs/Lib/Activity.php | 101 ----------------------------------------------- 1 file changed, 101 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index bab70997e..cedc9adc8 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2493,9 +2493,6 @@ class Activity { $item['item_private'] = 2; }*/ - // TODO: remove - // $is_parent = (($item['parent_mid'] && $item['parent_mid'] === $item['mid']) ? true : false); - if ($item['parent_mid'] && $item['parent_mid'] !== $item['mid']) { $is_child_node = true; } @@ -2574,12 +2571,6 @@ class Activity { }*/ } - // TODO: remove - /*if ($is_parent && (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !($is_sys_channel && $pubstream))) { - logger('no permission'); - return; - }*/ - if (tgroup_check($channel['channel_id'], $item) && (!$is_child_node)) { // for forum deliveries, make sure we keep a copy of the signed original set_iconfig($item, 'activitypub', 'rawmsg', $act->raw, 1); @@ -2629,15 +2620,6 @@ class Activity { return; } - // TODO: remove - /*if (is_array($act->obj)) { - $content = self::get_content($act->obj); - } - if (!$content) { - logger('no content'); - return; - }*/ - $item['aid'] = $channel['channel_account_id']; $item['uid'] = $channel['channel_id']; @@ -2704,54 +2686,6 @@ class Activity { $parent = null; - // TODO: remove - /*if (!$is_parent) { - $p = q("select parent_mid, id, obj_type from item where mid = '%s' and uid = %d limit 1", - dbesc($item['parent_mid']), - intval($item['uid']) - ); - if (!$p) { - $a = (($fetch_parents) ? self::fetch_and_store_parents($channel, $item) : false); - if ($a) { - $p = q("select parent_mid from item where mid = '%s' and uid = %d limit 1", - dbesc($item['parent_mid']), - intval($item['uid']) - ); - } - else { - logger('could not fetch parents'); - return; - - // @TODO we maybe could accept these is we formatted the body correctly with share_bb() - // or at least provided a link to the object - // if(in_array($act->type,[ 'Like','Dislike' ])) { - // return; - // } - - // @TODO do we actually want that? - // if no parent was fetched, turn into a top-level post - - // turn into a top level post - // $s['parent_mid'] = $s['mid']; - // $s['thr_parent'] = $s['mid']; - } - } - - if ($p[0]['obj_type'] === 'Question') { - if ($item['obj_type'] === ACTIVITY_OBJ_NOTE && $item['title'] && (!$item['content'])) { - $item['obj_type'] = 'Answer'; - } - } - - if ($p[0]['parent_mid'] !== $item['parent_mid']) { - $item['thr_parent'] = $item['parent_mid']; - } - else { - $item['thr_parent'] = $p[0]['parent_mid']; - } - $item['parent_mid'] = $p[0]['parent_mid']; - }*/ - if ($is_child_node) { $parent = q("select * from item where mid = '%s' and uid = %d limit 1", @@ -2811,24 +2745,6 @@ class Activity { $x = item_store($item); } - // TODO: remove - /*$r = q("select id, created, edited from item where mid = '%s' and uid = %d limit 1", - dbesc($item['mid']), - intval($item['uid']) - ); - if ($r) { - if ($item['edited'] > $r[0]['edited']) { - $item['id'] = $r[0]['id']; - $x = item_store_update($item); - } - else { - return; - } - } - else { - $x = item_store($item); - }*/ - if ($fetch_parents && $parent && !intval($parent[0]['item_private'])) { logger('topfetch', LOGGER_DEBUG); // if the thread owner is a connnection, we will already receive any additional comments to their posts @@ -2870,23 +2786,6 @@ class Activity { sync_an_item($channel['channel_id'], $x['item_id']); } - // TODO: remove - /*if (is_array($x) && $x['item_id']) { - if ($is_parent) { - if ($item['owner_xchan'] === $channel['channel_hash']) { - // We are the owner of this conversation, so send all received comments back downstream - Master::Summon(['Notifier', 'comment-import', $x['item_id']]); - } - $r = q("select * from item where id = %d limit 1", - intval($x['item_id']) - ); - if ($r) { - send_status_notifications($x['item_id'], $r[0]); - } - } - sync_an_item($channel['channel_id'], $x['item_id']); - }*/ - } static public function fetch_and_store_parents($channel, $observer_hash, $item, $force = false) { -- cgit v1.2.3 From 70fa7ad8d0fe3bab4f9702ba2d5ac0065977c567 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 1 Feb 2021 20:52:35 +0000 Subject: too many arguments --- Zotlabs/Daemon/Convo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Daemon/Convo.php b/Zotlabs/Daemon/Convo.php index f7478d778..940216b2c 100644 --- a/Zotlabs/Daemon/Convo.php +++ b/Zotlabs/Daemon/Convo.php @@ -49,7 +49,7 @@ class Convo { // and that lets us use implied_create $AS = new ActivityStreams($message); if ($AS->is_valid() && is_array($AS->obj)) { - $item = Activity::decode_note($AS, true); + $item = Activity::decode_note($AS); Activity::store($channel, $contact['abook_xchan'], $AS, $item); } } -- cgit v1.2.3 From 08c9152abdfa90da09931bdcc6e6c81ea243434c Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 1 Feb 2021 22:58:55 +0000 Subject: fix getting mimetype via getimagesize() and do not default to image/jpeg yet if it could not be found --- include/photo/photo_driver.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index 97871e139..87b1d96fe 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -69,7 +69,7 @@ function photo_factory($data, $type = null) { * @return null|string Guessed mimetype */ function guess_image_type($filename, $data = '') { - + if($data) $headers = (is_array($data) ? $data['header'] : $data); @@ -135,9 +135,10 @@ function guess_image_type($filename, $data = '') { } } - if(is_null($type) && strpos($filename, 'http') === false) { + if(is_null($type) && strpos($filename, 'http') === 0) { $size = getimagesize($filename); - $type = ((array_key_exists($size['mime'], $types)) ? $size['mime'] : 'image/jpeg'); + if (array_key_exists($size['mime'], $types)) + $type = $size['mime']; } if(is_null($type)) { -- cgit v1.2.3 From f3f49cf80f2441d576d825f116afdb5a66bb7c54 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Tue, 2 Feb 2021 10:58:10 +0100 Subject: fix php8 issues --- Zotlabs/Lib/Apps.php | 2 +- Zotlabs/Web/HTTPSig.php | 10 ++++++---- include/markdown.php | 9 ++++++--- include/permissions.php | 2 +- include/plugin.php | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php index 05b2ba177..d77a3fda2 100644 --- a/Zotlabs/Lib/Apps.php +++ b/Zotlabs/Lib/Apps.php @@ -307,7 +307,7 @@ class Apps { } } } - if($ret) { + if(isset($ret)) { if($translate) self::translate_system_apps($ret); diff --git a/Zotlabs/Web/HTTPSig.php b/Zotlabs/Web/HTTPSig.php index 0b3e2bf2e..7c3903682 100644 --- a/Zotlabs/Web/HTTPSig.php +++ b/Zotlabs/Web/HTTPSig.php @@ -161,6 +161,8 @@ class HTTPSig { logger('verified: ' . $x, LOGGER_DEBUG); + $fetched_key = ''; + if(! $x) { // try again, ignoring the local actor (xchan) cache and refetching the key @@ -244,7 +246,7 @@ class HTTPSig { } - function convertKey($key) { + static function convertKey($key) { if(strstr($key,'RSA ')) { return rsatopem($key); @@ -267,7 +269,7 @@ class HTTPSig { * false if no pub key found, otherwise return the pub key */ - function get_activitystreams_key($id) { + static function get_activitystreams_key($id) { // remove fragment @@ -298,7 +300,7 @@ class HTTPSig { } - function get_webfinger_key($id) { + static function get_webfinger_key($id) { $x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s'", dbesc(str_replace('acct:','',$id)), @@ -333,7 +335,7 @@ class HTTPSig { return (($key['public_key']) ? $key : false); } - function get_zotfinger_key($id) { + static function get_zotfinger_key($id) { $x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' and hubloc_network = 'zot6'", dbesc(str_replace('acct:','',$id)), diff --git a/include/markdown.php b/include/markdown.php index 0bfe595b8..013d57c29 100644 --- a/include/markdown.php +++ b/include/markdown.php @@ -213,6 +213,11 @@ function bb_to_markdown_share($match) { } +function bb_to_markdown_transform_tags($match) { + return '#'. str_replace(' ', '_', $match[3]); +} + + /** * @brief Convert bbcode to Markdown. * @@ -226,8 +231,7 @@ function bb_to_markdown($Text, $options = []) { * Transform #tags, strip off the [url] and replace spaces with underscore */ - $Text = preg_replace_callback('/#\[([zu])rl\=(.*?)\](.*?)\[\/[(zu)]rl\]/i', - create_function('$match', 'return \'#\'. str_replace(\' \', \'_\', $match[3]);'), $Text); + $Text = preg_replace_callback('/#\[([zu])rl\=(.*?)\](.*?)\[\/[(zu)]rl\]/i', 'bb_to_markdown_transform_tags', $Text); $Text = preg_replace('/#\^\[([zu])rl\=(.*?)\](.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text); @@ -282,7 +286,6 @@ function bb_to_markdown($Text, $options = []) { return $Text; } - /** * @brief Convert a HTML text into Markdown. * diff --git a/include/permissions.php b/include/permissions.php index ca8ff6e93..c7eee11f4 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -279,7 +279,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = // First find out what the channel owner declared permissions to be. - $channel_perm = \Zotlabs\Access\PermissionLimits::Get($uid,$permission); + $channel_perm = intval(\Zotlabs\Access\PermissionLimits::Get($uid,$permission)); $r = q("select channel_pageflags, channel_moved, channel_hash from channel where channel_id = %d limit 1", intval($uid) diff --git a/include/plugin.php b/include/plugin.php index c789ad522..269903373 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -912,7 +912,7 @@ function script_path() { // Some proxy setups may require using http_host - if(intval(App::$config['system']['script_path_use_http_host'])) + if(isset(App::$config['system']['script_path_use_http_host']) && intval(App::$config['system']['script_path_use_http_host'])) $server_var = 'HTTP_HOST'; else $server_var = 'SERVER_NAME'; -- cgit v1.2.3 From e312c381d897866b15179fd301d9979b46f2f678 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Tue, 2 Feb 2021 11:47:38 +0100 Subject: import_xchan() $arr photo structure has changed --- Zotlabs/Lib/Libzot.php | 6 +++--- Zotlabs/Lib/Libzotdir.php | 3 ++- include/html2bbcode.php | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index fd30f05f5..0ead8402e 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -763,8 +763,8 @@ class Libzot { 'xchan_guid' => $arr['id'], 'xchan_guid_sig' => $arr['id_sig'], 'xchan_pubkey' => $arr['public_key'], - 'xchan_photo_mimetype' => $arr['photo_mimetype'], - 'xchan_photo_l' => $arr['photo'], + 'xchan_photo_mimetype' => $arr['photo']['type'], + 'xchan_photo_l' => $arr['photo']['url'], 'xchan_addr' => escape_tags($arr['primary_location']['address']), 'xchan_url' => escape_tags($arr['primary_location']['url']), 'xchan_connurl' => $arr['primary_location']['connections_url'], @@ -772,7 +772,7 @@ class Libzot { 'xchan_connpage' => $arr['connect_url'], 'xchan_name' => (($arr['name']) ? escape_tags($arr['name']) : '-'), 'xchan_network' => 'zot6', - 'xchan_photo_date' => $arr['photo_updated'], + 'xchan_photo_date' => $arr['photo']['updated'], 'xchan_name_date' => $arr['name_updated'], 'xchan_hidden' => intval(1 - intval($arr['searchable'])), 'xchan_selfcensored' => $arr['adult_content'], diff --git a/Zotlabs/Lib/Libzotdir.php b/Zotlabs/Lib/Libzotdir.php index d4c5398ee..41c0a54e9 100644 --- a/Zotlabs/Lib/Libzotdir.php +++ b/Zotlabs/Lib/Libzotdir.php @@ -311,12 +311,13 @@ class Libzotdir { if ($ud['ud_addr'] && (! ($ud['ud_flags'] & UPDATE_FLAGS_DELETED))) { $success = false; + $zf = []; $href = Webfinger::zot_url(punify($ud['ud_addr'])); if($href) { $zf = Zotfinger::exec($href); } - if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) { + if(array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) { $xc = Libzot::import_xchan($zf['data'], 0, $ud); } else { diff --git a/include/html2bbcode.php b/include/html2bbcode.php index c916421b8..173ea63bd 100644 --- a/include/html2bbcode.php +++ b/include/html2bbcode.php @@ -87,6 +87,9 @@ function deletenode(&$doc, $node) function html2bbcode($message) { + if(!$message) + return; + $message = str_replace("\r", "", $message); $message = str_replace(array( -- cgit v1.2.3 From 2167d12b3fd9a66006b83cc8660325b6f8831a70 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 2 Feb 2021 12:57:46 +0000 Subject: composer add phpseclib --- composer.json | 3 +- composer.lock | 237 +- vendor/composer/InstalledVersions.php | 41 +- vendor/composer/autoload_classmap.php | 345 ++ vendor/composer/autoload_files.php | 1 + vendor/composer/autoload_psr4.php | 2 + vendor/composer/autoload_static.php | 359 ++ vendor/composer/installed.json | 237 + vendor/composer/installed.php | 31 +- vendor/composer/platform_check.php | 4 +- .../league/html-to-markdown/bin/html-to-markdown | 0 vendor/paragonie/constant_time_encoding/.gitignore | 2 + .../paragonie/constant_time_encoding/.travis.yml | 24 + .../paragonie/constant_time_encoding/LICENSE.txt | 48 + vendor/paragonie/constant_time_encoding/README.md | 84 + .../paragonie/constant_time_encoding/composer.json | 51 + .../constant_time_encoding/phpunit.xml.dist | 13 + vendor/paragonie/constant_time_encoding/psalm.xml | 9 + .../constant_time_encoding/src/Base32.php | 471 ++ .../constant_time_encoding/src/Base32Hex.php | 111 + .../constant_time_encoding/src/Base64.php | 271 ++ .../constant_time_encoding/src/Base64DotSlash.php | 88 + .../src/Base64DotSlashOrdered.php | 82 + .../constant_time_encoding/src/Base64UrlSafe.php | 95 + .../constant_time_encoding/src/Binary.php | 85 + .../src/EncoderInterface.php | 52 + .../constant_time_encoding/src/Encoding.php | 260 + .../paragonie/constant_time_encoding/src/Hex.php | 159 + .../constant_time_encoding/src/RFC4648.php | 175 + vendor/paragonie/random_compat/LICENSE | 22 + vendor/paragonie/random_compat/build-phar.sh | 5 + vendor/paragonie/random_compat/composer.json | 34 + .../random_compat/dist/random_compat.phar.pubkey | 5 + .../dist/random_compat.phar.pubkey.asc | 11 + vendor/paragonie/random_compat/lib/random.php | 32 + .../paragonie/random_compat/other/build_phar.php | 57 + vendor/paragonie/random_compat/psalm-autoload.php | 9 + vendor/paragonie/random_compat/psalm.xml | 19 + vendor/phpseclib/phpseclib/.github/FUNDING.yml | 12 + vendor/phpseclib/phpseclib/AUTHORS | 6 + vendor/phpseclib/phpseclib/BACKERS.md | 8 + vendor/phpseclib/phpseclib/LICENSE | 20 + vendor/phpseclib/phpseclib/README.md | 94 + vendor/phpseclib/phpseclib/appveyor.yml | 27 + vendor/phpseclib/phpseclib/composer.json | 77 + .../phpseclib/Common/Functions/Strings.php | 387 ++ vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php | 123 + .../phpseclib/phpseclib/Crypt/Blowfish.php | 556 +++ .../phpseclib/phpseclib/Crypt/ChaCha20.php | 797 ++++ .../phpseclib/Crypt/Common/AsymmetricKey.php | 492 ++ .../phpseclib/Crypt/Common/BlockCipher.php | 27 + .../Crypt/Common/Formats/Keys/OpenSSH.php | 234 + .../phpseclib/Crypt/Common/Formats/Keys/PKCS.php | 80 + .../phpseclib/Crypt/Common/Formats/Keys/PKCS1.php | 223 + .../phpseclib/Crypt/Common/Formats/Keys/PKCS8.php | 702 +++ .../phpseclib/Crypt/Common/Formats/Keys/PuTTY.php | 261 ++ .../Crypt/Common/Formats/Signature/Raw.php | 66 + .../phpseclib/Crypt/Common/PrivateKey.php | 30 + .../phpseclib/phpseclib/Crypt/Common/PublicKey.php | 29 + .../phpseclib/Crypt/Common/StreamCipher.php | 59 + .../phpseclib/Crypt/Common/SymmetricKey.php | 3271 +++++++++++++ .../phpseclib/Crypt/Common/Traits/Fingerprint.php | 62 + .../Crypt/Common/Traits/PasswordProtected.php | 51 + vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php | 1411 ++++++ vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php | 400 ++ .../phpseclib/Crypt/DH/Formats/Keys/PKCS1.php | 83 + .../phpseclib/Crypt/DH/Formats/Keys/PKCS8.php | 157 + .../phpseclib/phpseclib/Crypt/DH/Parameters.php | 40 + .../phpseclib/phpseclib/Crypt/DH/PrivateKey.php | 82 + .../phpseclib/phpseclib/Crypt/DH/PublicKey.php | 53 + vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php | 344 ++ .../phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php | 126 + .../phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php | 151 + .../phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php | 170 + .../phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php | 118 + .../phpseclib/Crypt/DSA/Formats/Keys/Raw.php | 92 + .../phpseclib/Crypt/DSA/Formats/Keys/XML.php | 133 + .../phpseclib/Crypt/DSA/Formats/Signature/ASN1.php | 68 + .../phpseclib/Crypt/DSA/Formats/Signature/Raw.php | 29 + .../phpseclib/Crypt/DSA/Formats/Signature/SSH2.php | 78 + .../phpseclib/phpseclib/Crypt/DSA/Parameters.php | 40 + .../phpseclib/phpseclib/Crypt/DSA/PrivateKey.php | 159 + .../phpseclib/phpseclib/Crypt/DSA/PublicKey.php | 91 + vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php | 477 ++ .../phpseclib/Crypt/EC/BaseCurves/Base.php | 220 + .../phpseclib/Crypt/EC/BaseCurves/Binary.php | 378 ++ .../phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php | 325 ++ .../phpseclib/Crypt/EC/BaseCurves/Montgomery.php | 285 ++ .../phpseclib/Crypt/EC/BaseCurves/Prime.php | 774 +++ .../Crypt/EC/BaseCurves/TwistedEdwards.php | 219 + .../phpseclib/Crypt/EC/Curves/Curve25519.php | 64 + .../phpseclib/Crypt/EC/Curves/Curve448.php | 71 + .../phpseclib/Crypt/EC/Curves/Ed25519.php | 334 ++ .../phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php | 267 ++ .../phpseclib/Crypt/EC/Curves/brainpoolP160r1.php | 36 + .../phpseclib/Crypt/EC/Curves/brainpoolP160t1.php | 49 + .../phpseclib/Crypt/EC/Curves/brainpoolP192r1.php | 36 + .../phpseclib/Crypt/EC/Curves/brainpoolP192t1.php | 36 + .../phpseclib/Crypt/EC/Curves/brainpoolP224r1.php | 36 + .../phpseclib/Crypt/EC/Curves/brainpoolP224t1.php | 36 + .../phpseclib/Crypt/EC/Curves/brainpoolP256r1.php | 36 + .../phpseclib/Crypt/EC/Curves/brainpoolP256t1.php | 36 + .../phpseclib/Crypt/EC/Curves/brainpoolP320r1.php | 42 + .../phpseclib/Crypt/EC/Curves/brainpoolP320t1.php | 42 + .../phpseclib/Crypt/EC/Curves/brainpoolP384r1.php | 48 + .../phpseclib/Crypt/EC/Curves/brainpoolP384t1.php | 48 + .../phpseclib/Crypt/EC/Curves/brainpoolP512r1.php | 48 + .../phpseclib/Crypt/EC/Curves/brainpoolP512t1.php | 48 + .../phpseclib/Crypt/EC/Curves/nistb233.php | 20 + .../phpseclib/Crypt/EC/Curves/nistb409.php | 20 + .../phpseclib/Crypt/EC/Curves/nistk163.php | 20 + .../phpseclib/Crypt/EC/Curves/nistk233.php | 20 + .../phpseclib/Crypt/EC/Curves/nistk283.php | 20 + .../phpseclib/Crypt/EC/Curves/nistk409.php | 20 + .../phpseclib/Crypt/EC/Curves/nistp192.php | 20 + .../phpseclib/Crypt/EC/Curves/nistp224.php | 20 + .../phpseclib/Crypt/EC/Curves/nistp256.php | 20 + .../phpseclib/Crypt/EC/Curves/nistp384.php | 20 + .../phpseclib/Crypt/EC/Curves/nistp521.php | 20 + .../phpseclib/Crypt/EC/Curves/nistt571.php | 20 + .../phpseclib/Crypt/EC/Curves/prime192v1.php | 20 + .../phpseclib/Crypt/EC/Curves/prime192v2.php | 36 + .../phpseclib/Crypt/EC/Curves/prime192v3.php | 36 + .../phpseclib/Crypt/EC/Curves/prime239v1.php | 36 + .../phpseclib/Crypt/EC/Curves/prime239v2.php | 36 + .../phpseclib/Crypt/EC/Curves/prime239v3.php | 36 + .../phpseclib/Crypt/EC/Curves/prime256v1.php | 20 + .../phpseclib/Crypt/EC/Curves/secp112r1.php | 36 + .../phpseclib/Crypt/EC/Curves/secp112r2.php | 37 + .../phpseclib/Crypt/EC/Curves/secp128r1.php | 36 + .../phpseclib/Crypt/EC/Curves/secp128r2.php | 37 + .../phpseclib/Crypt/EC/Curves/secp160k1.php | 48 + .../phpseclib/Crypt/EC/Curves/secp160r1.php | 36 + .../phpseclib/Crypt/EC/Curves/secp160r2.php | 37 + .../phpseclib/Crypt/EC/Curves/secp192k1.php | 47 + .../phpseclib/Crypt/EC/Curves/secp192r1.php | 80 + .../phpseclib/Crypt/EC/Curves/secp224k1.php | 47 + .../phpseclib/Crypt/EC/Curves/secp224r1.php | 36 + .../phpseclib/Crypt/EC/Curves/secp256k1.php | 51 + .../phpseclib/Crypt/EC/Curves/secp256r1.php | 36 + .../phpseclib/Crypt/EC/Curves/secp384r1.php | 54 + .../phpseclib/Crypt/EC/Curves/secp521r1.php | 48 + .../phpseclib/Crypt/EC/Curves/sect113r1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect113r2.php | 36 + .../phpseclib/Crypt/EC/Curves/sect131r1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect131r2.php | 36 + .../phpseclib/Crypt/EC/Curves/sect163k1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect163r1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect163r2.php | 36 + .../phpseclib/Crypt/EC/Curves/sect193r1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect193r2.php | 36 + .../phpseclib/Crypt/EC/Curves/sect233k1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect233r1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect239k1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect283k1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect283r1.php | 36 + .../phpseclib/Crypt/EC/Curves/sect409k1.php | 39 + .../phpseclib/Crypt/EC/Curves/sect409r1.php | 39 + .../phpseclib/Crypt/EC/Curves/sect571k1.php | 43 + .../phpseclib/Crypt/EC/Curves/sect571r1.php | 43 + .../phpseclib/Crypt/EC/Formats/Keys/Common.php | 555 +++ .../Crypt/EC/Formats/Keys/MontgomeryPrivate.php | 108 + .../Crypt/EC/Formats/Keys/MontgomeryPublic.php | 79 + .../phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php | 216 + .../phpseclib/Crypt/EC/Formats/Keys/PKCS1.php | 203 + .../phpseclib/Crypt/EC/Formats/Keys/PKCS8.php | 249 + .../phpseclib/Crypt/EC/Formats/Keys/PuTTY.php | 146 + .../phpseclib/Crypt/EC/Formats/Keys/XML.php | 484 ++ .../phpseclib/Crypt/EC/Formats/Keys/libsodium.php | 122 + .../phpseclib/Crypt/EC/Formats/Signature/ASN1.php | 68 + .../phpseclib/Crypt/EC/Formats/Signature/Raw.php | 29 + .../phpseclib/Crypt/EC/Formats/Signature/SSH2.php | 100 + .../phpseclib/phpseclib/Crypt/EC/Parameters.php | 40 + .../phpseclib/phpseclib/Crypt/EC/PrivateKey.php | 258 + .../phpseclib/phpseclib/Crypt/EC/PublicKey.php | 177 + .../phpseclib/phpseclib/phpseclib/Crypt/Hash.php | 1484 ++++++ .../phpseclib/phpseclib/Crypt/PublicKeyLoader.php | 64 + vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php | 669 +++ vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php | 309 ++ vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php | 837 ++++ .../phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php | 242 + .../phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php | 140 + .../phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php | 167 + .../phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php | 149 + .../phpseclib/Crypt/RSA/Formats/Keys/PSS.php | 250 + .../phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php | 130 + .../phpseclib/Crypt/RSA/Formats/Keys/Raw.php | 108 + .../phpseclib/Crypt/RSA/Formats/Keys/XML.php | 173 + .../phpseclib/phpseclib/Crypt/RSA/PrivateKey.php | 556 +++ .../phpseclib/phpseclib/Crypt/RSA/PublicKey.php | 507 ++ .../phpseclib/phpseclib/phpseclib/Crypt/Random.php | 223 + .../phpseclib/phpseclib/Crypt/Rijndael.php | 1022 ++++ .../phpseclib/phpseclib/Crypt/Salsa20.php | 529 +++ .../phpseclib/phpseclib/Crypt/TripleDES.php | 456 ++ .../phpseclib/phpseclib/Crypt/Twofish.php | 826 ++++ .../Exception/BadConfigurationException.php | 26 + .../phpseclib/Exception/BadDecryptionException.php | 26 + .../phpseclib/Exception/BadModeException.php | 26 + .../Exception/ConnectionClosedException.php | 26 + .../phpseclib/Exception/FileNotFoundException.php | 26 + .../Exception/InconsistentSetupException.php | 26 + .../Exception/InsufficientSetupException.php | 26 + .../phpseclib/Exception/NoKeyLoadedException.php | 26 + .../Exception/NoSupportedAlgorithmsException.php | 26 + .../Exception/UnableToConnectException.php | 26 + .../Exception/UnsupportedAlgorithmException.php | 26 + .../Exception/UnsupportedCurveException.php | 26 + .../Exception/UnsupportedFormatException.php | 26 + .../Exception/UnsupportedOperationException.php | 26 + vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php | 580 +++ vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php | 1498 ++++++ .../phpseclib/phpseclib/File/ASN1/Element.php | 49 + .../phpseclib/File/ASN1/Maps/AccessDescription.php | 36 + .../File/ASN1/Maps/AdministrationDomainName.php | 40 + .../File/ASN1/Maps/AlgorithmIdentifier.php | 39 + .../phpseclib/File/ASN1/Maps/AnotherName.php | 41 + .../phpseclib/File/ASN1/Maps/Attribute.php | 41 + .../phpseclib/File/ASN1/Maps/AttributeType.php | 30 + .../File/ASN1/Maps/AttributeTypeAndValue.php | 36 + .../phpseclib/File/ASN1/Maps/AttributeValue.php | 30 + .../phpseclib/File/ASN1/Maps/Attributes.php | 35 + .../File/ASN1/Maps/AuthorityInfoAccessSyntax.php | 35 + .../File/ASN1/Maps/AuthorityKeyIdentifier.php | 49 + .../phpseclib/File/ASN1/Maps/BaseDistance.php | 30 + .../phpseclib/File/ASN1/Maps/BasicConstraints.php | 43 + .../ASN1/Maps/BuiltInDomainDefinedAttribute.php | 36 + .../ASN1/Maps/BuiltInDomainDefinedAttributes.php | 35 + .../File/ASN1/Maps/BuiltInStandardAttributes.php | 71 + .../phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php | 30 + .../File/ASN1/Maps/CRLDistributionPoints.php | 35 + .../phpseclib/File/ASN1/Maps/CRLNumber.php | 30 + .../phpseclib/File/ASN1/Maps/CRLReason.php | 45 + .../phpseclib/File/ASN1/Maps/CertPolicyId.php | 30 + .../phpseclib/File/ASN1/Maps/Certificate.php | 37 + .../phpseclib/File/ASN1/Maps/CertificateIssuer.php | 30 + .../phpseclib/File/ASN1/Maps/CertificateList.php | 37 + .../File/ASN1/Maps/CertificatePolicies.php | 35 + .../File/ASN1/Maps/CertificateSerialNumber.php | 30 + .../File/ASN1/Maps/CertificationRequest.php | 37 + .../File/ASN1/Maps/CertificationRequestInfo.php | 45 + .../File/ASN1/Maps/Characteristic_two.php | 40 + .../phpseclib/File/ASN1/Maps/CountryName.php | 40 + .../phpseclib/phpseclib/File/ASN1/Maps/Curve.php | 40 + .../phpseclib/File/ASN1/Maps/DHParameter.php | 42 + .../phpseclib/File/ASN1/Maps/DSAParams.php | 37 + .../phpseclib/File/ASN1/Maps/DSAPrivateKey.php | 40 + .../phpseclib/File/ASN1/Maps/DSAPublicKey.php | 30 + .../phpseclib/File/ASN1/Maps/DigestInfo.php | 38 + .../phpseclib/File/ASN1/Maps/DirectoryString.php | 39 + .../phpseclib/File/ASN1/Maps/DisplayText.php | 38 + .../phpseclib/File/ASN1/Maps/DistributionPoint.php | 49 + .../File/ASN1/Maps/DistributionPointName.php | 44 + .../phpseclib/File/ASN1/Maps/DssSigValue.php | 36 + .../phpseclib/File/ASN1/Maps/ECParameters.php | 49 + .../phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php | 30 + .../phpseclib/File/ASN1/Maps/ECPrivateKey.php | 52 + .../phpseclib/File/ASN1/Maps/EDIPartyName.php | 46 + .../phpseclib/File/ASN1/Maps/EcdsaSigValue.php | 36 + .../phpseclib/File/ASN1/Maps/EncryptedData.php | 30 + .../File/ASN1/Maps/EncryptedPrivateKeyInfo.php | 36 + .../phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php | 35 + .../phpseclib/File/ASN1/Maps/Extension.php | 47 + .../File/ASN1/Maps/ExtensionAttribute.php | 46 + .../File/ASN1/Maps/ExtensionAttributes.php | 35 + .../phpseclib/File/ASN1/Maps/Extensions.php | 37 + .../phpseclib/File/ASN1/Maps/FieldElement.php | 30 + .../phpseclib/phpseclib/File/ASN1/Maps/FieldID.php | 39 + .../phpseclib/File/ASN1/Maps/GeneralName.php | 84 + .../phpseclib/File/ASN1/Maps/GeneralNames.php | 35 + .../phpseclib/File/ASN1/Maps/GeneralSubtree.php | 46 + .../phpseclib/File/ASN1/Maps/GeneralSubtrees.php | 35 + .../phpseclib/File/ASN1/Maps/HashAlgorithm.php | 30 + .../File/ASN1/Maps/HoldInstructionCode.php | 30 + .../phpseclib/File/ASN1/Maps/InvalidityDate.php | 30 + .../phpseclib/File/ASN1/Maps/IssuerAltName.php | 30 + .../File/ASN1/Maps/IssuingDistributionPoint.php | 72 + .../phpseclib/File/ASN1/Maps/KeyIdentifier.php | 30 + .../phpseclib/File/ASN1/Maps/KeyPurposeId.php | 30 + .../phpseclib/File/ASN1/Maps/KeyUsage.php | 43 + .../phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php | 30 + .../phpseclib/phpseclib/File/ASN1/Maps/Name.php | 35 + .../phpseclib/File/ASN1/Maps/NameConstraints.php | 44 + .../phpseclib/File/ASN1/Maps/NetworkAddress.php | 30 + .../phpseclib/File/ASN1/Maps/NoticeReference.php | 41 + .../File/ASN1/Maps/NumericUserIdentifier.php | 30 + .../phpseclib/File/ASN1/Maps/ORAddress.php | 37 + .../phpseclib/File/ASN1/Maps/OneAsymmetricKey.php | 52 + .../phpseclib/File/ASN1/Maps/OrganizationName.php | 30 + .../File/ASN1/Maps/OrganizationalUnitNames.php | 35 + .../phpseclib/File/ASN1/Maps/OtherPrimeInfo.php | 38 + .../phpseclib/File/ASN1/Maps/OtherPrimeInfos.php | 36 + .../phpseclib/File/ASN1/Maps/PBEParameter.php | 38 + .../phpseclib/File/ASN1/Maps/PBES2params.php | 38 + .../phpseclib/File/ASN1/Maps/PBKDF2params.php | 45 + .../phpseclib/File/ASN1/Maps/PBMAC1params.php | 38 + .../phpseclib/File/ASN1/Maps/PKCS9String.php | 36 + .../phpseclib/File/ASN1/Maps/Pentanomial.php | 37 + .../phpseclib/File/ASN1/Maps/PersonalName.php | 58 + .../phpseclib/File/ASN1/Maps/PolicyInformation.php | 42 + .../phpseclib/File/ASN1/Maps/PolicyMappings.php | 41 + .../phpseclib/File/ASN1/Maps/PolicyQualifierId.php | 30 + .../File/ASN1/Maps/PolicyQualifierInfo.php | 36 + .../phpseclib/File/ASN1/Maps/PostalAddress.php | 36 + .../phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php | 30 + .../phpseclib/File/ASN1/Maps/PrivateDomainName.php | 36 + .../phpseclib/File/ASN1/Maps/PrivateKey.php | 30 + .../phpseclib/File/ASN1/Maps/PrivateKeyInfo.php | 45 + .../File/ASN1/Maps/PrivateKeyUsagePeriod.php | 44 + .../phpseclib/File/ASN1/Maps/PublicKey.php | 30 + .../File/ASN1/Maps/PublicKeyAndChallenge.php | 36 + .../phpseclib/File/ASN1/Maps/PublicKeyInfo.php | 39 + .../phpseclib/File/ASN1/Maps/RC2CBCParameter.php | 41 + .../phpseclib/File/ASN1/Maps/RDNSequence.php | 42 + .../phpseclib/File/ASN1/Maps/RSAPrivateKey.php | 48 + .../phpseclib/File/ASN1/Maps/RSAPublicKey.php | 36 + .../phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php | 62 + .../phpseclib/File/ASN1/Maps/ReasonFlags.php | 43 + .../File/ASN1/Maps/RelativeDistinguishedName.php | 41 + .../File/ASN1/Maps/RevokedCertificate.php | 39 + .../File/ASN1/Maps/SignedPublicKeyAndChallenge.php | 37 + .../phpseclib/File/ASN1/Maps/SpecifiedECDomain.php | 49 + .../phpseclib/File/ASN1/Maps/SubjectAltName.php | 30 + .../File/ASN1/Maps/SubjectDirectoryAttributes.php | 35 + .../File/ASN1/Maps/SubjectInfoAccessSyntax.php | 35 + .../File/ASN1/Maps/SubjectPublicKeyInfo.php | 36 + .../phpseclib/File/ASN1/Maps/TBSCertList.php | 58 + .../phpseclib/File/ASN1/Maps/TBSCertificate.php | 69 + .../File/ASN1/Maps/TerminalIdentifier.php | 30 + .../phpseclib/phpseclib/File/ASN1/Maps/Time.php | 36 + .../phpseclib/File/ASN1/Maps/Trinomial.php | 30 + .../phpseclib/File/ASN1/Maps/UniqueIdentifier.php | 30 + .../phpseclib/File/ASN1/Maps/UserNotice.php | 42 + .../phpseclib/File/ASN1/Maps/Validity.php | 36 + .../File/ASN1/Maps/netscape_ca_policy_url.php | 30 + .../File/ASN1/Maps/netscape_cert_type.php | 44 + .../phpseclib/File/ASN1/Maps/netscape_comment.php | 30 + vendor/phpseclib/phpseclib/phpseclib/File/X509.php | 4076 ++++++++++++++++ .../phpseclib/phpseclib/Math/BigInteger.php | 864 ++++ .../phpseclib/Math/BigInteger/Engines/BCMath.php | 742 +++ .../Math/BigInteger/Engines/BCMath/Base.php | 116 + .../Math/BigInteger/Engines/BCMath/BuiltIn.php | 44 + .../BigInteger/Engines/BCMath/DefaultEngine.php | 29 + .../Math/BigInteger/Engines/BCMath/OpenSSL.php | 29 + .../Engines/BCMath/Reductions/Barrett.php | 193 + .../Engines/BCMath/Reductions/EvalBarrett.php | 117 + .../phpseclib/Math/BigInteger/Engines/Engine.php | 1219 +++++ .../phpseclib/Math/BigInteger/Engines/GMP.php | 751 +++ .../Math/BigInteger/Engines/GMP/DefaultEngine.php | 44 + .../phpseclib/Math/BigInteger/Engines/OpenSSL.php | 75 + .../phpseclib/Math/BigInteger/Engines/PHP.php | 1316 ++++++ .../phpseclib/Math/BigInteger/Engines/PHP/Base.php | 149 + .../Math/BigInteger/Engines/PHP/DefaultEngine.php | 29 + .../Math/BigInteger/Engines/PHP/Montgomery.php | 93 + .../Math/BigInteger/Engines/PHP/OpenSSL.php | 29 + .../BigInteger/Engines/PHP/Reductions/Barrett.php | 284 ++ .../BigInteger/Engines/PHP/Reductions/Classic.php | 46 + .../Engines/PHP/Reductions/EvalBarrett.php | 492 ++ .../Engines/PHP/Reductions/Montgomery.php | 130 + .../Engines/PHP/Reductions/MontgomeryMult.php | 81 + .../Engines/PHP/Reductions/PowerOfTwo.php | 63 + .../phpseclib/Math/BigInteger/Engines/PHP32.php | 418 ++ .../phpseclib/Math/BigInteger/Engines/PHP64.php | 422 ++ .../phpseclib/phpseclib/Math/BinaryField.php | 196 + .../phpseclib/Math/BinaryField/Integer.php | 520 ++ .../phpseclib/Math/Common/FiniteField.php | 26 + .../phpseclib/Math/Common/FiniteField/Integer.php | 26 + .../phpseclib/phpseclib/Math/PrimeField.php | 114 + .../phpseclib/Math/PrimeField/Integer.php | 399 ++ vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php | 3134 +++++++++++++ .../phpseclib/phpseclib/Net/SFTP/Stream.php | 794 ++++ vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php | 4955 ++++++++++++++++++++ .../phpseclib/phpseclib/System/SSH/Agent.php | 297 ++ .../phpseclib/System/SSH/Agent/Identity.php | 336 ++ .../System/SSH/Common/Traits/ReadBytes.php | 42 + vendor/phpseclib/phpseclib/phpseclib/bootstrap.php | 20 + vendor/phpseclib/phpseclib/phpseclib/openssl.cnf | 6 + vendor/sabre/dav/bin/naturalselection | 0 vendor/sabre/dav/bin/sabredav | 0 vendor/sabre/vobject/bin/generate_vcards | 0 vendor/sabre/vobject/bin/vobject | 0 380 files changed, 62526 insertions(+), 10 deletions(-) mode change 100644 => 100755 vendor/league/html-to-markdown/bin/html-to-markdown create mode 100644 vendor/paragonie/constant_time_encoding/.gitignore create mode 100644 vendor/paragonie/constant_time_encoding/.travis.yml create mode 100644 vendor/paragonie/constant_time_encoding/LICENSE.txt create mode 100644 vendor/paragonie/constant_time_encoding/README.md create mode 100644 vendor/paragonie/constant_time_encoding/composer.json create mode 100644 vendor/paragonie/constant_time_encoding/phpunit.xml.dist create mode 100644 vendor/paragonie/constant_time_encoding/psalm.xml create mode 100644 vendor/paragonie/constant_time_encoding/src/Base32.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base32Hex.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Binary.php create mode 100644 vendor/paragonie/constant_time_encoding/src/EncoderInterface.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Encoding.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Hex.php create mode 100644 vendor/paragonie/constant_time_encoding/src/RFC4648.php create mode 100644 vendor/paragonie/random_compat/LICENSE create mode 100755 vendor/paragonie/random_compat/build-phar.sh create mode 100644 vendor/paragonie/random_compat/composer.json create mode 100644 vendor/paragonie/random_compat/dist/random_compat.phar.pubkey create mode 100644 vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc create mode 100644 vendor/paragonie/random_compat/lib/random.php create mode 100644 vendor/paragonie/random_compat/other/build_phar.php create mode 100644 vendor/paragonie/random_compat/psalm-autoload.php create mode 100644 vendor/paragonie/random_compat/psalm.xml create mode 100644 vendor/phpseclib/phpseclib/.github/FUNDING.yml create mode 100644 vendor/phpseclib/phpseclib/AUTHORS create mode 100644 vendor/phpseclib/phpseclib/BACKERS.md create mode 100644 vendor/phpseclib/phpseclib/LICENSE create mode 100644 vendor/phpseclib/phpseclib/README.md create mode 100644 vendor/phpseclib/phpseclib/appveyor.yml create mode 100644 vendor/phpseclib/phpseclib/composer.json create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/X509.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/bootstrap.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/openssl.cnf mode change 100644 => 100755 vendor/sabre/dav/bin/naturalselection mode change 100644 => 100755 vendor/sabre/dav/bin/sabredav mode change 100644 => 100755 vendor/sabre/vobject/bin/generate_vcards mode change 100644 => 100755 vendor/sabre/vobject/bin/vobject diff --git a/composer.json b/composer.json index d138ccc43..8aecd896a 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,8 @@ "ramsey/uuid": "^4.1", "twbs/bootstrap": "^4.3.1", "blueimp/jquery-file-upload": "^10.3", - "desandro/imagesloaded": "^4.1" + "desandro/imagesloaded": "^4.1", + "phpseclib/phpseclib": "~3.0" }, "require-dev": { "phpunit/phpunit": "^9.4", diff --git a/composer.lock b/composer.lock index a6d94c8bb..466aa08b7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "81d1e8d9e12a7923b8c2bbfd46a3e4a6", + "content-hash": "49baaaa19b27cdfbb644c7ab94b45bce", "packages": [ { "name": "blueimp/jquery-file-upload", @@ -513,6 +513,123 @@ }, "time": "2019-12-02T02:32:27+00:00" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2020-12-06T15:14:20+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "pear/text_languagedetect", "version": "v1.0.1", @@ -561,6 +678,117 @@ }, "time": "2020-05-17T12:19:40+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/845a2275e886ba9fb386c8f59cb383dd9c8963e9", + "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^5.7|^6.0|^9.4", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2021-01-25T19:02:05+00:00" + }, { "name": "psr/log", "version": "1.1.3", @@ -6636,12 +6864,15 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.5", + "php": ">=7.3", "ext-curl": "*", "ext-gd": "*", "ext-mbstring": "*", "ext-xml": "*", - "ext-openssl": "*" + "ext-openssl": "*", + "ext-json": "*", + "ext-zip": "*", + "ext-posix": "*" }, "platform-dev": [], "plugin-api-version": "2.0.0" diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 66e0912d0..d46574ac8 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -1,5 +1,15 @@ array ( ), - 'reference' => 'f9d24d07dd67148a652610b002126e1e80b11839', + 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -105,6 +115,24 @@ private static $installed = array ( ), 'reference' => 'c83178d49e372ca967d1a8c77ae4e051b3a3c75c', ), + 'paragonie/constant_time_encoding' => + array ( + 'pretty_version' => 'v2.4.0', + 'version' => '2.4.0.0', + 'aliases' => + array ( + ), + 'reference' => 'f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c', + ), + 'paragonie/random_compat' => + array ( + 'pretty_version' => 'v9.99.100', + 'version' => '9.99.100.0', + 'aliases' => + array ( + ), + 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', + ), 'pear/text_languagedetect' => array ( 'pretty_version' => 'v1.0.1', @@ -114,6 +142,15 @@ private static $installed = array ( ), 'reference' => '9e253f26cef9a9066f53f200cc3e0684018cb5b5', ), + 'phpseclib/phpseclib' => + array ( + 'pretty_version' => '3.0.4', + 'version' => '3.0.4.0', + 'aliases' => + array ( + ), + 'reference' => '845a2275e886ba9fb386c8f59cb383dd9c8963e9', + ), 'psr/log' => array ( 'pretty_version' => '1.1.3', @@ -252,7 +289,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => 'f9d24d07dd67148a652610b002126e1e80b11839', + 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', ), ), ); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 26b7fec8e..1eef57c4a 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -376,6 +376,17 @@ return array( 'OAuth2\\TokenType\\Bearer' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php', 'OAuth2\\TokenType\\Mac' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php', 'OAuth2\\TokenType\\TokenTypeInterface' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/TokenTypeInterface.php', + 'ParagonIE\\ConstantTime\\Base32' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32.php', + 'ParagonIE\\ConstantTime\\Base32Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32Hex.php', + 'ParagonIE\\ConstantTime\\Base64' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64.php', + 'ParagonIE\\ConstantTime\\Base64DotSlash' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64DotSlash.php', + 'ParagonIE\\ConstantTime\\Base64DotSlashOrdered' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php', + 'ParagonIE\\ConstantTime\\Base64UrlSafe' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64UrlSafe.php', + 'ParagonIE\\ConstantTime\\Binary' => $vendorDir . '/paragonie/constant_time_encoding/src/Binary.php', + 'ParagonIE\\ConstantTime\\EncoderInterface' => $vendorDir . '/paragonie/constant_time_encoding/src/EncoderInterface.php', + 'ParagonIE\\ConstantTime\\Encoding' => $vendorDir . '/paragonie/constant_time_encoding/src/Encoding.php', + 'ParagonIE\\ConstantTime\\Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Hex.php', + 'ParagonIE\\ConstantTime\\RFC4648' => $vendorDir . '/paragonie/constant_time_encoding/src/RFC4648.php', 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', @@ -1082,8 +1093,10 @@ return array( 'Zotlabs\\Access\\Permissions' => $baseDir . '/Zotlabs/Access/Permissions.php', 'Zotlabs\\Daemon\\Addon' => $baseDir . '/Zotlabs/Daemon/Addon.php', 'Zotlabs\\Daemon\\Cache_embeds' => $baseDir . '/Zotlabs/Daemon/Cache_embeds.php', + 'Zotlabs\\Daemon\\Cache_query' => $baseDir . '/Zotlabs/Daemon/Cache_query.php', 'Zotlabs\\Daemon\\Checksites' => $baseDir . '/Zotlabs/Daemon/Checksites.php', 'Zotlabs\\Daemon\\Cli_suggest' => $baseDir . '/Zotlabs/Daemon/Cli_suggest.php', + 'Zotlabs\\Daemon\\Convo' => $baseDir . '/Zotlabs/Daemon/Convo.php', 'Zotlabs\\Daemon\\Cron' => $baseDir . '/Zotlabs/Daemon/Cron.php', 'Zotlabs\\Daemon\\Cron_daily' => $baseDir . '/Zotlabs/Daemon/Cron_daily.php', 'Zotlabs\\Daemon\\Cron_weekly' => $baseDir . '/Zotlabs/Daemon/Cron_weekly.php', @@ -1113,6 +1126,7 @@ return array( 'Zotlabs\\Identity\\OAuth2Storage' => $baseDir . '/Zotlabs/Identity/OAuth2Storage.php', 'Zotlabs\\Identity\\ProfilePhoto' => $baseDir . '/Zotlabs/Identity/ProfilePhoto.php', 'Zotlabs\\Lib\\AConfig' => $baseDir . '/Zotlabs/Lib/AConfig.php', + 'Zotlabs\\Lib\\ASCollection' => $baseDir . '/Zotlabs/Lib/ASCollection.php', 'Zotlabs\\Lib\\AbConfig' => $baseDir . '/Zotlabs/Lib/AbConfig.php', 'Zotlabs\\Lib\\AccessList' => $baseDir . '/Zotlabs/Lib/AccessList.php', 'Zotlabs\\Lib\\Activity' => $baseDir . '/Zotlabs/Lib/Activity.php', @@ -1128,6 +1142,7 @@ return array( 'Zotlabs\\Lib\\Enotify' => $baseDir . '/Zotlabs/Lib/Enotify.php', 'Zotlabs\\Lib\\ExtendedZip' => $baseDir . '/Zotlabs/Lib/ExtendedZip.php', 'Zotlabs\\Lib\\Group' => $baseDir . '/Zotlabs/Lib/Group.php', + 'Zotlabs\\Lib\\Hashpath' => $baseDir . '/Zotlabs/Lib/Hashpath.php', 'Zotlabs\\Lib\\IConfig' => $baseDir . '/Zotlabs/Lib/IConfig.php', 'Zotlabs\\Lib\\Img_filesize' => $baseDir . '/Zotlabs/Lib/Img_filesize.php', 'Zotlabs\\Lib\\JSalmon' => $baseDir . '/Zotlabs/Lib/JSalmon.php', @@ -1646,6 +1661,7 @@ return array( 'Zotlabs\\Update\\_1238' => $baseDir . '/Zotlabs/Update/_1238.php', 'Zotlabs\\Update\\_1239' => $baseDir . '/Zotlabs/Update/_1239.php', 'Zotlabs\\Update\\_1240' => $baseDir . '/Zotlabs/Update/_1240.php', + 'Zotlabs\\Update\\_1241' => $baseDir . '/Zotlabs/Update/_1241.php', 'Zotlabs\\Web\\Controller' => $baseDir . '/Zotlabs/Web/Controller.php', 'Zotlabs\\Web\\HTTPHeaders' => $baseDir . '/Zotlabs/Web/HTTPHeaders.php', 'Zotlabs\\Web\\HTTPSig' => $baseDir . '/Zotlabs/Web/HTTPSig.php', @@ -1728,4 +1744,333 @@ return array( 'Zotlabs\\Zot\\IHandler' => $baseDir . '/Zotlabs/Zot/IHandler.php', 'Zotlabs\\Zot\\Receiver' => $baseDir . '/Zotlabs/Zot/Receiver.php', 'Zotlabs\\Zot\\ZotHandler' => $baseDir . '/Zotlabs/Zot/ZotHandler.php', + 'phpseclib3\\Common\\Functions\\Strings' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php', + 'phpseclib3\\Crypt\\AES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', + 'phpseclib3\\Crypt\\Blowfish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', + 'phpseclib3\\Crypt\\ChaCha20' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php', + 'phpseclib3\\Crypt\\Common\\AsymmetricKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php', + 'phpseclib3\\Crypt\\Common\\BlockCipher' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Signature\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php', + 'phpseclib3\\Crypt\\Common\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php', + 'phpseclib3\\Crypt\\Common\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php', + 'phpseclib3\\Crypt\\Common\\StreamCipher' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php', + 'phpseclib3\\Crypt\\Common\\SymmetricKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php', + 'phpseclib3\\Crypt\\Common\\Traits\\Fingerprint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php', + 'phpseclib3\\Crypt\\Common\\Traits\\PasswordProtected' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php', + 'phpseclib3\\Crypt\\DES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', + 'phpseclib3\\Crypt\\DH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH.php', + 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\DH\\Parameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php', + 'phpseclib3\\Crypt\\DH\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php', + 'phpseclib3\\Crypt\\DH\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php', + 'phpseclib3\\Crypt\\DSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\XML' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php', + 'phpseclib3\\Crypt\\DSA\\Parameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php', + 'phpseclib3\\Crypt\\DSA\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php', + 'phpseclib3\\Crypt\\DSA\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php', + 'phpseclib3\\Crypt\\EC' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Binary' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\KoblitzPrime' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Montgomery' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Prime' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\TwistedEdwards' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Curve25519' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Curve448' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Ed25519' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Ed448' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistb233' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistb409' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk163' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk233' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk283' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk409' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp192' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp224' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp256' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp384' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp521' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistt571' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime192v1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime192v2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime192v3' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime239v1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime239v2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime239v3' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime256v1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp112r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp112r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp128r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp128r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp160k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp160r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp160r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp192k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp192r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp224k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp224r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp256k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp256r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp384r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp521r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect113r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect113r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect131r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect131r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect163k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect163r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect163r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect193r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect193r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect233k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect233r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect239k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect283k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect283r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect409k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect409r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect571k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect571r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\Common' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPrivate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPublic' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\XML' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\libsodium' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php', + 'phpseclib3\\Crypt\\EC\\Parameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php', + 'phpseclib3\\Crypt\\EC\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php', + 'phpseclib3\\Crypt\\EC\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php', + 'phpseclib3\\Crypt\\Hash' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', + 'phpseclib3\\Crypt\\PublicKeyLoader' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php', + 'phpseclib3\\Crypt\\RC2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', + 'phpseclib3\\Crypt\\RC4' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', + 'phpseclib3\\Crypt\\RSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\MSBLOB' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PSS' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\XML' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php', + 'phpseclib3\\Crypt\\RSA\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php', + 'phpseclib3\\Crypt\\RSA\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php', + 'phpseclib3\\Crypt\\Random' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', + 'phpseclib3\\Crypt\\Rijndael' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', + 'phpseclib3\\Crypt\\Salsa20' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php', + 'phpseclib3\\Crypt\\TripleDES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', + 'phpseclib3\\Crypt\\Twofish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', + 'phpseclib3\\Exception\\BadConfigurationException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php', + 'phpseclib3\\Exception\\BadDecryptionException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php', + 'phpseclib3\\Exception\\BadModeException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php', + 'phpseclib3\\Exception\\ConnectionClosedException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php', + 'phpseclib3\\Exception\\FileNotFoundException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php', + 'phpseclib3\\Exception\\InconsistentSetupException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php', + 'phpseclib3\\Exception\\InsufficientSetupException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php', + 'phpseclib3\\Exception\\NoKeyLoadedException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php', + 'phpseclib3\\Exception\\NoSupportedAlgorithmsException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php', + 'phpseclib3\\Exception\\UnableToConnectException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php', + 'phpseclib3\\Exception\\UnsupportedAlgorithmException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php', + 'phpseclib3\\Exception\\UnsupportedCurveException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php', + 'phpseclib3\\Exception\\UnsupportedFormatException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php', + 'phpseclib3\\Exception\\UnsupportedOperationException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php', + 'phpseclib3\\File\\ANSI' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', + 'phpseclib3\\File\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', + 'phpseclib3\\File\\ASN1\\Element' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', + 'phpseclib3\\File\\ASN1\\Maps\\AccessDescription' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php', + 'phpseclib3\\File\\ASN1\\Maps\\AdministrationDomainName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php', + 'phpseclib3\\File\\ASN1\\Maps\\AlgorithmIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\AnotherName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php', + 'phpseclib3\\File\\ASN1\\Maps\\Attribute' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php', + 'phpseclib3\\File\\ASN1\\Maps\\AttributeType' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php', + 'phpseclib3\\File\\ASN1\\Maps\\AttributeTypeAndValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\AttributeValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\Attributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\AuthorityInfoAccessSyntax' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php', + 'phpseclib3\\File\\ASN1\\Maps\\AuthorityKeyIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\BaseDistance' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php', + 'phpseclib3\\File\\ASN1\\Maps\\BasicConstraints' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php', + 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttribute' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php', + 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\BuiltInStandardAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\CPSuri' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php', + 'phpseclib3\\File\\ASN1\\Maps\\CRLDistributionPoints' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php', + 'phpseclib3\\File\\ASN1\\Maps\\CRLNumber' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php', + 'phpseclib3\\File\\ASN1\\Maps\\CRLReason' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertPolicyId' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php', + 'phpseclib3\\File\\ASN1\\Maps\\Certificate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificateIssuer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificateList' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificatePolicies' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificateSerialNumber' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequest' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequestInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\Characteristic_two' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php', + 'phpseclib3\\File\\ASN1\\Maps\\CountryName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php', + 'phpseclib3\\File\\ASN1\\Maps\\Curve' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php', + 'phpseclib3\\File\\ASN1\\Maps\\DHParameter' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php', + 'phpseclib3\\File\\ASN1\\Maps\\DSAParams' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php', + 'phpseclib3\\File\\ASN1\\Maps\\DSAPrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\DSAPublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\DigestInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\DirectoryString' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php', + 'phpseclib3\\File\\ASN1\\Maps\\DisplayText' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php', + 'phpseclib3\\File\\ASN1\\Maps\\DistributionPoint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php', + 'phpseclib3\\File\\ASN1\\Maps\\DistributionPointName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php', + 'phpseclib3\\File\\ASN1\\Maps\\DssSigValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\ECParameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php', + 'phpseclib3\\File\\ASN1\\Maps\\ECPoint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php', + 'phpseclib3\\File\\ASN1\\Maps\\ECPrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\EDIPartyName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php', + 'phpseclib3\\File\\ASN1\\Maps\\EcdsaSigValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\EncryptedData' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php', + 'phpseclib3\\File\\ASN1\\Maps\\EncryptedPrivateKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\ExtKeyUsageSyntax' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php', + 'phpseclib3\\File\\ASN1\\Maps\\Extension' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php', + 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttribute' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php', + 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\Extensions' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php', + 'phpseclib3\\File\\ASN1\\Maps\\FieldElement' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php', + 'phpseclib3\\File\\ASN1\\Maps\\FieldID' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralNames' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtree' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtrees' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php', + 'phpseclib3\\File\\ASN1\\Maps\\HashAlgorithm' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php', + 'phpseclib3\\File\\ASN1\\Maps\\HoldInstructionCode' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php', + 'phpseclib3\\File\\ASN1\\Maps\\InvalidityDate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php', + 'phpseclib3\\File\\ASN1\\Maps\\IssuerAltName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php', + 'phpseclib3\\File\\ASN1\\Maps\\IssuingDistributionPoint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php', + 'phpseclib3\\File\\ASN1\\Maps\\KeyIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\KeyPurposeId' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php', + 'phpseclib3\\File\\ASN1\\Maps\\KeyUsage' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php', + 'phpseclib3\\File\\ASN1\\Maps\\MaskGenAlgorithm' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php', + 'phpseclib3\\File\\ASN1\\Maps\\Name' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php', + 'phpseclib3\\File\\ASN1\\Maps\\NameConstraints' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php', + 'phpseclib3\\File\\ASN1\\Maps\\NetworkAddress' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php', + 'phpseclib3\\File\\ASN1\\Maps\\NoticeReference' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php', + 'phpseclib3\\File\\ASN1\\Maps\\NumericUserIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\ORAddress' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php', + 'phpseclib3\\File\\ASN1\\Maps\\OneAsymmetricKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\OrganizationName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php', + 'phpseclib3\\File\\ASN1\\Maps\\OrganizationalUnitNames' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php', + 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfos' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBEParameter' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBES2params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBKDF2params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBMAC1params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php', + 'phpseclib3\\File\\ASN1\\Maps\\PKCS9String' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php', + 'phpseclib3\\File\\ASN1\\Maps\\Pentanomial' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php', + 'phpseclib3\\File\\ASN1\\Maps\\PersonalName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyInformation' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyMappings' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierId' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\PostalAddress' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php', + 'phpseclib3\\File\\ASN1\\Maps\\Prime_p' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateDomainName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyUsagePeriod' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php', + 'phpseclib3\\File\\ASN1\\Maps\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyAndChallenge' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php', + 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\RC2CBCParameter' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php', + 'phpseclib3\\File\\ASN1\\Maps\\RDNSequence' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php', + 'phpseclib3\\File\\ASN1\\Maps\\RSAPrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\RSAPublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\RSASSA_PSS_params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php', + 'phpseclib3\\File\\ASN1\\Maps\\ReasonFlags' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php', + 'phpseclib3\\File\\ASN1\\Maps\\RelativeDistinguishedName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php', + 'phpseclib3\\File\\ASN1\\Maps\\RevokedCertificate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php', + 'phpseclib3\\File\\ASN1\\Maps\\SignedPublicKeyAndChallenge' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php', + 'phpseclib3\\File\\ASN1\\Maps\\SpecifiedECDomain' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectAltName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectDirectoryAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectInfoAccessSyntax' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectPublicKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\TBSCertList' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php', + 'phpseclib3\\File\\ASN1\\Maps\\TBSCertificate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php', + 'phpseclib3\\File\\ASN1\\Maps\\TerminalIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\Time' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php', + 'phpseclib3\\File\\ASN1\\Maps\\Trinomial' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php', + 'phpseclib3\\File\\ASN1\\Maps\\UniqueIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\UserNotice' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php', + 'phpseclib3\\File\\ASN1\\Maps\\Validity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php', + 'phpseclib3\\File\\ASN1\\Maps\\netscape_ca_policy_url' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php', + 'phpseclib3\\File\\ASN1\\Maps\\netscape_cert_type' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php', + 'phpseclib3\\File\\ASN1\\Maps\\netscape_comment' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php', + 'phpseclib3\\File\\X509' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/X509.php', + 'phpseclib3\\Math\\BigInteger' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\BuiltIn' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\DefaultEngine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\OpenSSL' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\Barrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\EvalBarrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\Engine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\GMP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\GMP\\DefaultEngine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\OpenSSL' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP32' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP64' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\DefaultEngine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Montgomery' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\OpenSSL' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Barrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Classic' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\EvalBarrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Montgomery' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\MontgomeryMult' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\PowerOfTwo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php', + 'phpseclib3\\Math\\BinaryField' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BinaryField.php', + 'phpseclib3\\Math\\BinaryField\\Integer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php', + 'phpseclib3\\Math\\Common\\FiniteField' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php', + 'phpseclib3\\Math\\Common\\FiniteField\\Integer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php', + 'phpseclib3\\Math\\PrimeField' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/PrimeField.php', + 'phpseclib3\\Math\\PrimeField\\Integer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php', + 'phpseclib3\\Net\\SFTP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', + 'phpseclib3\\Net\\SFTP\\Stream' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', + 'phpseclib3\\Net\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', + 'phpseclib3\\System\\SSH\\Agent' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', + 'phpseclib3\\System\\SSH\\Agent\\Identity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', + 'phpseclib3\\System\\SSH\\Common\\Traits\\ReadBytes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 269b50330..4f9ca4d0b 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -15,5 +15,6 @@ return array( 'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', + 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 59c2faa28..973842971 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'Zotlabs\\' => array($baseDir . '/Zotlabs'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Sabre\\Xml\\' => array($vendorDir . '/sabre/xml/lib'), @@ -20,6 +21,7 @@ return array( 'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'), 'Ramsey\\Collection\\' => array($vendorDir . '/ramsey/collection/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), 'Michelf\\' => array($vendorDir . '/michelf/php-markdown/Michelf'), 'League\\HTMLToMarkdown\\' => array($vendorDir . '/league/html-to-markdown/src'), 'ID3Parser\\' => array($vendorDir . '/lukasreschke/id3parser/src'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6988dc0b4..eb0766ee9 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -16,10 +16,15 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', + 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', ); public static $prefixLengthsPsr4 = array ( + 'p' => + array ( + 'phpseclib3\\' => 11, + ), 'Z' => array ( 'Zotlabs\\' => 8, @@ -45,6 +50,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'P' => array ( 'Psr\\Log\\' => 8, + 'ParagonIE\\ConstantTime\\' => 23, ), 'M' => array ( @@ -73,6 +79,10 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d ); public static $prefixDirsPsr4 = array ( + 'phpseclib3\\' => + array ( + 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', + ), 'Zotlabs\\' => array ( 0 => __DIR__ . '/../..' . '/Zotlabs', @@ -129,6 +139,10 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d array ( 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', ), + 'ParagonIE\\ConstantTime\\' => + array ( + 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', + ), 'Michelf\\' => array ( 0 => __DIR__ . '/..' . '/michelf/php-markdown/Michelf', @@ -557,6 +571,17 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'OAuth2\\TokenType\\Bearer' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php', 'OAuth2\\TokenType\\Mac' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php', 'OAuth2\\TokenType\\TokenTypeInterface' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/TokenTypeInterface.php', + 'ParagonIE\\ConstantTime\\Base32' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32.php', + 'ParagonIE\\ConstantTime\\Base32Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32Hex.php', + 'ParagonIE\\ConstantTime\\Base64' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64.php', + 'ParagonIE\\ConstantTime\\Base64DotSlash' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64DotSlash.php', + 'ParagonIE\\ConstantTime\\Base64DotSlashOrdered' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php', + 'ParagonIE\\ConstantTime\\Base64UrlSafe' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64UrlSafe.php', + 'ParagonIE\\ConstantTime\\Binary' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Binary.php', + 'ParagonIE\\ConstantTime\\EncoderInterface' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/EncoderInterface.php', + 'ParagonIE\\ConstantTime\\Encoding' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Encoding.php', + 'ParagonIE\\ConstantTime\\Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Hex.php', + 'ParagonIE\\ConstantTime\\RFC4648' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/RFC4648.php', 'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php', @@ -1263,8 +1288,10 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Access\\Permissions' => __DIR__ . '/../..' . '/Zotlabs/Access/Permissions.php', 'Zotlabs\\Daemon\\Addon' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Addon.php', 'Zotlabs\\Daemon\\Cache_embeds' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cache_embeds.php', + 'Zotlabs\\Daemon\\Cache_query' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cache_query.php', 'Zotlabs\\Daemon\\Checksites' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Checksites.php', 'Zotlabs\\Daemon\\Cli_suggest' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cli_suggest.php', + 'Zotlabs\\Daemon\\Convo' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Convo.php', 'Zotlabs\\Daemon\\Cron' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cron.php', 'Zotlabs\\Daemon\\Cron_daily' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cron_daily.php', 'Zotlabs\\Daemon\\Cron_weekly' => __DIR__ . '/../..' . '/Zotlabs/Daemon/Cron_weekly.php', @@ -1294,6 +1321,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Identity\\OAuth2Storage' => __DIR__ . '/../..' . '/Zotlabs/Identity/OAuth2Storage.php', 'Zotlabs\\Identity\\ProfilePhoto' => __DIR__ . '/../..' . '/Zotlabs/Identity/ProfilePhoto.php', 'Zotlabs\\Lib\\AConfig' => __DIR__ . '/../..' . '/Zotlabs/Lib/AConfig.php', + 'Zotlabs\\Lib\\ASCollection' => __DIR__ . '/../..' . '/Zotlabs/Lib/ASCollection.php', 'Zotlabs\\Lib\\AbConfig' => __DIR__ . '/../..' . '/Zotlabs/Lib/AbConfig.php', 'Zotlabs\\Lib\\AccessList' => __DIR__ . '/../..' . '/Zotlabs/Lib/AccessList.php', 'Zotlabs\\Lib\\Activity' => __DIR__ . '/../..' . '/Zotlabs/Lib/Activity.php', @@ -1309,6 +1337,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Lib\\Enotify' => __DIR__ . '/../..' . '/Zotlabs/Lib/Enotify.php', 'Zotlabs\\Lib\\ExtendedZip' => __DIR__ . '/../..' . '/Zotlabs/Lib/ExtendedZip.php', 'Zotlabs\\Lib\\Group' => __DIR__ . '/../..' . '/Zotlabs/Lib/Group.php', + 'Zotlabs\\Lib\\Hashpath' => __DIR__ . '/../..' . '/Zotlabs/Lib/Hashpath.php', 'Zotlabs\\Lib\\IConfig' => __DIR__ . '/../..' . '/Zotlabs/Lib/IConfig.php', 'Zotlabs\\Lib\\Img_filesize' => __DIR__ . '/../..' . '/Zotlabs/Lib/Img_filesize.php', 'Zotlabs\\Lib\\JSalmon' => __DIR__ . '/../..' . '/Zotlabs/Lib/JSalmon.php', @@ -1827,6 +1856,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Update\\_1238' => __DIR__ . '/../..' . '/Zotlabs/Update/_1238.php', 'Zotlabs\\Update\\_1239' => __DIR__ . '/../..' . '/Zotlabs/Update/_1239.php', 'Zotlabs\\Update\\_1240' => __DIR__ . '/../..' . '/Zotlabs/Update/_1240.php', + 'Zotlabs\\Update\\_1241' => __DIR__ . '/../..' . '/Zotlabs/Update/_1241.php', 'Zotlabs\\Web\\Controller' => __DIR__ . '/../..' . '/Zotlabs/Web/Controller.php', 'Zotlabs\\Web\\HTTPHeaders' => __DIR__ . '/../..' . '/Zotlabs/Web/HTTPHeaders.php', 'Zotlabs\\Web\\HTTPSig' => __DIR__ . '/../..' . '/Zotlabs/Web/HTTPSig.php', @@ -1909,6 +1939,335 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Zot\\IHandler' => __DIR__ . '/../..' . '/Zotlabs/Zot/IHandler.php', 'Zotlabs\\Zot\\Receiver' => __DIR__ . '/../..' . '/Zotlabs/Zot/Receiver.php', 'Zotlabs\\Zot\\ZotHandler' => __DIR__ . '/../..' . '/Zotlabs/Zot/ZotHandler.php', + 'phpseclib3\\Common\\Functions\\Strings' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php', + 'phpseclib3\\Crypt\\AES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', + 'phpseclib3\\Crypt\\Blowfish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', + 'phpseclib3\\Crypt\\ChaCha20' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php', + 'phpseclib3\\Crypt\\Common\\AsymmetricKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php', + 'phpseclib3\\Crypt\\Common\\BlockCipher' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\Common\\Formats\\Signature\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php', + 'phpseclib3\\Crypt\\Common\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php', + 'phpseclib3\\Crypt\\Common\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php', + 'phpseclib3\\Crypt\\Common\\StreamCipher' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php', + 'phpseclib3\\Crypt\\Common\\SymmetricKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php', + 'phpseclib3\\Crypt\\Common\\Traits\\Fingerprint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php', + 'phpseclib3\\Crypt\\Common\\Traits\\PasswordProtected' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php', + 'phpseclib3\\Crypt\\DES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', + 'phpseclib3\\Crypt\\DH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH.php', + 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\DH\\Parameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php', + 'phpseclib3\\Crypt\\DH\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php', + 'phpseclib3\\Crypt\\DH\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php', + 'phpseclib3\\Crypt\\DSA' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\XML' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php', + 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php', + 'phpseclib3\\Crypt\\DSA\\Parameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php', + 'phpseclib3\\Crypt\\DSA\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php', + 'phpseclib3\\Crypt\\DSA\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php', + 'phpseclib3\\Crypt\\EC' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Binary' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\KoblitzPrime' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Montgomery' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\Prime' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php', + 'phpseclib3\\Crypt\\EC\\BaseCurves\\TwistedEdwards' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Curve25519' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Curve448' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Ed25519' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php', + 'phpseclib3\\Crypt\\EC\\Curves\\Ed448' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistb233' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistb409' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk163' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk233' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk283' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistk409' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp192' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp224' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp256' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp384' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistp521' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php', + 'phpseclib3\\Crypt\\EC\\Curves\\nistt571' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime192v1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime192v2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime192v3' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime239v1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime239v2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime239v3' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php', + 'phpseclib3\\Crypt\\EC\\Curves\\prime256v1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp112r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp112r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp128r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp128r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp160k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp160r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp160r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp192k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp192r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp224k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp224r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp256k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp256r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp384r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\secp521r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect113r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect113r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect131r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect131r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect163k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect163r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect163r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect193r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect193r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect233k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect233r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect239k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect283k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect283r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect409k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect409r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect571k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php', + 'phpseclib3\\Crypt\\EC\\Curves\\sect571r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\Common' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPrivate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPublic' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\XML' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\libsodium' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php', + 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php', + 'phpseclib3\\Crypt\\EC\\Parameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php', + 'phpseclib3\\Crypt\\EC\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php', + 'phpseclib3\\Crypt\\EC\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php', + 'phpseclib3\\Crypt\\Hash' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', + 'phpseclib3\\Crypt\\PublicKeyLoader' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php', + 'phpseclib3\\Crypt\\RC2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', + 'phpseclib3\\Crypt\\RC4' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', + 'phpseclib3\\Crypt\\RSA' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\MSBLOB' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PSS' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php', + 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\XML' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php', + 'phpseclib3\\Crypt\\RSA\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php', + 'phpseclib3\\Crypt\\RSA\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php', + 'phpseclib3\\Crypt\\Random' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', + 'phpseclib3\\Crypt\\Rijndael' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', + 'phpseclib3\\Crypt\\Salsa20' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php', + 'phpseclib3\\Crypt\\TripleDES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', + 'phpseclib3\\Crypt\\Twofish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', + 'phpseclib3\\Exception\\BadConfigurationException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php', + 'phpseclib3\\Exception\\BadDecryptionException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php', + 'phpseclib3\\Exception\\BadModeException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php', + 'phpseclib3\\Exception\\ConnectionClosedException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php', + 'phpseclib3\\Exception\\FileNotFoundException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php', + 'phpseclib3\\Exception\\InconsistentSetupException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php', + 'phpseclib3\\Exception\\InsufficientSetupException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php', + 'phpseclib3\\Exception\\NoKeyLoadedException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php', + 'phpseclib3\\Exception\\NoSupportedAlgorithmsException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php', + 'phpseclib3\\Exception\\UnableToConnectException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php', + 'phpseclib3\\Exception\\UnsupportedAlgorithmException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php', + 'phpseclib3\\Exception\\UnsupportedCurveException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php', + 'phpseclib3\\Exception\\UnsupportedFormatException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php', + 'phpseclib3\\Exception\\UnsupportedOperationException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php', + 'phpseclib3\\File\\ANSI' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', + 'phpseclib3\\File\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', + 'phpseclib3\\File\\ASN1\\Element' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', + 'phpseclib3\\File\\ASN1\\Maps\\AccessDescription' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php', + 'phpseclib3\\File\\ASN1\\Maps\\AdministrationDomainName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php', + 'phpseclib3\\File\\ASN1\\Maps\\AlgorithmIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\AnotherName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php', + 'phpseclib3\\File\\ASN1\\Maps\\Attribute' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php', + 'phpseclib3\\File\\ASN1\\Maps\\AttributeType' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php', + 'phpseclib3\\File\\ASN1\\Maps\\AttributeTypeAndValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\AttributeValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\Attributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\AuthorityInfoAccessSyntax' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php', + 'phpseclib3\\File\\ASN1\\Maps\\AuthorityKeyIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\BaseDistance' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php', + 'phpseclib3\\File\\ASN1\\Maps\\BasicConstraints' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php', + 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttribute' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php', + 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\BuiltInStandardAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\CPSuri' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php', + 'phpseclib3\\File\\ASN1\\Maps\\CRLDistributionPoints' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php', + 'phpseclib3\\File\\ASN1\\Maps\\CRLNumber' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php', + 'phpseclib3\\File\\ASN1\\Maps\\CRLReason' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertPolicyId' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php', + 'phpseclib3\\File\\ASN1\\Maps\\Certificate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificateIssuer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificateList' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificatePolicies' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificateSerialNumber' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequest' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php', + 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequestInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\Characteristic_two' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php', + 'phpseclib3\\File\\ASN1\\Maps\\CountryName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php', + 'phpseclib3\\File\\ASN1\\Maps\\Curve' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php', + 'phpseclib3\\File\\ASN1\\Maps\\DHParameter' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php', + 'phpseclib3\\File\\ASN1\\Maps\\DSAParams' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php', + 'phpseclib3\\File\\ASN1\\Maps\\DSAPrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\DSAPublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\DigestInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\DirectoryString' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php', + 'phpseclib3\\File\\ASN1\\Maps\\DisplayText' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php', + 'phpseclib3\\File\\ASN1\\Maps\\DistributionPoint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php', + 'phpseclib3\\File\\ASN1\\Maps\\DistributionPointName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php', + 'phpseclib3\\File\\ASN1\\Maps\\DssSigValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\ECParameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php', + 'phpseclib3\\File\\ASN1\\Maps\\ECPoint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php', + 'phpseclib3\\File\\ASN1\\Maps\\ECPrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\EDIPartyName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php', + 'phpseclib3\\File\\ASN1\\Maps\\EcdsaSigValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php', + 'phpseclib3\\File\\ASN1\\Maps\\EncryptedData' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php', + 'phpseclib3\\File\\ASN1\\Maps\\EncryptedPrivateKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\ExtKeyUsageSyntax' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php', + 'phpseclib3\\File\\ASN1\\Maps\\Extension' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php', + 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttribute' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php', + 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\Extensions' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php', + 'phpseclib3\\File\\ASN1\\Maps\\FieldElement' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php', + 'phpseclib3\\File\\ASN1\\Maps\\FieldID' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralNames' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtree' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php', + 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtrees' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php', + 'phpseclib3\\File\\ASN1\\Maps\\HashAlgorithm' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php', + 'phpseclib3\\File\\ASN1\\Maps\\HoldInstructionCode' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php', + 'phpseclib3\\File\\ASN1\\Maps\\InvalidityDate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php', + 'phpseclib3\\File\\ASN1\\Maps\\IssuerAltName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php', + 'phpseclib3\\File\\ASN1\\Maps\\IssuingDistributionPoint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php', + 'phpseclib3\\File\\ASN1\\Maps\\KeyIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\KeyPurposeId' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php', + 'phpseclib3\\File\\ASN1\\Maps\\KeyUsage' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php', + 'phpseclib3\\File\\ASN1\\Maps\\MaskGenAlgorithm' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php', + 'phpseclib3\\File\\ASN1\\Maps\\Name' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php', + 'phpseclib3\\File\\ASN1\\Maps\\NameConstraints' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php', + 'phpseclib3\\File\\ASN1\\Maps\\NetworkAddress' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php', + 'phpseclib3\\File\\ASN1\\Maps\\NoticeReference' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php', + 'phpseclib3\\File\\ASN1\\Maps\\NumericUserIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\ORAddress' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php', + 'phpseclib3\\File\\ASN1\\Maps\\OneAsymmetricKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\OrganizationName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php', + 'phpseclib3\\File\\ASN1\\Maps\\OrganizationalUnitNames' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php', + 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfos' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBEParameter' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBES2params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBKDF2params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php', + 'phpseclib3\\File\\ASN1\\Maps\\PBMAC1params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php', + 'phpseclib3\\File\\ASN1\\Maps\\PKCS9String' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php', + 'phpseclib3\\File\\ASN1\\Maps\\Pentanomial' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php', + 'phpseclib3\\File\\ASN1\\Maps\\PersonalName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyInformation' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyMappings' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierId' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php', + 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\PostalAddress' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php', + 'phpseclib3\\File\\ASN1\\Maps\\Prime_p' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateDomainName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyUsagePeriod' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php', + 'phpseclib3\\File\\ASN1\\Maps\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyAndChallenge' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php', + 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\RC2CBCParameter' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php', + 'phpseclib3\\File\\ASN1\\Maps\\RDNSequence' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php', + 'phpseclib3\\File\\ASN1\\Maps\\RSAPrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\RSAPublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php', + 'phpseclib3\\File\\ASN1\\Maps\\RSASSA_PSS_params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php', + 'phpseclib3\\File\\ASN1\\Maps\\ReasonFlags' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php', + 'phpseclib3\\File\\ASN1\\Maps\\RelativeDistinguishedName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php', + 'phpseclib3\\File\\ASN1\\Maps\\RevokedCertificate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php', + 'phpseclib3\\File\\ASN1\\Maps\\SignedPublicKeyAndChallenge' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php', + 'phpseclib3\\File\\ASN1\\Maps\\SpecifiedECDomain' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectAltName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectDirectoryAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectInfoAccessSyntax' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php', + 'phpseclib3\\File\\ASN1\\Maps\\SubjectPublicKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php', + 'phpseclib3\\File\\ASN1\\Maps\\TBSCertList' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php', + 'phpseclib3\\File\\ASN1\\Maps\\TBSCertificate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php', + 'phpseclib3\\File\\ASN1\\Maps\\TerminalIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\Time' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php', + 'phpseclib3\\File\\ASN1\\Maps\\Trinomial' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php', + 'phpseclib3\\File\\ASN1\\Maps\\UniqueIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php', + 'phpseclib3\\File\\ASN1\\Maps\\UserNotice' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php', + 'phpseclib3\\File\\ASN1\\Maps\\Validity' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php', + 'phpseclib3\\File\\ASN1\\Maps\\netscape_ca_policy_url' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php', + 'phpseclib3\\File\\ASN1\\Maps\\netscape_cert_type' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php', + 'phpseclib3\\File\\ASN1\\Maps\\netscape_comment' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php', + 'phpseclib3\\File\\X509' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/X509.php', + 'phpseclib3\\Math\\BigInteger' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\BuiltIn' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\DefaultEngine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\OpenSSL' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\Barrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\EvalBarrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\Engine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\GMP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\GMP\\DefaultEngine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\OpenSSL' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP32' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP64' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\DefaultEngine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Montgomery' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\OpenSSL' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Barrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Classic' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\EvalBarrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Montgomery' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\MontgomeryMult' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php', + 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\PowerOfTwo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php', + 'phpseclib3\\Math\\BinaryField' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BinaryField.php', + 'phpseclib3\\Math\\BinaryField\\Integer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php', + 'phpseclib3\\Math\\Common\\FiniteField' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php', + 'phpseclib3\\Math\\Common\\FiniteField\\Integer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php', + 'phpseclib3\\Math\\PrimeField' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/PrimeField.php', + 'phpseclib3\\Math\\PrimeField\\Integer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php', + 'phpseclib3\\Net\\SFTP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', + 'phpseclib3\\Net\\SFTP\\Stream' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', + 'phpseclib3\\Net\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', + 'phpseclib3\\System\\SSH\\Agent' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', + 'phpseclib3\\System\\SSH\\Agent\\Identity' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', + 'phpseclib3\\System\\SSH\\Common\\Traits\\ReadBytes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 5a461e7fa..06d6df515 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -506,6 +506,129 @@ ], "install-path": "../michelf/php-markdown" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.4.0", + "version_normalized": "2.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "time": "2020-12-06T15:14:20+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "install-path": "../paragonie/constant_time_encoding" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "version_normalized": "9.99.100.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2020-10-15T08:29:30+00:00", + "type": "library", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "install-path": "../paragonie/random_compat" + }, { "name": "pear/text_languagedetect", "version": "v1.0.1", @@ -557,6 +680,120 @@ }, "install-path": "../pear/text_languagedetect" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.4", + "version_normalized": "3.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/845a2275e886ba9fb386c8f59cb383dd9c8963e9", + "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^5.7|^6.0|^9.4", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "time": "2021-01-25T19:02:05+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "install-path": "../phpseclib/phpseclib" + }, { "name": "psr/log", "version": "1.1.3", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 6672305a0..d8bea317c 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => 'f9d24d07dd67148a652610b002126e1e80b11839', + 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -92,6 +92,24 @@ ), 'reference' => 'c83178d49e372ca967d1a8c77ae4e051b3a3c75c', ), + 'paragonie/constant_time_encoding' => + array ( + 'pretty_version' => 'v2.4.0', + 'version' => '2.4.0.0', + 'aliases' => + array ( + ), + 'reference' => 'f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c', + ), + 'paragonie/random_compat' => + array ( + 'pretty_version' => 'v9.99.100', + 'version' => '9.99.100.0', + 'aliases' => + array ( + ), + 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', + ), 'pear/text_languagedetect' => array ( 'pretty_version' => 'v1.0.1', @@ -101,6 +119,15 @@ ), 'reference' => '9e253f26cef9a9066f53f200cc3e0684018cb5b5', ), + 'phpseclib/phpseclib' => + array ( + 'pretty_version' => '3.0.4', + 'version' => '3.0.4.0', + 'aliases' => + array ( + ), + 'reference' => '845a2275e886ba9fb386c8f59cb383dd9c8963e9', + ), 'psr/log' => array ( 'pretty_version' => '1.1.3', @@ -239,7 +266,7 @@ 'aliases' => array ( ), - 'reference' => 'f9d24d07dd67148a652610b002126e1e80b11839', + 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', ), ), ); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 589e9e770..92370c5a0 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 70200)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 70300)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/league/html-to-markdown/bin/html-to-markdown b/vendor/league/html-to-markdown/bin/html-to-markdown old mode 100644 new mode 100755 diff --git a/vendor/paragonie/constant_time_encoding/.gitignore b/vendor/paragonie/constant_time_encoding/.gitignore new file mode 100644 index 000000000..e0caea8fc --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/.gitignore @@ -0,0 +1,2 @@ +.idea/ +vendor/ \ No newline at end of file diff --git a/vendor/paragonie/constant_time_encoding/.travis.yml b/vendor/paragonie/constant_time_encoding/.travis.yml new file mode 100644 index 000000000..117c114a1 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/.travis.yml @@ -0,0 +1,24 @@ +language: php +sudo: false + +matrix: + fast_finish: true + include: + - php: "7.1" + - php: "7.2" + - php: "7.3" + - php: "7.4" + - php: "8.0" + - php: "nightly" + allow_failures: + - php: "nightly" + - php: "7.4" + - php: "8.0" + +install: + - composer self-update + - composer update + +script: + - vendor/bin/phpunit + - vendor/bin/psalm diff --git a/vendor/paragonie/constant_time_encoding/LICENSE.txt b/vendor/paragonie/constant_time_encoding/LICENSE.txt new file mode 100644 index 000000000..f424f5ecc --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/LICENSE.txt @@ -0,0 +1,48 @@ +The MIT License (MIT) + +Copyright (c) 2016 - 2020 Paragon Initiative Enterprises + +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. + +------------------------------------------------------------------------------ +This library was based on the work of Steve "Sc00bz" Thomas. +------------------------------------------------------------------------------ + +The MIT License (MIT) + +Copyright (c) 2014 Steve Thomas + +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/vendor/paragonie/constant_time_encoding/README.md b/vendor/paragonie/constant_time_encoding/README.md new file mode 100644 index 000000000..d7db2a2d0 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/README.md @@ -0,0 +1,84 @@ +# Constant-Time Encoding + +[![Build Status](https://travis-ci.org/paragonie/constant_time_encoding.svg?branch=master)](https://travis-ci.org/paragonie/constant_time_encoding) +[![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding) + +Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding), +this library aims to offer character encoding functions that do not leak +information about what you are encoding/decoding via processor cache +misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html). + +Our fork offers the following enchancements: + +* `mbstring.func_overload` resistance +* Unit tests +* Composer- and Packagist-ready +* Base16 encoding +* Base32 encoding +* Uses `pack()` and `unpack()` instead of `chr()` and `ord()` + +## PHP Version Requirements + +Version 2 of this library should work on **PHP 7** or newer. For PHP 5 +support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x). + +If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`. + +## How to Install + +```sh +composer require paragonie/constant_time_encoding +``` + +## How to Use + +```php +use \ParagonIE\ConstantTime\Encoding; + +// possibly (if applicable): +// require 'vendor/autoload.php'; + +$data = random_bytes(32); +echo Encoding::base64Encode($data), "\n"; +echo Encoding::base32EncodeUpper($data), "\n"; +echo Encoding::base32Encode($data), "\n"; +echo Encoding::hexEncode($data), "\n"; +echo Encoding::hexEncodeUpper($data), "\n"; +``` + +Example output: + +``` +1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= +2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ==== +2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== +d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1 +D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1 +``` + +If you only need a particular variant, you can just reference the +required class like so: + +```php +use \ParagonIE\ConstantTime\Base64; +use \ParagonIE\ConstantTime\Base32; + +$data = random_bytes(32); +echo Base64::encode($data), "\n"; +echo Base32::encode($data), "\n"; +``` + +Example output: + +``` +1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= +2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== +``` + +## Support Contracts + +If your company uses this library in their products or services, you may be +interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). diff --git a/vendor/paragonie/constant_time_encoding/composer.json b/vendor/paragonie/constant_time_encoding/composer.json new file mode 100644 index 000000000..583fe366f --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/composer.json @@ -0,0 +1,51 @@ +{ + "name": "paragonie/constant_time_encoding", + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base64", + "encoding", + "rfc4648", + "base32", + "base16", + "hex", + "bin2hex", + "hex2bin", + "base64_encode", + "base64_decode", + "base32_encode", + "base32_decode" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "support": { + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + } +} diff --git a/vendor/paragonie/constant_time_encoding/phpunit.xml.dist b/vendor/paragonie/constant_time_encoding/phpunit.xml.dist new file mode 100644 index 000000000..4d090343e --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/phpunit.xml.dist @@ -0,0 +1,13 @@ + + + + + ./src + + + + + ./tests + + + diff --git a/vendor/paragonie/constant_time_encoding/psalm.xml b/vendor/paragonie/constant_time_encoding/psalm.xml new file mode 100644 index 000000000..0a17264b0 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/psalm.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/vendor/paragonie/constant_time_encoding/src/Base32.php b/vendor/paragonie/constant_time_encoding/src/Base32.php new file mode 100644 index 000000000..7784bafbf --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/Base32.php @@ -0,0 +1,471 @@ + 96 && $src < 123) $ret += $src - 97 + 1; // -64 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96); + + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src): int + { + $ret = -1; + + // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src): string + { + $diff = 0x61; + + // if ($src > 25) $ret -= 72; + $diff -= ((25 - $src) >> 8) & 73; + + return \pack('C', $src + $diff); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $ret -= 40; + $diff -= ((25 - $src) >> 8) & 41; + + return \pack('C', $src + $diff); + } + + + /** + * Base32 decoding + * + * @param string $src + * @param bool $upper + * @param bool $strictPadding + * @return string + * @throws \TypeError + * @psalm-suppress RedundantCondition + */ + protected static function doDecode(string $src, bool $upper = false, bool $strictPadding = false): string + { + // We do this to reduce code duplication: + $method = $upper + ? 'decode5BitsUpper' + : 'decode5Bits'; + + // Remove padding + $srcLen = Binary::safeStrlen($src); + if ($srcLen === 0) { + return ''; + } + if ($strictPadding) { + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7; ++$j) { + if ($src[$srcLen - 1] === '=') { + $srcLen--; + } else { + break; + } + } + } + if (($srcLen & 7) === 1) { + throw new \RangeException( + 'Incorrect padding' + ); + } + } else { + $src = \rtrim($src, '='); + $srcLen = Binary::safeStrlen($src); + } + + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 8 <= $srcLen; $i += 8) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + /** @var int $c7 */ + $c7 = static::$method($chunk[8]); + + $dest .= \pack( + 'CCCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff, + (($c6 << 5) | ($c7 ) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + + if ($i + 6 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + + $dest .= \pack( + 'CCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; + } elseif ($i + 5 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + + $dest .= \pack( + 'CCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; + } elseif ($i + 4 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + + $dest .= \pack( + 'CCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; + } elseif ($i + 3 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + + $dest .= \pack( + 'CC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + } elseif ($i + 2 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + + $dest .= \pack( + 'CC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2) >> 8; + } elseif ($i + 1 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + + $dest .= \pack( + 'C', + (($c0 << 3) | ($c1 >> 2) ) & 0xff + ); + $err |= ($c0 | $c1) >> 8; + } else { + $dest .= \pack( + 'C', + (($c0 << 3) ) & 0xff + ); + $err |= ($c0) >> 8; + } + } + /** @var bool $check */ + $check = ($err === 0); + if (!$check) { + throw new \RangeException( + 'Base32::doDecode() only expects characters in the correct base32 alphabet' + ); + } + return $dest; + } + + /** + * Base32 Encoding + * + * @param string $src + * @param bool $upper + * @param bool $pad + * @return string + * @throws \TypeError + */ + protected static function doEncode(string $src, bool $upper = false, $pad = true): string + { + // We do this to reduce code duplication: + $method = $upper + ? 'encode5BitsUpper' + : 'encode5Bits'; + + $dest = ''; + $srcLen = Binary::safeStrlen($src); + + // Main loop (no padding): + for ($i = 0; $i + 5 <= $srcLen; $i += 5) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $b4 = $chunk[5]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . + static::$method((($b3 >> 2) ) & 31) . + static::$method((($b3 << 3) | ($b4 >> 5)) & 31) . + static::$method( $b4 & 31); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 3 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . + static::$method((($b3 >> 2) ) & 31) . + static::$method((($b3 << 3) ) & 31); + if ($pad) { + $dest .= '='; + } + } elseif ($i + 2 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) ) & 31); + if ($pad) { + $dest .= '==='; + } + } elseif ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) ) & 31); + if ($pad) { + $dest .= '===='; + } + } else { + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method( ($b0 << 2) & 31); + if ($pad) { + $dest .= '======'; + } + } + } + return $dest; + } +} diff --git a/vendor/paragonie/constant_time_encoding/src/Base32Hex.php b/vendor/paragonie/constant_time_encoding/src/Base32Hex.php new file mode 100644 index 000000000..68fdad52c --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/Base32Hex.php @@ -0,0 +1,111 @@ + 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); + + // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 + $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src): int + { + $ret = -1; + + // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); + + // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 + $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src): string + { + $src += 0x30; + + // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 + $src += ((0x39 - $src) >> 8) & 39; + + return \pack('C', $src); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src): string + { + $src += 0x30; + + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += ((0x39 - $src) >> 8) & 7; + + return \pack('C', $src); + } +} \ No newline at end of file diff --git a/vendor/paragonie/constant_time_encoding/src/Base64.php b/vendor/paragonie/constant_time_encoding/src/Base64.php new file mode 100644 index 000000000..4739e4895 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/Base64.php @@ -0,0 +1,271 @@ + $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + + $dest .= + static::encode6Bits( $b0 >> 2 ) . + static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . + static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . + static::encode6Bits( $b2 & 63); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= + static::encode6Bits($b0 >> 2) . + static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . + static::encode6Bits(($b1 << 2) & 63); + if ($pad) { + $dest .= '='; + } + } else { + $dest .= + static::encode6Bits( $b0 >> 2) . + static::encode6Bits(($b0 << 4) & 63); + if ($pad) { + $dest .= '=='; + } + } + } + return $dest; + } + + /** + * decode from base64 into binary + * + * Base64 character set "./[A-Z][a-z][0-9]" + * + * @param string $encodedString + * @param bool $strictPadding + * @return string + * @throws \RangeException + * @throws \TypeError + * @psalm-suppress RedundantCondition + */ + public static function decode(string $encodedString, bool $strictPadding = false): string + { + // Remove padding + $srcLen = Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + + if ($strictPadding) { + if (($srcLen & 3) === 0) { + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + } + } + } + if (($srcLen & 3) === 1) { + throw new \RangeException( + 'Incorrect padding' + ); + } + if ($encodedString[$srcLen - 1] === '=') { + throw new \RangeException( + 'Incorrect padding' + ); + } + } else { + $encodedString = \rtrim($encodedString, '='); + $srcLen = Binary::safeStrlen($encodedString); + } + + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 4 <= $srcLen; $i += 4) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, 4)); + $c0 = static::decode6Bits($chunk[1]); + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $c3 = static::decode6Bits($chunk[4]); + + $dest .= \pack( + 'CCC', + ((($c0 << 2) | ($c1 >> 4)) & 0xff), + ((($c1 << 4) | ($c2 >> 2)) & 0xff), + ((($c2 << 6) | $c3 ) & 0xff) + ); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i)); + $c0 = static::decode6Bits($chunk[1]); + + if ($i + 2 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $dest .= \pack( + 'CC', + ((($c0 << 2) | ($c1 >> 4)) & 0xff), + ((($c1 << 4) | ($c2 >> 2)) & 0xff) + ); + $err |= ($c0 | $c1 | $c2) >> 8; + } elseif ($i + 1 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $dest .= \pack( + 'C', + ((($c0 << 2) | ($c1 >> 4)) & 0xff) + ); + $err |= ($c0 | $c1) >> 8; + } elseif ($i < $srcLen && $strictPadding) { + $err |= 1; + } + } + /** @var bool $check */ + $check = ($err === 0); + if (!$check) { + throw new \RangeException( + 'Base64::decode() only expects characters in the correct base64 alphabet' + ); + } + return $dest; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 6-bit integers + * into 8-bit integers. + * + * Base64 character set: + * [A-Z] [a-z] [0-9] + / + * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f + * + * @param int $src + * @return int + */ + protected static function decode6Bits(int $src): int + { + $ret = -1; + + // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); + + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); + + // if ($src == 0x2b) $ret += 62 + 1; + $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; + + // if ($src == 0x2f) ret += 63 + 1; + $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += ((25 - $src) >> 8) & 6; + + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= ((51 - $src) >> 8) & 75; + + // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 + $diff -= ((61 - $src) >> 8) & 15; + + // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 + $diff += ((62 - $src) >> 8) & 3; + + return \pack('C', $src + $diff); + } +} diff --git a/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php b/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php new file mode 100644 index 000000000..8ad2e2bf1 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php @@ -0,0 +1,88 @@ + 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 + $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45); + + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62); + + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68); + + // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $src += 0x2e; + + // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 + $src += ((0x2f - $src) >> 8) & 17; + + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += ((0x5a - $src) >> 8) & 6; + + // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 + $src -= ((0x7a - $src) >> 8) & 75; + + return \pack('C', $src); + } +} diff --git a/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php new file mode 100644 index 000000000..dd1459e85 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php @@ -0,0 +1,82 @@ + 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 + $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45); + + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52); + + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $src += 0x2e; + + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += ((0x39 - $src) >> 8) & 7; + + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += ((0x5a - $src) >> 8) & 6; + + return \pack('C', $src); + } +} diff --git a/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php new file mode 100644 index 000000000..1a4107527 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php @@ -0,0 +1,95 @@ + 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); + + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); + + // if ($src == 0x2c) $ret += 62 + 1; + $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; + + // if ($src == 0x5f) ret += 63 + 1; + $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += ((25 - $src) >> 8) & 6; + + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= ((51 - $src) >> 8) & 75; + + // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 + $diff -= ((61 - $src) >> 8) & 13; + + // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 + $diff += ((62 - $src) >> 8) & 49; + + return \pack('C', $src + $diff); + } +} diff --git a/vendor/paragonie/constant_time_encoding/src/Binary.php b/vendor/paragonie/constant_time_encoding/src/Binary.php new file mode 100644 index 000000000..38dbc4e66 --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/Binary.php @@ -0,0 +1,85 @@ + $chunk */ + $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 1)); + /** @var int $c */ + $c = $chunk[1] & 0xf; + /** @var int $b */ + $b = $chunk[1] >> 4; + + $hex .= pack( + 'CC', + (87 + $b + ((($b - 10) >> 8) & ~38)), + (87 + $c + ((($c - 10) >> 8) & ~38)) + ); + } + return $hex; + } + + /** + * Convert a binary string into a hexadecimal string without cache-timing + * leaks, returning uppercase letters (as per RFC 4648) + * + * @param string $binString (raw binary) + * @return string + * @throws \TypeError + */ + public static function encodeUpper(string $binString): string + { + /** @var string $hex */ + $hex = ''; + /** @var int $len */ + $len = Binary::safeStrlen($binString); + + for ($i = 0; $i < $len; ++$i) { + /** @var array $chunk */ + $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 2)); + /** @var int $c */ + $c = $chunk[1] & 0xf; + /** @var int $b */ + $b = $chunk[1] >> 4; + + $hex .= pack( + 'CC', + (55 + $b + ((($b - 10) >> 8) & ~6)), + (55 + $c + ((($c - 10) >> 8) & ~6)) + ); + } + return $hex; + } + + /** + * Convert a hexadecimal string into a binary string without cache-timing + * leaks + * + * @param string $encodedString + * @param bool $strictPadding + * @return string (raw binary) + * @throws \RangeException + */ + public static function decode(string $encodedString, bool $strictPadding = false): string + { + /** @var int $hex_pos */ + $hex_pos = 0; + /** @var string $bin */ + $bin = ''; + /** @var int $c_acc */ + $c_acc = 0; + /** @var int $hex_len */ + $hex_len = Binary::safeStrlen($encodedString); + /** @var int $state */ + $state = 0; + if (($hex_len & 1) !== 0) { + if ($strictPadding) { + throw new \RangeException( + 'Expected an even number of hexadecimal characters' + ); + } else { + $encodedString = '0' . $encodedString; + ++$hex_len; + } + } + + /** @var array $chunk */ + $chunk = \unpack('C*', $encodedString); + while ($hex_pos < $hex_len) { + ++$hex_pos; + /** @var int $c */ + $c = $chunk[$hex_pos]; + /** @var int $c_num */ + $c_num = $c ^ 48; + /** @var int $c_num0 */ + $c_num0 = ($c_num - 10) >> 8; + /** @var int $c_alpha */ + $c_alpha = ($c & ~32) - 55; + /** @var int $c_alpha0 */ + $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; + + if (($c_num0 | $c_alpha0) === 0) { + throw new \RangeException( + 'Expected hexadecimal character' + ); + } + /** @var int $c_val */ + $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); + if ($state === 0) { + $c_acc = $c_val * 16; + } else { + $bin .= \pack('C', $c_acc | $c_val); + } + $state ^= 1; + } + return $bin; + } +} diff --git a/vendor/paragonie/constant_time_encoding/src/RFC4648.php b/vendor/paragonie/constant_time_encoding/src/RFC4648.php new file mode 100644 index 000000000..492cad00e --- /dev/null +++ b/vendor/paragonie/constant_time_encoding/src/RFC4648.php @@ -0,0 +1,175 @@ + "Zm9v" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base64Encode(string $str): string + { + return Base64::encode($str); + } + + /** + * RFC 4648 Base64 decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base64Decode(string $str): string + { + return Base64::decode($str, true); + } + + /** + * RFC 4648 Base64 (URL Safe) encoding + * + * "foo" -> "Zm9v" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base64UrlSafeEncode(string $str): string + { + return Base64UrlSafe::encode($str); + } + + /** + * RFC 4648 Base64 (URL Safe) decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base64UrlSafeDecode(string $str): string + { + return Base64UrlSafe::decode($str, true); + } + + /** + * RFC 4648 Base32 encoding + * + * "foo" -> "MZXW6===" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base32Encode(string $str): string + { + return Base32::encodeUpper($str); + } + + /** + * RFC 4648 Base32 encoding + * + * "MZXW6===" -> "foo" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base32Decode(string $str): string + { + return Base32::decodeUpper($str, true); + } + + /** + * RFC 4648 Base32-Hex encoding + * + * "foo" -> "CPNMU===" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base32HexEncode(string $str): string + { + return Base32::encodeUpper($str); + } + + /** + * RFC 4648 Base32-Hex decoding + * + * "CPNMU===" -> "foo" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base32HexDecode(string $str): string + { + return Base32::decodeUpper($str, true); + } + + /** + * RFC 4648 Base16 decoding + * + * "foo" -> "666F6F" + * + * @param string $str + * @return string + * @throws \TypeError + */ + public static function base16Encode(string $str): string + { + return Hex::encodeUpper($str); + } + + /** + * RFC 4648 Base16 decoding + * + * "666F6F" -> "foo" + * + * @param string $str + * @return string + */ + public static function base16Decode(string $str): string + { + return Hex::decode($str, true); + } +} \ No newline at end of file diff --git a/vendor/paragonie/random_compat/LICENSE b/vendor/paragonie/random_compat/LICENSE new file mode 100644 index 000000000..45c7017df --- /dev/null +++ b/vendor/paragonie/random_compat/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Paragon Initiative Enterprises + +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/vendor/paragonie/random_compat/build-phar.sh b/vendor/paragonie/random_compat/build-phar.sh new file mode 100755 index 000000000..b4a5ba31c --- /dev/null +++ b/vendor/paragonie/random_compat/build-phar.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) + +php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/vendor/paragonie/random_compat/composer.json b/vendor/paragonie/random_compat/composer.json new file mode 100644 index 000000000..f2b9c4e51 --- /dev/null +++ b/vendor/paragonie/random_compat/composer.json @@ -0,0 +1,34 @@ +{ + "name": "paragonie/random_compat", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "random", + "polyfill", + "pseudorandom" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "support": { + "issues": "https://github.com/paragonie/random_compat/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/random_compat" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "vimeo/psalm": "^1", + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + } +} diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey new file mode 100644 index 000000000..eb50ebfcd --- /dev/null +++ b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm +pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p ++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc +-----END PUBLIC KEY----- diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc new file mode 100644 index 000000000..6a1d7f300 --- /dev/null +++ b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (MingW32) + +iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip +QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg +1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW +NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA +NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV +JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= +=B6+8 +-----END PGP SIGNATURE----- diff --git a/vendor/paragonie/random_compat/lib/random.php b/vendor/paragonie/random_compat/lib/random.php new file mode 100644 index 000000000..c7731a56f --- /dev/null +++ b/vendor/paragonie/random_compat/lib/random.php @@ -0,0 +1,32 @@ +buildFromDirectory(dirname(__DIR__).'/lib'); +rename( + dirname(__DIR__).'/lib/index.php', + dirname(__DIR__).'/lib/random.php' +); + +/** + * If we pass an (optional) path to a private key as a second argument, we will + * sign the Phar with OpenSSL. + * + * If you leave this out, it will produce an unsigned .phar! + */ +if ($argc > 1) { + if (!@is_readable($argv[1])) { + echo 'Could not read the private key file:', $argv[1], "\n"; + exit(255); + } + $pkeyFile = file_get_contents($argv[1]); + + $private = openssl_get_privatekey($pkeyFile); + if ($private !== false) { + $pkey = ''; + openssl_pkey_export($private, $pkey); + $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + + /** + * Save the corresponding public key to the file + */ + if (!@is_readable($dist.'/random_compat.phar.pubkey')) { + $details = openssl_pkey_get_details($private); + file_put_contents( + $dist.'/random_compat.phar.pubkey', + $details['key'] + ); + } + } else { + echo 'An error occurred reading the private key from OpenSSL.', "\n"; + exit(255); + } +} diff --git a/vendor/paragonie/random_compat/psalm-autoload.php b/vendor/paragonie/random_compat/psalm-autoload.php new file mode 100644 index 000000000..d71d1b818 --- /dev/null +++ b/vendor/paragonie/random_compat/psalm-autoload.php @@ -0,0 +1,9 @@ + + + + + + + + + + + + + + + diff --git a/vendor/phpseclib/phpseclib/.github/FUNDING.yml b/vendor/phpseclib/phpseclib/.github/FUNDING.yml new file mode 100644 index 000000000..dc4ccd96e --- /dev/null +++ b/vendor/phpseclib/phpseclib/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: terrafrost +patreon: phpseclib +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: "packagist/phpseclib/phpseclib" +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/vendor/phpseclib/phpseclib/AUTHORS b/vendor/phpseclib/phpseclib/AUTHORS new file mode 100644 index 000000000..a08b3099c --- /dev/null +++ b/vendor/phpseclib/phpseclib/AUTHORS @@ -0,0 +1,6 @@ +phpseclib Lead Developer: TerraFrost (Jim Wigginton) + +phpseclib Developers: monnerat (Patrick Monnerat) + bantu (Andreas Fischer) + petrich (Hans-Jürgen Petrich) + GrahamCampbell (Graham Campbell) diff --git a/vendor/phpseclib/phpseclib/BACKERS.md b/vendor/phpseclib/phpseclib/BACKERS.md new file mode 100644 index 000000000..e03152ca1 --- /dev/null +++ b/vendor/phpseclib/phpseclib/BACKERS.md @@ -0,0 +1,8 @@ +# Backers + +phpseclib ongoing development is made possible by [Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) and by contributions by users like you. Thank you. + +## Backers + +- Zane Hooper +- [Setasign](https://www.setasign.com/) \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/LICENSE b/vendor/phpseclib/phpseclib/LICENSE new file mode 100644 index 000000000..e7214ebbe --- /dev/null +++ b/vendor/phpseclib/phpseclib/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2011-2019 TerraFrost and other contributors + +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/vendor/phpseclib/phpseclib/README.md b/vendor/phpseclib/phpseclib/README.md new file mode 100644 index 000000000..7df111bf5 --- /dev/null +++ b/vendor/phpseclib/phpseclib/README.md @@ -0,0 +1,94 @@ +# phpseclib - PHP Secure Communications Library + +[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=3.0)](https://travis-ci.com/phpseclib/phpseclib) + +## Supporting phpseclib + +- [Become a backer or sponsor on Patreon](https://www.patreon.com/phpseclib) +- [One-time donation via PayPal or crypto-currencies](http://sourceforge.net/donate/index.php?group_id=198487) +- [Subscribe to Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) + +## Introduction + +MIT-licensed pure-PHP implementations of the following: + +SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305 + +* [Browse Git](https://github.com/phpseclib/phpseclib) + +## Documentation + +* [Documentation / Manual](https://phpseclib.com/) +* [API Documentation](https://api.phpseclib.com/3.0/) (generated by Doctum) + +## Branches + +### master + +* Development Branch +* Unstable API +* Do not use in production + +### 3.0 + +* Long term support (LTS) release +* Major expansion of cryptographic primitives +* Minimum PHP version: 5.6.1 +* PSR-4 autoloading with namespace rooted at `\phpseclib3` +* Install via Composer: `composer require phpseclib/phpseclib:~3.0` + +### 2.0 + +* Long term support (LTS) release +* Modernized version of 1.0 +* Minimum PHP version: 5.3.3 +* PSR-4 autoloading with namespace rooted at `\phpseclib` +* Install via Composer: `composer require phpseclib/phpseclib:~2.0` + +### 1.0 + +* Long term support (LTS) release +* PHP4 compatible +* Composer compatible (PSR-0 autoloading) +* Install using Composer: `composer require phpseclib/phpseclib:~1.0` +* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm) +* [Download 1.0.19 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.19.zip/download) + +## Security contact information + +To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. + +## Support + +Need Support? + +* [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib) +* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new) +* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use) + +## Contributing + +1. Fork the Project + +2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/)) + +3. Install Development Dependencies + + ``` sh + composer install + ``` + +4. Create a Feature Branch + +5. (Recommended) Run the Test Suite + + ``` sh + vendor/bin/phpunit + ``` +6. (Recommended) Check whether your code conforms to our Coding Standards by running + + ``` sh + vendor/bin/phing -f build/build.xml sniff + ``` + +7. Send us a Pull Request diff --git a/vendor/phpseclib/phpseclib/appveyor.yml b/vendor/phpseclib/phpseclib/appveyor.yml new file mode 100644 index 000000000..210a90347 --- /dev/null +++ b/vendor/phpseclib/phpseclib/appveyor.yml @@ -0,0 +1,27 @@ +build: false +shallow_clone: false +platform: + - x86 + - x64 +clone_folder: C:\projects\phpseclib + +install: + - cinst -y OpenSSL.Light + - SET PATH=C:\Program Files\OpenSSL;%PATH% + - sc config wuauserv start= auto + - net start wuauserv + - cinst -y php --version 5.6.30 + - cd c:\tools\php56 + - copy php.ini-production php.ini + - echo date.timezone="UTC" >> php.ini + - echo extension_dir=ext >> php.ini + - echo extension=php_openssl.dll >> php.ini + - echo extension=php_gmp.dll >> php.ini + - cd C:\projects\phpseclib + - SET PATH=C:\tools\php56;%PATH% + - php.exe -r "readfile('http://getcomposer.org/installer');" | php.exe + - php.exe composer.phar install --prefer-source --no-interaction + +test_script: + - cd C:\projects\phpseclib + - vendor\bin\phpunit.bat tests/Windows32Test.php \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/composer.json b/vendor/phpseclib/phpseclib/composer.json new file mode 100644 index 000000000..34dc9993d --- /dev/null +++ b/vendor/phpseclib/phpseclib/composer.json @@ -0,0 +1,77 @@ +{ + "name": "phpseclib/phpseclib", + "type": "library", + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "keywords": [ + "security", + "crypto", + "cryptography", + "encryption", + "signature", + "signing", + "rsa", + "aes", + "blowfish", + "twofish", + "ssh", + "sftp", + "x509", + "x.509", + "asn1", + "asn.1", + "BigInteger" + ], + "homepage": "http://phpseclib.sourceforge.net", + "license": "MIT", + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^5.7|^6.0|^9.4", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations." + }, + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php b/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php new file mode 100644 index 000000000..666fce59f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php @@ -0,0 +1,387 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Common\Functions; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\Common\FiniteField; + +/** + * Common String Functions + * + * @package Functions\Strings + * @author Jim Wigginton + */ +abstract class Strings +{ + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @access public + * @return string + */ + public static function shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } + + /** + * String Pop + * + * Inspired by array_pop + * + * @param string $string + * @param int $index + * @access public + * @return string + */ + public static function pop(&$string, $index = 1) + { + $substr = substr($string, -$index); + $string = substr($string, 0, -$index); + return $substr; + } + + /** + * Parse SSH2-style string + * + * Returns either an array or a boolean if $data is malformed. + * + * Valid characters for $format are as follows: + * + * C = byte + * b = boolean (true/false) + * N = uint32 + * s = string + * i = mpint + * L = name-list + * + * uint64 is not supported. + * + * @param string $format + * @param string $data + * @return mixed + */ + public static function unpackSSH2($format, &$data) + { + $format = self::formatPack($format); + $result = []; + for ($i = 0; $i < strlen($format); $i++) { + switch ($format[$i]) { + case 'C': + case 'b': + if (!strlen($data)) { + throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); + } + break; + case 'N': + case 'i': + case 's': + case 'L': + if (strlen($data) < 4) { + throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); + } + break; + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + switch ($format[$i]) { + case 'C': + $result[] = ord(self::shift($data)); + continue 2; + case 'b': + $result[] = ord(self::shift($data)) != 0; + continue 2; + case 'N': + list(, $temp) = unpack('N', self::shift($data, 4)); + $result[] = $temp; + continue 2; + } + list(, $length) = unpack('N', self::shift($data, 4)); + if (strlen($data) < $length) { + throw new \LengthException("$length bytes needed; " . strlen($data) . ' bytes available'); + } + $temp = self::shift($data, $length); + switch ($format[$i]) { + case 'i': + $result[] = new BigInteger($temp, -256); + break; + case 's': + $result[] = $temp; + break; + case 'L': + $result[] = explode(',', $temp); + } + } + + return $result; + } + + /** + * Create SSH2-style string + * + * @param string[] ...$elements + * @access public + * @return mixed + */ + public static function packSSH2(...$elements) + { + $format = self::formatPack($elements[0]); + array_shift($elements); + if (strlen($format) != count($elements)) { + throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); + } + $result = ''; + for ($i = 0; $i < strlen($format); $i++) { + $element = $elements[$i]; + switch ($format[$i]) { + case 'C': + if (!is_int($element)) { + throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); + } + $result.= pack('C', $element); + break; + case 'b': + if (!is_bool($element)) { + throw new \InvalidArgumentException('A boolean parameter was expected.'); + } + $result.= $element ? "\1" : "\0"; + break; + case 'N': + if (is_float($element)) { + $element = (int) $element; + } + if (!is_int($element)) { + throw new \InvalidArgumentException('An integer was expected.'); + } + $result.= pack('N', $element); + break; + case 's': + if (!self::is_stringable($element)) { + throw new \InvalidArgumentException('A string was expected.'); + } + $result.= pack('Na*', strlen($element), $element); + break; + case 'i': + if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) { + throw new \InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.'); + } + $element = $element->toBytes(true); + $result.= pack('Na*', strlen($element), $element); + break; + case 'L': + if (!is_array($element)) { + throw new \InvalidArgumentException('An array was expected.'); + } + $element = implode(',', $element); + $result.= pack('Na*', strlen($element), $element); + break; + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + } + return $result; + } + + /** + * Expand a pack string + * + * Converts C5 to CCCCC, for example. + * + * @access private + * @param string $format + * @return string + */ + private static function formatPack($format) + { + $parts = preg_split('#(\d+)#', $format, -1, PREG_SPLIT_DELIM_CAPTURE); + $format = ''; + for ($i = 1; $i < count($parts); $i+=2) { + $format.= substr($parts[$i - 1], 0, -1) . str_repeat(substr($parts[$i - 1], -1), $parts[$i]); + } + $format.= $parts[$i - 1]; + + return $format; + } + + /** + * Convert binary data into bits + * + * bin2hex / hex2bin refer to base-256 encoded data as binary, whilst + * decbin / bindec refer to base-2 encoded data as binary. For the purposes + * of this function, bin refers to base-256 encoded data whilst bits refers + * to base-2 encoded data + * + * @access public + * @param string $x + * @return string + */ + public static function bits2bin($x) + { + /* + // the pure-PHP approach is faster than the GMP approach + if (function_exists('gmp_export')) { + return strlen($x) ? gmp_export(gmp_init($x, 2)) : gmp_init(0); + } + */ + + if (preg_match('#[^01]#', $x)) { + throw new \RuntimeException('The only valid characters are 0 and 1'); + } + + if (!defined('PHP_INT_MIN')) { + define('PHP_INT_MIN', ~PHP_INT_MAX); + } + + $length = strlen($x); + if (!$length) { + return ''; + } + $block_size = PHP_INT_SIZE << 3; + $pad = $block_size - ($length % $block_size); + if ($pad != $block_size) { + $x = str_repeat('0', $pad) . $x; + } + + $parts = str_split($x, $block_size); + $str = ''; + foreach ($parts as $part) { + $xor = $part[0] == '1' ? PHP_INT_MIN : 0; + $part[0] = '0'; + $str.= pack( + PHP_INT_SIZE == 4 ? 'N' : 'J', + $xor ^ eval('return 0b' . $part . ';') + ); + } + return ltrim($str, "\0"); + } + + /** + * Convert bits to binary data + * + * @access public + * @param string $x + * @return string + */ + public static function bin2bits($x) + { + /* + // the pure-PHP approach is slower than the GMP approach BUT + // i want to the pure-PHP version to be easily unit tested as well + if (function_exists('gmp_import')) { + return gmp_strval(gmp_import($x), 2); + } + */ + + $len = strlen($x); + $mod = $len % PHP_INT_SIZE; + if ($mod) { + $x = str_pad($x, $len + PHP_INT_SIZE - $mod, "\0", STR_PAD_LEFT); + } + + $bits = ''; + if (PHP_INT_SIZE == 4) { + $digits = unpack('N*', $x); + foreach ($digits as $digit) { + $bits.= sprintf('%032b', $digit); + } + } else { + $digits = unpack('J*', $x); + foreach ($digits as $digit) { + $bits.= sprintf('%064b', $digit); + } + } + + return ltrim($bits, '0'); + } + + /** + * Switch Endianness Bit Order + * + * @access public + * @param string $x + * @return string + */ + public static function switchEndianness($x) + { + $r = ''; + // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits + for ($i = strlen($x) - 1; $i >= 0; $i--) { + $b = ord($x[$i]); + $p1 = ($b * 0x0802) & 0x22110; + $p2 = ($b * 0x8020) & 0x88440; + $r.= chr( + (($p1 | $p2) * 0x10101) >> 16 + ); + } + return $r; + } + + /** + * Increment the current string + * + * @param string $var + * @return string + * @access public + */ + public static function increment_str(&$var) + { + for ($i = 4; $i <= strlen($var); $i+= 4) { + $temp = substr($var, -$i, 4); + switch ($temp) { + case "\xFF\xFF\xFF\xFF": + $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); + break; + case "\x7F\xFF\xFF\xFF": + $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); + return $var; + default: + $temp = unpack('Nnum', $temp); + $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); + return $var; + } + } + + $remainder = strlen($var) % 4; + + if ($remainder == 0) { + return $var; + } + + $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); + $temp = substr(pack('N', $temp['num'] + 1), -$remainder); + $var = substr_replace($var, $temp, 0, $remainder); + + return $var; + } + + /** + * Find whether the type of a variable is string (or could be converted to one) + * + * @param string|object $var + * @return boolean + * @access public + */ + public static function is_stringable($var) + { + return is_string($var) || (is_object($var) && method_exists($var, '__toString')); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php new file mode 100644 index 000000000..23ea6e146 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php @@ -0,0 +1,123 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $aes->decrypt($aes->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package AES + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +/** + * Pure-PHP implementation of AES. + * + * @package AES + * @author Jim Wigginton + * @access public + */ +class AES extends Rijndael +{ + /** + * Dummy function + * + * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. + * + * @see \phpseclib3\Crypt\Rijndael::setBlockLength() + * @access public + * @param int $length + * @throws \BadMethodCallException anytime it's called + */ + public function setBlockLength($length) + { + throw new \BadMethodCallException('The block length cannot be set for AES.'); + } + + /** + * Sets the key length + * + * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length + * + * @see \phpseclib3\Crypt\Rijndael:setKeyLength() + * @access public + * @param int $length + * @throws \LengthException if the key length isn't supported + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 192: + case 256: + break; + default: + throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); + } + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Rijndael supports five different key lengths, AES only supports three. + * + * @see \phpseclib3\Crypt\Rijndael:setKey() + * @see setKeyLength() + * @access public + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 24: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + + parent::setKey($key); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php new file mode 100644 index 000000000..c75d983ab --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php @@ -0,0 +1,556 @@ + + * setKey('12345678901234567890123456789012'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $blowfish->decrypt($blowfish->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package Blowfish + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; + +/** + * Pure-PHP implementation of Blowfish. + * + * @package Blowfish + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @access public + */ +class Blowfish extends BlockCipher +{ + /** + * Block Length of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + * @access private + */ + protected $block_size = 8; + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + * @access private + */ + protected $cipher_name_mcrypt = 'blowfish'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + * @access private + */ + protected $cfb_init_len = 500; + + /** + * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each + * + * S-Box 0 + * + * @access private + * @var array + */ + private static $sbox0 = [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + ]; + + /** + * S-Box 1 + * + * @access private + * @var array + */ + private static $sbox1 = [ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + ]; + + /** + * S-Box 2 + * + * @access private + * @var array + */ + private static $sbox2 = [ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + ]; + + /** + * S-Box 3 + * + * @access private + * @var array + */ + private static $sbox3 = [ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + ]; + + /** + * P-Array consists of 18 32-bit subkeys + * + * @var array + * @access private + */ + private static $parray = [ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, + 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b + ]; + + /** + * The BCTX-working Array + * + * Holds the expanded key [p] and the key-depended s-boxes [sb] + * + * @var array + * @access private + */ + private $bctx; + + /** + * Holds the last used key + * + * @var array + * @access private + */ + private $kl; + + /** + * The Key Length (in bytes) + * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 16; + + /** + * Default Constructor. + * + * @param string $mode + * @access public + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Sets the key length. + * + * Key lengths can be between 32 and 448 bits. + * + * @access public + * @param int $length + */ + public function setKeyLength($length) + { + if ($length < 32 || $length > 448) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported'); + } + + $this->key_length = $length >> 3; + + parent::setKeyLength($length); + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * @param int $engine + * @access protected + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($engine == self::ENGINE_OPENSSL) { + if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) { + return false; + } + if ($this->key_length < 16) { + return false; + } + self::$cipher_name_openssl_ecb = 'bf-ecb'; + $this->cipher_name_openssl = 'bf-' . $this->openssl_translate_mode(); + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + * @access private + */ + protected function setupKey() + { + if (isset($this->kl['key']) && $this->key === $this->kl['key']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key]; + + /* key-expanding p[] and S-Box building sb[] */ + $this->bctx = [ + 'p' => [], + 'sb' => [ + self::$sbox0, + self::$sbox1, + self::$sbox2, + self::$sbox3 + ] + ]; + + // unpack binary string in unsigned chars + $key = array_values(unpack('C*', $this->key)); + $keyl = count($key); + for ($j = 0, $i = 0; $i < 18; ++$i) { + // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ... + for ($data = 0, $k = 0; $k < 4; ++$k) { + $data = ($data << 8) | $key[$j]; + if (++$j >= $keyl) { + $j = 0; + } + } + $this->bctx['p'][] = self::$parray[$i] ^ $data; + } + + // encrypt the zero-string, replace P1 and P2 with the encrypted data, + // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys + $data = "\0\0\0\0\0\0\0\0"; + for ($i = 0; $i < 18; $i += 2) { + list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + $this->bctx['p'][$i ] = $l; + $this->bctx['p'][$i + 1] = $r; + } + for ($i = 0; $i < 4; ++$i) { + for ($j = 0; $j < 256; $j += 2) { + list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + $this->bctx['sb'][$i][$j ] = $l; + $this->bctx['sb'][$i][$j + 1] = $r; + } + } + } + + /** + * Encrypts a block + * + * @access private + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + $p = $this->bctx['p']; + // extract($this->bctx['sb'], EXTR_PREFIX_ALL, 'sb'); // slower + $sb_0 = $this->bctx['sb'][0]; + $sb_1 = $this->bctx['sb'][1]; + $sb_2 = $this->bctx['sb'][2]; + $sb_3 = $this->bctx['sb'][3]; + + $in = unpack('N*', $in); + $l = $in[1]; + $r = $in[2]; + + for ($i = 0; $i < 16; $i+= 2) { + $l^= $p[$i]; + $r^= self::safe_intval((self::safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]); + + $r^= $p[$i + 1]; + $l^= self::safe_intval((self::safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]); + } + return pack('N*', $r ^ $p[17], $l ^ $p[16]); + } + + /** + * Decrypts a block + * + * @access private + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + $p = $this->bctx['p']; + $sb_0 = $this->bctx['sb'][0]; + $sb_1 = $this->bctx['sb'][1]; + $sb_2 = $this->bctx['sb'][2]; + $sb_3 = $this->bctx['sb'][3]; + + $in = unpack('N*', $in); + $l = $in[1]; + $r = $in[2]; + + for ($i = 17; $i > 2; $i-= 2) { + $l^= $p[$i]; + $r^= self::safe_intval((self::safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]); + + $r^= $p[$i - 1]; + $l^= self::safe_intval((self::safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]); + } + return pack('N*', $r ^ $p[0], $l ^ $p[1]); + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() + * @access private + */ + protected function setupInlineCrypt() + { + $p = $this->bctx['p']; + $init_crypt = ' + static $sb_0, $sb_1, $sb_2, $sb_3; + if (!$sb_0) { + $sb_0 = $this->bctx["sb"][0]; + $sb_1 = $this->bctx["sb"][1]; + $sb_2 = $this->bctx["sb"][2]; + $sb_3 = $this->bctx["sb"][3]; + } + '; + + $safeint = self::safe_intval_inline(); + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + for ($i = 0; $i < 16; $i+= 2) { + $encrypt_block.= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i + 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } + $encrypt_block.= ' + $in = pack("N*", + $r ^ ' . $p[17] . ', + $l ^ ' . $p[16] . ' + ); + '; + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + + for ($i = 17; $i > 2; $i-= 2) { + $decrypt_block.= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i - 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } + + $decrypt_block.= ' + $in = pack("N*", + $r ^ ' . $p[0] . ', + $l ^ ' . $p[1] . ' + ); + '; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php new file mode 100644 index 000000000..0bf1c2eba --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php @@ -0,0 +1,797 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\BadDecryptionException; + +/** + * Pure-PHP implementation of ChaCha20. + * + * @package ChaCha20 + * @author Jim Wigginton + * @access public + */ +class ChaCha20 extends Salsa20 +{ + /** + * The OpenSSL specific name of the cipher + * + * @var string + */ + protected $cipher_name_openssl = 'chacha20'; + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @access protected + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_LIBSODIUM: + // PHP 7.2.0 (30 Nov 2017) added support for libsodium + + // we could probably make it so that if $this->counter == 0 then the first block would be done with either OpenSSL + // or PHP and then subsequent blocks would then be done with libsodium but idk - it's not a high priority atm + + // we could also make it so that if $this->counter == 0 and $this->continuousBuffer then do the first string + // with libsodium and subsequent strings with openssl or pure-PHP but again not a high priority + return function_exists('sodium_crypto_aead_chacha20poly1305_ietf_encrypt') && + $this->key_length == 32 && + (($this->usePoly1305 && !isset($this->poly1305Key) && $this->counter == 0) || $this->counter == 1) && + !$this->continuousBuffer; + case self::ENGINE_OPENSSL: + // OpenSSL 1.1.0 (released 25 Aug 2016) added support for chacha20. + // PHP didn't support OpenSSL 1.1.0 until 7.0.19 (11 May 2017) + + // if you attempt to provide openssl with a 128 bit key (as opposed to a 256 bit key) openssl will null + // pad the key to 256 bits and still use the expansion constant for 256-bit keys. the fact that + // openssl treats the IV as both the counter and nonce, however, let's us use openssl in continuous mode + // whereas libsodium does not + if ($this->key_length != 32) { + return false; + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + $this->setup(); + + if ($this->engine == self::ENGINE_LIBSODIUM) { + return $this->encrypt_with_libsodium($plaintext); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + $this->setup(); + + if ($this->engine == self::ENGINE_LIBSODIUM) { + return $this->decrypt_with_libsodium($ciphertext); + } + + return parent::decrypt($ciphertext); + } + + /** + * Encrypts a message with libsodium + * + * @see self::encrypt() + * @param string $plaintext + * @return string $text + */ + private function encrypt_with_libsodium($plaintext) + { + $params = [$plaintext, $this->aad, $this->nonce, $this->key]; + $ciphertext = strlen($this->nonce) == 8 ? + sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : + sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); + if (!$this->usePoly1305) { + return substr($ciphertext, 0, strlen($plaintext)); + } + + $newciphertext = substr($ciphertext, 0, strlen($plaintext)); + + $this->newtag = $this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12 ? + substr($ciphertext, strlen($plaintext)) : + $this->poly1305($newciphertext); + + return $newciphertext; + } + + /** + * Decrypts a message with libsodium + * + * @see self::decrypt() + * @param string $ciphertext + * @return string $text + */ + private function decrypt_with_libsodium($ciphertext) + { + $params = [$ciphertext, $this->aad, $this->nonce, $this->key]; + + if (isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + if ($this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12) { + $plaintext = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$params); + $this->oldtag = false; + if ($plaintext === false) { + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + return $plaintext; + } + $newtag = $this->poly1305($ciphertext); + if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + } + + $plaintext = strlen($this->nonce) == 8 ? + sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : + sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); + + return substr($plaintext, 0, strlen($ciphertext)); + } + + /** + * Sets the nonce. + * + * @param string $nonce + */ + public function setNonce($nonce) + { + if (!is_string($nonce)) { + throw new \UnexpectedValueException('The nonce should be a string'); + } + + /* + from https://tools.ietf.org/html/rfc7539#page-7 + + "Note also that the original ChaCha had a 64-bit nonce and 64-bit + block count. We have modified this here to be more consistent with + recommendations in Section 3.2 of [RFC5116]." + */ + switch (strlen($nonce)) { + case 8: // 64 bits + case 12: // 96 bits + break; + default: + throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported'); + } + + $this->nonce = $nonce; + $this->changed = true; + $this->setEngine(); + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setNonce() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * @see self::setKey() + * @see self::setNonce() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; + + $this->changed = $this->nonIVChanged = false; + + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + if ($this->usePoly1305 && !isset($this->poly1305Key)) { + $this->usingGeneratedPoly1305Key = true; + if ($this->engine == self::ENGINE_LIBSODIUM) { + return; + } + $this->createPoly1305Key(); + } + + $key = $this->key; + if (strlen($key) == 16) { + $constant = 'expand 16-byte k'; + $key.= $key; + } else { + $constant = 'expand 32-byte k'; + } + + $this->p1 = $constant . $key; + $this->p2 = $this->nonce; + if (strlen($this->nonce) == 8) { + $this->p2 = "\0\0\0\0" . $this->p2; + } + } + + /** + * The quarterround function + * + * @param int $a + * @param int $b + * @param int $c + * @param int $d + */ + protected static function quarterRound(&$a, &$b, &$c, &$d) + { + $a+= $b; $d = self::leftRotate($d ^ $a, 16); + $c+= $d; $b = self::leftRotate($b ^ $c, 12); + $a+= $b; $d = self::leftRotate($d ^ $a, 8); + $c+= $d; $b = self::leftRotate($b ^ $c, 7); + } + + /** + * The doubleround function + * + * @param int $x0 (by reference) + * @param int $x1 (by reference) + * @param int $x2 (by reference) + * @param int $x3 (by reference) + * @param int $x4 (by reference) + * @param int $x5 (by reference) + * @param int $x6 (by reference) + * @param int $x7 (by reference) + * @param int $x8 (by reference) + * @param int $x9 (by reference) + * @param int $x10 (by reference) + * @param int $x11 (by reference) + * @param int $x12 (by reference) + * @param int $x13 (by reference) + * @param int $x14 (by reference) + * @param int $x15 (by reference) + */ + protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) + { + // columnRound + static::quarterRound($x0, $x4, $x8, $x12); + static::quarterRound($x1, $x5, $x9, $x13); + static::quarterRound($x2, $x6, $x10, $x14); + static::quarterRound($x3, $x7, $x11, $x15); + // rowRound + static::quarterRound($x0, $x5, $x10, $x15); + static::quarterRound($x1, $x6, $x11, $x12); + static::quarterRound($x2, $x7, $x8, $x13); + static::quarterRound($x3, $x4, $x9, $x14); + } + + /** + * The Salsa20 hash function function + * + * On my laptop this loop unrolled / function dereferenced version of parent::salsa20 encrypts 1mb of text in + * 0.65s vs the 0.85s that it takes with the parent method. + * + * If we were free to assume that the host OS would always be 64-bits then the if condition in leftRotate could + * be eliminated and we could knock this done to 0.60s. + * + * For comparison purposes, RC4 takes 0.16s and AES in CTR mode with the Eval engine takes 0.48s. + * AES in CTR mode with the PHP engine takes 1.19s. Salsa20 / ChaCha20 do not benefit as much from the Eval + * approach due to the fact that there are a lot less variables to de-reference, fewer loops to unroll, etc + * + * @param string $x + */ + protected static function salsa20($x) + { + list(, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15) = unpack('V*', $x); + $z0 = $x0; + $z1 = $x1; + $z2 = $x2; + $z3 = $x3; + $z4 = $x4; + $z5 = $x5; + $z6 = $x6; + $z7 = $x7; + $z8 = $x8; + $z9 = $x9; + $z10 = $x10; + $z11 = $x11; + $z12 = $x12; + $z13 = $x13; + $z14 = $x14; + $z15 = $x15; + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); + $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); + $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); + + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); + $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); + $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); + + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); + $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); + $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); + + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); + $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); + $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); + $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); + $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); + + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); + $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); + $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); + + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); + $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); + $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); + + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); + $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); + $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); + + $x0+= $z0; + $x1+= $z1; + $x2+= $z2; + $x3+= $z3; + $x4+= $z4; + $x5+= $z5; + $x6+= $z6; + $x7+= $z7; + $x8+= $z8; + $x9+= $z9; + $x10+= $z10; + $x11+= $z11; + $x12+= $z12; + $x13+= $z13; + $x14+= $z14; + $x15+= $z15; + + return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php new file mode 100644 index 000000000..9c368ebb8 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php @@ -0,0 +1,492 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\ECDSA; + +/** + * Base Class for all asymmetric cipher classes + * + * @package AsymmetricKey + * @author Jim Wigginton + */ +abstract class AsymmetricKey +{ + /** + * Precomputed Zero + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected static $zero; + + /** + * Precomputed One + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected static $one; + + /** + * Format of the loaded key + * + * @var string + * @access private + */ + protected $format; + + /** + * Hash function + * + * @var \phpseclib3\Crypt\Hash + * @access private + */ + protected $hash; + + /** + * HMAC function + * + * @var \phpseclib3\Crypt\Hash + * @access private + */ + private $hmac; + + /** + * Supported plugins (lower case) + * + * @see self::initialize_static_variables() + * @var array + * @access private + */ + private static $plugins = []; + + /** + * Invisible plugins + * + * @see self::initialize_static_variables() + * @var array + * @access private + */ + private static $invisiblePlugins = []; + + /** + * Supported signature formats (lower case) + * + * @see self::initialize_static_variables() + * @var array + * @access private + */ + private static $signatureFormats = []; + + /** + * Supported signature formats (original case) + * + * @see self::initialize_static_variables() + * @var array + * @access private + */ + private static $signatureFileFormats = []; + + /** + * Available Engines + * + * @var boolean[] + * @access private + */ + protected static $engines = []; + + /** + * The constructor + */ + protected function __construct() + { + self::initialize_static_variables(); + + $this->hash = new Hash('sha256'); + $this->hmac = new Hash('sha256'); + } + + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$zero)) { + self::$zero= new BigInteger(0); + self::$one = new BigInteger(1); + } + + self::loadPlugins('Keys'); + if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') { + self::loadPlugins('Signature'); + } + } + + /** + * Load the key + * + * @param string $key + * @param string $password optional + * @return AsymmetricKey + */ + public static function load($key, $password = false) + { + self::initialize_static_variables(); + + $components = false; + foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { + if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) { + continue; + } + try { + $components = $format::load($key, $password); + } catch (\Exception $e) { + $components = false; + } + if ($components !== false) { + break; + } + } + + if ($components === false) { + throw new NoKeyLoadedException('Unable to read key'); + } + + $components['format'] = $format; + $new = static::onLoad($components); + $new->format = $format; + return $new instanceof PrivateKey ? + $new->withPassword($password) : + $new; + } + + /** + * Load the key, assuming a specific format + * + * @param string $type + * @param string $key + * @param string $password optional + * @return AsymmetricKey + */ + public static function loadFormat($type, $key, $password = false) + { + self::initialize_static_variables(); + + $components = false; + $format = strtolower($type); + if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) { + $format = self::$plugins[static::ALGORITHM]['Keys'][$format]; + $components = $format::load($key, $password); + } + + if ($components === false) { + throw new NoKeyLoadedException('Unable to read key'); + } + + $components['format'] = $format; + + $new = static::onLoad($components); + $new->format = $format; + return $new instanceof PrivateKey ? + $new->withPassword($password) : + $new; + } + + /** + * Validate Plugin + * + * @access private + * @param string $format + * @param string $type + * @param string $method optional + * @return mixed + */ + protected static function validatePlugin($format, $type, $method = NULL) + { + $type = strtolower($type); + if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) { + throw new UnsupportedFormatException("$type is not a supported format"); + } + $type = self::$plugins[static::ALGORITHM][$format][$type]; + if (isset($method) && !method_exists($type, $method)) { + throw new UnsupportedFormatException("$type does not implement $method"); + } + + return $type; + } + + /** + * Load Plugins + * + * @access private + * @param string $format + */ + private static function loadPlugins($format) + { + if (!isset(self::$plugins[static::ALGORITHM][$format])) { + self::$plugins[static::ALGORITHM][$format] = []; + foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $name = $file->getBasename('.php'); + $type = 'phpseclib3\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name; + $reflect = new \ReflectionClass($type); + if ($reflect->isTrait()) { + continue; + } + self::$plugins[static::ALGORITHM][$format][strtolower($name)] = $type; + if ($reflect->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM][] = $type; + } + } + } + } + + /** + * Returns a list of supported formats. + * + * @access public + * @return array + */ + public static function getSupportedKeyFormats() + { + self::initialize_static_variables(); + + return self::$plugins[static::ALGORITHM]['Keys']; + } + + /** + * Add a fileformat plugin + * + * The plugin needs to either already be loaded or be auto-loadable. + * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin. + * + * @see self::load() + * @param string $fullname + * @access public + * @return bool + */ + public static function addFileFormat($fullname) + { + self::initialize_static_variables(); + + if (class_exists($fullname)) { + $meta = new \ReflectionClass($fullname); + $shortname = $meta->getShortName(); + self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname; + if ($meta->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM] = strtolower($name); + } + } + } + + /** + * Returns the format of the loaded key. + * + * If the key that was loaded wasn't in a valid or if the key was auto-generated + * with RSA::createKey() then this will throw an exception. + * + * @see self::load() + * @access public + * @return mixed + */ + public function getLoadedFormat() + { + if (empty($this->format)) { + throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); + } + + $meta = new \ReflectionClass($this->format); + return $meta->getShortName(); + } + + /** + * Tests engine validity + * + * @access public + */ + public static function useBestEngine() + { + static::$engines = [ + 'PHP' => true, + 'OpenSSL' => extension_loaded('openssl'), + // this test can be satisfied by either of the following: + // http://php.net/manual/en/book.sodium.php + // https://github.com/paragonie/sodium_compat + 'libsodium' => function_exists('sodium_crypto_sign_keypair') + ]; + + return static::$engines; + } + + /** + * Flag to use internal engine only (useful for unit testing) + * + * @access public + */ + public static function useInternalEngine() + { + static::$engines = [ + 'PHP' => true, + 'OpenSSL' => false, + 'libsodium' => false + ]; + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + return $this->toString('PKCS8'); + } + + /** + * Determines which hashing function should be used + * + * @access public + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + $new->hash = new Hash($hash); + $new->hmac = new Hash($hash); + + return $new; + } + + /** + * Returns the hash algorithm currently being used + * + * @access public + */ + public function getHash() + { + return clone $this->hash; + } + + /** + * Compute the pseudorandom k for signature generation, + * using the process specified for deterministic DSA. + * + * @access public + * @param string $h1 + * @return string + */ + protected function computek($h1) + { + $v = str_repeat("\1", strlen($h1)); + + $k = str_repeat("\0", strlen($h1)); + + $x = $this->int2octets($this->x); + $h1 = $this->bits2octets($h1); + + $this->hmac->setKey($k); + $k = $this->hmac->hash($v . "\0" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + $k = $this->hmac->hash($v . "\1" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + + $qlen = $this->q->getLengthInBytes(); + + while (true) { + $t = ''; + while (strlen($t) < $qlen) { + $v = $this->hmac->hash($v); + $t = $t . $v; + } + $k = $this->bits2int($t); + + if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) { + break; + } + $k = $this->hmac->hash($v . "\0"); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + } + + return $k; + } + + /** + * Integer to Octet String + * + * @access private + * @param \phpseclib3\Math\BigInteger $v + * @return string + */ + private function int2octets($v) + { + $out = $v->toBytes(); + $rolen = $this->q->getLengthInBytes(); + if (strlen($out) < $rolen) { + return str_pad($out, $rolen, "\0", STR_PAD_LEFT); + } else if (strlen($out) > $rolen) { + return substr($out, -$rolen); + } else { + return $out; + } + } + + /** + * Bit String to Integer + * + * @access private + * @param string $in + * @return \phpseclib3\Math\BigInteger + */ + protected function bits2int($in) + { + $v = new BigInteger($in, 256); + $vlen = strlen($in) << 3; + $qlen = $this->q->getLength(); + if ($vlen > $qlen) { + return $v->bitwise_rightShift($vlen - $qlen); + } + return $v; + } + + /** + * Bit String to Octet String + * + * @access private + * @param string $in + * @return string + */ + private function bits2octets($in) + { + $z1 = $this->bits2int($in); + $z2 = $z1->subtract($this->q); + return $z2->compare(self::$zero) < 0 ? + $this->int2octets($z1) : + $this->int2octets($z2); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php new file mode 100644 index 000000000..a8ed74d86 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php @@ -0,0 +1,27 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * Base Class for all block cipher classes + * + * @package BlockCipher + * @author Jim Wigginton + */ +abstract class BlockCipher extends SymmetricKey +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..7c51dd391 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php @@ -0,0 +1,234 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Random; +use phpseclib3\Exception\UnsupportedFormatException; + +/** + * OpenSSH Formatted RSA Key Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class OpenSSH +{ + /** + * Default comment + * + * @var string + * @access private + */ + protected static $comment = 'phpseclib-generated-key'; + + /** + * Binary key flag + * + * @var bool + * @access private + */ + protected static $binary = false; + + /** + * Sets the default comment + * + * @access public + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = str_replace(["\r", "\n"], '', $comment); + } + + /** + * Break a public or private key down into its constituent components + * + * $type can be either ssh-dss or ssh-rsa + * + * @access public + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + // key format is described here: + // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD + + if (strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== false) { + $key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key); + $key = Base64::decode($key); + $magic = Strings::shift($key, 15); + if ($magic != "openssh-key-v1\0") { + throw new \RuntimeException('Expected openssh-key-v1'); + } + list($ciphername, $kdfname, $kdfoptions, $numKeys) = Strings::unpackSSH2('sssN', $key); + if ($numKeys != 1) { + // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys + // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass + // that to the appropriate key loading parser $numKey times or something + throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); + } + if (strlen($kdfoptions) || $kdfname != 'none' || $ciphername != 'none') { + /* + OpenSSH private keys use a customized version of bcrypt. specifically, instead of encrypting + OrpheanBeholderScryDoubt 64 times OpenSSH's bcrypt variant encrypts + OxychromaticBlowfishSwatDynamite 64 times. so we can't use crypt(). + + bcrypt is basically Blowfish with an altered key expansion. whereas Blowfish just runs the + key through the key expansion bcrypt interleaves the key expansion with the salt and + password. this renders openssl / mcrypt unusuable. this forces us to use a pure-PHP implementation + of bcrypt. the problem with that is that pure-PHP is too slow to be practically useful. + + in addition to encrypting a different string 64 times the OpenSSH implementation also performs bcrypt + from scratch $rounds times. calling crypt() 64x with bcrypt takes 0.7s. PHP is going to be naturally + slower. pure-PHP is 215x slower than OpenSSL for AES and pure-PHP is 43x slower for bcrypt. + 43 * 0.7 = 30s. no one wants to wait 30s to load a private key. + + another way to think about this.. according to wikipedia's article on Blowfish, + "Each new key requires pre-processing equivalent to encrypting about 4 kilobytes of text". + key expansion is done (9+64*2)*160 times. multiply that by 4 and it turns out that Blowfish, + OpenSSH style, is the equivalent of encrypting ~80mb of text. + + more supporting evidence: sodium_compat does not implement Argon2 (another password hashing + algorithm) because "It's not feasible to polyfill scrypt or Argon2 into PHP and get reasonable + performance. Users would feel motivated to select parameters that downgrade security to avoid + denial of service (DoS) attacks. The only winning move is not to play" + -- https://github.com/paragonie/sodium_compat/blob/master/README.md + */ + throw new \RuntimeException('Encrypted OpenSSH private keys are not supported'); + //list($salt, $rounds) = Strings::unpackSSH2('sN', $kdfoptions); + } + + list($publicKey, $paddedKey) = Strings::unpackSSH2('ss', $key); + list($type) = Strings::unpackSSH2('s', $publicKey); + list($checkint1, $checkint2) = Strings::unpackSSH2('NN', $paddedKey); + // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. + if ($checkint1 != $checkint2) { + throw new \RuntimeException('The two checkints do not match'); + } + self::checkType($type); + + return compact('type', 'publicKey', 'paddedKey'); + } + + $parts = explode(' ', $key, 3); + + if (!isset($parts[1])) { + $key = base64_decode($parts[0]); + $comment = isset($parts[1]) ? $parts[1] : false; + } else { + $asciiType = $parts[0]; + self::checkType($parts[0]); + $key = base64_decode($parts[1]); + $comment = isset($parts[2]) ? $parts[2] : false; + } + if ($key === false) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + list($type) = Strings::unpackSSH2('s', $key); + self::checkType($type); + if (isset($asciiType) && $asciiType != $type) { + throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); + } + if (strlen($key) <= 4) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $publicKey = $key; + + return compact('type', 'publicKey', 'comment'); + } + + /** + * Toggle between binary and printable keys + * + * Printable keys are what are generated by default. These are the ones that go in + * $HOME/.ssh/authorized_key. + * + * @access public + * @param bool $enabled + */ + public static function setBinaryOutput($enabled) + { + self::$binary = $enabled; + } + + /** + * Checks to see if the type is valid + * + * @access private + * @param string $candidate + */ + private static function checkType($candidate) + { + if (!in_array($candidate, static::$types)) { + throw new \RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types)); + } + } + + /** + * Wrap a private key appropriately + * + * @access public + * @param string $publicKey + * @param string $privateKey + * @param string $password + * @param array $options + * @return string + */ + protected static function wrapPrivateKey($publicKey, $privateKey, $password, $options) + { + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('Encrypted OpenSSH private keys are not supported'); + } + + list(, $checkint) = unpack('N', Random::string(4)); + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $paddedKey = Strings::packSSH2('NN', $checkint, $checkint) . + $privateKey . + Strings::packSSH2('s', $comment); + + /* + from http://tools.ietf.org/html/rfc4253#section-6 : + + Note that the length of the concatenation of 'packet_length', + 'padding_length', 'payload', and 'random padding' MUST be a multiple + of the cipher block size or 8, whichever is larger. + */ + $paddingLength = (7 * strlen($paddedKey)) % 8; + for ($i = 1; $i <= $paddingLength; $i++) { + $paddedKey.= chr($i); + } + $key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey); + $key = "openssh-key-v1\0$key"; + + return "-----BEGIN OPENSSH PRIVATE KEY-----\r\n" . + chunk_split(Base64::encode($key), 70) . + "-----END OPENSSH PRIVATE KEY-----"; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php new file mode 100644 index 000000000..3550cc531 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php @@ -0,0 +1,80 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +/** + * PKCS1 Formatted Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class PKCS +{ + /** + * Auto-detect the format + */ + const MODE_ANY = 0; + /** + * Require base64-encoded PEM's be supplied + */ + const MODE_PEM = 1; + /** + * Require raw DER's be supplied + */ + const MODE_DER = 2; + /**#@-*/ + + /** + * Is the key a base-64 encoded PEM, DER or should it be auto-detected? + * + * @access private + * @var int + */ + protected static $format = self::MODE_ANY; + + /** + * Require base64-encoded PEM's be supplied + * + * @access public + */ + public static function requirePEM() + { + self::$format = self::MODE_PEM; + } + + /** + * Require raw DER's be supplied + * + * @access public + */ + public static function requireDER() + { + self::$format = self::MODE_DER; + } + + /** + * Accept any format and auto detect the format + * + * This is the default setting + * + * @access public + */ + public static function requireAny() + { + self::$format = self::MODE_ANY; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..a362d938b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php @@ -0,0 +1,223 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\DES; +use phpseclib3\Crypt\TripleDES; +use phpseclib3\File\ASN1; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedAlgorithmException; + +/** + * PKCS1 Formatted Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class PKCS1 extends PKCS +{ + /** + * Default encryption algorithm + * + * @var string + * @access private + */ + private static $defaultEncryptionAlgorithm = 'AES-128-CBC'; + + /** + * Sets the default encryption algorithm + * + * @access public + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + + /** + * Returns the mode constant corresponding to the mode string + * + * @access public + * @param string $mode + * @return int + * @throws \UnexpectedValueException if the block cipher mode is unsupported + */ + private static function getEncryptionMode($mode) + { + switch ($mode) { + case 'CBC': + case 'ECB': + case 'CFB': + case 'OFB': + case 'CTR': + return $mode; + } + throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); + } + + /** + * Returns a cipher object corresponding to a string + * + * @access public + * @param string $algo + * @return string + * @throws \UnexpectedValueException if the encryption algorithm is unsupported + */ + private static function getEncryptionObject($algo) + { + $modes = '(CBC|ECB|CFB|OFB|CTR)'; + switch (true) { + case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches): + $cipher = new AES(self::getEncryptionMode($matches[2])); + $cipher->setKeyLength($matches[1]); + return $cipher; + case preg_match("#^DES-EDE3-$modes$#", $algo, $matches): + return new TripleDES(self::getEncryptionMode($matches[1])); + case preg_match("#^DES-$modes$#", $algo, $matches): + return new DES(self::getEncryptionMode($matches[1])); + default: + throw new UnsupportedAlgorithmException($algo . ' is not a supported algorithm'); + } + } + + /** + * Generate a symmetric key for PKCS#1 keys + * + * @access private + * @param string $password + * @param string $iv + * @param int $length + * @return string + */ + private static function generateSymmetricKey($password, $iv, $length) + { + $symkey = ''; + $iv = substr($iv, 0, 8); + while (strlen($symkey) < $length) { + $symkey.= md5($symkey . $password . $iv, true); + } + return substr($symkey, 0, $length); + } + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is + "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to + protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding + two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: + + http://tools.ietf.org/html/rfc1421#section-4.6.1.1 + http://tools.ietf.org/html/rfc1421#section-4.6.1.3 + + DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. + DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation + function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's + own implementation. ie. the implementation *is* the standard and any bugs that may exist in that + implementation are part of the standard, as well. + + * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ + if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { + $iv = Hex::decode(trim($matches[2])); + // remove the Proc-Type / DEK-Info sections as they're no longer needed + $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); + $ciphertext = ASN1::extractBER($key); + if ($ciphertext === false) { + $ciphertext = $key; + } + $crypto = self::getEncryptionObject($matches[1]); + $crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3)); + $crypto->setIV($iv); + $key = $crypto->decrypt($ciphertext); + } else { + if (self::$format != self::MODE_DER) { + $decoded = ASN1::extractBER($key); + if ($decoded !== false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + } + + return $key; + } + + /** + * Wrap a private key appropriately + * + * @access public + * @param string $key + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $type, $password, array $options = []) + { + if (empty($password) || !is_string($password)) { + return "-----BEGIN $type PRIVATE KEY-----\r\n" . + chunk_split(Base64::encode($key), 64) . + "-----END $type PRIVATE KEY-----"; + } + + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + + $cipher = self::getEncryptionObject($encryptionAlgorithm); + $iv = Random::string($cipher->getBlockLength() >> 3); + $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); + $cipher->setIV($iv); + $iv = strtoupper(Hex::encode($iv)); + return "-----BEGIN $type PRIVATE KEY-----\r\n" . + "Proc-Type: 4,ENCRYPTED\r\n" . + "DEK-Info: " . $encryptionAlgorithm. ",$iv\r\n" . + "\r\n" . + chunk_split(Base64::encode($cipher->encrypt($key)), 64) . + "-----END $type PRIVATE KEY-----"; + } + + /** + * Wrap a public key appropriately + * + * @access public + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + return "-----BEGIN $type PUBLIC KEY-----\r\n" . + chunk_split(Base64::encode($key), 64) . + "-----END $type PUBLIC KEY-----"; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..cb6d83ced --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php @@ -0,0 +1,702 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Crypt\DES; +use phpseclib3\Crypt\RC2; +use phpseclib3\Crypt\RC4; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\TripleDES; +use phpseclib3\Crypt\Random; +use phpseclib3\Math\BigInteger; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedAlgorithmException; + +/** + * PKCS#8 Formatted Key Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class PKCS8 extends PKCS +{ + /** + * Default encryption algorithm + * + * @var string + * @access private + */ + private static $defaultEncryptionAlgorithm = 'id-PBES2'; + + /** + * Default encryption scheme + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + * @access private + */ + private static $defaultEncryptionScheme = 'aes128-CBC-PAD'; + + /** + * Default PRF + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + * @access private + */ + private static $defaultPRF = 'id-hmacWithSHA256'; + + /** + * Default Iteration Count + * + * @var int + * @access private + */ + private static $defaultIterationCount = 2048; + + /** + * OIDs loaded + * + * @var bool + * @access private + */ + private static $oidsLoaded = false; + + /** + * Sets the default encryption algorithm + * + * @access public + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + + /** + * Sets the default encryption algorithm for PBES2 + * + * @access public + * @param string $algo + */ + public static function setEncryptionScheme($algo) + { + self::$defaultEncryptionScheme = $algo; + } + + /** + * Sets the iteration count + * + * @access public + * @param int $count + */ + public static function setIterationCount($count) + { + self::$defaultIterationCount = $count; + } + + /** + * Sets the PRF for PBES2 + * + * @access public + * @param string $algo + */ + public static function setPRF($algo) + { + self::$defaultPRF = $algo; + } + + /** + * Returns a SymmetricKey object based on a PBES1 $algo + * + * @return \phpseclib3\Crypt\Common\SymmetricKey + * @access public + * @param string $algo + */ + private static function getPBES1EncryptionObject($algo) + { + $algo = preg_match('#^pbeWith(?:MD2|MD5|SHA1|SHA)And(.*?)-CBC$#', $algo, $matches) ? + $matches[1] : + substr($algo, 13); // strlen('pbeWithSHAAnd') == 13 + + switch ($algo) { + case 'DES': + $cipher = new DES('cbc'); + break; + case 'RC2': + $cipher = new RC2('cbc'); + break; + case '3-KeyTripleDES': + $cipher = new TripleDES('cbc'); + break; + case '2-KeyTripleDES': + $cipher = new TripleDES('cbc'); + $cipher->setKeyLength(128); + break; + case '128BitRC2': + $cipher = new RC2('cbc'); + $cipher->setKeyLength(128); + break; + case '40BitRC2': + $cipher = new RC2('cbc'); + $cipher->setKeyLength(40); + break; + case '128BitRC4': + $cipher = new RC4(); + $cipher->setKeyLength(128); + break; + case '40BitRC4': + $cipher = new RC4(); + $cipher->setKeyLength(40); + break; + default: + throw new UnsupportedAlgorithmException("$algo is not a supported algorithm"); + } + + return $cipher; + } + + /** + * Returns a hash based on a PBES1 $algo + * + * @return string + * @access public + * @param string $algo + */ + private static function getPBES1Hash($algo) + { + if (preg_match('#^pbeWith(MD2|MD5|SHA1|SHA)And.*?-CBC$#', $algo, $matches)) { + return $matches[1] == 'SHA' ? 'sha1' : $matches[1]; + } + + return 'sha1'; + } + + /** + * Returns a KDF baesd on a PBES1 $algo + * + * @return string + * @access public + * @param string $algo + */ + private static function getPBES1KDF($algo) + { + switch ($algo) { + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + return 'pbkdf1'; + } + + return 'pkcs12'; + } + + /** + * Returns a SymmetricKey object baesd on a PBES2 $algo + * + * @return SymmetricKey + * @access public + * @param string $algo + */ + private static function getPBES2EncryptionObject($algo) + { + switch ($algo) { + case 'desCBC': + $cipher = new TripleDES('cbc'); + break; + case 'des-EDE3-CBC': + $cipher = new TripleDES('cbc'); + break; + case 'rc2CBC': + $cipher = new RC2('cbc'); + // in theory this can be changed + $cipher->setKeyLength(128); + break; + case 'rc5-CBC-PAD': + throw new UnsupportedAlgorithmException('rc5-CBC-PAD is not supported for PBES2 PKCS#8 keys'); + case 'aes128-CBC-PAD': + case 'aes192-CBC-PAD': + case 'aes256-CBC-PAD': + $cipher = new AES('cbc'); + $cipher->setKeyLength(substr($algo, 3, 3)); + break; + default: + throw new UnsupportedAlgorithmException("$algo is not supported"); + } + + return $cipher; + } + + /** + * Initialize static variables + * + * @access private + */ + private static function initialize_static_variables() + { + if (!static::$childOIDsLoaded) { + ASN1::loadOIDs(is_array(static::OID_NAME) ? + array_combine(static::OID_NAME, static::OID_VALUE) : + [static::OID_NAME => static::OID_VALUE] + ); + static::$childOIDsLoaded = true; + } + if (!self::$oidsLoaded) { + // from https://tools.ietf.org/html/rfc2898 + ASN1::loadOIDs([ + // PBES1 encryption schemes + 'pbeWithMD2AndDES-CBC' => '1.2.840.113549.1.5.1', + 'pbeWithMD2AndRC2-CBC' => '1.2.840.113549.1.5.4', + 'pbeWithMD5AndDES-CBC' => '1.2.840.113549.1.5.3', + 'pbeWithMD5AndRC2-CBC' => '1.2.840.113549.1.5.6', + 'pbeWithSHA1AndDES-CBC'=> '1.2.840.113549.1.5.10', + 'pbeWithSHA1AndRC2-CBC'=> '1.2.840.113549.1.5.11', + + // from PKCS#12: + // https://tools.ietf.org/html/rfc7292 + 'pbeWithSHAAnd128BitRC4' => '1.2.840.113549.1.12.1.1', + 'pbeWithSHAAnd40BitRC4' => '1.2.840.113549.1.12.1.2', + 'pbeWithSHAAnd3-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.3', + 'pbeWithSHAAnd2-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.4', + 'pbeWithSHAAnd128BitRC2-CBC' => '1.2.840.113549.1.12.1.5', + 'pbeWithSHAAnd40BitRC2-CBC' => '1.2.840.113549.1.12.1.6', + + 'id-PBKDF2' => '1.2.840.113549.1.5.12', + 'id-PBES2' => '1.2.840.113549.1.5.13', + 'id-PBMAC1' => '1.2.840.113549.1.5.14', + + // from PKCS#5 v2.1: + // http://www.rsa.com/rsalabs/pkcs/files/h11302-wp-pkcs5v2-1-password-based-cryptography-standard.pdf + 'id-hmacWithSHA1' => '1.2.840.113549.2.7', + 'id-hmacWithSHA224' => '1.2.840.113549.2.8', + 'id-hmacWithSHA256' => '1.2.840.113549.2.9', + 'id-hmacWithSHA384'=> '1.2.840.113549.2.10', + 'id-hmacWithSHA512'=> '1.2.840.113549.2.11', + 'id-hmacWithSHA512-224'=> '1.2.840.113549.2.12', + 'id-hmacWithSHA512-256'=> '1.2.840.113549.2.13', + + 'desCBC' => '1.3.14.3.2.7', + 'des-EDE3-CBC' => '1.2.840.113549.3.7', + 'rc2CBC' => '1.2.840.113549.3.2', + 'rc5-CBC-PAD' => '1.2.840.113549.3.9', + + 'aes128-CBC-PAD' => '2.16.840.1.101.3.4.1.2', + 'aes192-CBC-PAD'=> '2.16.840.1.101.3.4.1.22', + 'aes256-CBC-PAD'=> '2.16.840.1.101.3.4.1.42' + ]); + self::$oidsLoaded = true; + } + } + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password = '') + { + $decoded = self::preParse($key); + + $meta = []; + + $decrypted = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP); + if (strlen($password) && is_array($decrypted)) { + $algorithm = $decrypted['encryptionAlgorithm']['algorithm']; + switch ($algorithm) { + // PBES1 + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + case 'pbeWithSHAAnd3-KeyTripleDES-CBC': + case 'pbeWithSHAAnd2-KeyTripleDES-CBC': + case 'pbeWithSHAAnd128BitRC2-CBC': + case 'pbeWithSHAAnd40BitRC2-CBC': + case 'pbeWithSHAAnd128BitRC4': + case 'pbeWithSHAAnd40BitRC4': + $cipher = self::getPBES1EncryptionObject($algorithm); + $hash = self::getPBES1Hash($algorithm); + $kdf = self::getPBES1KDF($algorithm); + + $meta['meta']['algorithm'] = $algorithm; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP)); + $iterationCount = (int) $iterationCount->toString(); + $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER 2'); + } + + break; + case 'id-PBES2': + $meta['meta']['algorithm'] = $algorithm; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); + extract($temp); + + $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); + $meta['meta']['cipher'] = $encryptionScheme['algorithm']; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); + extract($temp); + + if (!$cipher instanceof RC2) { + $cipher->setIV($encryptionScheme['parameters']['octetString']); + } else { + $temp = ASN1::decodeBER($encryptionScheme['parameters']); + extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP)); + $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); + switch ($effectiveKeyLength) { + case 160: + $effectiveKeyLength = 40; + break; + case 120: + $effectiveKeyLength = 64; + break; + case 58: + $effectiveKeyLength = 128; + break; + //default: // should be >= 256 + } + $cipher->setIV($iv); + $cipher->setKeyLength($effectiveKeyLength); + } + + $meta['meta']['keyDerivationFunc'] = $keyDerivationFunc['algorithm']; + switch ($keyDerivationFunc['algorithm']) { + case 'id-PBKDF2': + $temp = ASN1::decodeBER($keyDerivationFunc['parameters']); + $prf = ['algorithm' => 'id-hmacWithSHA1']; + $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); + extract($params); + $meta['meta']['prf'] = $prf['algorithm']; + $hash = str_replace('-', '/', substr($prf['algorithm'], 11)); + $params = [ + $password, + 'pbkdf2', + $hash, + $salt, + (int) $iterationCount->toString() + ]; + if (isset($keyLength)) { + $params[] = (int) $keyLength->toString(); + } + $cipher->setPassword(...$params); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER 3'); + } + break; + default: + throw new UnsupportedAlgorithmException('Only PBKDF2 is supported for PBES2 PKCS#8 keys'); + } + break; + case 'id-PBMAC1': + //$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + //$value = ASN1::asn1map($temp[0], Maps\PBMAC1params::MAP); + // since i can't find any implementation that does PBMAC1 it is unsupported + throw new UnsupportedAlgorithmException('Only PBES1 and PBES2 PKCS#8 keys are supported.'); + // at this point we'll assume that the key conforms to PublicKeyInfo + } + } + + $private = ASN1::asn1map($decoded[0], Maps\OneAsymmetricKey::MAP); + if (is_array($private)) { + if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) { + $temp = $decoded[0]['content'][1]['content'][1]; + $private['privateKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); + } + if (is_array(static::OID_NAME)) { + if (!in_array($private['privateKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new UnsupportedAlgorithmException($private['privateKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($private['privateKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $private['privateKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($private['publicKey'])) { + if ($private['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0])); + } + $private['publicKey'] = substr($private['publicKey'], 1); + } + return $private + $meta; + } + + // EncryptedPrivateKeyInfo and PublicKeyInfo have largely identical "signatures". the only difference + // is that the former has an octet string and the later has a bit string. the first byte of a bit + // string represents the number of bits in the last byte that are to be ignored but, currently, + // bit strings wanting a non-zero amount of bits trimmed are not supported + $public = ASN1::asn1map($decoded[0], Maps\PublicKeyInfo::MAP); + + if (is_array($public)) { + if ($public['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0])); + } + if (is_array(static::OID_NAME)) { + if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new UnsupportedAlgorithmException($public['publicKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($public['publicKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $public['publicKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($public['publicKeyAlgorithm']['parameters']) && !$public['publicKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][0]['content'][1])) { + $temp = $decoded[0]['content'][0]['content'][1]; + $public['publicKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); + } + $public['publicKey'] = substr($public['publicKey'], 1); + return $public; + } + + throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); + } + + /** + * Wrap a private key appropriately + * + * @access public + * @param string $key + * @param string $attr + * @param mixed $params + * @param string $password + * @param string $oid optional + * @param string $publicKey optional + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $attr, $params, $password, $oid = null, $publicKey = '', array $options = []) + { + self::initialize_static_variables(); + + $key = [ + 'version' => 'v1', + 'privateKeyAlgorithm' => [ + 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid, + 'parameters' => $params + ], + 'privateKey' => $key + ]; + if (!empty($attr)) { + $key['attributes'] = $attr; + } + if (!empty($publicKey)) { + $key['version'] = 'v2'; + $key['publicKey'] = $publicKey; + } + $key = ASN1::encodeDER($key, Maps\OneAsymmetricKey::MAP); + if (!empty($password) && is_string($password)) { + $salt = Random::string(8); + + $iterationCount = isset($options['iterationCount']) ? $options['iterationCount'] : self::$defaultIterationCount; + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + $encryptionScheme = isset($options['encryptionScheme']) ? $options['encryptionScheme'] : self::$defaultEncryptionScheme; + $prf = isset($options['PRF']) ? $options['PRF'] : self::$defaultPRF; + + if ($encryptionAlgorithm == 'id-PBES2') { + $crypto = self::getPBES2EncryptionObject($encryptionScheme); + $hash = str_replace('-', '/', substr($prf, 11)); + $kdf = 'pbkdf2'; + $iv = Random::string($crypto->getBlockLength() >> 3); + + $PBKDF2params = [ + 'salt' => $salt, + 'iterationCount' => $iterationCount, + 'prf' => ['algorithm' => $prf, 'parameters' => null] + ]; + $PBKDF2params = ASN1::encodeDER($PBKDF2params, Maps\PBKDF2params::MAP); + + if (!$crypto instanceof RC2) { + $params = ['octetString' => $iv]; + } else { + $params = [ + 'rc2ParametersVersion' => 58, + 'iv' => $iv + ]; + $params = ASN1::encodeDER($params, Maps\RC2CBCParameter::MAP); + $params = new ASN1\Element($params); + } + + $params = [ + 'keyDerivationFunc' => [ + 'algorithm' => 'id-PBKDF2', + 'parameters' => new ASN1\Element($PBKDF2params) + ], + 'encryptionScheme' => [ + 'algorithm' => $encryptionScheme, + 'parameters' => $params + ] + ]; + $params = ASN1::encodeDER($params, Maps\PBES2params::MAP); + + $crypto->setIV($iv); + } else { + $crypto = self::getPBES1EncryptionObject($encryptionAlgorithm); + $hash = self::getPBES1Hash($encryptionAlgorithm); + $kdf = self::getPBES1KDF($encryptionAlgorithm); + + $params = [ + 'salt' => $salt, + 'iterationCount' => $iterationCount + ]; + $params = ASN1::encodeDER($params, Maps\PBEParameter::MAP); + } + $crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $crypto->encrypt($key); + + $key = [ + 'encryptionAlgorithm' => [ + 'algorithm' => $encryptionAlgorithm, + 'parameters' => new ASN1\Element($params) + ], + 'encryptedData' => $key + ]; + + $key = ASN1::encodeDER($key, Maps\EncryptedPrivateKeyInfo::MAP); + + return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . + chunk_split(Base64::encode($key), 64) . + "-----END ENCRYPTED PRIVATE KEY-----"; + } + + return "-----BEGIN PRIVATE KEY-----\r\n" . + chunk_split(Base64::encode($key), 64) . + "-----END PRIVATE KEY-----"; + } + + /** + * Wrap a public key appropriately + * + * @access public + * @param string $key + * @param mixed $params + * @param string $oid + * @return string + */ + protected static function wrapPublicKey($key, $params, $oid = null) + { + self::initialize_static_variables(); + + $key = [ + 'publicKeyAlgorithm' => [ + 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid, + 'parameters' => $params + ], + 'publicKey' => "\0" . $key + ]; + + $key = ASN1::encodeDER($key, Maps\PublicKeyInfo::MAP); + + return "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(Base64::encode($key), 64) . + "-----END PUBLIC KEY-----"; + } + + /** + * Perform some preliminary parsing of the key + * + * @param string $key + * @return array + */ + private static function preParse(&$key) + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (self::$format != self::MODE_DER) { + $decoded = ASN1::extractBER($key); + if ($decoded !== false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + return $decoded; + } + + /** + * Returns the encryption parameters used by the key + * + * @param string $key + * @return array + */ + public static function extractEncryptionAlgorithm($key) + { + $decoded = self::preParse($key); + + $r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP); + if (!is_array($r)) { + throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); + } + + if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { + $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); + $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP); + + $kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; + switch ($kdf['algorithm']) { + case 'id-PBKDF2': + $decoded = ASN1::decodeBER($kdf['parameters']->element); + $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); + } + } + + return $r['encryptionAlgorithm']; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..ccd06f75e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php @@ -0,0 +1,261 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedAlgorithmException; + +/** + * PuTTY Formatted Key Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class PuTTY +{ + /** + * Default comment + * + * @var string + * @access private + */ + private static $comment = 'phpseclib-generated-key'; + + /** + * Sets the default comment + * + * @access public + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = str_replace(["\r", "\n"], '', $comment); + } + + /** + * Generate a symmetric key for PuTTY keys + * + * @access public + * @param string $password + * @param int $length + * @return string + */ + private static function generateSymmetricKey($password, $length) + { + $symkey = ''; + $sequence = 0; + while (strlen($symkey) < $length) { + $temp = pack('Na*', $sequence++, $password); + $symkey.= Hex::decode(sha1($temp)); + } + return substr($symkey, 0, $length); + } + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== false) { + $lines = preg_split('#[\r\n]+#', $key); + switch (true) { + case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); + case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); + } + $lines = array_splice($lines, 1, -1); + $lines = array_map(function ($line) { + return rtrim($line, "\r\n"); + }, $lines); + $data = $current = ''; + $values = []; + $in_value = false; + foreach ($lines as $line) { + switch (true) { + case preg_match('#^(.*?): (.*)#', $line, $match): + $in_value = $line[strlen($line) - 1] == '\\'; + $current = strtolower($match[1]); + $values[$current] = $in_value ? substr($match[2], 0, -1) : $match[2]; + break; + case $in_value: + $in_value = $line[strlen($line) - 1] == '\\'; + $values[$current].= $in_value ? substr($line, 0, -1) : $line; + break; + default: + $data.= $line; + } + } + + $components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data); + if ($components === false) { + throw new \UnexpectedValueException('Unable to decode public key'); + } + $components+= $values; + $components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']); + + return $components; + } + + $components = []; + + $key = preg_split('#\r\n|\r|\n#', trim($key)); + $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0])); + $components['type'] = $type; + if (!in_array($type, static::$types)) { + $error = count(static::$types) == 1 ? + 'Only ' . static::$types[0] . ' keys are supported. ' : + ''; + throw new UnsupportedAlgorithmException($error . 'This is an unsupported ' . $type . ' key'); + } + $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); + $components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); + + $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); + $public = Base64::decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); + + $source = Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); + + extract(unpack('Nlength', Strings::shift($public, 4))); + $newtype = Strings::shift($public, $length); + if ($newtype != $type) { + throw new \RuntimeException('The binary type does not match the human readable type field'); + } + + $components['public'] = $public; + + $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4])); + $private = Base64::decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength)))); + + switch ($encryption) { + case 'aes256-cbc': + $symkey = self::generateSymmetricKey($password, 32); + $crypto = new AES('cbc'); + } + + $hashkey = 'putty-private-key-file-mac-key'; + + if ($encryption != 'none') { + $hashkey.= $password; + $crypto->setKey($symkey); + $crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3)); + $crypto->disablePadding(); + $private = $crypto->decrypt($private); + } + + $source.= Strings::packSSH2('s', $private); + + $hash = new Hash('sha1'); + $hash->setKey(sha1($hashkey, true)); + $hmac = trim(preg_replace('#Private-MAC: (.+)#', '$1', $key[$publicLength + $privateLength + 5])); + $hmac = Hex::decode($hmac); + + if (!hash_equals($hash->hash($source), $hmac)) { + throw new \UnexpectedValueException('MAC validation error'); + } + + $components['private'] = $private; + + return $components; + } + + /** + * Wrap a private key appropriately + * + * @access private + * @param string $public + * @param string $private + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) + { + $encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none'; + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + + $key = "PuTTY-User-Key-File-2: " . $type . "\r\nEncryption: "; $key.= $encryption; + $key.= "\r\nComment: " . $comment . "\r\n"; + + $public = Strings::packSSH2('s', $type) . $public; + + $source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public); + + $public = Base64::encode($public); + $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; + $key.= chunk_split($public, 64); + + if (empty($password) && !is_string($password)) { + $source.= Strings::packSSH2('s', $private); + $hashkey = 'putty-private-key-file-mac-key'; + } else { + $private.= Random::string(16 - (strlen($private) & 15)); + $source.= Strings::packSSH2('s', $private); + $crypto = new AES('cbc'); + + $crypto->setKey(self::generateSymmetricKey($password, 32)); + $crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3)); + $crypto->disablePadding(); + $private = $crypto->encrypt($private); + $hashkey = 'putty-private-key-file-mac-key' . $password; + } + + $private = Base64::encode($private); + $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; + $key.= chunk_split($private, 64); + $hash = new Hash('sha1'); + $hash->setKey(sha1($hashkey, true)); + $key.= 'Private-MAC: ' . Hex::encode($hash->hash($source)) . "\r\n"; + + return $key; + } + + /** + * Wrap a public key appropriately + * + * This is basically the format described in RFC 4716 (https://tools.ietf.org/html/rfc4716) + * + * @access private + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + $key = pack('Na*a*', strlen($type), $type, $key); + $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . + 'Comment: "' . str_replace(['\\', '"'], ['\\\\', '\"'], self::$comment) . "\"\r\n" . + chunk_split(Base64::encode($key), 64) . + '---- END SSH2 PUBLIC KEY ----'; + return $key; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php new file mode 100644 index 000000000..13e56e3b5 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php @@ -0,0 +1,66 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Signature; + +use phpseclib3\Math\BigInteger; + +/** + * Raw Signature Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class Raw +{ + /** + * Loads a signature + * + * @access public + * @param array $sig + * @return array|bool + */ + public static function load($sig) + { + switch (true) { + case !is_array($sig): + case !isset($sig['r']) || !isset($sig['s']): + case !$sig['r'] instanceof BigInteger: + case !$sig['s'] instanceof BigInteger: + return false; + } + + return [ + 'r' => $sig['r'], + 's' => $sig['s'] + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return compact('r', 's'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php new file mode 100644 index 000000000..007123283 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php @@ -0,0 +1,30 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * PrivateKey interface + * + * @package Common + * @author Jim Wigginton + * @access public + */ +interface PrivateKey +{ + public function sign($message); + //public function decrypt($ciphertext); + public function getPublicKey(); + public function toString($type, array $options = []); + public function withPassword($string); +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php new file mode 100644 index 000000000..0696de18c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php @@ -0,0 +1,29 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * PublicKey interface + * + * @package Common + * @author Jim Wigginton + * @access public + */ +interface PublicKey +{ + public function verify($message, $signature); + //public function encrypt($plaintext); + public function toString($type, array $options = []); + public function getFingerprint($algorithm); +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php new file mode 100644 index 000000000..f4d076d06 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php @@ -0,0 +1,59 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * Base Class for all stream cipher classes + * + * @package StreamCipher + * @author Jim Wigginton + */ +abstract class StreamCipher extends SymmetricKey +{ + /** + * Block Length of the cipher + * + * Stream ciphers do not have a block size + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + * @access private + */ + protected $block_size = 0; + + /** + * Default Constructor. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @return \phpseclib3\Crypt\Common\StreamCipher + */ + public function __construct() + { + parent::__construct('stream'); + } + + /** + * Stream ciphers not use an IV + * + * @access public + * @return bool + */ + public function usesIV() + { + return false; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php new file mode 100644 index 000000000..76019337f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php @@ -0,0 +1,3271 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +use phpseclib3\Crypt\Hash; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\PrimeField; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\BadModeException; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; + +/** + * Base Class for all \phpseclib3\Crypt\* cipher classes + * + * @package Base + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +abstract class SymmetricKey +{ + /** + * Encrypt / decrypt using the Counter mode. + * + * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CTR = -1; + /** + * Encrypt / decrypt using the Electronic Code Book mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_ECB = 1; + /** + * Encrypt / decrypt using the Code Book Chaining mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CBC = 2; + /** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CFB = 3; + /** + * Encrypt / decrypt using the Cipher Feedback mode (8bit) + * + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CFB8 = 38; + /** + * Encrypt / decrypt using the Output Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_OFB = 4; + /** + * Encrypt / decrypt using Galois/Counter mode. + * + * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_GCM = 5; + /** + * Encrypt / decrypt using streaming mode. + * + * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_STREAM = 6; + + /** + * Mode Map + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const MODE_MAP = [ + 'ctr' => self::MODE_CTR, + 'ecb' => self::MODE_ECB, + 'cbc' => self::MODE_CBC, + 'cfb' => self::MODE_CFB, + 'cfb8' => self::MODE_CFB8, + 'ofb' => self::MODE_OFB, + 'gcm' => self::MODE_GCM, + 'stream' => self::MODE_STREAM + ]; + + /** + * Base value for the internal implementation $engine switch + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_INTERNAL = 1; + /** + * Base value for the eval() implementation $engine switch + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_EVAL = 2; + /** + * Base value for the mcrypt implementation $engine switch + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_MCRYPT = 3; + /** + * Base value for the openssl implementation $engine switch + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL = 4; + /** + * Base value for the libsodium implementation $engine switch + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_LIBSODIUM = 5; + /** + * Base value for the openssl / gcm implementation $engine switch + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL_GCM = 6; + + /** + * Engine Reverse Map + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() + */ + const ENGINE_MAP = [ + self::ENGINE_INTERNAL => 'PHP', + self::ENGINE_EVAL => 'Eval', + self::ENGINE_MCRYPT => 'mcrypt', + self::ENGINE_OPENSSL => 'OpenSSL', + self::ENGINE_LIBSODIUM => 'libsodium', + self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)' + ]; + + /** + * The Encryption Mode + * + * @see self::__construct() + * @var int + * @access private + */ + protected $mode; + + /** + * The Block Length of the block cipher + * + * @var int + * @access private + */ + protected $block_size = 16; + + /** + * The Key + * + * @see self::setKey() + * @var string + * @access private + */ + protected $key = false; + + /** + * The Initialization Vector + * + * @see self::setIV() + * @var string + * @access private + */ + private $iv = false; + + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::clearBuffers() + * @var string + * @access private + */ + protected $encryptIV; + + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::clearBuffers() + * @var string + * @access private + */ + protected $decryptIV; + + /** + * Continuous Buffer status + * + * @see self::enableContinuousBuffer() + * @var bool + * @access private + */ + protected $continuousBuffer = false; + + /** + * Encryption buffer for CTR, OFB and CFB modes + * + * @see self::encrypt() + * @see self::clearBuffers() + * @var array + * @access private + */ + protected $enbuffer; + + /** + * Decryption buffer for CTR, OFB and CFB modes + * + * @see self::decrypt() + * @see self::clearBuffers() + * @var array + * @access private + */ + protected $debuffer; + + /** + * mcrypt resource for encryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::encrypt() + * @var resource + * @access private + */ + private $enmcrypt; + + /** + * mcrypt resource for decryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::decrypt() + * @var resource + * @access private + */ + private $demcrypt; + + /** + * Does the enmcrypt resource need to be (re)initialized? + * + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() + * @var bool + * @access private + */ + private $enchanged = true; + + /** + * Does the demcrypt resource need to be (re)initialized? + * + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() + * @var bool + * @access private + */ + private $dechanged = true; + + /** + * mcrypt resource for CFB mode + * + * mcrypt's CFB mode, in (and only in) buffered context, + * is broken, so phpseclib implements the CFB mode by it self, + * even when the mcrypt php extension is available. + * + * In order to do the CFB-mode work (fast) phpseclib + * use a separate ECB-mode mcrypt resource. + * + * @link http://phpseclib.sourceforge.net/cfb-demo.phps + * @see self::encrypt() + * @see self::decrypt() + * @see self::setupMcrypt() + * @var resource + * @access private + */ + private $ecb; + + /** + * Optimizing value while CFB-encrypting + * + * Only relevant if $continuousBuffer enabled + * and $engine == self::ENGINE_MCRYPT + * + * It's faster to re-init $enmcrypt if + * $buffer bytes > $cfb_init_len than + * using the $ecb resource furthermore. + * + * This value depends of the chosen cipher + * and the time it would be needed for it's + * initialization [by mcrypt_generic_init()] + * which, typically, depends on the complexity + * on its internaly Key-expanding algorithm. + * + * @see self::encrypt() + * @var int + * @access private + */ + protected $cfb_init_len = 600; + + /** + * Does internal cipher state need to be (re)initialized? + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + * @var bool + * @access private + */ + protected $changed = true; + + /** + * Does Eval engie need to be (re)initialized? + * + * @see self::setup() + * @var bool + * @access private + */ + protected $nonIVChanged = true; + + /** + * Padding status + * + * @see self::enablePadding() + * @var bool + * @access private + */ + private $padding = true; + + /** + * Is the mode one that is paddable? + * + * @see self::__construct() + * @var bool + * @access private + */ + private $paddable = false; + + /** + * Holds which crypt engine internaly should be use, + * which will be determined automatically on __construct() + * + * Currently available $engines are: + * - self::ENGINE_LIBSODIUM (very fast, php-extension: libsodium, extension_loaded('libsodium') required) + * - self::ENGINE_OPENSSL_GCM (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) + * - self::ENGINE_EVAL (medium, pure php-engine, no php-extension required) + * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) + * + * @see self::setEngine() + * @see self::encrypt() + * @see self::decrypt() + * @var int + * @access private + */ + protected $engine; + + /** + * Holds the preferred crypt engine + * + * @see self::setEngine() + * @see self::setPreferredEngine() + * @var int + * @access private + */ + private $preferredEngine; + + /** + * The mcrypt specific name of the cipher + * + * Only used if $engine == self::ENGINE_MCRYPT + * + * @link http://www.php.net/mcrypt_module_open + * @link http://www.php.net/mcrypt_list_algorithms + * @see self::setupMcrypt() + * @var string + * @access private + */ + protected $cipher_name_mcrypt; + + /** + * The openssl specific name of the cipher + * + * Only used if $engine == self::ENGINE_OPENSSL + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + * @access private + */ + protected $cipher_name_openssl; + + /** + * The openssl specific name of the cipher in ECB mode + * + * If OpenSSL does not support the mode we're trying to use (CTR) + * it can still be emulated with ECB mode. + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + * @access private + */ + protected static $cipher_name_openssl_ecb; + + /** + * The default salt used by setPassword() + * + * @see self::setPassword() + * @var string + * @access private + */ + private $password_default_salt = 'phpseclib/salt'; + + /** + * The name of the performance-optimized callback function + * + * Used by encrypt() / decrypt() + * only if $engine == self::ENGINE_INTERNAL + * + * @see self::encrypt() + * @see self::decrypt() + * @see self::setupInlineCrypt() + * @var Callback + * @access private + */ + protected $inline_crypt; + + /** + * If OpenSSL can be used in ECB but not in CTR we can emulate CTR + * + * @see self::openssl_ctr_process() + * @var bool + * @access private + */ + private $openssl_emulate_ctr = false; + + /** + * Don't truncate / null pad key + * + * @see self::clearBuffers() + * @var bool + * @access private + */ + private $skip_key_adjustment = false; + + /** + * Has the key length explicitly been set or should it be derived from the key, itself? + * + * @see self::setKeyLength() + * @var bool + * @access private + */ + protected $explicit_key_length = false; + + /** + * Hash subkey for GHASH + * + * @see self::setupGCM() + * @see self::ghash() + * @var BinaryField\Integer + * @access private + */ + private $h; + + /** + * Additional authenticated data + * + * @var string + * @access private + */ + protected $aad = ''; + + /** + * Authentication Tag produced after a round of encryption + * + * @var string + * @access private + */ + protected $newtag = false; + + /** + * Authentication Tag to be verified during decryption + * + * @var string + * @access private + */ + protected $oldtag = false; + + /** + * GCM Binary Field + * + * @see self::__construct() + * @see self::ghash() + * @var BinaryField + * @access private + */ + private static $gcmField; + + /** + * Poly1305 Prime Field + * + * @see self::enablePoly1305() + * @see self::poly1305() + * @var PrimeField + * @access private + */ + private static $poly1305Field; + + /** + * Poly1305 Key + * + * @see self::setPoly1305Key() + * @see self::poly1305() + * @var string + * @access private + */ + protected $poly1305Key; + + /** + * Poly1305 Flag + * + * @see self::setPoly1305Key() + * @see self::enablePoly1305() + * @var boolean + * @access private + */ + protected $usePoly1305 = false; + + /** + * The Original Initialization Vector + * + * GCM uses the nonce to build the IV but we want to be able to distinguish between nonce-derived + * IV's and user-set IV's + * + * @see self::setIV() + * @var string + * @access private + */ + private $origIV = false; + + /** + * Nonce + * + * Only used with GCM. We could re-use setIV() but nonce's can be of a different length and + * toggling between GCM and other modes could be more complicated if we re-used setIV() + * + * @see self::setNonce() + * @var string + * @access private + */ + protected $nonce = false; + + /** + * Default Constructor. + * + * $mode could be: + * + * - ecb + * + * - cbc + * + * - ctr + * + * - cfb + * + * - cfb8 + * + * - ofb + * + * - gcm + * + * @param string $mode + * @access public + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + $mode = strtolower($mode); + // necessary because of 5.6 compatibility; we can't do isset(self::MODE_MAP[$mode]) in 5.6 + $map = self::MODE_MAP; + if (!isset($map[$mode])) { + throw new BadModeException('No valid mode has been specified'); + } + + $mode = self::MODE_MAP[$mode]; + + // $mode dependent settings + switch ($mode) { + case self::MODE_ECB: + case self::MODE_CBC: + $this->paddable = true; + break; + case self::MODE_CTR: + case self::MODE_CFB: + case self::MODE_CFB8: + case self::MODE_OFB: + case self::MODE_STREAM: + $this->paddable = false; + break; + case self::MODE_GCM: + if ($this->block_size != 16) { + throw new BadModeException('GCM is only valid for block ciphers with a block size of 128 bits'); + } + if (!isset(self::$gcmField)) { + self::$gcmField = new BinaryField(128, 7, 2, 1, 0); + } + $this->paddable = false; + break; + default: + throw new BadModeException('No valid mode has been specified'); + } + + $this->mode = $mode; + } + + /** + * Sets the initialization vector. + * + * setIV() is not required when ecb or gcm modes are being used. + * + * {@internal Can be overwritten by a sub class, but does not have to be} + * + * @access public + * @param string $iv + * @throws \LengthException if the IV length isn't equal to the block size + * @throws \BadMethodCallException if an IV is provided when one shouldn't be + */ + public function setIV($iv) + { + if ($this->mode == self::MODE_ECB) { + throw new \BadMethodCallException('This mode does not require an IV.'); + } + + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Use setNonce instead'); + } + + if (!$this->usesIV()) { + throw new \BadMethodCallException('This algorithm does not use an IV.'); + } + + if (strlen($iv) != $this->block_size) { + throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required'); + } + + $this->iv = $this->origIV = $iv; + $this->changed = true; + } + + /** + * Enables Poly1305 mode. + * + * Once enabled Poly1305 cannot be disabled. + * + * @access public + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode + */ + public function enablePoly1305() + { + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + + $this->usePoly1305 = true; + } + + /** + * Enables Poly1305 mode. + * + * Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key + * will be made. + * + * @access public + * @param string $key optional + * @throws \LengthException if the key isn't long enough + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode + */ + public function setPoly1305Key($key = null) + { + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + + if (!is_string($key) || strlen($key) != 32) { + throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); + } + + if (!isset(self::$poly1305Field)) { + // 2^130-5 + self::$poly1305Field = new PrimeField(new BigInteger('3fffffffffffffffffffffffffffffffb', 16)); + } + + $this->poly1305Key = $key; + $this->usePoly1305 = true; + } + + /** + * Sets the nonce. + * + * setNonce() is only required when gcm is used + * + * @access public + * @param string $nonce + * @throws \BadMethodCallException if an nonce is provided when one shouldn't be + */ + public function setNonce($nonce) + { + if ($this->mode != self::MODE_GCM) { + throw new \BadMethodCallException('Nonces are only used in GCM mode.'); + } + + $this->nonce = $nonce; + $this->setEngine(); + } + + /** + * Sets additional authenticated data + * + * setAAD() is only used by gcm or in poly1305 mode + * + * @access public + * @param string $aad + * @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized + */ + public function setAAD($aad) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); + } + + $this->aad = $aad; + } + + /** + * Returns whether or not the algorithm uses an IV + * + * @access public + * @return bool + */ + public function usesIV() + { + return $this->mode != self::MODE_GCM && $this->mode != self::MODE_ECB; + } + + /** + * Returns whether or not the algorithm uses a nonce + * + * @access public + * @return bool + */ + public function usesNonce() + { + return $this->mode == self::MODE_GCM; + } + + /** + * Returns the current key length in bits + * + * @access public + * @return int + */ + public function getKeyLength() + { + return $this->key_length << 3; + } + + /** + * Returns the current block length in bits + * + * @access public + * @return int + */ + public function getBlockLength() + { + return $this->block_size << 3; + } + + /** + * Returns the current block length in bytes + * + * @access public + * @return int + */ + public function getBlockLengthInBytes() + { + return $this->block_size; + } + + /** + * Sets the key length. + * + * Keys with explicitly set lengths need to be treated accordingly + * + * @access public + * @param int $length + */ + public function setKeyLength($length) + { + $this->explicit_key_length = $length >> 3; + + if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) { + $this->key = false; + throw new InconsistentSetupException('Key has already been set and is not ' .$this->explicit_key_length . ' bytes long'); + } + } + + /** + * Sets the key. + * + * The min/max length(s) of the key depends on the cipher which is used. + * If the key not fits the length(s) of the cipher it will paded with null bytes + * up to the closest valid key length. If the key is more than max length, + * we trim the excess bits. + * + * If the key is not explicitly set, it'll be assumed to be all null bytes. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @access public + * @param string $key + */ + public function setKey($key) + { + if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { + throw new InconsistentSetupException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); + } + + $this->key = $key; + $this->key_length = strlen($key); + $this->setEngine(); + } + + /** + * Sets the password. + * + * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: + * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: + * $hash, $salt, $count, $dkLen + * + * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see Crypt/Hash.php + * @param string $password + * @param string $method + * @param string[] ...$func_args + * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length + * @return bool + * @access public + */ + public function setPassword($password, $method = 'pbkdf2', ...$func_args) + { + $key = ''; + + $method = strtolower($method); + switch ($method) { + case 'pkcs12': // from https://tools.ietf.org/html/rfc7292#appendix-B.2 + case 'pbkdf1': + case 'pbkdf2': + // Hash function + $hash = isset($func_args[0]) ? strtolower($func_args[0]) : 'sha1'; + $hashObj = new Hash(); + $hashObj->setHash($hash); + + // WPA and WPA2 use the SSID as the salt + $salt = isset($func_args[1]) ? $func_args[1] : $this->password_default_salt; + + // RFC2898#section-4.2 uses 1,000 iterations by default + // WPA and WPA2 use 4,096. + $count = isset($func_args[2]) ? $func_args[2] : 1000; + + // Keylength + if (isset($func_args[3])) { + if ($func_args[3] <= 0) { + throw new \LengthException('Derived key length cannot be longer 0 or less'); + } + $dkLen = $func_args[3]; + } else { + $key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length; + $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length; + } + + switch (true) { + case $method == 'pkcs12': + /* + In this specification, however, all passwords are created from + BMPStrings with a NULL terminator. This means that each character in + the original BMPString is encoded in 2 bytes in big-endian format + (most-significant byte first). There are no Unicode byte order + marks. The 2 bytes produced from the last character in the BMPString + are followed by 2 additional bytes with the value 0x00. + + -- https://tools.ietf.org/html/rfc7292#appendix-B.1 + */ + $password = "\0". chunk_split($password, 1, "\0") . "\0"; + + /* + This standard specifies 3 different values for the ID byte mentioned + above: + + 1. If ID=1, then the pseudorandom bits being produced are to be used + as key material for performing encryption or decryption. + + 2. If ID=2, then the pseudorandom bits being produced are to be used + as an IV (Initial Value) for encryption or decryption. + + 3. If ID=3, then the pseudorandom bits being produced are to be used + as an integrity key for MACing. + */ + // Construct a string, D (the "diversifier"), by concatenating v/8 + // copies of ID. + $blockLength = $hashObj->getBlockLengthInBytes(); + $d1 = str_repeat(chr(1), $blockLength); + $d2 = str_repeat(chr(2), $blockLength); + $s = ''; + if (strlen($salt)) { + while (strlen($s) < $blockLength) { + $s.= $salt; + } + } + $s = substr($s, 0, $blockLength); + + $p = ''; + if (strlen($password)) { + while (strlen($p) < $blockLength) { + $p.= $password; + } + } + $p = substr($p, 0, $blockLength); + + $i = $s . $p; + + $this->setKey(self::pkcs12helper($dkLen, $hashObj, $i, $d1, $count)); + if ($this->usesIV()) { + $this->setIV(self::pkcs12helper($this->block_size, $hashObj, $i, $d2, $count)); + } + + return true; + case $method == 'pbkdf1': + if ($dkLen > $hashObj->getLengthInBytes()) { + throw new \LengthException('Derived key length cannot be longer than the hash length'); + } + $t = $password . $salt; + for ($i = 0; $i < $count; ++$i) { + $t = $hashObj->hash($t); + } + $key = substr($t, 0, $dkLen); + + $this->setKey(substr($key, 0, $dkLen >> 1)); + if ($this->usesIV()) { + $this->setIV(substr($key, $dkLen >> 1)); + } + + return true; + case !in_array($hash, hash_algos()): + $i = 1; + $hashObj->setKey($password); + while (strlen($key) < $dkLen) { + $f = $u = $hashObj->hash($salt . pack('N', $i++)); + for ($j = 2; $j <= $count; ++$j) { + $u = $hashObj->hash($u); + $f^= $u; + } + $key.= $f; + } + $key = substr($key, 0, $dkLen); + break; + default: + $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true); + } + break; + default: + throw new UnsupportedAlgorithmException($method . ' is not a supported password hashing method'); + } + + $this->setKey($key); + + return true; + } + + /** + * PKCS#12 KDF Helper Function + * + * As discussed here: + * + * {@link https://tools.ietf.org/html/rfc7292#appendix-B} + * + * @see self::setPassword() + * @access private + * @param int $n + * @param \phpseclib3\Crypt\Hash $hashObj + * @param string $i + * @param string $d + * @param int $count + * @return string $a + */ + private static function pkcs12helper($n, $hashObj, $i, $d, $count) + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $blockLength = $hashObj->getBlockLength() >> 3; + + $c = ceil($n / $hashObj->getLengthInBytes()); + $a = ''; + for ($j = 1; $j <= $c; $j++) { + $ai = $d . $i; + for ($k = 0; $k < $count; $k++) { + $ai = $hashObj->hash($ai); + } + $b = ''; + while (strlen($b) < $blockLength) { + $b.= $ai; + } + $b = substr($b, 0, $blockLength); + $b = new BigInteger($b, 256); + $newi = ''; + for ($k = 0; $k < strlen($i); $k+= $blockLength) { + $temp = substr($i, $k, $blockLength); + $temp = new BigInteger($temp, 256); + $temp->setPrecision($blockLength << 3); + $temp = $temp->add($b); + $temp = $temp->add($one); + $newi.= $temp->toBytes(false); + } + $i = $newi; + $a.= $ai; + } + + return substr($a, 0, $n); + } + + /** + * Encrypts a message. + * + * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher + * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's + * necessary are discussed in the following + * URL: + * + * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} + * + * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. + * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that + * length. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::decrypt() + * @access public + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + if ($this->paddable) { + $plaintext = $this->pad($plaintext); + } + + $this->setup(); + + if ($this->mode == self::MODE_GCM) { + $oldIV = $this->iv; + Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $ciphertext = $cipher->encrypt($plaintext); + + $s = $this->ghash( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + self::len64($this->aad) . + self::len64($ciphertext) + ); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $this->newtag = $cipher->encrypt($s); + return $ciphertext; + } + + if (isset($this->poly1305Key)) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = false; + $ciphertext = $cipher->encrypt($plaintext); + $this->newtag = $this->poly1305($ciphertext); + return $ciphertext; + } + + if ($this->engine === self::ENGINE_OPENSSL) { + switch ($this->mode) { + case self::MODE_STREAM: + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + case self::MODE_ECB: + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + case self::MODE_CBC: + $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + $this->encryptIV = substr($result, -$this->block_size); + } + return $result; + case self::MODE_CTR: + return $this->openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $ciphertext = ''; + if ($this->continuousBuffer) { + $iv = &$this->encryptIV; + $pos = &$this->enbuffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + $plaintext = substr($plaintext, $i); + } + + $overflow = $len % $this->block_size; + + if ($overflow) { + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = Strings::pop($ciphertext, $this->block_size); + + $size = $len - $overflow; + $block = $iv ^ substr($plaintext, -$overflow); + $iv = substr_replace($iv, $block, 0, $overflow); + $ciphertext.= $block; + $pos = $overflow; + } elseif ($len) { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + + return $ciphertext; + case self::MODE_CFB8: + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->encryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + return $ciphertext; + case self::MODE_OFB: + return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); + } + } + + if ($this->engine === self::ENGINE_MCRYPT) { + if ($this->enchanged) { + @mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); + $this->enchanged = false; + } + + // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's + // rewritten CFB implementation the above outputs the same thing twice. + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $block_size = $this->block_size; + $iv = &$this->encryptIV; + $pos = &$this->enbuffer['pos']; + $len = strlen($plaintext); + $ciphertext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + $this->enbuffer['enmcrypt_init'] = true; + } + if ($len >= $block_size) { + if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { + if ($this->enbuffer['enmcrypt_init'] === true) { + @mcrypt_generic_init($this->enmcrypt, $this->key, $iv); + $this->enbuffer['enmcrypt_init'] = false; + } + $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); + $iv = substr($ciphertext, -$block_size); + $len%= $block_size; + } else { + while ($len >= $block_size) { + $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); + $ciphertext.= $iv; + $len-= $block_size; + $i+= $block_size; + } + } + } + + if ($len) { + $iv = @mcrypt_generic($this->ecb, $iv); + $block = $iv ^ substr($plaintext, -$len); + $iv = substr_replace($iv, $block, 0, $len); + $ciphertext.= $block; + $pos = $len; + } + + return $ciphertext; + } + + $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext); + + if (!$this->continuousBuffer) { + @mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); + } + + return $ciphertext; + } + + if ($this->engine === self::ENGINE_EVAL) { + $inline = $this->inline_crypt; + return $inline('encrypt', $plaintext); + } + + $buffer = &$this->enbuffer; + $block_size = $this->block_size; + $ciphertext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $ciphertext.= $this->encryptBlock(substr($plaintext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->encryptIV; + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $block = $this->encryptBlock($block ^ $xor); + $xor = $block; + $ciphertext.= $block; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->encryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'].= $this->encryptBlock($xor); + } + Strings::increment_str($xor); + $key = Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $key = $this->encryptBlock($xor); + Strings::increment_str($xor); + $ciphertext.= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + if ($this->continuousBuffer) { + $iv = &$this->encryptIV; + $pos = &$buffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->encryptBlock($iv) ^ substr($plaintext, $i, $block_size); + $ciphertext.= $iv; + $len-= $block_size; + $i+= $block_size; + } + if ($len) { + $iv = $this->encryptBlock($iv); + $block = $iv ^ substr($plaintext, $i); + $iv = substr_replace($iv, $block, 0, $len); + $ciphertext.= $block; + $pos = $len; + } + break; + case self::MODE_CFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i = 0; $i < $len; ++$i) { + $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); + $iv = substr($iv, 1) . $c; + } + + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->encryptIV = substr($ciphertext, -$block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB: + $xor = $this->encryptIV; + if (strlen($buffer['xor'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['xor'])) { + $xor = $this->encryptBlock($xor); + $buffer['xor'].= $xor; + } + $key = Strings::shift($buffer['xor'], $block_size); + $ciphertext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $xor = $this->encryptBlock($xor); + $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['xor'] = substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $ciphertext = $this->encryptBlock($plaintext); + break; + } + + return $ciphertext; + } + + /** + * Decrypts a message. + * + * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until + * it is. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::encrypt() + * @access public + * @param string $ciphertext + * @return string $plaintext + * @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size + */ + public function decrypt($ciphertext) + { + if ($this->paddable && strlen($ciphertext) % $this->block_size) { + throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); + } + + $this->setup(); + + if ($this->mode == self::MODE_GCM || isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + + if (isset($this->poly1305Key)) { + $newtag = $this->poly1305($ciphertext); + } else { + $oldIV = $this->iv; + Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $plaintext = $cipher->decrypt($ciphertext); + + $s = $this->ghash( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + self::len64($this->aad) . + self::len64($ciphertext) + ); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $newtag = $cipher->encrypt($s); + } + if ($this->oldtag != substr($newtag, 0, strlen($newtag))) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = false; + $plaintext = $cipher->decrypt($ciphertext); + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + return $plaintext; + } + + if ($this->engine === self::ENGINE_OPENSSL) { + switch ($this->mode) { + case self::MODE_STREAM: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + break; + case self::MODE_ECB: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + break; + case self::MODE_CBC: + $offset = $this->block_size; + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + $this->decryptIV = substr($ciphertext, -$offset, $this->block_size); + } + break; + case self::MODE_CTR: + $plaintext = $this->openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $plaintext = ''; + if ($this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$this->buffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + $ciphertext = substr($ciphertext, $i); + } + $overflow = $len % $this->block_size; + if ($overflow) { + $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + if ($len - $overflow) { + $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); + } + $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $plaintext.= $iv ^ substr($ciphertext, -$overflow); + $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); + $pos = $overflow; + } elseif ($len) { + $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + break; + case self::MODE_CFB8: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->decryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB: + $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); + } + + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + + if ($this->engine === self::ENGINE_MCRYPT) { + $block_size = $this->block_size; + if ($this->dechanged) { + @mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); + $this->dechanged = false; + } + + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$this->debuffer['pos']; + $len = strlen($ciphertext); + $plaintext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + } + if ($len >= $block_size) { + $cb = substr($ciphertext, $i, $len - $len % $block_size); + $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; + $iv = substr($cb, -$block_size); + $len%= $block_size; + } + if ($len) { + $iv = @mcrypt_generic($this->ecb, $iv); + $plaintext.= $iv ^ substr($ciphertext, -$len); + $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); + $pos = $len; + } + + return $plaintext; + } + + $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext); + + if (!$this->continuousBuffer) { + @mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); + } + + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + + if ($this->engine === self::ENGINE_EVAL) { + $inline = $this->inline_crypt; + return $inline('decrypt', $ciphertext); + } + + $block_size = $this->block_size; + + $buffer = &$this->debuffer; + $plaintext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $plaintext.= $this->decryptBlock(substr($ciphertext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->decryptIV; + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $plaintext.= $this->decryptBlock($block) ^ $xor; + $xor = $block; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->decryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'].= $this->encryptBlock($xor); + } + Strings::increment_str($xor); + $key = Strings::shift($buffer['ciphertext'], $block_size); + $plaintext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $key = $this->encryptBlock($xor); + Strings::increment_str($xor); + $plaintext.= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + if ($this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$buffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->encryptBlock($iv); + $cb = substr($ciphertext, $i, $block_size); + $plaintext.= $iv ^ $cb; + $iv = $cb; + $len-= $block_size; + $i+= $block_size; + } + if ($len) { + $iv = $this->encryptBlock($iv); + $plaintext.= $iv ^ substr($ciphertext, $i); + $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len); + $pos = $len; + } + break; + case self::MODE_CFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i = 0; $i < $len; ++$i) { + $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); + $iv = substr($iv, 1) . $ciphertext[$i]; + } + + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->decryptIV = substr($ciphertext, -$block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB: + $xor = $this->decryptIV; + if (strlen($buffer['xor'])) { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + if (strlen($block) > strlen($buffer['xor'])) { + $xor = $this->encryptBlock($xor); + $buffer['xor'].= $xor; + } + $key = Strings::shift($buffer['xor'], $block_size); + $plaintext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $xor = $this->encryptBlock($xor); + $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer['xor'] = substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $plaintext = $this->decryptBlock($ciphertext); + break; + } + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + + /** + * Get the authentication tag + * + * Only used in GCM or Poly1305 mode + * + * @see self::encrypt() + * @param int $length optional + * @return string + * @access public + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function getTag($length = 16) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + + if ($this->newtag === false) { + throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); + } + + // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it + // were 0 you might as well be doing CTR and less than 4 provides minimal security that could be trivially + // easily brute forced. + // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 + // for more info + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + + return $length == 16 ? + $this->newtag : + substr($this->newtag, 0, $length); + } + + /** + * Sets the authentication tag + * + * Only used in GCM mode + * + * @see self::decrypt() + * @param string $tag + * @access public + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function setTag($tag) + { + if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } + + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + + $length = strlen($tag); + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + $this->oldtag = $tag; + } + + /** + * Get the IV + * + * mcrypt requires an IV even if ECB is used + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $iv + * @return string + * @access private + */ + protected function getIV($iv) + { + return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv; + } + + /** + * OpenSSL CTR Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for CTR is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this + * function will emulate CTR with ECB when necessary. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + * @access private + */ + private function openssl_ctr_process($plaintext, &$encryptIV, &$buffer) + { + $ciphertext = ''; + + $block_size = $this->block_size; + $key = $this->key; + + if ($this->openssl_emulate_ctr) { + $xor = $encryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'].= openssl_encrypt($xor, static::$cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + } + Strings::increment_str($xor); + $otp = Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext.= $block ^ $otp; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $otp = openssl_encrypt($xor, static::$cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + Strings::increment_str($xor); + $ciphertext.= $block ^ $otp; + } + } + if ($this->continuousBuffer) { + $encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + + return $ciphertext; + } + + if (strlen($buffer['ciphertext'])) { + $ciphertext = $plaintext ^ Strings::shift($buffer['ciphertext'], strlen($plaintext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + + if (!strlen($plaintext)) { + return $ciphertext; + } + } + + $overflow = strlen($plaintext) % $block_size; + if ($overflow) { + $plaintext2 = Strings::pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 + $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $temp = Strings::pop($encrypted, $block_size); + $ciphertext.= $encrypted . ($plaintext2 ^ $temp); + if ($this->continuousBuffer) { + $buffer['ciphertext'] = substr($temp, $overflow); + $encryptIV = $temp; + } + } elseif (!strlen($buffer['ciphertext'])) { + $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $temp = Strings::pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $temp; + } + } + if ($this->continuousBuffer) { + $encryptIV = openssl_decrypt($encryptIV, static::$cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + if ($overflow) { + Strings::increment_str($encryptIV); + } + } + + return $ciphertext; + } + + /** + * OpenSSL OFB Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for OFB is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + * @access private + */ + private function openssl_ofb_process($plaintext, &$encryptIV, &$buffer) + { + if (strlen($buffer['xor'])) { + $ciphertext = $plaintext ^ $buffer['xor']; + $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + } else { + $ciphertext = ''; + } + + $block_size = $this->block_size; + + $len = strlen($plaintext); + $key = $this->key; + $overflow = $len % $block_size; + + if (strlen($plaintext)) { + if ($overflow) { + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $xor = Strings::pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $xor; + } + $ciphertext.= Strings::shift($xor, $overflow) ^ substr($plaintext, -$overflow); + if ($this->continuousBuffer) { + $buffer['xor'] = $xor; + } + } else { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + if ($this->continuousBuffer) { + $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); + } + } + } + + return $ciphertext; + } + + /** + * phpseclib <-> OpenSSL Mode Mapper + * + * May need to be overwritten by classes extending this one in some cases + * + * @return string + * @access private + */ + protected function openssl_translate_mode() + { + switch ($this->mode) { + case self::MODE_ECB: + return 'ecb'; + case self::MODE_CBC: + return 'cbc'; + case self::MODE_CTR: + case self::MODE_GCM: + return 'ctr'; + case self::MODE_CFB: + return 'cfb'; + case self::MODE_CFB8: + return 'cfb8'; + case self::MODE_OFB: + return 'ofb'; + } + } + + /** + * Pad "packets". + * + * Block ciphers working by encrypting between their specified [$this->]block_size at a time + * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to + * pad the input so that it is of the proper length. + * + * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, + * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping + * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is + * transmitted separately) + * + * @see self::disablePadding() + * @access public + */ + public function enablePadding() + { + $this->padding = true; + } + + /** + * Do not pad packets. + * + * @see self::enablePadding() + * @access public + */ + public function disablePadding() + { + $this->padding = false; + } + + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->encrypt(substr($plaintext, 16, 16)); + * + * + * echo $rijndael->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\*() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::disableContinuousBuffer() + * @access public + */ + public function enableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('This mode does not run in continuous mode'); + } + + $this->continuousBuffer = true; + + $this->setEngine(); + } + + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::enableContinuousBuffer() + * @access public + */ + public function disableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + if (!$this->continuousBuffer) { + return; + } + + $this->continuousBuffer = false; + + $this->setEngine(); + } + + /** + * Test for engine validity + * + * @see self::__construct() + * @param int $engine + * @access private + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_OPENSSL: + $this->openssl_emulate_ctr = false; + $result = $this->cipher_name_openssl && + extension_loaded('openssl'); + if (!$result) { + return false; + } + + $methods = openssl_get_cipher_methods(); + if (in_array($this->cipher_name_openssl, $methods)) { + return true; + } + // not all of openssl's symmetric cipher's support ctr. for those + // that don't we'll emulate it + switch ($this->mode) { + case self::MODE_CTR: + if (in_array(static::$cipher_name_openssl_ecb, $methods)) { + $this->openssl_emulate_ctr = true; + return true; + } + } + return false; + case self::ENGINE_MCRYPT: + return $this->cipher_name_mcrypt && + extension_loaded('mcrypt') && + in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms()); + case self::ENGINE_EVAL: + return method_exists($this, 'setupInlineCrypt'); + case self::ENGINE_INTERNAL: + return true; + } + + return false; + } + + /** + * Test for engine validity + * + * @see self::__construct() + * @param string $engine + * @access public + * @return bool + */ + public function isValidEngine($engine) + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_map('strtolower', self::ENGINE_MAP); + $reverseMap = array_flip($reverseMap); + } + $engine = strtolower($engine); + if (!isset($reverseMap[$engine])) { + return false; + } + + return $this->isValidEngineHelper($reverseMap[$engine]); + } + + /** + * Sets the preferred crypt engine + * + * Currently, $engine could be: + * + * - libsodium[very fast] + * + * - OpenSSL [very fast] + * + * - mcrypt [fast] + * + * - Eval [slow] + * + * - PHP [slowest] + * + * If the preferred crypt engine is not available the fastest available one will be used + * + * @see self::__construct() + * @param string $engine + * @access public + */ + public function setPreferredEngine($engine) + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_map('strtolower', self::ENGINE_MAP); + $reverseMap = array_flip($reverseMap); + } + $engine = strtolower($engine); + $this->preferredEngine = isset($reverseMap[$engine]) ? $reverseMap[$engine] : self::ENGINE_LIBSODIUM; + + $this->setEngine(); + } + + /** + * Returns the engine currently being utilized + * + * @see self::setEngine() + * @access public + */ + public function getEngine() + { + return self::ENGINE_MAP[$this->engine]; + } + + /** + * Sets the engine as appropriate + * + * @see self::__construct() + * @access private + */ + protected function setEngine() + { + $this->engine = null; + + $candidateEngines = [ + self::ENGINE_LIBSODIUM, + self::ENGINE_OPENSSL_GCM, + self::ENGINE_OPENSSL, + self::ENGINE_MCRYPT, + self::ENGINE_EVAL + ]; + if (isset($this->preferredEngine)) { + $temp = [$this->preferredEngine]; + $candidateEngines = array_merge( + $temp, + array_diff($candidateEngines, $temp) + ); + } + foreach ($candidateEngines as $engine) { + if ($this->isValidEngineHelper($engine)) { + $this->engine = $engine; + break; + } + } + if (!$this->engine) { + $this->engine = self::ENGINE_INTERNAL; + } + + if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { + // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, + // (re)open them with the module named in $this->cipher_name_mcrypt + @mcrypt_module_close($this->enmcrypt); + @mcrypt_module_close($this->demcrypt); + $this->enmcrypt = null; + $this->demcrypt = null; + + if ($this->ecb) { + @mcrypt_module_close($this->ecb); + $this->ecb = null; + } + } + + $this->changed = $this->nonIVChanged = true; + } + + /** + * Encrypts a block + * + * Note: Must be extended by the child \phpseclib3\Crypt\* class + * + * @access private + * @param string $in + * @return string + */ + abstract protected function encryptBlock($in); + + /** + * Decrypts a block + * + * Note: Must be extended by the child \phpseclib3\Crypt\* class + * + * @access private + * @param string $in + * @return string + */ + abstract protected function decryptBlock($in); + + /** + * Setup the key (expansion) + * + * Only used if $engine == self::ENGINE_INTERNAL + * + * Note: Must extend by the child \phpseclib3\Crypt\* class + * + * @see self::setup() + * @access private + */ + abstract protected function setupKey(); + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == self::ENGINE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * {@internal setup() is always called before en/decryption.} + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + * @access private + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->changed = false; + + if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true]; + //$this->newtag = $this->oldtag = false; + + if ($this->usesNonce()) { + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + if ($this->mode == self::MODE_GCM && !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + $this->setupGCM(); + } + } else { + $this->iv = $this->origIV; + } + + if ($this->iv === false && !in_array($this->mode, [self::MODE_STREAM, self::MODE_ECB])) { + if ($this->mode != self::MODE_GCM || !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + throw new InsufficientSetupException('No IV has been defined'); + } + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + $this->encryptIV = $this->decryptIV = $this->iv; + + switch ($this->engine) { + case self::ENGINE_MCRYPT: + $this->enchanged = $this->dechanged = true; + + if (!isset($this->enmcrypt)) { + static $mcrypt_modes = [ + self::MODE_CTR => 'ctr', + self::MODE_ECB => MCRYPT_MODE_ECB, + self::MODE_CBC => MCRYPT_MODE_CBC, + self::MODE_CFB => 'ncfb', + self::MODE_CFB8 => MCRYPT_MODE_CFB, + self::MODE_OFB => MCRYPT_MODE_NOFB, + self::MODE_STREAM => MCRYPT_MODE_STREAM, + ]; + + $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + + // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() + // to workaround mcrypt's broken ncfb implementation in buffered mode + // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + if ($this->mode == self::MODE_CFB) { + $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + } + } // else should mcrypt_generic_deinit be called? + + if ($this->mode == self::MODE_CFB) { + @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + } + break; + case self::ENGINE_INTERNAL: + $this->setupKey(); + break; + case self::ENGINE_EVAL: + if ($this->nonIVChanged) { + $this->setupKey(); + $this->setupInlineCrypt(); + } + } + + $this->nonIVChanged = false; + } + + /** + * Pads a string + * + * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. + * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to + * chr($this->block_size - (strlen($text) % $this->block_size) + * + * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless + * and padding will, hence forth, be enabled. + * + * @see self::unpad() + * @param string $text + * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size + * @access private + * @return string + */ + protected function pad($text) + { + $length = strlen($text); + + if (!$this->padding) { + if ($length % $this->block_size == 0) { + return $text; + } else { + throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); + } + } + + $pad = $this->block_size - ($length % $this->block_size); + + return str_pad($text, $length + $pad, chr($pad)); + } + + /** + * Unpads a string. + * + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. + * + * @see self::pad() + * @param string $text + * @throws \LengthException if the ciphertext's length is not a multiple of the block size + * @access private + * @return string + */ + protected function unpad($text) + { + if (!$this->padding) { + return $text; + } + + $length = ord($text[strlen($text) - 1]); + + if (!$length || $length > $this->block_size) { + throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); + } + + return substr($text, 0, -$length); + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * Stores the created (or existing) callback function-name + * in $this->inline_crypt + * + * Internally for phpseclib developers: + * + * _setupInlineCrypt() would be called only if: + * + * - $this->engine === self::ENGINE_EVAL + * + * - each time on _setup(), after(!) _setupKey() + * + * + * This ensures that _setupInlineCrypt() has always a + * full ready2go initializated internal cipher $engine state + * where, for example, the keys already expanded, + * keys/block_size calculated and such. + * + * It is, each time if called, the responsibility of _setupInlineCrypt(): + * + * - to set $this->inline_crypt to a valid and fully working callback function + * as a (faster) replacement for encrypt() / decrypt() + * + * - NOT to create unlimited callback functions (for memory reasons!) + * no matter how often _setupInlineCrypt() would be called. At some + * point of amount they must be generic re-useable. + * + * - the code of _setupInlineCrypt() it self, + * and the generated callback code, + * must be, in following order: + * - 100% safe + * - 100% compatible to encrypt()/decrypt() + * - using only php5+ features/lang-constructs/php-extensions if + * compatibility (down to php4) or fallback is provided + * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) + * - >= 10% faster than encrypt()/decrypt() [which is, by the way, + * the reason for the existence of _setupInlineCrypt() :-)] + * - memory-nice + * - short (as good as possible) + * + * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. + * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib3\Crypt\* class. + * - The following variable names are reserved: + * - $_* (all variable names prefixed with an underscore) + * - $self (object reference to it self. Do not use $this, but $self instead) + * - $in (the content of $in has to en/decrypt by the generated code) + * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only + * + * {@internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()} + * + * @see self::setup() + * @see self::createInlineCryptFunction() + * @see self::encrypt() + * @see self::decrypt() + * @access private + */ + //protected function setupInlineCrypt(); + + /** + * Creates the performance-optimized function for en/decrypt() + * + * Internally for phpseclib developers: + * + * _createInlineCryptFunction(): + * + * - merge the $cipher_code [setup'ed by _setupInlineCrypt()] + * with the current [$this->]mode of operation code + * + * - create the $inline function, which called by encrypt() / decrypt() + * as its replacement to speed up the en/decryption operations. + * + * - return the name of the created $inline callback function + * + * - used to speed up en/decryption + * + * + * + * The main reason why can speed up things [up to 50%] this way are: + * + * - using variables more effective then regular. + * (ie no use of expensive arrays but integers $k_0, $k_1 ... + * or even, for example, the pure $key[] values hardcoded) + * + * - avoiding 1000's of function calls of ie _encryptBlock() + * but inlining the crypt operations. + * in the mode of operation for() loop. + * + * - full loop unroll the (sometimes key-dependent) rounds + * avoiding this way ++$i counters and runtime-if's etc... + * + * The basic code architectur of the generated $inline en/decrypt() + * lambda function, in pseudo php, is: + * + * + * +----------------------------------------------------------------------------------------------+ + * | callback $inline = create_function: | + * | lambda_function_0001_crypt_ECB($action, $text) | + * | { | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_crypt']; // general init code. | + * | // ie: $sbox'es declarations used for | + * | // encrypt and decrypt'ing. | + * | | + * | switch ($action) { | + * | case 'encrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | + * | ie: specified $key or $box | + * | declarations for encrypt'ing. | + * | | + * | foreach ($ciphertext) { | + * | $in = $block_size of $ciphertext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for encryption. | + * | // $cipher_code['encrypt_block'] has to | + * | // encrypt the content of the $in variable | + * | | + * | $plaintext .= $in; | + * | } | + * | return $plaintext; | + * | | + * | case 'decrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_decrypt']; // decrypt sepcific init code | + * | ie: specified $key or $box | + * | declarations for decrypt'ing. | + * | foreach ($plaintext) { | + * | $in = $block_size of $plaintext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for decryption. | + * | // $cipher_code['decrypt_block'] has to | + * | // decrypt the content of the $in variable | + * | $ciphertext .= $in; | + * | } | + * | return $ciphertext; | + * | } | + * | } | + * +----------------------------------------------------------------------------------------------+ + * + * + * See also the \phpseclib3\Crypt\*::_setupInlineCrypt()'s for + * productive inline $cipher_code's how they works. + * + * Structure of: + * + * $cipher_code = [ + * 'init_crypt' => (string) '', // optional + * 'init_encrypt' => (string) '', // optional + * 'init_decrypt' => (string) '', // optional + * 'encrypt_block' => (string) '', // required + * 'decrypt_block' => (string) '' // required + * ]; + * + * + * @see self::setupInlineCrypt() + * @see self::encrypt() + * @see self::decrypt() + * @param array $cipher_code + * @access private + * @return string (the name of the created callback function) + */ + protected function createInlineCryptFunction($cipher_code) + { + $block_size = $this->block_size; + + // optional + $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : ''; + $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : ''; + $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : ''; + // required + $encrypt_block = $cipher_code['encrypt_block']; + $decrypt_block = $cipher_code['decrypt_block']; + + // Generating mode of operation inline code, + // merged with the $cipher_code algorithm + // for encrypt- and decryption. + switch ($this->mode) { + case self::MODE_ECB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $in = substr($_text, $_i, '.$block_size.'); + '.$encrypt_block.' + $_ciphertext.= $in; + } + + return $_ciphertext; + '; + + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); + $_ciphertext_len = strlen($_text); + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $in = substr($_text, $_i, '.$block_size.'); + '.$decrypt_block.' + $_plaintext.= $in; + } + + return $this->unpad($_plaintext); + '; + break; + case self::MODE_CTR: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + '.$encrypt_block.' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], '.$block_size.'); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + $in = $_xor; + '.$encrypt_block.' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_key = $in; + $_ciphertext.= $_block ^ $_key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % '.$block_size.') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; + + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + '.$encrypt_block.' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], '.$block_size.'); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + $in = $_xor; + '.$encrypt_block.' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_key = $in; + $_plaintext.= $_block ^ $_key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % '.$block_size.') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_plaintext; + '; + break; + case self::MODE_CFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_buffer = &$this->enbuffer; + + if ($this->continuousBuffer) { + $_iv = &$this->encryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $this->encryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = '.$block_size.' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); + } + while ($_len >= '.$block_size.') { + $in = $_iv; + '.$encrypt_block.'; + $_iv = $in ^ substr($_text, $_i, '.$block_size.'); + $_ciphertext.= $_iv; + $_len-= '.$block_size.'; + $_i+= '.$block_size.'; + } + if ($_len) { + $in = $_iv; + '.$encrypt_block.' + $_iv = $in; + $_block = $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, $_block, 0, $_len); + $_ciphertext.= $_block; + $_pos = $_len; + } + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_buffer = &$this->debuffer; + + if ($this->continuousBuffer) { + $_iv = &$this->decryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $this->decryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = '.$block_size.' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_plaintext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); + } + while ($_len >= '.$block_size.') { + $in = $_iv; + '.$encrypt_block.' + $_iv = $in; + $cb = substr($_text, $_i, '.$block_size.'); + $_plaintext.= $_iv ^ $cb; + $_iv = $cb; + $_len-= '.$block_size.'; + $_i+= '.$block_size.'; + } + if ($_len) { + $in = $_iv; + '.$encrypt_block.' + $_iv = $in; + $_plaintext.= $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); + $_pos = $_len; + } + + return $_plaintext; + '; + break; + case self::MODE_CFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $this->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + '.$encrypt_block.' + $_ciphertext .= ($_c = $_text[$_i] ^ $in); + $_iv = substr($_iv, 1) . $_c; + } + + if ($this->continuousBuffer) { + if ($_len >= '.$block_size.') { + $this->encryptIV = substr($_ciphertext, -'.$block_size.'); + } else { + $this->encryptIV = substr($this->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len); + } + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + '.$encrypt_block.' + $_plaintext .= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $_text[$_i]; + } + + if ($this->continuousBuffer) { + if ($_len >= '.$block_size.') { + $this->decryptIV = substr($_text, -'.$block_size.'); + } else { + $this->decryptIV = substr($this->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len); + } + } + + return $_plaintext; + '; + break; + case self::MODE_OFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], '.$block_size.'); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor; + } + $_key = $_xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % '.$block_size.') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], '.$block_size.'); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor; + } + $_key = $_xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % '.$block_size.') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_plaintext; + '; + break; + case self::MODE_STREAM: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + '.$encrypt_block.' + return $_ciphertext; + '; + $decrypt = $init_decrypt . ' + $_plaintext = ""; + '.$decrypt_block.' + return $_plaintext; + '; + break; + // case self::MODE_CBC: + default: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + $in = $this->encryptIV; + + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $in = substr($_text, $_i, '.$block_size.') ^ $in; + '.$encrypt_block.' + $_ciphertext.= $in; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $in; + } + + return $_ciphertext; + '; + + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); + $_ciphertext_len = strlen($_text); + + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $in = $_block = substr($_text, $_i, '.$block_size.'); + '.$decrypt_block.' + $_plaintext.= $in ^ $_iv; + $_iv = $_block; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $_iv; + } + + return $this->unpad($_plaintext); + '; + break; + } + + // Before discrediting this, please read the following: + // @see https://github.com/phpseclib/phpseclib/issues/1293 + // @see https://github.com/phpseclib/phpseclib/pull/1143 + eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};'); + + return \Closure::bind($func, $this, static::class); + } + + /** + * Convert float to int + * + * On ARM CPUs converting floats to ints doesn't always work + * + * @access private + * @param string $x + * @return int + */ + protected static function safe_intval($x) + { + switch (true) { + case is_int($x): + // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding" + case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': + return $x; + } + return (fmod($x, 0x80000000) & 0x7FFFFFFF) | + ((fmod(floor($x / 0x80000000), 2) & 1) << 31); + } + + /** + * eval()'able string for in-line float to int + * + * @access private + * @return string + */ + protected static function safe_intval_inline() + { + switch (true) { + case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: + case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': + return '%s'; + break; + default: + $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; + return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; + } + } + + /** + * Sets up GCM parameters + * + * See steps 1-2 of https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=23 + * for more info + * + * @access private + */ + private function setupGCM() + { + // don't keep on re-calculating $this->h + if (!$this->h || $this->h->key != $this->key) { + $cipher = new static('ecb'); + $cipher->setKey($this->key); + $cipher->disablePadding(); + + $this->h = self::$gcmField->newInteger( + Strings::switchEndianness($cipher->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")) + ); + $this->h->key = $this->key; + } + + if (strlen($this->nonce) == 12) { + $this->iv = $this->nonce . "\0\0\0\1"; + } else { + $this->iv = $this->ghash( + self::nullPad128($this->nonce) . str_repeat("\0", 8) . self::len64($this->nonce) + ); + } + } + + /** + * Performs GHASH operation + * + * See https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=20 + * for more info + * + * @see self::decrypt() + * @see self::encrypt() + * @access private + * @param string $x + * @return string + */ + private function ghash($x) + { + $h = $this->h; + $y = ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"]; + $x = str_split($x, 16); + $n = 0; + // the switchEndianness calls are necessary because the multiplication algorithm in BinaryField/Integer + // interprets strings as polynomials in big endian order whereas in GCM they're interpreted in little + // endian order per https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=19. + // big endian order is what binary field elliptic curves use per http://www.secg.org/sec1-v2.pdf#page=18. + + // we could switchEndianness here instead of in the while loop but doing so in the while loop seems like it + // might be slightly more performant + //$x = Strings::switchEndianness($x); + foreach ($x as $xn) { + $xn = Strings::switchEndianness($xn); + $t = $y[$n] ^ $xn; + $temp = self::$gcmField->newInteger($t); + $y[++$n] = $temp->multiply($h)->toBytes(); + $y[$n] = substr($y[$n], 1); + } + $y[$n] = Strings::switchEndianness($y[$n]); + return $y[$n]; + } + + /** + * Returns the bit length of a string in a packed format + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @access private + * @param string $str + * @return string + */ + private static function len64($str) + { + return "\0\0\0\0" . pack('N', 8 * strlen($str)); + } + + /** + * NULL pads a string to be a multiple of 128 + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @access private + * @param string $str + * @return string + */ + protected static function nullPad128($str) + { + $len = strlen($str); + return $str . str_repeat("\0", 16 * ceil($len / 16) - $len); + } + + /** + * Calculates Poly1305 MAC + * + * On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation + * it takes 1.2s. + * + * @see self::decrypt() + * @see self::encrypt() + * @access private + * @param string $text + * @return string + */ + protected function poly1305($text) + { + $s = $this->poly1305Key; // strlen($this->poly1305Key) == 32 + $r = Strings::shift($s, 16); + $r = strrev($r); + $r&= "\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xff"; + $s = strrev($s); + + $r = self::$poly1305Field->newInteger(new BigInteger($r, 256)); + $s = self::$poly1305Field->newInteger(new BigInteger($s, 256)); + $a = self::$poly1305Field->newInteger(new BigInteger()); + + $blocks = str_split($text, 16); + foreach ($blocks as $block) { + $n = strrev($block . chr(1)); + $n = self::$poly1305Field->newInteger(new BigInteger($n, 256)); + $a = $a->add($n); + $a = $a->multiply($r); + } + $r = $a->toBigInteger()->add($s->toBigInteger()); + $mask = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; + return strrev($r->toBytes()) & $mask; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php new file mode 100644 index 000000000..0db9c84ab --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php @@ -0,0 +1,62 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Traits; + +use phpseclib3\Crypt\Hash; + +/** + * Fingerprint Trait for Private Keys + * + * @package Common + * @author Jim Wigginton + * @access public + */ +trait Fingerprint +{ + /** + * Returns the public key's fingerprint + * + * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is + * no public key currently loaded, false is returned. + * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) + * + * @access public + * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned + * for invalid values. + * @return mixed + */ + public function getFingerprint($algorithm = 'md5') + { + $type = self::validatePlugin('Keys', 'OpenSSH', 'savePublicKey'); + if ($type === false) { + return false; + } + $key = $this->toString('OpenSSH', ['binary' => true]); + if ($key === false) { + return false; + } + switch ($algorithm) { + case 'sha256': + $hash = new Hash('sha256'); + $base = base64_encode($hash->hash($key)); + return substr($base, 0, strlen($base) - 1); + case 'md5': + return substr(chunk_split(md5($key), 2, ':'), 0, -1); + default: + return false; + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php new file mode 100644 index 000000000..058f9b949 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php @@ -0,0 +1,51 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Traits; + +/** + * Password Protected Trait for Private Keys + * + * @package Common + * @author Jim Wigginton + * @access public + */ +trait PasswordProtected +{ + /** + * Password + * + * @var string|bool + */ + private $password = false; + + /** + * Sets the password + * + * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. + * Or rather, pass in $password such that empty($password) && !is_string($password) is true. + * + * @see self::createKey() + * @see self::load() + * @access public + * @param string|boolean $password + */ + public function withPassword($password = false) + { + $new = clone $this; + $new->password = $password; + return $new; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php new file mode 100644 index 000000000..cbde382fd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php @@ -0,0 +1,1411 @@ + + * setKey('abcdefgh'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $des->decrypt($des->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package DES + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; + +/** + * Pure-PHP implementation of DES. + * + * @package DES + * @author Jim Wigginton + * @access public + */ +class DES extends BlockCipher +{ + /** + * Contains $keys[self::ENCRYPT] + * + * @access private + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\DES::processBlock() + */ + const ENCRYPT = 0; + /** + * Contains $keys[self::DECRYPT] + * + * @access private + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\DES::processBlock() + */ + const DECRYPT = 1; + + /** + * Block Length of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + * @access private + */ + protected $block_size = 8; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 8; + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + * @access private + */ + protected $cipher_name_mcrypt = 'des'; + + /** + * The OpenSSL names of the cipher / modes + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::openssl_mode_names + * @var array + * @access private + */ + protected $openssl_mode_names = [ + self::MODE_ECB => 'des-ecb', + self::MODE_CBC => 'des-cbc', + self::MODE_CFB => 'des-cfb', + self::MODE_OFB => 'des-ofb' + // self::MODE_CTR is undefined for DES + ]; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + * @access private + */ + protected $cfb_init_len = 500; + + /** + * Switch for DES/3DES encryption + * + * Used only if $engine == self::ENGINE_INTERNAL + * + * @see self::setupKey() + * @see self::processBlock() + * @var int + * @access private + */ + protected $des_rounds = 1; + + /** + * max possible size of $key + * + * @see self::setKey() + * @var string + * @access private + */ + protected $key_length_max = 8; + + /** + * The Key Schedule + * + * @see self::setupKey() + * @var array + * @access private + */ + private $keys; + + /** + * Shuffle table. + * + * For each byte value index, the entry holds an 8-byte string + * with each byte containing all bits in the same state as the + * corresponding bit in the index value. + * + * @see self::processBlock() + * @see self::setupKey() + * @var array + * @access private + */ + protected static $shuffle = [ + "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", + "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", + "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", + "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF", + "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF", + "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF", + "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF", + "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF", + "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF", + "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF", + "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF", + "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF", + "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF", + "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF", + "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF", + "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF", + "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF", + "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF", + "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF", + "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF", + "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF", + "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF", + "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF", + "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF", + "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF", + "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF", + "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF", + "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF", + "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF", + "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF", + "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF", + "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", + "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF", + "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF", + "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF", + "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF", + "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF", + "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF", + "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF", + "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF", + "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF", + "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF", + "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF", + "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF", + "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF", + "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF", + "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF", + "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF", + "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF", + "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF", + "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF", + "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF", + "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF", + "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF", + "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF", + "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF", + "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF", + "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF", + "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF", + "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF", + "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF", + "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF", + "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF", + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF", + "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF", + "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF", + "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF", + "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF", + "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF", + "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF", + "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF", + "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF", + "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF", + "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF", + "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF", + "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF", + "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF", + "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF", + "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF", + "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF", + "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF", + "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF", + "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF", + "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF", + "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF", + "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF", + "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF", + "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF", + "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF", + "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF", + "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF", + "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF", + "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF", + "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF", + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF", + "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF", + "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF", + "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF", + "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF", + "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF", + "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF", + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF", + "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF", + "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF", + "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF", + "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF", + "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF", + "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF", + "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF", + "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF", + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF", + "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF", + "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF", + "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF", + "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF", + "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF", + "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF", + "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF", + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF", + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF", + "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF", + "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF", + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF", + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF", + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + ]; + + /** + * IP mapping helper table. + * + * Indexing this table with each source byte performs the initial bit permutation. + * + * @var array + * @access private + */ + protected static $ipmap = [ + 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, + 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, + 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, + 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73, + 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35, + 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37, + 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75, + 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77, + 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1, + 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3, + 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1, + 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3, + 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5, + 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7, + 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5, + 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7, + 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39, + 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B, + 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79, + 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B, + 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D, + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9, + 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB, + 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9, + 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB, + 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD, + 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, + 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, + 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF + ]; + + /** + * Inverse IP mapping helper table. + * Indexing this table with a byte value reverses the bit order. + * + * @var array + * @access private + */ + protected static $invipmap = [ + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF + ]; + + /** + * Pre-permuted S-box1 + * + * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the + * P table: concatenation can then be replaced by exclusive ORs. + * + * @var array + * @access private + */ + protected static $sbox1 = [ + 0x00808200, 0x00000000, 0x00008000, 0x00808202, + 0x00808002, 0x00008202, 0x00000002, 0x00008000, + 0x00000200, 0x00808200, 0x00808202, 0x00000200, + 0x00800202, 0x00808002, 0x00800000, 0x00000002, + 0x00000202, 0x00800200, 0x00800200, 0x00008200, + 0x00008200, 0x00808000, 0x00808000, 0x00800202, + 0x00008002, 0x00800002, 0x00800002, 0x00008002, + 0x00000000, 0x00000202, 0x00008202, 0x00800000, + 0x00008000, 0x00808202, 0x00000002, 0x00808000, + 0x00808200, 0x00800000, 0x00800000, 0x00000200, + 0x00808002, 0x00008000, 0x00008200, 0x00800002, + 0x00000200, 0x00000002, 0x00800202, 0x00008202, + 0x00808202, 0x00008002, 0x00808000, 0x00800202, + 0x00800002, 0x00000202, 0x00008202, 0x00808200, + 0x00000202, 0x00800200, 0x00800200, 0x00000000, + 0x00008002, 0x00008200, 0x00000000, 0x00808002 + ]; + + /** + * Pre-permuted S-box2 + * + * @var array + * @access private + */ + protected static $sbox2 = [ + 0x40084010, 0x40004000, 0x00004000, 0x00084010, + 0x00080000, 0x00000010, 0x40080010, 0x40004010, + 0x40000010, 0x40084010, 0x40084000, 0x40000000, + 0x40004000, 0x00080000, 0x00000010, 0x40080010, + 0x00084000, 0x00080010, 0x40004010, 0x00000000, + 0x40000000, 0x00004000, 0x00084010, 0x40080000, + 0x00080010, 0x40000010, 0x00000000, 0x00084000, + 0x00004010, 0x40084000, 0x40080000, 0x00004010, + 0x00000000, 0x00084010, 0x40080010, 0x00080000, + 0x40004010, 0x40080000, 0x40084000, 0x00004000, + 0x40080000, 0x40004000, 0x00000010, 0x40084010, + 0x00084010, 0x00000010, 0x00004000, 0x40000000, + 0x00004010, 0x40084000, 0x00080000, 0x40000010, + 0x00080010, 0x40004010, 0x40000010, 0x00080010, + 0x00084000, 0x00000000, 0x40004000, 0x00004010, + 0x40000000, 0x40080010, 0x40084010, 0x00084000 + ]; + + /** + * Pre-permuted S-box3 + * + * @var array + * @access private + */ + protected static $sbox3 = [ + 0x00000104, 0x04010100, 0x00000000, 0x04010004, + 0x04000100, 0x00000000, 0x00010104, 0x04000100, + 0x00010004, 0x04000004, 0x04000004, 0x00010000, + 0x04010104, 0x00010004, 0x04010000, 0x00000104, + 0x04000000, 0x00000004, 0x04010100, 0x00000100, + 0x00010100, 0x04010000, 0x04010004, 0x00010104, + 0x04000104, 0x00010100, 0x00010000, 0x04000104, + 0x00000004, 0x04010104, 0x00000100, 0x04000000, + 0x04010100, 0x04000000, 0x00010004, 0x00000104, + 0x00010000, 0x04010100, 0x04000100, 0x00000000, + 0x00000100, 0x00010004, 0x04010104, 0x04000100, + 0x04000004, 0x00000100, 0x00000000, 0x04010004, + 0x04000104, 0x00010000, 0x04000000, 0x04010104, + 0x00000004, 0x00010104, 0x00010100, 0x04000004, + 0x04010000, 0x04000104, 0x00000104, 0x04010000, + 0x00010104, 0x00000004, 0x04010004, 0x00010100 + ]; + + /** + * Pre-permuted S-box4 + * + * @var array + * @access private + */ + protected static $sbox4 = [ + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x00401040, 0x80400040, 0x80400000, 0x80001000, + 0x00000000, 0x00401000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00400040, 0x80400000, + 0x80000000, 0x00001000, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x80001000, 0x00001040, + 0x80400040, 0x80000000, 0x00001040, 0x00400040, + 0x00001000, 0x00401040, 0x80401040, 0x80000040, + 0x00400040, 0x80400000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00000000, 0x00401000, + 0x00001040, 0x00400040, 0x80400040, 0x80000000, + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x80401040, 0x80000040, 0x80000000, 0x00001000, + 0x80400000, 0x80001000, 0x00401040, 0x80400040, + 0x80001000, 0x00001040, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x00001000, 0x00401040 + ]; + + /** + * Pre-permuted S-box5 + * + * @var array + * @access private + */ + protected static $sbox5 = [ + 0x00000080, 0x01040080, 0x01040000, 0x21000080, + 0x00040000, 0x00000080, 0x20000000, 0x01040000, + 0x20040080, 0x00040000, 0x01000080, 0x20040080, + 0x21000080, 0x21040000, 0x00040080, 0x20000000, + 0x01000000, 0x20040000, 0x20040000, 0x00000000, + 0x20000080, 0x21040080, 0x21040080, 0x01000080, + 0x21040000, 0x20000080, 0x00000000, 0x21000000, + 0x01040080, 0x01000000, 0x21000000, 0x00040080, + 0x00040000, 0x21000080, 0x00000080, 0x01000000, + 0x20000000, 0x01040000, 0x21000080, 0x20040080, + 0x01000080, 0x20000000, 0x21040000, 0x01040080, + 0x20040080, 0x00000080, 0x01000000, 0x21040000, + 0x21040080, 0x00040080, 0x21000000, 0x21040080, + 0x01040000, 0x00000000, 0x20040000, 0x21000000, + 0x00040080, 0x01000080, 0x20000080, 0x00040000, + 0x00000000, 0x20040000, 0x01040080, 0x20000080 + ]; + + /** + * Pre-permuted S-box6 + * + * @var array + * @access private + */ + protected static $sbox6 = [ + 0x10000008, 0x10200000, 0x00002000, 0x10202008, + 0x10200000, 0x00000008, 0x10202008, 0x00200000, + 0x10002000, 0x00202008, 0x00200000, 0x10000008, + 0x00200008, 0x10002000, 0x10000000, 0x00002008, + 0x00000000, 0x00200008, 0x10002008, 0x00002000, + 0x00202000, 0x10002008, 0x00000008, 0x10200008, + 0x10200008, 0x00000000, 0x00202008, 0x10202000, + 0x00002008, 0x00202000, 0x10202000, 0x10000000, + 0x10002000, 0x00000008, 0x10200008, 0x00202000, + 0x10202008, 0x00200000, 0x00002008, 0x10000008, + 0x00200000, 0x10002000, 0x10000000, 0x00002008, + 0x10000008, 0x10202008, 0x00202000, 0x10200000, + 0x00202008, 0x10202000, 0x00000000, 0x10200008, + 0x00000008, 0x00002000, 0x10200000, 0x00202008, + 0x00002000, 0x00200008, 0x10002008, 0x00000000, + 0x10202000, 0x10000000, 0x00200008, 0x10002008 + ]; + + /** + * Pre-permuted S-box7 + * + * @var array + * @access private + */ + protected static $sbox7 = [ + 0x00100000, 0x02100001, 0x02000401, 0x00000000, + 0x00000400, 0x02000401, 0x00100401, 0x02100400, + 0x02100401, 0x00100000, 0x00000000, 0x02000001, + 0x00000001, 0x02000000, 0x02100001, 0x00000401, + 0x02000400, 0x00100401, 0x00100001, 0x02000400, + 0x02000001, 0x02100000, 0x02100400, 0x00100001, + 0x02100000, 0x00000400, 0x00000401, 0x02100401, + 0x00100400, 0x00000001, 0x02000000, 0x00100400, + 0x02000000, 0x00100400, 0x00100000, 0x02000401, + 0x02000401, 0x02100001, 0x02100001, 0x00000001, + 0x00100001, 0x02000000, 0x02000400, 0x00100000, + 0x02100400, 0x00000401, 0x00100401, 0x02100400, + 0x00000401, 0x02000001, 0x02100401, 0x02100000, + 0x00100400, 0x00000000, 0x00000001, 0x02100401, + 0x00000000, 0x00100401, 0x02100000, 0x00000400, + 0x02000001, 0x02000400, 0x00000400, 0x00100001 + ]; + + /** + * Pre-permuted S-box8 + * + * @var array + * @access private + */ + protected static $sbox8 = [ + 0x08000820, 0x00000800, 0x00020000, 0x08020820, + 0x08000000, 0x08000820, 0x00000020, 0x08000000, + 0x00020020, 0x08020000, 0x08020820, 0x00020800, + 0x08020800, 0x00020820, 0x00000800, 0x00000020, + 0x08020000, 0x08000020, 0x08000800, 0x00000820, + 0x00020800, 0x00020020, 0x08020020, 0x08020800, + 0x00000820, 0x00000000, 0x00000000, 0x08020020, + 0x08000020, 0x08000800, 0x00020820, 0x00020000, + 0x00020820, 0x00020000, 0x08020800, 0x00000800, + 0x00000020, 0x08020020, 0x00000800, 0x00020820, + 0x08000800, 0x00000020, 0x08000020, 0x08020000, + 0x08020020, 0x08000000, 0x00020000, 0x08000820, + 0x00000000, 0x08020820, 0x00020020, 0x08000020, + 0x08020000, 0x08000800, 0x08000820, 0x00000000, + 0x08020820, 0x00020800, 0x00020800, 0x00000820, + 0x00000820, 0x00020020, 0x08000000, 0x08020800 + ]; + + /** + * Default Constructor. + * + * @param string $mode + * @access public + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * @param int $engine + * @access protected + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($this->key_length_max == 8) { + if ($engine == self::ENGINE_OPENSSL) { + self::$cipher_name_openssl_ecb = 'des-ecb'; + $this->cipher_name_openssl = 'des-' . $this->openssl_translate_mode(); + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the key. + * + * Keys must be 64-bits long or 8 bytes long. + * + * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * @access public + * @param string $key + */ + public function setKey($key) + { + if (!($this instanceof TripleDES) && strlen($key) != 8) { + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported'); + } + + // Sets the key + parent::setKey($key); + } + + /** + * Encrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::encrypt() + * @access private + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + return $this->processBlock($in, self::ENCRYPT); + } + + /** + * Decrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::decrypt() + * @access private + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + return $this->processBlock($in, self::DECRYPT); + } + + /** + * Encrypts or decrypts a 64-bit block + * + * $mode should be either self::ENCRYPT or self::DECRYPT. See + * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general + * idea of what this function does. + * + * @see self::encryptBlock() + * @see self::decryptBlock() + * @access private + * @param string $block + * @param int $mode + * @return string + */ + private function processBlock($block, $mode) + { + static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; + if (!$sbox1) { + $sbox1 = array_map('intval', self::$sbox1); + $sbox2 = array_map('intval', self::$sbox2); + $sbox3 = array_map('intval', self::$sbox3); + $sbox4 = array_map('intval', self::$sbox4); + $sbox5 = array_map('intval', self::$sbox5); + $sbox6 = array_map('intval', self::$sbox6); + $sbox7 = array_map('intval', self::$sbox7); + $sbox8 = array_map('intval', self::$sbox8); + /* Merge $shuffle with $[inv]ipmap */ + for ($i = 0; $i < 256; ++$i) { + $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; + $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; + } + } + + $keys = $this->keys[$mode]; + $ki = -1; + + // Do the initial IP permutation. + $t = unpack('Nl/Nr', $block); + list($l, $r) = [$t['l'], $t['r']]; + $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + + // Extract L0 and R0. + $t = unpack('Nl/Nr', $block); + list($l, $r) = [$t['l'], $t['r']]; + + for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { + // Perform the 16 steps. + for ($i = 0; $i < 16; $i++) { + // start of "the Feistel (F) function" - see the following URL: + // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png + // Merge key schedule. + $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki]; + $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[++$ki]; + + // S-box indexing. + $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l; + // end of "the Feistel (F) function" + + $l = $r; + $r = $t; + } + + // Last step should not permute L & R. + $t = $l; + $l = $r; + $r = $t; + } + + // Perform the inverse IP permutation. + return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleinvip[($r >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleinvip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleinvip[ $r & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleinvip[ $l & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + } + + /** + * Creates the key schedule + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @access private + */ + protected function setupKey() + { + if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key, 'des_rounds' => $this->des_rounds]; + + static $shifts = [ // number of key bits shifted per round + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 + ]; + + static $pc1map = [ + 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C, + 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E, + 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C, + 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E, + 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C, + 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E, + 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C, + 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E, + 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C, + 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E, + 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C, + 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E, + 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C, + 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E, + 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C, + 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E, + 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C, + 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E, + 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C, + 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E, + 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC, + 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE, + 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC, + 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE, + 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC, + 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE, + 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC, + 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE, + 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC, + 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE, + 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC, + 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE + ]; + + // Mapping tables for the PC-2 transformation. + static $pc2mapc1 = [ + 0x00000000, 0x00000400, 0x00200000, 0x00200400, + 0x00000001, 0x00000401, 0x00200001, 0x00200401, + 0x02000000, 0x02000400, 0x02200000, 0x02200400, + 0x02000001, 0x02000401, 0x02200001, 0x02200401 + ]; + static $pc2mapc2 = [ + 0x00000000, 0x00000800, 0x08000000, 0x08000800, + 0x00010000, 0x00010800, 0x08010000, 0x08010800, + 0x00000000, 0x00000800, 0x08000000, 0x08000800, + 0x00010000, 0x00010800, 0x08010000, 0x08010800, + 0x00000100, 0x00000900, 0x08000100, 0x08000900, + 0x00010100, 0x00010900, 0x08010100, 0x08010900, + 0x00000100, 0x00000900, 0x08000100, 0x08000900, + 0x00010100, 0x00010900, 0x08010100, 0x08010900, + 0x00000010, 0x00000810, 0x08000010, 0x08000810, + 0x00010010, 0x00010810, 0x08010010, 0x08010810, + 0x00000010, 0x00000810, 0x08000010, 0x08000810, + 0x00010010, 0x00010810, 0x08010010, 0x08010810, + 0x00000110, 0x00000910, 0x08000110, 0x08000910, + 0x00010110, 0x00010910, 0x08010110, 0x08010910, + 0x00000110, 0x00000910, 0x08000110, 0x08000910, + 0x00010110, 0x00010910, 0x08010110, 0x08010910, + 0x00040000, 0x00040800, 0x08040000, 0x08040800, + 0x00050000, 0x00050800, 0x08050000, 0x08050800, + 0x00040000, 0x00040800, 0x08040000, 0x08040800, + 0x00050000, 0x00050800, 0x08050000, 0x08050800, + 0x00040100, 0x00040900, 0x08040100, 0x08040900, + 0x00050100, 0x00050900, 0x08050100, 0x08050900, + 0x00040100, 0x00040900, 0x08040100, 0x08040900, + 0x00050100, 0x00050900, 0x08050100, 0x08050900, + 0x00040010, 0x00040810, 0x08040010, 0x08040810, + 0x00050010, 0x00050810, 0x08050010, 0x08050810, + 0x00040010, 0x00040810, 0x08040010, 0x08040810, + 0x00050010, 0x00050810, 0x08050010, 0x08050810, + 0x00040110, 0x00040910, 0x08040110, 0x08040910, + 0x00050110, 0x00050910, 0x08050110, 0x08050910, + 0x00040110, 0x00040910, 0x08040110, 0x08040910, + 0x00050110, 0x00050910, 0x08050110, 0x08050910, + 0x01000000, 0x01000800, 0x09000000, 0x09000800, + 0x01010000, 0x01010800, 0x09010000, 0x09010800, + 0x01000000, 0x01000800, 0x09000000, 0x09000800, + 0x01010000, 0x01010800, 0x09010000, 0x09010800, + 0x01000100, 0x01000900, 0x09000100, 0x09000900, + 0x01010100, 0x01010900, 0x09010100, 0x09010900, + 0x01000100, 0x01000900, 0x09000100, 0x09000900, + 0x01010100, 0x01010900, 0x09010100, 0x09010900, + 0x01000010, 0x01000810, 0x09000010, 0x09000810, + 0x01010010, 0x01010810, 0x09010010, 0x09010810, + 0x01000010, 0x01000810, 0x09000010, 0x09000810, + 0x01010010, 0x01010810, 0x09010010, 0x09010810, + 0x01000110, 0x01000910, 0x09000110, 0x09000910, + 0x01010110, 0x01010910, 0x09010110, 0x09010910, + 0x01000110, 0x01000910, 0x09000110, 0x09000910, + 0x01010110, 0x01010910, 0x09010110, 0x09010910, + 0x01040000, 0x01040800, 0x09040000, 0x09040800, + 0x01050000, 0x01050800, 0x09050000, 0x09050800, + 0x01040000, 0x01040800, 0x09040000, 0x09040800, + 0x01050000, 0x01050800, 0x09050000, 0x09050800, + 0x01040100, 0x01040900, 0x09040100, 0x09040900, + 0x01050100, 0x01050900, 0x09050100, 0x09050900, + 0x01040100, 0x01040900, 0x09040100, 0x09040900, + 0x01050100, 0x01050900, 0x09050100, 0x09050900, + 0x01040010, 0x01040810, 0x09040010, 0x09040810, + 0x01050010, 0x01050810, 0x09050010, 0x09050810, + 0x01040010, 0x01040810, 0x09040010, 0x09040810, + 0x01050010, 0x01050810, 0x09050010, 0x09050810, + 0x01040110, 0x01040910, 0x09040110, 0x09040910, + 0x01050110, 0x01050910, 0x09050110, 0x09050910, + 0x01040110, 0x01040910, 0x09040110, 0x09040910, + 0x01050110, 0x01050910, 0x09050110, 0x09050910 + ]; + static $pc2mapc3 = [ + 0x00000000, 0x00000004, 0x00001000, 0x00001004, + 0x00000000, 0x00000004, 0x00001000, 0x00001004, + 0x10000000, 0x10000004, 0x10001000, 0x10001004, + 0x10000000, 0x10000004, 0x10001000, 0x10001004, + 0x00000020, 0x00000024, 0x00001020, 0x00001024, + 0x00000020, 0x00000024, 0x00001020, 0x00001024, + 0x10000020, 0x10000024, 0x10001020, 0x10001024, + 0x10000020, 0x10000024, 0x10001020, 0x10001024, + 0x00080000, 0x00080004, 0x00081000, 0x00081004, + 0x00080000, 0x00080004, 0x00081000, 0x00081004, + 0x10080000, 0x10080004, 0x10081000, 0x10081004, + 0x10080000, 0x10080004, 0x10081000, 0x10081004, + 0x00080020, 0x00080024, 0x00081020, 0x00081024, + 0x00080020, 0x00080024, 0x00081020, 0x00081024, + 0x10080020, 0x10080024, 0x10081020, 0x10081024, + 0x10080020, 0x10080024, 0x10081020, 0x10081024, + 0x20000000, 0x20000004, 0x20001000, 0x20001004, + 0x20000000, 0x20000004, 0x20001000, 0x20001004, + 0x30000000, 0x30000004, 0x30001000, 0x30001004, + 0x30000000, 0x30000004, 0x30001000, 0x30001004, + 0x20000020, 0x20000024, 0x20001020, 0x20001024, + 0x20000020, 0x20000024, 0x20001020, 0x20001024, + 0x30000020, 0x30000024, 0x30001020, 0x30001024, + 0x30000020, 0x30000024, 0x30001020, 0x30001024, + 0x20080000, 0x20080004, 0x20081000, 0x20081004, + 0x20080000, 0x20080004, 0x20081000, 0x20081004, + 0x30080000, 0x30080004, 0x30081000, 0x30081004, + 0x30080000, 0x30080004, 0x30081000, 0x30081004, + 0x20080020, 0x20080024, 0x20081020, 0x20081024, + 0x20080020, 0x20080024, 0x20081020, 0x20081024, + 0x30080020, 0x30080024, 0x30081020, 0x30081024, + 0x30080020, 0x30080024, 0x30081020, 0x30081024, + 0x00000002, 0x00000006, 0x00001002, 0x00001006, + 0x00000002, 0x00000006, 0x00001002, 0x00001006, + 0x10000002, 0x10000006, 0x10001002, 0x10001006, + 0x10000002, 0x10000006, 0x10001002, 0x10001006, + 0x00000022, 0x00000026, 0x00001022, 0x00001026, + 0x00000022, 0x00000026, 0x00001022, 0x00001026, + 0x10000022, 0x10000026, 0x10001022, 0x10001026, + 0x10000022, 0x10000026, 0x10001022, 0x10001026, + 0x00080002, 0x00080006, 0x00081002, 0x00081006, + 0x00080002, 0x00080006, 0x00081002, 0x00081006, + 0x10080002, 0x10080006, 0x10081002, 0x10081006, + 0x10080002, 0x10080006, 0x10081002, 0x10081006, + 0x00080022, 0x00080026, 0x00081022, 0x00081026, + 0x00080022, 0x00080026, 0x00081022, 0x00081026, + 0x10080022, 0x10080026, 0x10081022, 0x10081026, + 0x10080022, 0x10080026, 0x10081022, 0x10081026, + 0x20000002, 0x20000006, 0x20001002, 0x20001006, + 0x20000002, 0x20000006, 0x20001002, 0x20001006, + 0x30000002, 0x30000006, 0x30001002, 0x30001006, + 0x30000002, 0x30000006, 0x30001002, 0x30001006, + 0x20000022, 0x20000026, 0x20001022, 0x20001026, + 0x20000022, 0x20000026, 0x20001022, 0x20001026, + 0x30000022, 0x30000026, 0x30001022, 0x30001026, + 0x30000022, 0x30000026, 0x30001022, 0x30001026, + 0x20080002, 0x20080006, 0x20081002, 0x20081006, + 0x20080002, 0x20080006, 0x20081002, 0x20081006, + 0x30080002, 0x30080006, 0x30081002, 0x30081006, + 0x30080002, 0x30080006, 0x30081002, 0x30081006, + 0x20080022, 0x20080026, 0x20081022, 0x20081026, + 0x20080022, 0x20080026, 0x20081022, 0x20081026, + 0x30080022, 0x30080026, 0x30081022, 0x30081026, + 0x30080022, 0x30080026, 0x30081022, 0x30081026 + ]; + static $pc2mapc4 = [ + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208 + ]; + static $pc2mapd1 = [ + 0x00000000, 0x00000001, 0x08000000, 0x08000001, + 0x00200000, 0x00200001, 0x08200000, 0x08200001, + 0x00000002, 0x00000003, 0x08000002, 0x08000003, + 0x00200002, 0x00200003, 0x08200002, 0x08200003 + ]; + static $pc2mapd2 = [ + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04 + ]; + static $pc2mapd3 = [ + 0x00000000, 0x00010000, 0x02000000, 0x02010000, + 0x00000020, 0x00010020, 0x02000020, 0x02010020, + 0x00040000, 0x00050000, 0x02040000, 0x02050000, + 0x00040020, 0x00050020, 0x02040020, 0x02050020, + 0x00002000, 0x00012000, 0x02002000, 0x02012000, + 0x00002020, 0x00012020, 0x02002020, 0x02012020, + 0x00042000, 0x00052000, 0x02042000, 0x02052000, + 0x00042020, 0x00052020, 0x02042020, 0x02052020, + 0x00000000, 0x00010000, 0x02000000, 0x02010000, + 0x00000020, 0x00010020, 0x02000020, 0x02010020, + 0x00040000, 0x00050000, 0x02040000, 0x02050000, + 0x00040020, 0x00050020, 0x02040020, 0x02050020, + 0x00002000, 0x00012000, 0x02002000, 0x02012000, + 0x00002020, 0x00012020, 0x02002020, 0x02012020, + 0x00042000, 0x00052000, 0x02042000, 0x02052000, + 0x00042020, 0x00052020, 0x02042020, 0x02052020, + 0x00000010, 0x00010010, 0x02000010, 0x02010010, + 0x00000030, 0x00010030, 0x02000030, 0x02010030, + 0x00040010, 0x00050010, 0x02040010, 0x02050010, + 0x00040030, 0x00050030, 0x02040030, 0x02050030, + 0x00002010, 0x00012010, 0x02002010, 0x02012010, + 0x00002030, 0x00012030, 0x02002030, 0x02012030, + 0x00042010, 0x00052010, 0x02042010, 0x02052010, + 0x00042030, 0x00052030, 0x02042030, 0x02052030, + 0x00000010, 0x00010010, 0x02000010, 0x02010010, + 0x00000030, 0x00010030, 0x02000030, 0x02010030, + 0x00040010, 0x00050010, 0x02040010, 0x02050010, + 0x00040030, 0x00050030, 0x02040030, 0x02050030, + 0x00002010, 0x00012010, 0x02002010, 0x02012010, + 0x00002030, 0x00012030, 0x02002030, 0x02012030, + 0x00042010, 0x00052010, 0x02042010, 0x02052010, + 0x00042030, 0x00052030, 0x02042030, 0x02052030, + 0x20000000, 0x20010000, 0x22000000, 0x22010000, + 0x20000020, 0x20010020, 0x22000020, 0x22010020, + 0x20040000, 0x20050000, 0x22040000, 0x22050000, + 0x20040020, 0x20050020, 0x22040020, 0x22050020, + 0x20002000, 0x20012000, 0x22002000, 0x22012000, + 0x20002020, 0x20012020, 0x22002020, 0x22012020, + 0x20042000, 0x20052000, 0x22042000, 0x22052000, + 0x20042020, 0x20052020, 0x22042020, 0x22052020, + 0x20000000, 0x20010000, 0x22000000, 0x22010000, + 0x20000020, 0x20010020, 0x22000020, 0x22010020, + 0x20040000, 0x20050000, 0x22040000, 0x22050000, + 0x20040020, 0x20050020, 0x22040020, 0x22050020, + 0x20002000, 0x20012000, 0x22002000, 0x22012000, + 0x20002020, 0x20012020, 0x22002020, 0x22012020, + 0x20042000, 0x20052000, 0x22042000, 0x22052000, + 0x20042020, 0x20052020, 0x22042020, 0x22052020, + 0x20000010, 0x20010010, 0x22000010, 0x22010010, + 0x20000030, 0x20010030, 0x22000030, 0x22010030, + 0x20040010, 0x20050010, 0x22040010, 0x22050010, + 0x20040030, 0x20050030, 0x22040030, 0x22050030, + 0x20002010, 0x20012010, 0x22002010, 0x22012010, + 0x20002030, 0x20012030, 0x22002030, 0x22012030, + 0x20042010, 0x20052010, 0x22042010, 0x22052010, + 0x20042030, 0x20052030, 0x22042030, 0x22052030, + 0x20000010, 0x20010010, 0x22000010, 0x22010010, + 0x20000030, 0x20010030, 0x22000030, 0x22010030, + 0x20040010, 0x20050010, 0x22040010, 0x22050010, + 0x20040030, 0x20050030, 0x22040030, 0x22050030, + 0x20002010, 0x20012010, 0x22002010, 0x22012010, + 0x20002030, 0x20012030, 0x22002030, 0x22012030, + 0x20042010, 0x20052010, 0x22042010, 0x22052010, + 0x20042030, 0x20052030, 0x22042030, 0x22052030 + ]; + static $pc2mapd4 = [ + 0x00000000, 0x00000400, 0x01000000, 0x01000400, + 0x00000000, 0x00000400, 0x01000000, 0x01000400, + 0x00000100, 0x00000500, 0x01000100, 0x01000500, + 0x00000100, 0x00000500, 0x01000100, 0x01000500, + 0x10000000, 0x10000400, 0x11000000, 0x11000400, + 0x10000000, 0x10000400, 0x11000000, 0x11000400, + 0x10000100, 0x10000500, 0x11000100, 0x11000500, + 0x10000100, 0x10000500, 0x11000100, 0x11000500, + 0x00080000, 0x00080400, 0x01080000, 0x01080400, + 0x00080000, 0x00080400, 0x01080000, 0x01080400, + 0x00080100, 0x00080500, 0x01080100, 0x01080500, + 0x00080100, 0x00080500, 0x01080100, 0x01080500, + 0x10080000, 0x10080400, 0x11080000, 0x11080400, + 0x10080000, 0x10080400, 0x11080000, 0x11080400, + 0x10080100, 0x10080500, 0x11080100, 0x11080500, + 0x10080100, 0x10080500, 0x11080100, 0x11080500, + 0x00000008, 0x00000408, 0x01000008, 0x01000408, + 0x00000008, 0x00000408, 0x01000008, 0x01000408, + 0x00000108, 0x00000508, 0x01000108, 0x01000508, + 0x00000108, 0x00000508, 0x01000108, 0x01000508, + 0x10000008, 0x10000408, 0x11000008, 0x11000408, + 0x10000008, 0x10000408, 0x11000008, 0x11000408, + 0x10000108, 0x10000508, 0x11000108, 0x11000508, + 0x10000108, 0x10000508, 0x11000108, 0x11000508, + 0x00080008, 0x00080408, 0x01080008, 0x01080408, + 0x00080008, 0x00080408, 0x01080008, 0x01080408, + 0x00080108, 0x00080508, 0x01080108, 0x01080508, + 0x00080108, 0x00080508, 0x01080108, 0x01080508, + 0x10080008, 0x10080408, 0x11080008, 0x11080408, + 0x10080008, 0x10080408, 0x11080008, 0x11080408, + 0x10080108, 0x10080508, 0x11080108, 0x11080508, + 0x10080108, 0x10080508, 0x11080108, 0x11080508, + 0x00001000, 0x00001400, 0x01001000, 0x01001400, + 0x00001000, 0x00001400, 0x01001000, 0x01001400, + 0x00001100, 0x00001500, 0x01001100, 0x01001500, + 0x00001100, 0x00001500, 0x01001100, 0x01001500, + 0x10001000, 0x10001400, 0x11001000, 0x11001400, + 0x10001000, 0x10001400, 0x11001000, 0x11001400, + 0x10001100, 0x10001500, 0x11001100, 0x11001500, + 0x10001100, 0x10001500, 0x11001100, 0x11001500, + 0x00081000, 0x00081400, 0x01081000, 0x01081400, + 0x00081000, 0x00081400, 0x01081000, 0x01081400, + 0x00081100, 0x00081500, 0x01081100, 0x01081500, + 0x00081100, 0x00081500, 0x01081100, 0x01081500, + 0x10081000, 0x10081400, 0x11081000, 0x11081400, + 0x10081000, 0x10081400, 0x11081000, 0x11081400, + 0x10081100, 0x10081500, 0x11081100, 0x11081500, + 0x10081100, 0x10081500, 0x11081100, 0x11081500, + 0x00001008, 0x00001408, 0x01001008, 0x01001408, + 0x00001008, 0x00001408, 0x01001008, 0x01001408, + 0x00001108, 0x00001508, 0x01001108, 0x01001508, + 0x00001108, 0x00001508, 0x01001108, 0x01001508, + 0x10001008, 0x10001408, 0x11001008, 0x11001408, + 0x10001008, 0x10001408, 0x11001008, 0x11001408, + 0x10001108, 0x10001508, 0x11001108, 0x11001508, + 0x10001108, 0x10001508, 0x11001108, 0x11001508, + 0x00081008, 0x00081408, 0x01081008, 0x01081408, + 0x00081008, 0x00081408, 0x01081008, 0x01081408, + 0x00081108, 0x00081508, 0x01081108, 0x01081508, + 0x00081108, 0x00081508, 0x01081108, 0x01081508, + 0x10081008, 0x10081408, 0x11081008, 0x11081408, + 0x10081008, 0x10081408, 0x11081008, 0x11081408, + 0x10081108, 0x10081508, 0x11081108, 0x11081508, + 0x10081108, 0x10081508, 0x11081108, 0x11081508 + ]; + + $keys = []; + for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { + // pad the key and remove extra characters as appropriate. + $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0"); + + // Perform the PC/1 transformation and compute C and D. + $t = unpack('Nl/Nr', $key); + list($l, $r) = [$t['l'], $t['r']]; + $key = (self::$shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | + (self::$shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | + (self::$shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | + (self::$shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | + (self::$shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | + (self::$shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | + (self::$shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | + (self::$shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); + $key = unpack('Nc/Nd', $key); + $c = ( $key['c'] >> 4) & 0x0FFFFFFF; + $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F); + + $keys[$des_round] = [ + self::ENCRYPT => [], + self::DECRYPT => array_fill(0, 32, 0) + ]; + for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) { + $c <<= $shifts[$i]; + $c = ($c | ($c >> 28)) & 0x0FFFFFFF; + $d <<= $shifts[$i]; + $d = ($d | ($d >> 28)) & 0x0FFFFFFF; + + // Perform the PC-2 transformation. + $cp = $pc2mapc1[ $c >> 24 ] | $pc2mapc2[($c >> 16) & 0xFF] | + $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[ $c & 0xFF]; + $dp = $pc2mapd1[ $d >> 24 ] | $pc2mapd2[($d >> 16) & 0xFF] | + $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF]; + + // Reorder: odd bytes/even bytes. Push the result in key schedule. + $val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) | + (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF); + $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) | + (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF); + $keys[$des_round][self::ENCRYPT][ ] = $val1; + $keys[$des_round][self::DECRYPT][$ki - 1] = $val1; + $keys[$des_round][self::ENCRYPT][ ] = $val2; + $keys[$des_round][self::DECRYPT][$ki ] = $val2; + } + } + + switch ($this->des_rounds) { + case 3: // 3DES keys + $this->keys = [ + self::ENCRYPT => array_merge( + $keys[0][self::ENCRYPT], + $keys[1][self::DECRYPT], + $keys[2][self::ENCRYPT] + ), + self::DECRYPT => array_merge( + $keys[2][self::DECRYPT], + $keys[1][self::ENCRYPT], + $keys[0][self::DECRYPT] + ) + ]; + break; + // case 1: // DES keys + default: + $this->keys = [ + self::ENCRYPT => $keys[0][self::ENCRYPT], + self::DECRYPT => $keys[0][self::DECRYPT] + ]; + } + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + * @access private + */ + protected function setupInlineCrypt() + { + // Engine configuration for: + // - DES ($des_rounds == 1) or + // - 3DES ($des_rounds == 3) + $des_rounds = $this->des_rounds; + + $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; + if (!$sbox1) { + $sbox1 = array_map("intval", self::$sbox1); + $sbox2 = array_map("intval", self::$sbox2); + $sbox3 = array_map("intval", self::$sbox3); + $sbox4 = array_map("intval", self::$sbox4); + $sbox5 = array_map("intval", self::$sbox5); + $sbox6 = array_map("intval", self::$sbox6); + $sbox7 = array_map("intval", self::$sbox7); + $sbox8 = array_map("intval", self::$sbox8);' + /* Merge $shuffle with $[inv]ipmap */ . ' + for ($i = 0; $i < 256; ++$i) { + $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; + $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; + } + } + '; + + $k = [ + self::ENCRYPT => $this->keys[self::ENCRYPT], + self::DECRYPT => $this->keys[self::DECRYPT] + ]; + $init_encrypt = ''; + $init_decrypt = ''; + + // Creating code for en- and decryption. + $crypt_block = []; + foreach ([self::ENCRYPT, self::DECRYPT] as $c) { + /* Do the initial IP permutation. */ + $crypt_block[$c] = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + $in = unpack("N*", + ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") + ); + ' . /* Extract L0 and R0 */ ' + $l = $in[1]; + $r = $in[2]; + '; + + $l = '$l'; + $r = '$r'; + + // Perform DES or 3DES. + for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { + // Perform the 16 steps. + for ($i = 0; $i < 16; ++$i) { + // start of "the Feistel (F) function" - see the following URL: + // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png + // Merge key schedule. + $crypt_block[$c].= ' + $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; + $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . + /* S-box indexing. */ + $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; + '; + // end of "the Feistel (F) function" + + // swap L & R + list($l, $r) = [$r, $l]; + } + list($l, $r) = [$r, $l]; + } + + // Perform the inverse IP permutation. + $crypt_block[$c].= '$in = + ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + '; + } + + // Creates the inline-crypt function + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $crypt_block[self::ENCRYPT], + 'decrypt_block' => $crypt_block[self::DECRYPT] + ] + ); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php new file mode 100644 index 000000000..9337200cf --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php @@ -0,0 +1,400 @@ + + * + * + * + * @category Crypt + * @package DH + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\DH\PrivateKey; +use phpseclib3\Crypt\DH\PublicKey; +use phpseclib3\Crypt\DH\Parameters; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP (EC)DH implementation + * + * @package DH + * @author Jim Wigginton + * @access public + */ +abstract class DH extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + * @access private + */ + const ALGORITHM = 'DH'; + + /** + * DH prime + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $prime; + + /** + * DH Base + * + * Prime divisor of p-1 + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $base; + + /** + * Create DH parameters + * + * This method is a bit polymorphic. It can take any of the following: + * - two BigInteger's (prime and base) + * - an integer representing the size of the prime in bits (the base is assumed to be 2) + * - a string (eg. diffie-hellman-group14-sha1) + * + * @access public + * @return \phpseclib3\Crypt\DH|bool + */ + public static function createParameters(...$args) + { + $params = new Parameters; + if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) { + //if (!$args[0]->isPrime()) { + // throw new \InvalidArgumentException('The first parameter should be a prime number'); + //} + $params->prime = $args[0]; + $params->base = $args[1]; + return $params; + } elseif (count($args) == 1 && is_numeric($args[0])) { + $params->prime = BigInteger::randomPrime($args[0]); + $params->base = new BigInteger(2); + return $params; + } elseif (count($args) != 1 || !is_string($args[0])) { + throw new \InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string'); + } + switch ($args[0]) { + // see http://tools.ietf.org/html/rfc2409#section-6.2 and + // http://tools.ietf.org/html/rfc2412, appendex E + case 'diffie-hellman-group1-sha1': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; + break; + // see http://tools.ietf.org/html/rfc3526#section-3 + case 'diffie-hellman-group14-sha1': // 2048-bit MODP Group + case 'diffie-hellman-group14-sha256': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-4 + case 'diffie-hellman-group15-sha512': // 3072-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-5 + case 'diffie-hellman-group16-sha512': // 4096-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-6 + case 'diffie-hellman-group17-sha512': // 6144-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . + 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . + 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . + 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . + '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . + 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . + '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-7 + case 'diffie-hellman-group18-sha512': // 8192-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . + 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . + 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . + 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . + '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . + 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . + '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4' . + '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED' . + '2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652D' . + 'E3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B' . + '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6' . + '6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851D' . + 'F9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92' . + '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA' . + '9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF'; + break; + default: + throw new \InvalidArgumentException('Invalid named prime provided'); + } + + $params->prime = new BigInteger($prime, 16); + $params->base = new BigInteger(2); + + return $params; + } + + /** + * Create public / private key pair. + * + * The rationale for the second parameter is described in http://tools.ietf.org/html/rfc4419#section-6.2 : + * + * "To increase the speed of the key exchange, both client and server may + * reduce the size of their private exponents. It should be at least + * twice as long as the key material that is generated from the shared + * secret. For more details, see the paper by van Oorschot and Wiener + * [VAN-OORSCHOT]." + * + * $length is in bits + * + * @param Parameters $params + * @param int $length optional + * @access public + * @return DH\PrivateKey + */ + public static function createKey(Parameters $params, $length = 0) + { + $one = new BigInteger(1); + if ($length) { + $max = $one->bitwise_leftShift($length); + $max = $max->subtract($one); + } else { + $max = $params->prime->subtract($one); + } + + $key = new PrivateKey; + $key->prime = $params->prime; + $key->base = $params->base; + $key->privateKey = BigInteger::randomRange($one, $max); + $key->publicKey = $key->base->powMod($key->privateKey, $key->prime); + return $key; + } + + /** + * Compute Shared Secret + * + * @param PrivateKey|EC $private + * @param PublicKey|BigInteger|string $public + * @access public + * @return mixed + */ + public static function computeSecret($private, $public) + { + if ($private instanceof PrivateKey) { // DH\PrivateKey + switch (true) { + case $public instanceof PublicKey: + if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) { + throw new \InvalidArgumentException('The public and private key do not share the same prime and / or base numbers'); + } + return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true); + case is_string($public): + $public = new BigInteger($public, -256); + case $public instanceof BigInteger: + return $public->powMod($private->privateKey, $private->prime)->toBytes(true); + default: + throw new \InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string'); + } + } + + if ($private instanceof EC\PrivateKey) { + switch (true) { + case $public instanceof EC\PublicKey: + $public = $public->getEncodedCoordinates(); + case is_string($public): + $point = $private->multiply($public); + switch ($private->getCurve()) { + case 'Curve25519': + case 'Curve448': + $secret = $point; + break; + default: + // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned + $secret = substr($point, 1, (strlen($point) - 1) >> 1); + } + /* + if (($secret[0] & "\x80") === "\x80") { + $secret = "\0$secret"; + } + */ + return $secret; + default: + throw new \InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)'); + } + } + } + + /** + * Load the key + * + * @param string $key + * @param string $password optional + * @return AsymmetricKey + */ + public static function load($key, $password = false) + { + try { + return EC::load($key, $password); + } catch (NoKeyLoadedException $e) {} + + return parent::load($key, $password); + } + + /** + * OnLoad Handler + * + * @return bool + * @access protected + * @param array $components + */ + protected static function onLoad($components) + { + if (!isset($components['privateKey']) && !isset($components['publicKey'])) { + $new = new Parameters; + } else { + $new = isset($components['privateKey']) ? + new PrivateKey : + new PublicKey; + } + + $new->prime = $components['prime']; + $new->base = $components['base']; + + if (isset($components['privateKey'])) { + $new->privateKey = $components['privateKey']; + } + if (isset($components['publicKey'])) { + $new->publicKey = $components['publicKey']; + } + + return $new; + } + + /** + * Determines which hashing function should be used + * + * @access public + * @param string $hash + */ + public function withHash($hash) + { + throw new UnsupportedOperationException('DH does not use a hash algorithm'); + } + + /** + * Returns the hash algorithm currently being used + * + * @access public + */ + public function getHash() + { + throw new UnsupportedOperationException('DH does not use a hash algorithm'); + } + + /** + * Returns the parameters + * + * A public / private key is only returned if the currently loaded "key" contains an x or y + * value. + * + * @see self::getPublicKey() + * @access public + * @return mixed + */ + public function getParameters() + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + $key = $type::saveParameters($this->prime, $this->base); + return self::load($key, 'PKCS1'); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..368b187fe --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php @@ -0,0 +1,83 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; + +/** + * "PKCS1" Formatted DH Key Handler + * + * @package DH + * @author Jim Wigginton + * @access public + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + return $components; + } + + /** + * Convert EC parameters to the appropriate format + * + * @access public + * @return string + */ + public static function saveParameters(BigInteger $prime, BigInteger $base, array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + + return "-----BEGIN DH PARAMETERS-----\r\n" . + chunk_split(base64_encode($params), 64) . + "-----END DH PARAMETERS-----\r\n"; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..e69fcee6e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php @@ -0,0 +1,157 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; + +/** + * PKCS#8 Formatted DH Key Handler + * + * @package DH + * @author Jim Wigginton + * @access public + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + * @access private + */ + const OID_NAME = 'dhKeyAgreement'; + + /** + * OID Value + * + * @var string + * @access private + */ + const OID_VALUE = '1.2.840.113549.1.3.1'; + + /** + * Child OIDs loaded + * + * @var bool + * @access private + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $isPublic = strpos($key, 'PUBLIC') !== false; + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + switch (true) { + case !$isPublic && $type == 'publicKey': + throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); + case $isPublic && $type == 'privateKey': + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + $decoded = ASN1::decodeBER($key[$type]); + switch (true) { + case empty($decoded): + case !is_array($decoded): + case !isset($decoded[0]['content']): + case !$decoded[0]['content'] instanceof BigInteger: + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components[$type] = $decoded[0]['content']; + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Math\BigInteger $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $prime, BigInteger $base, BigInteger $privateKey, BigInteger $publicKey, $password = '', array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($privateKey, ['type' => ASN1::TYPE_INTEGER]); + return self::wrapPrivateKey($key, [], $params, $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $prime, BigInteger $base, BigInteger $publicKey, array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($publicKey, ['type' => ASN1::TYPE_INTEGER]); + return self::wrapPublicKey($key, $params); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php new file mode 100644 index 000000000..d36283d03 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php @@ -0,0 +1,40 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\DH; + +/** + * DH Parameters + * + * @package DH + * @author Jim Wigginton + * @access public + */ +class Parameters extends DH +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->prime, $this->base, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php new file mode 100644 index 000000000..8756b4197 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php @@ -0,0 +1,82 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\DH; +use phpseclib3\Crypt\Common; + +/** + * DH Private Key + * + * @package DH + * @author Jim Wigginton + * @access public + */ +class PrivateKey extends DH +{ + use Common\Traits\PasswordProtected; + + /** + * Private Key + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $privateKey; + + /** + * Public Key + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $publicKey; + + /** + * Returns the public key + * + * @access public + * @return DH + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + + $key = $type::savePublicKey($this->prime, $this->base, $this->publicKey); + + return DH::loadFormat('PKCS8', $key); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + + return $type::savePrivateKey($this->prime, $this->base, $this->privateKey, $this->publicKey, $this->password, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php new file mode 100644 index 000000000..9670e28a1 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php @@ -0,0 +1,53 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\DH; +use phpseclib3\Crypt\Common; + +/** + * DH Public Key + * + * @package DH + * @author Jim Wigginton + * @access public + */ +class PublicKey extends DH +{ + use Common\Traits\Fingerprint; + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->prime, $this->base, $this->publicKey, $options); + } + + /** + * Returns the public key as a BigInteger + * + * @return \phpseclib3\Math\BigInteger + */ + public function toBigInteger() + { + return $this->publicKey; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php new file mode 100644 index 000000000..b368d83f5 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php @@ -0,0 +1,344 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * @category Crypt + * @package DSA + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\DSA\PrivateKey; +use phpseclib3\Crypt\DSA\PublicKey; +use phpseclib3\Crypt\DSA\Parameters; +use phpseclib3\Math\BigInteger; +use phpseclib3\Exception\InsufficientSetupException; + +/** + * Pure-PHP FIPS 186-4 compliant implementation of DSA. + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +abstract class DSA extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + * @access private + */ + const ALGORITHM = 'DSA'; + + /** + * DSA Prime P + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $p; + + /** + * DSA Group Order q + * + * Prime divisor of p-1 + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $q; + + /** + * DSA Group Generator G + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $g; + + /** + * DSA public key value y + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $y; + + /** + * Signature Format + * + * @var string + * @access private + */ + protected $sigFormat; + + /** + * Signature Format (Short) + * + * @var string + * @access private + */ + protected $shortFormat; + + /** + * Create DSA parameters + * + * @access public + * @param int $L + * @param int $N + * @return \phpseclib3\Crypt\DSA|bool + */ + public static function createParameters($L = 2048, $N = 224) + { + self::initialize_static_variables(); + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + switch (true) { + case $N == 160: + /* + in FIPS 186-1 and 186-2 N was fixed at 160 whereas K had an upper bound of 1024. + RFC 4253 (SSH Transport Layer Protocol) references FIPS 186-2 and as such most + SSH DSA implementations only support keys with an N of 160. + puttygen let's you set the size of L (but not the size of N) and uses 2048 as the + default L value. that's not really compliant with any of the FIPS standards, however, + for the purposes of maintaining compatibility with puttygen, we'll support it + */ + //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160: + // FIPS 186-3 changed this as follows: + //case $L == 1024 && $N == 160: + case $L == 2048 && $N == 224: + case $L == 2048 && $N == 256: + case $L == 3072 && $N == 256: + break; + default: + throw new \InvalidArgumentException('Invalid values for N and L'); + } + + $two = new BigInteger(2); + + $q = BigInteger::randomPrime($N); + $divisor = $q->multiply($two); + + do { + $x = BigInteger::random($L); + list(, $c) = $x->divide($divisor); + $p = $x->subtract($c->subtract(self::$one)); + } while ($p->getLength() != $L || !$p->isPrime()); + + $p_1 = $p->subtract(self::$one); + list($e) = $p_1->divide($q); + + // quoting http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#page=50 , + // "h could be obtained from a random number generator or from a counter that + // changes after each use". PuTTY (sshdssg.c) starts h off at 1 and increments + // it on each loop. wikipedia says "commonly h = 2 is used" so we'll just do that + $h = clone $two; + while (true) { + $g = $h->powMod($e, $p); + if (!$g->equals(self::$one)) { + break; + } + $h = $h->add(self::$one); + } + + $dsa = new Parameters; + $dsa->p = $p; + $dsa->q = $q; + $dsa->g = $g; + + return $dsa; + } + + /** + * Create public / private key pair. + * + * This method is a bit polymorphic. It can take a DSA/Parameters object, L / N as two distinct parameters or + * no parameters (at which point L and N will be generated with this method) + * + * Returns the private key, from which the publickey can be extracted + * + * @param int[] ...$args + * @access public + * @return DSA\PrivateKey + */ + public static function createKey(...$args) + { + self::initialize_static_variables(); + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (count($args) == 2 && is_int($args[0]) && is_int($args[1])) { + $params = self::createParameters($args[0], $args[1]); + } else if (count($args) == 1 && $args[0] instanceof Parameters) { + $params = $args[0]; + } else if (!count($args)) { + $params = self::createParameters(); + } else { + throw new InsufficientSetupException('Valid parameters are either two integers (L and N), a single DSA object or no parameters at all.'); + } + + $private = new PrivateKey; + $private->p = $params->p; + $private->q = $params->q; + $private->g = $params->g; + + $private->x = BigInteger::randomRange(self::$one, $private->q->subtract(self::$one)); + $private->y = $private->g->powMod($private->x, $private->p); + + //$public = clone $private; + //unset($public->x); + + return $private + ->withHash($params->hash->getHash()) + ->withSignatureFormat($params->shortFormat); + } + + /** + * OnLoad Handler + * + * @return bool + * @access protected + * @param array $components + */ + protected static function onLoad($components) + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (!isset($components['x']) && !isset($components['y'])) { + $new = new Parameters; + } else if (isset($components['x'])) { + $new = new PrivateKey; + $new->x = $components['x']; + } else { + $new = new PublicKey; + } + + $new->p = $components['p']; + $new->q = $components['q']; + $new->g = $components['g']; + + if (isset($components['y'])) { + $new->y = $components['y']; + } + + return $new; + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); + $this->shortFormat = 'ASN1'; + + parent::__construct(); + } + + /** + * Returns the key size + * + * More specifically, this L (the length of DSA Prime P) and N (the length of DSA Group Order q) + * + * @access public + * @return array + */ + public function getLength() + { + return ['L' => $this->p->getLength(), 'N' => $this->q->getLength()]; + } + + /** + * Returns the current engine being used + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @access public + * @return string + */ + public function getEngine() + { + return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? + 'OpenSSL' : 'PHP'; + } + + /** + * Returns the parameters + * + * A public / private key is only returned if the currently loaded "key" contains an x or y + * value. + * + * @see self::getPublicKey() + * @access public + * @return mixed + */ + public function getParameters() + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + $key = $type::saveParameters($this->p, $this->q, $this->g); + return DSA::load($key, 'PKCS1') + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @access public + * @param string $format + */ + public function withSignatureFormat($format) + { + $new = clone $this; + $new->shortFormat = $format; + $new->sigFormat = self::validatePlugin('Signature', $format); + return $new; + } + + /** + * Returns the signature format currently being used + * + * @access public + */ + public function getSignatureFormat() + { + return $this->shortFormat; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..bf2d9860c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,126 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; + +/** + * OpenSSH Formatted DSA Key Handler + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +abstract class OpenSSH extends Progenitor +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-dss']; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + + list($p, $q, $g, $y, $x, $comment) = Strings::unpackSSH2('i5s', $parsed['paddedKey']); + + return compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + + list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $parsed['publicKey']); + + $comment = $parsed['comment']; + + return compact('p', 'q', 'g', 'y', 'comment'); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + // from : + // string "ssh-dss" + // mpint p + // mpint q + // mpint g + // mpint y + $DSAPublicKey = Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $DSAPublicKey; + } + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $DSAPublicKey = 'ssh-dss ' . base64_encode($DSAPublicKey) . ' ' . $comment; + + return $DSAPublicKey; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => true]); + $privateKey = Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..757487377 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php @@ -0,0 +1,151 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use ParagonIE\ConstantTime\Base64; + +/** + * PKCS#1 Formatted DSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); + if (is_array($key)) { + return $key; + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAPrivateKey::MAP); + if (is_array($key)) { + return $key; + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); + if (is_array($key)) { + return $key; + } + + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + /** + * Convert DSA parameters to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @return string + */ + public static function saveParameters(BigInteger $p, BigInteger $q, BigInteger $g) + { + $key = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + + $key = ASN1::encodeDER($key, Maps\DSAParams::MAP); + + return "-----BEGIN DSA PARAMETERS-----\r\n" . + chunk_split(Base64::encode($key), 64) . + "-----END DSA PARAMETERS-----\r\n"; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $key = [ + 'version' => 0, + 'p' => $p, + 'q' => $q, + 'g' => $g, + 'y' => $y, + 'x' => $x + ]; + + $key = ASN1::encodeDER($key, Maps\DSAPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'DSA', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); + + return self::wrapPublicKey($key, 'DSA'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..71f66eb06 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php @@ -0,0 +1,170 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; + +/** + * PKCS#8 Formatted DSA Key Handler + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + * @access private + */ + const OID_NAME = 'id-dsa'; + + /** + * OID Value + * + * @var string + * @access private + */ + const OID_VALUE = '1.2.840.10040.4.1'; + + /** + * Child OIDs loaded + * + * @var bool + * @access private + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $isPublic = strpos($key, 'PUBLIC') !== false; + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + switch (true) { + case !$isPublic && $type == 'publicKey': + throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); + case $isPublic && $type == 'privateKey': + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + $decoded = ASN1::decodeBER($key[$type]); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $var = $type == 'privateKey' ? 'x' : 'y'; + $components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); + if (!$components[$var] instanceof BigInteger) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (isset($key['meta'])) { + $components['meta'] = $key['meta']; + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $params = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($x, Maps\DSAPublicKey::MAP); + return self::wrapPrivateKey($key, [], $params, $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) + { + $params = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); + return self::wrapPublicKey($key, $params); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..5f71e6840 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php @@ -0,0 +1,118 @@ + 160 kinda useless, hence this handlers not supporting such keys. + * + * PHP version 5 + * + * @category Crypt + * @package DSA + * @author Jim Wigginton + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; + +/** + * PuTTY Formatted DSA Key Handler + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +abstract class PuTTY extends Progenitor +{ + /** + * Public Handler + * + * @var string + * @access private + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH'; + + /** + * Algorithm Identifier + * + * @var array + * @access private + */ + protected static $types = ['ssh-dss']; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + extract($components); + unset($components['public'], $components['private']); + + list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $public); + list($x) = Strings::unpackSSH2('i', $private); + + return compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = false, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + $public = Strings::packSSH2('iiii', $p, $q, $g, $y); + $private = Strings::packSSH2('i', $x); + + return self::wrapPrivateKey($public, $private, 'ssh-dsa', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dsa'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php new file mode 100644 index 000000000..04eba721b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php @@ -0,0 +1,92 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; + +/** + * Raw DSA Key Handler + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param array $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); + } + + switch (true) { + case !isset($key['p']) || !isset($key['q']) || !isset($key['g']): + case !$key['p'] instanceof BigInteger: + case !$key['q'] instanceof BigInteger: + case !$key['g'] instanceof BigInteger: + case !isset($key['x']) && !isset($key['y']): + case isset($key['x']) && !$key['x'] instanceof BigInteger: + case isset($key['y']) && !$key['y'] instanceof BigInteger: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; + + return array_intersect_key($key, $options); + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '') + { + return compact('p', 'q', 'g', 'y', 'x'); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + return compact('p', 'q', 'g', 'y'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php new file mode 100644 index 000000000..42b3bbb99 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php @@ -0,0 +1,133 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; + +/** + * XML Formatted DSA Key Handler + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $use_errors = libxml_use_internal_errors(true); + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); + if (!$temp->length) { + continue; + } + $value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'p': // a prime modulus meeting the [DSS] requirements + // Parameters P, Q, and G can be public and common to a group of users. They might be known + // from application context. As such, they are optional but P and Q must either both appear + // or both be absent + $components['p'] = $value; + break; + case 'q': // an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 + $components['q'] = $value; + break; + case 'g': // an integer with certain properties with respect to P and Q + $components['g'] = $value; + break; + case 'y': // G**X mod P (where X is part of the private key and not made public) + $components['y'] = $value; + // the remaining options do not do anything + case 'j': // (P - 1) / Q + // Parameter J is available for inclusion solely for efficiency as it is calculatable from + // P and Q + case 'seed': // a DSA prime generation seed + // Parameters seed and pgenCounter are used in the DSA prime number generation algorithm + // specified in [DSS]. As such, they are optional but must either both be present or both + // be absent + case 'pgencounter': // a DSA prime generation counter + } + } + + libxml_use_internal_errors($use_errors); + + if (!isset($components['y'])) { + throw new \UnexpectedValueException('Key is missing y component'); + } + + switch (true) { + case !isset($components['p']): + case !isset($components['q']): + case !isset($components['g']): + return ['y' => $components['y']]; + } + + return $components; + } + + /** + * Convert a public key to the appropriate format + * + * See https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue + * + * @access public + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + return "\r\n" . + '

      ' . Base64::encode($p->toBytes()) . "

      \r\n" . + ' ' . Base64::encode($q->toBytes()) . "\r\n" . + ' ' . Base64::encode($g->toBytes()) . "\r\n" . + ' ' . Base64::encode($y->toBytes()) . "\r\n" . + '
      '; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php new file mode 100644 index 000000000..a9c29a346 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php @@ -0,0 +1,68 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\Math\BigInteger; +use phpseclib3\File\ASN1 as Encoder; +use phpseclib3\File\ASN1\Maps; + +/** + * ASN1 Signature Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @access public + * @param string $sig + * @return array|bool + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $decoded = Encoder::decodeBER($sig); + if (empty($decoded)) { + return false; + } + $components = Encoder::asn1map($decoded[0], Maps\DssSigValue::MAP); + + return $components; + } + + /** + * Returns a signature in the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return Encoder::encodeDER(compact('r', 's'), Maps\DssSigValue::MAP); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php new file mode 100644 index 000000000..e362e41bb --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php @@ -0,0 +1,29 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; + +/** + * Raw DSA Signature Handler + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +abstract class Raw extends Progenitor +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php new file mode 100644 index 000000000..39f1f6cef --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php @@ -0,0 +1,78 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; + +/** + * SSH2 Signature Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @access public + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $result = Strings::unpackSSH2('ss', $sig); + if ($result === false) { + return false; + } + list($type, $blob) = $result; + if ($type != 'ssh-dss' || strlen($blob) != 40) { + return false; + } + + return [ + 'r' => new BigInteger(substr($blob, 0, 20), 256), + 's' => new BigInteger(substr($blob, 20), 256) + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + if ($r->getLength() > 160 || $s->getLength() > 160) { + return false; + } + return Strings::packSSH2('ss', 'ssh-dss', + str_pad($r->toBytes(), 20, "\0", STR_PAD_LEFT) . + str_pad($s->toBytes(), 20, "\0", STR_PAD_LEFT) + ); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php new file mode 100644 index 000000000..3f36e9624 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php @@ -0,0 +1,40 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\DSA; + +/** + * DSA Parameters + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +class Parameters extends DSA +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->p, $this->q, $this->g, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php new file mode 100644 index 000000000..c976f2cf6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php @@ -0,0 +1,159 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common; + +/** + * DSA Private Key + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +class PrivateKey extends DSA implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * DSA secret exponent x + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $x; + + /** + * Returns the public key + * + * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key + * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. + * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this + * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g + * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified + * by getting a DSA PKCS8 public key: + * + * "openssl dsa -in private.dsa -pubout -outform PEM" + * + * ie. just swap out rsa with dsa in the rsa command above. + * + * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA + * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature + * without the parameters and the PKCS1 DSA public key format does not include the parameters. + * + * @see self::getPrivateKey() + * @access public + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + + $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); + + return DSA::loadFormat('PKCS8', $key) + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Create a signature + * + * @see self::verify() + * @access public + * @param string $message + * @return mixed + */ + public function sign($message) + { + $format = $this->sigFormat; + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $signature = ''; + $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); + + if ($result) { + if ($this->shortFormat == 'ASN1') { + return $signature; + } + + extract(ASN1Signature::load($signature)); + + return $format::save($r, $s); + } + } + + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + + while (true) { + $k = BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($this->q); + $temp = $h->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + if (!$s->equals(self::$zero)) { + break; + } + } + + // the following is an RFC6979 compliant implementation of deterministic DSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + + return $format::save($r, $s); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + + return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php new file mode 100644 index 000000000..156476f06 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php @@ -0,0 +1,91 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Crypt\Common; + +/** + * DSA Public Key + * + * @package DSA + * @author Jim Wigginton + * @access public + */ +class PublicKey extends DSA implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Verify a signature + * + * @see self::verify() + * @access public + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + $format = $this->sigFormat; + + $params = $format::load($signature); + if ($params === false || count($params) != 2) { + return false; + } + extract($params); + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; + + $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash()); + + if ($result != -1) { + return (bool) $result; + } + } + + $q_1 = $this->q->subtract(self::$one); + if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) { + return false; + } + + $w = $s->modInverse($this->q); + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + list(, $u1) = $h->multiply($w)->divide($this->q); + list(, $u2) = $r->multiply($w)->divide($this->q); + $v1 = $this->g->powMod($u1, $this->p); + $v2 = $this->y->powMod($u2, $this->p); + list(, $v) = $v1->multiply($v2)->divide($this->p); + list(, $v) = $v->divide($this->q); + + return $v->equals($r); + } + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php new file mode 100644 index 000000000..2c0ab1979 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php @@ -0,0 +1,477 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * @category Crypt + * @package EC + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\EC\PrivateKey; +use phpseclib3\Crypt\EC\PublicKey; +use phpseclib3\Crypt\EC\Parameters; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\Ed448; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\File\ASN1\Maps\ECParameters; +use phpseclib3\File\ASN1; +use phpseclib3\Math\BigInteger; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedOperationException; + +/** + * Pure-PHP implementation of EC. + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class EC extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + * @access private + */ + const ALGORITHM = 'EC'; + + /** + * Public Key QA + * + * @var object[] + */ + protected $QA; + + /** + * Curve + * + * @var \phpseclib3\Crypt\EC\BaseCurves\Base + */ + protected $curve; + + /** + * Signature Format + * + * @var string + * @access private + */ + protected $format; + + /** + * Signature Format (Short) + * + * @var string + * @access private + */ + protected $shortFormat; + + /** + * Curve Name + * + * @var string + */ + private $curveName; + + /** + * Curve Order + * + * Used for deterministic ECDSA + * + * @var \phpseclib3\Math\BigInteger + */ + protected $q; + + /** + * Alias for the private key + * + * Used for deterministic ECDSA. AsymmetricKey expects $x. I don't like x because + * with x you have x * the base point yielding an (x, y)-coordinate that is the + * public key. But the x is different depending on which side of the equal sign + * you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate. + * + * @var \phpseclib3\Math\BigInteger + */ + protected $x; + + /** + * Context + * + * @var string + */ + protected $context; + + /** + * Create public / private key pair. + * + * @access public + * @param string $curve + * @return \phpseclib3\Crypt\EC\PrivateKey + */ + public static function createKey($curve) + { + self::initialize_static_variables(); + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + $curve = strtolower($curve); + if (self::$engines['libsodium'] && $curve == 'ed25519' && function_exists('sodium_crypto_sign_keypair')) { + $kp = sodium_crypto_sign_keypair(); + + $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp)); + //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp)); + + $privatekey->curveName = 'Ed25519'; + //$publickey->curveName = $curve; + + return $privatekey; + } + + $privatekey = new PrivateKey; + + $curveName = $curve; + if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) { + $curveName = ucfirst($curveName); + } elseif (substr($curveName, 0, 10) == 'brainpoolp') { + $curveName = 'brainpoolP' . substr($curveName, 10); + } + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; + + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported'); + } + + $reflect = new \ReflectionClass($curve); + $curveName = $reflect->isFinal() ? + $reflect->getParentClass()->getShortName() : + $reflect->getShortName(); + + $curve = new $curve(); + $privatekey->dA = $dA = $curve->createRandomMultiplier(); + if ($curve instanceof Curve25519 && self::$engines['libsodium']) { + //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000'); + //$QA = sodium_crypto_scalarmult($dA->toBytes(), $r); + $QA = sodium_crypto_box_publickey_from_secretkey($dA->toBytes()); + $privatekey->QA = [$curve->convertInteger(new BigInteger(strrev($QA), 256))]; + } else { + $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA); + } + $privatekey->curve = $curve; + + //$publickey = clone $privatekey; + //unset($publickey->dA); + //unset($publickey->x); + + $privatekey->curveName = $curveName; + //$publickey->curveName = $curveName; + + if ($privatekey->curve instanceof TwistedEdwardsCurve) { + return $privatekey->withHash($curve::HASH); + } + + return $privatekey; + } + + /** + * OnLoad Handler + * + * @return bool + * @access protected + * @param array $components + */ + protected static function onLoad($components) + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (!isset($components['dA']) && !isset($components['QA'])) { + $new = new Parameters; + $new->curve = $components['curve']; + return $new; + } + + $new = isset($components['dA']) ? + new PrivateKey : + new PublicKey; + $new->curve = $components['curve']; + $new->QA = $components['QA']; + + if (isset($components['dA'])) { + $new->dA = $components['dA']; + } + + if ($new->curve instanceof TwistedEdwardsCurve) { + return $new->withHash($components['curve']::HASH); + } + + return $new; + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); + $this->shortFormat = 'ASN1'; + + parent::__construct(); + } + + /** + * Returns the curve + * + * Returns a string if it's a named curve, an array if not + * + * @access public + * @return string|array + */ + public function getCurve() + { + if ($this->curveName) { + return $this->curveName; + } + + if ($this->curve instanceof MontgomeryCurve) { + $this->curveName = $this->curve instanceof Curve25519 ? 'Curve25519' : 'Curve448'; + return $this->curveName; + } + + if ($this->curve instanceof TwistedEdwardsCurve) { + $this->curveName = $this->curve instanceof Ed25519 ? 'Ed25519' : 'Ed448'; + return $this->curveName; + } + + $params = $this->getParameters()->toString('PKCS8', ['namedCurve' => true]); + $decoded = ASN1::extractBER($params); + $decoded = ASN1::decodeBER($decoded); + $decoded = ASN1::asn1map($decoded[0], ECParameters::MAP); + if (isset($decoded['namedCurve'])) { + $this->curveName = $decoded['namedCurve']; + return $decoded['namedCurve']; + } + + if (!$namedCurves) { + PKCS1::useSpecifiedCurve(); + } + + return $decoded; + } + + /** + * Returns the key size + * + * Quoting https://tools.ietf.org/html/rfc5656#section-2, + * + * "The size of a set of elliptic curve domain parameters on a prime + * curve is defined as the number of bits in the binary representation + * of the field order, commonly denoted by p. Size on a + * characteristic-2 curve is defined as the number of bits in the binary + * representation of the field, commonly denoted by m. A set of + * elliptic curve domain parameters defines a group of order n generated + * by a base point P" + * + * @access public + * @return int + */ + public function getLength() + { + return $this->curve->getLength(); + } + + /** + * Returns the current engine being used + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @access public + * @return string + */ + public function getEngine() + { + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context) ? + 'libsodium' : 'PHP'; + } + + return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? + 'OpenSSL' : 'PHP'; + } + + /** + * Returns the public key coordinates as a string + * + * Used by ECDH + * + * @return string + */ + public function getEncodedCoordinates() + { + if ($this->curve instanceof MontgomeryCurve) { + return strrev($this->QA[0]->toBytes(true)); + } + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve->encodePoint($this->QA); + } + return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true); + } + + /** + * Returns the parameters + * + * @see self::getPublicKey() + * @access public + * @param string $type optional + * @return mixed + */ + public function getParameters($type = 'PKCS1') + { + $type = self::validatePlugin('Keys', $type, 'saveParameters'); + + $key = $type::saveParameters($this->curve); + + return EC::load($key, 'PKCS1') + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @access public + * @param string $format + */ + public function withSignatureFormat($format) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $new = clone $this; + $new->shortFormat = $format; + $new->sigFormat = self::validatePlugin('Signature', $format); + return $new; + } + + /** + * Returns the signature format currently being used + * + * @access public + */ + public function getSignatureFormat() + { + return $this->shortFormat; + } + + /** + * Sets the context + * + * Used by Ed25519 / Ed448. + * + * @see self::sign() + * @see self::verify() + * @access public + * @param string $context optional + */ + public function withContext($context = null) + { + if (!$this->curve instanceof TwistedEdwardsCurve) { + throw new UnsupportedCurveException('Only Ed25519 and Ed448 support contexts'); + } + + $new = clone $this; + if (!isset($context)) { + $new->context = null; + return $new; + } + if (!is_string($context)) { + throw new \InvalidArgumentException('setContext expects a string'); + } + if (strlen($context) > 255) { + throw new \LengthException('The context is supposed to be, at most, 255 bytes long'); + } + $new->context = $context; + return $new; + } + + /** + * Returns the signature format currently being used + * + * @access public + */ + public function getContext() + { + return $this->context; + } + + /** + * Determines which hashing function should be used + * + * @access public + * @param string $hash + */ + public function withHash($hash) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + if ($this->curve instanceof Ed25519 && $hash != 'sha512') { + throw new UnsupportedAlgorithmException('Ed25519 only supports sha512 as a hash'); + } + if ($this->curve instanceof Ed448 && $hash != 'shake256-912') { + throw new UnsupportedAlgorithmException('Ed448 only supports shake256 with a length of 114 bytes'); + } + + return parent::withHash($hash); + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + if ($this->curve instanceof MontgomeryCurve) { + return ''; + } + + return parent::__toString(); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php new file mode 100644 index 000000000..6102c0630 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php @@ -0,0 +1,220 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\Common\FiniteField; +use phpseclib3\Math\BigInteger; + +/** + * Base + * + * @package Prime + * @author Jim Wigginton + * @access public + */ +abstract class Base +{ + /** + * Doubles + * + * @var object[] + */ + protected $doubles; + + /** + * NAF Points + * + * @var int[] + */ + private $naf; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Finite Field Integer factory + * + * @var \phpseclib3\Math\FiniteField\Integer + */ + protected $factory; + + /** + * Returns a random integer + * + * @return object + */ + public function randomInteger() + { + return $this->factory->randomInteger(); + } + + /** + * Converts a BigInteger to a FiniteField integer + * + * @return object + */ + public function convertInteger(BigInteger $x) + { + return $this->factory->newInteger($x); + } + + /** + * Returns the length, in bytes, of the modulo + * + * @return integer + */ + public function getLengthInBytes() + { + return $this->factory->getLengthInBytes(); + } + + /** + * Returns the length, in bits, of the modulo + * + * @return integer + */ + public function getLength() + { + return $this->factory->getLength(); + } + + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, FiniteField\Integer $d) + { + $alreadyInternal = isset($p[2]); + $r = $alreadyInternal ? + [[], $p] : + [[], $this->convertToInternal($p)]; + + $d = $d->toBits(); + for ($i = 0; $i < strlen($d); $i++) { + $d_i = (int) $d[$i]; + $r[1 - $d_i] = $this->addPoint($r[0], $r[1]); + $r[$d_i] = $this->doublePoint($r[$d_i]); + } + + return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]); + } + + /** + * Creates a random scalar multiplier + * + * @return FiniteField + */ + public function createRandomMultiplier() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $dA = BigInteger::randomRange($one, $this->order->subtract($one)); + return $this->factory->newInteger($dA); + } + + /** + * Sets the Order + */ + public function setOrder(BigInteger $order) + { + $this->order = $order; + } + + /** + * Returns the Order + * + * @return \phpseclib3\Math\BigInteger + */ + public function getOrder() + { + return $this->order; + } + + /** + * Use a custom defined modular reduction function + * + * @return object + */ + public function setReduction(callable $func) + { + $this->factory->setReduction($func); + } + + /** + * Returns the affine point + * + * @return object[] + */ + public function convertToAffine(array $p) + { + return $p; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return object[] + */ + public function convertToInternal(array $p) + { + return $p; + } + + /** + * Negates a point + * + * @return object[] + */ + public function negatePoint(array $p) + { + $temp = [ + $p[0], + $p[1]->negate() + ]; + if (isset($p[2])) { + $temp[] = $p[2]; + } + return $temp; + } + + /** + * Multiply and Add Points + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $p1 = $this->convertToInternal($points[0]); + $p2 = $this->convertToInternal($points[1]); + $p1 = $this->multiplyPoint($p1, $scalars[0]); + $p2 = $this->multiplyPoint($p2, $scalars[1]); + $r = $this->addPoint($p1, $p2); + return $this->convertToAffine($r); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php new file mode 100644 index 000000000..d984ba4b4 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php @@ -0,0 +1,378 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField\Integer as BinaryInteger; + +/** + * Curves over y^2 + x*y = x^3 + a*x^2 + b + * + * @package Binary + * @author Jim Wigginton + * @access public + */ +class Binary extends Base +{ + /** + * Binary Field Integer factory + * + * @var \phpseclib3\Math\BinaryField + */ + protected $factory; + + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(...$modulo) + { + $this->modulo = $modulo; + $this->factory = new BinaryField(...$modulo); + + $this->one = $this->factory->newInteger("\1"); + } + + /** + * Set coefficients a and b + * + * @param string $a + * @param string $b + */ + public function setCoefficients($a, $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger(pack('H*', $a)); + $this->b = $this->factory->newInteger(pack('H*', $b)); + } + + /** + * Set x and y coordinates for the base point + * + * @param string|BinaryInteger $x + * @param string|BinaryInteger $y + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !is_string($x) && !$x instanceof BinaryInteger: + throw new \UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); + case !is_string($y) && !$y instanceof BinaryInteger: + throw new \UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x, + is_string($y) ? $this->factory->newInteger(pack('H*', $y)) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $o1 = $z1->multiply($z1); + $b = $x2->multiply($o1); + + if ($z2->equals($this->one)) { + $d = $y2->multiply($o1)->multiply($z1); + $e = $x1->add($b); + $f = $y1->add($d); + $z3 = $e->multiply($z1); + $h = $f->multiply($x2)->add($z3->multiply($y2)); + $i = $f->add($z3); + $g = $z3->multiply($z3); + $p1 = $this->a->multiply($g); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($h)); + + return [$x3, $y3, $z3]; + } + + $o2 = $z2->multiply($z2); + $a = $x1->multiply($o2); + $c = $y1->multiply($o2)->multiply($z2); + $d = $y2->multiply($o1)->multiply($z1); + $e = $a->add($b); + $f = $c->add($d); + $g = $e->multiply($z1); + $h = $f->multiply($x2)->add($g->multiply($y2)); + $z3 = $g->multiply($z2); + $i = $f->add($z3); + $p1 = $this->a->multiply($z3->multiply($z3)); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h)); + + return [$x3, $y3, $z3]; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + + list($x1, $y1, $z1) = $p; + + $a = $x1->multiply($x1); + $b = $a->multiply($a); + + if ($z1->equals($this->one)) { + $x3 = $b->add($this->b); + $z3 = clone $x1; + $p1 = $a->add($y1)->add($z3)->multiply($this->b); + $p2 = $a->add($y1)->multiply($b); + $y3 = $p1->add($p2); + + return [$x3, $y3, $z3]; + } + + $c = $z1->multiply($z1); + $d = $c->multiply($c); + $x3 = $b->add($this->b->multiply($d->multiply($d))); + $z3 = $x1->multiply($c); + $p1 = $b->multiply($z3); + $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3); + $y3 = $p1->add($p2); + + return [$x3, $y3, $z3]; + } + + /** + * Returns the X coordinate and the derived Y coordinate + * + * Not supported because it is covered by patents. + * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html , + * + * "Due to patent issues the compressed option is disabled by default for binary curves + * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at + * compile time." + * + * @return array + */ + public function derivePoint($m) + { + throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $lhs = $lhs->add($x->multiply($y)); + $x2 = $x->multiply($x); + $x3 = $x2->multiply($x); + $rhs = $x3->add($this->a->multiply($x2))->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [ + $x->multiply($z2), + $y->multiply($z2)->multiply($z) + ]; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p['fresh'] = true; + return $p; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php new file mode 100644 index 000000000..0a93f5126 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php @@ -0,0 +1,325 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over y^2 = x^3 + b + * + * @package KoblitzPrime + * @author Jim Wigginton + * @access public + */ +class KoblitzPrime extends Prime +{ + // don't overwrite setCoefficients() with one that only accepts one parameter so that + // one might be able to switch between KoblitzPrime and Prime more easily (for benchmarking + // purposes). + + /** + * Multiply and Add Points + * + * Uses a efficiently computable endomorphism to achieve a slight speedup + * + * Adapted from https://git.io/vxbrP + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + static $zero, $one, $two; + if (!isset($two)) { + $two = new BigInteger(2); + $one = new BigInteger(1); + } + + if (!isset($this->beta)) { + // get roots + $inv = $this->one->divide($this->two)->negate(); + $s = $this->three->negate()->squareRoot()->multiply($inv); + $betas = [ + $inv->add($s), + $inv->subtract($s) + ]; + $this->beta = $betas[0]->compare($betas[1]) < 0 ? $betas[0] : $betas[1]; + //echo strtoupper($this->beta->toHex(true)) . "\n"; exit; + } + + if (!isset($this->basis)) { + $factory = new PrimeField($this->order); + $tempOne = $factory->newInteger($one); + $tempTwo = $factory->newInteger($two); + $tempThree = $factory->newInteger(new BigInteger(3)); + + $inv = $tempOne->divide($tempTwo)->negate(); + $s = $tempThree->negate()->squareRoot()->multiply($inv); + + $lambdas = [ + $inv->add($s), + $inv->subtract($s) + ]; + + $lhs = $this->multiplyPoint($this->p, $lambdas[0])[0]; + $rhs = $this->p[0]->multiply($this->beta); + $lambda = $lhs->equals($rhs) ? $lambdas[0] : $lambdas[1]; + + $this->basis = static::extendedGCD($lambda->toBigInteger(), $this->order); + ///* + foreach ($this->basis as $basis) { + echo strtoupper($basis['a']->toHex(true)) . "\n"; + echo strtoupper($basis['b']->toHex(true)) . "\n\n"; + } + exit; + //*/ + } + + $npoints = $nscalars = []; + for ($i = 0; $i < count($points); $i++) { + $p = $points[$i]; + $k = $scalars[$i]->toBigInteger(); + + // begin split + list($v1, $v2) = $this->basis; + + $c1 = $v2['b']->multiply($k); + list($c1, $r) = $c1->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c1 = $c1->add($one); + } + + $c2 = $v1['b']->negate()->multiply($k); + list($c2, $r) = $c2->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c2 = $c2->add($one); + } + + $p1 = $c1->multiply($v1['a']); + $p2 = $c2->multiply($v2['a']); + $q1 = $c1->multiply($v1['b']); + $q2 = $c2->multiply($v2['b']); + + $k1 = $k->subtract($p1)->subtract($p2); + $k2 = $q1->add($q2)->negate(); + // end split + + $beta = [ + $p[0]->multiply($this->beta), + $p[1], + clone $this->one + ]; + + if (isset($p['naf'])) { + $beta['naf'] = array_map(function($p) { + return [ + $p[0]->multiply($this->beta), + $p[1], + clone $this->one + ]; + }, $p['naf']); + $beta['nafwidth'] = $p['nafwidth']; + } + + if ($k1->isNegative()) { + $k1 = $k1->negate(); + $p = $this->negatePoint($p); + } + + if ($k2->isNegative()) { + $k2 = $k2->negate(); + $beta = $this->negatePoint($beta); + } + + $pos = 2 * $i; + $npoints[$pos] = $p; + $nscalars[$pos] = $this->factory->newInteger($k1); + + $pos++; + $npoints[$pos] = $beta; + $nscalars[$pos] = $this->factory->newInteger($k2); + } + + return parent::multiplyAddPoints($npoints, $nscalars); + } + + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0]); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + + /** + * Doubles a jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x1, $y1, $z1) = $p; + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $b->multiply($b); + $d = $x1->add($b); + $d = $d->multiply($d)->subtract($a)->subtract($c)->multiply($this->two); + $e = $this->three->multiply($a); + $f = $e->multiply($e); + $x3 = $f->subtract($this->two->multiply($d)); + $y3 = $e->multiply($d->subtract($x3))->subtract( + $this->eight->multiply($c)); + $z3 = $this->two->multiply($y1)->multiply($z1); + return [$x3, $y3, $z3]; + } + + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x1, $y1) = $p; + $xx = $x1->multiply($x1); + $yy = $y1->multiply($y1); + $yyyy = $yy->multiply($yy); + $s = $x1->add($yy); + $s = $s->multiply($s)->subtract($xx)->subtract($yyyy)->multiply($this->two); + $m = $this->three->multiply($xx); + $t = $m->multiply($m)->subtract($this->two->multiply($s)); + $x3 = $t; + $y3 = $s->subtract($t); + $y3 = $m->multiply($y3)->subtract($this->eight->multiply($yyyy)); + $z3 = $this->two->multiply($y1); + return [$x3, $y3, $z3]; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($x)->multiply($x); + $rhs = $temp->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Calculates the parameters needed from the Euclidean algorithm as discussed at + * http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=148 + * + * @param BigInteger $u + * @param BigInteger $v + * @return BigInteger[] + */ + protected static function extendedGCD(BigInteger $u, BigInteger $v) + { + $one = new BigInteger(1); + $zero = new BigInteger(); + + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + + $stop = $v->bitwise_rightShift($v->getLength() >> 1); + + $a1 = clone $zero; + $b1 = clone $zero; + $a2 = clone $zero; + $b2 = clone $zero; + + $postGreatestIndex = 0; + + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + + if ($v->compare($stop) > 0) { + $a0 = $v; + $b0 = $c; + } else { + $postGreatestIndex++; + } + + if ($postGreatestIndex == 1) { + $a1 = $v; + $b1 = $c->negate(); + } + + if ($postGreatestIndex == 2) { + $rhs = $a0->multiply($a0)->add($b0->multiply($b0)); + $lhs = $v->multiply($v)->add($b->multiply($b)); + if ($lhs->compare($rhs) <= 0) { + $a2 = $a0; + $b2 = $b0->negate(); + } else { + $a2 = $v; + $b2 = $c->negate(); + } + + break; + } + } + + return [ + ['a' => $a1, 'b' => $b1], + ['a' => $a2, 'b' => $b2] + ]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php new file mode 100644 index 000000000..b4bba650a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php @@ -0,0 +1,285 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over y^2 = x^3 + a*x + x + * + * @package EC + * @author Jim Wigginton + * @access public + */ +class Montgomery extends Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeField + */ + protected $factory; + + /** + * Cofficient for x + * + * @var object + */ + protected $a; + + /** + * Constant used for point doubling + * + * @var object + */ + protected $a24; + + /** + * The Number Zero + * + * @var object + */ + protected $zero; + + /** + * The Number One + * + * @var object + */ + protected $one; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->zero = $this->factory->newInteger(new BigInteger()); + $this->one = $this->factory->newInteger(new BigInteger(1)); + } + + /** + * Set coefficients a + */ + public function setCoefficients(BigInteger $a) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $two = $this->factory->newInteger(new BigInteger(2)); + $four = $this->factory->newInteger(new BigInteger(4)); + $this->a24 = $this->a->subtract($two)->divide($four); + } + + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Doubles and adds a point on a curve + * + * See https://tools.ietf.org/html/draft-ietf-tls-curve25519-01#appendix-A.1.3 + * + * @return FiniteField[][] + */ + private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + return []; + } + + if (!isset($p[1])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); + } + + list($x2, $z2) = $p; + list($x3, $z3) = $q; + + $a = $x2->add($z2); + $aa = $a->multiply($a); + $b = $x2->subtract($z2); + $bb = $b->multiply($b); + $e = $aa->subtract($bb); + $c = $x3->add($z3); + $d = $x3->subtract($z3); + $da = $d->multiply($a); + $cb = $c->multiply($b); + $temp = $da->add($cb); + $x5 = $temp->multiply($temp); + $temp = $da->subtract($cb); + $z5 = $x1->multiply($temp->multiply($temp)); + $x4 = $aa->multiply($bb); + $temp = static::class == Curve25519::class ? $bb : $aa; + $z4 = $e->multiply($temp->add($this->a24->multiply($e))); + + return [ + [$x4, $z4], + [$x5, $z5] + ]; + } + + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, Integer $d) + { + $p1 = [$this->one, $this->zero]; + $alreadyInternal = isset($x[1]); + $p2 = $this->convertToInternal($p); + $x = $p[0]; + + $b = $d->toBits(); + $b = str_pad($b, 256, '0', STR_PAD_LEFT); + for ($i = 0; $i < strlen($b); $i++) { + $b_i = (int) $b[$i]; + if ($b_i) { + list($p2, $p1) = $this->doubleAndAddPoint($p2, $p1, $x); + } else { + list($p1, $p2) = $this->doubleAndAddPoint($p1, $p2, $x); + } + } + + return $alreadyInternal ? $p1 : $this->convertToAffine($p1); + } + + /** + * Converts an affine point to an XZ coordinate + * + * From https://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html + * + * XZ coordinates represent x y as X Z satsfying the following equations: + * + * x=X/Z + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one]; + } + + if (isset($p[1])) { + return $p; + } + + $p[1] = clone $this->one; + + return $p; + } + + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[1])) { + return $p; + } + list($x, $z) = $p; + return [$x->divide($z)]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php new file mode 100644 index 000000000..07606cfa7 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php @@ -0,0 +1,774 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over y^2 = x^3 + a*x + b + * + * @package Prime + * @author Jim Wigginton + * @access public + */ +class Prime extends Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeFields + */ + protected $factory; + + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + + /** + * The number three over the specified finite field + * + * @var object + */ + protected $three; + + /** + * The number four over the specified finite field + * + * @var object + */ + protected $four; + + /** + * The number eight over the specified finite field + * + * @var object + */ + protected $eight; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->two = $this->factory->newInteger(new BigInteger(2)); + $this->three = $this->factory->newInteger(new BigInteger(3)); + // used by jacobian coordinates + $this->one = $this->factory->newInteger(new BigInteger(1)); + $this->four = $this->factory->newInteger(new BigInteger(4)); + $this->eight = $this->factory->newInteger(new BigInteger(8)); + } + + /** + * Set coefficients a and b + */ + public function setCoefficients(BigInteger $a, BigInteger $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->b = $this->factory->newInteger($b); + } + + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Adds two "fresh" jacobian form on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedXY(array $p, array $q) + { + list($u1, $s1) = $p; + list($u2, $s2) = $q; + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3))->subtract( + $s1->multiply($h3)); + return [$x3, $y3, $h]; + } + + /** + * Adds one "fresh" jacobian form on the curve + * + * The second parameter should be the "fresh" one + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedX(array $p, array $q) + { + list($u1, $s1, $z1) = $p; + list($x2, $y2) = $q; + + $z12 = $z1->multiply($z1); + + $u2 = $x2->multiply($z12); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3))->subtract( + $s1->multiply($h3)); + $z3 = $h->multiply($z1); + return [$x3, $y3, $z3]; + } + + /** + * Adds two jacobian coordinates on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPoint(array $p, array $q) + { + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $z12 = $z1->multiply($z1); + $z22 = $z2->multiply($z2); + + $u1 = $x1->multiply($z22); + $u2 = $x2->multiply($z12); + $s1 = $y1->multiply($z22->multiply($z2)); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3))->subtract( + $s1->multiply($h3)); + $z3 = $h->multiply($z1)->multiply($z2); + return [$x3, $y3, $z3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + // use jacobian coordinates + if (isset($p[2]) && isset($q[2])) { + if (isset($p['fresh']) && isset($q['fresh'])) { + return $this->jacobianAddPointMixedXY($p, $q); + } + if (isset($p['fresh'])) { + return $this->jacobianAddPointMixedX($q, $p); + } + if (isset($q['fresh'])) { + return $this->jacobianAddPointMixedX($p, $q); + } + return $this->jacobianAddPoint($p, $q); + } + + if (isset($p[2]) || isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + if (!$p[1]->equals($q[1])) { + return []; + } else { // eg. doublePoint + list($numerator, $denominator) = $this->doublePointHelper($p); + } + } else { + $numerator = $q[1]->subtract($p[1]); + $denominator = $q[0]->subtract($p[0]); + } + $slope = $numerator->divide($denominator); + $x = $slope->multiply($slope)->subtract($p[0])->subtract($q[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + + return [$x, $y]; + } + + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0])->add($this->a); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + + /** + * Doubles a jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x, $y, $z) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $z2 = $z->multiply($z); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m2 = $this->a->multiply($z2->multiply($z2)); + $m = $m1->add($m2); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract( + $this->eight->multiply($y2->multiply($y2))); + $z1 = $this->two->multiply($y)->multiply($z); + return [$x1, $y1, $z1]; + } + + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m = $m1->add($this->a); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract( + $this->eight->multiply($y2->multiply($y2))); + $z1 = $this->two->multiply($y); + return [$x1, $y1, $z1]; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + // use jacobian coordinates + if (isset($p[2])) { + if (isset($p['fresh'])) { + return $this->jacobianDoublePointMixed($p); + } + return $this->jacobianDoublePoint($p); + } + + list($numerator, $denominator) = $this->doublePointHelper($p); + + $slope = $numerator->divide($denominator); + + $x = $slope->multiply($slope)->subtract($p[0])->subtract($p[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + + return [$x, $y]; + } + + /** + * Returns the X coordinate and the derived Y coordinate + * + * @return array + */ + public function derivePoint($m) + { + $y = ord(Strings::shift($m)); + $x = new BigInteger($m, 256); + $xp = $this->convertInteger($x); + switch ($y) { + case 2: $ypn = false; break; + case 3: $ypn = true; break; + default: + throw new \RuntimeException('Coordinate not in recognized format'); + } + $temp = $xp->multiply($this->a); + $temp = $xp->multiply($xp)->multiply($xp)->add($temp); + $temp = $temp->add($this->b); + $b = $temp->squareRoot(); + if (!$b) { + throw new \RuntimeException('Unable to derive Y coordinate'); + } + $bn = $b->isOdd(); + $yp = $ypn == $bn ? $b : $b->negate(); + return [$xp, $yp]; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($this->a); + $temp = $x->multiply($x)->multiply($x)->add($temp); + $rhs = $temp->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + + /** + * Multiply and Add Points + * + * Adapted from https://git.io/vxPUH + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $length = count($points); + + foreach ($points as &$point) { + $point = $this->convertToInternal($point); + } + + $wnd = [$this->getNAFPoints($points[0], 7)]; + $wndWidth = [isset($points[0]['nafwidth']) ? $points[0]['nafwidth'] : 7]; + for ($i = 1; $i < $length; $i++) { + $wnd[] = $this->getNAFPoints($points[$i], 1); + $wndWidth[] = isset($points[$i]['nafwidth']) ? $points[$i]['nafwidth'] : 1; + } + + $naf = []; + + // comb all window NAFs + + $max = 0; + for ($i = $length - 1; $i >= 1; $i-= 2) { + $a = $i - 1; + $b = $i; + if ($wndWidth[$a] != 1 || $wndWidth[$b] != 1) { + $naf[$a] = $scalars[$a]->getNAF($wndWidth[$a]); + $naf[$b] = $scalars[$b]->getNAF($wndWidth[$b]); + $max = max(count($naf[$a]), count($naf[$b]), $max); + continue; + } + + $comb = [ + $points[$a], // 1 + null, // 3 + null, // 5 + $points[$b] // 7 + ]; + + $comb[1] = $this->addPoint($points[$a], $points[$b]); + $comb[2] = $this->addPoint($points[$a], $this->negatePoint($points[$b])); + + $index = [ + -3, /* -1 -1 */ + -1, /* -1 0 */ + -5, /* -1 1 */ + -7, /* 0 -1 */ + 0, /* 0 -1 */ + 7, /* 0 1 */ + 5, /* 1 -1 */ + 1, /* 1 0 */ + 3 /* 1 1 */ + ]; + + $jsf = self::getJSFPoints($scalars[$a], $scalars[$b]); + + $max = max(count($jsf[0]), $max); + if ($max > 0) { + $naf[$a] = array_fill(0, $max, 0); + $naf[$b] = array_fill(0, $max, 0); + } else { + $naf[$a] = []; + $naf[$b] = []; + } + + for ($j = 0; $j < $max; $j++) { + $ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0; + $jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0; + + $naf[$a][$j] = $index[3 * ($ja + 1) + $jb + 1]; + $naf[$b][$j] = 0; + $wnd[$a] = $comb; + } + } + + $acc = []; + $temp = [0, 0, 0, 0]; + for ($i = $max; $i >= 0; $i--) { + $k = 0; + while ($i >= 0) { + $zero = true; + for ($j = 0; $j < $length; $j++) { + $temp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0; + if ($temp[$j] != 0) { + $zero = false; + } + } + if (!$zero) { + break; + } + $k++; + $i--; + } + + if ($i >= 0) { + $k++; + } + while ($k--) { + $acc = $this->doublePoint($acc); + } + + if ($i < 0) { + break; + } + + for ($j = 0; $j < $length; $j++) { + $z = $temp[$j]; + $p = null; + if ($z == 0) { + continue; + } + $p = $z > 0 ? + $wnd[$j][($z - 1) >> 1] : + $this->negatePoint($wnd[$j][(-$z - 1) >> 1]); + $acc = $this->addPoint($acc, $p); + } + } + + return $this->convertToAffine($acc); + } + + /** + * Precomputes NAF points + * + * Adapted from https://git.io/vxY1f + * + * @return int[] + */ + private function getNAFPoints($point, $wnd) + { + if (isset($point['naf'])) { + return $point['naf']; + } + + $res = [$point]; + $max = (1 << $wnd) - 1; + $dbl = $max == 1 ? null : $this->doublePoint($point); + for ($i = 1; $i < $max; $i++) { + $res[] = $this->addPoint($res[$i - 1], $dbl); + } + + $point['naf'] = $res; + + /* + $str = ''; + foreach ($res as $re) { + $re[0] = bin2hex($re[0]->toBytes()); + $re[1] = bin2hex($re[1]->toBytes()); + $str.= " ['$re[0]', '$re[1]'],\r\n"; + } + file_put_contents('temp.txt', $str); + exit; + */ + + return $res; + } + + /** + * Precomputes points in Joint Sparse Form + * + * Adapted from https://git.io/vxrpD + * + * @return int[] + */ + private static function getJSFPoints(Integer $k1, Integer $k2) + { + static $three; + if (!isset($three)) { + $three = new BigInteger(3); + } + + $jsf = [[], []]; + $k1 = $k1->toBigInteger(); + $k2 = $k2->toBigInteger(); + $d1 = 0; + $d2 = 0; + + while ($k1->compare(new BigInteger(-$d1)) > 0 || $k2->compare(new BigInteger(-$d2)) > 0) { + // first phase + $m14 = $k1->testBit(0) + 2 * $k1->testBit(1); + $m14+= $d1; + $m14&= 3; + + $m24 = $k2->testBit(0) + 2 * $k2->testBit(1); + $m24+= $d2; + $m24&= 3; + + if ($m14 == 3) { + $m14 = -1; + } + if ($m24 == 3) { + $m24 = -1; + } + + $u1 = 0; + if ($m14 & 1) { // if $m14 is odd + $m8 = $k1->testBit(0) + 2 * $k1->testBit(1) + 4 * $k1->testBit(2); + $m8+= $d1; + $m8&= 7; + $u1 = ($m8 == 3 || $m8 == 5) && $m24 == 2 ? -$m14 : $m14; + } + $jsf[0][] = $u1; + + $u2 = 0; + if ($m24 & 1) { // if $m24 is odd + $m8 = $k2->testBit(0) + 2 * $k2->testBit(1) + 4 * $k2->testBit(2); + $m8+= $d2; + $m8&= 7; + $u2 = ($m8 == 3 || $m8 == 5) && $m14 == 2 ? -$m24 : $m24; + } + $jsf[1][] = $u2; + + // second phase + if (2 * $d1 == $u1 + 1) { + $d1 = 1 - $d1; + } + if (2 * $d2 == $u2 + 1) { + $d2 = 1 - $d2; + } + $k1 = $k1->bitwise_rightShift(1); + $k2 = $k2->bitwise_rightShift(1); + } + + return $jsf; + } + + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [ + $x->multiply($z2), + $y->multiply($z2)->multiply($z) + ]; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p['fresh'] = true; + return $p; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php new file mode 100644 index 000000000..ff4ff2d4f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php @@ -0,0 +1,219 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 + * + * @package Prime + * @author Jim Wigginton + * @access public + */ +class TwistedEdwards extends Base +{ + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * Cofficient for x^2 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^2*y^2 + * + * @var object + */ + protected $d; + + /** + * Base Point + * + * @var object[] + */ + protected $p; + + /** + * The number zero over the specified finite field + * + * @var object + */ + protected $zero; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->zero = $this->factory->newInteger(new BigInteger(0)); + $this->one = $this->factory->newInteger(new BigInteger(1)); + $this->two = $this->factory->newInteger(new BigInteger(2)); + } + + /** + * Set coefficients a and b + */ + public function setCoefficients(BigInteger $a, BigInteger $d) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->d = $this->factory->newInteger($d); + } + + /** + * Set x and y coordinates for the base point + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getD() + { + return $this->d; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + return [ + $x->multiply($z), + $y->multiply($z) + ]; + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + + $lhs = $this->a->multiply($x2)->add($y2); + $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); + + return $lhs->equals($rhs); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php new file mode 100644 index 000000000..06842d8cd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php @@ -0,0 +1,64 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use phpseclib3\Math\BigInteger; + +class Curve25519 extends Montgomery +{ + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->a24 = $this->factory->newInteger(new BigInteger('121666')); + $this->p = [$this->factory->newInteger(new BigInteger(9))]; + // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed + $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + + /* + $this->setCoefficients( + new BigInteger('486662'), // a + ); + $this->setBasePoint( + new BigInteger(9), + new BigInteger('14781619447589544791020593568409986887264606134616475288964881837755586237401') + ); + */ + } + + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, Integer $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + + $d = $d->toBytes(); + $d&= "\xF8" . str_repeat("\xFF", 30) . "\x7F"; + $d = strrev($d); + $d|= "\x40"; + $d = $this->factory->newInteger(new BigInteger($d, -256)); + + return parent::multiplyPoint($p, $d); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php new file mode 100644 index 000000000..7dcf70847 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php @@ -0,0 +1,71 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use phpseclib3\Math\BigInteger; + +class Curve448 extends Montgomery +{ + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->a24 = $this->factory->newInteger(new BigInteger('39081')); + $this->p = [$this->factory->newInteger(new BigInteger(5))]; + // 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d + $this->setOrder(new BigInteger( + '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16)); + + /* + $this->setCoefficients( + new BigInteger('156326'), // a + ); + $this->setBasePoint( + new BigInteger(5), + new BigInteger( + '355293926785568175264127502063783334808976399387714271831880898' . + '435169088786967410002932673765864550910142774147268105838985595290' . + '606362') + ); + */ + } + + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, Integer $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + + $d = $d->toBytes(); + $d[0] = $d[0] & "\xFC"; + $d = strrev($d); + $d|= "\x80"; + $d = $this->factory->newInteger(new BigInteger($d, 256)); + + return parent::multiplyPoint($p, $d); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php new file mode 100644 index 000000000..d4c3e37a1 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php @@ -0,0 +1,334 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; + +class Ed25519 extends TwistedEdwards +{ + const HASH = 'sha512'; + /* + Per https://tools.ietf.org/html/rfc8032#page-6 EdDSA has several parameters, one of which is b: + + 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b + bits, and EdDSA signatures have exactly 2*b bits. b is + recommended to be a multiple of 8, so public key and signature + lengths are an integral number of octets. + + SIZE corresponds to b + */ + const SIZE = 32; + + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->setCoefficients( + // -1 + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC', 16), // a + // -121665/121666 + new BigInteger('52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3', 16) // d + ); + $this->setBasePoint( + new BigInteger('216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A', 16), + new BigInteger('6666666666666666666666666666666666666666666666666666666666666658', 16) + ); + $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + // algorithm 14.47 from http://cacr.uwaterloo.ca/hac/about/chap14.pdf#page=16 + /* + $this->setReduction(function($x) { + $parts = $x->bitwise_split(255); + $className = $this->className; + + if (count($parts) > 2) { + list(, $r) = $x->divide($className::$modulo); + return $r; + } + + $zero = new BigInteger(); + $c = new BigInteger(19); + + switch (count($parts)) { + case 2: + list($qi, $ri) = $parts; + break; + case 1: + $qi = $zero; + list($ri) = $parts; + break; + case 0: + return $zero; + } + $r = $ri; + + while ($qi->compare($zero) > 0) { + $temp = $qi->multiply($c)->bitwise_split(255); + if (count($temp) == 2) { + list($qi, $ri) = $temp; + } else { + $qi = $zero; + list($ri) = $temp; + } + $r = $r->add($ri); + } + + while ($r->compare($className::$modulo) > 0) { + $r = $r->subtract($className::$modulo); + } + return $r; + }); + */ + } + + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.1.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->add($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + /* we don't do $x2->squareRoot() because, quoting from + https://tools.ietf.org/html/rfc8032#section-5.1.1: + + "For point decoding or "decompression", square roots modulo p are + needed. They can be computed using the Tonelli-Shanks algorithm or + the special case for p = 5 (mod 8). To find a square root of a, + first compute the candidate root x = a^((p+3)/8) (mod p)." + */ + $exp = $this->getModulo()->add(new BigInteger(3)); + $exp = $exp->bitwise_rightShift(3); + $x = $x2->pow($exp); + + // If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a square root. + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + $temp = $this->getModulo()->subtract(new BigInteger(1)); + $temp = $temp->bitwise_rightShift(2); + $temp = $this->two->pow($temp); + $x = $x->multiply($temp); + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + + return [$x, $y]; + } + + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.1.5 + * + * Used by the various key handlers + * + * @param string $str + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function extractSecret($str) + { + if (strlen($str) != 32) { + throw new \LengthException('Private Key should be 32-bytes long'); + } + // 1. Hash the 32-byte private key using SHA-512, storing the digest in + // a 64-octet large buffer, denoted h. Only the lower 32 bytes are + // used for generating the public key. + $hash = new Hash('sha512'); + $h = $hash->hash($str); + $h = substr($h, 0, 32); + // 2. Prune the buffer: The lowest three bits of the first octet are + // cleared, the highest bit of the last octet is cleared, and the + // second highest bit of the last octet is set. + $h[0] = $h[0] & chr(0xF8); + $h = strrev($h); + $h[0] = ($h[0] & chr(0x3F)) | chr(0x40); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new BigInteger($h, 256); + $dA = $this->factory->newInteger($dA); + + $dA->secret = $str; + return $dA; + } + + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = $y->toBytes(); + $y[0] = $y[0] & chr(0x7F); + if ($x->isOdd()) { + $y[0] = $y[0] | chr(0x80); + } + $y = strrev($y); + + return $y; + } + + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(Random::string(32)); + } + + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.1.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one, clone $this->zero]; + } + + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p[3] = $p[0]->multiply($p[1]); + + return $p; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // from https://tools.ietf.org/html/rfc8032#page-12 + + list($x1, $y1, $z1, $t1) = $p; + + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $this->two->multiply($z1)->multiply($z1); + $h = $a->add($b); + $temp = $x1->add($y1); + $e = $h->subtract($temp->multiply($temp)); + $g = $a->subtract($b); + $f = $c->add($g); + + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3, $t3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // from https://tools.ietf.org/html/rfc8032#page-12 + + list($x1, $y1, $z1, $t1) = $p; + list($x2, $y2, $z2, $t2) = $q; + + $a = $y1->subtract($x1)->multiply($y2->subtract($x2)); + $b = $y1->add($x1)->multiply($y2->add($x2)); + $c = $t1->multiply($this->two)->multiply($this->d)->multiply($t2); + $d = $z1->multiply($this->two)->multiply($z2); + $e = $b->subtract($a); + $f = $d->subtract($c); + $g = $d->add($c); + $h = $b->add($a); + + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3, $t3]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php new file mode 100644 index 000000000..80ed33a8b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php @@ -0,0 +1,267 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; + +class Ed448 extends TwistedEdwards +{ + const HASH = 'shake256-912'; + const SIZE = 57; + + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger(1), + // -39081 + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756', 16) + ); + $this->setBasePoint( + new BigInteger('4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324' . + 'A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E', 16), + new BigInteger('693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E' . + '05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14', 16) + ); + $this->setOrder(new BigInteger( + '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16)); + } + + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.2.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->subtract($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + $exp = $this->getModulo()->add(new BigInteger(1)); + $exp = $exp->bitwise_rightShift(2); + $x = $x2->pow($exp); + + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + + return [$x, $y]; + } + + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.2.5 + * + * Used by the various key handlers + * + * @param string $str + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function extractSecret($str) + { + if (strlen($str) != 57) { + throw new \LengthException('Private Key should be 57-bytes long'); + } + // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the + // digest in a 114-octet large buffer, denoted h. Only the lower 57 + // bytes are used for generating the public key. + $hash = new Hash('shake256-912'); + $h = $hash->hash($str); + $h = substr($h, 0, 57); + // 2. Prune the buffer: The two least significant bits of the first + // octet are cleared, all eight bits the last octet are cleared, and + // the highest bit of the second to last octet is set. + $h[0] = $h[0] & chr(0xFC); + $h = strrev($h); + $h[0] = "\0"; + $h[1] = $h[1] | chr(0x80); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new BigInteger($h, 256); + $dA = $this->factory->newInteger($dA); + + $dA->secret = $str; + return $dA; + } + + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = "\0" . $y->toBytes(); + if ($x->isOdd()) { + $y[0] = $y[0] | chr(0x80); + } + $y = strrev($y); + + return $y; + } + + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(Random::string(57)); + } + + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.2.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one]; + } + + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + + return $p; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // from https://tools.ietf.org/html/rfc8032#page-18 + + list($x1, $y1, $z1) = $p; + + $b = $x1->add($y1); + $b = $b->multiply($b); + $c = $x1->multiply($x1); + $d = $y1->multiply($y1); + $e = $c->add($d); + $h = $z1->multiply($z1); + $j = $e->subtract($this->two->multiply($h)); + + $x3 = $b->subtract($e)->multiply($j); + $y3 = $c->subtract($d)->multiply($e); + $z3 = $e->multiply($j); + + return [$x3, $y3, $z3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // from https://tools.ietf.org/html/rfc8032#page-17 + + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $a = $z1->multiply($z2); + $b = $a->multiply($a); + $c = $x1->multiply($x2); + $d = $y1->multiply($y2); + $e = $this->d->multiply($c)->multiply($d); + $f = $b->subtract($e); + $g = $b->add($e); + $h = $x1->add($y1)->multiply($x2->add($y2)); + + $x3 = $a->multiply($f)->multiply($h->subtract($c)->subtract($d)); + $y3 = $a->multiply($g)->multiply($d->subtract($c)); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php new file mode 100644 index 000000000..23a4e6d27 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP160r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients( + new BigInteger('340E7BE2A280EB74E2BE61BADA745D97E8F7C300', 16), + new BigInteger('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16) + ); + $this->setBasePoint( + new BigInteger('BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3', 16), + new BigInteger('1667CB477A1A8EC338F94741669C976316DA6321', 16) + ); + $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php new file mode 100644 index 000000000..beafc34ba --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php @@ -0,0 +1,49 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP160t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients( + new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620C', 16), // eg. -3 + new BigInteger('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16) + ); + $this->setBasePoint( + new BigInteger('B199B13B9B34EFC1397E64BAEB05ACC265FF2378', 16), + new BigInteger('ADD6718B7C7C1961F0991B842443772152C9E0AD', 16) + ); + $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php new file mode 100644 index 000000000..11afdadb0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP192r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients( + new BigInteger('6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF', 16), + new BigInteger('469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9', 16) + ); + $this->setBasePoint( + new BigInteger('C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6', 16), + new BigInteger('14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F', 16) + ); + $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php new file mode 100644 index 000000000..71f956f29 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP192t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients( + new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294', 16), // eg. -3 + new BigInteger('13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79', 16) + ); + $this->setBasePoint( + new BigInteger('3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129', 16), + new BigInteger('097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9', 16) + ); + $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php new file mode 100644 index 000000000..83e49b026 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP224r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients( + new BigInteger('68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43', 16), + new BigInteger('2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B', 16) + ); + $this->setBasePoint( + new BigInteger('0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D', 16), + new BigInteger('58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD', 16) + ); + $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php new file mode 100644 index 000000000..97032a48c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP224t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients( + new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC', 16), // eg. -3 + new BigInteger('4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D', 16) + ); + $this->setBasePoint( + new BigInteger('6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580', 16), + new BigInteger('0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C', 16) + ); + $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php new file mode 100644 index 000000000..0d3860041 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP256r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients( + new BigInteger('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16), + new BigInteger('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16) + ); + $this->setBasePoint( + new BigInteger('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16), + new BigInteger('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16) + ); + $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php new file mode 100644 index 000000000..9c1d1cdbe --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP256t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients( + new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374', 16), // eg. -3 + new BigInteger('662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04', 16) + ); + $this->setBasePoint( + new BigInteger('A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4', 16), + new BigInteger('2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE', 16) + ); + $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php new file mode 100644 index 000000000..a6253a714 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP320r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . + '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients( + new BigInteger('3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4' . + '92F375A97D860EB4', 16), + new BigInteger('520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981' . + '6F5EB4AC8FB1F1A6', 16) + ); + $this->setBasePoint( + new BigInteger('43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7' . + '10AF8D0D39E20611', 16), + new BigInteger('14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7' . + 'D35245D1692E8EE1', 16) + ); + $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . + '82EC7EE8658E98691555B44C59311', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php new file mode 100644 index 000000000..e62771859 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP320t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . + '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients( + new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28' . + 'FCD412B1F1B32E24', 16), // eg. -3 + new BigInteger('A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE' . + 'B5B4FEF422340353', 16) + ); + $this->setBasePoint( + new BigInteger('925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF' . + '3357F624A21BED52', 16), + new BigInteger('63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B' . + '1B9BC0455FB0D2C3', 16) + ); + $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . + '82EC7EE8658E98691555B44C59311', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php new file mode 100644 index 000000000..5bc8a6d53 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php @@ -0,0 +1,48 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP384r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . + '1874700133107EC53', 16)); + $this->setCoefficients( + new BigInteger( + '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503' . + 'AD4EB04A8C7DD22CE2826', 16), + new BigInteger( + '4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DB' . + 'C9943AB78696FA504C11', 16) + ); + $this->setBasePoint( + new BigInteger( + '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D' . + '646AAEF87B2E247D4AF1E', 16), + new BigInteger( + '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E464621779' . + '1811142820341263C5315', 16) + ); + $this->setOrder(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . + '03B883202E9046565', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php new file mode 100644 index 000000000..8bd4a790f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php @@ -0,0 +1,48 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP384t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . + '1874700133107EC53', 16)); + $this->setCoefficients( + new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901' . + 'D1A71874700133107EC50', 16), // eg. -3 + new BigInteger( + '7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B8' . + '8805CED70355A33B471EE', 16) + ); + $this->setBasePoint( + new BigInteger( + '18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946' . + 'A5F54D8D0AA2F418808CC', 16), + new BigInteger( + '25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC' . + '2B2912675BF5B9E582928', 16) + ); + $this->setOrder(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . + '03B883202E9046565', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php new file mode 100644 index 000000000..8d22120fa --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php @@ -0,0 +1,48 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP512r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16)); + $this->setCoefficients( + new BigInteger( + '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA82' . + '53AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA', 16), + new BigInteger( + '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C' . + '1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723', 16) + ); + $this->setBasePoint( + new BigInteger( + '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D' . + '0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822', 16), + new BigInteger( + '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5' . + 'F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892', 16) + ); + $this->setOrder(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . + '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php new file mode 100644 index 000000000..8566182e4 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php @@ -0,0 +1,48 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP512t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16)); + $this->setCoefficients( + new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0', 16), // eg. -3 + new BigInteger( + '7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA23049' . + '76540F6450085F2DAE145C22553B465763689180EA2571867423E', 16) + ); + $this->setBasePoint( + new BigInteger( + '640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CD' . + 'B3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA', 16), + new BigInteger( + '5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEE' . + 'F216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332', 16) + ); + $this->setOrder(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . + '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php new file mode 100644 index 000000000..a2e974ace --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistb233 extends sect233r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php new file mode 100644 index 000000000..c3f25829f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistb409 extends sect409r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php new file mode 100644 index 000000000..2d3add6eb --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk163 extends sect163k1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php new file mode 100644 index 000000000..05efea40b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk233 extends sect233k1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php new file mode 100644 index 000000000..95420587e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk283 extends sect283k1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php new file mode 100644 index 000000000..eb55ce7bd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk409 extends sect409k1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php new file mode 100644 index 000000000..c600d79fb --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp192 extends secp192r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php new file mode 100644 index 000000000..5c4320ecf --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp224 extends secp224r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php new file mode 100644 index 000000000..56d0b5ad3 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp256 extends secp256r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php new file mode 100644 index 000000000..7a45babfc --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp384 extends secp384r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php new file mode 100644 index 000000000..167b058f6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp521 extends secp521r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php new file mode 100644 index 000000000..df92a3951 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistt571 extends sect571k1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php new file mode 100644 index 000000000..d329122a8 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class prime192v1 extends secp192r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php new file mode 100644 index 000000000..f5dbfa6bf --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime192v2 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', 16) + ); + $this->setBasePoint( + new BigInteger('EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', 16), + new BigInteger('6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php new file mode 100644 index 000000000..0bd83d372 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime192v3 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', 16) + ); + $this->setBasePoint( + new BigInteger('7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', 16), + new BigInteger('38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php new file mode 100644 index 000000000..e42e69256 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', 16) + ); + $this->setBasePoint( + new BigInteger('0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', 16), + new BigInteger('7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php new file mode 100644 index 000000000..ad6a3a866 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v2 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', 16) + ); + $this->setBasePoint( + new BigInteger('38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', 16), + new BigInteger('5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php new file mode 100644 index 000000000..ad41cfe02 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v3 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', 16) + ); + $this->setBasePoint( + new BigInteger('6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', 16), + new BigInteger('1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php new file mode 100644 index 000000000..8440514aa --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php @@ -0,0 +1,20 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class prime256v1 extends secp256r1 +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php new file mode 100644 index 000000000..4f0600180 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp112r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients( + new BigInteger('DB7C2ABF62E35E668076BEAD2088', 16), + new BigInteger('659EF8BA043916EEDE8911702B22', 16) + ); + $this->setBasePoint( + new BigInteger('09487239995A5EE76B55F9C2F098', 16), + new BigInteger('A89CE5AF8724C0A23E0E0FF77500', 16) + ); + $this->setOrder(new BigInteger('DB7C2ABF62E35E7628DFAC6561C5', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php new file mode 100644 index 000000000..e23e6b54d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php @@ -0,0 +1,37 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp112r2 extends Prime +{ + public function __construct() + { + // same modulo as secp112r1 + $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients( + new BigInteger('6127C24C05F38A0AAAF65C0EF02C', 16), + new BigInteger('51DEF1815DB5ED74FCC34C85D709', 16) + ); + $this->setBasePoint( + new BigInteger('4BA30AB5E892B4E1649DD0928643', 16), + new BigInteger('ADCD46F5882E3747DEF36E956E97', 16) + ); + $this->setOrder(new BigInteger('36DF0AAFD8B8D7597CA10520D04B', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php new file mode 100644 index 000000000..afe1336be --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp128r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC', 16), + new BigInteger('E87579C11079F43DD824993C2CEE5ED3', 16) + ); + $this->setBasePoint( + new BigInteger('161FF7528B899B2D0C28607CA52C5B86', 16), + new BigInteger('CF5AC8395BAFEB13C02DA292DDED7A83', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFE0000000075A30D1B9038A115', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php new file mode 100644 index 000000000..4e2719b12 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php @@ -0,0 +1,37 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp128r2 extends Prime +{ + public function __construct() + { + // same as secp128r1 + $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('D6031998D1B3BBFEBF59CC9BBFF9AEE1', 16), + new BigInteger('5EEEFCA380D02919DC2C6558BB6D8A5D', 16) + ); + $this->setBasePoint( + new BigInteger('7B6AA5D85E572983E6FB32A7CDEBC140', 16), + new BigInteger('27B6916A894D3AEE7106FE805FC34B44', 16) + ); + $this->setOrder(new BigInteger('3FFFFFFF7FFFFFFFBE0024720613B5A3', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php new file mode 100644 index 000000000..80ff73e32 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php @@ -0,0 +1,48 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp160k1 extends KoblitzPrime +{ + public function __construct() + { + // same as secp160r2 + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients( + new BigInteger('0000000000000000000000000000000000000000', 16), + new BigInteger('0000000000000000000000000000000000000007', 16) + ); + $this->setBasePoint( + new BigInteger('3B4C382CE37AA192A4019E763036F4F5DD4D7EBB', 16), + new BigInteger('938CF935318FDCED6BC28286531733C3F03C4FEE', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000001B8FA16DFAB9ACA16B6B3', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('0096341F1138933BC2F505', -16), + 'b' => new BigInteger('FF6E9D0418C67BB8D5F562', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01BDCB3A09AAAABEAFF4A8', -16), + 'b' => new BigInteger('04D12329FF0EF498EA67', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('645B7345A143464942CC46D7CF4D5D1E1E6CBB68', -16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php new file mode 100644 index 000000000..5d7739c48 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp160r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC', 16), + new BigInteger('1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45', 16) + ); + $this->setBasePoint( + new BigInteger('4A96B5688EF573284664698968C38BB913CBFC82', 16), + new BigInteger('23A628553168947D59DCC912042351377AC5FB32', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000001F4C8F927AED3CA752257', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php new file mode 100644 index 000000000..9b2789b41 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php @@ -0,0 +1,37 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp160r2 extends Prime +{ + public function __construct() + { + // same as secp160k1 + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70', 16), + new BigInteger('B4E134D3FB59EB8BAB57274904664D5AF50388BA', 16) + ); + $this->setBasePoint( + new BigInteger('52DCB034293A117E1F4FF11B30F7199D3144CE6D', 16), + new BigInteger('FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000000351EE786A818F3A1A16B', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php new file mode 100644 index 000000000..79ff610cf --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php @@ -0,0 +1,47 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp192k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37', 16)); + $this->setCoefficients( + new BigInteger('000000000000000000000000000000000000000000000000', 16), + new BigInteger('000000000000000000000000000000000000000000000003', 16) + ); + $this->setBasePoint( + new BigInteger('DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D', 16), + new BigInteger('9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('00B3FB3400DEC5C4ADCEB8655C', -16), + 'b' => new BigInteger('8EE96418CCF4CFC7124FDA0F', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01D90D03E8F096B9948B20F0A9', -16), + 'b' => new BigInteger('42E49819ABBA9474E1083F6B', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('447A96E6C647963E2F7809FEAAB46947F34B0AA3CA0BBA74', -16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php new file mode 100644 index 000000000..be7d38987 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php @@ -0,0 +1,80 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp192r1 extends Prime +{ + public function __construct() + { + $modulo = new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16); + $this->setModulo($modulo); + + // algorithm 2.27 from http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=66 + /* in theory this should be faster than regular modular reductions save for one small issue. + to convert to / from base-2**8 with BCMath you have to call bcmul() and bcdiv() a lot. + to convert to / from base-2**8 with PHP64 you have to call base256_rshift() a lot. + in short, converting to / from base-2**8 is pretty expensive and that expense is + enough to offset whatever else might be gained by a simplified reduction algorithm. + now, if PHP supported unsigned integers things might be different. no bit-shifting + would be required for the PHP engine and it'd be a lot faster. but as is, BigInteger + uses base-2**31 or base-2**26 depending on whether or not the system is has a 32-bit + or a 64-bit OS. + */ + /* + $m_length = $this->getLengthInBytes(); + $this->setReduction(function($c) use ($m_length) { + $cBytes = $c->toBytes(); + $className = $this->className; + + if (strlen($cBytes) > 2 * $m_length) { + list(, $r) = $c->divide($className::$modulo); + return $r; + } + + $c = str_pad($cBytes, 48, "\0", STR_PAD_LEFT); + $c = array_reverse(str_split($c, 8)); + + $null = "\0\0\0\0\0\0\0\0"; + $s1 = new BigInteger($c[2] . $c[1] . $c[0], 256); + $s2 = new BigInteger($null . $c[3] . $c[3], 256); + $s3 = new BigInteger($c[4] . $c[4] . $null, 256); + $s4 = new BigInteger($c[5] . $c[5] . $c[5], 256); + + $r = $s1->add($s2)->add($s3)->add($s4); + while ($r->compare($className::$modulo) >= 0) { + $r = $r->subtract($className::$modulo); + } + + return $r; + }); + */ + + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', 16) + ); + $this->setBasePoint( + new BigInteger('188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', 16), + new BigInteger('07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php new file mode 100644 index 000000000..6a2b9a82c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php @@ -0,0 +1,47 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp224k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D', 16)); + $this->setCoefficients( + new BigInteger('00000000000000000000000000000000000000000000000000000000', 16), + new BigInteger('00000000000000000000000000000000000000000000000000000005', 16) + ); + $this->setBasePoint( + new BigInteger('A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C', 16), + new BigInteger('7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5', 16) + ); + $this->setOrder(new BigInteger('010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('00B8ADF1378A6EB73409FA6C9C637D', -16), + 'b' => new BigInteger('94730F82B358A3776A826298FA6F', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01DCE8D2EC6184CAF0A972769FCC8B', -16), + 'b' => new BigInteger('4D2100BA3DC75AAB747CCF355DEC', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('01F178FFA4B17C89E6F73AECE2AAD57AF4C0A748B63C830947B27E04', -16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php new file mode 100644 index 000000000..23ac22979 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp224r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', 16), + new BigInteger('B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', 16) + ); + $this->setBasePoint( + new BigInteger('B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', 16), + new BigInteger('BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php new file mode 100644 index 000000000..958a48479 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php @@ -0,0 +1,51 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +//use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +//class secp256k1 extends Prime +class secp256k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16)); + $this->setCoefficients( + new BigInteger('0000000000000000000000000000000000000000000000000000000000000000', 16), + new BigInteger('0000000000000000000000000000000000000000000000000000000000000007', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)); + $this->setBasePoint( + new BigInteger('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), + new BigInteger('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16) + ); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16), + 'b' => new BigInteger('FF1BBC8129FEF177D790AB8056F5401B3D', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('114CA50F7A8E2F3F657C1108D9D44CFD8', -16), + 'b' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE', -16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php new file mode 100644 index 000000000..f929f4fa9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp256r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16), + new BigInteger('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16) + ); + $this->setBasePoint( + new BigInteger('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', 16), + new BigInteger('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php new file mode 100644 index 000000000..8c01a761c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php @@ -0,0 +1,54 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp384r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', + 16 + )); + $this->setCoefficients( + new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', + 16 + ), + new BigInteger( + 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', + 16 + ), + new BigInteger( + '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', + 16 + ) + ); + $this->setOrder(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', + 16 + )); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php new file mode 100644 index 000000000..8c2b9bbd1 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php @@ -0,0 +1,48 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp521r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFF', 16)); + $this->setCoefficients( + new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFC', 16), + new BigInteger('0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF1' . + '09E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B50' . + '3F00', 16) + ); + $this->setBasePoint( + new BigInteger('00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D' . + '3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5' . + 'BD66', 16), + new BigInteger('011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E' . + '662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1' . + '6650', 16) + ); + $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138' . + '6409', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php new file mode 100644 index 000000000..958082a35 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect113r1 extends Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients( + '003088250CA6E7C7FE649CE85820F7', + '00E8BEE4D3E2260744188BE0E9C723' + ); + $this->setBasePoint( + '009D73616F35F4AB1407D73562C10F', + '00A52830277958EE84D1315ED31886' + ); + $this->setOrder(new BigInteger('0100000000000000D9CCEC8A39E56F', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php new file mode 100644 index 000000000..9683c28f0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect113r2 extends Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients( + '00689918DBEC7E5A0DD6DFC0AA55C7', + '0095E9A9EC9B297BD4BF36E059184F' + ); + $this->setBasePoint( + '01A57A6A7B26CA5EF52FCDB8164797', + '00B3ADC94ED1FE674C06E695BABA1D' + ); + $this->setOrder(new BigInteger('010000000000000108789B2496AF93', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php new file mode 100644 index 000000000..f1585b7f3 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect131r1 extends Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients( + '07A11B09A76B562144418FF3FF8C2570B8', + '0217C05610884B63B9C6C7291678F9D341' + ); + $this->setBasePoint( + '0081BAF91FDF9833C40F9C181343638399', + '078C6E7EA38C001F73C8134B1B4EF9E150' + ); + $this->setOrder(new BigInteger('0400000000000000023123953A9464B54D', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php new file mode 100644 index 000000000..ecf7f99e0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect131r2 extends Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients( + '03E5A88919D7CAFCBF415F07C2176573B2', + '04B8266A46C55657AC734CE38F018F2192' + ); + $this->setBasePoint( + '0356DCD8F2F95031AD652D23951BB366A8', + '0648F06D867940A5366D9E265DE9EB240F' + ); + $this->setOrder(new BigInteger('0400000000000000016954A233049BA98F', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php new file mode 100644 index 000000000..cf51933b9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163k1 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000001', + '000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8', + '0289070FB05D38FF58321F2E800536D538CCDAA3D9' + ); + $this->setOrder(new BigInteger('04000000000000000000020108A2E0CC0D99F8A5EF', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php new file mode 100644 index 000000000..ca1c00ff2 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163r1 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '07B6882CAAEFA84F9554FF8428BD88E246D2782AE2', + '0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9' + ); + $this->setBasePoint( + '0369979697AB43897789566789567F787A7876A654', + '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883' + ); + $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B', 16)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php new file mode 100644 index 000000000..c473b9408 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163r2 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000001', + '020A601907B8C953CA1481EB10512F78744A3205FD' + ); + $this->setBasePoint( + '03F0EBA16286A2D57EA0991168D4994637E8343E36', + '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1' + ); + $this->setOrder(new BigInteger('040000000000000000000292FE77E70C12A4234C33', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php new file mode 100644 index 000000000..830f1ba2d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect193r1 extends Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients( + '0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01', + '00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814' + ); + $this->setBasePoint( + '01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1', + '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05' + ); + $this->setOrder(new BigInteger('01000000000000000000000000C7F34A778F443ACC920EBA49', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php new file mode 100644 index 000000000..6bf2462b6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect193r2 extends Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients( + '0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B', + '00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE' + ); + $this->setBasePoint( + '00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F', + '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C' + ); + $this->setOrder(new BigInteger('010000000000000000000000015AAB561B005413CCD4EE99D5', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php new file mode 100644 index 000000000..7a42f299b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect233k1 extends Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126', + '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3' + ); + $this->setOrder(new BigInteger('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php new file mode 100644 index 000000000..86d910c11 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect233r1 extends Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000001', + '0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD' + ); + $this->setBasePoint( + '00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B', + '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052' + ); + $this->setOrder(new BigInteger('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php new file mode 100644 index 000000000..1c8fcd1f0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect239k1 extends Binary +{ + public function __construct() + { + $this->setModulo(239, 158, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC', + '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA' + ); + $this->setOrder(new BigInteger('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php new file mode 100644 index 000000000..fdd48226f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect283k1 extends Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836', + '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259' + ); + $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php new file mode 100644 index 000000000..32a52e66b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php @@ -0,0 +1,36 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect283r1 extends Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000001', + '027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5' + ); + $this->setBasePoint( + '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053', + '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4' + ); + $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307', 16)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php new file mode 100644 index 000000000..d9c798a27 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php @@ -0,0 +1,39 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect409k1 extends Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients( + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746', + '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B' + ); + $this->setOrder(new BigInteger( + '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F' . + '83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF', 16 + )); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php new file mode 100644 index 000000000..c441180c7 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php @@ -0,0 +1,39 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect409r1 extends Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients( + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', + '0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F' + ); + $this->setBasePoint( + '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7', + '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706' + ); + $this->setOrder(new BigInteger( + '010000000000000000000000000000000000000000000000000001E2' . + 'AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173', 16 + )); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php new file mode 100644 index 000000000..c1dd4f11c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php @@ -0,0 +1,43 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect571k1 extends Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709584' . + '93B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972', + '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0' . + 'AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3' + ); + $this->setOrder(new BigInteger( + '020000000000000000000000000000000000000000000000000000000000000000000000' . + '131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001', 16 + )); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php new file mode 100644 index 000000000..95239342b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php @@ -0,0 +1,43 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect571r1 extends Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000001', + '02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD' . + '8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A' + ); + $this->setBasePoint( + '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950' . + 'F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19', + '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43' . + 'BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B' + ); + $this->setOrder(new BigInteger( + '03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'E661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47', 16 + )); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php new file mode 100644 index 000000000..1993002fc --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php @@ -0,0 +1,555 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Exception\UnsupportedCurveException; + +/** + * Generic EC Key Parsing Helper functions + * + * @package EC + * @author Jim Wigginton + * @access public + */ +trait Common +{ + /** + * Curve OIDs + * + * @var array + */ + private static $curveOIDs = []; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Use Named Curves + * + * @var bool + */ + private static $useNamedCurves = true; + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (empty(self::$curveOIDs)) { + // the sec* curves are from the standards for efficient cryptography group + // sect* curves are curves over binary finite fields + // secp* curves are curves over prime finite fields + // sec*r* curves are regular curves; sec*k* curves are koblitz curves + // brainpool*r* curves are regular prime finite field curves + // brainpool*t* curves are twisted versions of the brainpool*r* curves + self::$curveOIDs = [ + 'prime192v1' => '1.2.840.10045.3.1.1', // J.5.1, example 1 (aka secp192r1) + 'prime192v2' => '1.2.840.10045.3.1.2', // J.5.1, example 2 + 'prime192v3' => '1.2.840.10045.3.1.3', // J.5.1, example 3 + 'prime239v1' => '1.2.840.10045.3.1.4', // J.5.2, example 1 + 'prime239v2' => '1.2.840.10045.3.1.5', // J.5.2, example 2 + 'prime239v3' => '1.2.840.10045.3.1.6', // J.5.2, example 3 + 'prime256v1' => '1.2.840.10045.3.1.7', // J.5.3, example 1 (aka secp256r1) + + // https://tools.ietf.org/html/rfc5656#section-10 + 'nistp256' => '1.2.840.10045.3.1.7', // aka secp256r1 + 'nistp384' => '1.3.132.0.34', // aka secp384r1 + 'nistp521' => '1.3.132.0.35', // aka secp521r1 + + 'nistk163' => '1.3.132.0.1', // aka sect163k1 + 'nistp192' => '1.2.840.10045.3.1.1', // aka secp192r1 + 'nistp224' => '1.3.132.0.33', // aka secp224r1 + 'nistk233' => '1.3.132.0.26', // aka sect233k1 + 'nistb233' => '1.3.132.0.27', // aka sect233r1 + 'nistk283' => '1.3.132.0.16', // aka sect283k1 + 'nistk409' => '1.3.132.0.36', // aka sect409k1 + 'nistb409' => '1.3.132.0.37', // aka sect409r1 + 'nistt571' => '1.3.132.0.38', // aka sect571k1 + + // from https://tools.ietf.org/html/rfc5915 + 'secp192r1' => '1.2.840.10045.3.1.1', // aka prime192v1 + 'sect163k1' => '1.3.132.0.1', + 'sect163r2' => '1.3.132.0.15', + 'secp224r1' => '1.3.132.0.33', + 'sect233k1'=> '1.3.132.0.26', + 'sect233r1'=> '1.3.132.0.27', + 'secp256r1' => '1.2.840.10045.3.1.7', // aka prime256v1 + 'sect283k1' => '1.3.132.0.16', + 'sect283r1' => '1.3.132.0.17', + 'secp384r1' => '1.3.132.0.34', + 'sect409k1' => '1.3.132.0.36', + 'sect409r1' => '1.3.132.0.37', + 'secp521r1' => '1.3.132.0.35', + 'sect571k1' => '1.3.132.0.38', + 'sect571r1' => '1.3.132.0.39', + // from http://www.secg.org/SEC2-Ver-1.0.pdf + 'secp112r1' => '1.3.132.0.6', + 'secp112r2' => '1.3.132.0.7', + 'secp128r1' => '1.3.132.0.28', + 'secp128r2' => '1.3.132.0.29', + 'secp160k1' => '1.3.132.0.9', + 'secp160r1' => '1.3.132.0.8', + 'secp160r2' => '1.3.132.0.30', + 'secp192k1' => '1.3.132.0.31', + 'secp224k1' => '1.3.132.0.32', + 'secp256k1' => '1.3.132.0.10', + + 'sect113r1' => '1.3.132.0.4', + 'sect113r2' => '1.3.132.0.5', + 'sect131r1' => '1.3.132.0.22', + 'sect131r2' => '1.3.132.0.23', + 'sect163r1' => '1.3.132.0.2', + 'sect193r1' => '1.3.132.0.24', + 'sect193r2' => '1.3.132.0.25', + 'sect239k1' => '1.3.132.0.3', + + // from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf#page=36 + /* + 'c2pnb163v1' => '1.2.840.10045.3.0.1', // J.4.1, example 1 + 'c2pnb163v2' => '1.2.840.10045.3.0.2', // J.4.1, example 2 + 'c2pnb163v3' => '1.2.840.10045.3.0.3', // J.4.1, example 3 + 'c2pnb172w1' => '1.2.840.10045.3.0.4', // J.4.2, example 1 + 'c2tnb191v1' => '1.2.840.10045.3.0.5', // J.4.3, example 1 + 'c2tnb191v2' => '1.2.840.10045.3.0.6', // J.4.3, example 2 + 'c2tnb191v3' => '1.2.840.10045.3.0.7', // J.4.3, example 3 + 'c2onb191v4' => '1.2.840.10045.3.0.8', // J.4.3, example 4 + 'c2onb191v5' => '1.2.840.10045.3.0.9', // J.4.3, example 5 + 'c2pnb208w1' => '1.2.840.10045.3.0.10', // J.4.4, example 1 + 'c2tnb239v1' => '1.2.840.10045.3.0.11', // J.4.5, example 1 + 'c2tnb239v2' => '1.2.840.10045.3.0.12', // J.4.5, example 2 + 'c2tnb239v3' => '1.2.840.10045.3.0.13', // J.4.5, example 3 + 'c2onb239v4' => '1.2.840.10045.3.0.14', // J.4.5, example 4 + 'c2onb239v5' => '1.2.840.10045.3.0.15', // J.4.5, example 5 + 'c2pnb272w1' => '1.2.840.10045.3.0.16', // J.4.6, example 1 + 'c2pnb304w1' => '1.2.840.10045.3.0.17', // J.4.7, example 1 + 'c2tnb359v1' => '1.2.840.10045.3.0.18', // J.4.8, example 1 + 'c2pnb368w1' => '1.2.840.10045.3.0.19', // J.4.9, example 1 + 'c2tnb431r1' => '1.2.840.10045.3.0.20', // J.4.10, example 1 + */ + + // http://www.ecc-brainpool.org/download/Domain-parameters.pdf + // https://tools.ietf.org/html/rfc5639 + 'brainpoolP160r1' => '1.3.36.3.3.2.8.1.1.1', + 'brainpoolP160t1' => '1.3.36.3.3.2.8.1.1.2', + 'brainpoolP192r1' => '1.3.36.3.3.2.8.1.1.3', + 'brainpoolP192t1' => '1.3.36.3.3.2.8.1.1.4', + 'brainpoolP224r1' => '1.3.36.3.3.2.8.1.1.5', + 'brainpoolP224t1' => '1.3.36.3.3.2.8.1.1.6', + 'brainpoolP256r1' => '1.3.36.3.3.2.8.1.1.7', + 'brainpoolP256t1' => '1.3.36.3.3.2.8.1.1.8', + 'brainpoolP320r1' => '1.3.36.3.3.2.8.1.1.9', + 'brainpoolP320t1' => '1.3.36.3.3.2.8.1.1.10', + 'brainpoolP384r1' => '1.3.36.3.3.2.8.1.1.11', + 'brainpoolP384t1' => '1.3.36.3.3.2.8.1.1.12', + 'brainpoolP512r1' => '1.3.36.3.3.2.8.1.1.13', + 'brainpoolP512t1' => '1.3.36.3.3.2.8.1.1.14' + ]; + ASN1::loadOIDs([ + 'prime-field' => '1.2.840.10045.1.1', + 'characteristic-two-field' => '1.2.840.10045.1.2', + 'characteristic-two-basis' => '1.2.840.10045.1.2.3', + // per http://www.secg.org/SEC1-Ver-1.0.pdf#page=84, gnBasis "not used here" + 'gnBasis' => '1.2.840.10045.1.2.3.1', // NULL + 'tpBasis' => '1.2.840.10045.1.2.3.2', // Trinomial + 'ppBasis' => '1.2.840.10045.1.2.3.3' // Pentanomial + ] + self::$curveOIDs); + } + } + + /** + * Explicitly set the curve + * + * If the key contains an implicit curve phpseclib needs the curve + * to be explicitly provided + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + */ + public static function setImplicitCurve(BaseCurve $curve) + { + self::$implicitCurve = $curve; + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param array $params + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + protected static function loadCurveByParam(array $params) + { + if (count($params) > 1) { + throw new \RuntimeException('No parameters are present'); + } + if (isset($params['namedCurve'])) { + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve']; + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $params['namedCurve'] . ' is not supported'); + } + return new $curve(); + } + if (isset($params['implicitCurve'])) { + if (!isset(self::$implicitCurve)) { + throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); + } + return self::$implicitCurve; + } + if (isset($params['specifiedCurve'])) { + $data = $params['specifiedCurve']; + switch ($data['fieldID']['fieldType']) { + case 'prime-field': + $curve = new PrimeCurve(); + $curve->setModulo($data['fieldID']['parameters']); + $curve->setCoefficients( + new BigInteger($data['curve']['a'], 256), + new BigInteger($data['curve']['b'], 256) + ); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + case 'characteristic-two-field': + $curve = new BinaryCurve(); + $params = ASN1::decodeBER($data['fieldID']['parameters']); + $params = ASN1::asn1map($params[0], Maps\Characteristic_two::MAP); + $modulo = [(int) $params['m']->toString()]; + switch ($params['basis']) { + case 'tpBasis': + $modulo[] = (int) $params['parameters']->toString(); + break; + case 'ppBasis': + $temp = ASN1::decodeBER($params['parameters']); + $temp = ASN1::asn1map($temp[0], Maps\Pentanomial::MAP); + $modulo[] = (int) $temp['k3']->toString(); + $modulo[] = (int) $temp['k2']->toString(); + $modulo[] = (int) $temp['k1']->toString(); + } + $modulo[] = 0; + $curve->setModulo(...$modulo); + $len = ceil($modulo[0] / 8); + $curve->setCoefficients( + Hex::encode($data['curve']['a']), + Hex::encode($data['curve']['b']) + ); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + default: + throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); + } + } + throw new \RuntimeException('No valid parameters are present'); + } + + /** + * Extract points from a string + * + * Supports both compressed and uncompressed points + * + * @param string $str + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + public static function extractPoint($str, BaseCurve $curve) + { + if ($curve instanceof TwistedEdwardsCurve) { + // first step of point deciding as discussed at the following URL's: + // https://tools.ietf.org/html/rfc8032#section-5.1.3 + // https://tools.ietf.org/html/rfc8032#section-5.2.3 + $y = $str; + $y = strrev($y); + $sign = (bool) (ord($y[0]) & 0x80); + $y[0] = $y[0] & chr(0x7F); + $y = new BigInteger($y, 256); + if ($y->compare($curve->getModulo()) >= 0) { + throw new \RuntimeException('The Y coordinate should not be >= the modulo'); + } + $point = $curve->recoverX($y, $sign); + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + + // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, + // currently, bit strings wanting a non-zero amount of bits trimmed are not supported + if (($val = Strings::shift($str)) != "\0") { + throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Hex::encode($val)); + } + if ($str == "\0") { + return []; + } + + $keylen = strlen($str); + $order = $curve->getLengthInBytes(); + // point compression is being used + if ($keylen == $order + 1) { + return $curve->derivePoint($str); + } + + // point compression is not being used + if ($keylen == 2 * $order + 1) { + preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); + list(, $w, $x, $y) = $matches; + if ($w != "\4") { + throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Hex::encode($val)); + } + $point = [ + $curve->convertInteger(new BigInteger($x, 256)), + $curve->convertInteger(new BigInteger($y, 256)) + ]; + + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + + return $point; + } + + throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); + } + + /** + * Encode Parameters + * + * @todo Maybe at some point this could be moved to __toString() for each of the curves? + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param bool $returnArray optional + * @param array $options optional + * @return string|false + */ + private static function encodeParameters(BaseCurve $curve, $returnArray = false, array $options = []) + { + $useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves; + + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + if ($useNamedCurves) { + if (isset(self::$curveOIDs[$name])) { + if ($reflect->isFinal()) { + $reflect = $reflect->getParentClass(); + $name = $reflect->getShortName(); + } + return $returnArray ? + ['namedCurve' => $name] : + ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP); + } + foreach (new \DirectoryIterator(__DIR__ . '/../../Curves/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $testName = $file->getBasename('.php'); + $class = 'phpseclib3\Crypt\EC\Curves\\' . $testName; + $reflect = new \ReflectionClass($class); + if ($reflect->isFinal()) { + continue; + } + $candidate = new $class(); + switch ($name) { + case 'Prime': + if (!$candidate instanceof PrimeCurve) { + break; + } + if (!$candidate->getModulo()->equals($curve->getModulo())) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + + return $returnArray ? + ['namedCurve' => $testName] : + ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); + case 'Binary': + if (!$candidate instanceof BinaryCurve) { + break; + } + if ($candidate->getModulo() != $curve->getModulo()) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + + return $returnArray ? + ['namedCurve' => $testName] : + ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); + } + } + } + + $order = $curve->getOrder(); + // we could try to calculate the order thusly: + // https://crypto.stackexchange.com/a/27914/4520 + // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm + if (!$order) { + throw new \RuntimeException('Specified Curves need the order to be specified'); + } + $point = $curve->getBasePoint(); + $x = $point[0]->toBytes(); + $y = $point[1]->toBytes(); + + if ($curve instanceof PrimeCurve) { + /* + * valid versions are: + * + * ecdpVer1: + * - neither the curve or the base point are generated verifiably randomly. + * ecdpVer2: + * - curve and base point are generated verifiably at random and curve.seed is present + * ecdpVer3: + * - base point is generated verifiably at random but curve is not. curve.seed is present + */ + // other (optional) parameters can be calculated using the methods discused at + // https://crypto.stackexchange.com/q/28947/4520 + $data = [ + 'version' => 'ecdpVer1', + 'fieldID' => [ + 'fieldType' => 'prime-field', + 'parameters' => $curve->getModulo() + ], + 'curve' => [ + 'a' => $curve->getA()->toBytes(), + 'b' => $curve->getB()->toBytes() + ], + 'base' => "\4" . $x . $y, + 'order' => $order + ]; + + return $returnArray ? + ['specifiedCurve' => $data] : + ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); + } + if ($curve instanceof BinaryCurve) { + $modulo = $curve->getModulo(); + $basis = count($modulo); + $m = array_shift($modulo); + array_pop($modulo); // the last parameter should always be 0 + //rsort($modulo); + switch ($basis) { + case 3: + $basis = 'tpBasis'; + $modulo = new BigInteger($modulo[0]); + break; + case 5: + $basis = 'ppBasis'; + // these should be in strictly ascending order (hence the commented out rsort above) + $modulo = [ + 'k1' => new BigInteger($modulo[2]), + 'k2' => new BigInteger($modulo[1]), + 'k3' => new BigInteger($modulo[0]) + ]; + $modulo = ASN1::encodeDER($modulo, Maps\Pentanomial::MAP); + $modulo = new ASN1\Element($modulo); + } + $params = ASN1::encodeDER([ + 'm' => new BigInteger($m), + 'basis' => $basis, + 'parameters' => $modulo + ], Maps\Characteristic_two::MAP); + $params = new ASN1\Element($params); + $a = ltrim($curve->getA()->toBytes(), "\0"); + if (!strlen($a)) { + $a = "\0"; + } + $b = ltrim($curve->getB()->toBytes(), "\0"); + if (!strlen($b)) { + $b = "\0"; + } + $data = [ + 'version' => 'ecdpVer1', + 'fieldID' => [ + 'fieldType' => 'characteristic-two-field', + 'parameters' => $params + ], + 'curve' => [ + 'a' => $a, + 'b' => $b + ], + 'base' => "\4" . $x . $y, + 'order' => $order + ]; + + return $returnArray ? + ['specifiedCurve' => $data] : + ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); + } + + throw new UnsupportedCurveException('Curve cannot be serialized'); + } + + /** + * Use Specified Curve + * + * A specified curve has all the coefficients, the base points, etc, explicitely included. + * A specified curve is a more verbose way of representing a curve + */ + public static function useSpecifiedCurve() + { + self::$useNamedCurves = false; + } + + /** + * Use Named Curve + * + * A named curve does not include any parameters. It is up to the EC parameters to + * know what the coefficients, the base points, etc, are from the name of the curve. + * A named curve is a more concise way of representing a curve + */ + public static function useNamedCurve() + { + self::$useNamedCurves = true; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php new file mode 100644 index 000000000..b0c850100 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php @@ -0,0 +1,108 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Curve448; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Math\BigInteger; +use phpseclib3\Exception\UnsupportedFormatException; + +/** + * Montgomery Curve Private Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class MontgomeryPrivate +{ + /** + * Is invisible flag + * + * @access private + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $curve = new Curve25519; + break; + case 56: + $curve = new Curve448; + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + + $components = ['curve' => $curve]; + $components['dA'] = $components['curve']->convertInteger(new BigInteger($key, 256)); + // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @access public + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) + { + return strrev($publicKey[0]->toBytes()); + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $password optional + * @return string + */ + public static function savePrivateKey(Integer $privateKey, MontgomeryCurve $curve, array $publicKey, $password = '') + { + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); + } + + return $privateKey->toBytes(); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php new file mode 100644 index 000000000..72dc80b17 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php @@ -0,0 +1,79 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Curve448; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Math\BigInteger; + +/** + * Montgomery Public Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class MontgomeryPublic +{ + /** + * Is invisible flag + * + * @access private + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $curve = new Curve25519; + break; + case 56: + $curve = new Curve448; + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + + $components = ['curve' => $curve]; + $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($key), 256))]; + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @access public + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) + { + return strrev($publicKey[0]->toBytes()); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..5372e11bb --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php @@ -0,0 +1,216 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Math\Common\FiniteField\Integer; + +/** + * OpenSSH Formatted EC Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class OpenSSH extends Progenitor +{ + use Common; + + /** + * Supported Key Types + * + * @var array + */ + protected static $types = [ + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521', + 'ssh-ed25519' + ]; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + $paddedKey = $parsed['paddedKey']; + list($type) = Strings::unpackSSH2('s', $paddedKey); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + if ($type == 'ssh-ed25519' ) { + list(, $key, $comment) = Strings::unpackSSH2('sss', $paddedKey); + $key = libsodium::load($key); + $key['comment'] = $comment; + return $key; + } + list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey); + $curve = self::loadCurveByParam(['namedCurve' => $curveName]); + return [ + 'curve' => $curve, + 'dA' => $curve->convertInteger($privateKey), + 'QA' => self::extractPoint("\0$publicKey", $curve), + 'comment' => $comment + ]; + } + + if ($parsed['type'] == 'ssh-ed25519') { + if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + + $curve = new Ed25519(); + $qa = self::extractPoint($parsed['publicKey'], $curve); + } else { + list($curveName, $publicKey) = Strings::unpackSSH2('ss', $parsed['publicKey']); + $curveName = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; + $curve = new $curveName(); + + $qa = self::extractPoint("\0" . $publicKey, $curve); + } + + return [ + 'curve' => $curve, + 'QA' => $qa, + 'comment' => $parsed['comment'] + ]; + } + + /** + * Returns the alias that corresponds to a curve + * + * @return string + */ + private static function getAlias(BaseCurve $curve) + { + self::initialize_static_variables(); + + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + + $oid = self::$curveOIDs[$name]; + $aliases = array_filter(self::$curveOIDs, function($v) use ($oid) { + return $v == $oid; + }); + $aliases = array_keys($aliases); + + for ($i = 0; $i < count($aliases); $i++) { + if (in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) { + $alias = $aliases[$i]; + break; + } + } + + if (!isset($alias)) { + throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports'); + } + + return $alias; + } + + /** + * Convert an EC public key to the appropriate format + * + * @access public + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + + if ($curve instanceof Ed25519) { + $key = Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey)); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + + $key = 'ssh-ed25519 ' . base64_encode($key) . ' ' . $comment; + return $key; + } + + $alias = self::getAlias($curve); + + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $key = Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + + $key = 'ecdsa-sha2-' . $alias . ' ' . base64_encode($key) . ' ' . $comment; + + return $key; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) + { + if ($curve instanceof Ed25519) { + if (!isset($privateKey->secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (strlen($privateKey->secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + + $pubKey = $curve->encodePoint($publicKey); + + $publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey); + $privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $privateKey->secret . $pubKey); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } + + $alias = self::getAlias($curve); + + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => true]); + + $privateKey = Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..b28492bcd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php @@ -0,0 +1,203 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Math\BigInteger; +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Common\Functions\Strings; + +/** + * "PKCS1" (RFC5915) Formatted EC Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class PKCS1 extends Progenitor +{ + use Common; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) { + $components = []; + + preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches); + $decoded = parent::load($matches[0], $password); + $decoded = ASN1::decodeBER($decoded); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (!is_array($ecPrivate)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (isset($ecPrivate['parameters'])) { + $components['curve'] = self::loadCurveByParam($ecPrivate['parameters']); + } + + preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches); + $decoded = parent::load($matches[0], ''); + $decoded = ASN1::decodeBER($decoded); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + $ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (!is_array($ecParams)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + $ecParams = self::loadCurveByParam($ecParams); + + // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes + // even if the modulo is the same + if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) { + throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); + } + + if (!isset($components['curve'])) { + $components['curve'] = $ecParams; + } + + $temp = new BigInteger($ecPrivate['privateKey'], 256); + $components['dA'] = $components['curve']->convertInteger($temp); + $components['QA'] = isset($ecPrivate['publicKey']) ? + self::extractPoint($ecPrivate['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (is_array($key)) { + return ['curve' => self::loadCurveByParam($key)]; + } + + $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (!is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + if (!isset($key['parameters'])) { + throw new \RuntimeException('Key cannot be loaded without parameters'); + } + + $components = []; + $components['curve'] = self::loadCurveByParam($key['parameters']); + $temp = new BigInteger($key['privateKey'], 256); + $components['dA'] = $components['curve']->convertInteger($temp); + $components['QA'] = isset($ecPrivate['publicKey']) ? + self::extractPoint($ecPrivate['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert EC parameters to the appropriate format + * + * @access public + * @return string + */ + public static function saveParameters(BaseCurve $curve, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + + $key = self::encodeParameters($curve, false, $options); + + return "-----BEGIN EC PARAMETERS-----\r\n" . + chunk_split(Base64::encode($key), 64) . + "-----END EC PARAMETERS-----\r\n"; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards Curves are not supported'); + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + $key = [ + 'version' => 'ecPrivkeyVer1', + 'privateKey' => $privateKey->toBytes(), + 'parameters' => new ASN1\Element(self::encodeParameters($curve)), + 'publicKey' => "\0" . $publicKey + ]; + + $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'EC', $password, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..247beedb2 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php @@ -0,0 +1,249 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\Ed448; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Common\Functions\Strings; + +/** + * PKCS#8 Formatted EC Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class PKCS8 extends Progenitor +{ + use Common; + + /** + * OID Name + * + * @var array + * @access private + */ + const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448']; + + /** + * OID Value + * + * @var string + * @access private + */ + const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113']; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + // initialize_static_variables() is defined in both the trait and the parent class + // when it's defined in two places it's the traits one that's called + // the parent one is needed, as well, but the parent one is called by other methods + // in the parent class as needed and in the context of the parent it's the parent + // one that's called + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $isPublic = strpos($key, 'PUBLIC') !== false; + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + switch (true) { + case !$isPublic && $type == 'publicKey': + throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); + case $isPublic && $type == 'privateKey': + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + + switch ($key[$type . 'Algorithm']['algorithm']) { + case 'id-Ed25519': + case 'id-Ed448': + return self::loadEdDSA($key); + } + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + $params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (!$params) { + throw new \RuntimeException('Unable to decode the parameters using Maps\ECParameters'); + } + + $components = []; + $components['curve'] = self::loadCurveByParam($params); + + if ($isPublic) { + $components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']); + + return $components; + } + + $decoded = ASN1::decodeBER($key['privateKey']); + $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (isset($key['parameters']) && $params != $key['parameters']) { + throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); + } + + $temp = new BigInteger($key['privateKey'], 256); + $components['dA'] = $components['curve']->convertInteger($temp); + + $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); + + return $components; + } + + /** + * Break a public or private EdDSA key down into its constituent components + * + * @return array + */ + private static function loadEdDSA(array $key) + { + $components = []; + + if (isset($key['privateKey'])) { + $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); + + // 0x04 == octet string + // 0x20 == length (32 bytes) + if (substr($key['privateKey'], 0, 2) != "\x04\x20") { + throw new \RuntimeException('The first two bytes of the private key field should be 0x0420'); + } + $components['dA'] = $components['curve']->extractSecret(substr($key['privateKey'], 2)); + } + + if (isset($key['publicKey'])) { + if (!isset($components['curve'])) { + $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); + } + + $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); + } + + if (isset($key['privateKey']) && !isset($components['QA'])) { + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + } + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @access public + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('Montgomery Curves are not supported'); + } + + if ($curve instanceof TwistedEdwardsCurve) { + return self::wrapPublicKey( + $curve->encodePoint($publicKey), + null, + $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' + ); + } + + $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); + + $key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + return self::wrapPublicKey($key, $params, 'id-ecPublicKey'); + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('Montgomery Curves are not supported'); + } + + if ($curve instanceof TwistedEdwardsCurve) { + return self::wrapPrivateKey( + "\x04\x20" . $privateKey->secret, + [], + null, + $password, + $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448', + "\0" . $curve->encodePoint($publicKey) + ); + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); + + $key = [ + 'version' => 'ecPrivkeyVer1', + 'privateKey' => $privateKey->toBytes(), + //'parameters' => $params, + 'publicKey' => "\0" . $publicKey + ]; + + $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); + + return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..181ab76c9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php @@ -0,0 +1,146 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; + +/** + * PuTTY Formatted EC Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class PuTTY extends Progenitor +{ + use Common; + + /** + * Public Handler + * + * @var string + * @access private + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\EC\Formats\Keys\OpenSSH'; + + /** + * Supported Key Types + * + * @var array + * @access private + */ + protected static $types = [ + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521', + 'ssh-ed25519' + ]; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + + $private = $components['private']; + + $temp = Base64::encode(Strings::packSSH2('s', $components['type']) . $components['public']); + $components = OpenSSH::load($components['type'] . ' ' . $temp . ' ' . $components['comment']); + + if ($components['curve'] instanceof TwistedEdwardsCurve) { + if (Strings::shift($private, 4) != "\0\0\0\x20") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + $components['dA'] = $components['curve']->extractSecret($private); + } else { + list($temp) = Strings::unpackSSH2('i', $private); + $components['dA'] = $components['curve']->convertInteger($temp); + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = false, array $options = []) + { + self::initialize_static_variables(); + + $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); + $name = $public[0]; + $public = Base64::decode($public[1]); + list(, $length) = unpack('N', Strings::shift($public, 4)); + Strings::shift($public, $length); + + // PuTTY pads private keys with a null byte per the following: + // https://github.com/github/putty/blob/a3d14d77f566a41fc61dfdc5c2e0e384c9e6ae8b/sshecc.c#L1926 + if (!$curve instanceof TwistedEdwardsCurve) { + $private = $privateKey->toBytes(); + if (!(strlen($privateKey->toBits()) & 7)) { + $private ="\0$private"; + } + } + + $private = $curve instanceof TwistedEdwardsCurve ? + Strings::packSSH2('s', $privateKey->secret) : + Strings::packSSH2('s', $private); + + return self::wrapPrivateKey($public, $private, $name, $password, $options); + } + + /** + * Convert an EC public key to the appropriate format + * + * @access public + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField[] $publicKey + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey) + { + $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); + $type = $public[0]; + $public = Base64::decode($public[1]); + list(, $length) = unpack('N', Strings::shift($public, 4)); + Strings::shift($public, $length); + + return self::wrapPublicKey($public, $type); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php new file mode 100644 index 000000000..d6d8018ad --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php @@ -0,0 +1,484 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedCurveException; + +/** + * XML Formatted EC Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class XML +{ + use Common; + + /** + * Default namespace + * + * @var string + */ + private static $namespace; + + /** + * Flag for using RFC4050 syntax + * + * @var bool + */ + private static $rfc4050 = false; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $use_errors = libxml_use_internal_errors(true); + + $temp = self::isolateNamespace($key, 'http://www.w3.org/2009/xmldsig11#'); + if ($temp) { + $key = $temp; + } + + $temp = self::isolateNamespace($key, 'http://www.w3.org/2001/04/xmldsig-more#'); + if ($temp) { + $key = $temp; + } + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + + if (!$dom->loadXML($key)) { + libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + libxml_use_internal_errors($use_errors); + $curve = self::loadCurveByParam($xpath); + + $pubkey = self::query($xpath, 'publickey', 'Public Key is not present'); + + $QA = self::query($xpath, 'ecdsakeyvalue')->length ? + self::extractPointRFC4050($xpath, $curve) : + self::extractPoint("\0" . $pubkey, $curve); + + libxml_use_internal_errors($use_errors); + + return compact('curve', 'QA'); + } + + /** + * Case-insensitive xpath query + * + * @param \DOMXPath $xpath + * @param string $name + * @param string $error optional + * @param bool $decode optional + * @return \DOMNodeList + */ + private static function query($xpath, $name, $error = null, $decode = true) + { + $query = '/'; + $names = explode('/', $name); + foreach ($names as $name) { + $query.= "/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$name']"; + } + $result = $xpath->query($query); + if (!isset($error)) { + return $result; + } + + if (!$result->length) { + throw new \RuntimeException($error); + } + return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; + } + + /** + * Finds the first element in the relevant namespace, strips the namespacing and returns the XML for that element. + * + * @param string $xml + * @param string $ns + */ + private static function isolateNamespace($xml, $ns) + { + $dom = new \DOMDocument(); + if (!$dom->loadXML($xml)) { + return false; + } + $xpath = new \DOMXPath($dom); + $nodes = $xpath->query("//*[namespace::*[.='$ns'] and not(../namespace::*[.='$ns'])]"); + if (!$nodes->length) { + return false; + } + $node = $nodes->item(0); + $ns_name = $node->lookupPrefix($ns); + $node->removeAttributeNS($ns, $ns_name); + return $dom->saveXML($node); + } + + /** + * Decodes the value + * + * @param string $value + */ + private static function decodeValue($value) + { + return Base64::decode(str_replace(["\r", "\n", ' ', "\t"], '', $value)); + } + + /** + * Extract points from an XML document + * + * @param \DOMXPath $xpath + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + private static function extractPointRFC4050(\DOMXPath $xpath, BaseCurve $curve) + { + $x = self::query($xpath, 'publickey/x'); + $y = self::query($xpath, 'publickey/y'); + if (!$x->length || !$x->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / X coordinate not found'); + } + if (!$y->length || !$y->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / Y coordinate not found'); + } + $point = [ + $curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))), + $curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))) + ]; + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParam(\DOMXPath $xpath) + { + $namedCurve = self::query($xpath, 'namedcurve'); + if ($namedCurve->length == 1) { + $oid = $namedCurve->item(0)->getAttribute('URN'); + $oid = preg_replace('#[^\d.]#', '', $oid); + $name = array_search($oid, self::$curveOIDs); + if ($name === false) { + throw new UnsupportedCurveException('Curve with OID of ' . $oid . ' is not supported'); + } + + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $name; + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $name . ' is not supported'); + } + return new $curve(); + } + + $params = self::query($xpath, 'explicitparams'); + if ($params->length) { + return self::loadCurveByParamRFC4050($xpath); + } + + $params = self::query($xpath, 'ecparameters'); + if (!$params->length) { + throw new \RuntimeException('No parameters are present'); + } + + $fieldTypes = [ + 'prime-field' => ['fieldid/prime/p'], + 'gnb' => ['fieldid/gnb/m'], + 'tnb' => ['fieldid/tnb/k'], + 'pnb' => ['fieldid/pnb/k1', 'fieldid/pnb/k2', 'fieldid/pnb/k3'], + 'unknown' => [] + ]; + + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = preg_replace('#.*/#', '', $query); + $$param = self::decodeValue($result->item(0)->textContent); + } + break; + } + + $a = self::query($xpath, 'curve/a', 'A coefficient is not present'); + $b = self::query($xpath, 'curve/b', 'B coefficient is not present'); + $base = self::query($xpath, 'base', 'Base point is not present'); + $order = self::query($xpath, 'order', 'Order is not present'); + + switch ($type) { + case 'prime-field': + $curve = new PrimeCurve(); + $curve->setModulo(new BigInteger($p, 256)); + $curve->setCoefficients( + new BigInteger($a, 256), + new BigInteger($b, 256) + ); + $point = self::extractPoint("\0" . $base, $curve); + $curve->setBasePoint(...$point); + $curve->setOrder(new BigInteger($order, 256)); + return $curve; + case 'gnb': + case 'tnb': + case 'pnb': + default: + throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParamRFC4050(\DOMXPath $xpath) + { + $fieldTypes = [ + 'prime-field' => ['primefieldparamstype/p'], + 'unknown' => [] + ]; + + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = preg_replace('#.*/#', '', $query); + $$param = $result->item(0)->textContent; + } + break; + } + + $a = self::query($xpath, 'curveparamstype/a', 'A coefficient is not present', false); + $b = self::query($xpath, 'curveparamstype/b', 'B coefficient is not present', false); + $x = self::query($xpath, 'basepointparams/basepoint/ecpointtype/x', 'Base Point X is not present', false); + $y = self::query($xpath, 'basepointparams/basepoint/ecpointtype/y', 'Base Point Y is not present', false); + $order = self::query($xpath, 'order', 'Order is not present', false); + + switch ($type) { + case 'prime-field': + $curve = new PrimeCurve(); + + $p = str_replace(["\r", "\n", ' ', "\t"], '', $p); + $curve->setModulo(new BigInteger($p)); + + $a = str_replace(["\r", "\n", ' ', "\t"], '', $a); + $b = str_replace(["\r", "\n", ' ', "\t"], '', $b); + $curve->setCoefficients( + new BigInteger($a), + new BigInteger($b) + ); + + $x = str_replace(["\r", "\n", ' ', "\t"], '', $x); + $y = str_replace(["\r", "\n", ' ', "\t"], '', $y); + $curve->setBasePoint( + new BigInteger($x), + new BigInteger($y) + ); + + $order = str_replace(["\r", "\n", ' ', "\t"], '', $order); + $curve->setOrder(new BigInteger($order)); + return $curve; + default: + throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + + /** + * Sets the namespace. dsig11 is the most common one. + * + * Set to null to unset. Used only for creating public keys. + * + * @param string $namespace + */ + public static function setNamespace($namespace) + { + self::$namespace = $namespace; + } + + /** + * Uses the XML syntax specified in https://tools.ietf.org/html/rfc4050 + */ + public static function enableRFC4050Syntax() + { + self::$rfc4050 = true; + } + + /** + * Uses the XML syntax specified in https://www.w3.org/TR/xmldsig-core/#sec-ECParameters + */ + public static function disableRFC4050Syntax() + { + self::$rfc4050 = false; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + + if (empty(static::$namespace)) { + $pre = $post = ''; + } else { + $pre = static::$namespace . ':'; + $post = ':' . static::$namespace; + } + + if (self::$rfc4050) { + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" . + self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . + '<' . $pre . 'PublicKey>' . "\r\n" . + '<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" . + '<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" . + '' . "\r\n" . + ''; + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" . + self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . + '<' . $pre . 'PublicKey>' . Base64::encode($publicKey) . '' . "\r\n" . + ''; + } + + /** + * Encode Parameters + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param string $pre + * @param array $options optional + * @return string|false + */ + private static function encodeXMLParameters(BaseCurve $curve, $pre, array $options = []) + { + $result = self::encodeParameters($curve, true, $options); + + if (isset($result['namedCurve'])) { + $namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />'; + return self::$rfc4050 ? + '' . str_replace('URI', 'URN', $namedCurve) . '' : + $namedCurve; + } + + if (self::$rfc4050) { + $xml = '<' . $pre . 'ExplicitParams>' . "\r\n" . + '<' . $pre . 'FieldParams>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml.= '<' . $pre . 'PrimeFieldParamsType>' . "\r\n" . + '<' . $pre . 'P>' . $temp['fieldID']['parameters'] . '' . "\r\n" . + '' . "\r\n"; + $a = $curve->getA(); + $b = $curve->getB(); + list($x, $y) = $curve->getBasePoint(); + break; + default: + throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml.= '' . "\r\n" . + '<' . $pre . 'CurveParamsType>' . "\r\n" . + '<' . $pre . 'A>' . $a . '' . "\r\n" . + '<' . $pre . 'B>' . $b . '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'BasePointParams>' . "\r\n" . + '<' . $pre . 'BasePoint>' . "\r\n" . + '<' . $pre . 'ECPointType>' . "\r\n" . + '<' . $pre . 'X>' . $x . '' . "\r\n" . + '<' . $pre . 'Y>' . $y . '' . "\r\n" . + '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'Order>' . $curve->getOrder() . '' . "\r\n" . + '' . "\r\n" . + '' . "\r\n"; + + return $xml; + } + + if (isset($result['specifiedCurve'])) { + $xml = '<' . $pre . 'ECParameters>' . "\r\n" . + '<' . $pre . 'FieldID>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml.= '<' . $pre . 'Prime>' . "\r\n" . + '<' . $pre . 'P>' . Base64::encode($temp['fieldID']['parameters']->toBytes()) . '' . "\r\n" . + '' . "\r\n" ; + break; + default: + throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml.= '' . "\r\n" . + '<' . $pre . 'Curve>' . "\r\n" . + '<' . $pre . 'A>' . Base64::encode($temp['curve']['a']) . '' . "\r\n" . + '<' . $pre . 'B>' . Base64::encode($temp['curve']['b']) . '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'Base>' . Base64::encode($temp['base']) . '' . "\r\n" . + '<' . $pre . 'Order>' . Base64::encode($temp['order']) . '' . "\r\n" . + ''; + return $xml; + } + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php new file mode 100644 index 000000000..b8be19444 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php @@ -0,0 +1,122 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Exception\UnsupportedFormatException; + +/** + * libsodium Key Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class libsodium +{ + use Common; + + /** + * Is invisible flag + * + * @access private + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $public = $key; + break; + case 64: + $private = substr($key, 0, 32); + $public = substr($key, -32); + break; + case 96: + $public = substr($key, -32); + if (substr($key, 32, 32) != $public) { + throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); + } + $private = substr($key, 0, 32); + break; + default: + throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); + } + + $curve = new Ed25519(); + $components = ['curve' => $curve]; + if (isset($private)) { + $components['dA'] = $curve->extractSecret($private); + } + $components['QA'] = isset($public) ? + self::extractPoint($public, $curve) : + $curve->multiplyPoint($curve->getBasePoint(), $components['dA']); + + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @access public + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(Ed25519 $curve, array $publicKey) + { + return $curve->encodePoint($publicKey); + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $password optional + * @return string + */ + public static function savePrivateKey(Integer $privateKey, Ed25519 $curve, array $publicKey, $password = '') + { + if (!isset($privateKey->secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (strlen($privateKey->secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('libsodium private keys do not support encryption'); + } + return $privateKey->secret . $curve->encodePoint($publicKey); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php new file mode 100644 index 000000000..3509eb61e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php @@ -0,0 +1,68 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Math\BigInteger; +use phpseclib3\File\ASN1 as Encoder; +use phpseclib3\File\ASN1\Maps\EcdsaSigValue; + +/** + * ASN1 Signature Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @access public + * @param string $sig + * @return array + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $decoded = Encoder::decodeBER($sig); + if (empty($decoded)) { + return false; + } + $components = Encoder::asn1map($decoded[0], EcdsaSigValue::MAP); + + return $components; + } + + /** + * Returns a signature in the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return Encoder::encodeDER(compact('r', 's'), EcdsaSigValue::MAP); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php new file mode 100644 index 000000000..eebef46b2 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php @@ -0,0 +1,29 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; + +/** + * Raw DSA Signature Handler + * + * @package EC + * @author Jim Wigginton + * @access public + */ +abstract class Raw extends Progenitor +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php new file mode 100644 index 000000000..261100dbe --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php @@ -0,0 +1,100 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; + +/** + * SSH2 Signature Handler + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @access public + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $result = Strings::unpackSSH2('ss', $sig); + if ($result === false) { + return false; + } + list($type, $blob) = $result; + switch ($type) { + // see https://tools.ietf.org/html/rfc5656#section-3.1.2 + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + break; + default: + return false; + } + + $result = Strings::unpackSSH2('ii', $blob); + if ($result === false) { + return false; + } + + return [ + 'r' => $result[0], + 's' => $result[1] + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @param string $curve + * @return string + */ + public static function save(BigInteger $r, BigInteger $s, $curve) + { + switch ($curve) { + case 'secp256r1': + $curve = 'nistp256'; + break; + case 'secp384r1': + $curve = 'nistp384'; + break; + case 'secp521r1': + $curve = 'nistp521'; + break; + default: + return false; + } + + $blob = Strings::packSSH2('ii', $r, $s); + + return Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php new file mode 100644 index 000000000..96527c754 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php @@ -0,0 +1,40 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Crypt\EC; + +/** + * EC Parameters + * + * @package EC + * @author Jim Wigginton + * @access public + */ +class Parameters extends EC +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->curve, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php new file mode 100644 index 000000000..4ffa5fdf5 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php @@ -0,0 +1,258 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\Common; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Common\Functions\Strings; + +/** + * EC Private Key + * + * @package EC + * @author Jim Wigginton + * @access public + */ +class PrivateKey extends EC implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * Private Key dA + * + * sign() converts this to a BigInteger so one might wonder why this is a FiniteFieldInteger instead of + * a BigInteger. That's because a FiniteFieldInteger, when converted to a byte string, is null padded by + * a certain amount whereas a BigInteger isn't. + * + * @var object + */ + protected $dA; + + /** + * Multiplies an encoded point by the private key + * + * Used by ECDH + * + * @param string $coordinates + * @return string + */ + public function multiply($coordinates) + { + if ($this->curve instanceof MontgomeryCurve) { + if ($this->curve instanceof Curve25519 && self::$engines['libsodium']) { + return sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates); + } + + $point = [$this->curve->convertInteger(new BigInteger(strrev($coordinates), 256))]; + $point = $this->curve->multiplyPoint($point, $this->dA); + return strrev($point[0]->toBytes(true)); + } + if (!$this->curve instanceof TwistedEdwardsCurve) { + $coordinates = "\0$coordinates"; + } + $point = PKCS1::extractPoint($coordinates, $this->curve); + $point = $this->curve->multiplyPoint($point, $this->dA); + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve->encodePoint($point); + } + if (empty($point)) { + throw new \RuntimeException('The infinity point is invalid'); + } + return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true); + } + + /** + * Create a signature + * + * @see self::verify() + * @access public + * @param string $message + * @return mixed + */ + public function sign($message) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $dA = $this->dA->toBigInteger(); + + $order = $this->curve->getOrder(); + + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === false) { + return false; + } + + if ($this->curve instanceof TwistedEdwardsCurve) { + if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + $result = sodium_crypto_sign_detached($message, $this->toString('libsodium')); + return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result) : $result; + } + + // contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not. + // quoting https://tools.ietf.org/html/rfc8032#section-8.5 , + // "The Ed25519ph and Ed448ph variants ... SHOULD NOT be used" + $A = $this->curve->encodePoint($this->QA); + $curve = $this->curve; + $hash = new Hash($curve::HASH); + + $secret = substr($hash->hash($this->dA->secret), $curve::SIZE); + + if ($curve instanceof Ed25519) { + $dom = !isset($this->context) ? '' : + 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom = 'SigEd448' . "\0" . chr(strlen($context)) . $context; + } + // SHA-512(dom2(F, C) || prefix || PH(M)) + $r = $hash->hash($dom . $secret . $message); + $r = strrev($r); + $r = new BigInteger($r, 256); + list(, $r) = $r->divide($order); + $R = $curve->multiplyPoint($curve->getBasePoint(), $curve->convertInteger($r)); + $R = $curve->encodePoint($R); + $k = $hash->hash($dom . $R . $A . $message); + $k = strrev($k); + $k = new BigInteger($k, 256); + list(, $k) = $k->divide($order); + $S = $k->multiply($dA)->add($r); + list(, $S) = $S->divide($order); + $S = str_pad(strrev($S->toBytes()), $curve::SIZE, "\0"); + return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $R . $S) : $R . $S; + } + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $signature = ''; + // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long + // supported signing / verification + // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; + // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even + // has curve-specific optimizations + $result = openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); + + if ($result) { + if ($shortFormat == 'ASN1') { + return $signature; + } + + extract(ASN1Signature::load($signature)); + + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + } + + $e = $this->hash->hash($message); + $e = new BigInteger($e, 256); + + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + + while (true) { + $k = BigInteger::randomRange(self::$one, $order->subtract(self::$one)); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $this->curve->convertInteger($k)); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($order); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($order); + $temp = $z->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($order); + if (!$s->equals(self::$zero)) { + break; + } + } + + // the following is an RFC6979 compliant implementation of deterministic ECDSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + // if this were actually being used it'd probably be better if this lived in load() and createKey() + $this->q = $this->curve->getOrder(); + $dA = $this->dA->toBigInteger(); + $this->x = $dA; + + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $this->curve->convertInteger($k)); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->password, $options); + } + + /** + * Returns the public key + * + * @see self::getPrivateKey() + * @access public + * @return mixed + */ + public function getPublicKey() + { + $format = 'PKCS8'; + if ($this->curve instanceof MontgomeryCurve) { + $format = 'MontgomeryPublic'; + } + + $type = self::validatePlugin('Keys', $format, 'savePublicKey'); + + $key = $type::savePublicKey($this->curve, $this->QA); + $key = EC::loadFormat($format, $key); + if ($this->curve instanceof MontgomeryCurve) { + return $key; + } + $key = $key + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + if ($this->curve instanceof TwistedEdwardsCurve) { + $key = $key->withContext($this->context); + } + return $key; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php new file mode 100644 index 000000000..2cb92ab68 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php @@ -0,0 +1,177 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\Hash; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\Common; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Common\Functions\Strings; + +/** + * EC Public Key + * + * @package EC + * @author Jim Wigginton + * @access public + */ +class PublicKey extends EC implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Verify a signature + * + * @see self::verify() + * @access public + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === false) { + return false; + } + + $order = $this->curve->getOrder(); + + if ($this->curve instanceof TwistedEdwardsCurve) { + if ($shortFormat == 'SSH2') { + list(, $signature) = Strings::unpackSSH2('ss', $signature); + } + + if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium')); + } + + $curve = $this->curve; + if (strlen($signature) != 2 * $curve::SIZE) { + return false; + } + + $R = substr($signature, 0, $curve::SIZE); + $S = substr($signature, $curve::SIZE); + + try { + $R = PKCS1::extractPoint($R, $curve); + $R = $this->curve->convertToInternal($R); + } catch (\Exception $e) { + return false; + } + + $S = strrev($S); + $S = new BigInteger($S, 256); + + if ($S->compare($order) >= 0) { + return false; + } + + $A = $curve->encodePoint($this->QA); + + if ($curve instanceof Ed25519) { + $dom2 = !isset($this->context) ? '' : + 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom2 = 'SigEd448' . "\0" . chr(strlen($context)) . $context; + } + + $hash = new Hash($curve::HASH); + $k = $hash->hash($dom2 . substr($signature, 0, $curve::SIZE) . $A . $message); + $k = strrev($k); + $k = new BigInteger($k, 256); + list(, $k) = $k->divide($order); + + $qa = $curve->convertToInternal($this->QA); + + $lhs = $curve->multiplyPoint($curve->getBasePoint(), $curve->convertInteger($S)); + $rhs = $curve->multiplyPoint($qa, $curve->convertInteger($k)); + $rhs = $curve->addPoint($rhs, $R); + $rhs = $curve->convertToAffine($rhs); + + return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]); + } + + $params = $format::load($signature); + if ($params === false || count($params) != 2) { + return false; + } + extract($params); + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; + + $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); + + if ($result != -1) { + return (bool) $result; + } + } + + $n_1 = $order->subtract(self::$one); + if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) { + return false; + } + + $e = $this->hash->hash($message); + $e = new BigInteger($e, 256); + + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + + $w = $s->modInverse($order); + list(, $u1) = $z->multiply($w)->divide($order); + list(, $u2) = $r->multiply($w)->divide($order); + + $u1 = $this->curve->convertInteger($u1); + $u2 = $this->curve->convertInteger($u2); + + list($x1, $y1) = $this->curve->multiplyAddPoints( + [$this->curve->getBasePoint(), $this->QA], + [$u1, $u2] + ); + + $x1 = $x1->toBigInteger(); + list(, $x1) = $x1->divide($order); + + return $x1->equals($r); + } + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->curve, $this->QA, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php new file mode 100644 index 000000000..706de2147 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php @@ -0,0 +1,1484 @@ + + * setKey('abcdefg'); + * + * echo base64_encode($hash->hash('abcdefg')); + * ?> + * + * + * @category Crypt + * @package Hash + * @author Jim Wigginton + * @copyright 2015 Jim Wigginton + * @author Andreas Fischer + * @copyright 2015 Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Math\PrimeField; + +/** + * @package Hash + * @author Jim Wigginton + * @author Andreas Fischer + * @access public + */ +class Hash +{ + /** + * Padding Types + * + * @access private + */ + //const PADDING_KECCAK = 1; + + /** + * Padding Types + * + * @access private + */ + const PADDING_SHA3 = 2; + + /** + * Padding Types + * + * @access private + */ + const PADDING_SHAKE = 3; + + /** + * Padding Type + * + * Only used by SHA3 + * + * @var int + * @access private + */ + private $paddingType = 0; + + /** + * Hash Parameter + * + * @see self::setHash() + * @var int + * @access private + */ + private $hashParam; + + /** + * Byte-length of hash output (Internal HMAC) + * + * @see self::setHash() + * @var int + * @access private + */ + private $length; + + /** + * Hash Algorithm + * + * @see self::setHash() + * @var string + * @access private + */ + private $algo; + + /** + * Key + * + * @see self::setKey() + * @var string + * @access private + */ + private $key = false; + + /** + * Nonce + * + * @see self::setNonce() + * @var string + * @access private + */ + private $nonce = false; + + /** + * Hash Parameters + * + * @var array + * @access private + */ + private $parameters = []; + + /** + * Computed Key + * + * @see self::_computeKey() + * @var string + * @access private + */ + private $computedKey = false; + + /** + * Outer XOR (Internal HMAC) + * + * Used only for sha512/* + * + * @see self::hash() + * @var string + * @access private + */ + private $opad; + + /** + * Inner XOR (Internal HMAC) + * + * Used only for sha512/* + * + * @see self::hash() + * @var string + * @access private + */ + private $ipad; + + /** + * Recompute AES Key + * + * Used only for umac + * + * @see self::hash() + * @var boolean + * @access private + */ + private $recomputeAESKey; + + /** + * umac cipher object + * + * @see self::hash() + * @var \phpseclib3\Crypt\AES + * @access private + */ + private $c; + + /** + * umac pad + * + * @see self::hash() + * @var string + * @access private + */ + private $pad; + + /**#@+ + * UMAC variables + * + * @var PrimeField + */ + private static $factory36; + private static $factory64; + private static $factory128; + private static $offset64; + private static $offset128; + private static $marker64; + private static $marker128; + private static $maxwordrange64; + private static $maxwordrange128; + /**#@-*/ + + /** + * Default Constructor. + * + * @param string $hash + * @access public + */ + public function __construct($hash = 'sha256') + { + $this->setHash($hash); + } + + /** + * Sets the key for HMACs + * + * Keys can be of any length. + * + * @access public + * @param string $key + */ + public function setKey($key = false) + { + $this->key = $key; + $this->computeKey(); + $this->recomputeAESKey = true; + } + + /** + * Sets the nonce for UMACs + * + * Keys can be of any length. + * + * @access public + * @param string $nonce + */ + public function setNonce($nonce = false) + { + switch (true) { + case !is_string($nonce): + case strlen($nonce) > 0 && strlen($nonce) <= 16: + $this->recomputeAESKey = true; + $this->nonce = $nonce; + return; + } + + throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive'); + } + + /** + * Pre-compute the key used by the HMAC + * + * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes + * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC." + * + * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/ + * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during + * every call + * + * @access private + */ + private function computeKey() + { + if ($this->key === false) { + $this->computedKey = false; + return; + } + + if (strlen($this->key) <= $this->getBlockLengthInBytes()) { + $this->computedKey = $this->key; + return; + } + + $this->computedKey = is_array($this->algo) ? + call_user_func($this->algo, $this->key) : + hash($this->algo, $this->key, true); + } + + /** + * Gets the hash function. + * + * As set by the constructor or by the setHash() method. + * + * @access public + * @return string + */ + public function getHash() + { + return $this->hashParam; + } + + /** + * Sets the hash function. + * + * @access public + * @param string $hash + */ + public function setHash($hash) + { + $this->hashParam = $hash = strtolower($hash); + switch ($hash) { + case 'umac-32': + case 'umac-64': + case 'umac-96': + case 'umac-128': + $this->blockSize = 128; + $this->length = abs(substr($hash, -3)) >> 3; + $this->algo = 'umac'; + return; + case 'md2-96': + case 'md5-96': + case 'sha1-96': + case 'sha224-96': + case 'sha256-96': + case 'sha384-96': + case 'sha512-96': + case 'sha512/224-96': + case 'sha512/256-96': + $hash = substr($hash, 0, -3); + $this->length = 12; // 96 / 8 = 12 + break; + case 'md2': + case 'md5': + $this->length = 16; + break; + case 'sha1': + $this->length = 20; + break; + case 'sha224': + case 'sha512/224': + case 'sha3-224': + $this->length = 28; + break; + case 'sha256': + case 'sha512/256': + case 'sha3-256': + $this->length = 32; + break; + case 'sha384': + case 'sha3-384': + $this->length = 48; + break; + case 'sha512': + case 'sha3-512': + $this->length = 64; + break; + default: + if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) { + $this->paddingType = self::PADDING_SHAKE; + $hash = $matches[1]; + $this->length = $matches[2] >> 3; + } else { + throw new UnsupportedAlgorithmException( + "$hash is not a supported algorithm" + ); + } + } + + switch ($hash) { + case 'md2': + case 'md2-96': + $this->blockSize = 128; + break; + case 'md5-96': + case 'sha1-96': + case 'sha224-96': + case 'sha256-96': + case 'md5': + case 'sha1': + case 'sha224': + case 'sha256': + $this->blockSize = 512; + break; + case 'sha3-224': + $this->blockSize = 1152; // 1600 - 2*224 + break; + case 'sha3-256': + case 'shake256': + $this->blockSize = 1088; // 1600 - 2*256 + break; + case 'sha3-384': + $this->blockSize = 832; // 1600 - 2*384 + break; + case 'sha3-512': + $this->blockSize = 576; // 1600 - 2*512 + break; + case 'shake128': + $this->blockSize = 1344; // 1600 - 2*128 + break; + default: + $this->blockSize = 1024; + } + + if (in_array(substr($hash, 0, 5), ['sha3-', 'shake'])) { + // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": + // http://php.net/ChangeLog-7.php#7.1.0 + if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0,5) == 'shake') { + //preg_match('#(\d+)$#', $hash, $matches); + //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize + //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize + if (!$this->paddingType) { + $this->paddingType = self::PADDING_SHA3; + } + $this->parameters = [ + 'capacity' => 1600 - $this->blockSize, + 'rate' => $this->blockSize, + 'length' => $this->length, + 'padding' => $this->paddingType + ]; + $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32']; + } + } + + if ($hash == 'sha512/224' || $hash == 'sha512/256') { + // PHP 7.1.0 introduced sha512/224 and sha512/256 support: + // http://php.net/ChangeLog-7.php#7.1.0 + if (version_compare(PHP_VERSION, '7.1.0') < 0) { + // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24 + $initial = $hash == 'sha512/256' ? + [ + '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD', + '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2' + ] : + [ + '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF', + '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1' + ]; + for ($i = 0; $i < 8; $i++) { + $initial[$i] = new BigInteger($initial[$i], 16); + $initial[$i]->setPrecision(64); + } + + $this->parameters = compact('initial'); + + $hash = ['phpseclib3\Crypt\Hash', 'sha512']; + } + } + + if (is_array($hash)) { + $b = $this->blockSize >> 3; + $this->ipad = str_repeat(chr(0x36), $b); + $this->opad = str_repeat(chr(0x5C), $b); + } + + $this->algo = $hash; + + $this->computeKey(); + } + + /** + * KDF: Key-Derivation Function + * + * The key-derivation function generates pseudorandom bits used to key the hash functions. + * + * @param int $index a non-negative integer less than 2^64 + * @param int $numbytes a non-negative integer less than 2^64 + * @return string string of length numbytes bytes + */ + private function kdf($index, $numbytes) + { + $this->c->setIV(pack('N4', 0, $index, 0, 1)); + + return $this->c->encrypt(str_repeat("\0", $numbytes)); + } + + /** + * PDF Algorithm + * + * @return string string of length taglen bytes. + */ + private function pdf() + { + $k = $this->key; + $nonce = $this->nonce; + $taglen = $this->length; + + // + // Extract and zero low bit(s) of Nonce if needed + // + if ($taglen <= 8) { + $last = strlen($nonce) - 1; + $mask = $taglen == 4 ? "\3" : "\1"; + $index = $nonce[$last] & $mask; + $nonce[$last] = $nonce[$last] ^ $index; + } + + // + // Make Nonce BLOCKLEN bytes by appending zeroes if needed + // + $nonce = str_pad($nonce, 16, "\0"); + + // + // Generate subkey, encipher and extract indexed substring + // + $kp = $this->kdf(0, 16); + $c = new AES('ctr'); + $c->disablePadding(); + $c->setKey($kp); + $c->setIV($nonce); + $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); + + // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you + // unpack() doesn't leak timing info + return $taglen <= 8 ? + substr($t, unpack('C', $index)[1] * $taglen, $taglen) : + substr($t, 0, $taglen); + } + + /** + * UHASH Algorithm + * + * @param string $m string of length less than 2^67 bits. + * @param int $taglen the integer 4, 8, 12 or 16. + * @return string string of length taglen bytes. + */ + private function uhash($m, $taglen) + { + // + // One internal iteration per 4 bytes of output + // + $iters = $taglen >> 2; + + // + // Define total key needed for all iterations using KDF. + // L1Key reuses most key material between iterations. + // + //$L1Key = $this->kdf(1, 1024 + ($iters - 1) * 16); + $L1Key = $this->kdf(1, (1024 + ($iters - 1)) * 16); + $L2Key = $this->kdf(2, $iters * 24); + $L3Key1 = $this->kdf(3, $iters * 64); + $L3Key2 = $this->kdf(4, $iters * 4); + + // + // For each iteration, extract key and do three-layer hash. + // If bytelength(M) <= 1024, then skip L2-HASH. + // + $y = ''; + for ($i = 0; $i < $iters; $i++) { + $L1Key_i = substr($L1Key, $i * 16, 1024); + $L2Key_i = substr($L2Key, $i * 24, 24); + $L3Key1_i = substr($L3Key1, $i * 64, 64); + $L3Key2_i = substr($L3Key2, $i * 4, 4); + + $a = self::L1Hash($L1Key_i, $m); + $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a); + $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b); + $y.= $c; + } + + return $y; + } + + /** + * L1-HASH Algorithm + * + * The first-layer hash breaks the message into 1024-byte chunks and + * hashes each with a function called NH. Concatenating the results + * forms a string, which is up to 128 times shorter than the original. + * + * @param string $k string of length 1024 bytes. + * @param string $m string of length less than 2^67 bits. + * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes. + */ + private static function L1Hash($k, $m) + { + // + // Break M into 1024 byte chunks (final chunk may be shorter) + // + $m = str_split($m, 1024); + + // + // For each chunk, except the last: endian-adjust, NH hash + // and add bit-length. Use results to build Y. + // + $length = new BigInteger(1024 * 8); + $y = ''; + for ($i = 0; $i < count($m) - 1; $i++) { + $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP + $y.= static::nh($k, $m[$i], $length); + } + + // + // For the last chunk: pad to 32-byte boundary, endian-adjust, + // NH hash and add bit-length. Concatenate the result to Y. + // + $length = strlen($m[$i]); + $pad = 32 - ($length % 32); + $pad = max(32, $length + $pad % 32); + $m[$i] = str_pad($m[$i], $pad, "\0"); // zeropad + $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP + + $y.= static::nh($k, $m[$i], new BigInteger($length * 8)); + + return $y; + } + + /** + * NH Algorithm + * + * @param string $k string of length 1024 bytes. + * @param string $m string with length divisible by 32 bytes. + * @return string string of length 8 bytes. + */ + private static function nh($k, $m, $length) + { + $toUInt32 = function($x) { + $x = new BigInteger($x, 256); + $x->setPrecision(32); + return $x; + }; + + // + // Break M and K into 4-byte chunks + // + //$t = strlen($m) >> 2; + $m = str_split($m, 4); + $t = count($m); + $k = str_split($k, 4); + $k = array_pad(array_slice($k, 0, $t), $t, 0); + + $m = array_map($toUInt32, $m); + $k = array_map($toUInt32, $k); + + // + // Perform NH hash on the chunks, pairing words for multiplication + // which are 4 apart to accommodate vector-parallelism. + // + $y = new BigInteger; + $y->setPrecision(64); + $i = 0; + while ($i < $t) { + $temp = $m[$i]->add($k[$i]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 4]->add($k[$i + 4])); + $y = $y->add($temp); + + $temp = $m[$i + 1]->add($k[$i + 1]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 5]->add($k[$i + 5])); + $y = $y->add($temp); + + $temp = $m[$i + 2]->add($k[$i + 2]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 6]->add($k[$i + 6])); + $y = $y->add($temp); + + $temp = $m[$i + 3]->add($k[$i + 3]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 7]->add($k[$i + 7])); + $y = $y->add($temp); + + $i+= 8; + } + + return $y->add($length)->toBytes(); + } + + /** + * L2-HASH: Second-Layer Hash + * + * The second-layer rehashes the L1-HASH output using a polynomial hash + * called POLY. If the L1-HASH output is long, then POLY is called once + * on a prefix of the L1-HASH output and called using different settings + * on the remainder. (This two-step hashing of the L1-HASH output is + * needed only if the message length is greater than 16 megabytes.) + * Careful implementation of POLY is necessary to avoid a possible + * timing attack (see Section 6.6 for more information). + * + * @param string $k string of length 24 bytes. + * @param string $m string of length less than 2^64 bytes. + * @return string string of length 16 bytes. + */ + private static function L2Hash($k, $m) + { + // + // Extract keys and restrict to special key-sets + // + $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; + $k64 = new BigInteger($k64, 256); + $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; + $k128 = new BigInteger($k128, 256); + + // + // If M is no more than 2^17 bytes, hash under 64-bit prime, + // otherwise, hash first 2^17 bytes under 64-bit prime and + // remainder under 128-bit prime. + // + if (strlen($m) <= 0x20000) { // 2^14 64-bit words + $y = self::poly(64, self::$maxwordrange64, $k64, $m); + } else { + $m_1 = substr($m, 0, 0x20000); // 1 << 17 + $m_2 = substr($m, 0x20000) . "\x80"; + $length = strlen($m_2); + $pad = 16 - ($length % 16); + $pad%= 16; + $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad + $y = self::poly(64, self::$maxwordrange64, $k64, $m_1); + $y = str_pad($y, 16, "\0", STR_PAD_LEFT); + $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2); + } + + return str_pad($y, 16, "\0", STR_PAD_LEFT); + } + + /** + * POLY Algorithm + * + * @param int $wordbits the integer 64 or 128. + * @param BigInteger $maxwordrange positive integer less than 2^wordbits. + * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1. + * @param string $m string with length divisible by (wordbits / 8) bytes. + * @return integer in the range 0 ... prime(wordbits) - 1. + */ + private static function poly($wordbits, $maxwordrange, $k, $m) + { + // + // Define constants used for fixing out-of-range words + // + $wordbytes = $wordbits >> 3; + if ($wordbits == 128) { + $factory = self::$factory128; + $offset = self::$offset128; + $marker = self::$marker128; + } else { + $factory = self::$factory64; + $offset = self::$offset64; + $marker = self::$marker64; + } + + $k = $factory->newInteger($k); + + // + // Break M into chunks of length wordbytes bytes + // + $m_i = str_split($m, $wordbytes); + + // + // Each input word m is compared with maxwordrange. If not smaller + // then 'marker' and (m - offset), both in range, are hashed. + // + $y = $factory->newInteger(new BigInteger(1)); + foreach ($m_i as $m) { + $m = $factory->newInteger(new BigInteger($m, 256)); + if ($m->compare($maxwordrange) >= 0) { + $y = $k->multiply($y)->add($marker); + $y = $k->multiply($y)->add($m->subtract($offset)); + } else { + $y = $k->multiply($y)->add($m); + } + } + + return $y->toBytes(); + } + + /** + * L3-HASH: Third-Layer Hash + * + * The output from L2-HASH is 16 bytes long. This final hash function + * hashes the 16-byte string to a fixed length of 4 bytes. + * + * @param string $k1 string of length 64 bytes. + * @param string $k2 string of length 4 bytes. + * @param string $m string of length 16 bytes. + * @return string string of length 4 bytes. + */ + private static function L3Hash($k1, $k2, $m) + { + $factory = self::$factory36; + + $y = $factory->newInteger(new BigInteger()); + for ($i = 0; $i < 8; $i++) { + $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256)); + $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256)); + $y = $y->add($m_i->multiply($k_i)); + } + $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT); + $y = $y ^ $k2; + + return $y; + } + + /** + * Compute the Hash / HMAC / UMAC. + * + * @access public + * @param string $text + * @return string + */ + public function hash($text) + { + $algo = $this->algo; + if ($algo == 'umac') { + if ($this->recomputeAESKey) { + if (!is_string($this->nonce)) { + throw new InsufficientSetupException('No nonce has been set'); + } + if (!is_string($this->key)) { + throw new InsufficientSetupException('No key has been set'); + } + if (strlen($this->key) != 16) { + throw new \LengthException('Key must be 16 bytes long'); + } + + if (!isset(self::$maxwordrange64)) { + $one = new BigInteger(1); + + $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256); + self::$factory36 = new PrimeField($prime36); + + $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256); + self::$factory64 = new PrimeField($prime64); + + $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256); + self::$factory128 = new PrimeField($prime128); + + self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256); + self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64)); + self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256); + self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128)); + + self::$marker64 = self::$factory64->newInteger($prime64->subtract($one)); + self::$marker128 = self::$factory128->newInteger($prime128->subtract($one)); + + $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32)); + self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64); + + $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96)); + self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128); + } + + $this->c = new AES('ctr'); + $this->c->disablePadding(); + $this->c->setKey($this->key); + + $this->pad = $this->pdf(); + + $this->recomputeAESKey = false; + } + + $hashedmessage = $this->uhash($text, $this->length); + return $hashedmessage ^ $this->pad; + } + + if (is_array($algo)) { + if (empty($this->key) || !is_string($this->key)) { + return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); + } + + // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 + + $key = str_pad($this->computedKey, $b, chr(0)); + $temp = $this->ipad ^ $key; + $temp .= $text; + $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); + $output = $this->opad ^ $key; + $output.= $temp; + $output = $algo($output, ...array_values($this->parameters)); + + return substr($output, 0, $this->length); + } + + $output = !empty($this->key) || is_string($this->key) ? + hash_hmac($algo, $text, $this->computedKey, true) : + hash($algo, $text, true); + + return strlen($output) > $this->length + ? substr($output, 0, $this->length) + : $output; + } + + /** + * Returns the hash length (in bits) + * + * @access public + * @return int + */ + public function getLength() + { + return $this->length << 3; + } + + /** + * Returns the hash length (in bytes) + * + * @access public + * @return int + */ + public function getLengthInBytes() + { + return $this->length; + } + + /** + * Returns the block length (in bits) + * + * @access public + * @return int + */ + public function getBlockLength() + { + return $this->blockSize; + } + + /** + * Returns the block length (in bytes) + * + * @access public + * @return int + */ + public function getBlockLengthInBytes() + { + return $this->blockSize >> 3; + } + + /** + * Pads SHA3 based on the mode + * + * @access private + * @param int $padLength + * @param int $padType + * @return string + */ + private static function sha3_pad($padLength, $padType) + { + switch ($padType) { + //case self::PADDING_KECCAK: + // $temp = chr(0x06) . str_repeat("\0", $padLength - 1); + // $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); + // return $temp + case self::PADDING_SHAKE: + $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); + $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); + return $temp; + //case self::PADDING_SHA3: + default: + // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36 + return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80); + } + } + + /** + * Pure-PHP 32-bit implementation of SHA3 + * + * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation + * of SHA3 will *not* work on PHP 64-bit. This is because this implementation + * employees bitwise NOTs and bitwise left shifts. And the round constants only work + * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and + * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow + * things down. + * + * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees + * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed + * 64-bit integers, which complicates addition, whereas that limitation isn't an issue + * for SHA3. + * + * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is + * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and + * capacity c". This is relevant because, altho the KECCAK standard defines a mode + * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3 + * + * @access private + * @param string $p + * @param int $c + * @param int $r + * @param int $d + * @param int $padType + */ + private static function sha3_32($p, $c, $r, $d, $padType) + { + $block_size = $r >> 3; + $padLength = $block_size - (strlen($p) % $block_size); + $num_ints = $block_size >> 2; + + $p.= static::sha3_pad($padLength, $padType); + + $n = strlen($p) / $r; // number of blocks + + $s = [ + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] + ]; + + $p = str_split($p, $block_size); + + foreach ($p as $pi) { + $pi = unpack('V*', $pi); + $x = $y = 0; + for ($i = 1; $i <= $num_ints; $i+=2) { + $s[$x][$y][0]^= $pi[$i + 1]; + $s[$x][$y][1]^= $pi[$i]; + if (++$y == 5) { + $y = 0; + $x++; + } + } + static::processSHA3Block32($s); + } + + $z = ''; + $i = $j = 0; + while (strlen($z) < $d) { + $z.= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]); + if ($j == 5) { + $j = 0; + $i++; + if ($i == 5) { + $i = 0; + static::processSHA3Block32($s); + } + } + } + + return $z; + } + + /** + * 32-bit block processing method for SHA3 + * + * @access private + * @param array $s + */ + private static function processSHA3Block32(&$s) + { + static $rotationOffsets = [ + [ 0, 1, 62, 28, 27], + [36, 44, 6, 55, 20], + [ 3, 10, 43, 25, 39], + [41, 45, 15, 21, 8], + [18, 2, 61, 56, 14] + ]; + + // the standards give these constants in hexadecimal notation. it's tempting to want to use + // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive + // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead + static $roundConstants = [ + [0, 1], + [0, 32898], + [-2147483648, 32906], + [-2147483648, -2147450880], + [0, 32907], + [0, -2147483647], + [-2147483648, -2147450751], + [-2147483648, 32777], + [0, 138], + [0, 136], + [0, -2147450871], + [0, -2147483638], + [0, -2147450741], + [-2147483648, 139], + [-2147483648, 32905], + [-2147483648, 32771], + [-2147483648, 32770], + [-2147483648, 128], + [0, 32778], + [-2147483648, -2147483638], + [-2147483648, -2147450751], + [-2147483648, 32896], + [0, -2147483647], + [-2147483648, -2147450872] + ]; + + for ($round = 0; $round < 24; $round++) { + // theta step + $parity = $rotated = []; + for ($i = 0; $i < 5; $i++) { + $parity[] = [ + $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0], + $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1] + ]; + $rotated[] = static::rotateLeft32($parity[$i], 1); + } + + $temp = [ + [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]], + [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]], + [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]], + [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]], + [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]] + ]; + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $s[$i][$j][0]^= $temp[$j][0]; + $s[$i][$j][1]^= $temp[$j][1]; + } + } + + $st = $s; + + // rho and pi steps + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]); + } + } + + // chi step + for ($i = 0; $i < 5; $i++) { + $s[$i][0] = [ + $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]), + $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1]) + ]; + $s[$i][1] = [ + $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]), + $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1]) + ]; + $s[$i][2] = [ + $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]), + $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1]) + ]; + $s[$i][3] = [ + $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]), + $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1]) + ]; + $s[$i][4] = [ + $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]), + $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1]) + ]; + } + + // iota step + $s[0][0][0]^= $roundConstants[$round][0]; + $s[0][0][1]^= $roundConstants[$round][1]; + } + } + + /** + * Rotate 32-bit int + * + * @access private + * @param array $x + * @param int $shift + */ + private static function rotateLeft32($x, $shift) + { + if ($shift < 32) { + list($hi, $lo) = $x; + } else { + $shift-= 32; + list($lo, $hi) = $x; + } + + return [ + ($hi << $shift) | (($lo >> (32 - $shift)) & (1 << $shift) - 1), + ($lo << $shift) | (($hi >> (32 - $shift)) & (1 << $shift) - 1) + ]; + } + + /** + * Pure-PHP 64-bit implementation of SHA3 + * + * @access private + * @param string $p + * @param int $c + * @param int $r + * @param int $d + * @param int $padType + */ + private static function sha3_64($p, $c, $r, $d, $padType) + { + $block_size = $r >> 3; + $padLength = $block_size - (strlen($p) % $block_size); + $num_ints = $block_size >> 2; + + $p.= static::sha3_pad($padLength, $padType); + + $n = strlen($p) / $r; // number of blocks + + $s = [ + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0] + ]; + + $p = str_split($p, $block_size); + + foreach ($p as $pi) { + $pi = unpack('P*', $pi); + $x = $y = 0; + foreach ($pi as $subpi) { + $s[$x][$y++]^= $subpi; + if ($y == 5) { + $y = 0; + $x++; + } + } + static::processSHA3Block64($s); + } + + $z = ''; + $i = $j = 0; + while (strlen($z) < $d) { + $z.= pack('P', $s[$i][$j++]); + if ($j == 5) { + $j = 0; + $i++; + if ($i == 5) { + $i = 0; + static::processSHA3Block64($s); + } + } + } + + return $z; + } + + /** + * 64-bit block processing method for SHA3 + * + * @access private + * @param array $s + */ + private static function processSHA3Block64(&$s) + { + static $rotationOffsets = [ + [ 0, 1, 62, 28, 27], + [36, 44, 6, 55, 20], + [ 3, 10, 43, 25, 39], + [41, 45, 15, 21, 8], + [18, 2, 61, 56, 14] + ]; + + static $roundConstants = [ + 1, + 32898, + -9223372036854742902, + -9223372034707259392, + 32907, + 2147483649, + -9223372034707259263, + -9223372036854743031, + 138, + 136, + 2147516425, + 2147483658, + 2147516555, + -9223372036854775669, + -9223372036854742903, + -9223372036854743037, + -9223372036854743038, + -9223372036854775680, + 32778, + -9223372034707292150, + -9223372034707259263, + -9223372036854742912, + 2147483649, + -9223372034707259384 + ]; + + for ($round = 0; $round < 24; $round++) { + // theta step + $parity = []; + for ($i = 0; $i < 5; $i++) { + $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i]; + } + $temp = [ + $parity[4] ^ static::rotateLeft64($parity[1], 1), + $parity[0] ^ static::rotateLeft64($parity[2], 1), + $parity[1] ^ static::rotateLeft64($parity[3], 1), + $parity[2] ^ static::rotateLeft64($parity[4], 1), + $parity[3] ^ static::rotateLeft64($parity[0], 1) + ]; + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $s[$i][$j]^= $temp[$j]; + } + } + + $st = $s; + + // rho and pi steps + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]); + } + } + + // chi step + for ($i = 0; $i < 5; $i++) { + $s[$i] = [ + $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]), + $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]), + $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]), + $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]), + $st[$i][4] ^ (~$st[$i][0] & $st[$i][1]) + ]; + } + + // iota step + $s[0][0]^= $roundConstants[$round]; + } + } + + /** + * Rotate 64-bit int + * + * @access private + * @param int $x + * @param int $shift + */ + private static function rotateLeft64($x, $shift) + { + return ($x << $shift) | (($x >> (64 - $shift)) & ((1 << $shift) - 1)); + } + + /** + * Pure-PHP implementation of SHA512 + * + * @access private + * @param string $m + * @param array $hash + * @return string + */ + private static function sha512($m, $hash) + { + static $k; + + if (!isset($k)) { + // Initialize table of round constants + // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) + $k = [ + '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', + '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', + 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', + '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', + 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', + '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', + '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', + 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', + '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', + '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', + 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', + 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', + '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', + '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', + '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', + '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', + 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', + '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', + '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', + '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' + ]; + + for ($i = 0; $i < 80; $i++) { + $k[$i] = new BigInteger($k[$i], 16); + } + } + + // Pre-processing + $length = strlen($m); + // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 + $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); + $m[$length] = chr(0x80); + // we don't support hashing strings 512MB long + $m.= pack('N4', 0, 0, 0, $length << 3); + + // Process the message in successive 1024-bit chunks + $chunks = str_split($m, 128); + foreach ($chunks as $chunk) { + $w = []; + for ($i = 0; $i < 16; $i++) { + $temp = new BigInteger(Strings::shift($chunk, 8), 256); + $temp->setPrecision(64); + $w[] = $temp; + } + + // Extend the sixteen 32-bit words into eighty 32-bit words + for ($i = 16; $i < 80; $i++) { + $temp = [ + $w[$i - 15]->bitwise_rightRotate(1), + $w[$i - 15]->bitwise_rightRotate(8), + $w[$i - 15]->bitwise_rightShift(7) + ]; + $s0 = $temp[0]->bitwise_xor($temp[1]); + $s0 = $s0->bitwise_xor($temp[2]); + $temp = [ + $w[$i - 2]->bitwise_rightRotate(19), + $w[$i - 2]->bitwise_rightRotate(61), + $w[$i - 2]->bitwise_rightShift(6) + ]; + $s1 = $temp[0]->bitwise_xor($temp[1]); + $s1 = $s1->bitwise_xor($temp[2]); + $w[$i] = clone $w[$i - 16]; + $w[$i] = $w[$i]->add($s0); + $w[$i] = $w[$i]->add($w[$i - 7]); + $w[$i] = $w[$i]->add($s1); + } + + // Initialize hash value for this chunk + $a = clone $hash[0]; + $b = clone $hash[1]; + $c = clone $hash[2]; + $d = clone $hash[3]; + $e = clone $hash[4]; + $f = clone $hash[5]; + $g = clone $hash[6]; + $h = clone $hash[7]; + + // Main loop + for ($i = 0; $i < 80; $i++) { + $temp = [ + $a->bitwise_rightRotate(28), + $a->bitwise_rightRotate(34), + $a->bitwise_rightRotate(39) + ]; + $s0 = $temp[0]->bitwise_xor($temp[1]); + $s0 = $s0->bitwise_xor($temp[2]); + $temp = [ + $a->bitwise_and($b), + $a->bitwise_and($c), + $b->bitwise_and($c) + ]; + $maj = $temp[0]->bitwise_xor($temp[1]); + $maj = $maj->bitwise_xor($temp[2]); + $t2 = $s0->add($maj); + + $temp = [ + $e->bitwise_rightRotate(14), + $e->bitwise_rightRotate(18), + $e->bitwise_rightRotate(41) + ]; + $s1 = $temp[0]->bitwise_xor($temp[1]); + $s1 = $s1->bitwise_xor($temp[2]); + $temp = [ + $e->bitwise_and($f), + $g->bitwise_and($e->bitwise_not()) + ]; + $ch = $temp[0]->bitwise_xor($temp[1]); + $t1 = $h->add($s1); + $t1 = $t1->add($ch); + $t1 = $t1->add($k[$i]); + $t1 = $t1->add($w[$i]); + + $h = clone $g; + $g = clone $f; + $f = clone $e; + $e = $d->add($t1); + $d = clone $c; + $c = clone $b; + $b = clone $a; + $a = $t1->add($t2); + } + + // Add this chunk's hash to result so far + $hash = [ + $hash[0]->add($a), + $hash[1]->add($b), + $hash[2]->add($c), + $hash[3]->add($d), + $hash[4]->add($e), + $hash[5]->add($f), + $hash[6]->add($g), + $hash[7]->add($h) + ]; + } + + // Produce the final hash value (big-endian) + // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) + $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . + $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes(); + + return $temp; + } + + /** + * __toString() magic method + */ + public function __toString() + { + return $this->getHash(); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php new file mode 100644 index 000000000..c7c7e0af4 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php @@ -0,0 +1,64 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\File\X509; + +/** + * PublicKeyLoader + * + * @package Common + * @author Jim Wigginton + * @access public + */ +abstract class PublicKeyLoader +{ + /** + * Loads a public or private key + * + * @return AsymmetricKey + * @access public + * @param string|array $key + * @param string $password optional + */ + public static function load($key, $password = false) + { + try { + return EC::load($key, $password); + } catch (NoKeyLoadedException $e) {} + + try { + return RSA::load($key, $password); + } catch (NoKeyLoadedException $e) {} + + try { + return DSA::load($key, $password); + } catch (NoKeyLoadedException $e) {} + + try { + $x509 = new X509(); + $x509->loadX509($key); + $key = $x509->getPublicKey(); + if ($key) { + return $key; + } + } catch (\Exception $e) {} + + throw new NoKeyLoadedException('Unable to read key'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php new file mode 100644 index 000000000..813eeca45 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php @@ -0,0 +1,669 @@ + + * setKey('abcdefgh'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $rc2->decrypt($rc2->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package RC2 + * @author Patrick Monnerat + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; + +/** + * Pure-PHP implementation of RC2. + * + * @package RC2 + * @access public + */ +class RC2 extends BlockCipher +{ + /** + * Block Length of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + * @access private + */ + protected $block_size = 8; + + /** + * The Key + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::key + * @see self::setKey() + * @var string + * @access private + */ + protected $key; + + /** + * The Original (unpadded) Key + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::key + * @see self::setKey() + * @see self::encrypt() + * @see self::decrypt() + * @var string + * @access private + */ + private $orig_key; + + /** + * Don't truncate / null pad key + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::clearBuffers() + * @var bool + * @access private + */ + private $skip_key_adjustment = true; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\RC2::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 16; // = 128 bits + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + * @access private + */ + protected $cipher_name_mcrypt = 'rc2'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + * @access private + */ + protected $cfb_init_len = 500; + + /** + * The key length in bits. + * + * {@internal Should be in range [1..1024].} + * + * {@internal Changing this value after setting the key has no effect.} + * + * @see self::setKeyLength() + * @see self::setKey() + * @var int + * @access private + */ + private $default_key_length = 1024; + + /** + * The key length in bits. + * + * {@internal Should be in range [1..1024].} + * + * @see self::isValidEnine() + * @see self::setKey() + * @var int + * @access private + */ + private $current_key_length; + + /** + * The Key Schedule + * + * @see self::setupKey() + * @var array + * @access private + */ + private $keys; + + /** + * Key expansion randomization table. + * Twice the same 256-value sequence to save a modulus in key expansion. + * + * @see self::setKey() + * @var array + * @access private + */ + private static $pitable = [ + 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, + 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, + 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, + 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, + 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, + 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, + 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, + 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, + 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, + 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, + 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, + 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, + 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, + 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, + 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, + 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, + 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, + 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, + 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, + 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, + 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, + 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, + 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, + 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, + 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, + 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, + 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, + 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, + 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, + 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, + 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, + 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD, + 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, + 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, + 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, + 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, + 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, + 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, + 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, + 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, + 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, + 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, + 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, + 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, + 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, + 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, + 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, + 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, + 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, + 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, + 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, + 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, + 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, + 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, + 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, + 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, + 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, + 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, + 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, + 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, + 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, + 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, + 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, + 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD + ]; + + /** + * Inverse key expansion randomization table. + * + * @see self::setKey() + * @var array + * @access private + */ + private static $invpitable = [ + 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66, + 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4, + 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20, + 0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53, + 0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68, + 0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B, + 0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12, + 0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB, + 0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3, + 0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26, + 0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67, + 0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB, + 0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC, + 0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60, + 0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7, + 0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD, + 0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24, + 0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31, + 0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE, + 0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99, + 0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C, + 0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA, + 0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35, + 0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61, + 0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72, + 0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3, + 0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F, + 0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9, + 0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77, + 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75, + 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87, + 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6 + ]; + + /** + * Default Constructor. + * + * @param string $mode + * @access public + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @access protected + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_OPENSSL: + if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { + return false; + } + self::$cipher_name_openssl_ecb = 'rc2-ecb'; + $this->cipher_name_openssl = 'rc2-' . $this->openssl_translate_mode(); + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the key length. + * + * Valid key lengths are 8 to 1024. + * Calling this function after setting the key has no effect until the next + * \phpseclib3\Crypt\RC2::setKey() call. + * + * @access public + * @param int $length in bits + * @throws \LengthException if the key length isn't supported + */ + public function setKeyLength($length) + { + if ($length < 8 || $length > 1024) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); + } + + $this->default_key_length = $this->current_key_length = $length; + $this->explicit_key_length = $length >> 3; + } + + /** + * Returns the current key length + * + * @access public + * @return int + */ + public function getKeyLength() + { + return $this->current_key_length; + } + + /** + * Sets the key. + * + * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg. + * strlen($key) <= 128), however, we only use the first 128 bytes if $key + * has more then 128 bytes in it, and set $key to a single null byte if + * it is empty. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * @access public + * @param string $key + * @param int|boolean $t1 optional Effective key length in bits. + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key, $t1 = false) + { + $this->orig_key = $key; + + if ($t1 === false) { + $t1 = $this->default_key_length; + } + + if ($t1 < 1 || $t1 > 1024) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); + } + + $this->current_key_length = $t1; + if (strlen($key) < 1 || strlen($key) > 128) { + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported'); + } + + $t = strlen($key); + + // The mcrypt RC2 implementation only supports effective key length + // of 1024 bits. It is however possible to handle effective key + // lengths in range 1..1024 by expanding the key and applying + // inverse pitable mapping to the first byte before submitting it + // to mcrypt. + + // Key expansion. + $l = array_values(unpack('C*', $key)); + $t8 = ($t1 + 7) >> 3; + $tm = 0xFF >> (8 * $t8 - $t1); + + // Expand key. + $pitable = self::$pitable; + for ($i = $t; $i < 128; $i++) { + $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]]; + } + $i = 128 - $t8; + $l[$i] = $pitable[$l[$i] & $tm]; + while ($i--) { + $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]]; + } + + // Prepare the key for mcrypt. + $l[0] = self::$invpitable[$l[0]]; + array_unshift($l, 'C*'); + + $this->key = pack(...$l); + $this->key_length = strlen($this->key); + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); + } + + /** + * Encrypts a message. + * + * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::encrypt, with some additional OpenSSL handling code + * + * @see self::decrypt() + * @access public + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + if ($this->engine == self::ENGINE_OPENSSL) { + $temp = $this->key; + $this->key = $this->orig_key; + $result = parent::encrypt($plaintext); + $this->key = $temp; + return $result; + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::decrypt, with some additional OpenSSL handling code + * + * @see self::encrypt() + * @access public + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if ($this->engine == self::ENGINE_OPENSSL) { + $temp = $this->key; + $this->key = $this->orig_key; + $result = parent::decrypt($ciphertext); + $this->key = $temp; + return $result; + } + + return parent::decrypt($ciphertext); + } + + /** + * Encrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @access private + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); + $keys = $this->keys; + $limit = 20; + $actions = [$limit => 44, 44 => 64]; + $j = 0; + + for (;;) { + // Mixing round. + $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; + $r0 |= $r0 >> 16; + $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; + $r1 |= $r1 >> 16; + $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; + $r2 |= $r2 >> 16; + $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; + $r3 |= $r3 >> 16; + + if ($j === $limit) { + if ($limit === 64) { + break; + } + + // Mashing round. + $r0 += $keys[$r3 & 0x3F]; + $r1 += $keys[$r0 & 0x3F]; + $r2 += $keys[$r1 & 0x3F]; + $r3 += $keys[$r2 & 0x3F]; + $limit = $actions[$limit]; + } + } + + return pack('vvvv', $r0, $r1, $r2, $r3); + } + + /** + * Decrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @access private + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); + $keys = $this->keys; + $limit = 44; + $actions = [$limit => 20, 20 => 0]; + $j = 64; + + for (;;) { + // R-mixing round. + $r3 = ($r3 | ($r3 << 16)) >> 5; + $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; + $r2 = ($r2 | ($r2 << 16)) >> 3; + $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; + $r1 = ($r1 | ($r1 << 16)) >> 2; + $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; + $r0 = ($r0 | ($r0 << 16)) >> 1; + $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF; + + if ($j === $limit) { + if ($limit === 0) { + break; + } + + // R-mashing round. + $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; + $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; + $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; + $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF; + $limit = $actions[$limit]; + } + } + + return pack('vvvv', $r0, $r1, $r2, $r3); + } + + /** + * Creates the key schedule + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @access private + */ + protected function setupKey() + { + if (!isset($this->key)) { + $this->setKey(''); + } + + // Key has already been expanded in \phpseclib3\Crypt\RC2::setKey(): + // Only the first value must be altered. + $l = unpack('Ca/Cb/v*', $this->key); + array_unshift($l, self::$pitable[$l['a']] | ($l['b'] << 8)); + unset($l['a']); + unset($l['b']); + $this->keys = $l; + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + * @access private + */ + protected function setupInlineCrypt() + { + // Init code for both, encrypt and decrypt. + $init_crypt = '$keys = $this->keys;'; + + $keys = $this->keys; + + // $in is the current 8 bytes block which has to be en/decrypt + $encrypt_block = $decrypt_block = ' + $in = unpack("v4", $in); + $r0 = $in[1]; + $r1 = $in[2]; + $r2 = $in[3]; + $r3 = $in[4]; + '; + + // Create code for encryption. + $limit = 20; + $actions = [$limit => 44, 44 => 64]; + $j = 0; + + for (;;) { + // Mixing round. + $encrypt_block .= ' + $r0 = (($r0 + ' . $keys[$j++] . ' + + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; + $r0 |= $r0 >> 16; + $r1 = (($r1 + ' . $keys[$j++] . ' + + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; + $r1 |= $r1 >> 16; + $r2 = (($r2 + ' . $keys[$j++] . ' + + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; + $r2 |= $r2 >> 16; + $r3 = (($r3 + ' . $keys[$j++] . ' + + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; + $r3 |= $r3 >> 16;'; + + if ($j === $limit) { + if ($limit === 64) { + break; + } + + // Mashing round. + $encrypt_block .= ' + $r0 += $keys[$r3 & 0x3F]; + $r1 += $keys[$r0 & 0x3F]; + $r2 += $keys[$r1 & 0x3F]; + $r3 += $keys[$r2 & 0x3F];'; + $limit = $actions[$limit]; + } + } + + $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + + // Create code for decryption. + $limit = 44; + $actions = [$limit => 20, 20 => 0]; + $j = 64; + + for (;;) { + // R-mixing round. + $decrypt_block .= ' + $r3 = ($r3 | ($r3 << 16)) >> 5; + $r3 = ($r3 - ' . $keys[--$j] . ' - + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; + $r2 = ($r2 | ($r2 << 16)) >> 3; + $r2 = ($r2 - ' . $keys[--$j] . ' - + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; + $r1 = ($r1 | ($r1 << 16)) >> 2; + $r1 = ($r1 - ' . $keys[--$j] . ' - + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; + $r0 = ($r0 | ($r0 << 16)) >> 1; + $r0 = ($r0 - ' . $keys[--$j] . ' - + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; + + if ($j === $limit) { + if ($limit === 0) { + break; + } + + // R-mashing round. + $decrypt_block .= ' + $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; + $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; + $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; + $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; + $limit = $actions[$limit]; + } + } + + $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + + // Creates the inline-crypt function + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php new file mode 100644 index 000000000..d2d3a71c0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php @@ -0,0 +1,309 @@ + + * setKey('abcdefgh'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rc4->decrypt($rc4->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package RC4 + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\StreamCipher; + +/** + * Pure-PHP implementation of RC4. + * + * @package RC4 + * @author Jim Wigginton + * @access public + */ +class RC4 extends StreamCipher +{ + /** + * @access private + * @see \phpseclib3\Crypt\RC4::_crypt() + */ + const ENCRYPT = 0; + + /** + * @access private + * @see \phpseclib3\Crypt\RC4::_crypt() + */ + const DECRYPT = 1; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\RC4::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 128; // = 1024 bits + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + * @access private + */ + protected $cipher_name_mcrypt = 'arcfour'; + + /** + * The Key + * + * @see self::setKey() + * @var string + * @access private + */ + protected $key; + + /** + * The Key Stream for decryption and encryption + * + * @see self::setKey() + * @var array + * @access private + */ + private $stream; + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @access protected + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($engine == self::ENGINE_OPENSSL) { + if ($this->continuousBuffer) { + return false; + } + if (version_compare(PHP_VERSION, '5.3.7') >= 0) { + $this->cipher_name_openssl = 'rc4-40'; + } else { + switch (strlen($this->key)) { + case 5: + $this->cipher_name_openssl = 'rc4-40'; + break; + case 8: + $this->cipher_name_openssl = 'rc4-64'; + break; + case 16: + $this->cipher_name_openssl = 'rc4'; + break; + default: + return false; + } + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the key length + * + * Keys can be between 1 and 256 bytes long. + * + * @access public + * @param int $length + * @throws \LengthException if the key length is invalid + */ + public function setKeyLength($length) + { + if ($length < 8 || $length > 2048) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported'); + } + + $this->key_length = $length >> 3; + + parent::setKeyLength($length); + } + + /** + * Sets the key length + * + * Keys can be between 1 and 256 bytes long. + * + * @access public + * @param string $key + */ + public function setKey($key) + { + $length = strlen($key); + if ($length < 1 || $length > 256) { + throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); + } + + parent::setKey($key); + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @access public + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + if ($this->engine != self::ENGINE_INTERNAL) { + return parent::encrypt($plaintext); + } + return $this->crypt($plaintext, self::ENCRYPT); + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @access public + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if ($this->engine != self::ENGINE_INTERNAL) { + return parent::decrypt($ciphertext); + } + return $this->crypt($ciphertext, self::DECRYPT); + } + + /** + * Encrypts a block + * + * @access private + * @param string $in + */ + protected function encryptBlock($in) + { + // RC4 does not utilize this method + } + + /** + * Decrypts a block + * + * @access private + * @param string $in + */ + protected function decryptBlock($in) + { + // RC4 does not utilize this method + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + * @access private + */ + protected function setupKey() + { + $key = $this->key; + $keyLength = strlen($key); + $keyStream = range(0, 255); + $j = 0; + for ($i = 0; $i < 256; $i++) { + $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255; + $temp = $keyStream[$i]; + $keyStream[$i] = $keyStream[$j]; + $keyStream[$j] = $temp; + } + + $this->stream = []; + $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = [ + 0, // index $i + 0, // index $j + $keyStream + ]; + } + + /** + * Encrypts or decrypts a message. + * + * @see self::encrypt() + * @see self::decrypt() + * @access private + * @param string $text + * @param int $mode + * @return string $text + */ + private function crypt($text, $mode) + { + if ($this->changed) { + $this->setup(); + } + + $stream = &$this->stream[$mode]; + if ($this->continuousBuffer) { + $i = &$stream[0]; + $j = &$stream[1]; + $keyStream = &$stream[2]; + } else { + $i = $stream[0]; + $j = $stream[1]; + $keyStream = $stream[2]; + } + + $len = strlen($text); + for ($k = 0; $k < $len; ++$k) { + $i = ($i + 1) & 255; + $ksi = $keyStream[$i]; + $j = ($j + $ksi) & 255; + $ksj = $keyStream[$j]; + + $keyStream[$i] = $ksj; + $keyStream[$j] = $ksi; + $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]); + } + + return $text; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php new file mode 100644 index 000000000..9ff33e677 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -0,0 +1,837 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $ciphertext = $public->encrypt($plaintext); + * + * echo $private->decrypt($ciphertext); + * ?> + * + * + * Here's an example of how to create signatures and verify signatures with this library: + * + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * One thing to consider when using this: so phpseclib uses PSS mode by default. + * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So + * should phpseclib save to the id-RSASSA-PSS format by default or the + * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better + * because SSH doesn't use PSS and idk how many SSH servers would be able to + * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS + * format is used by default (unless you change it up to use PKCS1 instead) + * + * @category Crypt + * @package RSA + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\RSA\PrivateKey; +use phpseclib3\Crypt\RSA\PublicKey; +use phpseclib3\Math\BigInteger; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; + +/** + * Pure-PHP PKCS#1 compliant implementation of RSA. + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class RSA extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + * @access private + */ + const ALGORITHM = 'RSA'; + + /** + * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} + * (OAEP) for encryption / decryption. + * + * Uses sha256 by default + * + * @see self::setHash() + * @see self::setMGFHash() + * @access public + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_OAEP = 1; + /** + * Use PKCS#1 padding. + * + * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards + * compatibility with protocols (like SSH-1) written before OAEP's introduction. + * + * @access public + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_PKCS1 = 2; + /** + * Do not use any padding + * + * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy + * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. + * + * @access public + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_NONE = 4; + + /** + * Use the Probabilistic Signature Scheme for signing + * + * Uses sha256 and 0 as the salt length + * + * @see self::setSaltLength() + * @see self::setMGFHash() + * @see self::setHash() + * @see self::sign() + * @see self::verify() + * @see self::setHash() + * @access public + */ + const SIGNATURE_PSS = 16; + /** + * Use a relaxed version of PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + * @access public + */ + const SIGNATURE_RELAXED_PKCS1 = 32; + /** + * Use PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + * @access public + */ + const SIGNATURE_PKCS1 = 64; + + /** + * Encryption padding mode + * + * @var int + * @access private + */ + protected $encryptionPadding = self::ENCRYPTION_OAEP; + + /** + * Signature padding mode + * + * @var int + * @access private + */ + protected $signaturePadding = self::SIGNATURE_PSS; + + /** + * Length of hash function output + * + * @var int + * @access private + */ + protected $hLen; + + /** + * Length of salt + * + * @var int + * @access private + */ + protected $sLen; + + /** + * Label + * + * @var string + * @access private + */ + protected $label = ''; + + /** + * Hash function for the Mask Generation Function + * + * @var \phpseclib3\Crypt\Hash + * @access private + */ + protected $mgfHash; + + /** + * Length of MGF hash function output + * + * @var int + * @access private + */ + protected $mgfHLen; + + /** + * Modulus (ie. n) + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $modulus; + + /** + * Modulus length + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $k; + + /** + * Exponent (ie. e or d) + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + protected $exponent; + + /** + * Default public exponent + * + * @var int + * @link http://en.wikipedia.org/wiki/65537_%28number%29 + * @access private + */ + private static $defaultExponent = 65537; + + /** + * Enable Blinding? + * + * @var bool + * @access private + */ + protected static $enableBlinding = true; + + /** + * Smallest Prime + * + * Per , this number ought not result in primes smaller + * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime + * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if + * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is + * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's + * a chance neither gmp nor OpenSSL are installed) + * + * @var int + * @access private + */ + private static $smallestPrime = 4096; + + /** + * Sets the public exponent for key generation + * + * This will be 65537 unless changed. + * + * @access public + * @param int $val + */ + public static function setExponent($val) + { + self::$defaultExponent = $val; + } + + /** + * Sets the smallest prime number in bits. Used for key generation + * + * This will be 4096 unless changed. + * + * @access public + * @param int $val + */ + public static function setSmallestPrime($val) + { + self::$smallestPrime = $val; + } + + /** + * Create a private key + * + * The public key can be extracted from the private key + * + * @return RSA + * @access public + * @param int $bits + */ + public static function createKey($bits = 2048) + { + self::initialize_static_variables(); + + static $e; + if (!isset($e)) { + $e = new BigInteger(self::$defaultExponent); + } + + $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be + if ($regSize > self::$smallestPrime) { + $num_primes = floor($bits / self::$smallestPrime); + $regSize = self::$smallestPrime; + } else { + $num_primes = 2; + } + + $n = clone self::$one; + $exponents = $coefficients = $primes = []; + $lcm = [ + 'top' => clone self::$one, + 'bottom' => false + ]; + + do { + for ($i = 1; $i <= $num_primes; $i++) { + if ($i != $num_primes) { + $primes[$i] = BigInteger::randomPrime($regSize); + } else { + extract(BigInteger::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + list($min) = $min->divide($n); + $min = $min->add(self::$one); + list($max) = $max->divide($n); + $primes[$i] = BigInteger::randomRangePrime($min, $max); + } + + // the first coefficient is calculated differently from the rest + // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1]) + if ($i > 2) { + $coefficients[$i] = $n->modInverse($primes[$i]); + } + + $n = $n->multiply($primes[$i]); + + $temp = $primes[$i]->subtract(self::$one); + + // textbook RSA implementations use Euler's totient function instead of the least common multiple. + // see http://en.wikipedia.org/wiki/Euler%27s_totient_function + $lcm['top'] = $lcm['top']->multiply($temp); + $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp); + } + + list($temp) = $lcm['top']->divide($lcm['bottom']); + $gcd = $temp->gcd($e); + $i0 = 1; + } while (!$gcd->equals(self::$one)); + + $coefficients[2] = $primes[2]->modInverse($primes[1]); + + $d = $e->modInverse($temp); + + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $e->modInverse($temp); + } + + // from : + // RSAPrivateKey ::= SEQUENCE { + // version Version, + // modulus INTEGER, -- n + // publicExponent INTEGER, -- e + // privateExponent INTEGER, -- d + // prime1 INTEGER, -- p + // prime2 INTEGER, -- q + // exponent1 INTEGER, -- d mod (p-1) + // exponent2 INTEGER, -- d mod (q-1) + // coefficient INTEGER, -- (inverse of q) mod p + // otherPrimeInfos OtherPrimeInfos OPTIONAL + // } + $privatekey = new PrivateKey; + $privatekey->modulus = $n; + $privatekey->k = $bits >> 3; + $privatekey->publicExponent = $e; + $privatekey->exponent = $d; + $privatekey->privateExponent = $e; + $privatekey->primes = $primes; + $privatekey->exponents = $exponents; + $privatekey->coefficients = $coefficients; + + /* + $publickey = new PublicKey; + $publickey->modulus = $n; + $publickey->k = $bits >> 3; + $publickey->exponent = $e; + $publickey->publicExponent = $e; + $publickey->isPublic = true; + */ + + return $privatekey; + } + + /** + * OnLoad Handler + * + * @return bool + * @access protected + * @param array $components + */ + protected static function onLoad($components) + { + $key = $components['isPublicKey'] ? + new PublicKey : + new PrivateKey; + + $key->modulus = $components['modulus']; + $key->publicExponent = $components['publicExponent']; + $key->k = $key->modulus->getLengthInBytes(); + + if ($components['isPublicKey'] || !isset($components['privateExponent'])) { + $key->exponent = $key->publicExponent; + } else { + $key->privateExponent = $components['privateExponent']; + $key->exponent = $key->privateExponent; + $key->primes = $components['primes']; + $key->exponents = $components['exponents']; + $key->coefficients = $components['coefficients']; + } + + if ($components['format'] == PSS::class) { + // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is + // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib + // uses PSS padding by default. it assumes the more secure method by default and altho it provides + // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent + // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that + // not only does it defaults to the most secure methods - it doesn't even let you choose less + // secure methods + //$key = $key->withPadding(self::SIGNATURE_PSS); + if (isset($components['hash'])) { + $key = $key->withHash($components['hash']); + } + if (isset($components['MGFHash'])) { + $key = $key->withMGFHash($components['MGFHash']); + } + if (isset($components['saltLength'])) { + $key = $key->withSaltLength($components['saltLength']); + } + } + + return $key; + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + parent::__construct(); + + $this->hLen = $this->hash->getLengthInBytes(); + $this->mgfHash = new Hash('sha256'); + $this->mgfHLen = $this->mgfHash->getLengthInBytes(); + } + + /** + * Integer-to-Octet-String primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. + * + * @access private + * @param bool|\phpseclib3\Math\BigInteger $x + * @param int $xLen + * @return bool|string + */ + protected function i2osp($x, $xLen) + { + if ($x === false) { + return false; + } + $x = $x->toBytes(); + if (strlen($x) > $xLen) { + throw new \OutOfRangeException('Resultant string length out of range'); + } + return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); + } + + /** + * Octet-String-to-Integer primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. + * + * @access private + * @param string $x + * @return \phpseclib3\Math\BigInteger + */ + protected function os2ip($x) + { + return new BigInteger($x, 256); + } + + /** + * EMSA-PKCS1-V1_5-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. + * + * @access private + * @param string $m + * @param int $emLen + * @throws \LengthException if the intended encoded message length is too short + * @return string + */ + protected function emsa_pkcs1_v1_5_encode($m, $emLen) + { + $h = $this->hash->hash($m); + + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hash->getHash()) { + case 'md2': + $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10"; + break; + case 'md5': + $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"; + break; + case 'sha1': + $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"; + break; + case 'sha256': + $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; + break; + case 'sha384': + $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"; + break; + case 'sha512': + $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"; + break; + // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 + case 'sha224': + $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"; + break; + case 'sha512/224': + $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c"; + break; + case 'sha512/256': + $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20"; + } + $t.= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + throw new \LengthException('Intended encoded message length too short'); + } + + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; + } + + /** + * MGF1 + * + * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. + * + * @access private + * @param string $mgfSeed + * @param int $maskLen + * @return string + */ + protected function mgf1($mgfSeed, $maskLen) + { + // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. + + $t = ''; + $count = ceil($maskLen / $this->mgfHLen); + for ($i = 0; $i < $count; $i++) { + $c = pack('N', $i); + $t.= $this->mgfHash->hash($mgfSeed . $c); + } + + return substr($t, 0, $maskLen); + } + + /** + * Returns the key size + * + * More specifically, this returns the size of the modulo in bits. + * + * @access public + * @return int + */ + public function getLength() + { + return !isset($this->modulus) ? 0 : $this->modulus->getLength(); + } + + /** + * Determines which hashing function should be used + * + * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and + * decryption. + * + * @access public + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->hash = new Hash($hash); + break; + default: + throw new UnsupportedAlgorithmException( + 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' + ); + } + $new->hLen = $new->hash->getLengthInBytes(); + + return $new; + } + + /** + * Determines which hashing function should be used for the mask generation function + * + * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's + * best if Hash and MGFHash are set to the same thing this is not a requirement. + * + * @access public + * @param string $hash + */ + public function withMGFHash($hash) + { + $new = clone $this; + + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->mgfHash = new Hash($hash); + break; + default: + throw new UnsupportedAlgorithmException( + 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' + ); + } + $new->mgfHLen = $new->mgfHash->getLengthInBytes(); + + return $new; + } + + /** + * Returns the MGF hash algorithm currently being used + * + * @access public + */ + public function getMGFHash() + { + return clone $this->mgfHash; + } + + /** + * Determines the salt length + * + * Used by RSA::PADDING_PSS + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: + * + * Typical salt lengths in octets are hLen (the length of the output + * of the hash function Hash) and 0. + * + * @access public + * @param int $sLen + */ + public function withSaltLength($sLen) + { + $new = clone $this; + $new->sLen = $sLen; + return $new; + } + + /** + * Returns the salt length currently being used + * + * @access public + */ + public function getSaltLength() + { + return $this->sLen !== null ? $this->sLen : $this->hLen; + } + + /** + * Determines the label + * + * Used by RSA::PADDING_OAEP + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: + * + * Both the encryption and the decryption operations of RSAES-OAEP take + * the value of a label L as input. In this version of PKCS #1, L is + * the empty string; other uses of the label are outside the scope of + * this document. + * + * @access public + * @param string $label + */ + public function withLabel($label) + { + $new = clone $this; + $new->label = $label; + return $new; + } + + /** + * Returns the label currently being used + * + * @access public + */ + public function getLabel() + { + return $this->label; + } + + /** + * Determines the padding modes + * + * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1); + * + * @access public + * @param int $padding + */ + public function withPadding($padding) + { + $masks = [ + self::ENCRYPTION_OAEP, + self::ENCRYPTION_PKCS1, + self::ENCRYPTION_NONE + ]; + $numSelected = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $numSelected++; + } + } + if ($numSelected > 1) { + throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); + } + $encryptionPadding = $selected; + + $masks = [ + self::SIGNATURE_PSS, + self::SIGNATURE_RELAXED_PKCS1, + self::SIGNATURE_PKCS1 + ]; + $numSelected = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $numSelected++; + } + } + if ($numSelected > 1) { + throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); + } + $signaturePadding = $selected; + + $new = clone $this; + $new->encryptionPadding = $encryptionPadding; + $new->signaturePadding = $signaturePadding; + return $new; + } + + /** + * Returns the padding currently being used + * + * @access public + */ + public function getPadding() + { + return $this->signaturePadding | $this->encryptionPadding; + } + + /** + * Returns the current engine being used + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @access public + * @return string + */ + public function getEngine() + { + return 'PHP'; + } + + /** + * Enable RSA Blinding + * + * @access public + */ + public static function enableBlinding() + { + static::$enableBlinding = true; + } + + /** + * Disable RSA Blinding + * + * @access public + */ + public static function disableBlinding() + { + static::$enableBlinding = false; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php new file mode 100644 index 000000000..74771204d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php @@ -0,0 +1,242 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedFormatException; + +/** + * Microsoft BLOB Formatted RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class MSBLOB +{ + /** + * Public/Private Key Pair + * + * @access private + */ + const PRIVATEKEYBLOB = 0x7; + /** + * Public Key + * + * @access private + */ + const PUBLICKEYBLOB = 0x6; + /** + * Public Key + * + * @access private + */ + const PUBLICKEYBLOBEX = 0xA; + /** + * RSA public key exchange algorithm + * + * @access private + */ + const CALG_RSA_KEYX = 0x0000A400; + /** + * RSA public key exchange algorithm + * + * @access private + */ + const CALG_RSA_SIGN = 0x00002400; + /** + * Public Key + * + * @access private + */ + const RSA1 = 0x31415352; + /** + * Private Key + * + * @access private + */ + const RSA2 = 0x32415352; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $key = Base64::decode($key); + + if (!is_string($key)) { + throw new \UnexpectedValueException('Base64 decoding produced an error'); + } + if (strlen($key) < 20) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + // PUBLICKEYSTRUC publickeystruc + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx + extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8))); + /** + * @var string $type + * @var string $version + * @var integer $reserved + * @var integer $algo + */ + switch (ord($type)) { + case self::PUBLICKEYBLOB: + case self::PUBLICKEYBLOBEX: + $publickey = true; + break; + case self::PRIVATEKEYBLOB: + $publickey = false; + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $components = ['isPublicKey' => $publickey]; + + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx + switch ($algo) { + case self::CALG_RSA_KEYX: + case self::CALG_RSA_SIGN: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + // RSAPUBKEY rsapubkey + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx + // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit + extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12))); + /** + * @var integer $magic + * @var integer $bitlen + * @var string $pubexp + */ + switch ($magic) { + case self::RSA2: + $components['isPublicKey'] = false; + case self::RSA1: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $baseLength = $bitlen / 16; + if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256); + // BYTE modulus[rsapubkey.bitlen/8] + $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); + + if ($publickey) { + return $components; + } + + $components['isPublicKey'] = false; + + // BYTE prime1[rsapubkey.bitlen/16] + $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE prime2[rsapubkey.bitlen/16] + $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); + // BYTE exponent1[rsapubkey.bitlen/16] + $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE exponent2[rsapubkey.bitlen/16] + $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); + // BYTE coefficient[rsapubkey.bitlen/16] + $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + if (isset($components['privateExponent'])) { + $components['publicExponent'] = $components['privateExponent']; + } + // BYTE privateExponent[rsapubkey.bitlen/8] + $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); + } + + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('MSBLOB private keys do not support encryption'); + } + + $n = strrev($n->toBytes()); + $e = str_pad(strrev($e->toBytes()), 4, "\0"); + $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); + $key.= pack('VVa*', self::RSA2, 8 * strlen($n), $e); + $key.= $n; + $key.= strrev($primes[1]->toBytes()); + $key.= strrev($primes[2]->toBytes()); + $key.= strrev($exponents[1]->toBytes()); + $key.= strrev($exponents[2]->toBytes()); + $key.= strrev($coefficients[2]->toBytes()); + $key.= strrev($d->toBytes()); + + return Base64::encode($key); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + $n = strrev($n->toBytes()); + $e = str_pad(strrev($e->toBytes()), 4, "\0"); + $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); + $key.= pack('VVa*', self::RSA1, 8 * strlen($n), $e); + $key.= $n; + + return Base64::encode($key); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..0f92c1003 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,140 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; + +/** + * OpenSSH Formatted RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class OpenSSH extends Progenitor +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-rsa']; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + + $primes = $coefficients = []; + + list( + $modulus, + $publicExponent, + $privateExponent, + $coefficients[2], + $primes[1], + $primes[2], + $comment, + ) = Strings::unpackSSH2('i6s', $parsed['paddedKey']); + + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + + $isPublicKey = false; + + return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + + list($publicExponent, $modulus) = Strings::unpackSSH2('ii', $parsed['publicKey']); + + return [ + 'isPublicKey' => true, + 'modulus' => $modulus, + 'publicExponent' => $publicExponent, + 'comment' => $parsed['comment'] + ]; + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $RSAPublicKey; + } + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment; + + return $RSAPublicKey; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($n, $e, ['binary' => true]); + $privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..5203e4631 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php @@ -0,0 +1,167 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; + +/** + * PKCS#1 Formatted RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'PUBLIC') !== false) { + $components = ['isPublicKey' => true]; + } elseif (strpos($key, 'PRIVATE') !== false) { + $components = ['isPublicKey' => false]; + } else { + $components = []; + } + + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP); + if (is_array($key)) { + $components+= [ + 'modulus' => $key['modulus'], + 'publicExponent' => $key['publicExponent'], + 'privateExponent' => $key['privateExponent'], + 'primes' => [1 => $key['prime1'], $key['prime2']], + 'exponents' => [1 => $key['exponent1'], $key['exponent2']], + 'coefficients' => [2 => $key['coefficient']] + ]; + if ($key['version'] == 'multi') { + foreach ($key['otherPrimeInfos'] as $primeInfo) { + $components['primes'][] = $primeInfo['prime']; + $components['exponents'][] = $primeInfo['exponent']; + $components['coefficients'][] = $primeInfo['coefficient']; + } + } + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = false; + } + return $components; + } + + $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP); + + if (!is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = true; + } + + return $components + $key; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $num_primes = count($primes); + $key = [ + 'version' => $num_primes == 2 ? 'two-prime' : 'multi', + 'modulus' => $n, + 'publicExponent' => $e, + 'privateExponent' => $d, + 'prime1' => $primes[1], + 'prime2' => $primes[2], + 'exponent1' => $exponents[1], + 'exponent2' => $exponents[2], + 'coefficient' => $coefficients[2] + ]; + for ($i = 3; $i <= $num_primes; $i++) { + $key['otherPrimeInfos'][] = [ + 'prime' => $primes[$i], + 'exponent' => $exponents[$i], + 'coefficient' => $coefficients[$i] + ]; + } + + $key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'RSA', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + $key = [ + 'modulus' => $n, + 'publicExponent' => $e + ]; + + $key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP); + + return self::wrapPublicKey($key, 'RSA'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..8ead2c95b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php @@ -0,0 +1,149 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\Common\Functions\Strings; + +/** + * PKCS#8 Formatted RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + * @access private + */ + const OID_NAME = 'rsaEncryption'; + + /** + * OID Value + * + * @var string + * @access private + */ + const OID_VALUE = '1.2.840.113549.1.1.1'; + + /** + * Child OIDs loaded + * + * @var bool + * @access private + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'PUBLIC') !== false) { + $components = ['isPublicKey' => true]; + } elseif (strpos($key, 'PRIVATE') !== false) { + $components = ['isPublicKey' => false]; + } else { + $components = []; + } + + $key = parent::load($key, $password); + + if (isset($key['privateKey'])) { + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = false; + } + $type = 'private'; + } else { + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = true; + } + $type = 'public'; + } + + $result = $components + PKCS1::load($key[$type . 'Key']); + + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + + return $result; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = ASN1::extractBER($key); + return self::wrapPrivateKey($key, [], null, $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $key = PKCS1::savePublicKey($n, $e); + $key = ASN1::extractBER($key); + return self::wrapPublicKey($key, null); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php new file mode 100644 index 000000000..813653aef --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php @@ -0,0 +1,250 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; + +/** + * PKCS#8 Formatted RSA-PSS Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class PSS extends Progenitor +{ + /** + * OID Name + * + * @var string + * @access private + */ + const OID_NAME = 'id-RSASSA-PSS'; + + /** + * OID Value + * + * @var string + * @access private + */ + const OID_VALUE = '1.2.840.113549.1.1.10'; + + /** + * OIDs loaded + * + * @var bool + * @access private + */ + private static $oidsLoaded = false; + + /** + * Child OIDs loaded + * + * @var bool + * @access private + */ + protected static $childOIDsLoaded = false; + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!self::$oidsLoaded) { + ASN1::loadOIDs([ + 'md2' => '1.2.840.113549.2.2', + 'md4' => '1.2.840.113549.2.4', + 'md5' => '1.2.840.113549.2.5', + 'id-sha1' => '1.3.14.3.2.26', + 'id-sha256' => '2.16.840.1.101.3.4.2.1', + 'id-sha384' => '2.16.840.1.101.3.4.2.2', + 'id-sha512' => '2.16.840.1.101.3.4.2.3', + 'id-sha224' => '2.16.840.1.101.3.4.2.4', + 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', + 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', + + 'id-mgf1' => '1.2.840.113549.1.1.8' + ]); + self::$oidsLoaded = true; + } + } + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'private' : 'public'; + + $result = $components + PKCS1::load($key[$type . 'Key']); + + if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { + $decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); + if ($decoded === false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP); + } else { + $params = []; + } + + if (isset($params['maskGenAlgorithm']['parameters'])) { + $decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); + if ($decoded === false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP); + } else { + $params['maskGenAlgorithm'] = [ + 'algorithm' => 'id-mgf1', + 'parameters' => ['algorithm' => 'id-sha1'] + ]; + } + + if (!isset($params['hashAlgorithm']['algorithm'])) { + $params['hashAlgorithm']['algorithm'] = 'id-sha1'; + } + + $result['hash'] = str_replace('id-', '', $params['hashAlgorithm']['algorithm']); + $result['MGFHash'] = str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']); + if (isset($params['saltLength'])) { + $result['saltLength'] = (int) $params['saltLength']->toString(); + } + + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + + return $result; + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + self::initialize_static_variables(); + + $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPrivateKey($key, [], $params, $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + self::initialize_static_variables(); + + $key = PKCS1::savePublicKey($n, $e); + $key = ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPublicKey($key, $params); + } + + /** + * Encodes PSS parameters + * + * @access public + * @param array $options + * @return string + */ + public static function savePSSParams(array $options) + { + /* + The trailerField field is an integer. It provides + compatibility with IEEE Std 1363a-2004 [P1363A]. The value + MUST be 1, which represents the trailer field with hexadecimal + value 0xBC. Other trailer fields, including the trailer field + composed of HashID concatenated with 0xCC that is specified in + IEEE Std 1363a, are not supported. Implementations that + perform signature generation MUST omit the trailerField field, + indicating that the default trailer field value was used. + Implementations that perform signature validation MUST + recognize both a present trailerField field with value 1 and an + absent trailerField field. + + source: https://tools.ietf.org/html/rfc4055#page-9 + */ + $params = [ + 'trailerField' => new BigInteger(1) + ]; + if (isset($options['hash'])) { + $params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash']; + } + if (isset($options['MGFHash'])) { + $temp = ['algorithm' => 'id-' . $options['MGFHash']]; + $temp = ASN1::encodeDER($temp, Maps\HashAlgorithm::MAP); + $params['maskGenAlgorithm'] = [ + 'algorithm' => 'id-mgf1', + 'parameters' => new ASN1\Element($temp) + ]; + } + if (isset($options['saltLength'])) { + $params['saltLength'] = new BigInteger($options['saltLength']); + } + + return new ASN1\Element(ASN1::encodeDER($params, Maps\RSASSA_PSS_params::MAP)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..4c93b873d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php @@ -0,0 +1,130 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; + +/** + * PuTTY Formatted RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class PuTTY extends Progenitor +{ + /** + * Public Handler + * + * @var string + * @access private + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH'; + + /** + * Algorithm Identifier + * + * @var array + * @access private + */ + protected static $types = ['ssh-rsa']; + + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + extract($components); + unset($components['public'], $components['private']); + + $isPublicKey = false; + + $result = Strings::unpackSSH2('ii', $public); + if ($result === false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + list($publicExponent, $modulus) = $result; + + $result = Strings::unpackSSH2('iiii', $private); + if ($result === false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $primes = $coefficients = []; + list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; + + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + + return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); + } + + $public = Strings::packSSH2('ii', $e, $n); + $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); + + return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php new file mode 100644 index 000000000..49d789285 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php @@ -0,0 +1,108 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; + +/** + * Raw RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); + } + if (isset($key['isPublicKey']) && isset($key['modulus'])) { + if (isset($key['privateExponent']) || isset($key['publicExponent'])) { + if (!isset($key['primes'])) { + return $key; + } + if (isset($key['exponents']) && isset($key['coefficients']) && isset($key['publicExponent']) && isset($key['privateExponent'])) { + return $key; + } + } + } + $components = ['isPublicKey' => true]; + switch (true) { + case isset($key['e']): + $components['publicExponent'] = $key['e']; + break; + case isset($key['exponent']): + $components['publicExponent'] = $key['exponent']; + break; + case isset($key['publicExponent']): + $components['publicExponent'] = $key['publicExponent']; + break; + case isset($key[0]): + $components['publicExponent'] = $key[0]; + } + switch (true) { + case isset($key['n']): + $components['modulus'] = $key['n']; + break; + case isset($key['modulo']): + $components['modulus'] = $key['modulo']; + break; + case isset($key['modulus']): + $components['modulus'] = $key['modulus']; + break; + case isset($key[1]): + $components['modulus'] = $key[1]; + } + if (isset($components['modulus']) && isset($components['publicExponent'])) { + return $components; + } + + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return array + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return ['e' => clone $e, 'n' => clone $n]; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php new file mode 100644 index 000000000..389f93a82 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php @@ -0,0 +1,173 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedFormatException; + +/** + * XML Formatted RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @access public + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $components = [ + 'isPublicKey' => false, + 'primes' => [], + 'exponents' => [], + 'coefficients' => [] + ]; + + $use_errors = libxml_use_internal_errors(true); + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); + if (!$temp->length) { + continue; + } + $value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'modulus': + $components['modulus'] = $value; + break; + case 'exponent': + $components['publicExponent'] = $value; + break; + case 'p': + $components['primes'][1] = $value; + break; + case 'q': + $components['primes'][2] = $value; + break; + case 'dp': + $components['exponents'][1] = $value; + break; + case 'dq': + $components['exponents'][2] = $value; + break; + case 'inverseq': + $components['coefficients'][2] = $value; + break; + case 'd': + $components['privateExponent'] = $value; + } + } + + libxml_use_internal_errors($use_errors); + + foreach ($components as $key => $value) { + if (is_array($value) && !count($value)) { + unset($components[$key]); + } + } + + if (isset($components['modulus']) && isset($components['publicExponent'])) { + if (count($components) == 3) { + $components['isPublicKey'] = true; + } + return $components; + } + + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + + /** + * Convert a private key to the appropriate format. + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); + } + + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('XML private keys do not support encryption'); + } + + return "\r\n" . + ' ' . Base64::encode($n->toBytes()) . "\r\n" . + ' ' . Base64::encode($e->toBytes()) . "\r\n" . + '

      ' . Base64::encode($primes[1]->toBytes()) . "

      \r\n" . + ' ' . Base64::encode($primes[2]->toBytes()) . "\r\n" . + ' ' . Base64::encode($exponents[1]->toBytes()) . "\r\n" . + ' ' . Base64::encode($exponents[2]->toBytes()) . "\r\n" . + ' ' . Base64::encode($coefficients[2]->toBytes()) . "\r\n" . + ' ' . Base64::encode($d->toBytes()) . "\r\n" . + '
      '; + } + + /** + * Convert a public key to the appropriate format + * + * @access public + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return "\r\n" . + ' ' . Base64::encode($n->toBytes()) . "\r\n" . + ' ' . Base64::encode($e->toBytes()) . "\r\n" . + ''; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php new file mode 100644 index 000000000..5205ce63d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php @@ -0,0 +1,556 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA; + +use phpseclib3\Crypt\RSA; +use phpseclib3\Math\BigInteger; +use phpseclib3\File\ASN1; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exceptions\NoKeyLoadedException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; + +/** + * Raw RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +class PrivateKey extends RSA implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * Primes for Chinese Remainder Theorem (ie. p and q) + * + * @var array + * @access private + */ + protected $primes; + + /** + * Exponents for Chinese Remainder Theorem (ie. dP and dQ) + * + * @var array + * @access private + */ + protected $exponents; + + /** + * Coefficients for Chinese Remainder Theorem (ie. qInv) + * + * @var array + * @access private + */ + protected $coefficients; + + /** + * Public Exponent + * + * @var mixed + * @access private + */ + protected $publicExponent = false; + + /** + * RSADP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. + * + * @access private + * @param \phpseclib3\Math\BigInteger $c + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsadp($c) + { + if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Ciphertext representative out of range'); + } + return $this->exponentiate($c); + } + + /** + * RSASP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. + * + * @access private + * @param \phpseclib3\Math\BigInteger $m + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsasp1($m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Signature representative out of range'); + } + return $this->exponentiate($m); + } + + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + protected function exponentiate(BigInteger $x) + { + switch (true) { + case empty($this->primes): + case $this->primes[1]->equals(self::$zero): + case empty($this->coefficients): + case $this->coefficients[2]->equals(self::$zero): + case empty($this->exponents): + case $this->exponents[1]->equals(self::$zero): + return $x->modPow($this->exponent, $this->modulus); + } + + $num_primes = count($this->primes); + + if (!static::$enableBlinding) { + $m_i = [ + 1 => $x->modPow($this->exponents[1], $this->primes[1]), + 2 => $x->modPow($this->exponents[2], $this->primes[2]) + ]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } else { + $smallest = $this->primes[1]; + for ($i = 2; $i <= $num_primes; $i++) { + if ($smallest->compare($this->primes[$i]) > 0) { + $smallest = $this->primes[$i]; + } + } + + $r = BigInteger::randomRange(self::$one, $smallest->subtract(self::$one)); + + $m_i = [ + 1 => $this->blind($x, $r, 1), + 2 => $this->blind($x, $r, 2) + ]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $this->blind($x, $r, $i); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } + + return $m; + } + + /** + * Performs RSA Blinding + * + * Protects against timing attacks by employing RSA Blinding. + * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) + * + * @access private + * @param \phpseclib3\Math\BigInteger $x + * @param \phpseclib3\Math\BigInteger $r + * @param int $i + * @return \phpseclib3\Math\BigInteger + */ + private function blind($x, $r, $i) + { + $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); + $x = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->modInverse($this->primes[$i]); + $x = $x->multiply($r); + list(, $x) = $x->divide($this->primes[$i]); + + return $x; + } + + /** + * EMSA-PSS-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. + * + * @return string + * @access private + * @param string $m + * @throws \RuntimeException on encoding error + * @param int $emBits + */ + private function emsa_pss_encode($m, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + throw new \LengthException('RSA modulus too short'); + } + + $salt = Random::string($sLen); + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h = $this->hash->hash($m2); + $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); + $db = $ps . chr(1) . $salt; + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); + $maskedDB = $db ^ $dbMask; + $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; + $em = $maskedDB . $h . chr(0xBC); + + return $em; + } + + /** + * RSASSA-PSS-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. + * + * @access private + * @param string $m + * @return bool|string + */ + private function rsassa_pss_sign($m) + { + // EMSA-PSS encoding + + $em = $this->emsa_pss_encode($m, 8 * $this->k - 1); + + // RSA signature + + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + + // Output the signature S + + return $s; + } + + /** + * RSASSA-PKCS1-V1_5-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. + * + * @access private + * @param string $m + * @throws \LengthException if the RSA modulus is too short + * @return bool|string + */ + private function rsassa_pkcs1_v1_5_sign($m) + { + // EMSA-PKCS1-v1_5 encoding + + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + } catch (\LengthException $e) { + throw new \LengthException('RSA modulus too short'); + } + + // RSA signature + + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + + // Output the signature S + + return $s; + } + + /** + * Create a signature + * + * @see self::verify() + * @access public + * @param string $message + * @return string + */ + public function sign($message) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_PKCS1: + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_sign($message); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_sign($message); + } + } + + /** + * RSAES-PKCS1-V1_5-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. + * + * @access private + * @param string $c + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_decrypt($c) + { + // Length checking + + if (strlen($c) != $this->k) { // or if k < 11 + throw new \LengthException('Ciphertext representative too long'); + } + + // RSA decryption + + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + + // EME-PKCS1-v1_5 decoding + + if (ord($em[0]) != 0 || ord($em[1]) > 2) { + throw new \RuntimeException('Decryption error'); + } + + $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); + $m = substr($em, strlen($ps) + 3); + + if (strlen($ps) < 8) { + throw new \RuntimeException('Decryption error'); + } + + // Output M + + return $m; + } + + /** + * RSAES-OAEP-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error + * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: + * + * Note. Care must be taken to ensure that an opponent cannot + * distinguish the different error conditions in Step 3.g, whether by + * error message or timing, or, more generally, learn partial + * information about the encoded message EM. Otherwise an opponent may + * be able to obtain useful information about the decryption of the + * ciphertext C, leading to a chosen-ciphertext attack such as the one + * observed by Manger [36]. + * + * @access private + * @param string $c + * @return bool|string + */ + private function rsaes_oaep_decrypt($c) + { + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { + throw new \LengthException('Ciphertext representative too long'); + } + + // RSA decryption + + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + + // EME-OAEP decoding + + $lHash = $this->hash->hash($this->label); + $y = ord($em[0]); + $maskedSeed = substr($em, 1, $this->hLen); + $maskedDB = substr($em, $this->hLen + 1); + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $seed = $maskedSeed ^ $seedMask; + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $lHash2 = substr($db, 0, $this->hLen); + $m = substr($db, $this->hLen); + $hashesMatch = hash_equals($lHash, $lHash2); + $leadingZeros = 1; + $patternMatch = 0; + $offset = 0; + for ($i = 0; $i < strlen($m); $i++) { + $patternMatch|= $leadingZeros & ($m[$i] === "\1"); + $leadingZeros&= $m[$i] === "\0"; + $offset+= $patternMatch ? 0 : 1; + } + + // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation + // to protect against timing attacks + if (!$hashesMatch & !$patternMatch) { + throw new \RuntimeException('Decryption error'); + } + + // Output the message M + + return substr($m, $offset + 1); + } + + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @access private + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (strlen($m) > $this->k) { + throw new \LengthException('Ciphertext representative too long'); + } + + $temp = $this->os2ip($m); + $temp = $this->rsadp($temp); + return $this->i2osp($temp, $this->k); + } + + /** + * Decryption + * + * @see self::encrypt() + * @access public + * @param string $ciphertext + * @return bool|string + */ + public function decrypt($ciphertext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($ciphertext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_decrypt($ciphertext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_decrypt($ciphertext); + } + } + + /** + * Returns the public key + * + * @access public + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + if (empty($this->modulus) || empty($this->publicExponent)) { + throw new \RuntimeException('Public key components not found'); + } + + $key = $type::savePublicKey($this->modulus, $this->publicExponent); + return RSA::loadFormat('PKCS8', $key) + ->withHash($this->hash->getHash()) + ->withMGFHash($this->mgfHash->getHash()) + ->withSaltLength($this->sLen) + ->withLabel($this->label) + ->withPadding($this->signaturePadding | $this->encryptionPadding); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin( + 'Keys', + $type, + empty($this->primes) ? 'savePublicKey' : 'savePrivateKey' + ); + + if ($type == PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options+= [ + 'hash' => $this->hash->getHash(), + 'MGFHash' => $this->mgfHash->getHash(), + 'saltLength' => $this->getSaltLength() + ]; + } else { + throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + + if (empty($this->primes)) { + return $type::savePublicKey($this->modulus, $this->exponent, $options); + } + + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + + /* + $key = $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + if ($key !== false || count($this->primes) == 2) { + return $key; + } + + $nSize = $this->getSize() >> 1; + + $primes = [1 => clone self::$one, clone self::$one]; + $i = 1; + foreach ($this->primes as $prime) { + $primes[$i] = $primes[$i]->multiply($prime); + if ($primes[$i]->getLength() >= $nSize) { + $i++; + } + } + + $exponents = []; + $coefficients = [2 => $primes[2]->modInverse($primes[1])]; + + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $this->modulus->modInverse($temp); + } + + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $primes, $exponents, $coefficients, $this->password, $options); + */ + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php new file mode 100644 index 000000000..3475ad999 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php @@ -0,0 +1,507 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA; + +use phpseclib3\Crypt\RSA; +use phpseclib3\Math\BigInteger; +use phpseclib3\File\ASN1; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\Common; +use phpseclib3\File\ASN1\Maps\DigestInfo; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; + +/** + * Raw RSA Key Handler + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +class PublicKey extends RSA implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + private function exponentiate(BigInteger $x) + { + return $x->modPow($this->exponent, $this->modulus); + } + + /** + * RSAVP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. + * + * @access private + * @param \phpseclib3\Math\BigInteger $s + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsavp1($s) + { + if ($s->compare(self::$zero) < 0 || $s->compare($this->modulus) > 0) { + return false; + } + return $this->exponentiate($s); + } + + /** + * RSASSA-PKCS1-V1_5-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. + * + * @access private + * @param string $m + * @param string $s + * @throws \LengthException if the RSA modulus is too short + * @return bool + */ + private function rsassa_pkcs1_v1_5_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === false) { + return false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + // EMSA-PKCS1-v1_5 encoding + + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em2 = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + } catch (\LengthException $e) { + throw new \LengthException('RSA modulus too short'); + } + + // Compare + return hash_equals($em, $em2); + } + + /** + * RSASSA-PKCS1-V1_5-VERIFY (relaxed matching) + * + * Per {@link http://tools.ietf.org/html/rfc3447#page-43 RFC3447#page-43} PKCS1 v1.5 + * specified the use BER encoding rather than DER encoding that PKCS1 v2.0 specified. + * This means that under rare conditions you can have a perfectly valid v1.5 signature + * that fails to validate with _rsassa_pkcs1_v1_5_verify(). PKCS1 v2.1 also recommends + * that if you're going to validate these types of signatures you "should indicate + * whether the underlying BER encoding is a DER encoding and hence whether the signature + * is valid with respect to the specification given in [PKCS1 v2.0+]". so if you do + * $rsa->getLastPadding() and get RSA::PADDING_RELAXED_PKCS1 back instead of + * RSA::PADDING_PKCS1... that means BER encoding was used. + * + * @access private + * @param string $m + * @param string $s + * @return bool + */ + private function rsassa_pkcs1_v1_5_relaxed_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === false) { + return false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + if (Strings::shift($em, 2) != "\0\1") { + return false; + } + + $em = ltrim($em, "\xFF"); + if (Strings::shift($em) != "\0") { + return false; + } + + $decoded = ASN1::decodeBER($em); + if (!is_array($decoded) || empty($decoded[0]) || strlen($em) > $decoded[0]['length']) { + return false; + } + + static $oids; + if (!isset($oids)) { + $oids = [ + 'md2' => '1.2.840.113549.2.2', + 'md4' => '1.2.840.113549.2.4', // from PKCS1 v1.5 + 'md5' => '1.2.840.113549.2.5', + 'id-sha1' => '1.3.14.3.2.26', + 'id-sha256' => '2.16.840.1.101.3.4.2.1', + 'id-sha384' => '2.16.840.1.101.3.4.2.2', + 'id-sha512' => '2.16.840.1.101.3.4.2.3', + // from PKCS1 v2.2 + 'id-sha224' => '2.16.840.1.101.3.4.2.4', + 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', + 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', + ]; + ASN1::loadOIDs($oids); + } + + $decoded = ASN1::asn1map($decoded[0], DigestInfo::MAP); + if (!isset($decoded) || $decoded === false) { + return false; + } + + if (!isset($oids[$decoded['digestAlgorithm']['algorithm']])) { + return false; + } + + $hash = $decoded['digestAlgorithm']['algorithm']; + $hash = substr($hash, 0, 3) == 'id-' ? + substr($hash, 3) : + $hash; + $hash = new Hash($hash); + $em = $hash->hash($m); + $em2 = $decoded['digest']; + + return hash_equals($em, $em2); + } + + /** + * EMSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. + * + * @access private + * @param string $m + * @param string $em + * @param int $emBits + * @return string + */ + private function emsa_pss_verify($m, $em, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + return false; + } + + if ($em[strlen($em) - 1] != chr(0xBC)) { + return false; + } + + $maskedDB = substr($em, 0, -$this->hLen - 1); + $h = substr($em, -$this->hLen - 1, $this->hLen); + $temp = chr(0xFF << ($emBits & 7)); + if ((~$maskedDB[0] & $temp) != $temp) { + return false; + } + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; + $temp = $emLen - $this->hLen - $sLen - 2; + if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { + return false; + } + $salt = substr($db, $temp + 1); // should be $sLen long + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h2 = $this->hash->hash($m2); + return hash_equals($h, $h2); + } + + /** + * RSASSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. + * + * @access private + * @param string $m + * @param string $s + * @return bool|string + */ + private function rsassa_pss_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $modBits = strlen($this->modulus->toBits()); + + $s2 = $this->os2ip($s); + $m2 = $this->rsavp1($s2); + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + // EMSA-PSS verification + + return $this->emsa_pss_verify($m, $em, $modBits - 1); + } + + /** + * Verifies a signature + * + * @see self::sign() + * @param string $message + * @param string $signature + * @return bool + */ + public function verify($message, $signature) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature); + case self::SIGNATURE_PKCS1: + return $this->rsassa_pkcs1_v1_5_verify($message, $signature); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_verify($message, $signature); + } + } + + /** + * RSAES-PKCS1-V1_5-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. + * + * @access private + * @param string $m + * @param bool $pkcs15_compat optional + * @throws \LengthException if strlen($m) > $this->k - 11 + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_encrypt($m, $pkcs15_compat = false) + { + $mLen = strlen($m); + + // Length checking + + if ($mLen > $this->k - 11) { + throw new \LengthException('Message too long'); + } + + // EME-PKCS1-v1_5 encoding + + $psLen = $this->k - $mLen - 3; + $ps = ''; + while (strlen($ps) != $psLen) { + $temp = Random::string($psLen - strlen($ps)); + $temp = str_replace("\x00", '', $temp); + $ps.= $temp; + } + $type = 2; + $em = chr(0) . chr($type) . $ps . chr(0) . $m; + + // RSA encryption + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + + // Output the ciphertext C + + return $c; + } + + /** + * RSAES-OAEP-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and + * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. + * + * @access private + * @param string $m + * @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 + * @return string + */ + private function rsaes_oaep_encrypt($m) + { + $mLen = strlen($m); + + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if ($mLen > $this->k - 2 * $this->hLen - 2) { + throw new \LengthException('Message too long'); + } + + // EME-OAEP encoding + + $lHash = $this->hash->hash($this->label); + $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); + $db = $lHash . $ps . chr(1) . $m; + $seed = Random::string($this->hLen); + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $maskedDB = $db ^ $dbMask; + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $maskedSeed = $seed ^ $seedMask; + $em = chr(0) . $maskedSeed . $maskedDB; + + // RSA encryption + + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + + // Output the ciphertext C + + return $c; + } + + /** + * RSAEP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. + * + * @access private + * @param \phpseclib3\Math\BigInteger $m + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsaep($m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Message representative out of range'); + } + return $this->exponentiate($m); + } + + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @access private + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (strlen($m) > $this->k) { + throw new \LengthException('Message too long'); + } + + $temp = $this->os2ip($m); + $temp = $this->rsaep($temp); + return $this->i2osp($temp, $this->k); + } + + /** + * Encryption + * + * Both self::PADDING_OAEP and self::PADDING_PKCS1 both place limits on how long $plaintext can be. + * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will + * be concatenated together. + * + * @see self::decrypt() + * @access public + * @param string $plaintext + * @return bool|string + * @throws \LengthException if the RSA modulus is too short + */ + public function encrypt($plaintext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($plaintext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_encrypt($plaintext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_encrypt($plaintext); + } + } + + /** + * Returns the public key + * + * The public key is only returned under two circumstances - if the private key had the public key embedded within it + * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this + * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. + * + * @param string $type + * @param array $options optional + * @return mixed + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + if ($type == PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options+= [ + 'hash' => $this->hash->getHash(), + 'MGFHash' => $this->mgfHash->getHash(), + 'saltLength' => $this->getSaltLength() + ]; + } else { + throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + + return $type::savePublicKey($this->modulus, $this->publicExponent, $options); + } + + /** + * Converts a public key to a private key + * + * @return RSA + */ + public function asPrivateKey() + { + $new = new PrivateKey; + $new->exponent = $this->exponent; + $new->modulus = $this->modulus; + $new->k = $this->k; + $new->format = $this->format; + return $new + ->withHash($this->hash->getHash()) + ->withMGFHash($this->mgfHash->getHash()) + ->withSaltLength($this->sLen) + ->withLabel($this->label) + ->withPadding($this->signaturePadding | $this->encryptionPadding); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php new file mode 100644 index 000000000..b05f040eb --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php @@ -0,0 +1,223 @@ + + * + * + * + * @category Crypt + * @package Random + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +/** + * Pure-PHP Random Number Generator + * + * @package Random + * @author Jim Wigginton + * @access public + */ +abstract class Random +{ + /** + * Generate a random string. + * + * Although microoptimizations are generally discouraged as they impair readability this function is ripe with + * microoptimizations because this function has the potential of being called a huge number of times. + * eg. for RSA key generation. + * + * @param int $length + * @throws \RuntimeException if a symmetric cipher is needed but not loaded + * @return string + */ + public static function string($length) + { + if (!$length) { + return ''; + } + + try { + return \random_bytes($length); + } catch (\Exception $e) { + // random_compat will throw an Exception, which in PHP 5 does not implement Throwable + } catch (\Throwable $e) { + // If a sufficient source of randomness is unavailable, random_bytes() will throw an + // object that implements the Throwable interface (Exception, TypeError, Error). + // We don't actually need to do anything here. The string() method should just continue + // as normal. Note, however, that if we don't have a sufficient source of randomness for + // random_bytes(), most of the other calls here will fail too, so we'll end up using + // the PHP implementation. + } + // at this point we have no choice but to use a pure-PHP CSPRNG + + // cascade entropy across multiple PHP instances by fixing the session and collecting all + // environmental variables, including the previous session data and the current session + // data. + // + // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively) + // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but + // PHP isn't low level to be able to use those as sources and on a web server there's not likely + // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use + // however, a ton of people visiting the website. obviously you don't want to base your seeding + // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled + // by the user and (2) this isn't just looking at the data sent by the current user - it's based + // on the data sent by all users. one user requests the page and a hash of their info is saved. + // another user visits the page and the serialization of their data is utilized along with the + // server environment stuff and a hash of the previous http request data (which itself utilizes + // a hash of the session data before that). certainly an attacker should be assumed to have + // full control over his own http requests. he, however, is not going to have control over + // everyone's http requests. + static $crypto = false, $v; + if ($crypto === false) { + // save old session data + $old_session_id = session_id(); + $old_use_cookies = ini_get('session.use_cookies'); + $old_session_cache_limiter = session_cache_limiter(); + $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false; + if ($old_session_id != '') { + session_write_close(); + } + + session_id(1); + ini_set('session.use_cookies', 0); + session_cache_limiter(''); + session_start(); + + $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . + (isset($_POST) ? self::safe_serialize($_POST) : '') . + (isset($_GET) ? self::safe_serialize($_GET) : '') . + (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') . + self::safe_serialize($GLOBALS) . + self::safe_serialize($_SESSION) . + self::safe_serialize($_OLD_SESSION); + $v = $seed = $_SESSION['seed'] = sha1($v, true); + if (!isset($_SESSION['count'])) { + $_SESSION['count'] = 0; + } + $_SESSION['count']++; + + session_write_close(); + + // restore old session data + if ($old_session_id != '') { + session_id($old_session_id); + session_start(); + ini_set('session.use_cookies', $old_use_cookies); + session_cache_limiter($old_session_cache_limiter); + } else { + if ($_OLD_SESSION !== false) { + $_SESSION = $_OLD_SESSION; + unset($_OLD_SESSION); + } else { + unset($_SESSION); + } + } + + // in SSH2 a shared secret and an exchange hash are generated through the key exchange process. + // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C. + // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the + // original hash and the current hash. we'll be emulating that. for more info see the following URL: + // + // http://tools.ietf.org/html/rfc4253#section-7.2 + // + // see the is_string($crypto) part for an example of how to expand the keys + $key = sha1($seed . 'A', true); + $iv = sha1($seed . 'C', true); + + // ciphers are used as per the nist.gov link below. also, see this link: + // + // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives + switch (true) { + case class_exists('\phpseclib3\Crypt\AES'): + $crypto = new AES('ctr'); + break; + case class_exists('\phpseclib3\Crypt\Twofish'): + $crypto = new Twofish('ctr'); + break; + case class_exists('\phpseclib3\Crypt\Blowfish'): + $crypto = new Blowfish('ctr'); + break; + case class_exists('\phpseclib3\Crypt\TripleDES'): + $crypto = new TripleDES('ctr'); + break; + case class_exists('\phpseclib3\Crypt\DES'): + $crypto = new DES('ctr'); + break; + case class_exists('\phpseclib3\Crypt\RC4'): + $crypto = new RC4(); + break; + default: + throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); + } + + $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3)); + $crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3)); + $crypto->enableContinuousBuffer(); + } + + //return $crypto->encrypt(str_repeat("\0", $length)); + + // the following is based off of ANSI X9.31: + // + // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf + // + // OpenSSL uses that same standard for it's random numbers: + // + // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c + // (do a search for "ANS X9.31 A.2.4") + $result = ''; + while (strlen($result) < $length) { + $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21 + $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20 + $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20 + $result.= $r; + } + + return substr($result, 0, $length); + } + + /** + * Safely serialize variables + * + * If a class has a private __sleep() it'll emit a warning + * @return mixed + * @param mixed $arr + */ + private static function safe_serialize(&$arr) + { + if (is_object($arr)) { + return ''; + } + if (!is_array($arr)) { + return serialize($arr); + } + // prevent circular array recursion + if (isset($arr['__phpseclib_marker'])) { + return ''; + } + $safearr = []; + $arr['__phpseclib_marker'] = true; + foreach (array_keys($arr) as $key) { + // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage + if ($key !== '__phpseclib_marker') { + $safearr[$key] = self::safe_serialize($arr[$key]); + } + } + unset($arr['__phpseclib_marker']); + return serialize($safearr); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php new file mode 100644 index 000000000..fb1edcf6e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php @@ -0,0 +1,1022 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rijndael->decrypt($rijndael->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package Rijndael + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadModeException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\BadDecryptionException; + +/** + * Pure-PHP implementation of Rijndael. + * + * @package Rijndael + * @author Jim Wigginton + * @access public + */ +class Rijndael extends BlockCipher +{ + /** + * The mcrypt specific name of the cipher + * + * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. + * \phpseclib3\Crypt\Rijndael determines automatically whether mcrypt is useable + * or not for the current $block_size/$key_length. + * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::engine + * @see self::isValidEngine() + * @var string + * @access private + */ + protected $cipher_name_mcrypt = 'rijndael-128'; + + /** + * The Key Schedule + * + * @see self::setup() + * @var array + * @access private + */ + private $w; + + /** + * The Inverse Key Schedule + * + * @see self::setup() + * @var array + * @access private + */ + private $dw; + + /** + * The Block Length divided by 32 + * + * {@internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size + * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could + * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see self::setBlockLength() + * @var int + * @access private + */ + private $Nb = 4; + + /** + * The Key Length (in bytes) + * + * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see self::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 16; + + /** + * The Key Length divided by 32 + * + * @see self::setKeyLength() + * @var int + * @access private + * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 + */ + private $Nk = 4; + + /** + * The Number of Rounds + * + * {@internal The max value is 14, the min value is 10.} + * + * @var int + * @access private + */ + private $Nr; + + /** + * Shift offsets + * + * @var array + * @access private + */ + private $c; + + /** + * Holds the last used key- and block_size information + * + * @var array + * @access private + */ + private $kl; + + /** + * Default Constructor. + * + * @param string $mode + * @access public + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Sets the key length. + * + * Valid key lengths are 128, 160, 192, 224, and 256. + * + * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined + * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to + * 192/256 bits as, for example, mcrypt will do. + * + * That said, if you want be compatible with other Rijndael and AES implementations, + * you should not setKeyLength(160) or setKeyLength(224). + * + * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use + * the mcrypt php extension, even if available. + * This results then in slower encryption. + * + * @access public + * @throws \LengthException if the key length is invalid + * @param int $length + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + $this->key_length = $length >> 3; + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); + } + + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Rijndael supports five different key lengths + * + * @see setKeyLength() + * @access public + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 20: + case 24: + case 28: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); + } + + parent::setKey($key); + } + + /** + * Sets the block length + * + * Valid block lengths are 128, 160, 192, 224, and 256. + * + * @access public + * @param int $length + */ + public function setBlockLength($length) + { + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); + } + + $this->Nb = $length >> 5; + $this->block_size = $length >> 3; + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @access protected + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_LIBSODIUM: + return function_exists('sodium_crypto_aead_aes256gcm_is_available') && + sodium_crypto_aead_aes256gcm_is_available() && + $this->mode == self::MODE_GCM && + $this->key_length == 32 && + $this->nonce && strlen($this->nonce) == 12 && + $this->block_size == 16; + case self::ENGINE_OPENSSL_GCM: + if (!extension_loaded('openssl')) { + return false; + } + $methods = openssl_get_cipher_methods(); + return $this->mode == self::MODE_GCM && + version_compare(PHP_VERSION, '7.1.0', '>=') && + in_array('aes-' . $this->getKeyLength() . '-gcm', $methods) && + $this->block_size == 16; + case self::ENGINE_OPENSSL: + if ($this->block_size != 16) { + return false; + } + self::$cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; + $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->openssl_translate_mode(); + break; + case self::ENGINE_MCRYPT: + $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); + if ($this->key_length % 8) { // is it a 160/224-bit key? + // mcrypt is not usable for them, only for 128/192/256-bit keys + return false; + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Encrypts a block + * + * @access private + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + static $tables; + if (empty($tables)) { + $tables = &$this->getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + + $state = []; + $words = unpack('N*', $in); + + $c = $this->c; + $w = $this->w; + $Nb = $this->Nb; + $Nr = $this->Nr; + + // addRoundKey + $wc = $Nb - 1; + foreach ($words as $word) { + $state[] = $word ^ $w[++$wc]; + } + + // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - + // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding + // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf. + // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization. + // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1], + // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. + + // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf + $temp = []; + for ($round = 1; $round < $Nr; ++$round) { + $i = 0; // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + + while ($i < $Nb) { + $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^ + $t1[$state[$j] >> 16 & 0x000000FF] ^ + $t2[$state[$k] >> 8 & 0x000000FF] ^ + $t3[$state[$l] & 0x000000FF] ^ + $w[++$wc]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + $state = $temp; + } + + // subWord + for ($i = 0; $i < $Nb; ++$i) { + $state[$i] = $sbox[$state[$i] & 0x000000FF] | + ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) | + ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) | + ($sbox[$state[$i] >> 24 & 0x000000FF] << 24); + } + + // shiftRows + addRoundKey + $i = 0; // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + while ($i < $Nb) { + $temp[$i] = ($state[$i] & 0xFF000000) ^ + ($state[$j] & 0x00FF0000) ^ + ($state[$k] & 0x0000FF00) ^ + ($state[$l] & 0x000000FF) ^ + $w[$i]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + + return pack('N*', ...$temp); + } + + /** + * Decrypts a block + * + * @access private + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + static $invtables; + if (empty($invtables)) { + $invtables = &$this->getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + + $state = []; + $words = unpack('N*', $in); + + $c = $this->c; + $dw = $this->dw; + $Nb = $this->Nb; + $Nr = $this->Nr; + + // addRoundKey + $wc = $Nb - 1; + foreach ($words as $word) { + $state[] = $word ^ $dw[++$wc]; + } + + $temp = []; + for ($round = $Nr - 1; $round > 0; --$round) { + $i = 0; // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + + while ($i < $Nb) { + $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^ + $dt1[$state[$j] >> 16 & 0x000000FF] ^ + $dt2[$state[$k] >> 8 & 0x000000FF] ^ + $dt3[$state[$l] & 0x000000FF] ^ + $dw[++$wc]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + $state = $temp; + } + + // invShiftRows + invSubWord + addRoundKey + $i = 0; // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + + while ($i < $Nb) { + $word = ($state[$i] & 0xFF000000) | + ($state[$j] & 0x00FF0000) | + ($state[$k] & 0x0000FF00) | + ($state[$l] & 0x000000FF); + + $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] | + ($isbox[$word >> 8 & 0x000000FF] << 8) | + ($isbox[$word >> 16 & 0x000000FF] << 16) | + ($isbox[$word >> 24 & 0x000000FF] << 24)); + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + + return pack('N*', ...$temp); + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @access private + */ + protected function setupKey() + { + // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. + // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse + static $rcon = [0, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, + 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, + 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, + 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, + 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 + ]; + + if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size]; + + $this->Nk = $this->key_length >> 2; + // see Rijndael-ammended.pdf#page=44 + $this->Nr = max($this->Nk, $this->Nb) + 6; + + // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44, + // "Table 8: Shift offsets in Shiftrow for the alternative block lengths" + // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14, + // "Table 2: Shift offsets for different block lengths" + switch ($this->Nb) { + case 4: + case 5: + case 6: + $this->c = [0, 1, 2, 3]; + break; + case 7: + $this->c = [0, 1, 2, 4]; + break; + case 8: + $this->c = [0, 1, 3, 4]; + } + + $w = array_values(unpack('N*words', $this->key)); + + $length = $this->Nb * ($this->Nr + 1); + for ($i = $this->Nk; $i < $length; $i++) { + $temp = $w[$i - 1]; + if ($i % $this->Nk == 0) { + // according to , "the size of an integer is platform-dependent". + // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, + // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' + // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. + $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord + $temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk]; + } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { + $temp = $this->subWord($temp); + } + $w[$i] = $w[$i - $this->Nk] ^ $temp; + } + + // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns + // and generate the inverse key schedule. more specifically, + // according to (section 5.3.3), + // "The key expansion for the Inverse Cipher is defined as follows: + // 1. Apply the Key Expansion. + // 2. Apply InvMixColumn to all Round Keys except the first and the last one." + // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" + list($dt0, $dt1, $dt2, $dt3) = $this->getInvTables(); + $temp = $this->w = $this->dw = []; + for ($i = $row = $col = 0; $i < $length; $i++, $col++) { + if ($col == $this->Nb) { + if ($row == 0) { + $this->dw[0] = $this->w[0]; + } else { + // subWord + invMixColumn + invSubWord = invMixColumn + $j = 0; + while ($j < $this->Nb) { + $dw = $this->subWord($this->w[$row][$j]); + $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^ + $dt1[$dw >> 16 & 0x000000FF] ^ + $dt2[$dw >> 8 & 0x000000FF] ^ + $dt3[$dw & 0x000000FF]; + $j++; + } + $this->dw[$row] = $temp; + } + + $col = 0; + $row++; + } + $this->w[$row][$col] = $w[$i]; + } + + $this->dw[$row] = $this->w[$row]; + + // Converting to 1-dim key arrays (both ascending) + $this->dw = array_reverse($this->dw); + $w = array_pop($this->w); + $dw = array_pop($this->dw); + foreach ($this->w as $r => $wr) { + foreach ($wr as $c => $wc) { + $w[] = $wc; + $dw[] = $this->dw[$r][$c]; + } + } + $this->w = $w; + $this->dw = $dw; + } + + /** + * Performs S-Box substitutions + * + * @return array + * @access private + * @param int $word + */ + private function subWord($word) + { + static $sbox; + if (empty($sbox)) { + list(, , , , $sbox) = self::getTables(); + } + + return $sbox[$word & 0x000000FF] | + ($sbox[$word >> 8 & 0x000000FF] << 8) | + ($sbox[$word >> 16 & 0x000000FF] << 16) | + ($sbox[$word >> 24 & 0x000000FF] << 24); + } + + /** + * Provides the mixColumns and sboxes tables + * + * @see self::encryptBlock() + * @see self::setupInlineCrypt() + * @see self::subWord() + * @access private + * @return array &$tables + */ + protected function &getTables() + { + static $tables; + if (empty($tables)) { + // according to (section 5.2.1), + // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so + // those are the names we'll use. + $t3 = array_map('intval', [ + // with array_map('intval', ...) we ensure we have only int's and not + // some slower floats converted by php automatically on high values + 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, + 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, + 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, + 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, + 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, + 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, + 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, + 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, + 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, + 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, + 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, + 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, + 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, + 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, + 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, + 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, + 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, + 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, + 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, + 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, + 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, + 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, + 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, + 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, + 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, + 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, + 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, + 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, + 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, + 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, + 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, + 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C + ]); + + foreach ($t3 as $t3i) { + $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF); + $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF); + $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF); + } + + $tables = [ + // The Precomputed mixColumns tables t0 - t3 + $t0, + $t1, + $t2, + $t3, + // The SubByte S-Box + [ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 + ] + ]; + } + return $tables; + } + + /** + * Provides the inverse mixColumns and inverse sboxes tables + * + * @see self::decryptBlock() + * @see self::setupInlineCrypt() + * @see self::setupKey() + * @access private + * @return array &$tables + */ + protected function &getInvTables() + { + static $tables; + if (empty($tables)) { + $dt3 = array_map('intval', [ + 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, + 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, + 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, + 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, + 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, + 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, + 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, + 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, + 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, + 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, + 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, + 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, + 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, + 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, + 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, + 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, + 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, + 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, + 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, + 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, + 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, + 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, + 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, + 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, + 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, + 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, + 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, + 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, + 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, + 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, + 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, + 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 + ]); + + foreach ($dt3 as $dt3i) { + $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF); + $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF); + $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF); + }; + + $tables = [ + // The Precomputed inverse mixColumns tables dt0 - dt3 + $dt0, + $dt1, + $dt2, + $dt3, + // The inverse SubByte S-Box + [ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D + ] + ]; + } + return $tables; + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + * @access private + */ + protected function setupInlineCrypt() + { + $w = $this->w; + $dw = $this->dw; + $init_encrypt = ''; + $init_decrypt = ''; + + $Nr = $this->Nr; + $Nb = $this->Nb; + $c = $this->c; + + // Generating encrypt code: + $init_encrypt.= ' + static $tables; + if (empty($tables)) { + $tables = &$this->getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + '; + + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $encrypt_block = '$in = unpack("N*", $in);'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n"; + } + + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block.= + '$'.$e.$i.' = + $t0[($'.$s.$i .' >> 24) & 0xff] ^ + $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^ + $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^ + $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^ + '.$w[++$wc].";\n"; + } + } + + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block.= + '$'.$e.$i.' = + $sbox[ $'.$e.$i.' & 0xff] | + ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) | + ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) | + ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; + } + $encrypt_block .= '$in = pack("N*"'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block.= ', + ($'.$e.$i .' & '.((int)0xFF000000).') ^ + ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^ + ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^ + ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^ + '.$w[$i]."\n"; + } + $encrypt_block .= ');'; + + // Generating decrypt code: + $init_decrypt.= ' + static $invtables; + if (empty($invtables)) { + $invtables = &$this->getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + '; + + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $decrypt_block = '$in = unpack("N*", $in);'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n"; + } + + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block.= + '$'.$e.$i.' = + $dt0[($'.$s.$i .' >> 24) & 0xff] ^ + $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^ + $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^ + $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^ + '.$dw[++$wc].";\n"; + } + } + + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block.= + '$'.$e.$i.' = + $isbox[ $'.$e.$i.' & 0xff] | + ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) | + ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) | + ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; + } + $decrypt_block .= '$in = pack("N*"'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block.= ', + ($'.$e.$i. ' & '.((int)0xFF000000).') ^ + ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^ + ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^ + ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^ + '.$dw[$i]."\n"; + } + $decrypt_block .= ');'; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => '', + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } + + /** + * Encrypts a message. + * + * @see self::decrypt() + * @see parent::encrypt() + * @access public + * @param string $plaintext + * @return string + */ + public function encrypt($plaintext) + { + $this->setup(); + + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + $this->newtag = sodium_crypto_aead_aes256gcm_encrypt($plaintext, $this->aad, $this->nonce, $this->key); + return Strings::shift($this->newtag, strlen($plaintext)); + case self::ENGINE_OPENSSL_GCM: + return openssl_encrypt( + $plaintext, + 'aes-' . $this->getKeyLength() . '-gcm', + $this->key, + OPENSSL_RAW_DATA, + $this->nonce, + $this->newtag, + $this->aad + ); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * @see self::encrypt() + * @see parent::decrypt() + * @access public + * @param string $ciphertext + * @return string + */ + public function decrypt($ciphertext) + { + $this->setup(); + + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + if (strlen($this->oldtag) != 16) { + break; + } + $plaintext = sodium_crypto_aead_aes256gcm_decrypt($ciphertext . $this->oldtag, $this->aad, $this->nonce, $this->key); + if ($plaintext === false) { + $this->oldtag = false; + throw new BadDecryptionException('Error decrypting ciphertext with libsodium'); + } + return $plaintext; + case self::ENGINE_OPENSSL_GCM: + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + $plaintext = openssl_decrypt( + $ciphertext, + 'aes-' . $this->getKeyLength() . '-gcm', + $this->key, + OPENSSL_RAW_DATA, + $this->nonce, + $this->oldtag, + $this->aad + ); + if ($plaintext === false) { + $this->oldtag = false; + throw new BadDecryptionException('Error decrypting ciphertext with OpenSSL'); + } + return $plaintext; + } + + return parent::decrypt($ciphertext); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php new file mode 100644 index 000000000..d76af6af0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php @@ -0,0 +1,529 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\StreamCipher; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Common\Functions\Strings; + +/** + * Pure-PHP implementation of Salsa20. + * + * @package Salsa20 + * @author Jim Wigginton + * @access public + */ +class Salsa20 extends StreamCipher +{ + /** + * Part 1 of the state + * + * @var string|false + */ + protected $p1 = false; + + /** + * Part 2 of the state + * + * @var string|false + */ + protected $p2 = false; + + /** + * Key Length (in bytes) + * + * @var int + */ + protected $key_length = 32; // = 256 bits + + /** + * @access private + * @see \phpseclib3\Crypt\Salsa20::crypt() + */ + const ENCRYPT = 0; + + /** + * @access private + * @see \phpseclib3\Crypt\Salsa20::crypt() + */ + const DECRYPT = 1; + + /** + * Encryption buffer for continuous mode + * + * @var array + */ + protected $enbuffer; + + /** + * Decryption buffer for continuous mode + * + * @var array + */ + protected $debuffer; + + /** + * Counter + * + * @var int + */ + protected $counter = 0; + + /** + * Using Generated Poly1305 Key + * + * @var boolean + */ + protected $usingGeneratedPoly1305Key = false; + + /** + * Salsa20 uses a nonce + * + * @return bool + */ + public function usesNonce() + { + return true; + } + + /** + * Sets the key. + * + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported'); + } + + parent::setKey($key); + } + + /** + * Sets the nonce. + * + * @param string $nonce + */ + public function setNonce($nonce) + { + if (strlen($nonce) != 8) { + throw new \LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported'); + } + + $this->nonce = $nonce; + $this->changed = true; + $this->setEngine(); + } + + /** + * Sets the counter. + * + * @param int $counter + */ + public function setCounter($counter) + { + $this->counter = $counter; + $this->setEngine(); + } + + /** + * Creates a Poly1305 key using the method discussed in RFC8439 + * + * See https://tools.ietf.org/html/rfc8439#section-2.6.1 + */ + protected function createPoly1305Key() + { + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + $c = clone $this; + $c->setCounter(0); + $c->usePoly1305 = false; + $block = $c->encrypt(str_repeat("\0", 256)); + $this->setPoly1305Key(substr($block, 0, 32)); + + if ($this->counter == 0) { + $this->counter++; + } + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setNonce() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * @see self::setKey() + * @see self::setNonce() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; + + $this->changed = $this->nonIVChanged = false; + + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + if ($this->usePoly1305 && !isset($this->poly1305Key)) { + $this->usingGeneratedPoly1305Key = true; + $this->createPoly1305Key(); + } + + $key = $this->key; + if (strlen($key) == 16) { + $constant = 'expand 16-byte k'; + $key.= $key; + } else { + $constant = 'expand 32-byte k'; + } + + $this->p1 = substr($constant, 0, 4) . + substr($key, 0, 16) . + substr($constant, 4, 4) . + $this->nonce . + "\0\0\0\0"; + $this->p2 = substr($constant, 8, 4) . + substr($key, 16, 16) . + substr($constant, 12, 4); + } + + /** + * Setup the key (expansion) + */ + protected function setupKey() + { + // Salsa20 does not utilize this method + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + $ciphertext = $this->crypt($plaintext, self::ENCRYPT); + if (isset($this->poly1305Key)) { + $this->newtag = $this->poly1305($ciphertext); + } + return $ciphertext; + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if (isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + $newtag = $this->poly1305($ciphertext); + if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + } + + return $this->crypt($ciphertext, self::DECRYPT); + } + + /** + * Encrypts a block + * + * @param string $in + */ + protected function encryptBlock($in) + { + // Salsa20 does not utilize this method + } + + /** + * Decrypts a block + * + * @param string $in + */ + protected function decryptBlock($in) + { + // Salsa20 does not utilize this method + } + + /** + * Encrypts or decrypts a message. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $text + * @param int $mode + * @return string $text + */ + private function crypt($text, $mode) + { + $this->setup(); + if (!$this->continuousBuffer) { + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $this->counter) . $this->p2; + return openssl_encrypt( + $text, + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + } + $i = $this->counter; + $blocks = str_split($text, 64); + foreach ($blocks as &$block) { + $block^= static::salsa20($this->p1 . pack('V', $i++) . $this->p2); + } + + return implode('', $blocks); + } + + if ($mode == self::ENCRYPT) { + $buffer = &$this->enbuffer; + } else { + $buffer = &$this->debuffer; + } + if (strlen($buffer['ciphertext'])) { + $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text)); + $text = substr($text, strlen($ciphertext)); + if (!strlen($text)) { + return $ciphertext; + } + } + + $overflow = strlen($text) % 64; // & 0x3F + if ($overflow) { + $text2 = Strings::pop($text, $overflow); + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $buffer['counter']) . $this->p2; + // at this point $text should be a multiple of 64 + $buffer['counter']+= (strlen($text) >> 6) + 1; // ie. divide by 64 + $encrypted = openssl_encrypt( + $text . str_repeat("\0", 64), + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + $temp = Strings::pop($encrypted, 64); + } else { + $blocks = str_split($text, 64); + if (strlen($text)) { + foreach ($blocks as &$block) { + $block^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + } + $encrypted = implode('', $blocks); + $temp = static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + $ciphertext.= $encrypted . ($text2 ^ $temp); + $buffer['ciphertext'] = substr($temp, $overflow); + } elseif (!strlen($buffer['ciphertext'])) { + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $buffer['counter']) . $this->p2; + $buffer['counter']+= (strlen($text) >> 6); + $ciphertext.= openssl_encrypt( + $text, + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + } else { + $blocks = str_split($text, 64); + foreach ($blocks as &$block) { + $block^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + $ciphertext.= implode('', $blocks); + } + } + + return $ciphertext; + } + + /** + * Left Rotate + * + * @param int $x + * @param int $n + * @return int + */ + protected static function leftRotate($x, $n) + { + $r1 = $x << $n; + if (PHP_INT_SIZE == 8) { + $r1&= 0xFFFFFFFF; + $r2 = ($x & 0xFFFFFFFF) >> (32 - $n); + } else { + $r2 = $x >> (32 - $n); + $r2&= (1 << $n) - 1; + } + return $r1 | $r2; + } + + /** + * The quarterround function + * + * @param int $a + * @param int $b + * @param int $c + * @param int $d + */ + protected static function quarterRound(&$a, &$b, &$c, &$d) + { + $b^= self::leftRotate($a + $d, 7); + $c^= self::leftRotate($b + $a, 9); + $d^= self::leftRotate($c + $b, 13); + $a^= self::leftRotate($d + $c, 18); + } + + /** + * The doubleround function + * + * @param int $x0 (by reference) + * @param int $x1 (by reference) + * @param int $x2 (by reference) + * @param int $x3 (by reference) + * @param int $x4 (by reference) + * @param int $x5 (by reference) + * @param int $x6 (by reference) + * @param int $x7 (by reference) + * @param int $x8 (by reference) + * @param int $x9 (by reference) + * @param int $x10 (by reference) + * @param int $x11 (by reference) + * @param int $x12 (by reference) + * @param int $x13 (by reference) + * @param int $x14 (by reference) + * @param int $x15 (by reference) + */ + protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) + { + // columnRound + static::quarterRound( $x0, $x4, $x8, $x12); + static::quarterRound( $x5, $x9, $x13, $x1); + static::quarterRound($x10, $x14, $x2, $x6); + static::quarterRound($x15, $x3, $x7, $x11); + // rowRound + static::quarterRound( $x0, $x1, $x2, $x3); + static::quarterRound( $x5, $x6, $x7, $x4); + static::quarterRound($x10, $x11, $x8, $x9); + static::quarterRound($x15, $x12, $x13, $x14); + } + + /** + * The Salsa20 hash function function + * + * @param string $x + */ + protected static function salsa20($x) + { + $z = $x = unpack('V*', $x); + for ($i = 0; $i < 10; $i++) { + static::doubleRound(...$z); + } + + for ($i = 1; $i <= 16; $i++) { + $x[$i]+= $z[$i]; + } + + return pack('V*', ...$x); + } + + /** + * Calculates Poly1305 MAC + * + * @see self::decrypt() + * @see self::encrypt() + * @access private + * @param string $ciphertext + * @return string + */ + protected function poly1305($ciphertext) + { + if (!$this->usingGeneratedPoly1305Key) { + return parent::poly1305($this->aad . $ciphertext); + } else { + /* + sodium_crypto_aead_chacha20poly1305_encrypt does not calculate the poly1305 tag + the same way sodium_crypto_aead_chacha20poly1305_ietf_encrypt does. you can see + how the latter encrypts it in Salsa20::encrypt(). here's how the former encrypts + it: + + $this->newtag = $this->poly1305( + $this->aad . + pack('V', strlen($this->aad)) . "\0\0\0\0" . + $ciphertext . + pack('V', strlen($ciphertext)) . "\0\0\0\0" + ); + + phpseclib opts to use the IETF construction, even when the nonce is 64-bits + instead of 96-bits + */ + return parent::poly1305( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + pack('V', strlen($this->aad)) . "\0\0\0\0" . + pack('V', strlen($ciphertext)) . "\0\0\0\0" + ); + } + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php new file mode 100644 index 000000000..2c98d6392 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php @@ -0,0 +1,456 @@ + + * setKey('abcdefghijklmnopqrstuvwx'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $des->decrypt($des->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package TripleDES + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +/** + * Pure-PHP implementation of Triple DES. + * + * @package TripleDES + * @author Jim Wigginton + * @access public + */ +class TripleDES extends DES +{ + /** + * Encrypt / decrypt using inner chaining + * + * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3). + */ + const MODE_3CBC = -2; + + /** + * Encrypt / decrypt using outer chaining + * + * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib3\Crypt\Common\BlockCipher::MODE_CBC. + */ + const MODE_CBC3 = self::MODE_CBC; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\TripleDES::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 24; + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\DES::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + * @access private + */ + protected $cipher_name_mcrypt = 'tripledes'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + * @access private + */ + protected $cfb_init_len = 750; + + /** + * max possible size of $key + * + * @see self::setKey() + * @see \phpseclib3\Crypt\DES::setKey() + * @var string + * @access private + */ + protected $key_length_max = 24; + + /** + * Internal flag whether using self::MODE_3CBC or not + * + * @var bool + * @access private + */ + private $mode_3cbc; + + /** + * The \phpseclib3\Crypt\DES objects + * + * Used only if $mode_3cbc === true + * + * @var array + * @access private + */ + private $des; + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt or OpenSSL extensions should be used. + * + * $mode could be: + * + * - ecb + * + * - cbc + * + * - ctr + * + * - cfb + * + * - ofb + * + * - 3cbc + * + * - cbc3 (same as cbc) + * + * @see \phpseclib3\Crypt\DES::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param string $mode + * @access public + */ + public function __construct($mode) + { + switch (strtolower($mode)) { + // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC + // and additional flag us internally as 3CBC + case '3cbc': + parent::__construct('cbc'); + $this->mode_3cbc = true; + + // This three $des'es will do the 3CBC work (if $key > 64bits) + $this->des = [ + new DES('cbc'), + new DES('cbc'), + new DES('cbc'), + ]; + + // we're going to be doing the padding, ourselves, so disable it in the \phpseclib3\Crypt\DES objects + $this->des[0]->disablePadding(); + $this->des[1]->disablePadding(); + $this->des[2]->disablePadding(); + break; + case 'cbc3': + $mode = 'cbc'; + // If not 3CBC, we init as usual + default: + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @access protected + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($engine == self::ENGINE_OPENSSL) { + self::$cipher_name_openssl_ecb = 'des-ede3'; + $mode = $this->openssl_translate_mode(); + $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the initialization vector. + * + * SetIV is not required when \phpseclib3\Crypt\Common\SymmetricKey::MODE_ECB is being used. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setIV() + * @access public + * @param string $iv + */ + public function setIV($iv) + { + parent::setIV($iv); + if ($this->mode_3cbc) { + $this->des[0]->setIV($iv); + $this->des[1]->setIV($iv); + $this->des[2]->setIV($iv); + } + } + + /** + * Sets the key length. + * + * Valid key lengths are 128 and 192 bits. + * + * If you want to use a 64-bit key use DES.php + * + * @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength() + * @access public + * @throws \LengthException if the key length is invalid + * @param int $length + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 192: + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported'); + } + + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys. + * + * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. + * + * @access public + * @see \phpseclib3\Crypt\DES::setKey() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * @throws \LengthException if the key length is invalid + * @param string $key + */ + public function setKey($key) + { + if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { + throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); + } + + switch (strlen($key)) { + case 16: + $key.= substr($key, 0, 8); + break; + case 24: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported'); + } + + // copied from self::setKey() + $this->key = $key; + $this->key_length = strlen($key); + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); + + if ($this->mode_3cbc) { + $this->des[0]->setKey(substr($key, 0, 8)); + $this->des[1]->setKey(substr($key, 8, 8)); + $this->des[2]->setKey(substr($key, 16, 8)); + } + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @access public + * @param string $plaintext + * @return string $cipertext + */ + public function encrypt($plaintext) + { + // parent::en/decrypt() is able to do all the work for all modes and keylengths, + // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits + + // if the key is smaller then 8, do what we'd normally do + if ($this->mode_3cbc && strlen($this->key) > 8) { + return $this->des[2]->encrypt( + $this->des[1]->decrypt( + $this->des[0]->encrypt( + $this->pad($plaintext) + ) + ) + ); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @access public + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if ($this->mode_3cbc && strlen($this->key) > 8) { + return $this->unpad( + $this->des[0]->decrypt( + $this->des[1]->encrypt( + $this->des[2]->decrypt( + str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0") + ) + ) + ) + ); + } + + return parent::decrypt($ciphertext); + } + + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $des->encrypt(substr($plaintext, 0, 8)); + * echo $des->encrypt(substr($plaintext, 8, 8)); + * + * + * echo $des->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $des->encrypt(substr($plaintext, 0, 8)); + * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); + * + * + * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\DES() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::enableContinuousBuffer() + * @see self::disableContinuousBuffer() + * @access public + */ + public function enableContinuousBuffer() + { + parent::enableContinuousBuffer(); + if ($this->mode_3cbc) { + $this->des[0]->enableContinuousBuffer(); + $this->des[1]->enableContinuousBuffer(); + $this->des[2]->enableContinuousBuffer(); + } + } + + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::disableContinuousBuffer() + * @see self::enableContinuousBuffer() + * @access public + */ + public function disableContinuousBuffer() + { + parent::disableContinuousBuffer(); + if ($this->mode_3cbc) { + $this->des[0]->disableContinuousBuffer(); + $this->des[1]->disableContinuousBuffer(); + $this->des[2]->disableContinuousBuffer(); + } + } + + /** + * Creates the key schedule + * + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @access private + */ + protected function setupKey() + { + switch (true) { + // if $key <= 64bits we configure our internal pure-php cipher engine + // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same. + case strlen($this->key) <= 8: + $this->des_rounds = 1; + break; + + // otherwise, if $key > 64bits, we configure our engine to work as 3DES. + default: + $this->des_rounds = 3; + + // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. + if ($this->mode_3cbc) { + $this->des[0]->setupKey(); + $this->des[1]->setupKey(); + $this->des[2]->setupKey(); + + // because $des[0-2] will, now, do all the work we can return here + // not need unnecessary stress parent::setupKey() with our, now unused, $key. + return; + } + } + // setup our key + parent::setupKey(); + } + + /** + * Sets the internal crypt engine + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setPreferredEngine() + * @param int $engine + * @access public + */ + public function setPreferredEngine($engine) + { + if ($this->mode_3cbc) { + $this->des[0]->setPreferredEngine($engine); + $this->des[1]->setPreferredEngine($engine); + $this->des[2]->setPreferredEngine($engine); + } + + parent::setPreferredEngine($engine); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php new file mode 100644 index 000000000..c9cc5b46c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php @@ -0,0 +1,826 @@ + + * setKey('12345678901234567890123456789012'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $twofish->decrypt($twofish->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package Twofish + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; + +/** + * Pure-PHP implementation of Twofish. + * + * @package Twofish + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @access public + */ +class Twofish extends BlockCipher +{ + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + * @access private + */ + protected $cipher_name_mcrypt = 'twofish'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + * @access private + */ + protected $cfb_init_len = 800; + + /** + * Q-Table + * + * @var array + * @access private + */ + private static $q0 = [ + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, + 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, + 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, + 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, + 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, + 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, + 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, + 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, + 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, + 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, + 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, + 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, + 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, + 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, + 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, + 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, + 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, + 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, + 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, + 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, + 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, + 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 + ]; + + /** + * Q-Table + * + * @var array + * @access private + */ + private static $q1 = [ + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, + 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, + 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, + 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, + 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, + 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, + 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, + 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, + 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, + 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, + 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, + 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, + 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, + 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, + 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, + 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, + 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, + 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, + 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, + 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, + 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, + 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 + ]; + + /** + * M-Table + * + * @var array + * @access private + */ + private static $m0 = [ + 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8, + 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, + 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, + 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F, + 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, + 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, + 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3, + 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, + 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, + 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C, + 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, + 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, + 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC, + 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, + 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, + 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17, + 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, + 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, + 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149, + 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, + 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, + 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48, + 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, + 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, + 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5, + 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, + 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, + 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC, + 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, + 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, + 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2, + 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 + ]; + + /** + * M-Table + * + * @var array + * @access private + */ + private static $m1 = [ + 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4, + 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, + 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, + 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E, + 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, + 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, + 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D, + 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, + 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, + 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B, + 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, + 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, + 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D, + 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, + 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, + 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7, + 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, + 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, + 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E, + 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, + 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, + 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F, + 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, + 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, + 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7, + 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, + 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, + 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323, + 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, + 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, + 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000, + 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 + ]; + + /** + * M-Table + * + * @var array + * @access private + */ + private static $m2 = [ + 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA, + 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, + 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, + 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE, + 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, + 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, + 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065, + 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, + 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, + 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF, + 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, + 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, + 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF, + 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, + 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, + 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC, + 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, + 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, + 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101, + 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, + 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, + 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A, + 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, + 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, + 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6, + 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, + 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, + 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB, + 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, + 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, + 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746, + 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF + ]; + + /** + * M-Table + * + * @var array + * @access private + */ + private static $m3 = [ + 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF, + 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, + 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, + 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A, + 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, + 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, + 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63, + 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, + 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, + 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197, + 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, + 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, + 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20, + 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, + 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, + 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730, + 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, + 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, + 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F, + 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, + 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, + 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D, + 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, + 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, + 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6, + 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, + 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, + 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439, + 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, + 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, + 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000, + 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8 + ]; + + /** + * The Key Schedule Array + * + * @var array + * @access private + */ + private $K = []; + + /** + * The Key depended S-Table 0 + * + * @var array + * @access private + */ + private $S0 = []; + + /** + * The Key depended S-Table 1 + * + * @var array + * @access private + */ + private $S1 = []; + + /** + * The Key depended S-Table 2 + * + * @var array + * @access private + */ + private $S2 = []; + + /** + * The Key depended S-Table 3 + * + * @var array + * @access private + */ + private $S3 = []; + + /** + * Holds the last used key + * + * @var array + * @access private + */ + private $kl; + + /** + * The Key Length (in bytes) + * + * @see Crypt_Twofish::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 16; + + /** + * Default Constructor. + * + * @param string $mode + * @access public + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Sets the key length. + * + * Valid key lengths are 128, 192 or 256 bits + * + * @access public + * @param int $length + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 192: + case 256: + break; + default: + throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Rijndael supports five different key lengths + * + * @see setKeyLength() + * @access public + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 24: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + + parent::setKey($key); + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + * @access private + */ + protected function setupKey() + { + if (isset($this->kl['key']) && $this->key === $this->kl['key']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key]; + + /* Key expanding and generating the key-depended s-boxes */ + $le_longs = unpack('V*', $this->key); + $key = unpack('C*', $this->key); + $m0 = self::$m0; + $m1 = self::$m1; + $m2 = self::$m2; + $m3 = self::$m3; + $q0 = self::$q0; + $q1 = self::$q1; + + $K = $S0 = $S1 = $S2 = $S3 = []; + + switch (strlen($this->key)) { + case 16: + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[3], $le_longs[4]); + for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { + $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^ + $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^ + $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^ + $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]]; + $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^ + $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^ + $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^ + $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]]; + $B = ($B << 8) | ($B >> 24 & 0xff); + $A = self::safe_intval($A + $B); + $K[] = $A; + $A = self::safe_intval($A + $B); + $K[] = ($A << 9 | $A >> 23 & 0x1ff); + } + for ($i = 0; $i < 256; ++$i) { + $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0]; + $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1]; + $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2]; + $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3]; + } + break; + case 24: + list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[3], $le_longs[4]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[5], $le_longs[6]); + for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { + $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ + $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ + $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ + $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]]; + $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ + $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ + $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ + $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]]; + $B = ($B << 8) | ($B >> 24 & 0xff); + $A = self::safe_intval($A + $B); + $K[] = $A; + $A = self::safe_intval($A + $B); + $K[] = ($A << 9 | $A >> 23 & 0x1ff); + } + for ($i = 0; $i < 256; ++$i) { + $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0]; + $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1]; + $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2]; + $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3]; + } + break; + default: // 32 + list($sf, $se, $sd, $sc) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[3], $le_longs[4]); + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[5], $le_longs[6]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[7], $le_longs[8]); + for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { + $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ + $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ + $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ + $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]]; + $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ + $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ + $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ + $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]]; + $B = ($B << 8) | ($B >> 24 & 0xff); + $A = self::safe_intval($A + $B); + $K[] = $A; + $A = self::safe_intval($A + $B); + $K[] = ($A << 9 | $A >> 23 & 0x1ff); + } + for ($i = 0; $i < 256; ++$i) { + $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0]; + $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1]; + $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2]; + $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3]; + } + } + + $this->K = $K; + $this->S0 = $S0; + $this->S1 = $S1; + $this->S2 = $S2; + $this->S3 = $S3; + } + + /** + * _mdsrem function using by the twofish cipher algorithm + * + * @access private + * @param string $A + * @param string $B + * @return array + */ + private function mdsrem($A, $B) + { + // No gain by unrolling this loop. + for ($i = 0; $i < 8; ++$i) { + // Get most significant coefficient. + $t = 0xff & ($B >> 24); + + // Shift the others up. + $B = ($B << 8) | (0xff & ($A >> 24)); + $A<<= 8; + + $u = $t << 1; + + // Subtract the modular polynomial on overflow. + if ($t & 0x80) { + $u^= 0x14d; + } + + // Remove t * (a * x^2 + 1). + $B ^= $t ^ ($u << 16); + + // Form u = a*t + t/a = t*(a + 1/a). + $u^= 0x7fffffff & ($t >> 1); + + // Add the modular polynomial on underflow. + if ($t & 0x01) { + $u^= 0xa6 ; + } + + // Remove t * (a + 1/a) * (x^3 + x). + $B^= ($u << 24) | ($u << 8); + } + + return [ + 0xff & $B >> 24, + 0xff & $B >> 16, + 0xff & $B >> 8, + 0xff & $B]; + } + + /** + * Encrypts a block + * + * @access private + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + $S0 = $this->S0; + $S1 = $this->S1; + $S2 = $this->S2; + $S3 = $this->S3; + $K = $this->K; + + $in = unpack("V4", $in); + $R0 = $K[0] ^ $in[1]; + $R1 = $K[1] ^ $in[2]; + $R2 = $K[2] ^ $in[3]; + $R3 = $K[3] ^ $in[4]; + + $ki = 7; + while ($ki < 39) { + $t0 = $S0[ $R0 & 0xff] ^ + $S1[($R0 >> 8) & 0xff] ^ + $S2[($R0 >> 16) & 0xff] ^ + $S3[($R0 >> 24) & 0xff]; + $t1 = $S0[($R1 >> 24) & 0xff] ^ + $S1[ $R1 & 0xff] ^ + $S2[($R1 >> 8) & 0xff] ^ + $S3[($R1 >> 16) & 0xff]; + $R2^= self::safe_intval($t0 + $t1 + $K[++$ki]); + $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + + $t0 = $S0[ $R2 & 0xff] ^ + $S1[($R2 >> 8) & 0xff] ^ + $S2[($R2 >> 16) & 0xff] ^ + $S3[($R2 >> 24) & 0xff]; + $t1 = $S0[($R3 >> 24) & 0xff] ^ + $S1[ $R3 & 0xff] ^ + $S2[($R3 >> 8) & 0xff] ^ + $S3[($R3 >> 16) & 0xff]; + $R0^= self::safe_intval($t0 + $t1 + $K[++$ki]); + $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + } + + // @codingStandardsIgnoreStart + return pack("V4", $K[4] ^ $R2, + $K[5] ^ $R3, + $K[6] ^ $R0, + $K[7] ^ $R1); + // @codingStandardsIgnoreEnd + } + + /** + * Decrypts a block + * + * @access private + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + $S0 = $this->S0; + $S1 = $this->S1; + $S2 = $this->S2; + $S3 = $this->S3; + $K = $this->K; + + $in = unpack("V4", $in); + $R0 = $K[4] ^ $in[1]; + $R1 = $K[5] ^ $in[2]; + $R2 = $K[6] ^ $in[3]; + $R3 = $K[7] ^ $in[4]; + + $ki = 40; + while ($ki > 8) { + $t0 = $S0[$R0 & 0xff] ^ + $S1[$R0 >> 8 & 0xff] ^ + $S2[$R0 >> 16 & 0xff] ^ + $S3[$R0 >> 24 & 0xff]; + $t1 = $S0[$R1 >> 24 & 0xff] ^ + $S1[$R1 & 0xff] ^ + $S2[$R1 >> 8 & 0xff] ^ + $S3[$R1 >> 16 & 0xff]; + $R3^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); + + $t0 = $S0[$R2 & 0xff] ^ + $S1[$R2 >> 8 & 0xff] ^ + $S2[$R2 >> 16 & 0xff] ^ + $S3[$R2 >> 24 & 0xff]; + $t1 = $S0[$R3 >> 24 & 0xff] ^ + $S1[$R3 & 0xff] ^ + $S2[$R3 >> 8 & 0xff] ^ + $S3[$R3 >> 16 & 0xff]; + $R1^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); + } + + // @codingStandardsIgnoreStart + return pack("V4", $K[0] ^ $R2, + $K[1] ^ $R3, + $K[2] ^ $R0, + $K[3] ^ $R1); + // @codingStandardsIgnoreEnd + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() + * @access private + */ + protected function setupInlineCrypt() + { + $K = $this->K; + $init_crypt = ' + static $S0, $S1, $S2, $S3; + if (!$S0) { + for ($i = 0; $i < 256; ++$i) { + $S0[] = (int)$this->S0[$i]; + $S1[] = (int)$this->S1[$i]; + $S2[] = (int)$this->S2[$i]; + $S3[] = (int)$this->S3[$i]; + } + } + '; + + $safeint = self::safe_intval_inline(); + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("V4", $in); + $R0 = '.$K[0].' ^ $in[1]; + $R1 = '.$K[1].' ^ $in[2]; + $R2 = '.$K[2].' ^ $in[3]; + $R3 = '.$K[3].' ^ $in[4]; + '; + for ($ki = 7, $i = 0; $i < 8; ++$i) { + $encrypt_block.= ' + $t0 = $S0[ $R0 & 0xff] ^ + $S1[($R0 >> 8) & 0xff] ^ + $S2[($R0 >> 16) & 0xff] ^ + $S3[($R0 >> 24) & 0xff]; + $t1 = $S0[($R1 >> 24) & 0xff] ^ + $S1[ $R1 & 0xff] ^ + $S2[($R1 >> 8) & 0xff] ^ + $S3[($R1 >> 16) & 0xff]; + $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . '; + $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + + $t0 = $S0[ $R2 & 0xff] ^ + $S1[($R2 >> 8) & 0xff] ^ + $S2[($R2 >> 16) & 0xff] ^ + $S3[($R2 >> 24) & 0xff]; + $t1 = $S0[($R3 >> 24) & 0xff] ^ + $S1[ $R3 & 0xff] ^ + $S2[($R3 >> 8) & 0xff] ^ + $S3[($R3 >> 16) & 0xff]; + $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; + $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + '; + } + $encrypt_block.= ' + $in = pack("V4", '.$K[4].' ^ $R2, + '.$K[5].' ^ $R3, + '.$K[6].' ^ $R0, + '.$K[7].' ^ $R1); + '; + + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("V4", $in); + $R0 = '.$K[4].' ^ $in[1]; + $R1 = '.$K[5].' ^ $in[2]; + $R2 = '.$K[6].' ^ $in[3]; + $R3 = '.$K[7].' ^ $in[4]; + '; + for ($ki = 40, $i = 0; $i < 8; ++$i) { + $decrypt_block.= ' + $t0 = $S0[$R0 & 0xff] ^ + $S1[$R0 >> 8 & 0xff] ^ + $S2[$R0 >> 16 & 0xff] ^ + $S3[$R0 >> 24 & 0xff]; + $t1 = $S0[$R1 >> 24 & 0xff] ^ + $S1[$R1 & 0xff] ^ + $S2[$R1 >> 8 & 0xff] ^ + $S3[$R1 >> 16 & 0xff]; + $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; + + $t0 = $S0[$R2 & 0xff] ^ + $S1[$R2 >> 8 & 0xff] ^ + $S2[$R2 >> 16 & 0xff] ^ + $S3[$R2 >> 24 & 0xff]; + $t1 = $S0[$R3 >> 24 & 0xff] ^ + $S1[$R3 & 0xff] ^ + $S2[$R3 >> 8 & 0xff] ^ + $S3[$R3 >> 16 & 0xff]; + $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; + '; + } + $decrypt_block.= ' + $in = pack("V4", '.$K[0].' ^ $R2, + '.$K[1].' ^ $R3, + '.$K[2].' ^ $R0, + '.$K[3].' ^ $R1); + '; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php new file mode 100644 index 000000000..fa5a818ac --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadConfigurationException + * + * @package BadConfigurationException + * @author Jim Wigginton + */ +class BadConfigurationException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php new file mode 100644 index 000000000..c1171b159 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadDecryptionException + * + * @package BadDecryptionException + * @author Jim Wigginton + */ +class BadDecryptionException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php new file mode 100644 index 000000000..ace9f578d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadModeException + * + * @package BadModeException + * @author Jim Wigginton + */ +class BadModeException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php new file mode 100644 index 000000000..d6300d5c6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * ConnectionClosedException + * + * @package ConnectionClosedException + * @author Jim Wigginton + */ +class ConnectionClosedException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php new file mode 100644 index 000000000..bc1b91898 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * FileNotFoundException + * + * @package FileNotFoundException + * @author Jim Wigginton + */ +class FileNotFoundException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php new file mode 100644 index 000000000..77db4a0e2 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * InconsistentSetupException + * + * @package InconsistentSetupException + * @author Jim Wigginton + */ +class InconsistentSetupException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php new file mode 100644 index 000000000..27f49f2f8 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * InsufficientSetupException + * + * @package InsufficientSetupException + * @author Jim Wigginton + */ +class InsufficientSetupException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php new file mode 100644 index 000000000..95152eb46 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * NoKeyLoadedException + * + * @package NoKeyLoadedException + * @author Jim Wigginton + */ +class NoKeyLoadedException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php new file mode 100644 index 000000000..7a7471dca --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * NoSupportedAlgorithmsException + * + * @package NoSupportedAlgorithmsException + * @author Jim Wigginton + */ +class NoSupportedAlgorithmsException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php new file mode 100644 index 000000000..909ef67fa --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnableToConnectException + * + * @package UnableToConnectException + * @author Jim Wigginton + */ +class UnableToConnectException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php new file mode 100644 index 000000000..e0c07a436 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedAlgorithmException + * + * @package UnsupportedAlgorithmException + * @author Jim Wigginton + */ +class UnsupportedAlgorithmException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php new file mode 100644 index 000000000..6d746ab1b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedCurveException + * + * @package UnsupportedCurveException + * @author Jim Wigginton + */ +class UnsupportedCurveException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php new file mode 100644 index 000000000..f58f812d3 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedFormatException + * + * @package UnsupportedFormatException + * @author Jim Wigginton + */ +class UnsupportedFormatException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php new file mode 100644 index 000000000..7872a1a82 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedOperationException + * + * @package UnsupportedOperationException + * @author Jim Wigginton + */ +class UnsupportedOperationException extends \RuntimeException +{ +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php new file mode 100644 index 000000000..f0dc19618 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php @@ -0,0 +1,580 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File; + +/** + * Pure-PHP ANSI Decoder + * + * @package ANSI + * @author Jim Wigginton + * @access public + */ +class ANSI +{ + /** + * Max Width + * + * @var int + * @access private + */ + private $max_x; + + /** + * Max Height + * + * @var int + * @access private + */ + private $max_y; + + /** + * Max History + * + * @var int + * @access private + */ + private $max_history; + + /** + * History + * + * @var array + * @access private + */ + private $history; + + /** + * History Attributes + * + * @var array + * @access private + */ + private $history_attrs; + + /** + * Current Column + * + * @var int + * @access private + */ + private $x; + + /** + * Current Row + * + * @var int + * @access private + */ + private $y; + + /** + * Old Column + * + * @var int + * @access private + */ + private $old_x; + + /** + * Old Row + * + * @var int + * @access private + */ + private $old_y; + + /** + * An empty attribute cell + * + * @var object + * @access private + */ + private $base_attr_cell; + + /** + * The current attribute cell + * + * @var object + * @access private + */ + private $attr_cell; + + /** + * An empty attribute row + * + * @var array + * @access private + */ + private $attr_row; + + /** + * The current screen text + * + * @var array + * @access private + */ + private $screen; + + /** + * The current screen attributes + * + * @var array + * @access private + */ + private $attrs; + + /** + * Current ANSI code + * + * @var string + * @access private + */ + private $ansi; + + /** + * Tokenization + * + * @var array + * @access private + */ + private $tokenization; + + /** + * Default Constructor. + * + * @return \phpseclib3\File\ANSI + * @access public + */ + public function __construct() + { + $attr_cell = new \stdClass(); + $attr_cell->bold = false; + $attr_cell->underline = false; + $attr_cell->blink = false; + $attr_cell->background = 'black'; + $attr_cell->foreground = 'white'; + $attr_cell->reverse = false; + $this->base_attr_cell = clone $attr_cell; + $this->attr_cell = clone $attr_cell; + + $this->setHistory(200); + $this->setDimensions(80, 24); + } + + /** + * Set terminal width and height + * + * Resets the screen as well + * + * @param int $x + * @param int $y + * @access public + */ + public function setDimensions($x, $y) + { + $this->max_x = $x - 1; + $this->max_y = $y - 1; + $this->x = $this->y = 0; + $this->history = $this->history_attrs = []; + $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell); + $this->screen = array_fill(0, $this->max_y + 1, ''); + $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row); + $this->ansi = ''; + } + + /** + * Set the number of lines that should be logged past the terminal height + * + * @param int $history + * @access public + */ + public function setHistory($history) + { + $this->max_history = $history; + } + + /** + * Load a string + * + * @param string $source + * @access public + */ + public function loadString($source) + { + $this->setDimensions($this->max_x + 1, $this->max_y + 1); + $this->appendString($source); + } + + /** + * Appdend a string + * + * @param string $source + * @access public + */ + public function appendString($source) + { + $this->tokenization = ['']; + for ($i = 0; $i < strlen($source); $i++) { + if (strlen($this->ansi)) { + $this->ansi.= $source[$i]; + $chr = ord($source[$i]); + // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements + // single character CSI's not currently supported + switch (true) { + case $this->ansi == "\x1B=": + $this->ansi = ''; + continue 2; + case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['): + case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126: + break; + default: + continue 2; + } + $this->tokenization[] = $this->ansi; + $this->tokenization[] = ''; + // http://ascii-table.com/ansi-escape-sequences-vt-100.php + switch ($this->ansi) { + case "\x1B[H": // Move cursor to upper left corner + $this->old_x = $this->x; + $this->old_y = $this->y; + $this->x = $this->y = 0; + break; + case "\x1B[J": // Clear screen from cursor down + $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y)); + $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, '')); + + $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y)); + $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row)); + + if (count($this->history) == $this->max_history) { + array_shift($this->history); + array_shift($this->history_attrs); + } + case "\x1B[K": // Clear screen from cursor right + $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x); + + array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - ($this->x - 1), $this->base_attr_cell)); + break; + case "\x1B[2K": // Clear entire line + $this->screen[$this->y] = str_repeat(' ', $this->x); + $this->attrs[$this->y] = $this->attr_row; + break; + case "\x1B[?1h": // set cursor key to application + case "\x1B[?25h": // show the cursor + case "\x1B(B": // set united states g0 character set + break; + case "\x1BE": // Move to next line + $this->newLine(); + $this->x = 0; + break; + default: + switch (true) { + case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines + $this->old_y = $this->y; + $this->y+= $match[1]; + break; + case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h + $this->old_x = $this->x; + $this->old_y = $this->y; + $this->x = $match[2] - 1; + $this->y = $match[1] - 1; + break; + case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines + $this->old_x = $this->x; + $this->x+= $match[1]; + break; + case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines + $this->old_x = $this->x; + $this->x-= $match[1]; + if ($this->x < 0) { + $this->x = 0; + } + break; + case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window + break; + case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes + $attr_cell = &$this->attr_cell; + $mods = explode(';', $match[1]); + foreach ($mods as $mod) { + switch ($mod) { + case '': + case '0': // Turn off character attributes + $attr_cell = clone $this->base_attr_cell; + break; + case '1': // Turn bold mode on + $attr_cell->bold = true; + break; + case '4': // Turn underline mode on + $attr_cell->underline = true; + break; + case '5': // Turn blinking mode on + $attr_cell->blink = true; + break; + case '7': // Turn reverse video on + $attr_cell->reverse = !$attr_cell->reverse; + $temp = $attr_cell->background; + $attr_cell->background = $attr_cell->foreground; + $attr_cell->foreground = $temp; + break; + default: // set colors + //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground; + $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' }; + //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background; + $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' }; + switch ($mod) { + // @codingStandardsIgnoreStart + case '30': $front = 'black'; break; + case '31': $front = 'red'; break; + case '32': $front = 'green'; break; + case '33': $front = 'yellow'; break; + case '34': $front = 'blue'; break; + case '35': $front = 'magenta'; break; + case '36': $front = 'cyan'; break; + case '37': $front = 'white'; break; + + case '40': $back = 'black'; break; + case '41': $back = 'red'; break; + case '42': $back = 'green'; break; + case '43': $back = 'yellow'; break; + case '44': $back = 'blue'; break; + case '45': $back = 'magenta'; break; + case '46': $back = 'cyan'; break; + case '47': $back = 'white'; break; + // @codingStandardsIgnoreEnd + + default: + //user_error('Unsupported attribute: ' . $mod); + $this->ansi = ''; + break 2; + } + } + } + break; + default: + //user_error("{$this->ansi} is unsupported\r\n"); + } + } + $this->ansi = ''; + continue; + } + + $this->tokenization[count($this->tokenization) - 1].= $source[$i]; + switch ($source[$i]) { + case "\r": + $this->x = 0; + break; + case "\n": + $this->newLine(); + break; + case "\x08": // backspace + if ($this->x) { + $this->x--; + $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell; + $this->screen[$this->y] = substr_replace( + $this->screen[$this->y], + $source[$i], + $this->x, + 1 + ); + } + break; + case "\x0F": // shift + break; + case "\x1B": // start ANSI escape code + $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1); + //if (!strlen($this->tokenization[count($this->tokenization) - 1])) { + // array_pop($this->tokenization); + //} + $this->ansi.= "\x1B"; + break; + default: + $this->attrs[$this->y][$this->x] = clone $this->attr_cell; + if ($this->x > strlen($this->screen[$this->y])) { + $this->screen[$this->y] = str_repeat(' ', $this->x); + } + $this->screen[$this->y] = substr_replace( + $this->screen[$this->y], + $source[$i], + $this->x, + 1 + ); + + if ($this->x > $this->max_x) { + $this->x = 0; + $this->newLine(); + } else { + $this->x++; + } + } + } + } + + /** + * Add a new line + * + * Also update the $this->screen and $this->history buffers + * + * @access private + */ + private function newLine() + { + //if ($this->y < $this->max_y) { + // $this->y++; + //} + + while ($this->y >= $this->max_y) { + $this->history = array_merge($this->history, [array_shift($this->screen)]); + $this->screen[] = ''; + + $this->history_attrs = array_merge($this->history_attrs, [array_shift($this->attrs)]); + $this->attrs[] = $this->attr_row; + + if (count($this->history) >= $this->max_history) { + array_shift($this->history); + array_shift($this->history_attrs); + } + + $this->y--; + } + $this->y++; + } + + /** + * Returns the current coordinate without preformating + * + * @access private + * @param \stdClass $last_attr + * @param \stdClass $cur_attr + * @param string $char + * @return string + */ + private function processCoordinate($last_attr, $cur_attr, $char) + { + $output = ''; + + if ($last_attr != $cur_attr) { + $close = $open = ''; + if ($last_attr->foreground != $cur_attr->foreground) { + if ($cur_attr->foreground != 'white') { + $open.= ''; + } + if ($last_attr->foreground != 'white') { + $close = '' . $close; + } + } + if ($last_attr->background != $cur_attr->background) { + if ($cur_attr->background != 'black') { + $open.= ''; + } + if ($last_attr->background != 'black') { + $close = '' . $close; + } + } + if ($last_attr->bold != $cur_attr->bold) { + if ($cur_attr->bold) { + $open.= ''; + } else { + $close = '' . $close; + } + } + if ($last_attr->underline != $cur_attr->underline) { + if ($cur_attr->underline) { + $open.= ''; + } else { + $close = '' . $close; + } + } + if ($last_attr->blink != $cur_attr->blink) { + if ($cur_attr->blink) { + $open.= ''; + } else { + $close = '' . $close; + } + } + $output.= $close . $open; + } + + $output.= htmlspecialchars($char); + + return $output; + } + + /** + * Returns the current screen without preformating + * + * @access private + * @return string + */ + private function getScreenHelper() + { + $output = ''; + $last_attr = $this->base_attr_cell; + for ($i = 0; $i <= $this->max_y; $i++) { + for ($j = 0; $j <= $this->max_x; $j++) { + $cur_attr = $this->attrs[$i][$j]; + $output.= $this->processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); + $last_attr = $this->attrs[$i][$j]; + } + $output.= "\r\n"; + } + $output = substr($output, 0, -2); + // close any remaining open tags + $output.= $this->processCoordinate($last_attr, $this->base_attr_cell, ''); + return rtrim($output); + } + + /** + * Returns the current screen + * + * @access public + * @return string + */ + public function getScreen() + { + return '
      ' . $this->getScreenHelper() . '
      '; + } + + /** + * Returns the current screen and the x previous lines + * + * @access public + * @return string + */ + public function getHistory() + { + $scrollback = ''; + $last_attr = $this->base_attr_cell; + for ($i = 0; $i < count($this->history); $i++) { + for ($j = 0; $j <= $this->max_x + 1; $j++) { + $cur_attr = $this->history_attrs[$i][$j]; + $scrollback.= $this->processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); + $last_attr = $this->history_attrs[$i][$j]; + } + $scrollback.= "\r\n"; + } + $base_attr_cell = $this->base_attr_cell; + $this->base_attr_cell = $last_attr; + $scrollback.= $this->getScreen(); + $this->base_attr_cell = $base_attr_cell; + + return '
      ' . $scrollback . '
      '; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php new file mode 100644 index 000000000..cdc5b697d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php @@ -0,0 +1,1498 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File; + +use ParagonIE\ConstantTime\Base64; +use phpseclib3\File\ASN1\Element; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; +use DateTime; +use DateTimeZone; + +/** + * Pure-PHP ASN.1 Parser + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ASN1 +{ + // Tag Classes + // http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 + const CLASS_UNIVERSAL = 0; + const CLASS_APPLICATION = 1; + const CLASS_CONTEXT_SPECIFIC = 2; + const CLASS_PRIVATE = 3; + + // Tag Classes + // http://www.obj-sys.com/asn1tutorial/node124.html + const TYPE_BOOLEAN = 1; + const TYPE_INTEGER = 2; + const TYPE_BIT_STRING = 3; + const TYPE_OCTET_STRING = 4; + const TYPE_NULL = 5; + const TYPE_OBJECT_IDENTIFIER = 6; + //const TYPE_OBJECT_DESCRIPTOR = 7; + //const TYPE_INSTANCE_OF = 8; // EXTERNAL + const TYPE_REAL = 9; + const TYPE_ENUMERATED = 10; + //const TYPE_EMBEDDED = 11; + const TYPE_UTF8_STRING = 12; + //const TYPE_RELATIVE_OID = 13; + const TYPE_SEQUENCE = 16; // SEQUENCE OF + const TYPE_SET = 17; // SET OF + + // More Tag Classes + // http://www.obj-sys.com/asn1tutorial/node10.html + const TYPE_NUMERIC_STRING = 18; + const TYPE_PRINTABLE_STRING = 19; + const TYPE_TELETEX_STRING = 20; // T61String + const TYPE_VIDEOTEX_STRING = 21; + const TYPE_IA5_STRING = 22; + const TYPE_UTC_TIME = 23; + const TYPE_GENERALIZED_TIME = 24; + const TYPE_GRAPHIC_STRING = 25; + const TYPE_VISIBLE_STRING = 26; // ISO646String + const TYPE_GENERAL_STRING = 27; + const TYPE_UNIVERSAL_STRING = 28; + //const TYPE_CHARACTER_STRING = 29; + const TYPE_BMP_STRING = 30; + + // Tag Aliases + // These tags are kinda place holders for other tags. + const TYPE_CHOICE = -1; + const TYPE_ANY = -2; + + /** + * ASN.1 object identifiers + * + * @var array + * @access private + * @link http://en.wikipedia.org/wiki/Object_identifier + */ + private static $oids = []; + + /** + * ASN.1 object identifier reverse mapping + * + * @var array + * @access private + */ + private static $reverseOIDs = []; + + /** + * Default date format + * + * @var string + * @access private + * @link http://php.net/class.datetime + */ + private static $format = 'D, d M Y H:i:s O'; + + /** + * Filters + * + * If the mapping type is self::TYPE_ANY what do we actually encode it as? + * + * @var array + * @access private + * @see self::encode_der() + */ + private static $filters; + + /** + * Current Location of most recent ASN.1 encode process + * + * Useful for debug purposes + * + * @var array + * @access private + * @see self::encode_der() + */ + private static $location; + + /** + * DER Encoded String + * + * In case we need to create ASN1\Element object's.. + * + * @var string + * @access private + * @see self::decodeDER() + */ + private static $encoded; + + /** + * Type mapping table for the ANY type. + * + * Structured or unknown types are mapped to a \phpseclib3\File\ASN1\Element. + * Unambiguous types get the direct mapping (int/real/bool). + * Others are mapped as a choice, with an extra indexing level. + * + * @var array + * @access public + */ + const ANY_MAP = [ + self::TYPE_BOOLEAN => true, + self::TYPE_INTEGER => true, + self::TYPE_BIT_STRING => 'bitString', + self::TYPE_OCTET_STRING => 'octetString', + self::TYPE_NULL => 'null', + self::TYPE_OBJECT_IDENTIFIER => 'objectIdentifier', + self::TYPE_REAL => true, + self::TYPE_ENUMERATED => 'enumerated', + self::TYPE_UTF8_STRING => 'utf8String', + self::TYPE_NUMERIC_STRING => 'numericString', + self::TYPE_PRINTABLE_STRING => 'printableString', + self::TYPE_TELETEX_STRING => 'teletexString', + self::TYPE_VIDEOTEX_STRING => 'videotexString', + self::TYPE_IA5_STRING => 'ia5String', + self::TYPE_UTC_TIME => 'utcTime', + self::TYPE_GENERALIZED_TIME => 'generalTime', + self::TYPE_GRAPHIC_STRING => 'graphicString', + self::TYPE_VISIBLE_STRING => 'visibleString', + self::TYPE_GENERAL_STRING => 'generalString', + self::TYPE_UNIVERSAL_STRING => 'universalString', + //self::TYPE_CHARACTER_STRING => 'characterString', + self::TYPE_BMP_STRING => 'bmpString' + ]; + + /** + * String type to character size mapping table. + * + * Non-convertable types are absent from this table. + * size == 0 indicates variable length encoding. + * + * @var array + * @access public + */ + const STRING_TYPE_SIZE = [ + self::TYPE_UTF8_STRING => 0, + self::TYPE_BMP_STRING => 2, + self::TYPE_UNIVERSAL_STRING => 4, + self::TYPE_PRINTABLE_STRING => 1, + self::TYPE_TELETEX_STRING => 1, + self::TYPE_IA5_STRING => 1, + self::TYPE_VISIBLE_STRING => 1, + ]; + + /** + * Parse BER-encoding + * + * Serves a similar purpose to openssl's asn1parse + * + * @param string $encoded + * @return array + * @access public + */ + public static function decodeBER($encoded) + { + if ($encoded instanceof Element) { + $encoded = $encoded->element; + } + + self::$encoded = $encoded; + + $decoded = [self::decode_ber($encoded)]; + + // encapsulate in an array for BC with the old decodeBER + return $decoded; + } + + /** + * Parse BER-encoding (Helper function) + * + * Sometimes we want to get the BER encoding of a particular tag. $start lets us do that without having to reencode. + * $encoded is passed by reference for the recursive calls done for self::TYPE_BIT_STRING and + * self::TYPE_OCTET_STRING. In those cases, the indefinite length is used. + * + * @param string $encoded + * @param int $start + * @param int $encoded_pos + * @return array|bool + * @access private + */ + private static function decode_ber($encoded, $start = 0, $encoded_pos = 0) + { + $current = ['start' => $start]; + + $type = ord($encoded[$encoded_pos++]); + $start++; + + $constructed = ($type >> 5) & 1; + + $tag = $type & 0x1F; + if ($tag == 0x1F) { + $tag = 0; + // process septets (since the eighth bit is ignored, it's not an octet) + do { + $temp = ord($encoded[$encoded_pos++]); + $loop = $temp >> 7; + $tag <<= 7; + $tag |= $temp & 0x7F; + $start++; + } while ($loop); + } + + // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 + $length = ord($encoded[$encoded_pos++]); + $start++; + if ($length == 0x80) { // indefinite length + // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all + // immediately available." -- paragraph 8.1.3.2.c + $length = strlen($encoded) - $encoded_pos; + } elseif ($length & 0x80) { // definite length, long form + // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only + // support it up to four. + $length&= 0x7F; + $temp = substr($encoded, $encoded_pos, $length); + $encoded_pos += $length; + // tags of indefinte length don't really have a header length; this length includes the tag + $current+= ['headerlength' => $length + 2]; + $start+= $length; + extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); + /** @var integer $length */ + } else { + $current+= ['headerlength' => 2]; + } + + if ($length > (strlen($encoded) - $encoded_pos)) { + return false; + } + + $content = substr($encoded, $encoded_pos, $length); + $content_pos = 0; + + // at this point $length can be overwritten. it's only accurate for definite length things as is + + /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1 + built-in types. It defines an application-independent data type that must be distinguishable from all other + data types. The other three classes are user defined. The APPLICATION class distinguishes data types that + have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within + a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the + alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this + data type; the term CONTEXT-SPECIFIC does not appear. + + -- http://www.obj-sys.com/asn1tutorial/node12.html */ + $class = ($type >> 6) & 3; + switch ($class) { + case self::CLASS_APPLICATION: + case self::CLASS_PRIVATE: + case self::CLASS_CONTEXT_SPECIFIC: + if (!$constructed) { + return [ + 'type' => $class, + 'constant' => $tag, + 'content' => $content, + 'length' => $length + $start - $current['start'] + ] + $current; + } + + $newcontent = []; + $remainingLength = $length; + while ($remainingLength > 0) { + $temp = self::decode_ber($content, $start, $content_pos); + if ($temp === false) { + break; + } + $length = $temp['length']; + // end-of-content octets - see paragraph 8.1.5 + if (substr($content, $content_pos + $length, 2) == "\0\0") { + $length+= 2; + $start+= $length; + $newcontent[] = $temp; + break; + } + $start+= $length; + $remainingLength-= $length; + $newcontent[] = $temp; + $content_pos += $length; + } + + return [ + 'type' => $class, + 'constant' => $tag, + // the array encapsulation is for BC with the old format + 'content' => $newcontent, + // the only time when $content['headerlength'] isn't defined is when the length is indefinite. + // the absence of $content['headerlength'] is how we know if something is indefinite or not. + // technically, it could be defined to be 2 and then another indicator could be used but whatever. + 'length' => $start - $current['start'] + ] + $current; + } + + $current+= ['type' => $tag]; + + // decode UNIVERSAL tags + switch ($tag) { + case self::TYPE_BOOLEAN: + // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 + //if (strlen($content) != 1) { + // return false; + //} + $current['content'] = (bool) ord($content[$content_pos]); + break; + case self::TYPE_INTEGER: + case self::TYPE_ENUMERATED: + $current['content'] = new BigInteger(substr($content, $content_pos), -256); + break; + case self::TYPE_REAL: // not currently supported + return false; + case self::TYPE_BIT_STRING: + // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, + // the number of unused bits in the final subsequent octet. The number shall be in the range zero to + // seven. + if (!$constructed) { + $current['content'] = substr($content, $content_pos); + } else { + $temp = self::decode_ber($content, $start, $content_pos); + if ($temp === false) { + return false; + } + $length-= (strlen($content) - $content_pos); + $last = count($temp) - 1; + for ($i = 0; $i < $last; $i++) { + // all subtags should be bit strings + //if ($temp[$i]['type'] != self::TYPE_BIT_STRING) { + // return false; + //} + $current['content'].= substr($temp[$i]['content'], 1); + } + // all subtags should be bit strings + //if ($temp[$last]['type'] != self::TYPE_BIT_STRING) { + // return false; + //} + $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); + } + break; + case self::TYPE_OCTET_STRING: + if (!$constructed) { + $current['content'] = substr($content, $content_pos); + } else { + $current['content'] = ''; + $length = 0; + while (substr($content, $content_pos, 2) != "\0\0") { + $temp = self::decode_ber($content, $length + $start, $content_pos); + if ($temp === false) { + return false; + } + $content_pos += $temp['length']; + // all subtags should be octet strings + //if ($temp['type'] != self::TYPE_OCTET_STRING) { + // return false; + //} + $current['content'].= $temp['content']; + $length+= $temp['length']; + } + if (substr($content, $content_pos, 2) == "\0\0") { + $length+= 2; // +2 for the EOC + } + } + break; + case self::TYPE_NULL: + // "The contents octets shall not contain any octets." -- paragraph 8.8.2 + //if (strlen($content)) { + // return false; + //} + break; + case self::TYPE_SEQUENCE: + case self::TYPE_SET: + $offset = 0; + $current['content'] = []; + $content_len = strlen($content); + while ($content_pos < $content_len) { + // if indefinite length construction was used and we have an end-of-content string next + // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2 + if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") { + $length = $offset + 2; // +2 for the EOC + break 2; + } + $temp = self::decode_ber($content, $start + $offset, $content_pos); + if ($temp === false) { + return false; + } + $content_pos += $temp['length']; + $current['content'][] = $temp; + $offset+= $temp['length']; + } + break; + case self::TYPE_OBJECT_IDENTIFIER: + $current['content'] = self::decodeOID(substr($content, $content_pos)); + break; + /* Each character string type shall be encoded as if it had been declared: + [UNIVERSAL x] IMPLICIT OCTET STRING + + -- X.690-0207.pdf#page=23 (paragraph 8.21.3) + + Per that, we're not going to do any validation. If there are any illegal characters in the string, + we don't really care */ + case self::TYPE_NUMERIC_STRING: + // 0,1,2,3,4,5,6,7,8,9, and space + case self::TYPE_PRINTABLE_STRING: + // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma, + // hyphen, full stop, solidus, colon, equal sign, question mark + case self::TYPE_TELETEX_STRING: + // The Teletex character set in CCITT's T61, space, and delete + // see http://en.wikipedia.org/wiki/Teletex#Character_sets + case self::TYPE_VIDEOTEX_STRING: + // The Videotex character set in CCITT's T.100 and T.101, space, and delete + case self::TYPE_VISIBLE_STRING: + // Printing character sets of international ASCII, and space + case self::TYPE_IA5_STRING: + // International Alphabet 5 (International ASCII) + case self::TYPE_GRAPHIC_STRING: + // All registered G sets, and space + case self::TYPE_GENERAL_STRING: + // All registered C and G sets, space and delete + case self::TYPE_UTF8_STRING: + // ???? + case self::TYPE_BMP_STRING: + $current['content'] = substr($content, $content_pos); + break; + case self::TYPE_UTC_TIME: + case self::TYPE_GENERALIZED_TIME: + $current['content'] = self::decodeTime(substr($content, $content_pos), $tag); + default: + } + + $start+= $length; + + // ie. length is the length of the full TLV encoding - it's not just the length of the value + return $current + ['length' => $start - $current['start']]; + } + + /** + * ASN.1 Map + * + * Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format. + * + * "Special" mappings may be applied on a per tag-name basis via $special. + * + * @param array $decoded + * @param array $mapping + * @param array $special + * @return array|bool|Element + * @access public + */ + public static function asn1map($decoded, $mapping, $special = []) + { + if (!is_array($decoded)) { + return false; + } + + if (isset($mapping['explicit']) && is_array($decoded['content'])) { + $decoded = $decoded['content'][0]; + } + + switch (true) { + case $mapping['type'] == self::TYPE_ANY: + $intype = $decoded['type']; + // !isset(self::ANY_MAP[$intype]) produces a fatal error on PHP 5.6 + if (isset($decoded['constant']) || !array_key_exists($intype, self::ANY_MAP) || (ord(self::$encoded[$decoded['start']]) & 0x20)) { + return new Element(substr(self::$encoded, $decoded['start'], $decoded['length'])); + } + $inmap = self::ANY_MAP[$intype]; + if (is_string($inmap)) { + return [$inmap => self::asn1map($decoded, ['type' => $intype] + $mapping, $special)]; + } + break; + case $mapping['type'] == self::TYPE_CHOICE: + foreach ($mapping['children'] as $key => $option) { + switch (true) { + case isset($option['constant']) && $option['constant'] == $decoded['constant']: + case !isset($option['constant']) && $option['type'] == $decoded['type']: + $value = self::asn1map($decoded, $option, $special); + break; + case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE: + $v = self::asn1map($decoded, $option, $special); + if (isset($v)) { + $value = $v; + } + } + if (isset($value)) { + if (isset($special[$key])) { + $value = $special[$key]($value); + } + return [$key => $value]; + } + } + return null; + case isset($mapping['implicit']): + case isset($mapping['explicit']): + case $decoded['type'] == $mapping['type']: + break; + default: + // if $decoded['type'] and $mapping['type'] are both strings, but different types of strings, + // let it through + switch (true) { + case $decoded['type'] < 18: // self::TYPE_NUMERIC_STRING == 18 + case $decoded['type'] > 30: // self::TYPE_BMP_STRING == 30 + case $mapping['type'] < 18: + case $mapping['type'] > 30: + return null; + } + } + + if (isset($mapping['implicit'])) { + $decoded['type'] = $mapping['type']; + } + + switch ($decoded['type']) { + case self::TYPE_SEQUENCE: + $map = []; + + // ignore the min and max + if (isset($mapping['min']) && isset($mapping['max'])) { + $child = $mapping['children']; + foreach ($decoded['content'] as $content) { + if (($map[] = self::asn1map($content, $child, $special)) === null) { + return null; + } + } + + return $map; + } + + $n = count($decoded['content']); + $i = 0; + + foreach ($mapping['children'] as $key => $child) { + $maymatch = $i < $n; // Match only existing input. + if ($maymatch) { + $temp = $decoded['content'][$i]; + + if ($child['type'] != self::TYPE_CHOICE) { + // Get the mapping and input class & constant. + $childClass = $tempClass = self::CLASS_UNIVERSAL; + $constant = null; + if (isset($temp['constant'])) { + $tempClass = $temp['type']; + } + if (isset($child['class'])) { + $childClass = $child['class']; + $constant = $child['cast']; + } elseif (isset($child['constant'])) { + $childClass = self::CLASS_CONTEXT_SPECIFIC; + $constant = $child['constant']; + } + + if (isset($constant) && isset($temp['constant'])) { + // Can only match if constants and class match. + $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; + } else { + // Can only match if no constant expected and type matches or is generic. + $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; + } + } + } + + if ($maymatch) { + // Attempt submapping. + $candidate = self::asn1map($temp, $child, $special); + $maymatch = $candidate !== null; + } + + if ($maymatch) { + // Got the match: use it. + if (isset($special[$key])) { + $candidate = $special[$key]($candidate); + } + $map[$key] = $candidate; + $i++; + } elseif (isset($child['default'])) { + switch ($child['type']) { + case ASN1::TYPE_INTEGER: + $map[$key] = new BigInteger($child['default']); + break; + //case self::TYPE_OBJECT_IDENTIFIER: + // if (!isset(self::$reverseOIDs[$name])) { + // return null; + // } + //case ASN1::TYPE_BOOLEAN: + default: + $map[$key] = $child['default']; + } + } elseif (!isset($child['optional'])) { + return null; // Syntax error. + } + } + + // Fail mapping if all input items have not been consumed. + return $i < $n ? null: $map; + + // the main diff between sets and sequences is the encapsulation of the foreach in another for loop + case self::TYPE_SET: + $map = []; + + // ignore the min and max + if (isset($mapping['min']) && isset($mapping['max'])) { + $child = $mapping['children']; + foreach ($decoded['content'] as $content) { + if (($map[] = self::asn1map($content, $child, $special)) === null) { + return null; + } + } + + return $map; + } + + for ($i = 0; $i < count($decoded['content']); $i++) { + $temp = $decoded['content'][$i]; + $tempClass = self::CLASS_UNIVERSAL; + if (isset($temp['constant'])) { + $tempClass = $temp['type']; + } + + foreach ($mapping['children'] as $key => $child) { + if (isset($map[$key])) { + continue; + } + $maymatch = true; + if ($child['type'] != self::TYPE_CHOICE) { + $childClass = self::CLASS_UNIVERSAL; + $constant = null; + if (isset($child['class'])) { + $childClass = $child['class']; + $constant = $child['cast']; + } elseif (isset($child['constant'])) { + $childClass = self::CLASS_CONTEXT_SPECIFIC; + $constant = $child['constant']; + } + + if (isset($constant) && isset($temp['constant'])) { + // Can only match if constants and class match. + $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; + } else { + // Can only match if no constant expected and type matches or is generic. + $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; + } + } + + if ($maymatch) { + // Attempt submapping. + $candidate = self::asn1map($temp, $child, $special); + $maymatch = $candidate !== null; + } + + if (!$maymatch) { + break; + } + + // Got the match: use it. + if (isset($special[$key])) { + $candidate = $special[$key]($candidate); + } + $map[$key] = $candidate; + break; + } + } + + foreach ($mapping['children'] as $key => $child) { + if (!isset($map[$key])) { + if (isset($child['default'])) { + $map[$key] = $child['default']; + } elseif (!isset($child['optional'])) { + return null; + } + } + } + return $map; + case self::TYPE_OBJECT_IDENTIFIER: + return isset(self::$oids[$decoded['content']]) ? self::$oids[$decoded['content']] : $decoded['content']; + case self::TYPE_UTC_TIME: + case self::TYPE_GENERALIZED_TIME: + // for explicitly tagged optional stuff + if (is_array($decoded['content'])) { + $decoded['content'] = $decoded['content'][0]['content']; + } + // for implicitly tagged optional stuff + // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist + // in the wild that OpenSSL decodes without issue so we'll support them as well + if (!is_object($decoded['content'])) { + $decoded['content'] = self::decodeTime($decoded['content'], $decoded['type']); + } + return $decoded['content'] ? $decoded['content']->format(self::$format) : false; + case self::TYPE_BIT_STRING: + if (isset($mapping['mapping'])) { + $offset = ord($decoded['content'][0]); + $size = (strlen($decoded['content']) - 1) * 8 - $offset; + /* + From X.680-0207.pdf#page=46 (21.7): + + "When a "NamedBitList" is used in defining a bitstring type ASN.1 encoding rules are free to add (or remove) + arbitrarily any trailing 0 bits to (or from) values that are being encoded or decoded. Application designers should + therefore ensure that different semantics are not associated with such values which differ only in the number of trailing + 0 bits." + */ + $bits = count($mapping['mapping']) == $size ? [] : array_fill(0, count($mapping['mapping']) - $size, false); + for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) { + $current = ord($decoded['content'][$i]); + for ($j = $offset; $j < 8; $j++) { + $bits[] = (bool) ($current & (1 << $j)); + } + $offset = 0; + } + $values = []; + $map = array_reverse($mapping['mapping']); + foreach ($map as $i => $value) { + if ($bits[$i]) { + $values[] = $value; + } + } + return $values; + } + case self::TYPE_OCTET_STRING: + return $decoded['content']; + case self::TYPE_NULL: + return ''; + case self::TYPE_BOOLEAN: + return $decoded['content']; + case self::TYPE_NUMERIC_STRING: + case self::TYPE_PRINTABLE_STRING: + case self::TYPE_TELETEX_STRING: + case self::TYPE_VIDEOTEX_STRING: + case self::TYPE_IA5_STRING: + case self::TYPE_GRAPHIC_STRING: + case self::TYPE_VISIBLE_STRING: + case self::TYPE_GENERAL_STRING: + case self::TYPE_UNIVERSAL_STRING: + case self::TYPE_UTF8_STRING: + case self::TYPE_BMP_STRING: + return $decoded['content']; + case self::TYPE_INTEGER: + case self::TYPE_ENUMERATED: + $temp = $decoded['content']; + if (isset($mapping['implicit'])) { + $temp = new BigInteger($decoded['content'], -256); + } + if (isset($mapping['mapping'])) { + $temp = (int) $temp->toString(); + return isset($mapping['mapping'][$temp]) ? + $mapping['mapping'][$temp] : + false; + } + return $temp; + } + } + + /** + * DER-decode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @access public + * @param string $string + * @return int + */ + public static function decodeLength(&$string) + { + $length = ord(Strings::shift($string)); + if ($length & 0x80) { // definite length, long form + $length&= 0x7F; + $temp = Strings::shift($string, $length); + list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); + } + return $length; + } + + /** + * ASN.1 Encode + * + * DER-encodes an ASN.1 semantic mapping ($mapping). Some libraries would probably call this function + * an ASN.1 compiler. + * + * "Special" mappings can be applied via $special. + * + * @param Element|string|array $source + * @param array $mapping + * @param array $special + * @return string + * @access public + */ + public static function encodeDER($source, $mapping, $special = []) + { + self::$location = []; + return self::encode_der($source, $mapping, null, $special); + } + + /** + * ASN.1 Encode (Helper function) + * + * @param Element|string|array $source + * @param array $mapping + * @param int $idx + * @param array $special + * @return string + * @access private + */ + private static function encode_der($source, $mapping, $idx = null, $special = []) + { + if ($source instanceof Element) { + return $source->element; + } + + // do not encode (implicitly optional) fields with value set to default + if (isset($mapping['default']) && $source === $mapping['default']) { + return ''; + } + + if (isset($idx)) { + if (isset($special[$idx])) { + $source = $special[$idx]($source); + } + self::$location[] = $idx; + } + + $tag = $mapping['type']; + + switch ($tag) { + case self::TYPE_SET: // Children order is not important, thus process in sequence. + case self::TYPE_SEQUENCE: + $tag|= 0x20; // set the constructed bit + + // ignore the min and max + if (isset($mapping['min']) && isset($mapping['max'])) { + $value = []; + $child = $mapping['children']; + + foreach ($source as $content) { + $temp = self::encode_der($content, $child, null, $special); + if ($temp === false) { + return false; + } + $value[]= $temp; + } + /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared + as octet strings with the shorter components being padded at their trailing end with 0-octets. + NOTE - The padding octets are for comparison purposes only and do not appear in the encodings." + + -- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ + if ($mapping['type'] == self::TYPE_SET) { + sort($value); + } + $value = implode('', $value); + break; + } + + $value = ''; + foreach ($mapping['children'] as $key => $child) { + if (!array_key_exists($key, $source)) { + if (!isset($child['optional'])) { + return false; + } + continue; + } + + $temp = self::encode_der($source[$key], $child, $key, $special); + if ($temp === false) { + return false; + } + + // An empty child encoding means it has been optimized out. + // Else we should have at least one tag byte. + if ($temp === '') { + continue; + } + + // if isset($child['constant']) is true then isset($child['optional']) should be true as well + if (isset($child['constant'])) { + /* + From X.680-0207.pdf#page=58 (30.6): + + "The tagging construction specifies explicit tagging if any of the following holds: + ... + c) the "Tag Type" alternative is used and the value of "TagDefault" for the module is IMPLICIT TAGS or + AUTOMATIC TAGS, but the type defined by "Type" is an untagged choice type, an untagged open type, or + an untagged "DummyReference" (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 8.3)." + */ + if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); + $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; + } else { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); + $temp = $subtag . substr($temp, 1); + } + } + $value.= $temp; + } + break; + case self::TYPE_CHOICE: + $temp = false; + + foreach ($mapping['children'] as $key => $child) { + if (!isset($source[$key])) { + continue; + } + + $temp = self::encode_der($source[$key], $child, $key, $special); + if ($temp === false) { + return false; + } + + // An empty child encoding means it has been optimized out. + // Else we should have at least one tag byte. + if ($temp === '') { + continue; + } + + $tag = ord($temp[0]); + + // if isset($child['constant']) is true then isset($child['optional']) should be true as well + if (isset($child['constant'])) { + if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); + $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; + } else { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); + $temp = $subtag . substr($temp, 1); + } + } + } + + if (isset($idx)) { + array_pop(self::$location); + } + + if ($temp && isset($mapping['cast'])) { + $temp[0] = chr(($mapping['class'] << 6) | ($tag & 0x20) | $mapping['cast']); + } + + return $temp; + case self::TYPE_INTEGER: + case self::TYPE_ENUMERATED: + if (!isset($mapping['mapping'])) { + if (is_numeric($source)) { + $source = new BigInteger($source); + } + $value = $source->toBytes(true); + } else { + $value = array_search($source, $mapping['mapping']); + if ($value === false) { + return false; + } + $value = new BigInteger($value); + $value = $value->toBytes(true); + } + if (!strlen($value)) { + $value = chr(0); + } + break; + case self::TYPE_UTC_TIME: + case self::TYPE_GENERALIZED_TIME: + $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y'; + $format.= 'mdHis'; + $date = new DateTime($source, new DateTimeZone('GMT')); + $value = $date->format($format) . 'Z'; + break; + case self::TYPE_BIT_STRING: + if (isset($mapping['mapping'])) { + $bits = array_fill(0, count($mapping['mapping']), 0); + $size = 0; + for ($i = 0; $i < count($mapping['mapping']); $i++) { + if (in_array($mapping['mapping'][$i], $source)) { + $bits[$i] = 1; + $size = $i; + } + } + + if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) { + $size = $mapping['min'] - 1; + } + + $offset = 8 - (($size + 1) & 7); + $offset = $offset !== 8 ? $offset : 0; + + $value = chr($offset); + + for ($i = $size + 1; $i < count($mapping['mapping']); $i++) { + unset($bits[$i]); + } + + $bits = implode('', array_pad($bits, $size + $offset + 1, 0)); + $bytes = explode(' ', rtrim(chunk_split($bits, 8, ' '))); + foreach ($bytes as $byte) { + $value.= chr(bindec($byte)); + } + + break; + } + case self::TYPE_OCTET_STRING: + /* The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, + the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven. + + -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */ + $value = $source; + break; + case self::TYPE_OBJECT_IDENTIFIER: + $value = self::encodeOID($source); + break; + case self::TYPE_ANY: + $loc = self::$location; + if (isset($idx)) { + array_pop(self::$location); + } + + switch (true) { + case !isset($source): + return self::encode_der(null, ['type' => self::TYPE_NULL] + $mapping, null, $special); + case is_int($source): + case $source instanceof BigInteger: + return self::encode_der($source, ['type' => self::TYPE_INTEGER] + $mapping, null, $special); + case is_float($source): + return self::encode_der($source, ['type' => self::TYPE_REAL] + $mapping, null, $special); + case is_bool($source): + return self::encode_der($source, ['type' => self::TYPE_BOOLEAN] + $mapping, null, $special); + case is_array($source) && count($source) == 1: + $typename = implode('', array_keys($source)); + $outtype = array_search($typename, self::ANY_MAP, true); + if ($outtype !== false) { + return self::encode_der($source[$typename], ['type' => $outtype] + $mapping, null, $special); + } + } + + $filters = self::$filters; + foreach ($loc as $part) { + if (!isset($filters[$part])) { + $filters = false; + break; + } + $filters = $filters[$part]; + } + if ($filters === false) { + throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); + } + return self::encode_der($source, $filters + $mapping, null, $special); + case self::TYPE_NULL: + $value = ''; + break; + case self::TYPE_NUMERIC_STRING: + case self::TYPE_TELETEX_STRING: + case self::TYPE_PRINTABLE_STRING: + case self::TYPE_UNIVERSAL_STRING: + case self::TYPE_UTF8_STRING: + case self::TYPE_BMP_STRING: + case self::TYPE_IA5_STRING: + case self::TYPE_VISIBLE_STRING: + case self::TYPE_VIDEOTEX_STRING: + case self::TYPE_GRAPHIC_STRING: + case self::TYPE_GENERAL_STRING: + $value = $source; + break; + case self::TYPE_BOOLEAN: + $value = $source ? "\xFF" : "\x00"; + break; + default: + throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location)); + } + + if (isset($idx)) { + array_pop(self::$location); + } + + if (isset($mapping['cast'])) { + if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) { + $value = chr($tag) . self::encodeLength(strlen($value)) . $value; + $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast']; + } else { + $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast']; + } + } + + return chr($tag) . self::encodeLength(strlen($value)) . $value; + } + + /** + * BER-decode the OID + * + * Called by _decode_ber() + * + * @access public + * @param string $content + * @return string + */ + public static function decodeOID($content) + { + static $eighty; + if (!$eighty) { + $eighty = new BigInteger(80); + } + + $oid = array(); + $pos = 0; + $len = strlen($content); + $n = new BigInteger(); + while ($pos < $len) { + $temp = ord($content[$pos++]); + $n = $n->bitwise_leftShift(7); + $n = $n->bitwise_or(new BigInteger($temp & 0x7F)); + if (~$temp & 0x80) { + $oid[] = $n; + $n = new BigInteger(); + } + } + $part1 = array_shift($oid); + $first = floor(ord($content[0]) / 40); + /* + "This packing of the first two object identifier components recognizes that only three values are allocated from the root + node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1." + + -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22 + */ + if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78) + array_unshift($oid, ord($content[0]) % 40); + array_unshift($oid, $first); + } else { + array_unshift($oid, $part1->subtract($eighty)); + array_unshift($oid, 2); + } + + return implode('.', $oid); + } + + /** + * DER-encode the OID + * + * Called by _encode_der() + * + * @access public + * @param string $source + * @return string + */ + public static function encodeOID($source) + { + static $mask, $zero, $forty; + if (!$mask) { + $mask = new BigInteger(0x7F); + $zero = new BigInteger(); + $forty = new BigInteger(40); + } + + if (!preg_match('#(?:\d+\.)+#', $source)) { + $oid = isset(self::$reverseOIDs[$source]) ? self::$reverseOIDs[$source] : false; + } else { + $oid = $source; + } + if ($oid === false) { + throw new \RuntimeException('Invalid OID'); + } + + $parts = explode('.', $oid); + $part1 = array_shift($parts); + $part2 = array_shift($parts); + + $first = new BigInteger($part1); + $first = $first->multiply($forty); + $first = $first->add(new BigInteger($part2)); + + array_unshift($parts, $first->toString()); + + $value = ''; + foreach ($parts as $part) { + if (!$part) { + $temp = "\0"; + } else { + $temp = ''; + $part = new BigInteger($part); + while (!$part->equals($zero)) { + $submask = $part->bitwise_and($mask); + $submask->setPrecision(8); + $temp = (chr(0x80) | $submask->toBytes()) . $temp; + $part = $part->bitwise_rightShift(7); + } + $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F); + } + $value.= $temp; + } + + return $value; + } + + /** + * BER-decode the time + * + * Called by _decode_ber() and in the case of implicit tags asn1map(). + * + * @access private + * @param string $content + * @param int $tag + * @return string + */ + private static function decodeTime($content, $tag) + { + /* UTCTime: + http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 + http://www.obj-sys.com/asn1tutorial/node15.html + + GeneralizedTime: + http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2 + http://www.obj-sys.com/asn1tutorial/node14.html */ + + $format = 'YmdHis'; + + if ($tag == self::TYPE_UTC_TIME) { + // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds + // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the + // browsers parse it phpseclib ought to too + if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) { + $content = $matches[1] . '00' . $matches[2]; + } + $prefix = substr($content, 0, 2) >= 50 ? '19' : '20'; + $content = $prefix . $content; + } elseif (strpos($content, '.') !== false) { + $format.= '.u'; + } + + if ($content[strlen($content) - 1] == 'Z') { + $content = substr($content, 0, -1) . '+0000'; + } + + if (strpos($content, '-') !== false || strpos($content, '+') !== false) { + $format.= 'O'; + } + + // error supression isn't necessary as of PHP 7.0: + // http://php.net/manual/en/migration70.other-changes.php + return @DateTime::createFromFormat($format, $content); + } + + /** + * Set the time format + * + * Sets the time / date format for asn1map(). + * + * @access public + * @param string $format + */ + public static function setTimeFormat($format) + { + self::$format = $format; + } + + /** + * Load OIDs + * + * Load the relevant OIDs for a particular ASN.1 semantic mapping. + * Previously loaded OIDs are retained. + * + * @access public + * @param array $oids + */ + public static function loadOIDs($oids) + { + self::$reverseOIDs+= $oids; + self::$oids = array_flip(self::$reverseOIDs); + } + + /** + * Set filters + * + * See \phpseclib3\File\X509, etc, for an example. + * Previously loaded filters are not retained. + * + * @access public + * @param array $filters + */ + public static function setFilters($filters) + { + self::$filters = $filters; + } + + /** + * String type conversion + * + * This is a lazy conversion, dealing only with character size. + * No real conversion table is used. + * + * @param string $in + * @param int $from + * @param int $to + * @return string + * @access public + */ + public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) + { + // isset(self::STRING_TYPE_SIZE[$from] returns a fatal error on PHP 5.6 + if (!array_key_exists($from, self::STRING_TYPE_SIZE) || !array_key_exists($to, self::STRING_TYPE_SIZE)) { + return false; + } + $insize = self::STRING_TYPE_SIZE[$from]; + $outsize = self::STRING_TYPE_SIZE[$to]; + $inlength = strlen($in); + $out = ''; + + for ($i = 0; $i < $inlength;) { + if ($inlength - $i < $insize) { + return false; + } + + // Get an input character as a 32-bit value. + $c = ord($in[$i++]); + switch (true) { + case $insize == 4: + $c = ($c << 8) | ord($in[$i++]); + $c = ($c << 8) | ord($in[$i++]); + case $insize == 2: + $c = ($c << 8) | ord($in[$i++]); + case $insize == 1: + break; + case ($c & 0x80) == 0x00: + break; + case ($c & 0x40) == 0x00: + return false; + default: + $bit = 6; + do { + if ($bit > 25 || $i >= $inlength || (ord($in[$i]) & 0xC0) != 0x80) { + return false; + } + $c = ($c << 6) | (ord($in[$i++]) & 0x3F); + $bit += 5; + $mask = 1 << $bit; + } while ($c & $bit); + $c &= $mask - 1; + break; + } + + // Convert and append the character to output string. + $v = ''; + switch (true) { + case $outsize == 4: + $v .= chr($c & 0xFF); + $c >>= 8; + $v .= chr($c & 0xFF); + $c >>= 8; + case $outsize == 2: + $v .= chr($c & 0xFF); + $c >>= 8; + case $outsize == 1: + $v .= chr($c & 0xFF); + $c >>= 8; + if ($c) { + return false; + } + break; + case ($c & 0x80000000) != 0: + return false; + case $c >= 0x04000000: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x04000000; + case $c >= 0x00200000: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x00200000; + case $c >= 0x00010000: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x00010000; + case $c >= 0x00000800: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x00000800; + case $c >= 0x00000080: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x000000C0; + default: + $v .= chr($c); + break; + } + $out .= strrev($v); + } + return $out; + } + + /** + * Extract raw BER from Base64 encoding + * + * @access private + * @param string $str + * @return string + */ + public static function extractBER($str) + { + /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them + * above and beyond the ceritificate. + * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: + * + * Bag Attributes + * localKeyID: 01 00 00 00 + * subject=/O=organization/OU=org unit/CN=common name + * issuer=/O=organization/CN=common name + */ + if (strlen($str) > ini_get('pcre.backtrack_limit')) { + $temp = $str; + } else { + $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); + $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $str, 1); + } + // remove new lines + $temp = str_replace(["\r", "\n", ' '], '', $temp); + // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff + $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false; + return $temp != false ? $temp : $str; + } + + /** + * DER-encode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @access public + * @param int $length + * @return string + */ + public static function encodeLength($length) + { + if ($length <= 0x7F) { + return chr($length); + } + + $temp = ltrim(pack('N', $length), chr(0)); + return pack('Ca*', 0x80 | strlen($temp), $temp); + } + + /** + * Returns the OID corresponding to a name + * + * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if + * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version + * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able + * to work from version to version. + * + * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that + * what's being passed to it already is an OID and return that instead. A few examples. + * + * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' + * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' + * getOID('zzz') == 'zzz' + * + * @access public + * @param string $name + * @return string + */ + public static function getOID($name) + { + return isset(self::$reverseOIDs[$name]) ? self::$reverseOIDs[$name] : $name; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php new file mode 100644 index 000000000..ade26ae51 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php @@ -0,0 +1,49 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1; + +/** + * ASN.1 Raw Element + * + * An ASN.1 ANY mapping will return an ASN1\Element object. Use of this object + * will also bypass the normal encoding rules in ASN1::encodeDER() + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +class Element +{ + /** + * Raw element value + * + * @var string + * @access private + */ + public $element; + + /** + * Constructor + * + * @param string $encoded + * @return \phpseclib3\File\ASN1\Element + * @access public + */ + public function __construct($encoded) + { + $this->element = $encoded; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php new file mode 100644 index 000000000..969de8c44 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AccessDescription + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AccessDescription +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'accessMethod' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'accessLocation' => GeneralName::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php new file mode 100644 index 000000000..1b607e7cd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AdministrationDomainName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AdministrationDomainName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 2, + 'children' => [ + 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php new file mode 100644 index 000000000..f9f25334a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AlgorithmIdentifier + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AlgorithmIdentifier +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'algorithm' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php new file mode 100644 index 000000000..3fe2ba0bd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AnotherName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AnotherName +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type-id' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'value' => [ + 'type' => ASN1::TYPE_ANY, + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php new file mode 100644 index 000000000..a80dad31c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Attribute + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Attribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => AttributeType::MAP, + 'value'=> [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => AttributeValue::MAP + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php new file mode 100644 index 000000000..891b80825 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeType + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AttributeType +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php new file mode 100644 index 000000000..ff4faa078 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeTypeAndValue + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AttributeTypeAndValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => AttributeType::MAP, + 'value'=> AttributeValue::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php new file mode 100644 index 000000000..eca03273c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeValue + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AttributeValue +{ + const MAP = ['type' => ASN1::TYPE_ANY]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php new file mode 100644 index 000000000..563a69001 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Attributes + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Attributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => Attribute::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php new file mode 100644 index 000000000..38c714d5a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AuthorityInfoAccessSyntax + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AuthorityInfoAccessSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => AccessDescription::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php new file mode 100644 index 000000000..b6b08ae01 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php @@ -0,0 +1,49 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AuthorityKeyIdentifier + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class AuthorityKeyIdentifier +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyIdentifier' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + KeyIdentifier::MAP, + 'authorityCertIssuer' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP, + 'authorityCertSerialNumber' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + CertificateSerialNumber::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php new file mode 100644 index 000000000..8453e49d9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BaseDistance + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class BaseDistance +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php new file mode 100644 index 000000000..490bc9201 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php @@ -0,0 +1,43 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BasicConstraints + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class BasicConstraints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'cA' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ], + 'pathLenConstraint' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php new file mode 100644 index 000000000..19f31c24a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInDomainDefinedAttribute + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class BuiltInDomainDefinedAttribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => ['type' => ASN1::TYPE_PRINTABLE_STRING], + 'value' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php new file mode 100644 index 000000000..dc412118c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInDomainDefinedAttributes + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class BuiltInDomainDefinedAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-domain-defined-attributes + 'children' => BuiltInDomainDefinedAttribute::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php new file mode 100644 index 000000000..4cbe0b09f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php @@ -0,0 +1,71 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInStandardAttributes + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class BuiltInStandardAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'country-name' => ['optional' => true] + CountryName::MAP, + 'administration-domain-name' => ['optional' => true] + AdministrationDomainName::MAP, + 'network-address' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + NetworkAddress::MAP, + 'terminal-identifier' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + TerminalIdentifier::MAP, + 'private-domain-name' => [ + 'constant' => 2, + 'optional' => true, + 'explicit' => true + ] + PrivateDomainName::MAP, + 'organization-name' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + OrganizationName::MAP, + 'numeric-user-identifier' => [ + 'constant' => 4, + 'optional' => true, + 'implicit' => true + ] + NumericUserIdentifier::MAP, + 'personal-name' => [ + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ] + PersonalName::MAP, + 'organizational-unit-names' => [ + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ] + OrganizationalUnitNames::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php new file mode 100644 index 000000000..78733df9a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CPSuri + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CPSuri +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php new file mode 100644 index 000000000..21ab66236 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLDistributionPoints + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CRLDistributionPoints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => DistributionPoint::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php new file mode 100644 index 000000000..921fdd529 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLNumber + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CRLNumber +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php new file mode 100644 index 000000000..e43e4dd75 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLReason + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CRLReason +{ + const MAP = [ + 'type' => ASN1::TYPE_ENUMERATED, + 'mapping' => [ + 'unspecified', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + // Value 7 is not used. + 8 => 'removeFromCRL', + 'privilegeWithdrawn', + 'aACompromise' + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php new file mode 100644 index 000000000..a4620e7d0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertPolicyId + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CertPolicyId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php new file mode 100644 index 000000000..f8ff4130f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Certificate + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Certificate +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'tbsCertificate' => TBSCertificate::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php new file mode 100644 index 000000000..ba4504afc --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificateIssuer + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CertificateIssuer +{ + const MAP = GeneralNames::MAP; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php new file mode 100644 index 000000000..79a1f3242 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificateList + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CertificateList +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'tbsCertList' => TBSCertList::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php new file mode 100644 index 000000000..e9f9354af --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificatePolicies + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CertificatePolicies +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => PolicyInformation::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php new file mode 100644 index 000000000..83f26d311 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificateSerialNumber + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CertificateSerialNumber +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php new file mode 100644 index 000000000..23587f087 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificationRequest + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CertificationRequest +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'certificationRequestInfo' => CertificationRequestInfo::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php new file mode 100644 index 000000000..1ebff5ff6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificationRequestInfo + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CertificationRequestInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1'] + ], + 'subject' => Name::MAP, + 'subjectPKInfo' => SubjectPublicKeyInfo::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP, + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php new file mode 100644 index 000000000..b73e0ba2d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Characteristic_two + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Characteristic_two +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'm' => ['type' => ASN1::TYPE_INTEGER], // field size 2**m + 'basis' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php new file mode 100644 index 000000000..83b3a2c3f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CountryName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class CountryName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 1, + 'children' => [ + 'x121-dcc-code' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'iso-3166-alpha2-code' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php new file mode 100644 index 000000000..1a574583b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Curve + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Curve +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'a' => FieldElement::MAP, + 'b' => FieldElement::MAP, + 'seed' => [ + 'type' => ASN1::TYPE_BIT_STRING, + 'optional' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php new file mode 100644 index 000000000..8edd9d06b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DHParameter + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DHParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'prime' => ['type' => ASN1::TYPE_INTEGER], + 'base' => ['type' => ASN1::TYPE_INTEGER], + 'privateValueLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php new file mode 100644 index 000000000..c89fd84b4 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAParams + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DSAParams +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'p' => ['type' => ASN1::TYPE_INTEGER], + 'q' => ['type' => ASN1::TYPE_INTEGER], + 'g' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php new file mode 100644 index 000000000..eaec347da --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAPrivateKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DSAPrivateKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => ['type' => ASN1::TYPE_INTEGER], + 'p' => ['type' => ASN1::TYPE_INTEGER], + 'q' => ['type' => ASN1::TYPE_INTEGER], + 'g' => ['type' => ASN1::TYPE_INTEGER], + 'y' => ['type' => ASN1::TYPE_INTEGER], + 'x' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php new file mode 100644 index 000000000..867d80b7d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAPublicKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DSAPublicKey +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php new file mode 100644 index 000000000..828c27989 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DigestInfo + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DigestInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'digestAlgorithm' => AlgorithmIdentifier::MAP, + 'digest' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php new file mode 100644 index 000000000..458acab19 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DirectoryString + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DirectoryString +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'teletexString' => ['type' => ASN1::TYPE_TELETEX_STRING], + 'printableString' => ['type' => ASN1::TYPE_PRINTABLE_STRING], + 'universalString' => ['type' => ASN1::TYPE_UNIVERSAL_STRING], + 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING], + 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php new file mode 100644 index 000000000..6c88b41cb --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DisplayText + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DisplayText +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], + 'visibleString' => ['type' => ASN1::TYPE_VISIBLE_STRING], + 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING], + 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php new file mode 100644 index 000000000..91b3feef5 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php @@ -0,0 +1,49 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DistributionPoint + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DistributionPoint +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'distributionPoint' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + DistributionPointName::MAP, + 'reasons' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + ReasonFlags::MAP, + 'cRLIssuer' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php new file mode 100644 index 000000000..fc157bcae --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php @@ -0,0 +1,44 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DistributionPointName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DistributionPointName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'fullName' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP, + 'nameRelativeToCRLIssuer' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + RelativeDistinguishedName::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php new file mode 100644 index 000000000..1bffe9253 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DssSigValue + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class DssSigValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'r' => ['type' => ASN1::TYPE_INTEGER], + 's' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php new file mode 100644 index 000000000..c27d16f9e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php @@ -0,0 +1,49 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECParameters + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * -- implicitCurve NULL + * -- specifiedCurve SpecifiedECDomain + * } + * -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. + * -- Details for SpecifiedECDomain can be found in [X9.62]. + * -- Any future additions to this CHOICE should be coordinated + * -- with ANSI X9. + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ECParameters +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'namedCurve' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'implicitCurve' => ['type' => ASN1::TYPE_NULL], + 'specifiedCurve' => SpecifiedECDomain::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php new file mode 100644 index 000000000..1a9429a44 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECPoint + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ECPoint +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php new file mode 100644 index 000000000..a0d7a066c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php @@ -0,0 +1,52 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECPrivateKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ECPrivateKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => [1 => 'ecPrivkeyVer1'] + ], + 'privateKey' => ['type' => ASN1::TYPE_OCTET_STRING], + 'parameters' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + ECParameters::MAP, + 'publicKey' => [ + 'type' => ASN1::TYPE_BIT_STRING, + 'constant' => 1, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php new file mode 100644 index 000000000..0c2327b8e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php @@ -0,0 +1,46 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EDIPartyName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class EDIPartyName +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'nameAssigner' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + DirectoryString::MAP, + // partyName is technically required but \phpseclib3\File\ASN1 doesn't currently support non-optional constants and + // setting it to optional gets the job done in any event. + 'partyName' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + DirectoryString::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php new file mode 100644 index 000000000..98dd965aa --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EcdsaSigValue + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class EcdsaSigValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'r' => ['type' => ASN1::TYPE_INTEGER], + 's' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php new file mode 100644 index 000000000..7873579fd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EncryptedData + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class EncryptedData +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php new file mode 100644 index 000000000..5d409eb1a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EncryptedPrivateKeyInfo + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class EncryptedPrivateKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'encryptionAlgorithm' => AlgorithmIdentifier::MAP, + 'encryptedData' => EncryptedData::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php new file mode 100644 index 000000000..c61116df4 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtKeyUsageSyntax + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ExtKeyUsageSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => KeyPurposeId::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php new file mode 100644 index 000000000..392007938 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php @@ -0,0 +1,47 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Extension + * + * A certificate using system MUST reject the certificate if it encounters + * a critical extension it does not recognize; however, a non-critical + * extension may be ignored if it is not recognized. + * + * http://tools.ietf.org/html/rfc5280#section-4.2 + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Extension +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'extnId' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'critical' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ], + 'extnValue' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php new file mode 100644 index 000000000..6455e1898 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php @@ -0,0 +1,46 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtensionAttribute + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ExtensionAttribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'extension-attribute-type' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ], + 'extension-attribute-value' => [ + 'type' => ASN1::TYPE_ANY, + 'constant' => 1, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php new file mode 100644 index 000000000..047bb29a4 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtensionAttributes + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ExtensionAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => 256, // ub-extension-attributes + 'children' => ExtensionAttribute::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php new file mode 100644 index 000000000..e3d528d45 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Extensions + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Extensions +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + // technically, it's MAX, but we'll assume anything < 0 is MAX + 'max' => -1, + // if 'children' isn't an array then 'min' and 'max' must be defined + 'children' => Extension::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php new file mode 100644 index 000000000..6666e2ade --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * FieldElement + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class FieldElement +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php new file mode 100644 index 000000000..13c6ac490 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * FieldID + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class FieldID +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'fieldType' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php new file mode 100644 index 000000000..ba0b9e484 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php @@ -0,0 +1,84 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class GeneralName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'otherName' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + AnotherName::MAP, + 'rfc822Name' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ], + 'dNSName' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ], + 'x400Address' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ORAddress::MAP, + 'directoryName' => [ + 'constant' => 4, + 'optional' => true, + 'explicit' => true + ] + Name::MAP, + 'ediPartyName' => [ + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ] + EDIPartyName::MAP, + 'uniformResourceIdentifier' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ], + 'iPAddress' => [ + 'type' => ASN1::TYPE_OCTET_STRING, + 'constant' => 7, + 'optional' => true, + 'implicit' => true + ], + 'registeredID' => [ + 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, + 'constant' => 8, + 'optional' => true, + 'implicit' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php new file mode 100644 index 000000000..c8a3c89bd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralNames + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class GeneralNames +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => GeneralName::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php new file mode 100644 index 000000000..15d954304 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php @@ -0,0 +1,46 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralSubtree + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class GeneralSubtree +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'base' => GeneralName::MAP, + 'minimum' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'default' => '0' + ] + BaseDistance::MAP, + 'maximum' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + ] + BaseDistance::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php new file mode 100644 index 000000000..3b10265cd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralSubtrees + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class GeneralSubtrees +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => GeneralSubtree::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php new file mode 100644 index 000000000..02f587d13 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * HashAglorithm + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class HashAlgorithm +{ + const MAP = AlgorithmIdentifier::MAP; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php new file mode 100644 index 000000000..7d4959614 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * HoldInstructionCode + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class HoldInstructionCode +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php new file mode 100644 index 000000000..0ae964ce9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * InvalidityDate + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class InvalidityDate +{ + const MAP = ['type' => ASN1::TYPE_GENERALIZED_TIME]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php new file mode 100644 index 000000000..5f71db8f7 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * IssuerAltName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class IssuerAltName +{ + const MAP = GeneralNames::MAP; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php new file mode 100644 index 000000000..f4b35b380 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php @@ -0,0 +1,72 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * IssuingDistributionPoint + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class IssuingDistributionPoint +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'distributionPoint' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + DistributionPointName::MAP, + 'onlyContainsUserCerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 1, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlyContainsCACerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 2, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlySomeReasons' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ReasonFlags::MAP, + 'indirectCRL' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 4, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlyContainsAttributeCerts' =>[ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 5, + 'optional' => true, + 'default' => false, + 'implicit' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php new file mode 100644 index 000000000..eb2939b85 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyIdentifier + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class KeyIdentifier +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php new file mode 100644 index 000000000..7aee54ada --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyPurposeId + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class KeyPurposeId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php new file mode 100644 index 000000000..abf599ed1 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php @@ -0,0 +1,43 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyUsage + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class KeyUsage +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'digitalSignature', + 'nonRepudiation', + 'keyEncipherment', + 'dataEncipherment', + 'keyAgreement', + 'keyCertSign', + 'cRLSign', + 'encipherOnly', + 'decipherOnly' + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php new file mode 100644 index 000000000..5e0e26f07 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * MaskGenAglorithm + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class MaskGenAlgorithm +{ + const MAP = AlgorithmIdentifier::MAP; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php new file mode 100644 index 000000000..a4ba82a0e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Name + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Name +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'rdnSequence' => RDNSequence::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php new file mode 100644 index 000000000..518e68f6b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php @@ -0,0 +1,44 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NameConstraints + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class NameConstraints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'permittedSubtrees' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + GeneralSubtrees::MAP, + 'excludedSubtrees' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + GeneralSubtrees::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php new file mode 100644 index 000000000..a67c0276c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NetworkAddress + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class NetworkAddress +{ + const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php new file mode 100644 index 000000000..cea267733 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NoticeReference + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class NoticeReference +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'organization' => DisplayText::MAP, + 'noticeNumbers' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 200, + 'children' => ['type' => ASN1::TYPE_INTEGER] + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php new file mode 100644 index 000000000..04998393c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NumericUserIdentifier + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class NumericUserIdentifier +{ + const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php new file mode 100644 index 000000000..cde7b3d6c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ORAddress + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ORAddress +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'built-in-standard-attributes' => BuiltInStandardAttributes::MAP, + 'built-in-domain-defined-attributes' => ['optional' => true] + BuiltInDomainDefinedAttributes::MAP, + 'extension-attributes' => ['optional' => true] + ExtensionAttributes::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php new file mode 100644 index 000000000..9a5c16873 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php @@ -0,0 +1,52 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OneAsymmetricKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class OneAsymmetricKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1', 'v2'] + ], + 'privateKeyAlgorithm'=> AlgorithmIdentifier::MAP, + 'privateKey' => PrivateKey::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP, + 'publicKey' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + PublicKey::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php new file mode 100644 index 000000000..250c92774 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OrganizationName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class OrganizationName +{ + const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php new file mode 100644 index 000000000..eb2ac677a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OrganizationalUnitNames + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class OrganizationalUnitNames +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-organizational-units + 'children' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php new file mode 100644 index 000000000..d75fa3f7c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OtherPrimeInfo + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class OtherPrimeInfo +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'prime' => ['type' => ASN1::TYPE_INTEGER], // ri + 'exponent' => ['type' => ASN1::TYPE_INTEGER], // di + 'coefficient' => ['type' => ASN1::TYPE_INTEGER] // ti + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php new file mode 100644 index 000000000..bb833171d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OtherPrimeInfos + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class OtherPrimeInfos +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => OtherPrimeInfo::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php new file mode 100644 index 000000000..bd17291fd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBEParameter + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PBEParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], + 'iterationCount' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php new file mode 100644 index 000000000..1d807db70 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBES2params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PBES2params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyDerivationFunc'=> AlgorithmIdentifier::MAP, + 'encryptionScheme' => AlgorithmIdentifier::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php new file mode 100644 index 000000000..16d37a95b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBKDF2params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PBKDF2params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + // technically, this is a CHOICE in RFC2898 but the other "choice" is, currently, more of a placeholder + // in the RFC + 'salt'=> ['type' => ASN1::TYPE_OCTET_STRING], + 'iterationCount'=> ['type' => ASN1::TYPE_INTEGER], + 'keyLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'prf' => AlgorithmIdentifier::MAP + ['optional' => true] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php new file mode 100644 index 000000000..f375aa16b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBMAC1params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PBMAC1params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyDerivationFunc'=> AlgorithmIdentifier::MAP, + 'messageAuthScheme'=> AlgorithmIdentifier::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php new file mode 100644 index 000000000..11c638bdf --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PKCS9String + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PKCS9String +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], + 'directoryString' => DirectoryString::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php new file mode 100644 index 000000000..493cd2992 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Pentanomial + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Pentanomial +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'k1' => ['type' => ASN1::TYPE_INTEGER], // k1 > 0 + 'k2' => ['type' => ASN1::TYPE_INTEGER], // k2 > k1 + 'k3' => ['type' => ASN1::TYPE_INTEGER], // k3 > h2 + ] + ]; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php new file mode 100644 index 000000000..c9492c9ef --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php @@ -0,0 +1,58 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PersonalName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PersonalName +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'children' => [ + 'surname' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ], + 'given-name' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ], + 'initials' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ], + 'generation-qualifier' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php new file mode 100644 index 000000000..cfda3990c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyInformation + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PolicyInformation +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'policyIdentifier' => CertPolicyId::MAP, + 'policyQualifiers' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 0, + 'max' => -1, + 'optional' => true, + 'children' => PolicyQualifierInfo::MAP + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php new file mode 100644 index 000000000..c1086477a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyMappings + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PolicyMappings +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'issuerDomainPolicy' => CertPolicyId::MAP, + 'subjectDomainPolicy' => CertPolicyId::MAP + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php new file mode 100644 index 000000000..454a9d1a9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyQualifierId + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PolicyQualifierId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php new file mode 100644 index 000000000..a1d7e1727 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyQualifierInfo + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PolicyQualifierInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'policyQualifierId' => PolicyQualifierId::MAP, + 'qualifier' => ['type' => ASN1::TYPE_ANY] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php new file mode 100644 index 000000000..ec8354fa0 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PostalAddress + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PostalAddress +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 1, + 'max' => -1, + 'children' => DirectoryString::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php new file mode 100644 index 000000000..09c8006be --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Prime_p + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Prime_p +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php new file mode 100644 index 000000000..b26c0cbaa --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateDomainName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PrivateDomainName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php new file mode 100644 index 000000000..7670f4add --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PrivateKey +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php new file mode 100644 index 000000000..170f6f276 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKeyInfo + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PrivateKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1'] + ], + 'privateKeyAlgorithm'=> AlgorithmIdentifier::MAP, + 'privateKey' => PrivateKey::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php new file mode 100644 index 000000000..8c396a000 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php @@ -0,0 +1,44 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKeyUsagePeriod + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PrivateKeyUsagePeriod +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'notBefore' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME], + 'notAfter' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php new file mode 100644 index 000000000..b8239aa6a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PublicKey +{ + const MAP = ['type' => ASN1::TYPE_BIT_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php new file mode 100644 index 000000000..ef212812d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKeyAndChallenge + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PublicKeyAndChallenge +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'spki' => SubjectPublicKeyInfo::MAP, + 'challenge' => ['type' => ASN1::TYPE_IA5_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php new file mode 100644 index 000000000..587230bc3 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKeyInfo + * + * this format is not formally defined anywhere but is none-the-less the form you + * get when you do "openssl rsa -in private.pem -outform PEM -pubout" + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class PublicKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'publicKeyAlgorithm'=> AlgorithmIdentifier::MAP, + 'publicKey' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php new file mode 100644 index 000000000..3697f103b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RC2CBCParameter + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class RC2CBCParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'rc2ParametersVersion'=> [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'iv'=> ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php new file mode 100644 index 000000000..848e2c938 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RDNSequence + * + * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, + * but they can be useful at times when either there is no unique attribute in the entry or you + * want to ensure that the entry's DN contains some useful identifying information. + * + * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class RDNSequence +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + // RDNSequence does not define a min or a max, which means it doesn't have one + 'min' => 0, + 'max' => -1, + 'children' => RelativeDistinguishedName::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php new file mode 100644 index 000000000..fbbb0f7cf --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php @@ -0,0 +1,48 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSAPrivateKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class RSAPrivateKey +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['two-prime', 'multi'] + ], + 'modulus' => ['type' => ASN1::TYPE_INTEGER], // n + 'publicExponent' => ['type' => ASN1::TYPE_INTEGER], // e + 'privateExponent' => ['type' => ASN1::TYPE_INTEGER], // d + 'prime1' => ['type' => ASN1::TYPE_INTEGER], // p + 'prime2' => ['type' => ASN1::TYPE_INTEGER], // q + 'exponent1' => ['type' => ASN1::TYPE_INTEGER], // d mod (p-1) + 'exponent2' => ['type' => ASN1::TYPE_INTEGER], // d mod (q-1) + 'coefficient' => ['type' => ASN1::TYPE_INTEGER], // (inverse of q) mod p + 'otherPrimeInfos' => OtherPrimeInfos::MAP + ['optional' => true] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php new file mode 100644 index 000000000..1ea441d03 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSAPublicKey + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class RSAPublicKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'modulus' => ['type' => ASN1::TYPE_INTEGER], + 'publicExponent' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php new file mode 100644 index 000000000..b9ad46b01 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php @@ -0,0 +1,62 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSASSA_PSS_params + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class RSASSA_PSS_params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'hashAlgorithm' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + //'default' => 'sha1Identifier' + ] + HashAlgorithm::MAP, + 'maskGenAlgorithm' => [ + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + //'default' => 'mgf1SHA1Identifier' + ] + MaskGenAlgorithm::MAP, + 'saltLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 2, + 'optional' => true, + 'explicit' => true, + 'default' => 20 + ], + 'trailerField' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 3, + 'optional' => true, + 'explicit' => true, + 'default' => 1 + ] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php new file mode 100644 index 000000000..3cb32c480 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php @@ -0,0 +1,43 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ReasonFlags + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class ReasonFlags +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'unused', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + 'privilegeWithdrawn', + 'aACompromise' + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php new file mode 100644 index 000000000..de9dfaf60 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RelativeDistinguishedName + * + * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, + * but they can be useful at times when either there is no unique attribute in the entry or you + * want to ensure that the entry's DN contains some useful identifying information. + * + * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class RelativeDistinguishedName +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => AttributeTypeAndValue::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php new file mode 100644 index 000000000..b012d9dff --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RevokedCertificate + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class RevokedCertificate +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'userCertificate' => CertificateSerialNumber::MAP, + 'revocationDate' => Time::MAP, + 'crlEntryExtensions' => [ + 'optional' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php new file mode 100644 index 000000000..c3591e2ff --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SignedPublicKeyAndChallenge + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class SignedPublicKeyAndChallenge +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'publicKeyAndChallenge' => PublicKeyAndChallenge::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php new file mode 100644 index 000000000..fb437eab4 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php @@ -0,0 +1,49 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SpecifiedECDomain + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class SpecifiedECDomain +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => [1 => 'ecdpVer1', 'ecdpVer2', 'ecdpVer3'] + ], + 'fieldID' => FieldID::MAP, + 'curve' => Curve::MAP, + 'base' => ECPoint::MAP, + 'order' => ['type' => ASN1::TYPE_INTEGER], + 'cofactor' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'hash' => ['optional' => true] + HashAlgorithm::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php new file mode 100644 index 000000000..02d2d6d49 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectAltName + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class SubjectAltName +{ + const MAP = GeneralNames::MAP; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php new file mode 100644 index 000000000..1eff925a2 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectDirectoryAttributes + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class SubjectDirectoryAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => Attribute::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php new file mode 100644 index 000000000..98ab3ddd6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectInfoAccessSyntax + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class SubjectInfoAccessSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => AccessDescription::MAP + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php new file mode 100644 index 000000000..c367608cd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectPublicKeyInfo + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class SubjectPublicKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'algorithm' => AlgorithmIdentifier::MAP, + 'subjectPublicKey' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php new file mode 100644 index 000000000..49be58eb9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php @@ -0,0 +1,58 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TBSCertList + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class TBSCertList +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1', 'v2', 'v3'], + 'optional' => true, + 'default' => 'v2' + ], + 'signature' => AlgorithmIdentifier::MAP, + 'issuer' => Name::MAP, + 'thisUpdate' => Time::MAP, + 'nextUpdate' => [ + 'optional' => true + ] + Time::MAP, + 'revokedCertificates' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 0, + 'max' => -1, + 'children' => RevokedCertificate::MAP + ], + 'crlExtensions' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php new file mode 100644 index 000000000..dc5fe2aa3 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php @@ -0,0 +1,69 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TBSCertificate + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class TBSCertificate +{ + // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + // technically, default implies optional, but we'll define it as being optional, none-the-less, just to + // reenforce that fact + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'mapping' => ['v1', 'v2', 'v3'], + 'default' => 'v1' + ], + 'serialNumber' => CertificateSerialNumber::MAP, + 'signature' => AlgorithmIdentifier::MAP, + 'issuer' => Name::MAP, + 'validity' => Validity::MAP, + 'subject' => Name::MAP, + 'subjectPublicKeyInfo' => SubjectPublicKeyInfo::MAP, + // implicit means that the T in the TLV structure is to be rewritten, regardless of the type + 'issuerUniqueID' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + UniqueIdentifier::MAP, + 'subjectUniqueID' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + UniqueIdentifier::MAP, + // doesn't use the EXPLICIT keyword but if + // it's not IMPLICIT, it's EXPLICIT + 'extensions' => [ + 'constant' => 3, + 'optional' => true, + 'explicit' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php new file mode 100644 index 000000000..5c6fdddb6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TerminalIdentifier + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class TerminalIdentifier +{ + const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php new file mode 100644 index 000000000..a673c3afc --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Time + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Time +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'utcTime' => ['type' => ASN1::TYPE_UTC_TIME], + 'generalTime' => ['type' => ASN1::TYPE_GENERALIZED_TIME] + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php new file mode 100644 index 000000000..7cd4ba27c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Trinomial + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Trinomial +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php new file mode 100644 index 000000000..64645773d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * UniqueIdentifier + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class UniqueIdentifier +{ + const MAP = ['type' => ASN1::TYPE_BIT_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php new file mode 100644 index 000000000..2a0c86542 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * UserNotice + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class UserNotice +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'noticeRef' => [ + 'optional' => true, + 'implicit' => true + ] + NoticeReference::MAP, + 'explicitText' => [ + 'optional' => true, + 'implicit' => true + ] + DisplayText::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php new file mode 100644 index 000000000..040aa7f59 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Validity + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class Validity +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'notBefore' => Time::MAP, + 'notAfter' => Time::MAP + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php new file mode 100644 index 000000000..1da389a72 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_ca_policy_url + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class netscape_ca_policy_url +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php new file mode 100644 index 000000000..c5845b594 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php @@ -0,0 +1,44 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_cert_type + * + * mapping is from + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class netscape_cert_type +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'SSLClient', + 'SSLServer', + 'Email', + 'ObjectSigning', + 'Reserved', + 'SSLCA', + 'EmailCA', + 'ObjectSigningCA' + ] + ]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php new file mode 100644 index 000000000..8ff14dacc --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php @@ -0,0 +1,30 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_comment + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +abstract class netscape_comment +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php new file mode 100644 index 000000000..eb122b6bb --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php @@ -0,0 +1,4076 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File; + +use DateTimeImmutable; +use DateTimeInterface; +use DateTimeZone; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\File\ASN1\Element; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; +use phpseclib3\Crypt\PublicKeyLoader; + +/** + * Pure-PHP X.509 Parser + * + * @package X509 + * @author Jim Wigginton + * @access public + */ +class X509 +{ + /** + * Flag to only accept signatures signed by certificate authorities + * + * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs + * + * @access public + */ + const VALIDATE_SIGNATURE_BY_CA = 1; + + /** + * Return internal array representation + * + * @access public + * @see \phpseclib3\File\X509::getDN() + */ + const DN_ARRAY = 0; + /** + * Return string + * + * @access public + * @see \phpseclib3\File\X509::getDN() + */ + const DN_STRING = 1; + /** + * Return ASN.1 name string + * + * @access public + * @see \phpseclib3\File\X509::getDN() + */ + const DN_ASN1 = 2; + /** + * Return OpenSSL compatible array + * + * @access public + * @see \phpseclib3\File\X509::getDN() + */ + const DN_OPENSSL = 3; + /** + * Return canonical ASN.1 RDNs string + * + * @access public + * @see \phpseclib3\File\X509::getDN() + */ + const DN_CANON = 4; + /** + * Return name hash for file indexing + * + * @access public + * @see \phpseclib3\File\X509::getDN() + */ + const DN_HASH = 5; + + /** + * Save as PEM + * + * ie. a base64-encoded PEM with a header and a footer + * + * @access public + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + */ + const FORMAT_PEM = 0; + /** + * Save as DER + * + * @access public + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + */ + const FORMAT_DER = 1; + /** + * Save as a SPKAC + * + * @access public + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + * + * Only works on CSRs. Not currently supported. + */ + const FORMAT_SPKAC = 2; + /** + * Auto-detect the format + * + * Used only by the load*() functions + * + * @access public + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + */ + const FORMAT_AUTO_DETECT = 3; + + /** + * Attribute value disposition. + * If disposition is >= 0, this is the index of the target value. + */ + const ATTR_ALL = -1; // All attribute values (array). + const ATTR_APPEND = -2; // Add a value. + const ATTR_REPLACE = -3; // Clear first, then add a value. + + /** + * Distinguished Name + * + * @var array + * @access private + */ + private $dn; + + /** + * Public key + * + * @var string + * @access private + */ + private $publicKey; + + /** + * Private key + * + * @var string + * @access private + */ + private $privateKey; + + /** + * Object identifiers for X.509 certificates + * + * @var array + * @access private + * @link http://en.wikipedia.org/wiki/Object_identifier + */ + private $oids; + + /** + * The certificate authorities + * + * @var array + * @access private + */ + private $CAs; + + /** + * The currently loaded certificate + * + * @var array + * @access private + */ + private $currentCert; + + /** + * The signature subject + * + * There's no guarantee \phpseclib3\File\X509 is going to re-encode an X.509 cert in the same way it was originally + * encoded so we take save the portion of the original cert that the signature would have made for. + * + * @var string + * @access private + */ + private $signatureSubject; + + /** + * Certificate Start Date + * + * @var string + * @access private + */ + private $startDate; + + /** + * Certificate End Date + * + * @var string + * @access private + */ + private $endDate; + + /** + * Serial Number + * + * @var string + * @access private + */ + private $serialNumber; + + /** + * Key Identifier + * + * See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and + * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}. + * + * @var string + * @access private + */ + private $currentKeyIdentifier; + + /** + * CA Flag + * + * @var bool + * @access private + */ + private $caFlag = false; + + /** + * SPKAC Challenge + * + * @var string + * @access private + */ + private $challenge; + + /** + * @var array + * @access private + */ + private $extensionValues = []; + + /** + * OIDs loaded + * + * @var bool + * @access private + */ + private static $oidsLoaded = false; + + /** + * Recursion Limit + * + * @var int + * @access private + */ + private static $recur_limit = 5; + + /** + * URL fetch flag + * + * @var bool + * @access private + */ + private static $disable_url_fetch = false; + + /** + * @var array + * @access private + */ + private static $extensions = []; + + /** + * @var ?array + * @access private + */ + private $ipAddresses = null; + + /** + * @var ?array + * @access private + */ + private $domains = null; + + /** + * Default Constructor. + * + * @return \phpseclib3\File\X509 + * @access public + */ + public function __construct() + { + // Explicitly Tagged Module, 1988 Syntax + // http://tools.ietf.org/html/rfc5280#appendix-A.1 + + if (!self::$oidsLoaded) { + // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 + ASN1::loadOIDs([ + //'id-pkix' => '1.3.6.1.5.5.7', + //'id-pe' => '1.3.6.1.5.5.7.1', + //'id-qt' => '1.3.6.1.5.5.7.2', + //'id-kp' => '1.3.6.1.5.5.7.3', + //'id-ad' => '1.3.6.1.5.5.7.48', + 'id-qt-cps' => '1.3.6.1.5.5.7.2.1', + 'id-qt-unotice' => '1.3.6.1.5.5.7.2.2', + 'id-ad-ocsp' =>'1.3.6.1.5.5.7.48.1', + 'id-ad-caIssuers' => '1.3.6.1.5.5.7.48.2', + 'id-ad-timeStamping' => '1.3.6.1.5.5.7.48.3', + 'id-ad-caRepository' => '1.3.6.1.5.5.7.48.5', + //'id-at' => '2.5.4', + 'id-at-name' => '2.5.4.41', + 'id-at-surname' => '2.5.4.4', + 'id-at-givenName' => '2.5.4.42', + 'id-at-initials' => '2.5.4.43', + 'id-at-generationQualifier' => '2.5.4.44', + 'id-at-commonName' => '2.5.4.3', + 'id-at-localityName' => '2.5.4.7', + 'id-at-stateOrProvinceName' => '2.5.4.8', + 'id-at-organizationName' => '2.5.4.10', + 'id-at-organizationalUnitName' => '2.5.4.11', + 'id-at-title' => '2.5.4.12', + 'id-at-description' => '2.5.4.13', + 'id-at-dnQualifier' => '2.5.4.46', + 'id-at-countryName' => '2.5.4.6', + 'id-at-serialNumber' => '2.5.4.5', + 'id-at-pseudonym' => '2.5.4.65', + 'id-at-postalCode' => '2.5.4.17', + 'id-at-streetAddress' => '2.5.4.9', + 'id-at-uniqueIdentifier' => '2.5.4.45', + 'id-at-role' => '2.5.4.72', + 'id-at-postalAddress' => '2.5.4.16', + + //'id-domainComponent' => '0.9.2342.19200300.100.1.25', + //'pkcs-9' => '1.2.840.113549.1.9', + 'pkcs-9-at-emailAddress' => '1.2.840.113549.1.9.1', + //'id-ce' => '2.5.29', + 'id-ce-authorityKeyIdentifier' => '2.5.29.35', + 'id-ce-subjectKeyIdentifier' => '2.5.29.14', + 'id-ce-keyUsage' => '2.5.29.15', + 'id-ce-privateKeyUsagePeriod' => '2.5.29.16', + 'id-ce-certificatePolicies' => '2.5.29.32', + //'anyPolicy' => '2.5.29.32.0', + + 'id-ce-policyMappings' => '2.5.29.33', + + 'id-ce-subjectAltName' => '2.5.29.17', + 'id-ce-issuerAltName' => '2.5.29.18', + 'id-ce-subjectDirectoryAttributes' => '2.5.29.9', + 'id-ce-basicConstraints' => '2.5.29.19', + 'id-ce-nameConstraints' => '2.5.29.30', + 'id-ce-policyConstraints' => '2.5.29.36', + 'id-ce-cRLDistributionPoints' => '2.5.29.31', + 'id-ce-extKeyUsage' => '2.5.29.37', + //'anyExtendedKeyUsage' => '2.5.29.37.0', + 'id-kp-serverAuth' => '1.3.6.1.5.5.7.3.1', + 'id-kp-clientAuth' => '1.3.6.1.5.5.7.3.2', + 'id-kp-codeSigning' => '1.3.6.1.5.5.7.3.3', + 'id-kp-emailProtection' => '1.3.6.1.5.5.7.3.4', + 'id-kp-timeStamping' => '1.3.6.1.5.5.7.3.8', + 'id-kp-OCSPSigning' => '1.3.6.1.5.5.7.3.9', + 'id-ce-inhibitAnyPolicy' => '2.5.29.54', + 'id-ce-freshestCRL' => '2.5.29.46', + 'id-pe-authorityInfoAccess' => '1.3.6.1.5.5.7.1.1', + 'id-pe-subjectInfoAccess' => '1.3.6.1.5.5.7.1.11', + 'id-ce-cRLNumber' => '2.5.29.20', + 'id-ce-issuingDistributionPoint' => '2.5.29.28', + 'id-ce-deltaCRLIndicator' => '2.5.29.27', + 'id-ce-cRLReasons' => '2.5.29.21', + 'id-ce-certificateIssuer' => '2.5.29.29', + 'id-ce-holdInstructionCode' => '2.5.29.23', + //'holdInstruction' => '1.2.840.10040.2', + 'id-holdinstruction-none' => '1.2.840.10040.2.1', + 'id-holdinstruction-callissuer' => '1.2.840.10040.2.2', + 'id-holdinstruction-reject' => '1.2.840.10040.2.3', + 'id-ce-invalidityDate' => '2.5.29.24', + + 'rsaEncryption' => '1.2.840.113549.1.1.1', + 'md2WithRSAEncryption' => '1.2.840.113549.1.1.2', + 'md5WithRSAEncryption' => '1.2.840.113549.1.1.4', + 'sha1WithRSAEncryption' => '1.2.840.113549.1.1.5', + 'sha224WithRSAEncryption' => '1.2.840.113549.1.1.14', + 'sha256WithRSAEncryption' => '1.2.840.113549.1.1.11', + 'sha384WithRSAEncryption' => '1.2.840.113549.1.1.12', + 'sha512WithRSAEncryption' => '1.2.840.113549.1.1.13', + + 'id-ecPublicKey' => '1.2.840.10045.2.1', + 'ecdsa-with-SHA1' => '1.2.840.10045.4.1', + // from https://tools.ietf.org/html/rfc5758#section-3.2 + 'ecdsa-with-SHA224' => '1.2.840.10045.4.3.1', + 'ecdsa-with-SHA256' => '1.2.840.10045.4.3.2', + 'ecdsa-with-SHA384' => '1.2.840.10045.4.3.3', + 'ecdsa-with-SHA512' => '1.2.840.10045.4.3.4', + + 'id-dsa' => '1.2.840.10040.4.1', + 'id-dsa-with-sha1' => '1.2.840.10040.4.3', + // from https://tools.ietf.org/html/rfc5758#section-3.1 + 'id-dsa-with-sha224' => '2.16.840.1.101.3.4.3.1', + 'id-dsa-with-sha256' => '2.16.840.1.101.3.4.3.2', + + // from https://tools.ietf.org/html/rfc8410: + 'id-Ed25519' => '1.3.101.112', + 'id-Ed448' => '1.3.101.113', + + 'id-RSASSA-PSS' => '1.2.840.113549.1.1.10', + + //'id-sha224' => '2.16.840.1.101.3.4.2.4', + //'id-sha256' => '2.16.840.1.101.3.4.2.1', + //'id-sha384' => '2.16.840.1.101.3.4.2.2', + //'id-sha512' => '2.16.840.1.101.3.4.2.3', + //'id-GostR3411-94-with-GostR3410-94' => '1.2.643.2.2.4', + //'id-GostR3411-94-with-GostR3410-2001' => '1.2.643.2.2.3', + //'id-GostR3410-2001' => '1.2.643.2.2.20', + //'id-GostR3410-94' => '1.2.643.2.2.19', + // Netscape Object Identifiers from "Netscape Certificate Extensions" + 'netscape' => '2.16.840.1.113730', + 'netscape-cert-extension' => '2.16.840.1.113730.1', + 'netscape-cert-type' => '2.16.840.1.113730.1.1', + 'netscape-comment' => '2.16.840.1.113730.1.13', + 'netscape-ca-policy-url' => '2.16.840.1.113730.1.8', + // the following are X.509 extensions not supported by phpseclib + 'id-pe-logotype' => '1.3.6.1.5.5.7.1.12', + 'entrustVersInfo' => '1.2.840.113533.7.65.0', + 'verisignPrivate' => '2.16.840.1.113733.1.6.9', + // for Certificate Signing Requests + // see http://tools.ietf.org/html/rfc2985 + 'pkcs-9-at-unstructuredName' => '1.2.840.113549.1.9.2', // PKCS #9 unstructured name + 'pkcs-9-at-challengePassword' => '1.2.840.113549.1.9.7', // Challenge password for certificate revocations + 'pkcs-9-at-extensionRequest' => '1.2.840.113549.1.9.14' // Certificate extension request + ]); + } + } + + /** + * Load X.509 certificate + * + * Returns an associative array describing the X.509 cert or a false if the cert failed to load + * + * @param string $cert + * @param int $mode + * @access public + * @return mixed + */ + public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) + { + if (is_array($cert) && isset($cert['tbsCertificate'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + $this->dn = $cert['tbsCertificate']['subject']; + if (!isset($this->dn)) { + return false; + } + $this->currentCert = $cert; + + $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); + $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; + + unset($this->signatureSubject); + + return $cert; + } + + if ($mode != self::FORMAT_DER) { + $newcert = ASN1::extractBER($cert); + if ($mode == self::FORMAT_PEM && $cert == $newcert) { + return false; + } + $cert = $newcert; + } + + if ($cert === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($cert); + + if (!empty($decoded)) { + $x509 = ASN1::asn1map($decoded[0], Maps\Certificate::MAP); + } + if (!isset($x509) || $x509 === false) { + $this->currentCert = false; + return false; + } + + $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + if ($this->isSubArrayValid($x509, 'tbsCertificate/extensions')) { + $this->mapInExtensions($x509, 'tbsCertificate/extensions'); + } + $this->mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence'); + $this->mapInDNs($x509, 'tbsCertificate/subject/rdnSequence'); + + $key = $x509['tbsCertificate']['subjectPublicKeyInfo']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + + $this->currentCert = $x509; + $this->dn = $x509['tbsCertificate']['subject']; + + $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); + $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; + + return $x509; + } + + /** + * Save X.509 certificate + * + * @param array $cert + * @param int $format optional + * @access public + * @return string + */ + public function saveX509($cert, $format = self::FORMAT_PEM) + { + if (!is_array($cert) || !isset($cert['tbsCertificate'])) { + return false; + } + + switch (true) { + // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()" + case !($algorithm = $this->subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): + case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): + break; + default: + $cert['tbsCertificate']['subjectPublicKeyInfo'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])) + ); + } + + if ($algorithm == 'rsaEncryption') { + $cert['signatureAlgorithm']['parameters'] = null; + $cert['tbsCertificate']['signature']['parameters'] = null; + } + + $filters = []; + $type_utf8_string = ['type' => ASN1::TYPE_UTF8_STRING]; + $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string; + $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string; + $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string; + $filters['tbsCertificate']['subject']['rdnSequence']['value'] = $type_utf8_string; + $filters['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = $type_utf8_string; + $filters['signatureAlgorithm']['parameters'] = $type_utf8_string; + $filters['authorityCertIssuer']['directoryName']['rdnSequence']['value'] = $type_utf8_string; + //$filters['policyQualifiers']['qualifier'] = $type_utf8_string; + $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string; + $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string; + + foreach (self::$extensions as $extension) { + $filters['tbsCertificate']['extensions'][] = $extension; + } + + /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib3\File\ASN1::TYPE_IA5_STRING. + \phpseclib3\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random + characters. + */ + $filters['policyQualifiers']['qualifier'] + = ['type' => ASN1::TYPE_IA5_STRING]; + + ASN1::setFilters($filters); + + $this->mapOutExtensions($cert, 'tbsCertificate/extensions'); + $this->mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence'); + $this->mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence'); + + $cert = ASN1::encodeDER($cert, Maps\Certificate::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $cert; + // case self::FORMAT_PEM: + default: + return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Base64::encode($cert), 64) . '-----END CERTIFICATE-----'; + } + } + + /** + * Map extension values from octet string to extension-specific internal + * format. + * + * @param array $root (by reference) + * @param string $path + * @access private + */ + private function mapInExtensions(&$root, $path) + { + $extensions = &$this->subArrayUnchecked($root, $path); + + if ($extensions) { + for ($i = 0; $i < count($extensions); $i++) { + $id = $extensions[$i]['extnId']; + $value = &$extensions[$i]['extnValue']; + $decoded = ASN1::decodeBER($value); + /* [extnValue] contains the DER encoding of an ASN.1 value + corresponding to the extension type identified by extnID */ + $map = $this->getMapping($id); + if (!is_bool($map)) { + $decoder = $id == 'id-ce-nameConstraints' ? + [static::class, 'decodeNameConstraintIP'] : + [static::class, 'decodeIP']; + $mapped = ASN1::asn1map($decoded[0], $map, ['iPAddress' => $decoder]); + $value = $mapped === false ? $decoded[0] : $mapped; + + if ($id == 'id-ce-certificatePolicies') { + for ($j = 0; $j < count($value); $j++) { + if (!isset($value[$j]['policyQualifiers'])) { + continue; + } + for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { + $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; + $map = $this->getMapping($subid); + $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; + if ($map !== false) { + $decoded = ASN1::decodeBER($subvalue); + $mapped = ASN1::asn1map($decoded[0], $map); + $subvalue = $mapped === false ? $decoded[0] : $mapped; + } + } + } + } + } + } + } + } + + /** + * Map extension values from extension-specific internal format to + * octet string. + * + * @param array $root (by reference) + * @param string $path + * @access private + */ + private function mapOutExtensions(&$root, $path) + { + foreach ($this->extensionValues as $id => $value) { + $root['tbsCertificate']['extensions'][] = [ + 'extnId' => $id, + 'extnValue' => $value, + ]; + } + + $extensions = &$this->subArray($root, $path); + + if (is_array($extensions)) { + $size = count($extensions); + for ($i = 0; $i < $size; $i++) { + if ($extensions[$i] instanceof Element) { + continue; + } + + $id = $extensions[$i]['extnId']; + $value = &$extensions[$i]['extnValue']; + + switch ($id) { + case 'id-ce-certificatePolicies': + for ($j = 0; $j < count($value); $j++) { + if (!isset($value[$j]['policyQualifiers'])) { + continue; + } + for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { + $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; + $map = $this->getMapping($subid); + $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; + if ($map !== false) { + // by default \phpseclib3\File\ASN1 will try to render qualifier as a \phpseclib3\File\ASN1::TYPE_IA5_STRING since it's + // actual type is \phpseclib3\File\ASN1::TYPE_ANY + $subvalue = new Element(ASN1::encodeDER($subvalue, $map)); + } + } + } + break; + case 'id-ce-authorityKeyIdentifier': // use 00 as the serial number instead of an empty string + if (isset($value['authorityCertSerialNumber'])) { + if ($value['authorityCertSerialNumber']->toBytes() == '') { + $temp = chr((ASN1::CLASS_CONTEXT_SPECIFIC << 6) | 2) . "\1\0"; + $value['authorityCertSerialNumber'] = new Element($temp); + } + } + } + + /* [extnValue] contains the DER encoding of an ASN.1 value + corresponding to the extension type identified by extnID */ + $map = $this->getMapping($id); + if (is_bool($map)) { + if (!$map) { + //user_error($id . ' is not a currently supported extension'); + unset($extensions[$i]); + } + } else { + $value = ASN1::encodeDER($value, $map, ['iPAddress' => [static::class, 'encodeIP']]); + } + } + } + } + + /** + * Map attribute values from ANY type to attribute-specific internal + * format. + * + * @param array $root (by reference) + * @param string $path + * @access private + */ + private function mapInAttributes(&$root, $path) + { + $attributes = &$this->subArray($root, $path); + + if (is_array($attributes)) { + for ($i = 0; $i < count($attributes); $i++) { + $id = $attributes[$i]['type']; + /* $value contains the DER encoding of an ASN.1 value + corresponding to the attribute type identified by type */ + $map = $this->getMapping($id); + if (is_array($attributes[$i]['value'])) { + $values = &$attributes[$i]['value']; + for ($j = 0; $j < count($values); $j++) { + $value = ASN1::encodeDER($values[$j], Maps\AttributeValue::MAP); + $decoded = ASN1::decodeBER($value); + if (!is_bool($map)) { + $mapped = ASN1::asn1map($decoded[0], $map); + if ($mapped !== false) { + $values[$j] = $mapped; + } + if ($id == 'pkcs-9-at-extensionRequest' && $this->isSubArrayValid($values, $j)) { + $this->mapInExtensions($values, $j); + } + } elseif ($map) { + $values[$j] = $value; + } + } + } + } + } + } + + /** + * Map attribute values from attribute-specific internal format to + * ANY type. + * + * @param array $root (by reference) + * @param string $path + * @access private + */ + private function mapOutAttributes(&$root, $path) + { + $attributes = &$this->subArray($root, $path); + + if (is_array($attributes)) { + $size = count($attributes); + for ($i = 0; $i < $size; $i++) { + /* [value] contains the DER encoding of an ASN.1 value + corresponding to the attribute type identified by type */ + $id = $attributes[$i]['type']; + $map = $this->getMapping($id); + if ($map === false) { + //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); + unset($attributes[$i]); + } elseif (is_array($attributes[$i]['value'])) { + $values = &$attributes[$i]['value']; + for ($j = 0; $j < count($values); $j++) { + switch ($id) { + case 'pkcs-9-at-extensionRequest': + $this->mapOutExtensions($values, $j); + break; + } + + if (!is_bool($map)) { + $temp = ASN1::encodeDER($values[$j], $map); + $decoded = ASN1::decodeBER($temp); + $values[$j] = ASN1::asn1map($decoded[0], Maps\AttributeValue::MAP); + } + } + } + } + } + } + + /** + * Map DN values from ANY type to DN-specific internal + * format. + * + * @param array $root (by reference) + * @param string $path + * @access private + */ + private function mapInDNs(&$root, $path) + { + $dns = &$this->subArray($root, $path); + + if (is_array($dns)) { + for ($i = 0; $i < count($dns); $i++) { + for ($j = 0; $j < count($dns[$i]); $j++) { + $type = $dns[$i][$j]['type']; + $value = &$dns[$i][$j]['value']; + if (is_object($value) && $value instanceof Element) { + $map = $this->getMapping($type); + if (!is_bool($map)) { + $decoded = ASN1::decodeBER($value); + $value = ASN1::asn1map($decoded[0], $map); + } + } + } + } + } + } + + /** + * Map DN values from DN-specific internal format to + * ANY type. + * + * @param array $root (by reference) + * @param string $path + * @access private + */ + private function mapOutDNs(&$root, $path) + { + $dns = &$this->subArray($root, $path); + + if (is_array($dns)) { + $size = count($dns); + for ($i = 0; $i < $size; $i++) { + for ($j = 0; $j < count($dns[$i]); $j++) { + $type = $dns[$i][$j]['type']; + $value = &$dns[$i][$j]['value']; + if (is_object($value) && $value instanceof Element) { + continue; + } + + $map = $this->getMapping($type); + if (!is_bool($map)) { + $value = new Element(ASN1::encodeDER($value, $map)); + } + } + } + } + } + + /** + * Associate an extension ID to an extension mapping + * + * @param string $extnId + * @access private + * @return mixed + */ + private function getMapping($extnId) + { + if (!is_string($extnId)) { // eg. if it's a \phpseclib3\File\ASN1\Element object + return true; + } + + if (isset(self::$extensions[$extnId])) { + return self::$extensions[$extnId]; + } + + switch ($extnId) { + case 'id-ce-keyUsage': + return Maps\KeyUsage::MAP; + case 'id-ce-basicConstraints': + return Maps\BasicConstraints::MAP; + case 'id-ce-subjectKeyIdentifier': + return Maps\KeyIdentifier::MAP; + case 'id-ce-cRLDistributionPoints': + return Maps\CRLDistributionPoints::MAP; + case 'id-ce-authorityKeyIdentifier': + return Maps\AuthorityKeyIdentifier::MAP; + case 'id-ce-certificatePolicies': + return Maps\CertificatePolicies::MAP; + case 'id-ce-extKeyUsage': + return Maps\ExtKeyUsageSyntax::MAP; + case 'id-pe-authorityInfoAccess': + return Maps\AuthorityInfoAccessSyntax::MAP; + case 'id-ce-subjectAltName': + return Maps\SubjectAltName::MAP; + case 'id-ce-subjectDirectoryAttributes': + return Maps\SubjectDirectoryAttributes::MAP; + case 'id-ce-privateKeyUsagePeriod': + return Maps\PrivateKeyUsagePeriod::MAP; + case 'id-ce-issuerAltName': + return Maps\IssuerAltName::MAP; + case 'id-ce-policyMappings': + return Maps\PolicyMappings::MAP; + case 'id-ce-nameConstraints': + return Maps\NameConstraints::MAP; + + case 'netscape-cert-type': + return Maps\netscape_cert_type::MAP; + case 'netscape-comment': + return Maps\netscape_comment::MAP; + case 'netscape-ca-policy-url': + return Maps\netscape_ca_policy_url::MAP; + + // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets + // back around to asn1map() and we don't want it decoded again. + //case 'id-qt-cps': + // return Maps\CPSuri::MAP; + case 'id-qt-unotice': + return Maps\UserNotice::MAP; + + // the following OIDs are unsupported but we don't want them to give notices when calling saveX509(). + case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt + case 'entrustVersInfo': + // http://support.microsoft.com/kb/287547 + case '1.3.6.1.4.1.311.20.2': // szOID_ENROLL_CERTTYPE_EXTENSION + case '1.3.6.1.4.1.311.21.1': // szOID_CERTSRV_CA_VERSION + // "SET Secure Electronic Transaction Specification" + // http://www.maithean.com/docs/set_bk3.pdf + case '2.23.42.7.0': // id-set-hashedRootKey + // "Certificate Transparency" + // https://tools.ietf.org/html/rfc6962 + case '1.3.6.1.4.1.11129.2.4.2': + // "Qualified Certificate statements" + // https://tools.ietf.org/html/rfc3739#section-3.2.6 + case '1.3.6.1.5.5.7.1.3': + return true; + + // CSR attributes + case 'pkcs-9-at-unstructuredName': + return Maps\PKCS9String::MAP; + case 'pkcs-9-at-challengePassword': + return Maps\DirectoryString::MAP; + case 'pkcs-9-at-extensionRequest': + return Maps\Extensions::MAP; + + // CRL extensions. + case 'id-ce-cRLNumber': + return Maps\CRLNumber::MAP; + case 'id-ce-deltaCRLIndicator': + return Maps\CRLNumber::MAP; + case 'id-ce-issuingDistributionPoint': + return Maps\IssuingDistributionPoint::MAP; + case 'id-ce-freshestCRL': + return Maps\CRLDistributionPoints::MAP; + case 'id-ce-cRLReasons': + return Maps\CRLReason::MAP; + case 'id-ce-invalidityDate': + return Maps\InvalidityDate::MAP; + case 'id-ce-certificateIssuer': + return Maps\CertificateIssuer::MAP; + case 'id-ce-holdInstructionCode': + return Maps\HoldInstructionCode::MAP; + case 'id-at-postalAddress': + return Maps\PostalAddress::MAP; + } + + return false; + } + + /** + * Load an X.509 certificate as a certificate authority + * + * @param string $cert + * @access public + * @return bool + */ + public function loadCA($cert) + { + $olddn = $this->dn; + $oldcert = $this->currentCert; + $oldsigsubj = $this->signatureSubject; + $oldkeyid = $this->currentKeyIdentifier; + + $cert = $this->loadX509($cert); + if (!$cert) { + $this->dn = $olddn; + $this->currentCert = $oldcert; + $this->signatureSubject = $oldsigsubj; + $this->currentKeyIdentifier = $oldkeyid; + + return false; + } + + /* From RFC5280 "PKIX Certificate and CRL Profile": + + If the keyUsage extension is present, then the subject public key + MUST NOT be used to verify signatures on certificates or CRLs unless + the corresponding keyCertSign or cRLSign bit is set. */ + //$keyUsage = $this->getExtension('id-ce-keyUsage'); + //if ($keyUsage && !in_array('keyCertSign', $keyUsage)) { + // return false; + //} + + /* From RFC5280 "PKIX Certificate and CRL Profile": + + The cA boolean indicates whether the certified public key may be used + to verify certificate signatures. If the cA boolean is not asserted, + then the keyCertSign bit in the key usage extension MUST NOT be + asserted. If the basic constraints extension is not present in a + version 3 certificate, or the extension is present but the cA boolean + is not asserted, then the certified public key MUST NOT be used to + verify certificate signatures. */ + //$basicConstraints = $this->getExtension('id-ce-basicConstraints'); + //if (!$basicConstraints || !$basicConstraints['cA']) { + // return false; + //} + + $this->CAs[] = $cert; + + $this->dn = $olddn; + $this->currentCert = $oldcert; + $this->signatureSubject = $oldsigsubj; + + return true; + } + + /** + * Validate an X.509 certificate against a URL + * + * From RFC2818 "HTTP over TLS": + * + * Matching is performed using the matching rules specified by + * [RFC2459]. If more than one identity of a given type is present in + * the certificate (e.g., more than one dNSName name, a match in any one + * of the set is considered acceptable.) Names may contain the wildcard + * character * which is considered to match any single domain name + * component or component fragment. E.g., *.a.com matches foo.a.com but + * not bar.foo.a.com. f*.com matches foo.com but not bar.com. + * + * @param string $url + * @access public + * @return bool + */ + public function validateURL($url) + { + if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { + return false; + } + + $components = parse_url($url); + if (!isset($components['host'])) { + return false; + } + + if ($names = $this->getExtension('id-ce-subjectAltName')) { + foreach ($names as $name) { + foreach ($name as $key => $value) { + $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value); + switch ($key) { + case 'dNSName': + /* From RFC2818 "HTTP over TLS": + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. */ + if (preg_match('#^' . $value . '$#', $components['host'])) { + return true; + } + break; + case 'iPAddress': + /* From RFC2818 "HTTP over TLS": + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. */ + if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) { + return true; + } + } + } + } + return false; + } + + if ($value = $this->getDNProp('id-at-commonName')) { + $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value[0]); + return preg_match('#^' . $value . '$#', $components['host']); + } + + return false; + } + + /** + * Validate a date + * + * If $date isn't defined it is assumed to be the current date. + * + * @param DateTimeInterface|string $date optional + * @access public + * @return boolean + */ + public function validateDate($date = null) + { + if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { + return false; + } + + if (!isset($date)) { + $date = new DateTimeImmutable(null, new DateTimeZone(@date_default_timezone_get())); + } + + $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore']; + $notBefore = isset($notBefore['generalTime']) ? $notBefore['generalTime'] : $notBefore['utcTime']; + + $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter']; + $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime']; + + if (is_string($date)) { + $date = new DateTimeImmutable($date, new DateTimeZone(@date_default_timezone_get())); + } + + $notBefore = new DateTimeImmutable($notBefore, new DateTimeZone(@date_default_timezone_get())); + $notAfter = new DateTimeImmutable($notAfter, new DateTimeZone(@date_default_timezone_get())); + + return $date >= $notBefore && $date<= $notAfter; + } + + /** + * Fetches a URL + * + * @param string $url + * @access private + * @return bool|string + */ + private static function fetchURL($url) + { + if (self::$disable_url_fetch) { + return false; + } + + $parts = parse_url($url); + $data = ''; + switch ($parts['scheme']) { + case 'http': + $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80); + if (!$fsock) { + return false; + } + fputs($fsock, "GET $parts[path] HTTP/1.0\r\n"); + fputs($fsock, "Host: $parts[host]\r\n\r\n"); + $line = fgets($fsock, 1024); + if (strlen($line) < 3) { + return false; + } + preg_match('#HTTP/1.\d (\d{3})#', $line, $temp); + if ($temp[1] != '200') { + return false; + } + + // skip the rest of the headers in the http response + while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") { + } + + while (!feof($fsock)) { + $temp = fread($fsock, 1024); + if ($temp === false) { + return false; + } + $data.= $temp; + } + + break; + //case 'ftp': + //case 'ldap': + //default: + } + + return $data; + } + + /** + * Validates an intermediate cert as identified via authority info access extension + * + * See https://tools.ietf.org/html/rfc4325 for more info + * + * @param bool $caonly + * @param int $count + * @access private + * @return bool + */ + private function testForIntermediate($caonly, $count) + { + $opts = $this->getExtension('id-pe-authorityInfoAccess'); + if (!is_array($opts)) { + return false; + } + foreach ($opts as $opt) { + if ($opt['accessMethod'] == 'id-ad-caIssuers') { + // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP, + // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325 + // discusses + if (isset($opt['accessLocation']['uniformResourceIdentifier'])) { + $url = $opt['accessLocation']['uniformResourceIdentifier']; + break; + } + } + } + + if (!isset($url)) { + return false; + } + + $cert = static::fetchURL($url); + if (!is_string($cert)) { + return false; + } + + $parent = new static(); + $parent->CAs = $this->CAs; + /* + "Conforming applications that support HTTP or FTP for accessing + certificates MUST be able to accept .cer files and SHOULD be able + to accept .p7c files." -- https://tools.ietf.org/html/rfc4325 + + A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797" + + These are currently unsupported + */ + if (!is_array($parent->loadX509($cert))) { + return false; + } + + if (!$parent->validateSignatureCountable($caonly, ++$count)) { + return false; + } + + $this->CAs[] = $parent->currentCert; + //$this->loadCA($cert); + + return true; + } + + /** + * Validate a signature + * + * Works on X.509 certs, CSR's and CRL's. + * Returns true if the signature is verified, false if it is not correct or null on error + * + * By default returns false for self-signed certs. Call validateSignature(false) to make this support + * self-signed. + * + * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}. + * + * @param bool $caonly optional + * @access public + * @return mixed + */ + public function validateSignature($caonly = true) + { + return $this->validateSignatureCountable($caonly, 0); + } + + /** + * Validate a signature + * + * Performs said validation whilst keeping track of how many times validation method is called + * + * @param bool $caonly + * @param int $count + * @access private + * @return mixed + */ + private function validateSignatureCountable($caonly, $count) + { + if (!is_array($this->currentCert) || !isset($this->signatureSubject)) { + return null; + } + + if ($count == self::$recur_limit) { + return false; + } + + /* TODO: + "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")." + -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6 + + implement pathLenConstraint in the id-ce-basicConstraints extension */ + + switch (true) { + case isset($this->currentCert['tbsCertificate']): + // self-signed cert + switch (true) { + case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']: + case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(self::DN_STRING) === $this->getDN(self::DN_STRING): + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier'); + switch (true) { + case !is_array($authorityKey): + case !$subjectKeyID: + case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + $signingCert = $this->currentCert; // working cert + } + } + + if (!empty($this->CAs)) { + for ($i = 0; $i < count($this->CAs); $i++) { + // even if the cert is a self-signed one we still want to see if it's a CA; + // if not, we'll conditionally return an error + $ca = $this->CAs[$i]; + switch (true) { + case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']: + case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); + switch (true) { + case !is_array($authorityKey): + case !$subjectKeyID: + case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { + break 2; // serial mismatch - check other ca + } + $signingCert = $ca; // working cert + break 3; + } + } + } + if (count($this->CAs) == $i && $caonly) { + return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + } + } elseif (!isset($signingCert) || $caonly) { + return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + } + return $this->validateSignatureHelper( + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + case isset($this->currentCert['certificationRequestInfo']): + return $this->validateSignatureHelper( + $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'], + $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + case isset($this->currentCert['publicKeyAndChallenge']): + return $this->validateSignatureHelper( + $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'], + $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + case isset($this->currentCert['tbsCertList']): + if (!empty($this->CAs)) { + for ($i = 0; $i < count($this->CAs); $i++) { + $ca = $this->CAs[$i]; + switch (true) { + case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']: + case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); + switch (true) { + case !is_array($authorityKey): + case !$subjectKeyID: + case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { + break 2; // serial mismatch - check other ca + } + $signingCert = $ca; // working cert + break 3; + } + } + } + } + if (!isset($signingCert)) { + return false; + } + return $this->validateSignatureHelper( + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + default: + return false; + } + } + + /** + * Validates a signature + * + * Returns true if the signature is verified and false if it is not correct. + * If the algorithms are unsupposed an exception is thrown. + * + * @param string $publicKeyAlgorithm + * @param string $publicKey + * @param string $signatureAlgorithm + * @param string $signature + * @param string $signatureSubject + * @access private + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @return bool + */ + private function validateSignatureHelper($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) + { + switch ($publicKeyAlgorithm) { + case 'id-RSASSA-PSS': + $key = RSA::loadFormat('PSS', $publicKey); + break; + case 'rsaEncryption': + $key = RSA::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'md2WithRSAEncryption': + case 'md5WithRSAEncryption': + case 'sha1WithRSAEncryption': + case 'sha224WithRSAEncryption': + case 'sha256WithRSAEncryption': + case 'sha384WithRSAEncryption': + case 'sha512WithRSAEncryption': + $key = $key + ->withHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)) + ->withPadding(RSA::SIGNATURE_PKCS1); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + case 'id-Ed25519': + case 'id-Ed448': + $key = EC::loadFormat('PKCS8', $publicKey); + break; + case 'id-ecPublicKey': + $key = EC::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'ecdsa-with-SHA1': + case 'ecdsa-with-SHA224': + case 'ecdsa-with-SHA256': + case 'ecdsa-with-SHA384': + case 'ecdsa-with-SHA512': + $key = $key + ->withHash(preg_replace('#^ecdsa-with-#', '', strtolower($signatureAlgorithm))); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + case 'id-dsa': + $key = DSA::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'id-dsa-with-sha1': + case 'id-dsa-with-sha224': + case 'id-dsa-with-sha256': + $key = $key + ->withHash(preg_replace('#^id-dsa-with-#', '', strtolower($signatureAlgorithm))); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + default: + throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); + } + + return $key->verify($signatureSubject, $signature); + } + + /** + * Sets the recursion limit + * + * When validating a signature it may be necessary to download intermediate certs from URI's. + * An intermediate cert that linked to itself would result in an infinite loop so to prevent + * that we set a recursion limit. A negative number means that there is no recursion limit. + * + * @param int $count + * @access public + */ + public static function setRecurLimit($count) + { + self::$recur_limit = $count; + } + + /** + * Prevents URIs from being automatically retrieved + * + * @access public + */ + public static function disableURLFetch() + { + self::$disable_url_fetch = true; + } + + /** + * Allows URIs to be automatically retrieved + * + * @access public + */ + public static function enableURLFetch() + { + self::$disable_url_fetch = false; + } + + /** + * Decodes an IP address + * + * Takes in a base64 encoded "blob" and returns a human readable IP address + * + * @param string $ip + * @access private + * @return string + */ + public static function decodeIP($ip) + { + return inet_ntop($ip); + } + + /** + * Decodes an IP address in a name constraints extension + * + * Takes in a base64 encoded "blob" and returns a human readable IP address / mask + * + * @param string $ip + * @access private + * @return array + */ + public static function decodeNameConstraintIP($ip) + { + $size = strlen($ip) >> 1; + $mask = substr($ip, $size); + $ip = substr($ip, 0, $size); + return [inet_ntop($ip), inet_ntop($mask)]; + } + + /** + * Encodes an IP address + * + * Takes a human readable IP address into a base64-encoded "blob" + * + * @param string|array $ip + * @access private + * @return string + */ + public static function encodeIP($ip) + { + return is_string($ip) ? + inet_pton($ip) : + inet_pton($ip[0]) . inet_pton($ip[1]); + } + + /** + * "Normalizes" a Distinguished Name property + * + * @param string $propName + * @access private + * @return mixed + */ + private function translateDNProp($propName) + { + switch (strtolower($propName)) { + case 'id-at-countryname': + case 'countryname': + case 'c': + return 'id-at-countryName'; + case 'id-at-organizationname': + case 'organizationname': + case 'o': + return 'id-at-organizationName'; + case 'id-at-dnqualifier': + case 'dnqualifier': + return 'id-at-dnQualifier'; + case 'id-at-commonname': + case 'commonname': + case 'cn': + return 'id-at-commonName'; + case 'id-at-stateorprovincename': + case 'stateorprovincename': + case 'state': + case 'province': + case 'provincename': + case 'st': + return 'id-at-stateOrProvinceName'; + case 'id-at-localityname': + case 'localityname': + case 'l': + return 'id-at-localityName'; + case 'id-emailaddress': + case 'emailaddress': + return 'pkcs-9-at-emailAddress'; + case 'id-at-serialnumber': + case 'serialnumber': + return 'id-at-serialNumber'; + case 'id-at-postalcode': + case 'postalcode': + return 'id-at-postalCode'; + case 'id-at-streetaddress': + case 'streetaddress': + return 'id-at-streetAddress'; + case 'id-at-name': + case 'name': + return 'id-at-name'; + case 'id-at-givenname': + case 'givenname': + return 'id-at-givenName'; + case 'id-at-surname': + case 'surname': + case 'sn': + return 'id-at-surname'; + case 'id-at-initials': + case 'initials': + return 'id-at-initials'; + case 'id-at-generationqualifier': + case 'generationqualifier': + return 'id-at-generationQualifier'; + case 'id-at-organizationalunitname': + case 'organizationalunitname': + case 'ou': + return 'id-at-organizationalUnitName'; + case 'id-at-pseudonym': + case 'pseudonym': + return 'id-at-pseudonym'; + case 'id-at-title': + case 'title': + return 'id-at-title'; + case 'id-at-description': + case 'description': + return 'id-at-description'; + case 'id-at-role': + case 'role': + return 'id-at-role'; + case 'id-at-uniqueidentifier': + case 'uniqueidentifier': + case 'x500uniqueidentifier': + return 'id-at-uniqueIdentifier'; + case 'postaladdress': + case 'id-at-postaladdress': + return 'id-at-postalAddress'; + default: + return false; + } + } + + /** + * Set a Distinguished Name property + * + * @param string $propName + * @param mixed $propValue + * @param string $type optional + * @access public + * @return bool + */ + public function setDNProp($propName, $propValue, $type = 'utf8String') + { + if (empty($this->dn)) { + $this->dn = ['rdnSequence' => []]; + } + + if (($propName = $this->translateDNProp($propName)) === false) { + return false; + } + + foreach ((array) $propValue as $v) { + if (!is_array($v) && isset($type)) { + $v = [$type => $v]; + } + $this->dn['rdnSequence'][] = [ + [ + 'type' => $propName, + 'value'=> $v + ] + ]; + } + + return true; + } + + /** + * Remove Distinguished Name properties + * + * @param string $propName + * @access public + */ + public function removeDNProp($propName) + { + if (empty($this->dn)) { + return; + } + + if (($propName = $this->translateDNProp($propName)) === false) { + return; + } + + $dn = &$this->dn['rdnSequence']; + $size = count($dn); + for ($i = 0; $i < $size; $i++) { + if ($dn[$i][0]['type'] == $propName) { + unset($dn[$i]); + } + } + + $dn = array_values($dn); + // fix for https://bugs.php.net/75433 affecting PHP 7.2 + if (!isset($dn[0])) { + $dn = array_splice($dn, 0, 0); + } + } + + /** + * Get Distinguished Name properties + * + * @param string $propName + * @param array $dn optional + * @param bool $withType optional + * @return mixed + * @access public + */ + public function getDNProp($propName, $dn = null, $withType = false) + { + if (!isset($dn)) { + $dn = $this->dn; + } + + if (empty($dn)) { + return false; + } + + if (($propName = $this->translateDNProp($propName)) === false) { + return false; + } + + $filters = []; + $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); + $dn = $dn['rdnSequence']; + $result = []; + for ($i = 0; $i < count($dn); $i++) { + if ($dn[$i][0]['type'] == $propName) { + $v = $dn[$i][0]['value']; + if (!$withType) { + if (is_array($v)) { + foreach ($v as $type => $s) { + $type = array_search($type, ASN1::ANY_MAP); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $s = ASN1::convert($s, $type); + if ($s !== false) { + $v = $s; + break; + } + } + } + if (is_array($v)) { + $v = array_pop($v); // Always strip data type. + } + } elseif (is_object($v) && $v instanceof Element) { + $map = $this->getMapping($propName); + if (!is_bool($map)) { + $decoded = ASN1::decodeBER($v); + $v = ASN1::asn1map($decoded[0], $map); + } + } + } + $result[] = $v; + } + } + + return $result; + } + + /** + * Set a Distinguished Name + * + * @param mixed $dn + * @param bool $merge optional + * @param string $type optional + * @access public + * @return bool + */ + public function setDN($dn, $merge = false, $type = 'utf8String') + { + if (!$merge) { + $this->dn = null; + } + + if (is_array($dn)) { + if (isset($dn['rdnSequence'])) { + $this->dn = $dn; // No merge here. + return true; + } + + // handles stuff generated by openssl_x509_parse() + foreach ($dn as $prop => $value) { + if (!$this->setDNProp($prop, $value, $type)) { + return false; + } + } + return true; + } + + // handles everything else + $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE); + for ($i = 1; $i < count($results); $i+=2) { + $prop = trim($results[$i], ', =/'); + $value = $results[$i + 1]; + if (!$this->setDNProp($prop, $value, $type)) { + return false; + } + } + + return true; + } + + /** + * Get the Distinguished Name for a certificates subject + * + * @param mixed $format optional + * @param array $dn optional + * @access public + * @return array|bool + */ + public function getDN($format = self::DN_ARRAY, $dn = null) + { + if (!isset($dn)) { + $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; + } + + switch ((int) $format) { + case self::DN_ARRAY: + return $dn; + case self::DN_ASN1: + $filters = []; + $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); + return ASN1::encodeDER($dn, Maps\Name::MAP); + case self::DN_CANON: + // No SEQUENCE around RDNs and all string values normalized as + // trimmed lowercase UTF-8 with all spacing as one blank. + // constructed RDNs will not be canonicalized + $filters = []; + $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $result = ''; + $this->mapOutDNs($dn, 'rdnSequence'); + foreach ($dn['rdnSequence'] as $rdn) { + foreach ($rdn as $i => $attr) { + $attr = &$rdn[$i]; + if (is_array($attr['value'])) { + foreach ($attr['value'] as $type => $v) { + $type = array_search($type, ASN1::ANY_MAP, true); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $v = ASN1::convert($v, $type); + if ($v !== false) { + $v = preg_replace('/\s+/', ' ', $v); + $attr['value'] = strtolower(trim($v)); + break; + } + } + } + } + } + $result .= ASN1::encodeDER($rdn, Maps\RelativeDistinguishedName::MAP); + } + return $result; + case self::DN_HASH: + $dn = $this->getDN(self::DN_CANON, $dn); + $hash = new Hash('sha1'); + $hash = $hash->hash($dn); + extract(unpack('Vhash', $hash)); + return strtolower(Hex::encode(pack('N', $hash))); + } + + // Default is to return a string. + $start = true; + $output = ''; + + $result = []; + $filters = []; + $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); + + foreach ($dn['rdnSequence'] as $field) { + $prop = $field[0]['type']; + $value = $field[0]['value']; + + $delim = ', '; + switch ($prop) { + case 'id-at-countryName': + $desc = 'C'; + break; + case 'id-at-stateOrProvinceName': + $desc = 'ST'; + break; + case 'id-at-organizationName': + $desc = 'O'; + break; + case 'id-at-organizationalUnitName': + $desc = 'OU'; + break; + case 'id-at-commonName': + $desc = 'CN'; + break; + case 'id-at-localityName': + $desc = 'L'; + break; + case 'id-at-surname': + $desc = 'SN'; + break; + case 'id-at-uniqueIdentifier': + $delim = '/'; + $desc = 'x500UniqueIdentifier'; + break; + case 'id-at-postalAddress': + $delim = '/'; + $desc = 'postalAddress'; + break; + default: + $delim = '/'; + $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop); + } + + if (!$start) { + $output.= $delim; + } + if (is_array($value)) { + foreach ($value as $type => $v) { + $type = array_search($type, ASN1::ANY_MAP, true); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $v = ASN1::convert($v, $type); + if ($v !== false) { + $value = $v; + break; + } + } + } + if (is_array($value)) { + $value = array_pop($value); // Always strip data type. + } + } elseif (is_object($value) && $value instanceof Element) { + $callback = function($x) { return '\x' . bin2hex($x[0]); }; + $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element)); + } + $output.= $desc . '=' . $value; + $result[$desc] = isset($result[$desc]) ? + array_merge((array) $result[$desc], [$value]) : + $value; + $start = false; + } + + return $format == self::DN_OPENSSL ? $result : $output; + } + + /** + * Get the Distinguished Name for a certificate/crl issuer + * + * @param int $format optional + * @access public + * @return mixed + */ + public function getIssuerDN($format = self::DN_ARRAY) + { + switch (true) { + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDN($format, $this->currentCert['tbsCertificate']['issuer']); + case isset($this->currentCert['tbsCertList']): + return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']); + } + + return false; + } + + /** + * Get the Distinguished Name for a certificate/csr subject + * Alias of getDN() + * + * @param int $format optional + * @access public + * @return mixed + */ + public function getSubjectDN($format = self::DN_ARRAY) + { + switch (true) { + case !empty($this->dn): + return $this->getDN($format); + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDN($format, $this->currentCert['tbsCertificate']['subject']); + case isset($this->currentCert['certificationRequestInfo']): + return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']); + } + + return false; + } + + /** + * Get an individual Distinguished Name property for a certificate/crl issuer + * + * @param string $propName + * @param bool $withType optional + * @access public + * @return mixed + */ + public function getIssuerDNProp($propName, $withType = false) + { + switch (true) { + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['issuer'], $withType); + case isset($this->currentCert['tbsCertList']): + return $this->getDNProp($propName, $this->currentCert['tbsCertList']['issuer'], $withType); + } + + return false; + } + + /** + * Get an individual Distinguished Name property for a certificate/csr subject + * + * @param string $propName + * @param bool $withType optional + * @access public + * @return mixed + */ + public function getSubjectDNProp($propName, $withType = false) + { + switch (true) { + case !empty($this->dn): + return $this->getDNProp($propName, null, $withType); + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['subject'], $withType); + case isset($this->currentCert['certificationRequestInfo']): + return $this->getDNProp($propName, $this->currentCert['certificationRequestInfo']['subject'], $withType); + } + + return false; + } + + /** + * Get the certificate chain for the current cert + * + * @access public + * @return mixed + */ + public function getChain() + { + $chain = [$this->currentCert]; + + if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { + return false; + } + if (empty($this->CAs)) { + return $chain; + } + while (true) { + $currentCert = $chain[count($chain) - 1]; + for ($i = 0; $i < count($this->CAs); $i++) { + $ca = $this->CAs[$i]; + if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) { + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); + switch (true) { + case !is_array($authorityKey): + case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + if ($currentCert === $ca) { + break 3; + } + $chain[] = $ca; + break 2; + } + } + } + if ($i == count($this->CAs)) { + break; + } + } + foreach ($chain as $key => $value) { + $chain[$key] = new X509(); + $chain[$key]->loadX509($value); + } + return $chain; + } + + /** + * Set public key + * + * Key needs to be a \phpseclib3\Crypt\RSA object + * + * @param PublicKey $key + * @access public + * @return bool + */ + public function setPublicKey(PublicKey $key) + { + $this->publicKey = $key; + } + + /** + * Set private key + * + * Key needs to be a \phpseclib3\Crypt\RSA object + * + * @param PrivateKey $key + * @access public + */ + public function setPrivateKey(PrivateKey $key) + { + $this->privateKey = $key; + } + + /** + * Set challenge + * + * Used for SPKAC CSR's + * + * @param string $challenge + * @access public + */ + public function setChallenge($challenge) + { + $this->challenge = $challenge; + } + + /** + * Gets the public key + * + * Returns a \phpseclib3\Crypt\RSA object or a false. + * + * @access public + * @return mixed + */ + public function getPublicKey() + { + if (isset($this->publicKey)) { + return $this->publicKey; + } + + if (isset($this->currentCert) && is_array($this->currentCert)) { + $paths = [ + 'tbsCertificate/subjectPublicKeyInfo', + 'certificationRequestInfo/subjectPKInfo', + 'publicKeyAndChallenge/spki' + ]; + foreach ($paths as $path) { + $keyinfo = $this->subArray($this->currentCert, $path); + if (!empty($keyinfo)) { + break; + } + } + } + if (empty($keyinfo)) { + return false; + } + + $key = $keyinfo['subjectPublicKey']; + + switch ($keyinfo['algorithm']['algorithm']) { + case 'rsaEncryption': + return RSA::loadFormat('PKCS8', $key); + case 'id-ecPublicKey': + case 'id-Ed25519': + case 'id-Ed448': + return EC::loadFormat('PKCS8', $key); + case 'id-dsa': + return DSA::loadFormat('PKCS8', $key); + } + + return false; + } + + /** + * Load a Certificate Signing Request + * + * @param string $csr + * @param int $mode + * @return mixed + * @access public + */ + public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) + { + if (is_array($csr) && isset($csr['certificationRequestInfo'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + unset($this->signatureSubject); + $this->dn = $csr['certificationRequestInfo']['subject']; + if (!isset($this->dn)) { + return false; + } + + $this->currentCert = $csr; + return $csr; + } + + // see http://tools.ietf.org/html/rfc2986 + + if ($mode != self::FORMAT_DER) { + $newcsr = ASN1::extractBER($csr); + if ($mode == self::FORMAT_PEM && $csr == $newcsr) { + return false; + } + $csr = $newcsr; + } + $orig = $csr; + + if ($csr === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($csr); + + if (empty($decoded)) { + $this->currentCert = false; + return false; + } + + $csr = ASN1::asn1map($decoded[0], Maps\CertificationRequest::MAP); + if (!isset($csr) || $csr === false) { + $this->currentCert = false; + return false; + } + + $this->mapInAttributes($csr, 'certificationRequestInfo/attributes'); + $this->mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); + + $this->dn = $csr['certificationRequestInfo']['subject']; + + $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + $key = $csr['certificationRequestInfo']['subjectPKInfo']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + + $this->currentKeyIdentifier = null; + $this->currentCert = $csr; + + $this->publicKey = null; + $this->publicKey = $this->getPublicKey(); + + return $csr; + } + + /** + * Save CSR request + * + * @param array $csr + * @param int $format optional + * @access public + * @return string + */ + public function saveCSR($csr, $format = self::FORMAT_PEM) + { + if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) { + return false; + } + + switch (true) { + case !($algorithm = $this->subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): + case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): + break; + default: + $csr['certificationRequestInfo']['subjectPKInfo'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])) + ); + } + + $filters = []; + $filters['certificationRequestInfo']['subject']['rdnSequence']['value'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + + ASN1::setFilters($filters); + + $this->mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); + $this->mapOutAttributes($csr, 'certificationRequestInfo/attributes'); + $csr = ASN1::encodeDER($csr, Maps\CertificationRequest::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $csr; + // case self::FORMAT_PEM: + default: + return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Base64::encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; + } + } + + /** + * Load a SPKAC CSR + * + * SPKAC's are produced by the HTML5 keygen element: + * + * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen + * + * @param string $spkac + * @access public + * @return mixed + */ + public function loadSPKAC($spkac) + { + if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + unset($this->signatureSubject); + $this->currentCert = $spkac; + return $spkac; + } + + // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge + + // OpenSSL produces SPKAC's that are preceded by the string SPKAC= + $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false; + if ($temp != false) { + $spkac = $temp; + } + $orig = $spkac; + + if ($spkac === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($spkac); + + if (empty($decoded)) { + $this->currentCert = false; + return false; + } + + $spkac = ASN1::asn1map($decoded[0], Maps\SignedPublicKeyAndChallenge::MAP); + + if (!isset($spkac) || $spkac === false) { + $this->currentCert = false; + return false; + } + + $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + $key = $spkac['publicKeyAndChallenge']['spki']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + + $this->currentKeyIdentifier = null; + $this->currentCert = $spkac; + + $this->publicKey = null; + $this->publicKey = $this->getPublicKey(); + + return $spkac; + } + + /** + * Save a SPKAC CSR request + * + * @param array $spkac + * @param int $format optional + * @access public + * @return string + */ + public function saveSPKAC($spkac, $format = self::FORMAT_PEM) + { + if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) { + return false; + } + + $algorithm = $this->subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); + switch (true) { + case !$algorithm: + case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']): + break; + default: + $spkac['publicKeyAndChallenge']['spki'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])) + ); + } + + $spkac = ASN1::encodeDER($spkac, Maps\SignedPublicKeyAndChallenge::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $spkac; + // case self::FORMAT_PEM: + default: + // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much + // no other SPKAC decoders phpseclib will use that same format + return 'SPKAC=' . Base64::encode($spkac); + } + } + + /** + * Load a Certificate Revocation List + * + * @param string $crl + * @param int $mode + * @return mixed + * @access public + */ + public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) + { + if (is_array($crl) && isset($crl['tbsCertList'])) { + $this->currentCert = $crl; + unset($this->signatureSubject); + return $crl; + } + + if ($mode != self::FORMAT_DER) { + $newcrl = ASN1::extractBER($crl); + if ($mode == self::FORMAT_PEM && $crl == $newcrl) { + return false; + } + $crl = $newcrl; + } + $orig = $crl; + + if ($crl === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($crl); + + if (empty($decoded)) { + $this->currentCert = false; + return false; + } + + $crl = ASN1::asn1map($decoded[0], Maps\CertificateList::MAP); + if (!isset($crl) || $crl === false) { + $this->currentCert = false; + return false; + } + + $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + $this->mapInDNs($crl, 'tbsCertList/issuer/rdnSequence'); + if ($this->isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { + $this->mapInExtensions($crl, 'tbsCertList/crlExtensions'); + } + if ($this->isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { + $rclist_ref = &$this->subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); + if ($rclist_ref) { + $rclist = $crl['tbsCertList']['revokedCertificates']; + foreach ($rclist as $i => $extension) { + if ($this->isSubArrayValid($rclist, "$i/crlEntryExtensions")) { + $this->mapInExtensions($rclist_ref, "$i/crlEntryExtensions"); + } + } + } + } + + $this->currentKeyIdentifier = null; + $this->currentCert = $crl; + + return $crl; + } + + /** + * Save Certificate Revocation List. + * + * @param array $crl + * @param int $format optional + * @access public + * @return string + */ + public function saveCRL($crl, $format = self::FORMAT_PEM) + { + if (!is_array($crl) || !isset($crl['tbsCertList'])) { + return false; + } + + $filters = []; + $filters['tbsCertList']['issuer']['rdnSequence']['value'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + $filters['tbsCertList']['signature']['parameters'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + $filters['signatureAlgorithm']['parameters'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + + if (empty($crl['tbsCertList']['signature']['parameters'])) { + $filters['tbsCertList']['signature']['parameters'] + = ['type' => ASN1::TYPE_NULL]; + } + + if (empty($crl['signatureAlgorithm']['parameters'])) { + $filters['signatureAlgorithm']['parameters'] + = ['type' => ASN1::TYPE_NULL]; + } + + ASN1::setFilters($filters); + + $this->mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence'); + $this->mapOutExtensions($crl, 'tbsCertList/crlExtensions'); + $rclist = &$this->subArray($crl, 'tbsCertList/revokedCertificates'); + if (is_array($rclist)) { + foreach ($rclist as $i => $extension) { + $this->mapOutExtensions($rclist, "$i/crlEntryExtensions"); + } + } + + $crl = ASN1::encodeDER($crl, Maps\CertificateList::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $crl; + // case self::FORMAT_PEM: + default: + return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Base64::encode($crl), 64) . '-----END X509 CRL-----'; + } + } + + /** + * Helper function to build a time field according to RFC 3280 section + * - 4.1.2.5 Validity + * - 5.1.2.4 This Update + * - 5.1.2.5 Next Update + * - 5.1.2.6 Revoked Certificates + * by choosing utcTime iff year of date given is before 2050 and generalTime else. + * + * @param string $date in format date('D, d M Y H:i:s O') + * @access private + * @return array|Element + */ + private function timeField($date) + { + if ($date instanceof Element) { + return $date; + } + $dateObj = new DateTimeImmutable($date, new DateTimeZone('GMT')); + $year = $dateObj->format('Y'); // the same way ASN1.php parses this + if ($year < 2050) { + return ['utcTime' => $date]; + } else { + return ['generalTime' => $date]; + } + } + + /** + * Sign an X.509 certificate + * + * $issuer's private key needs to be loaded. + * $subject can be either an existing X.509 cert (if you want to resign it), + * a CSR or something with the DN and public key explicitly set. + * + * @param \phpseclib3\File\X509 $issuer + * @param \phpseclib3\File\X509 $subject + * @access public + * @return mixed + */ + public function sign($issuer, $subject) + { + if (!is_object($issuer->privateKey) || empty($issuer->dn)) { + return false; + } + + if (isset($subject->publicKey) && !($subjectPublicKey = $subject->formatSubjectPublicKey())) { + return false; + } + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); + if ($signatureAlgorithm != 'id-RSASSA-PSS') { + $signatureAlgorithm = ['algorithm' => $signatureAlgorithm]; + } else { + $r = PSS::load($issuer->privateKey->toString('PSS')); + $signatureAlgorithm = [ + 'algorithm' => 'id-RSASSA-PSS', + 'parameters' => PSS::savePSSParams($r) + ]; + } + + if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) { + $this->currentCert = $subject->currentCert; + $this->currentCert['tbsCertificate']['signature'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; + + + if (!empty($this->startDate)) { + $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->timeField($this->startDate); + } + if (!empty($this->endDate)) { + $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->timeField($this->endDate); + } + if (!empty($this->serialNumber)) { + $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber; + } + if (!empty($subject->dn)) { + $this->currentCert['tbsCertificate']['subject'] = $subject->dn; + } + if (!empty($subject->publicKey)) { + $this->currentCert['tbsCertificate']['subjectPublicKeyInfo'] = $subjectPublicKey; + } + $this->removeExtension('id-ce-authorityKeyIdentifier'); + if (isset($subject->domains)) { + $this->removeExtension('id-ce-subjectAltName'); + } + } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) { + return false; + } else { + if (!isset($subject->publicKey)) { + return false; + } + + $startDate = new DateTimeImmutable('now', new DateTimeZone(@date_default_timezone_get())); + $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O'); + + $endDate = new DateTimeImmutable('+1 year', new DateTimeZone(@date_default_timezone_get())); + $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O'); + + /* "The serial number MUST be a positive integer" + "Conforming CAs MUST NOT use serialNumber values longer than 20 octets." + -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2 + + for the integer to be positive the leading bit needs to be 0 hence the + application of a bitmap + */ + $serialNumber = !empty($this->serialNumber) ? + $this->serialNumber : + new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256); + + $this->currentCert = [ + 'tbsCertificate' => + [ + 'version' => 'v3', + 'serialNumber' => $serialNumber, // $this->setSerialNumber() + 'signature' => $signatureAlgorithm, + 'issuer' => false, // this is going to be overwritten later + 'validity' => [ + 'notBefore' => $this->timeField($startDate), // $this->setStartDate() + 'notAfter' => $this->timeField($endDate) // $this->setEndDate() + ], + 'subject' => $subject->dn, + 'subjectPublicKeyInfo' => $subjectPublicKey + ], + 'signatureAlgorithm' => $signatureAlgorithm, + 'signature' => false // this is going to be overwritten later + ]; + + // Copy extensions from CSR. + $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0); + + if (!empty($csrexts)) { + $this->currentCert['tbsCertificate']['extensions'] = $csrexts; + } + } + + $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn; + + if (isset($issuer->currentKeyIdentifier)) { + $this->setExtension('id-ce-authorityKeyIdentifier', [ + //'authorityCertIssuer' => array( + // array( + // 'directoryName' => $issuer->dn + // ) + //), + 'keyIdentifier' => $issuer->currentKeyIdentifier + ]); + //$extensions = &$this->currentCert['tbsCertificate']['extensions']; + //if (isset($issuer->serialNumber)) { + // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; + //} + //unset($extensions); + } + + if (isset($subject->currentKeyIdentifier)) { + $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier); + } + + $altName = []; + + if (isset($subject->domains) && count($subject->domains)) { + $altName = array_map(['\phpseclib3\File\X509', 'dnsName'], $subject->domains); + } + + if (isset($subject->ipAddresses) && count($subject->ipAddresses)) { + // should an IP address appear as the CN if no domain name is specified? idk + //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1); + $ipAddresses = []; + foreach ($subject->ipAddresses as $ipAddress) { + $encoded = $subject->ipAddress($ipAddress); + if ($encoded !== false) { + $ipAddresses[] = $encoded; + } + } + if (count($ipAddresses)) { + $altName = array_merge($altName, $ipAddresses); + } + } + + if (!empty($altName)) { + $this->setExtension('id-ce-subjectAltName', $altName); + } + + if ($this->caFlag) { + $keyUsage = $this->getExtension('id-ce-keyUsage'); + if (!$keyUsage) { + $keyUsage = []; + } + + $this->setExtension( + 'id-ce-keyUsage', + array_values(array_unique(array_merge($keyUsage, ['cRLSign', 'keyCertSign']))) + ); + + $basicConstraints = $this->getExtension('id-ce-basicConstraints'); + if (!$basicConstraints) { + $basicConstraints = []; + } + + $this->setExtension( + 'id-ce-basicConstraints', + array_unique(array_merge(['cA' => true], $basicConstraints)), + true + ); + + if (!isset($subject->currentKeyIdentifier)) { + $this->setExtension('id-ce-subjectKeyIdentifier', $this->computeKeyIdentifier($this->currentCert), false, false); + } + } + + // resync $this->signatureSubject + // save $tbsCertificate in case there are any \phpseclib3\File\ASN1\Element objects in it + $tbsCertificate = $this->currentCert['tbsCertificate']; + $this->loadX509($this->saveX509($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); + $result['tbsCertificate'] = $tbsCertificate; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Sign a CSR + * + * @access public + * @return mixed + */ + public function signCSR() + { + if (!is_object($this->privateKey) || empty($this->dn)) { + return false; + } + + $origPublicKey = $this->publicKey; + $this->publicKey = $this->privateKey->getPublicKey(); + $publicKey = $this->formatSubjectPublicKey(); + $this->publicKey = $origPublicKey; + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); + + if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) { + $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; + if (!empty($this->dn)) { + $this->currentCert['certificationRequestInfo']['subject'] = $this->dn; + } + $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey; + } else { + $this->currentCert = [ + 'certificationRequestInfo' => + [ + 'version' => 'v1', + 'subject' => $this->dn, + 'subjectPKInfo' => $publicKey + ], + 'signatureAlgorithm' => ['algorithm' => $signatureAlgorithm], + 'signature' => false // this is going to be overwritten later + ]; + } + + // resync $this->signatureSubject + // save $certificationRequestInfo in case there are any \phpseclib3\File\ASN1\Element objects in it + $certificationRequestInfo = $this->currentCert['certificationRequestInfo']; + $this->loadCSR($this->saveCSR($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); + $result['certificationRequestInfo'] = $certificationRequestInfo; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Sign a SPKAC + * + * @access public + * @return mixed + */ + public function signSPKAC() + { + if (!is_object($this->privateKey)) { + return false; + } + + $origPublicKey = $this->publicKey; + $this->publicKey = $this->privateKey->getPublicKey(); + $publicKey = $this->formatSubjectPublicKey(); + $this->publicKey = $origPublicKey; + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); + + // re-signing a SPKAC seems silly but since everything else supports re-signing why not? + if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) { + $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; + $this->currentCert['publicKeyAndChallenge']['spki'] = $publicKey; + if (!empty($this->challenge)) { + // the bitwise AND ensures that the output is a valid IA5String + $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge)); + } + } else { + $this->currentCert = [ + 'publicKeyAndChallenge' => + [ + 'spki' => $publicKey, + // quoting , + // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified." + // both Firefox and OpenSSL ("openssl spkac -key private.key") behave this way + // we could alternatively do this instead if we ignored the specs: + // Random::string(8) & str_repeat("\x7F", 8) + 'challenge' => !empty($this->challenge) ? $this->challenge : '' + ], + 'signatureAlgorithm' => ['algorithm' => $signatureAlgorithm], + 'signature' => false // this is going to be overwritten later + ]; + } + + // resync $this->signatureSubject + // save $publicKeyAndChallenge in case there are any \phpseclib3\File\ASN1\Element objects in it + $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge']; + $this->loadSPKAC($this->saveSPKAC($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); + $result['publicKeyAndChallenge'] = $publicKeyAndChallenge; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Sign a CRL + * + * $issuer's private key needs to be loaded. + * + * @param \phpseclib3\File\X509 $issuer + * @param \phpseclib3\File\X509 $crl + * @access public + * @return mixed + */ + public function signCRL($issuer, $crl) + { + if (!is_object($issuer->privateKey) || empty($issuer->dn)) { + return false; + } + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); + + $thisUpdate = new DateTimeImmutable('now', new DateTimeZone(@date_default_timezone_get())); + $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O'); + + if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) { + $this->currentCert = $crl->currentCert; + $this->currentCert['tbsCertList']['signature']['algorithm'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; + } else { + $this->currentCert = [ + 'tbsCertList' => + [ + 'version' => 'v2', + 'signature' => ['algorithm' => $signatureAlgorithm], + 'issuer' => false, // this is going to be overwritten later + 'thisUpdate' => $this->timeField($thisUpdate) // $this->setStartDate() + ], + 'signatureAlgorithm' => ['algorithm' => $signatureAlgorithm], + 'signature' => false // this is going to be overwritten later + ]; + } + + $tbsCertList = &$this->currentCert['tbsCertList']; + $tbsCertList['issuer'] = $issuer->dn; + $tbsCertList['thisUpdate'] = $this->timeField($thisUpdate); + + if (!empty($this->endDate)) { + $tbsCertList['nextUpdate'] = $this->timeField($this->endDate); // $this->setEndDate() + } else { + unset($tbsCertList['nextUpdate']); + } + + if (!empty($this->serialNumber)) { + $crlNumber = $this->serialNumber; + } else { + $crlNumber = $this->getExtension('id-ce-cRLNumber'); + // "The CRL number is a non-critical CRL extension that conveys a + // monotonically increasing sequence number for a given CRL scope and + // CRL issuer. This extension allows users to easily determine when a + // particular CRL supersedes another CRL." + // -- https://tools.ietf.org/html/rfc5280#section-5.2.3 + $crlNumber = $crlNumber !== false ? $crlNumber->add(new BigInteger(1)) : null; + } + + $this->removeExtension('id-ce-authorityKeyIdentifier'); + $this->removeExtension('id-ce-issuerAltName'); + + // Be sure version >= v2 if some extension found. + $version = isset($tbsCertList['version']) ? $tbsCertList['version'] : 0; + if (!$version) { + if (!empty($tbsCertList['crlExtensions'])) { + $version = 1; // v2. + } elseif (!empty($tbsCertList['revokedCertificates'])) { + foreach ($tbsCertList['revokedCertificates'] as $cert) { + if (!empty($cert['crlEntryExtensions'])) { + $version = 1; // v2. + } + } + } + + if ($version) { + $tbsCertList['version'] = $version; + } + } + + // Store additional extensions. + if (!empty($tbsCertList['version'])) { // At least v2. + if (!empty($crlNumber)) { + $this->setExtension('id-ce-cRLNumber', $crlNumber); + } + + if (isset($issuer->currentKeyIdentifier)) { + $this->setExtension('id-ce-authorityKeyIdentifier', [ + //'authorityCertIssuer' => array( + // ] + // 'directoryName' => $issuer->dn + // ] + //), + 'keyIdentifier' => $issuer->currentKeyIdentifier + ]); + //$extensions = &$tbsCertList['crlExtensions']; + //if (isset($issuer->serialNumber)) { + // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; + //} + //unset($extensions); + } + + $issuerAltName = $this->getExtension('id-ce-subjectAltName', $issuer->currentCert); + + if ($issuerAltName !== false) { + $this->setExtension('id-ce-issuerAltName', $issuerAltName); + } + } + + if (empty($tbsCertList['revokedCertificates'])) { + unset($tbsCertList['revokedCertificates']); + } + + unset($tbsCertList); + + // resync $this->signatureSubject + // save $tbsCertList in case there are any \phpseclib3\File\ASN1\Element objects in it + $tbsCertList = $this->currentCert['tbsCertList']; + $this->loadCRL($this->saveCRL($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); + $result['tbsCertList'] = $tbsCertList; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Identify signature algorithm from key settings + * + * @param PrivateKey $key + * @access private + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @return string + */ + private static function identifySignatureAlgorithm(PrivateKey $key) + { + if ($key instanceof RSA) { + if ($key->getPadding() & RSA::SIGNATURE_PSS) { + return 'id-RSASSA-PSS'; + } + switch ($key->getHash()) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha224': + case 'sha256': + case 'sha384': + case 'sha512': + return $key->getHash() . 'WithRSAEncryption'; + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for RSA are: md2, md5, sha1, sha224, sha256, sha384, sha512'); + } + + if ($key instanceof DSA) { + switch ($key->getHash()) { + case 'sha1': + case 'sha224': + case 'sha256': + return 'id-dsa-with-' . $key->getHash(); + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for DSA are: sha1, sha224, sha256'); + } + + if ($key instanceof EC) { + switch ($key->getCurve()) { + case 'Ed25519': + case 'Ed448': + return 'id-' . $key->getCurve(); + } + switch ($key->getHash()) { + case 'sha1': + case 'sha224': + case 'sha256': + case 'sha384': + case 'sha512': + return 'ecdsa-with-' . strtoupper($key->getHash()); + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for EC are: sha1, sha224, sha256, sha384, sha512'); + } + + throw new UnsupportedAlgorithmException('The only supported public key classes are: RSA, DSA, EC'); + } + + /** + * Set certificate start date + * + * @param DateTimeInterface|string $date + * @access public + */ + public function setStartDate($date) + { + if (!is_object($date) || !($date instanceof DateTimeInterface)) { + $date = new DateTimeImmutable($date, new DateTimeZone(@date_default_timezone_get())); + } + + $this->startDate = $date->format('D, d M Y H:i:s O'); + } + + /** + * Set certificate end date + * + * @param DateTimeInterface|string $date + * @access public + */ + public function setEndDate($date) + { + /* + To indicate that a certificate has no well-defined expiration date, + the notAfter SHOULD be assigned the GeneralizedTime value of + 99991231235959Z. + + -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5 + */ + if (is_string($date) && strtolower($date) === 'lifetime') { + $temp = '99991231235959Z'; + $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . ASN1::encodeLength(strlen($temp)) . $temp; + $this->endDate = new Element($temp); + } else { + if (!is_object($date) || !($date instanceof DateTimeInterface)) { + $date = new DateTimeImmutable($date, new DateTimeZone(@date_default_timezone_get())); + } + + $this->endDate = $date->format('D, d M Y H:i:s O'); + } + } + + /** + * Set Serial Number + * + * @param string $serial + * @param int $base optional + * @access public + */ + public function setSerialNumber($serial, $base = -256) + { + $this->serialNumber = new BigInteger($serial, $base); + } + + /** + * Turns the certificate into a certificate authority + * + * @access public + */ + public function makeCA() + { + $this->caFlag = true; + } + + /** + * Check for validity of subarray + * + * This is intended for use in conjunction with _subArrayUnchecked(), + * implementing the checks included in _subArray() but without copying + * a potentially large array by passing its reference by-value to is_array(). + * + * @param array $root + * @param string $path + * @return boolean + * @access private + */ + private function isSubArrayValid($root, $path) + { + if (!is_array($root)) { + return false; + } + + foreach (explode('/', $path) as $i) { + if (!is_array($root)) { + return false; + } + + if (!isset($root[$i])) { + return true; + } + + $root = $root[$i]; + } + + return true; + } + + /** + * Get a reference to a subarray + * + * This variant of _subArray() does no is_array() checking, + * so $root should be checked with _isSubArrayValid() first. + * + * This is here for performance reasons: + * Passing a reference (i.e. $root) by-value (i.e. to is_array()) + * creates a copy. If $root is an especially large array, this is expensive. + * + * @param array $root + * @param string $path absolute path with / as component separator + * @param bool $create optional + * @access private + * @return array|false + */ + private function &subArrayUnchecked(&$root, $path, $create = false) + { + $false = false; + + foreach (explode('/', $path) as $i) { + if (!isset($root[$i])) { + if (!$create) { + return $false; + } + + $root[$i] = []; + } + + $root = &$root[$i]; + } + + return $root; + } + + /** + * Get a reference to a subarray + * + * @param array $root + * @param string $path absolute path with / as component separator + * @param bool $create optional + * @access private + * @return array|false + */ + private function &subArray(&$root, $path, $create = false) + { + $false = false; + + if (!is_array($root)) { + return $false; + } + + foreach (explode('/', $path) as $i) { + if (!is_array($root)) { + return $false; + } + + if (!isset($root[$i])) { + if (!$create) { + return $false; + } + + $root[$i] = []; + } + + $root = &$root[$i]; + } + + return $root; + } + + /** + * Get a reference to an extension subarray + * + * @param array $root + * @param string $path optional absolute path with / as component separator + * @param bool $create optional + * @access private + * @return array|false + */ + private function &extensions(&$root, $path = null, $create = false) + { + if (!isset($root)) { + $root = $this->currentCert; + } + + switch (true) { + case !empty($path): + case !is_array($root): + break; + case isset($root['tbsCertificate']): + $path = 'tbsCertificate/extensions'; + break; + case isset($root['tbsCertList']): + $path = 'tbsCertList/crlExtensions'; + break; + case isset($root['certificationRequestInfo']): + $pth = 'certificationRequestInfo/attributes'; + $attributes = &$this->subArray($root, $pth, $create); + + if (is_array($attributes)) { + foreach ($attributes as $key => $value) { + if ($value['type'] == 'pkcs-9-at-extensionRequest') { + $path = "$pth/$key/value/0"; + break 2; + } + } + if ($create) { + $key = count($attributes); + $attributes[] = ['type' => 'pkcs-9-at-extensionRequest', 'value' => []]; + $path = "$pth/$key/value/0"; + } + } + break; + } + + $extensions = &$this->subArray($root, $path, $create); + + if (!is_array($extensions)) { + $false = false; + return $false; + } + + return $extensions; + } + + /** + * Remove an Extension + * + * @param string $id + * @param string $path optional + * @access private + * @return bool + */ + private function removeExtensionHelper($id, $path = null) + { + $extensions = &$this->extensions($this->currentCert, $path); + + if (!is_array($extensions)) { + return false; + } + + $result = false; + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + unset($extensions[$key]); + $result = true; + } + } + + $extensions = array_values($extensions); + // fix for https://bugs.php.net/75433 affecting PHP 7.2 + if (!isset($extensions[0])) { + $extensions = array_splice($extensions, 0, 0); + } + return $result; + } + + /** + * Get an Extension + * + * Returns the extension if it exists and false if not + * + * @param string $id + * @param array $cert optional + * @param string $path optional + * @access private + * @return mixed + */ + private function getExtensionHelper($id, $cert = null, $path = null) + { + $extensions = $this->extensions($cert, $path); + + if (!is_array($extensions)) { + return false; + } + + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + return $value['extnValue']; + } + } + + return false; + } + + /** + * Returns a list of all extensions in use + * + * @param array $cert optional + * @param string $path optional + * @access private + * @return array + */ + private function getExtensionsHelper($cert = null, $path = null) + { + $exts = $this->extensions($cert, $path); + $extensions = []; + + if (is_array($exts)) { + foreach ($exts as $extension) { + $extensions[] = $extension['extnId']; + } + } + + return $extensions; + } + + /** + * Set an Extension + * + * @param string $id + * @param mixed $value + * @param bool $critical optional + * @param bool $replace optional + * @param string $path optional + * @access private + * @return bool + */ + private function setExtensionHelper($id, $value, $critical = false, $replace = true, $path = null) + { + $extensions = &$this->extensions($this->currentCert, $path, true); + + if (!is_array($extensions)) { + return false; + } + + $newext = ['extnId' => $id, 'critical' => $critical, 'extnValue' => $value]; + + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + if (!$replace) { + return false; + } + + $extensions[$key] = $newext; + return true; + } + } + + $extensions[] = $newext; + return true; + } + + /** + * Remove a certificate, CSR or CRL Extension + * + * @param string $id + * @access public + * @return bool + */ + public function removeExtension($id) + { + return $this->removeExtensionHelper($id); + } + + /** + * Get a certificate, CSR or CRL Extension + * + * Returns the extension if it exists and false if not + * + * @param string $id + * @param array $cert optional + * @param string $path + * @access public + * @return mixed + */ + public function getExtension($id, $cert = null, $path=null) + { + return $this->getExtensionHelper($id, $cert, $path); + } + + /** + * Returns a list of all extensions in use in certificate, CSR or CRL + * + * @param array $cert optional + * @param string $path optional + * @access public + * @return array + */ + public function getExtensions($cert = null, $path = null) + { + return $this->getExtensionsHelper($cert, $path); + } + + /** + * Set a certificate, CSR or CRL Extension + * + * @param string $id + * @param mixed $value + * @param bool $critical optional + * @param bool $replace optional + * @access public + * @return bool + */ + public function setExtension($id, $value, $critical = false, $replace = true) + { + return $this->setExtensionHelper($id, $value, $critical, $replace); + } + + /** + * Remove a CSR attribute. + * + * @param string $id + * @param int $disposition optional + * @access public + * @return bool + */ + public function removeAttribute($id, $disposition = self::ATTR_ALL) + { + $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes'); + + if (!is_array($attributes)) { + return false; + } + + $result = false; + foreach ($attributes as $key => $attribute) { + if ($attribute['type'] == $id) { + $n = count($attribute['value']); + switch (true) { + case $disposition == self::ATTR_APPEND: + case $disposition == self::ATTR_REPLACE: + return false; + case $disposition >= $n: + $disposition -= $n; + break; + case $disposition == self::ATTR_ALL: + case $n == 1: + unset($attributes[$key]); + $result = true; + break; + default: + unset($attributes[$key]['value'][$disposition]); + $attributes[$key]['value'] = array_values($attributes[$key]['value']); + $result = true; + break; + } + if ($result && $disposition != self::ATTR_ALL) { + break; + } + } + } + + $attributes = array_values($attributes); + return $result; + } + + /** + * Get a CSR attribute + * + * Returns the attribute if it exists and false if not + * + * @param string $id + * @param int $disposition optional + * @param array $csr optional + * @access public + * @return mixed + */ + public function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null) + { + if (empty($csr)) { + $csr = $this->currentCert; + } + + $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); + + if (!is_array($attributes)) { + return false; + } + + foreach ($attributes as $key => $attribute) { + if ($attribute['type'] == $id) { + $n = count($attribute['value']); + switch (true) { + case $disposition == self::ATTR_APPEND: + case $disposition == self::ATTR_REPLACE: + return false; + case $disposition == self::ATTR_ALL: + return $attribute['value']; + case $disposition >= $n: + $disposition -= $n; + break; + default: + return $attribute['value'][$disposition]; + } + } + } + + return false; + } + + /** + * Returns a list of all CSR attributes in use + * + * @param array $csr optional + * @access public + * @return array + */ + public function getAttributes($csr = null) + { + if (empty($csr)) { + $csr = $this->currentCert; + } + + $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); + $attrs = []; + + if (is_array($attributes)) { + foreach ($attributes as $attribute) { + $attrs[] = $attribute['type']; + } + } + + return $attrs; + } + + /** + * Set a CSR attribute + * + * @param string $id + * @param mixed $value + * @param int $disposition optional + * @access public + * @return bool + */ + public function setAttribute($id, $value, $disposition = self::ATTR_ALL) + { + $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes', true); + + if (!is_array($attributes)) { + return false; + } + + switch ($disposition) { + case self::ATTR_REPLACE: + $disposition = self::ATTR_APPEND; + case self::ATTR_ALL: + $this->removeAttribute($id); + break; + } + + foreach ($attributes as $key => $attribute) { + if ($attribute['type'] == $id) { + $n = count($attribute['value']); + switch (true) { + case $disposition == self::ATTR_APPEND: + $last = $key; + break; + case $disposition >= $n: + $disposition -= $n; + break; + default: + $attributes[$key]['value'][$disposition] = $value; + return true; + } + } + } + + switch (true) { + case $disposition >= 0: + return false; + case isset($last): + $attributes[$last]['value'][] = $value; + break; + default: + $attributes[] = ['type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value: [$value]]; + break; + } + + return true; + } + + /** + * Sets the subject key identifier + * + * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions. + * + * @param string $value + * @access public + */ + public function setKeyIdentifier($value) + { + if (empty($value)) { + unset($this->currentKeyIdentifier); + } else { + $this->currentKeyIdentifier = $value; + } + } + + /** + * Compute a public key identifier. + * + * Although key identifiers may be set to any unique value, this function + * computes key identifiers from public key according to the two + * recommended methods (4.2.1.2 RFC 3280). + * Highly polymorphic: try to accept all possible forms of key: + * - Key object + * - \phpseclib3\File\X509 object with public or private key defined + * - Certificate or CSR array + * - \phpseclib3\File\ASN1\Element object + * - PEM or DER string + * + * @param mixed $key optional + * @param int $method optional + * @access public + * @return string binary key identifier + */ + public function computeKeyIdentifier($key = null, $method = 1) + { + if (is_null($key)) { + $key = $this; + } + + switch (true) { + case is_string($key): + break; + case is_array($key) && isset($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): + return $this->computeKeyIdentifier($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $method); + case is_array($key) && isset($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): + return $this->computeKeyIdentifier($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $method); + case !is_object($key): + return false; + case $key instanceof Element: + // Assume the element is a bitstring-packed key. + $decoded = ASN1::decodeBER($key->element); + if (empty($decoded)) { + return false; + } + $raw = ASN1::asn1map($decoded[0], ['type' => ASN1::TYPE_BIT_STRING]); + if (empty($raw)) { + return false; + } + // If the key is private, compute identifier from its corresponding public key. + $key = PublicKeyLoader::load($raw); + if ($key instanceof PrivateKey) { // If private. + return $this->computeKeyIdentifier($key, $method); + } + $key = $raw; // Is a public key. + break; + case $key instanceof X509: + if (isset($key->publicKey)) { + return $this->computeKeyIdentifier($key->publicKey, $method); + } + if (isset($key->privateKey)) { + return $this->computeKeyIdentifier($key->privateKey, $method); + } + if (isset($key->currentCert['tbsCertificate']) || isset($key->currentCert['certificationRequestInfo'])) { + return $this->computeKeyIdentifier($key->currentCert, $method); + } + return false; + default: // Should be a key object (i.e.: \phpseclib3\Crypt\RSA). + $key = $key->getPublicKey(); + break; + } + + // If in PEM format, convert to binary. + $key = ASN1::extractBER($key); + + // Now we have the key string: compute its sha-1 sum. + $hash = new Hash('sha1'); + $hash = $hash->hash($key); + + if ($method == 2) { + $hash = substr($hash, -8); + $hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40); + } + + return $hash; + } + + /** + * Format a public key as appropriate + * + * @access private + * @return array|bool + */ + private function formatSubjectPublicKey() + { + $format = $this->publicKey instanceof RSA && ($this->publicKey->getPadding() & RSA::SIGNATURE_PSS) ? + 'PSS' : + 'PKCS8'; + + $publicKey = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->toString($format))); + + $decoded = ASN1::decodeBER($publicKey); + $mapped = ASN1::asn1map($decoded[0], Maps\SubjectPublicKeyInfo::MAP); + + $mapped['subjectPublicKey'] = $this->publicKey->toString($format); + + return $mapped; + } + + /** + * Set the domain name's which the cert is to be valid for + * + * @param mixed[] ...$domains + * @access public + * @return array + */ + public function setDomain(...$domains) + { + $this->domains = $domains; + $this->removeDNProp('id-at-commonName'); + $this->setDNProp('id-at-commonName', $this->domains[0]); + } + + /** + * Set the IP Addresses's which the cert is to be valid for + * + * @access public + * @param mixed[] ...$ipAddresses + */ + public function setIPAddress(...$ipAddresses) + { + $this->ipAddresses = $ipAddresses; + /* + if (!isset($this->domains)) { + $this->removeDNProp('id-at-commonName'); + $this->setDNProp('id-at-commonName', $this->ipAddresses[0]); + } + */ + } + + /** + * Helper function to build domain array + * + * @access private + * @param string $domain + * @return array + */ + private function dnsName($domain) + { + return ['dNSName' => $domain]; + } + + /** + * Helper function to build IP Address array + * + * (IPv6 is not currently supported) + * + * @access private + * @param string $address + * @return array + */ + private function iPAddress($address) + { + return ['iPAddress' => $address]; + } + + /** + * Get the index of a revoked certificate. + * + * @param array $rclist + * @param string $serial + * @param bool $create optional + * @access private + * @return int|false + */ + private function revokedCertificate(&$rclist, $serial, $create = false) + { + $serial = new BigInteger($serial); + + foreach ($rclist as $i => $rc) { + if (!($serial->compare($rc['userCertificate']))) { + return $i; + } + } + + if (!$create) { + return false; + } + + $i = count($rclist); + $revocationDate = new DateTimeImmutable('now', new DateTimeZone(@date_default_timezone_get())); + $rclist[] = ['userCertificate' => $serial, + 'revocationDate' => $this->timeField($revocationDate->format('D, d M Y H:i:s O'))]; + return $i; + } + + /** + * Revoke a certificate. + * + * @param string $serial + * @param string $date optional + * @access public + * @return bool + */ + public function revoke($serial, $date = null) + { + if (isset($this->currentCert['tbsCertList'])) { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if ($this->revokedCertificate($rclist, $serial) === false) { // If not yet revoked + if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { + if (!empty($date)) { + $rclist[$i]['revocationDate'] = $this->timeField($date); + } + + return true; + } + } + } + } + + return false; + } + + /** + * Unrevoke a certificate. + * + * @param string $serial + * @access public + * @return bool + */ + public function unrevoke($serial) + { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + unset($rclist[$i]); + $rclist = array_values($rclist); + return true; + } + } + + return false; + } + + /** + * Get a revoked certificate. + * + * @param string $serial + * @access public + * @return mixed + */ + public function getRevoked($serial) + { + if (is_array($rclist = $this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $rclist[$i]; + } + } + + return false; + } + + /** + * List revoked certificates + * + * @param array $crl optional + * @access public + * @return array|bool + */ + public function listRevoked($crl = null) + { + if (!isset($crl)) { + $crl = $this->currentCert; + } + + if (!isset($crl['tbsCertList'])) { + return false; + } + + $result = []; + + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + foreach ($rclist as $rc) { + $result[] = $rc['userCertificate']->toString(); + } + } + + return $result; + } + + /** + * Remove a Revoked Certificate Extension + * + * @param string $serial + * @param string $id + * @access public + * @return bool + */ + public function removeRevokedCertificateExtension($serial, $id) + { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->removeExtensionHelper($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + + return false; + } + + /** + * Get a Revoked Certificate Extension + * + * Returns the extension if it exists and false if not + * + * @param string $serial + * @param string $id + * @param array $crl optional + * @access public + * @return mixed + */ + public function getRevokedCertificateExtension($serial, $id, $crl = null) + { + if (!isset($crl)) { + $crl = $this->currentCert; + } + + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + + return false; + } + + /** + * Returns a list of all extensions in use for a given revoked certificate + * + * @param string $serial + * @param array $crl optional + * @access public + * @return array|bool + */ + public function getRevokedCertificateExtensions($serial, $crl = null) + { + if (!isset($crl)) { + $crl = $this->currentCert; + } + + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + + return false; + } + + /** + * Set a Revoked Certificate Extension + * + * @param string $serial + * @param string $id + * @param mixed $value + * @param bool $critical optional + * @param bool $replace optional + * @access public + * @return bool + */ + public function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) + { + if (isset($this->currentCert['tbsCertList'])) { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { + return $this->setExtensionHelper($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + } + + return false; + } + + /** + * Register the mapping for a custom/unsupported extension. + * + * @param string $id + * @param array $mapping + */ + public static function registerExtension($id, array $mapping) + { + if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) { + throw new \RuntimeException( + 'Extension ' . $id . ' has already been defined with a different mapping.' + ); + } + + self::$extensions[$id] = $mapping; + } + + /** + * Register the mapping for a custom/unsupported extension. + * + * @param string $id + * + * @return array|null + */ + public static function getRegisteredExtension($id) + { + return isset(self::$extensions[$id]) ? self::$extensions[$id] : null; + } + + /** + * Register the mapping for a custom/unsupported extension. + * + * @param string $id + * @param mixed $value + */ + public function setExtensionValue($id, $value) + { + $this->extensionValues[$id] = $value; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php new file mode 100644 index 000000000..f6ff12ed5 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -0,0 +1,864 @@ + + * add($b); + * + * echo $c->toString(); // outputs 5 + * ?> + * + * + * @category Math + * @package BigInteger + * @author Jim Wigginton + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math; + +use phpseclib3\Exception\BadConfigurationException; + +/** + * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 + * numbers. + * + * @package BigInteger + * @author Jim Wigginton + * @access public + */ +class BigInteger implements \Serializable +{ + /** + * Main Engine + * + * @var string + */ + private static $mainEngine; + + /** + * Modular Exponentiation Engine + * + * @var string + */ + private static $modexpEngine; + + /** + * Selected Engines + * + * @var array + */ + private static $engines; + + /** + * The actual BigInteger object + * + * @var object + */ + private $value; + + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param string $main + * @param array $modexps optional + */ + public static function setEngine($main, $modexps = ['DefaultEngine']) + { + self::$engines = []; + + $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main; + if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) { + throw new \InvalidArgumentException("$main is not a valid engine"); + } + if (!$fqmain::isValidEngine()) { + throw new BadConfigurationException("$main is not setup correctly on this system"); + } + self::$mainEngine = $fqmain; + + if (!in_array('Default', $modexps)) { + $modexps[] = 'DefaultEngine'; + } + + $found = false; + foreach ($modexps as $modexp) { + try { + $fqmain::setModExpEngine($modexp); + $found = true; + break; + } catch (\Exception $e) { + } + } + + if (!$found) { + throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); + } + + self::$modexpEngine = $modexp; + + self::$engines = [$main, $modexp]; + } + + /** + * Returns the engine type + * + * @return string[] + */ + public static function getEngine() + { + self::initialize_static_variables(); + + return self::$engines; + } + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!isset(self::$mainEngine)) { + $engines = [ + ['GMP'], + ['PHP64', ['OpenSSL']], + ['BCMath', ['OpenSSL']], + ['PHP32', ['OpenSSL']] + ]; + foreach ($engines as $engine) { + try { + self::setEngine($engine[0], isset($engine[1]) ? $engine[1] : []); + break; + } catch (\Exception $e) { + } + } + } + } + + /** + * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. + * + * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using + * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. + * + * @param int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set. + * @param int $base + * @return BigInteger + */ + public function __construct($x = 0, $base = 10) + { + self::initialize_static_variables(); + + if ($x instanceof self::$mainEngine) { + $this->value = clone $x; + } elseif ($x instanceof BigInteger\Engines\Engine) { + $this->value = new static("$x"); + $this->value->setPrecision($x->getPrecision()); + } else { + $this->value = new self::$mainEngine($x, $base); + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return $this->value->toString(); + } + + /** + * __toString() magic method + */ + public function __toString() + { + return (string) $this->value; + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + */ + public function __debugInfo() + { + return $this->value->__debugInfo(); + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + return $this->value->toBytes($twos_compliment); + } + + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = false) + { + return $this->value->toHex($twos_compliment); + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + function toBits($twos_compliment = false) + { + return $this->value->toBits($twos_compliment); + } + + /** + * Adds two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + public function add(BigInteger $y) + { + return new static($this->value->add($y->value)); + } + + /** + * Subtracts two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + function subtract(BigInteger $y) + { + return new static($this->value->subtract($y->value)); + } + + /** + * Multiplies two BigIntegers + * + * @param BigInteger $x + * @return BigInteger + */ + public function multiply(BigInteger $x) + { + return new static($this->value->multiply($x->value)); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * Here's an example: + * + * divide($b); + * + * echo $quotient->toString(); // outputs 0 + * echo "\r\n"; + * echo $remainder->toString(); // outputs 10 + * ?> + * + * + * @param BigInteger $y + * @return BigInteger[] + */ + public function divide(BigInteger $y) + { + list($q, $r) = $this->value->divide($y->value); + return [ + new static($q), + new static($r) + ]; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @return BigInteger + * @param BigInteger $n + */ + public function modInverse(BigInteger $n) + { + return new static($this->value->modInverse($n->value)); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @return BigInteger[] + * @param BigInteger $n + */ + public function extendedGCD(BigInteger $n) + { + extract($this->value->extendedGCD($n->value)); + /** + * @var BigInteger $gcd + * @var BigInteger $x + * @var BigInteger $y + */ + return [ + 'gcd' => new static($gcd), + 'x' => new static($x), + 'y' => new static($y) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BigInteger $n + * @return BigInteger + */ + public function gcd(BigInteger $n) + { + return new static($this->value->gcd($n->value)); + } + + /** + * Absolute value. + * + * @return BigInteger + * @access public + */ + public function abs() + { + return new static($this->value->abs()); + } + + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + $this->value->setPrecision($bits); + } + + /** + * Get Precision + * + * Returns the precision if it exists, false if it doesn't + * + * @return int|bool + */ + public function getPrecision() + { + return $this->value->getPrecision(); + } + + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * phpseclib 1.0 serialized strings look like this: + * O:15:"Math_BigInteger":1:{s:3:"hex";s:18:"00ab54a98ceb1f0ad2";} + * + * phpseclib 3.0 serialized strings look like this: + * C:25:"phpseclib\Math\BigInteger":42:{a:1:{s:3:"hex";s:18:"00ab54a98ceb1f0ad2";}} + * + * @return string + */ + public function serialize() + { + $val = ['hex' => $this->toHex(true)]; + $precision = $this->value->getPrecision(); + if ($precision > 0) { + $val['precision'] = $precision; + } + return serialize($val); + } + + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + * + * @param string $serialized + */ + public function unserialize($serialized) + { + $r = unserialize($serialized); + $temp = new static($r['hex'], -16); + $this->value = $temp->value; + if (isset($r['precision'])) { + // recalculate $this->bitmask + $this->setPrecision($r['precision']); + } + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function powMod(BigInteger $e, BigInteger $n) + { + return new static($this->value->powMod($e->value, $n->value)); + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function modPow(BigInteger $e, BigInteger $n) + { + return new static($this->value->modPow($e->value, $n->value)); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BigInteger $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @access public + * @see self::equals() + */ + public function compare(BigInteger $y) + { + return $this->value->compare($y->value); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BigInteger $x + * @return bool + */ + public function equals(BigInteger $x) + { + return $this->value->equals($x->value); + } + + /** + * Logical Not + * + * @return BigInteger + */ + public function bitwise_not() + { + return new static($this->value->bitwise_not()); + } + + /** + * Logical And + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_and(BigInteger $x) + { + return new static($this->value->bitwise_and($x->value)); + } + + /** + * Logical Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_or(BigInteger $x) + { + return new static($this->value->bitwise_or($x->value)); + } + + /** + * Logical Exclusive Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_xor(BigInteger $x) + { + return new static($this->value->bitwise_xor($x->value)); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightShift($shift) + { + return new static($this->value->bitwise_rightShift($shift)); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftShift($shift) + { + return new static($this->value->bitwise_leftShift($shift)); + } + + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftRotate($shift) + { + return new static($this->value->bitwise_leftRotate($shift)); + } + + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightRotate($shift) + { + return new static($this->value->bitwise_rightRotate($shift)); + } + + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return BigInteger[] + */ + public static function minMaxBits($bits) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + extract($class::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + return [ + 'min' => new static($min), + 'max' => new static($max) + ]; + } + + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return $this->value->getLength(); + } + + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return $this->value->getLengthInBytes(); + } + + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function random($size) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + return new static($class::random($size)); + } + + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function randomPrime($size) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + return new static($class::randomPrime($size)); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BigInteger $min + * @param BigInteger $max + * @return false|BigInteger + */ + public static function randomRangePrime(BigInteger $min, BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRangePrime($min->value, $max->value)); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BigInteger $min + * @param BigInteger $max + * @return BigInteger + */ + public static function randomRange(BigInteger $min, BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRange($min->value, $max->value)); + } + + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = false) + { + return $this->value->isPrime($t); + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n optional + * @return BigInteger + */ + public function root($n = 2) + { + return new static($this->value->root($n)); + } + + /** + * Performs exponentiation. + * + * @param BigInteger $n + * @return BigInteger + */ + public function pow(BigInteger $n) + { + return new static($this->value->pow($n->value)); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function min(BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = array_map(function($num) { return $num->value; }, $nums); + return new static($class::min(...$nums)); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function max(BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = array_map(function($num) { return $num->value; }, $nums); + return new static($class::max(...$nums)); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BigInteger $min + * @param BigInteger $max + * @return bool + */ + public function between(BigInteger $min, BigInteger $max) + { + return $this->value->between($min->value, $max->value); + } + + /** + * Clone + */ + public function __clone() + { + $this->value = clone $this->value; + } + + /** + * Is Odd? + * + * @return boolean + */ + public function isOdd() + { + return $this->value->isOdd(); + } + + /** + * Tests if a bit is set + * + * @param int $x + * @return boolean + */ + public function testBit($x) + { + return $this->value->testBit($x); + } + + /** + * Is Negative? + * + * @return boolean + */ + public function isNegative() + { + return $this->value->isNegative(); + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return BigInteger + */ + public function negate() + { + return new static($this->value->negate()); + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param BigInteger $r + * @return int + */ + public static function scan1divide(BigInteger $r) + { + $class = self::$mainEngine; + return $class::scan1divide($r->value); + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $func = $this->value->createRecurringModuloFunction(); + return function(BigInteger $x) use ($func) { + return new static($func($x->value)); + }; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return \phpseclib3\Math\BigInteger[] + */ + public function bitwise_split($split) + { + return array_map(function($val) { + return new static($val); + }, $this->value->bitwise_split($split)); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php new file mode 100644 index 000000000..b97392432 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php @@ -0,0 +1,742 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Exception\BadConfigurationException; + +/** + * BCMath Engine. + * + * @package BCMath + * @author Jim Wigginton + * @access public + */ +class BCMath extends Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + * @access protected + */ + const FAST_BITWISE = false; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + * @access protected + */ + const ENGINE_DIR = 'BCMath'; + + /** + * Modular Exponentiation Engine + * + * @var string + */ + protected static $modexpEngine; + + /** + * Engine Validity Flag + * + * @var bool + */ + protected static $isValidEngine; + + /** + * BigInteger(0) + * + * @var \phpseclib3\Math\BigInteger\Engines\BCMath + */ + protected static $zero; + + /** + * BigInteger(1) + * + * @var \phpseclib3\Math\BigInteger\Engines\BCMath + */ + protected static $one; + + /** + * BigInteger(2) + * + * @var \phpseclib3\Math\BigInteger\Engines\BCMath + */ + protected static $two; + + /** + * Primes > 2 and < 1000 + * + * @var array + */ + protected static $primes; + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return extension_loaded('bcmath'); + } + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + * @return \phpseclib3\Math\BigInteger\Engines\BCMath + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(self::$isValidEngine)) { + self::$isValidEngine = self::isValidEngine(); + } + if (!self::$isValidEngine) { + throw new BadConfigurationException('BCMath is not setup correctly on this system'); + } + + $this->value = '0'; + + parent::__construct($x, $base); + } + + /** + * Initialize a BCMath BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 256: + // round $len to the nearest 4 + $len = (strlen($this->value) + 3) & 0xFFFFFFFC; + + $x = str_pad($this->value, $len, chr(0), STR_PAD_LEFT); + + $this->value = '0'; + for ($i = 0; $i < $len; $i+= 4) { + $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 + $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0); + } + + if ($this->is_negative) { + $this->value = '-' . $this->value; + } + break; + case 16: + $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; + $temp = new self(Hex::decode($x), 256); + $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; + $this->is_negative = false; + break; + case 10: + // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different + // results then doing it on '-1' does (modInverse does $x[0]) + $this->value = $this->value === '-' ? '0' : (string) $this->value; + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if ($this->value === '0') { + return '0'; + } + + return ltrim($this->value, '0'); + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + $value = ''; + $current = $this->value; + + if ($current[0] == '-') { + $current = substr($current, 1); + } + + while (bccomp($current, '0', 0) > 0) { + $temp = bcmod($current, '16777216'); + $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value; + $current = bcdiv($current, '16777216', 0); + } + + return $this->precision > 0 ? + substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($value, chr(0)); + } + + /** + * Adds two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function add(BCMath $y) + { + $temp = new self(); + $temp->value = bcadd($this->value, $y->value); + + return $this->normalize($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function subtract(BCMath $y) + { + $temp = new self(); + $temp->value = bcsub($this->value, $y->value); + + return $this->normalize($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param BCMath $x + * @return BCMath + */ + public function multiply(BCMath $x) + { + $temp = new self(); + $temp->value = bcmul($this->value, $x->value); + + return $this->normalize($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param BCMath $y + * @return BCMath + */ + public function divide(BCMath $y) + { + $quotient = new self(); + $remainder = new self(); + + $quotient->value = bcdiv($this->value, $y->value, 0); + $remainder->value = bcmod($this->value, $y->value); + + if ($remainder->value[0] == '-') { + $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); + } + + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @return false|BCMath + * @param \phpseclib3\Math\BigInteger\Engines\BCMath $n + */ + public function modInverse(BCMath $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param BCMath $n + * @return BCMath + */ + public function extendedGCD(BCMath $n) + { + // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works + // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, + // the basic extended euclidean algorithim is what we're using. + + $u = $this->value; + $v = $n->value; + + $a = '1'; + $b = '0'; + $c = '0'; + $d = '1'; + + while (bccomp($v, '0', 0) != 0) { + $q = bcdiv($u, $v, 0); + + $temp = $u; + $u = $v; + $v = bcsub($temp, bcmul($v, $q, 0), 0); + + $temp = $a; + $a = $c; + $c = bcsub($temp, bcmul($a, $q, 0), 0); + + $temp = $b; + $b = $d; + $d = bcsub($temp, bcmul($b, $q, 0), 0); + } + + return [ + 'gcd' => $this->normalize(new static($u)), + 'x' => $this->normalize(new static($a)), + 'y' => $this->normalize(new static($b)) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BCMath $n + * @return BCMath + */ + public function gcd(BCMath $n) + { + extract($this->extendedGCD($n)); + /** @var BCMath $gcd */ + return $gcd; + } + + /** + * Absolute value. + * + * @return \phpseclib3\Math\BigInteger\Engines\BCMath + */ + public function abs() + { + $temp = new static(); + $temp->value = strlen($this->value) && $this->value[0] == '-' ? + substr($this->value, 1) : + $this->value; + + return $temp; + } + + /** + * Logical And + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_and(BCMath $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_or(BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_xor(BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\BCMath + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\BCMath + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); + + return $this->normalize($temp); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BCMath $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(BCMath $y) + { + return bccomp($this->value, $y->value, 0); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BCMath $x + * @return bool + */ + public function equals(BCMath $x) + { + return $this->value == $x->value; + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function modPow(BCMath $e, BCMath $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function powMod(BCMath $e, BCMath $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected function powModInner(BCMath $e, BCMath $n) + { + try { + $class = self::$modexpEngine; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param BCMath $result + * @return BCMath + */ + protected function normalize(BCMath $result) + { + unset($result->reduce); + + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + if ($result->bitmask !== false) { + $result->value = bcmod($result->value, $result->bitmask->value); + } + + return $result; + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BCMath $min + * @param BCMath $max + * @return false|BCMath + */ + public static function randomRangePrime(BCMath $min, BCMath $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BCMath $min + * @param BCMath $max + * @return BCMath + */ + public static function randomRange(BCMath $min, BCMath $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + if (!$this->isOdd()) { + $this->value = bcadd($this->value, '1'); + } + } + + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value === '1') { + return false; + } + if ($this->value === '2') { + return true; + } + if ($this->value[strlen($this->value) - 1] % 2 == 0) { + return false; + } + + $value = $this->value; + + foreach (self::$primes as $prime) { + $r = bcmod($this->value, $prime); + if ($r == '0') { + return $this->value == $prime; + } + } + + return true; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @see self::isPrime() + * @param BCMath $r + * @return int + */ + public static function scan1divide(BCMath $r) + { + $r_value = &$r->value; + $s = 0; + // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one) check earlier + while ($r_value[strlen($r_value) - 1] % 2 == 0) { + $r_value = bcdiv($r_value, '2', 0); + ++$s; + } + + return $s; + } + + /** + * Performs exponentiation. + * + * @param BCMath $n + * @return BCMath + */ + public function pow(BCMath $n) + { + $temp = new self(); + $temp->value = bcpow($this->value, $n->value); + + return $this->normalize($temp); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function min(BCMath ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function max(BCMath ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BCMath $min + * @param BCMath $max + * @return bool + */ + public function between(BCMath $min, BCMath $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + + /** + * Set Bitmask + * + * @return Engine + * @param int $bits + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + $temp = parent::setBitmask($bits); + return $temp->add(static::$one); + } + + /** + * Is Odd? + * + * @return boolean + */ + public function isOdd() + { + return $this->value[strlen($this->value) - 1] % 2 == 1; + } + + /** + * Tests if a bit is set + * + * @return boolean + */ + public function testBit($x) + { + return bccomp( + bcmod($this->value, bcpow('2', $x + 1, 0), 0), + bcpow('2', $x, 0), + 0 + ) >= 0; + } + + /** + * Is Negative? + * + * @return boolean + */ + public function isNegative() + { + return strlen($this->value) && $this->value[0] == '-'; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return BCMath + */ + public function negate() + { + $temp = clone $this; + + if (!strlen($temp->value)) { + return $temp; + } + + $temp->value = $temp->value[0] == '-' ? + substr($this->value, 1) : + '-' . $this->value; + + return $temp; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php new file mode 100644 index 000000000..0e189b707 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php @@ -0,0 +1,116 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath; + +/** + * Sliding Window Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class Base extends BCMath +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + * @access private + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + * @access private + */ + const DATA = 1; + + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @param \phpseclib3\Math\BigInteger\Engines\BCMath $x + * @param \phpseclib3\Math\BigInteger\Engines\BCMath $e + * @param \phpseclib3\Math\BigInteger\Engines\BCMath $n + * @param string $class + * @return \phpseclib3\Math\BigInteger\Engines\BCMath + */ + protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = '1'; + return $x->normalize($temp); + } + + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + + /** + * Modular reduction preparation + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function prepareReduce($x, $n, $class) + { + return static::reduce($x, $n); + } + + /** + * Modular multiply + * + * @param string $x + * @param string $y + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function multiplyReduce($x, $y, $n, $class) + { + return static::reduce(bcmul($x, $y), $n); + } + + /** + * Modular square + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function squareReduce($x, $n, $class) + { + return static::reduce(bcmul($x, $x), $n); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php new file mode 100644 index 000000000..f312be15e --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php @@ -0,0 +1,44 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath; + +/** + * Built-In BCMath Modular Exponentiation Engine + * + * @package BCMath + * @author Jim Wigginton + * @access public + */ +abstract class BuiltIn extends BCMath +{ + /** + * Performs modular exponentiation. + * + * @param BCMath $x + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n) + { + $temp = new BCMath(); + $temp->value = bcpowmod($x->value, $e->value, $n->value); + + return $x->normalize($temp); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php new file mode 100644 index 000000000..a6d175f5c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php @@ -0,0 +1,29 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett; + +/** + * PHP Default Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class DefaultEngine extends Barrett +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php new file mode 100644 index 000000000..df7c965d6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php @@ -0,0 +1,29 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @package BCMath + * @author Jim Wigginton + * @access public + */ +abstract class OpenSSL extends Progenitor +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php new file mode 100644 index 000000000..32b16dca6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php @@ -0,0 +1,193 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use phpseclib3\Math\BigInteger\Engines\BCMath\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class Barrett extends Base +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + * @access private + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + * @access private + */ + const DATA = 1; + + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param string $n + * @param string $m + * @return array|string + */ + protected static function reduce($n, $m) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $m_length = strlen($m); + + if (strlen($n) > 2 * $m_length) { + return bcmod($n, $m); + } + + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m); + } + // n = 2 * m.length + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + + $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); + $u = bcdiv($lhs, $m, 0); + $m1 = bcsub($lhs, bcmul($u, $m)); + + $cache[self::DATA][] = [ + 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1'=> $m1 // m.length + ]; + } else { + extract($cache[self::DATA][$key]); + } + + $cutoff = $m_length + ($m_length >> 1); + + $lsd = substr($n, -$cutoff); + $msd = substr($n, 0, -$cutoff); + + $temp = bcmul($msd, $m1); // m.length + (m.length >> 1) + $n = bcadd($lsd, $temp); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n, $m); + //} + + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = substr($n, 0, -$m_length + 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = bcmul($temp, $u); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = substr($temp, 0, -($m_length >> 1) - 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = bcmul($temp, $m); + + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + + $result = bcsub($n, $temp); + + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $temp = '1' . str_repeat('0', $m_length + 1); + $result = bcadd($result, $temp); + } + + while (bccomp($result, $m) >= 0) { + $result = bcsub($result, $m); + } + + return $result; + } + + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param string $x + * @param string $n + * @return string + */ + private static function regularBarrett($x, $n) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $n_length = strlen($n); + + if (strlen($x) > 2 * $n_length) { + return bcmod($x, $n); + } + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = '1' . str_repeat('0', 2 * $n_length); + $cache[self::DATA][] = bcdiv($lhs, $n, 0); + } + + $temp = substr($x, 0, -$n_length + 1); + $temp = bcmul($temp, $cache[self::DATA][$key]); + $temp = substr($temp, 0, -$n_length - 1); + + $r1 = substr($x, -$n_length - 1); + $r2 = substr(bcmul($temp, $n), -$n_length - 1); + $result = bcsub($r1, $r2); + + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $q = '1' . str_repeat('0', $n_length + 1); + $result = bcadd($result, $q); + } + + while (bccomp($result, $n) >= 0) { + $result = bcsub($result, $n); + } + + return $result; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php new file mode 100644 index 000000000..27530ec7d --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php @@ -0,0 +1,117 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use phpseclib3\Math\BigInteger\Engines\BCMath\Base; +use phpseclib3\Math\BigInteger\Engines\BCMath; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class EvalBarrett extends Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param string $n + * @param string $m + * @return string + */ + protected static function reduce($n, $m) + { + $inline = self::$custom_reduction; + return $inline($n); + } + + /** + * Generate Custom Reduction + * + * @param BCMath $m + * @param string $class + * @return callable|void + */ + protected static function generateCustomReduction(BCMath $m, $class) + { + if (isset($n->reduce)) { + self::$custom_reduction = $n->reduce; + return $n->reduce; + } + + $m_length = strlen($m); + + if ($m_length < 5) { + $code = 'return bcmod($x, $n);'; + eval('$func = function ($n) { ' . $code . '};'); + self::$custom_reduction = $func; + return; + } + + $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); + $u = bcdiv($lhs, $m, 0); + $m1 = bcsub($lhs, bcmul($u, $m)); + + $cutoff = $m_length + ($m_length >> 1); + + $m = "'$m'"; + $u = "'$u'"; + $m1= "'$m1'"; + + $code.= ' + $lsd = substr($n, -' . $cutoff . '); + $msd = substr($n, 0, -' . $cutoff . '); + + $temp = bcmul($msd, ' . $m1 . '); + $n = bcadd($lsd, $temp); + + $temp = substr($n, 0, ' . (-$m_length + 1) . '); + $temp = bcmul($temp, ' . $u . '); + $temp = substr($temp, 0, ' . (-($m_length >> 1) - 1) . '); + $temp = bcmul($temp, ' . $m . '); + + $result = bcsub($n, $temp); + + if ($result[0] == \'-\') { + $temp = \'1' . str_repeat('0', $m_length + 1) . '\'; + $result = bcadd($result, $temp); + } + + while (bccomp($result, ' . $m . ') >= 0) { + $result = bcsub($result, ' . $m . '); + } + + return $result;'; + + eval('$func = function ($n) { ' . $code . '};'); + + self::$custom_reduction = $func; + + return $func; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php new file mode 100644 index 000000000..10dd994bd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php @@ -0,0 +1,1219 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Crypt\Random; +use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; + +/** + * Base Engine. + * + * @package Engine + * @author Jim Wigginton + * @access public + */ +abstract class Engine implements \Serializable +{ + /** + * Holds the BigInteger's value + * + * @var mixed + */ + protected $value; + + /** + * Holds the BigInteger's sign + * + * @var bool + */ + protected $is_negative; + + /** + * Precision + * + * @see static::setPrecision() + */ + protected $precision = -1; + + /** + * Precision Bitmask + * + * @see static::setPrecision() + */ + protected $bitmask = false; + + /** + * Recurring Modulo Function + * + * @var callable + */ + protected $reduce; + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + */ + public function __construct($x, $base) + { + if (!isset(static::$primes)) { + static::$primes = [ + 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 + ]; + static::$zero = new static(0); + static::$one = new static(1); + static::$two = new static(2); + } + + // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 + // '0' is the only value like this per http://php.net/empty + if (empty($x) && (abs($base) != 256 || $x !== '0')) { + return; + } + + switch ($base) { + case -256: + case 256: + if ($base == -256 && (ord($x[0]) & 0x80)) { + $this->value = ~$x; + $this->is_negative = true; + } else { + $this->value = $x; + $this->is_negative = false; + } + + static::initialize($base); + + if ($this->is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -16: + case 16: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x); + + $is_negative = false; + if ($base < 0 && hexdec($x[0]) >= 8) { + $this->is_negative = $is_negative = true; + $x = Hex::encode(~Hex::decode($x)); + } + + $this->value = $x; + static::initialize($base); + + if ($is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -10: + case 10: + // (?value = preg_replace('#(?value) || $this->value == '-') { + $this->value = '0'; + } + static::initialize($base); + break; + case -2: + case 2: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^([01]*).*#', '$1', $x); + + $temp = new static(Strings::bits2bin($x), 128 * $base); // ie. either -16 or +16 + $this->value = $temp->value; + if ($temp->is_negative) { + $this->is_negative = true; + } + + break; + default: + // base not supported, so we'll let $this == 0 + } + } + + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param string $engine + */ + public static function setModExpEngine($engine) + { + $fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; + if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) { + throw new \InvalidArgumentException("$engine is not a valid engine"); + } + if (!$fqengine::isValidEngine()) { + throw new BadConfigurationException("$engine is not setup correctly on this system"); + } + static::$modexpEngine = $fqengine; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * @return string + */ + protected function toBytesHelper() + { + $comparison = $this->compare(new static()); + if ($comparison == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $temp = $comparison < 0 ? $this->add(new static(1)) : $this; + $bytes = $temp->toBytes(); + + if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 + $bytes = chr(0); + } + + if (ord($bytes[0]) & 0x80) { + $bytes = chr(0) . $bytes; + } + + return $comparison < 0 ? ~$bytes : $bytes; + } + + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = false) + { + return Hex::encode($this->toBytes($twos_compliment)); + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + $hex = $this->toBytes($twos_compliment); + $bits = Strings::bin2bits($hex); + + $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); + + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $result; + } + + return $result; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} + * + * @param \phpseclib3\Math\BigInteger\Engines\Engine $n + * @return \phpseclib3\Math\BigInteger\Engines\Engine|false + */ + protected function modInverseHelper(Engine $n) + { + // $x mod -$n == $x mod $n. + $n = $n->abs(); + + if ($this->compare(static::$zero) < 0) { + $temp = $this->abs(); + $temp = $temp->modInverse($n); + return $this->normalize($n->subtract($temp)); + } + + extract($this->extendedGCD($n)); + /** + * @var BigInteger $gcd + * @var BigInteger $x + */ + + if (!$gcd->equals(static::$one)) { + return false; + } + + $x = $x->compare(static::$zero) < 0 ? $x->add($n) : $x; + + return $this->compare(static::$zero) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); + } + + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * @return string + */ + public function serialize() + { + $val = ['hex' => $this->toHex(true)]; + if ($this->precision > 0) { + $val['precision'] = $this->precision; + } + return serialize($val); + } + + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + * + * @param string $serialized + */ + public function unserialize($serialized) + { + $r = unserialize($serialized); + $temp = new static($r['hex'], -16); + $this->value = $temp->value; + $this->is_negative = $temp->is_negative; + if (isset($r['precision'])) { + // recalculate $this->bitmask + $this->setPrecision($r['precision']); + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + */ + public function __debugInfo() + { + return [ + 'value' => '0x' . $this->toHex(true), + 'engine' => basename(static::class) + ]; + } + + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + if ($bits < 1) { + $this->precision = -1; + $this->bitmask = false; + + return; + } + $this->precision = $bits; + $this->bitmask = static::setBitmask($bits); + + $temp = $this->normalize($this); + $this->value = $temp->value; + } + + /** + * Get Precision + * + * Returns the precision if it exists, -1 if it doesn't + * + * @return int + */ + public function getPrecision() + { + return $this->precision; + } + + /** + * Set Bitmask + * @return Engine + * @param int $bits + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + return new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); + } + + /** + * Logical Not + * + * @return Engine|string + */ + public function bitwise_not() + { + // calculuate "not" without regard to $this->precision + // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) + $temp = $this->toBytes(); + if ($temp == '') { + return $this->normalize(static::$zero); + } + $pre_msb = decbin(ord($temp[0])); + $temp = ~$temp; + $msb = decbin(ord($temp[0])); + if (strlen($msb) == 8) { + $msb = substr($msb, strpos($msb, '0')); + } + $temp[0] = chr(bindec($msb)); + + // see if we need to add extra leading 1's + $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; + $new_bits = $this->precision - $current_bits; + if ($new_bits <= 0) { + return $this->normalize(new static($temp, 256)); + } + + // generate as many leading 1's as we need to. + $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); + + self::base256_lshift($leading_ones, $current_bits); + + $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($leading_ones | $temp, 256)); + } + + /** + * Logical Left Shift + * + * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. + * + * @param string $x + * @param int $shift + * @return string + */ + protected static function base256_lshift(&$x, $shift) + { + if ($shift == 0) { + return; + } + + $num_bytes = $shift >> 3; // eg. floor($shift/8) + $shift &= 7; // eg. $shift % 8 + + $carry = 0; + for ($i = strlen($x) - 1; $i >= 0; --$i) { + $temp = ord($x[$i]) << $shift | $carry; + $x[$i] = chr($temp); + $carry = $temp >> 8; + } + $carry = ($carry != 0) ? chr($carry) : ''; + $x = $carry . $x . str_repeat(chr(0), $num_bytes); + } + + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + public function bitwise_leftRotate($shift) + { + $bits = $this->toBytes(); + + if ($this->precision > 0) { + $precision = $this->precision; + if (static::FAST_BITWISE) { + $mask = $this->bitmask->toBytes(); + } else { + $mask = $this->bitmask->subtract(new static(1)); + $mask = $mask->toBytes(); + } + } else { + $temp = ord($bits[0]); + for ($i = 0; $temp >> $i; ++$i) { + } + $precision = 8 * strlen($bits) - 8 + $i; + $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); + } + + if ($shift < 0) { + $shift+= $precision; + } + $shift%= $precision; + + if (!$shift) { + return clone $this; + } + + $left = $this->bitwise_leftShift($shift); + $left = $left->bitwise_and(new static($mask, 256)); + $right = $this->bitwise_rightShift($precision - $shift); + $result = static::FAST_BITWISE ? $left->bitwise_or($right) : $left->add($right); + return $this->normalize($result); + } + + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + public function bitwise_rightRotate($shift) + { + return $this->bitwise_leftRotate(-$shift); + } + + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return \phpseclib3\Math\BigInteger\Engines\Engine[] + */ + public static function minMaxBits($bits) + { + $bytes = $bits >> 3; + $min = str_repeat(chr(0), $bytes); + $max = str_repeat(chr(0xFF), $bytes); + $msb = $bits & 7; + if ($msb) { + $min = chr(1 << ($msb - 1)) . $min; + $max = chr((1 << $msb) - 1) . $max; + } else { + $min[0] = chr(0x80); + } + return [ + 'min' => new static($min, 256), + 'max' => new static($max, 256) + ]; + } + + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return strlen($this->toBits()); + } + + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return strlen($this->toBytes()); + } + + /** + * Performs some pre-processing for powMod + * + * @param Engine $e + * @param Engine $n + * @return bool|Engine + */ + protected function powModOuter(Engine $e, Engine $n) + { + $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); + + if ($e->compare(new static()) < 0) { + $e = $e->abs(); + + $temp = $this->modInverse($n); + if ($temp === false) { + return false; + } + + return $this->normalize($temp->powModInner($e, $n)); + } + + return $this->powModInner($e, $n); + } + + /** + * Sliding Window k-ary Modular Exponentiation + * + * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, + * however, this function performs a modular reduction after every multiplication and squaring operation. + * As such, this function has the same preconditions that the reductions being used do. + * + * @param \phpseclib3\Math\BigInteger\Engines\Engine $x + * @param \phpseclib3\Math\BigInteger\Engines\Engine $e + * @param \phpseclib3\Math\BigInteger\Engines\Engine $n + * @param string $class + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) + { + static $window_ranges = [7, 25, 81, 241, 673, 1793]; // from BigInteger.java's oddModPow function + //static $window_ranges = [0, 7, 36, 140, 450, 1303, 3529]; // from MPM 7.3.1 + + $e_bits = $e->toBits(); + $e_length = strlen($e_bits); + + // calculate the appropriate window size. + // $window_size == 3 if $window_ranges is between 25 and 81, for example. + for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { + } + + $n_value = $n->value; + + if (method_exists(static::class, 'generateCustomReduction')) { + static::generateCustomReduction($n, $class); + } + + // precompute $this^0 through $this^$window_size + $powers = []; + $powers[1] = static::prepareReduce($x->value, $n_value, $class); + $powers[2] = static::squareReduce($powers[1], $n_value, $class); + + // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end + // in a 1. ie. it's supposed to be odd. + $temp = 1 << ($window_size - 1); + for ($i = 1; $i < $temp; ++$i) { + $i2 = $i << 1; + $powers[$i2 + 1] = static::multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $class); + } + + $result = new $class(1); + $result = static::prepareReduce($result->value, $n_value, $class); + + for ($i = 0; $i < $e_length;) { + if (!$e_bits[$i]) { + $result = static::squareReduce($result, $n_value, $class); + ++$i; + } else { + for ($j = $window_size - 1; $j > 0; --$j) { + if (!empty($e_bits[$i + $j])) { + break; + } + } + + // eg. the length of substr($e_bits, $i, $j + 1) + for ($k = 0; $k <= $j; ++$k) { + $result = static::squareReduce($result, $n_value, $class); + } + + $result = static::multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $class); + + $i += $j + 1; + } + } + + $temp = new $class(); + $temp->value = static::reduce($result, $n_value, $class); + + return $temp; + } + + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + public static function random($size) + { + extract(static::minMaxBits($size)); + /** + * @var BigInteger $min + * @var BigInteger $max + */ + return static::randomRange($min, $max); + } + + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + public static function randomPrime($size) + { + extract(static::minMaxBits($size)); + /** + * @var BigInteger $min + * @var BigInteger $max + */ + return static::randomRangePrime($min, $max); + } + + /** + * Performs some pre-processing for randomRangePrime + * + * @param Engine $min + * @param Engine $max + * @return bool|Engine + */ + protected static function randomRangePrimeOuter(Engine $min, Engine $max) + { + $compare = $max->compare($min); + + if (!$compare) { + return $min->isPrime() ? $min : false; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + + $x = static::randomRange($min, $max); + + return static::randomRangePrimeInner($x, $min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param Engine $min + * @param Engine $max + * @return Engine + */ + protected static function randomRangeHelper(Engine $min, Engine $max) + { + $compare = $max->compare($min); + + if (!$compare) { + return $min; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + + if (!isset(static::$one)) { + static::$one = new static(1); + } + + $max = $max->subtract($min->subtract(static::$one)); + + $size = strlen(ltrim($max->toBytes(), chr(0))); + + /* + doing $random % $max doesn't work because some numbers will be more likely to occur than others. + eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 + would produce 5 whereas the only value of random that could produce 139 would be 139. ie. + not all numbers would be equally likely. some would be more likely than others. + + creating a whole new random number until you find one that is within the range doesn't work + because, for sufficiently small ranges, the likelihood that you'd get a number within that range + would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability + would be pretty high that $random would be greater than $max. + + phpseclib works around this using the technique described here: + + http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string + */ + $random_max = new static(chr(1) . str_repeat("\0", $size), 256); + $random = new static(Random::string($size), 256); + + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + + while ($random->compare($max_multiple) >= 0) { + $random = $random->subtract($max_multiple); + $random_max = $random_max->subtract($max_multiple); + $random = $random->bitwise_leftShift(8); + $random = $random->add(new static(Random::string(1), 256)); + $random_max = $random_max->bitwise_leftShift(8); + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + } + list(, $random) = $random->divide($max); + + return $random->add($min); + } + + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return bool|Engine + */ + protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) + { + if (!isset(static::$two)) { + static::$two = new static('2'); + } + + $x->make_odd(); + if ($x->compare($max) > 0) { + // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range + if ($min->equals($max)) { + return false; + } + $x = clone $min; + $x->make_odd(); + } + + $initial_x = clone $x; + + while (true) { + if ($x->isPrime()) { + return $x; + } + + $x = $x->add(static::$two); + + if ($x->compare($max) > 0) { + $x = clone $min; + if ($x->equals(static::$two)) { + return $x; + } + $x->make_odd(); + } + + if ($x->equals($initial_x)) { + return false; + } + } + } + + /** + * Sets the $t parameter for primality testing + * + * @return int + */ + protected function setupIsPrime() + { + $length = $this->getLengthInBytes(); + + // see HAC 4.49 "Note (controlling the error probability)" + // @codingStandardsIgnoreStart + if ($length >= 163) { $t = 2; } // floor(1300 / 8) + else if ($length >= 106) { $t = 3; } // floor( 850 / 8) + else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) + else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) + else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) + else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) + else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) + else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) + else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) + else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) + else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) + else { $t = 27; } + // @codingStandardsIgnoreEnd + + return $t; + } + + /** + * Tests Primality + * + * Uses the {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24} for more info. + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + if (!$this->testSmallPrimes()) { + return false; + } + + $n = clone $this; + $n_1 = $n->subtract(static::$one); + $n_2 = $n->subtract(static::$two); + + $r = clone $n_1; + $s = static::scan1divide($r); + + for ($i = 0; $i < $t; ++$i) { + $a = static::randomRange(static::$two, $n_2); + $y = $a->modPow($r, $n); + + if (!$y->equals(static::$one) && !$y->equals($n_1)) { + for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { + $y = $y->modPow(static::$two, $n); + if ($y->equals(static::$one)) { + return false; + } + } + + if (!$y->equals($n_1)) { + return false; + } + } + } + + return true; + } + + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = false) + { + if (!$t) { + $t = $this->setupIsPrime(); + } + return $this->testPrimality($t); + } + + /** + * Performs a few preliminary checks on root + * + * @param int $n + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + protected function rootHelper($n) + { + if ($n < 1) { + return clone static::$zero; + } // we want positive exponents + if ($this->compare(static::$one) < 0) { + return clone static::$zero; + } // we want positive numbers + if ($this->compare(static::$two) < 0) { + return clone static::$one; + } // n-th root of 1 or 2 is 1 + + return $this->rootInner($n); + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} + * + * @param int $n + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + protected function rootInner($n) + { + $n = new static($n); + + // g is our guess number + $g = static::$two; + // while (g^n < num) g=g*2 + while ($g->pow($n)->compare($this) < 0) { + $g = $g->multiply(static::$two); + } + // if (g^n==num) num is a power of 2, we're lucky, end of job + // == 0 bccomp(bcpow($g, $n), $n->value)==0 + if ($g->pow($n)->equals($this) > 0) { + $root = $g; + return $this->normalize($root); + } + + // if we're here num wasn't a power of 2 :( + $og = $g; // og means original guess and here is our upper bound + $g = $g->divide(static::$two)[0]; // g is set to be our lower bound + $step = $og->subtract($g)->divide(static::$two)[0]; // step is the half of upper bound - lower bound + $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval + + // while step>1 + + while ($step->compare(static::$one) == 1) { + $guess = $g->pow($n); + $step = $step->divide(static::$two)[0]; + $comp = $guess->compare($this); // compare our guess with real number + switch ($comp) { + case -1: // if guess is lower we add the new step + $g = $g->add($step); + break; + case 1: // if guess is higher we sub the new step + $g = $g->subtract($step); + break; + case 0: // if guess is exactly the num we're done, we return the value + $root = $g; + break 2; + } + } + + if ($comp == 1) { + $g = $g->subtract($step); + } + + // whatever happened, g is the closest guess we can make so return it + $root = $g; + + return $this->normalize($root); + } + + /** + * Calculates the nth root of a biginteger. + * + * @param int $n + * @return Engine + */ + public function root($n = 2) + { + return $this->rootHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function minHelper(array $nums) + { + if (count($nums) == 1) { + return $nums[0]; + } + $min = $nums[0]; + for ($i = 1; $i < count($nums); $i++) { + $min = $min->compare($nums[$i]) > 0 ? $nums[$i] : $min; + } + return $min; + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function maxHelper(array $nums) + { + if (count($nums) == 1) { + return $nums[0]; + } + $max = $nums[0]; + for ($i = 1; $i < count($nums); $i++) { + $max = $max->compare($nums[$i]) < 0 ? $nums[$i] : $max; + } + return $max; + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $class = static::class; + + $fqengine = !method_exists(static::$modexpEngine, 'reduce') ? + '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : + static::$modexpEngine; + if (method_exists($fqengine, 'generateCustomReduction')) { + $func = $fqengine::generateCustomReduction($this, static::class); + $this->reduce = eval('return function(' . static::class . ' $x) use ($func, $class) { + $r = new $class(); + $r->value = $func($x->value); + return $r; + };'); + return clone $this->reduce; + } + $n = $this->value; + $this->reduce = eval('return function(' . static::class . ' $x) use ($n, $fqengine, $class) { + $r = new $class(); + $r->value = $fqengine::reduce($x->value, $n, $class); + return $r; + };'); + return clone $this->reduce; + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * @param Engine $n + * @param Engine $stop (optional) + * @return Engine + */ + protected function extendedGCDHelper(Engine $n, Engine $stop = null) + { + $u = clone $this; + $v = clone $n; + + $one = new static(1); + $zero = new static(); + + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + } + + return [ + 'gcd'=> $u, + 'x' => $a, + 'y' => $b + ]; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return \phpseclib3\Math\BigInteger\Engines\Engine[] + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + + $mask = static::$one->bitwise_leftShift($split)->subtract(static::$one); + + $num = clone $this; + + $vals = []; + while (!$num->equals(static::$zero)) { + $vals[] = $num->bitwise_and($mask); + $num = $num->bitwise_rightShift($split); + } + + return array_reverse($vals); + } + + /** + * Logical And + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseAndHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($left & $right, -256)); + } + + /** + * Logical Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseOrHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($left | $right, -256)); + } + + /** + * Logical Exclusive Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseXorHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + return $this->normalize(new static($left ^ $right, -256)); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php new file mode 100644 index 000000000..2cbc9cbed --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php @@ -0,0 +1,751 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Exception\BadConfigurationException; + +/** + * GMP Engine. + * + * @package GMP + * @author Jim Wigginton + * @access public + */ +class GMP extends Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + * @access protected + */ + const FAST_BITWISE = true; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + * @access protected + */ + const ENGINE_DIR = 'GMP'; + + /** + * Modular Exponentiation Engine + * + * @var string + */ + protected static $modexpEngine; + + /** + * Engine Validity Flag + * + * @var bool + */ + protected static $isValidEngine; + + /** + * BigInteger(0) + * + * @var \phpseclib3\Math\BigInteger\Engines\GMP + */ + protected static $zero; + + /** + * BigInteger(1) + * + * @var \phpseclib3\Math\BigInteger\Engines\GMP + */ + protected static $one; + + /** + * BigInteger(2) + * + * @var \phpseclib3\Math\BigInteger\Engines\GMP + */ + protected static $two; + + /** + * Primes > 2 and < 1000 + * + * Unused for GMP Engine + * + * @var mixed + */ + protected static $primes; + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return extension_loaded('gmp'); + } + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + * @return \phpseclib3\Math\BigInteger\Engines\GMP + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(self::$isValidEngine)) { + self::$isValidEngine = self::isValidEngine(); + } + if (!self::$isValidEngine) { + throw new BadConfigurationException('GMP is not setup correctly on this system'); + } + + if ($x instanceof \GMP) { + $this->value = $x; + return; + } + + $this->value = gmp_init(0); + + parent::__construct($x, $base); + } + + /** + * Initialize a GMP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 256: + $this->value = gmp_import($this->value); + if ($this->is_negative) { + $this->value = -$this->value; + } + break; + case 16: + $temp = $this->is_negative ? '-0x' . $this->value : '0x' . $this->value; + $this->value = gmp_init($temp); + break; + case 10: + $this->value = gmp_init(isset($this->value) ? $this->value : '0'); + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return (string) $this->value; + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + $hex = $this->toHex($twos_compliment); + + $bits = gmp_strval(gmp_init($hex, 16), 2); + + if ($this->precision > 0) { + $bits = substr($bits, -$this->precision); + } + + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $bits; + } + + return $bits; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + if (gmp_cmp($this->value, gmp_init(0)) == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $temp = gmp_export($this->value); + + return $this->precision > 0 ? + substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($temp, chr(0)); + } + + /** + * Adds two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function add(GMP $y) + { + $temp = new self(); + $temp->value = $this->value + $y->value; + + return $this->normalize($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function subtract(GMP $y) + { + $temp = new self(); + $temp->value = $this->value - $y->value; + + return $this->normalize($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param GMP $x + * @return GMP + */ + public function multiply(GMP $x) + { + $temp = new self(); + $temp->value = $this->value * $x->value; + + return $this->normalize($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param GMP $y + * @return GMP + */ + public function divide(GMP $y) + { + $quotient = new self(); + $remainder = new self(); + + list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); + + if (gmp_sign($remainder->value) < 0) { + $remainder->value = $remainder->value + gmp_abs($y->value); + } + + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param GMP $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @access public + * @see self::equals() + */ + public function compare(GMP $y) + { + $r = gmp_cmp($this->value, $y->value); + if ($r < -1) { + $r = -1; + } + if ($r > 1) { + $r = 1; + } + return $r; + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param GMP $x + * @return bool + */ + public function equals(GMP $x) + { + return $this->value == $x->value; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param GMP $n + * @return false|GMP + */ + public function modInverse(GMP $n) + { + $temp = new self(); + $temp->value = gmp_invert($this->value, $n->value); + + return $temp->value === false ? false : $this->normalize($temp); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param \phpseclib3\Math\BigInteger\Engines\GMP $n + * @return \phpseclib3\Math\BigInteger\Engines\GMP[] + */ + public function extendedGCD(GMP $n) + { + extract(gmp_gcdext($this->value, $n->value)); + + return [ + 'gcd' => $this->normalize(new self($g)), + 'x' => $this->normalize(new self($s)), + 'y' => $this->normalize(new self($t)) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param GMP $n + * @return GMP + */ + public function gcd(GMP $n) + { + $r = gmp_gcd($this->value, $n->value); + return $this->normalize(new self($r)); + } + + /** + * Absolute value. + * + * @return \phpseclib3\Math\BigInteger\Engines\GMP + * @access public + */ + public function abs() + { + $temp = new self(); + $temp->value = gmp_abs($this->value); + + return $temp; + } + + /** + * Logical And + * + * @param GMP $x + * @return GMP + */ + public function bitwise_and(GMP $x) + { + $temp = new self(); + $temp->value = $this->value & $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_or(GMP $x) + { + $temp = new self(); + $temp->value = $this->value | $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Exclusive Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_xor(GMP $x) + { + $temp = new self(); + $temp->value = $this->value ^ $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\GMP + */ + public function bitwise_rightShift($shift) + { + // 0xFFFFFFFF >> 2 == -1 (on 32-bit systems) + // gmp_init('0xFFFFFFFF') >> 2 == gmp_init('0x3FFFFFFF') + + $temp = new self(); + $temp->value = $this->value >> $shift; + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\GMP + */ + public function bitwise_leftShift($shift) + { + $temp = new self(); + $temp->value = $this->value << $shift; + + return $this->normalize($temp); + } + + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function modPow(GMP $e, GMP $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function powMod(GMP $e, GMP $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected function powModInner(GMP $e, GMP $n) + { + $class = self::$modexpEngine; + return $class::powModHelper($this, $e, $n); + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param GMP $result + * @return GMP + */ + protected function normalize(GMP $result) + { + unset($result->reduce); + + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + if ($result->bitmask !== false) { + $flip = $result->value < 0; + if ($flip) { + $result->value = -$result->value; + } + $result->value = $result->value & $result->bitmask->value; + if ($flip) { + $result->value = -$result->value; + } + } + + return $result; + } + + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return GMP + */ + protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) + { + $p = gmp_nextprime($x->value); + + if ($p <= $max->value) { + return new self($p); + } + + if ($min->value != $x->value) { + $x = new self($x->value - 1); + } + + return self::randomRangePrime($min, $x); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param GMP $min + * @param GMP $max + * @return false|GMP + */ + public static function randomRangePrime(GMP $min, GMP $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param GMP $min + * @param GMP $max + * @return GMP + */ + public static function randomRange(GMP $min, GMP $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + gmp_setbit($this->value, 0); + } + + /** + * Tests Primality + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + return gmp_prob_prime($this->value, $t) != 0; + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n + * @return GMP + */ + protected function rootInner($n) + { + $root = new self(); + $root->value = gmp_root($this->value, $n); + return $this->normalize($root); + } + + /** + * Performs exponentiation. + * + * @param GMP $n + * @return GMP + */ + public function pow(GMP $n) + { + $temp = new self(); + $temp->value = $this->value ** $n->value; + + return $this->normalize($temp); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function min(GMP ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function max(GMP ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param GMP $min + * @param GMP $max + * @return bool + */ + public function between(GMP $min, GMP $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $temp = $this->value; + $this->reduce = function(GMP $x) use ($temp) { + return new GMP($x->value % $temp); + }; + return $this->reduce; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param GMP $r + * @return int + */ + public static function scan1divide(GMP $r) + { + $s = gmp_scan1($r->value, 0); + $r->value >>= $s; + return $s; + } + + /** + * Is Odd? + * + * @return boolean + */ + public function isOdd() + { + return gmp_testbit($this->value, 0); + } + + /** + * Tests if a bit is set + * + * @return boolean + */ + public function testBit($x) + { + return gmp_testbit($this->value, $x); + } + + /** + * Is Negative? + * + * @return boolean + */ + public function isNegative() + { + return gmp_sign($this->value) == -1; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return GMP + */ + public function negate() + { + $temp = clone $this; + $temp->value = -$this->value; + + return $temp; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php new file mode 100644 index 000000000..9889271ec --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php @@ -0,0 +1,44 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\GMP; + +use phpseclib3\Math\BigInteger\Engines\GMP; + +/** + * GMP Modular Exponentiation Engine + * + * @package GMP + * @author Jim Wigginton + * @access public + */ +abstract class DefaultEngine extends GMP +{ + /** + * Performs modular exponentiation. + * + * @param GMP $x + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected static function powModHelper(GMP $x, GMP $e, GMP $n) + { + $temp = new GMP(); + $temp->value = gmp_powm($x->value, $e->value, $n->value); + + return $x->normalize($temp); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php new file mode 100644 index 000000000..ce4d18a3f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php @@ -0,0 +1,75 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @package Engines + * @author Jim Wigginton + * @access public + */ +abstract class OpenSSL +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return extension_loaded('openssl') && static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @return Engine + */ + public static function powModHelper(Engine $x, Engine $e, Engine $n) + { + if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { + throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); + } + + $key = PKCS8::savePublicKey( + new BigInteger($n), + new BigInteger($e) + ); + $rsa = RSA::load($key); + //$rsa->setPublicKeyFormat('PKCS1'); + + $plaintext = str_pad($x->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT); + + // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it + // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line" + // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what + // about odd numbers divisible by 3, by 5, etc? + if (!openssl_public_encrypt($plaintext, $result, "$rsa", OPENSSL_NO_PADDING)) { + throw new \UnexpectedValueException(openssl_error_string()); + } + + $class = get_class($x); + return new $class($result, 256); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php new file mode 100644 index 000000000..5f94e68ba --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php @@ -0,0 +1,1316 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Exception\BadConfigurationException; + +/** + * Pure-PHP Engine. + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class PHP extends Engine +{ + /**#@+ + * Array constants + * + * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and + * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. + * + * @access protected + */ + /** + * $result[self::VALUE] contains the value. + */ + const VALUE = 0; + /** + * $result[self::SIGN] contains the sign. + */ + const SIGN = 1; + /**#@-*/ + + /** + * Karatsuba Cutoff + * + * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? + * + * @access private + */ + const KARATSUBA_CUTOFF = 25; + + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + * @access protected + */ + const FAST_BITWISE = true; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + * @access protected + */ + const ENGINE_DIR = 'PHP'; + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + * @return \phpseclib3\Math\BigInteger\Engines\PHP + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine)) { + static::$isValidEngine = static::isValidEngine(); + } + if (!static::$isValidEngine) { + throw new BadConfigurationException(static::class . ' is not setup correctly on this system'); + } + + $this->value = []; + parent::__construct($x, $base); + } + + /** + * Initialize a PHP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 16: + $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; + $temp = new static(Hex::decode($x), 256); + $this->value = $temp->value; + break; + case 10: + $temp = new static(); + + $multiplier = new static(); + $multiplier->value = [static::MAX10]; + + $x = $this->value; + + if ($x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = str_pad($x, strlen($x) + ((static::MAX10LEN - 1) * strlen($x)) % static::MAX10LEN, 0, STR_PAD_LEFT); + while (strlen($x)) { + $temp = $temp->multiply($multiplier); + $temp = $temp->add(new static($this->int2bytes(substr($x, 0, static::MAX10LEN)), 256)); + $x = substr($x, static::MAX10LEN); + } + + $this->value = $temp->value; + } + } + + /** + * Pads strings so that unpack may be used on them + * + * @param string $str + * @return string + */ + protected function pad($str) + { + $length = strlen($str); + + $pad = 4 - (strlen($str) % 4); + + return str_pad($str, $length + $pad, "\0", STR_PAD_LEFT); + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if (!count($this->value)) { + return '0'; + } + + $temp = clone $this; + $temp->bitmask = false; + $temp->is_negative = false; + + $divisor = new static(); + $divisor->value = [static::MAX10]; + $result = ''; + while (count($temp->value)) { + list($temp, $mod) = $temp->divide($divisor); + $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', static::MAX10LEN, '0', STR_PAD_LEFT) . $result; + } + $result = ltrim($result, '0'); + if (empty($result)) { + $result = '0'; + } + + if ($this->is_negative) { + $result = '-' . $result; + } + + return $result; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + if (!count($this->value)) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $result = $this->bitwise_small_split(8); + $result = implode('', array_map('chr', $result)); + + return $this->precision > 0 ? + str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) : + $result; + } + + /** + * Performs addition. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function addHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return [ + self::VALUE => $y_value, + self::SIGN => $y_negative + ]; + } elseif ($y_size == 0) { + return [ + self::VALUE => $x_value, + self::SIGN => $x_negative + ]; + } + + // subtract, if appropriate + if ($x_negative != $y_negative) { + if ($x_value == $y_value) { + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + $temp = self::subtractHelper($x_value, false, $y_value, false); + $temp[self::SIGN] = self::compareHelper($x_value, false, $y_value, false) > 0 ? + $x_negative : $y_negative; + + return $temp; + } + + if ($x_size < $y_size) { + $size = $x_size; + $value = $y_value; + } else { + $size = $y_size; + $value = $x_value; + } + + $value[count($value)] = 0; // just in case the carry adds an extra digit + + $carry = 0; + for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) { + //$sum = $x_value[$j] * static::BASE_FULL + $x_value[$i] + $y_value[$j] * static::BASE_FULL + $y_value[$i] + $carry; + $sum = ($x_value[$j] + $y_value[$j]) * static::BASE_FULL + $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum - static::MAX_DIGIT2 : $sum; + + $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $value[$i] = (int) ($sum - static::BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) + $value[$j] = $temp; + } + + if ($j == $size) { // ie. if $y_size is odd + $sum = $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::BASE_FULL; + $value[$i] = $carry ? $sum - static::BASE_FULL : $sum; + ++$i; // ie. let $i = $j since we've just done $value[$i] + } + + if ($carry) { + for (; $value[$i] == static::MAX_DIGIT; ++$i) { + $value[$i] = 0; + } + ++$value[$i]; + } + + return [ + self::VALUE => self::trim($value), + self::SIGN => $x_negative + ]; + } + + /** + * Performs subtraction. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + static function subtractHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return [ + self::VALUE => $y_value, + self::SIGN => !$y_negative + ]; + } elseif ($y_size == 0) { + return [ + self::VALUE => $x_value, + self::SIGN => $x_negative + ]; + } + + // add, if appropriate (ie. -$x - +$y or +$x - -$y) + if ($x_negative != $y_negative) { + $temp = self::addHelper($x_value, false, $y_value, false); + $temp[self::SIGN] = $x_negative; + + return $temp; + } + + $diff = self::compareHelper($x_value, $x_negative, $y_value, $y_negative); + + if (!$diff) { + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + // switch $x and $y around, if appropriate. + if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_negative = !$x_negative; + + $x_size = count($x_value); + $y_size = count($y_value); + } + + // at this point, $x_value should be at least as big as - if not bigger than - $y_value + + $carry = 0; + for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) { + $sum = ($x_value[$j] - $y_value[$j]) * static::BASE_FULL + $x_value[$i] - $y_value[$i] - $carry; + + $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum + static::MAX_DIGIT2 : $sum; + + $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $x_value[$i] = (int) ($sum - static::BASE_FULL * $temp); + $x_value[$j] = $temp; + } + + if ($j == $y_size) { // ie. if $y_size is odd + $sum = $x_value[$i] - $y_value[$i] - $carry; + $carry = $sum < 0; + $x_value[$i] = $carry ? $sum + static::BASE_FULL : $sum; + ++$i; + } + + if ($carry) { + for (; !$x_value[$i]; ++$i) { + $x_value[$i] = static::MAX_DIGIT; + } + --$x_value[$i]; + } + + return [ + self::VALUE => self::trim($x_value), + self::SIGN => $x_negative + ]; + } + + /** + * Performs multiplication. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function multiplyHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + //if ( $x_value == $y_value ) { + // return [ + // self::VALUE => self::square($x_value), + // self::SIGN => $x_sign != $y_value + // ]; + //} + + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + return [ + self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? + self::trim(self::regularMultiply($x_value, $y_value)) : + self::trim(self::karatsuba($x_value, $y_value)), + self::SIGN => $x_negative != $y_negative + ]; + } + + /** + * Performs Karatsuba multiplication on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + private static function karatsuba(array $x_value, array $y_value) + { + $m = min(count($x_value) >> 1, count($y_value) >> 1); + + if ($m < self::KARATSUBA_CUTOFF) { + return self::regularMultiply($x_value, $y_value); + } + + $x1 = array_slice($x_value, $m); + $x0 = array_slice($x_value, 0, $m); + $y1 = array_slice($y_value, $m); + $y0 = array_slice($y_value, 0, $m); + + $z2 = self::karatsuba($x1, $y1); + $z0 = self::karatsuba($x0, $y0); + + $z1 = self::addHelper($x1, false, $x0, false); + $temp = self::addHelper($y1, false, $y0, false); + $z1 = self::karatsuba($z1[self::VALUE], $temp[self::VALUE]); + $temp = self::addHelper($z2, false, $z0, false); + $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xy = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xy = self::addHelper($xy[self::VALUE], $xy[self::SIGN], $z0, false); + + return $xy[self::VALUE]; + } + + /** + * Performs long multiplication on two BigIntegers + * + * Modeled after 'multiply' in MutableBigInteger.java. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + protected static function regularMultiply(array $x_value, array $y_value) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return []; + } + + $product_value = self::array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int) ($temp - static::BASE_FULL * $carry); + } + + $product_value[$j] = $carry; + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int) ($temp - static::BASE_FULL * $carry); + } + + $product_value[$k] = $carry; + } + + return $product_value; + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param \phpseclib3\Math\BigInteger\engines\PHP $y + * @return array + * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. + */ + protected function divideHelper(PHP $y) + { + if (count($y->value) == 1) { + list($q, $r) = $this->divide_digit($this->value, $y->value[0]); + $quotient = new static(); + $remainder = new static(); + $quotient->value = $q; + $remainder->value = [$r]; + $quotient->is_negative = $this->is_negative != $y->is_negative; + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + $x = clone $this; + $y = clone $y; + + $x_sign = $x->is_negative; + $y_sign = $y->is_negative; + + $x->is_negative = $y->is_negative = false; + + $diff = $x->compare($y); + + if (!$diff) { + $temp = new static(); + $temp->value = [1]; + $temp->is_negative = $x_sign != $y_sign; + return [$this->normalize($temp), $this->normalize(static::$zero)]; + } + + if ($diff < 0) { + // if $x is negative, "add" $y. + if ($x_sign) { + $x = $y->subtract($x); + } + return [$this->normalize(static::$zero), $this->normalize($x)]; + } + + // normalize $x and $y as described in HAC 14.23 / 14.24 + $msb = $y->value[count($y->value) - 1]; + for ($shift = 0; !($msb & static::MSB); ++$shift) { + $msb <<= 1; + } + $x->lshift($shift); + $y->lshift($shift); + $y_value = &$y->value; + + $x_max = count($x->value) - 1; + $y_max = count($y->value) - 1; + + $quotient = new static(); + $quotient_value = &$quotient->value; + $quotient_value = self::array_repeat(0, $x_max - $y_max + 1); + + static $temp, $lhs, $rhs; + if (!isset($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + $temp_value = &$temp->value; + $rhs_value = &$rhs->value; + + // $temp = $y << ($x_max - $y_max-1) in base 2**26 + $temp_value = array_merge(self::array_repeat(0, $x_max - $y_max), $y_value); + + while ($x->compare($temp) >= 0) { + // calculate the "common residue" + ++$quotient_value[$x_max - $y_max]; + $x = $x->subtract($temp); + $x_max = count($x->value) - 1; + } + + for ($i = $x_max; $i >= $y_max + 1; --$i) { + $x_value = &$x->value; + $x_window = [ + isset($x_value[$i]) ? $x_value[$i] : 0, + isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, + isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 + ]; + $y_window = [ + $y_value[$y_max], + ($y_max > 0) ? $y_value[$y_max - 1] : 0 + ]; + + $q_index = $i - $y_max - 1; + if ($x_window[0] == $y_window[0]) { + $quotient_value[$q_index] = static::MAX_DIGIT; + } else { + $quotient_value[$q_index] = self::safe_divide( + $x_window[0] * static::BASE_FULL + $x_window[1], + $y_window[0] + ); + } + + $temp_value = [$y_window[1], $y_window[0]]; + + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + + $rhs_value = [$x_window[2], $x_window[1], $x_window[0]]; + + while ($lhs->compare($rhs) > 0) { + --$quotient_value[$q_index]; + + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + } + + $adjust = self::array_repeat(0, $q_index); + $temp_value = [$quotient_value[$q_index]]; + $temp = $temp->multiply($y); + $temp_value = &$temp->value; + if (count($temp_value)) { + $temp_value = array_merge($adjust, $temp_value); + } + + $x = $x->subtract($temp); + + if ($x->compare(static::$zero) < 0) { + $temp_value = array_merge($adjust, $y_value); + $x = $x->add($temp); + + --$quotient_value[$q_index]; + } + + $x_max = count($x_value) - 1; + } + + // unnormalize the remainder + $x->rshift($shift); + + $quotient->is_negative = $x_sign != $y_sign; + + // calculate the "common residue", if appropriate + if ($x_sign) { + $y->rshift($shift); + $x = $y->subtract($x); + } + + return [$this->normalize($quotient), $this->normalize($x)]; + } + + /** + * Divides a BigInteger by a regular integer + * + * abc / x = a00 / x + b0 / x + c / x + * + * @param array $dividend + * @param int $divisor + * @return array + */ + private static function divide_digit(array $dividend, $divisor) + { + $carry = 0; + $result = []; + + for ($i = count($dividend) - 1; $i >= 0; --$i) { + $temp = static::BASE_FULL * $carry + $dividend[$i]; + $result[$i] = self::safe_divide($temp, $divisor); + $carry = (int) ($temp - $divisor * $result[$i]); + } + + return [$result, $carry]; + } + + /** + * Single digit division + * + * Even if int64 is being used the division operator will return a float64 value + * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't + * have the precision of int64 this is a problem so, when int64 is being used, + * we'll guarantee that the dividend is divisible by first subtracting the remainder. + * + * @param int $x + * @param int $y + * @return int + */ + private static function safe_divide($x, $y) + { + if (static::BASE === 26) { + return (int) ($x / $y); + } + + // static::BASE === 31 + return ($x - ($x % $y)) / $y; + } + + /* + * Convert an array / boolean to a PHP BigInteger object + * + * @param array $arr + * @return \phpseclib3\Math\BigInteger\Engines\PHP + */ + protected function convertToObj(array $arr) + { + $result = new static(); + $result->value = $arr[self::VALUE]; + $result->is_negative = $arr[self::SIGN]; + + return $this->normalize($result); + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param PHP $result + * @return PHP + */ + protected function normalize(PHP $result) + { + unset($result->reduce); + + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + $value = &$result->value; + + if (!count($value)) { + $result->is_negative = false; + return $result; + } + + $value = static::trim($value); + + if (!empty($result->bitmask->value)) { + $length = min(count($value), count($result->bitmask->value)); + $value = array_slice($value, 0, $length); + + for ($i = 0; $i < $length; ++$i) { + $value[$i] = $value[$i] & $result->bitmask->value[$i]; + } + } + + return $result; + } + + /* + * Compares two numbers. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return int + * @see static::compare() + */ + protected static function compareHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + if ($x_negative != $y_negative) { + return (!$x_negative && $y_negative) ? 1 : -1; + } + + $result = $x_negative ? -1 : 1; + + if (count($x_value) != count($y_value)) { + return (count($x_value) > count($y_value)) ? $result : -$result; + } + $size = max(count($x_value), count($y_value)); + + $x_value = array_pad($x_value, $size, 0); + $y_value = array_pad($y_value, $size, 0); + + for ($i = count($x_value) - 1; $i >= 0; --$i) { + if ($x_value[$i] != $y_value[$i]) { + return ($x_value[$i] > $y_value[$i]) ? $result : -$result; + } + } + + return 0; + } + + /** + * Absolute value. + * + * @return \phpseclib3\Math\BigInteger\Engines\PHP + */ + public function abs() + { + $temp = new static(); + $temp->value = $this->value; + + return $temp; + } + + /** + * Trim + * + * Removes leading zeros + * + * @param array $value + * @return PHP + */ + protected static function trim(array $value) + { + for ($i = count($value) - 1; $i >= 0; --$i) { + if ($value[$i]) { + break; + } + unset($value[$i]); + } + + return $value; + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\PHP + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + + // could just replace lshift with this, but then all lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->rshift($shift); + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return \phpseclib3\Math\BigInteger\Engines\PHP + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->lshift($shift); + + return $this->normalize($temp); + } + + /** + * Converts 32-bit integers to bytes. + * + * @param int $x + * @return string + */ + private static function int2bytes($x) + { + return ltrim(pack('N', $x), chr(0)); + } + + /** + * Array Repeat + * + * @param int $input + * @param int $multiplier + * @return array + */ + protected static function array_repeat($input, $multiplier) + { + return $multiplier ? array_fill(0, $multiplier, $input) : []; + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function lshift($shift) + { + if ($shift == 0) { + return; + } + + $num_digits = (int) ($shift / static::BASE); + $shift %= static::BASE; + $shift = 1 << $shift; + + $carry = 0; + + for ($i = 0; $i < count($this->value); ++$i) { + $temp = $this->value[$i] * $shift + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $this->value[$i] = (int) ($temp - $carry * static::BASE_FULL); + } + + if ($carry) { + $this->value[count($this->value)] = $carry; + } + + while ($num_digits--) { + array_unshift($this->value, 0); + } + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function rshift($shift) + { + if ($shift == 0) { + return; + } + + $num_digits = (int) ($shift / static::BASE); + $shift %= static::BASE; + $carry_shift = static::BASE - $shift; + $carry_mask = (1 << $shift) - 1; + + if ($num_digits) { + $this->value = array_slice($this->value, $num_digits); + } + + $carry = 0; + + for ($i = count($this->value) - 1; $i >= 0; --$i) { + $temp = $this->value[$i] >> $shift | $carry; + $carry = ($this->value[$i] & $carry_mask) << $carry_shift; + $this->value[$i] = $temp; + } + + $this->value = static::trim($this->value); + } + + /** + * Performs modular exponentiation. + * + * @param PHP $e + * @param PHP $n + * @return PHP + */ + protected function powModInner(PHP $e, PHP $n) + { + try { + $class = static::$modexpEngine; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + + /** + * Performs squaring + * + * @param array $x + * @return array + */ + protected static function square(array $x) + { + return count($x) < 2 * self::KARATSUBA_CUTOFF ? + self::trim(self::baseSquare($x)) : + self::trim(self::karatsubaSquare($x)); + } + + /** + * Performs traditional squaring on two BigIntegers + * + * Squaring can be done faster than multiplying a number by itself can be. See + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. + * + * @param array $value + * @return array + */ + protected static function baseSquare(array $value) + { + if (empty($value)) { + return []; + } + $square_value = self::array_repeat(0, 2 * count($value)); + + for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { + $i2 = $i << 1; + + $temp = $square_value[$i2] + $value[$i] * $value[$i]; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$i2] = (int) ($temp - static::BASE_FULL * $carry); + + // note how we start from $i+1 instead of 0 as we do in multiplication. + for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { + $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$k] = (int) ($temp - static::BASE_FULL * $carry); + } + + // the following line can yield values larger 2**15. at this point, PHP should switch + // over to floats. + $square_value[$i + $max_index + 1] = $carry; + } + + return $square_value; + } + + /** + * Performs Karatsuba "squaring" on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. + * + * @param array $value + * @return array + */ + protected static function karatsubaSquare(array $value) + { + $m = count($value) >> 1; + + if ($m < self::KARATSUBA_CUTOFF) { + return self::baseSquare($value); + } + + $x1 = array_slice($value, $m); + $x0 = array_slice($value, 0, $m); + + $z2 = self::karatsubaSquare($x1); + $z0 = self::karatsubaSquare($x0); + + $z1 = self::addHelper($x1, false, $x0, false); + $z1 = self::karatsubaSquare($z1[self::VALUE]); + $temp = self::addHelper($z2, false, $z0, false); + $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xx = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xx = self::addHelper($xx[self::VALUE], $xx[self::SIGN], $z0, false); + + return $xx[self::VALUE]; + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + $this->value[0] |= 1; + } + + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value == [1]) { + return false; + } + if ($this->value == [2]) { + return true; + } + if (~$this->value[0] & 1) { + return false; + } + + $value = $this->value; + foreach (static::$primes as $prime) { + list(, $r) = self::divide_digit($value, $prime); + if (!$r) { + return count($value) == 1 && $value[0] == $prime; + } + } + + return true; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @see self::isPrime() + * @param PHP $r + * @return int + */ + public static function scan1divide(PHP $r) + { + $r_value = &$r->value; + for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { + $temp = ~$r_value[$i] & static::MAX_DIGIT; + for ($j = 1; ($temp >> $j) & 1; ++$j) { + } + if ($j <= static::BASE) { + break; + } + } + $s = static::BASE * $i + $j; + $r->rshift($s); + return $s; + } + + /** + * Performs exponentiation. + * + * @param PHP $n + * @return PHP + */ + protected function powHelper(PHP $n) + { + if ($n->compare(static::$zero) == 0) { + return new static(1); + } // n^0 = 1 + + $temp = clone $this; + while (!$n->equals(static::$one)) { + $temp = $temp->multiply($this); + $n = $n->subtract(static::$one); + } + + return $temp; + } + + /** + * Is Odd? + * + * @return boolean + */ + public function isOdd() + { + return (bool) ($this->value[0] & 1); + } + + /** + * Tests if a bit is set + * + * @return boolean + */ + public function testBit($x) + { + $digit = floor($x / static::BASE); + $bit = $x % static::BASE; + + if (!isset($this->value[$digit])) { + return false; + } + + return (bool) ($this->value[$digit] & (1 << $bit)); + } + + /** + * Is Negative? + * + * @return boolean + */ + public function isNegative() + { + return $this->is_negative; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return BigInteger + */ + public function negate() + { + $temp = clone $this; + $temp->is_negative = !$temp->is_negative; + + return $temp; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return \phpseclib3\Math\BigInteger\Engines\PHP[] + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + + $width = (int) ($split / static::BASE); + if (!$width) { + $arr = $this->bitwise_small_split($split); + return array_map(function ($digit) { + $temp = new static(); + $temp->value = $digit != 0 ? [$digit] : []; + return $temp; + }, $arr); + } + + $vals = []; + $val = $this->value; + + $i = $overflow = 0; + $len = count($val); + while ($i < $len) { + $digit = []; + if (!$overflow) { + $digit = array_slice($val, $i, $width); + $i+= $width; + $overflow = $split % static::BASE; + if ($overflow) { + $mask = (1 << $overflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $mask; + } + } else { + $remaining = static::BASE - $overflow; + $tempsplit = $split - $remaining; + $tempwidth = (int) ($tempsplit / static::BASE + 1); + $digit = array_slice($val, $i, $tempwidth); + $i+= $tempwidth; + $tempoverflow = $tempsplit % static::BASE; + if ($tempoverflow) { + $tempmask = (1 << $tempoverflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $tempmask; + } + $newbits = 0; + for ($j = count($digit) - 1; $j >= 0; $j--) { + $temp = $digit[$j] & $mask; + $digit[$j] = ($digit[$j] >> $overflow) | ($newbits << $remaining); + $newbits = $temp; + } + $overflow = $tempoverflow; + $mask = $tempmask; + } + $temp = new static(); + $temp->value = static::trim($digit); + $vals[] = $temp; + } + + return array_reverse($vals); + } + + /** + * Bitwise Split where $split < static::BASE + * + * @param int $split + * @return \phpseclib3\Math\BigInteger\Engines\PHP[] + */ + private function bitwise_small_split($split) + { + $vals = []; + $val = $this->value; + + $mask = (1 << $split) - 1; + + $i = $overflow = 0; + $len = count($val); + $val[] = 0; + $remaining = static::BASE; + while ($i != $len) { + $digit = $val[$i] & $mask; + $val[$i]>>= $split; + if (!$overflow) { + $remaining-= $split; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + + if (!$remaining) { + $i++; + $remaining = static::BASE; + $overflow = 0; + } + } else if (++$i != $len) { + $tempmask = (1 << $overflow) - 1; + $digit|= ($val[$i] & $tempmask) << $remaining; + $val[$i]>>= $overflow; + $remaining = static::BASE - $overflow; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + } + + $vals[] = $digit; + } + + while ($vals[count($vals) - 1] == 0) { + unset($vals[count($vals) - 1]); + } + + return array_reverse($vals); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php new file mode 100644 index 000000000..fb781c945 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php @@ -0,0 +1,149 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\PHP; + +/** + * PHP Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class Base extends PHP +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + * @access private + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + * @access private + */ + const DATA = 1; + + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * The most naive approach to modular exponentiation has very unreasonable requirements, and + * and although the approach involving repeated squaring does vastly better, it, too, is impractical + * for our purposes. The reason being that division - by far the most complicated and time-consuming + * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. + * + * Modular reductions resolve this issue. Although an individual modular reduction takes more time + * then an individual division, when performed in succession (with the same modulo), they're a lot faster. + * + * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, + * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the + * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because + * the product of two odd numbers is odd), but what about when RSA isn't used? + * + * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a + * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the + * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, + * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and + * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. + * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. + * + * @param \phpseclib3\Math\BigInteger\Engines\PHP $x + * @param \phpseclib3\Math\BigInteger\Engines\PHP $e + * @param \phpseclib3\Math\BigInteger\Engines\PHP $n + * @param string $class + * @return \phpseclib3\Math\BigInteger\Engines\PHP + */ + protected static function powModHelper(PHP $x, PHP $e, PHP $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = [1]; + return $x->normalize($temp); + } + + if ($e->value == [1]) { + list(, $temp) = $x->divide($n); + return $x->normalize($temp); + } + + if ($e->value == [2]) { + $temp = new $class; + $temp->value = $class::square($x->value); + list(, $temp) = $temp->divide($n); + return $x->normalize($temp); + } + + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + + /** + * Modular reduction preparation + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return static::reduce($x, $n, $class); + } + + /** + * Modular multiply + * + * @param array $x + * @param array $y + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function multiplyReduce(array $x, array $y, array $n, $class) + { + $temp = $class::multiplyHelper($x, false, $y, false); + return static::reduce($temp[self::VALUE], $n, $class); + } + + /** + * Modular square + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function squareReduce(array $x, array $n, $class) + { + return static::reduce($class::square($x), $n, $class); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php new file mode 100644 index 000000000..138deb1f6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php @@ -0,0 +1,29 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett; + +/** + * PHP Default Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class DefaultEngine extends EvalBarrett +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php new file mode 100644 index 000000000..0ebbd71a8 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php @@ -0,0 +1,93 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo; +use phpseclib3\Math\BigInteger\Engines\PHP; +use phpseclib3\Math\BigInteger\Engines\PHP\Base; +use phpseclib3\Math\BigInteger\Engines\Engine; + +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class Montgomery extends Base +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @param \phpseclib3\Math\BigInteger\Engines\Engine $x + * @param \phpseclib3\Math\BigInteger\Engines\Engine $e + * @param \phpseclib3\Math\BigInteger\Engines\Engine $n + * @param string $class + * @return \phpseclib3\Math\BigInteger\Engines\Engine + */ + protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) + { + // is the modulo odd? + if ($n->value[0] & 1) { + return parent::slidingWindow($x, $e, $n, $class); + } + // if it's not, it's even + + // find the lowest set bit (eg. the max pow of 2 that divides $n) + for ($i = 0; $i < count($n->value); ++$i) { + if ($n->value[$i]) { + $temp = decbin($n->value[$i]); + $j = strlen($temp) - strrpos($temp, '1') - 1; + $j+= $class::BASE * $i; + break; + } + } + // at this point, 2^$j * $n/(2^$j) == $n + + $mod1 = clone $n; + $mod1->rshift($j); + $mod2 = new $class(); + $mod2->value = [1]; + $mod2->lshift($j); + + $part1 = $mod1->value != [1] ? parent::slidingWindow($x, $e, $mod1, $class) : new $class(); + $part2 = PowerOfTwo::slidingWindow($x, $e, $mod2, $class); + + $y1 = $mod2->modInverse($mod1); + $y2 = $mod1->modInverse($mod2); + + $result = $part1->multiply($mod2); + $result = $result->multiply($y1); + + $temp = $part2->multiply($mod1); + $temp = $temp->multiply($y2); + + $result = $result->add($temp); + list(, $result) = $result->divide($n); + + return $result; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php new file mode 100644 index 000000000..1b7b5b401 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php @@ -0,0 +1,29 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class OpenSSL extends Progenitor +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php new file mode 100644 index 000000000..03e0f8aaa --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php @@ -0,0 +1,284 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class Barrett extends Base +{ + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param array $n + * @param array $m + * @param string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $m_length = count($m); + + // if (self::compareHelper($n, $static::square($m)) >= 0) { + if (count($n) > 2 * $m_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $n; + $rhs->value = $m; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m, $class); + } + // n = 2 * m.length + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + + $lhs = new $class(); + $lhs_value = &$lhs->value; + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $m; + + list($u, $m1) = $lhs->divide($rhs); + $u = $u->value; + $m1 = $m1->value; + + $cache[self::DATA][] = [ + 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1'=> $m1 // m.length + ]; + } else { + extract($cache[self::DATA][$key]); + } + + $cutoff = $m_length + ($m_length >> 1); + $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) + $msd = array_slice($n, $cutoff); // m.length >> 1 + + $lsd = self::trim($lsd); + $temp = $class::multiplyHelper($msd, false, $m1, false); // m.length + (m.length >> 1) + $n = $class::addHelper($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n[self::VALUE], $m, $class); + //} + + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = array_slice($n[self::VALUE], $m_length - 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = $class::multiplyHelper($temp, false, $u, false); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = $class::multiplyHelper($temp, false, $m, false); + + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + + $result = $class::subtractHelper($n[self::VALUE], false, $temp[self::VALUE], false); + + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $m, false); + } + + return $result[self::VALUE]; + } + + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + private static function regularBarrett(array $x, array $n, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $n_length = count($n); + + if (count($x) > 2 * $n_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $x; + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = new $class(); + $lhs_value = &$lhs->value; + $lhs_value = self::array_repeat(0, 2 * $n_length); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $n; + list($temp, ) = $lhs->divide($rhs); // m.length + $cache[self::DATA][] = $temp->value; + } + + // 2 * m.length - (m.length - 1) = m.length + 1 + $temp = array_slice($x, $n_length - 1); + // (m.length + 1) + m.length = 2 * m.length + 1 + $temp = $class::multiplyHelper($temp, false, $cache[self::DATA][$key], false); + // (2 * m.length + 1) - (m.length - 1) = m.length + 2 + $temp = array_slice($temp[self::VALUE], $n_length + 1); + + // m.length + 1 + $result = array_slice($x, 0, $n_length + 1); + // m.length + 1 + $temp = self::multiplyLower($temp, false, $n, false, $n_length + 1, $class); + // $temp == array_slice($class::regularMultiply($temp, false, $n, false)->value, 0, $n_length + 1) + + if (self::compareHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { + $corrector_value = self::array_repeat(0, $n_length + 1); + $corrector_value[count($corrector_value)] = 1; + $result = $class::addHelper($result, false, $corrector_value, false); + $result = $result[self::VALUE]; + } + + // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits + $result = $class::subtractHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]); + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Performs long multiplication up to $stop digits + * + * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. + * + * @see self::regularBarrett() + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @param int $stop + * @param string $class + * @return array + */ + private static function multiplyLower(array $x_value, $x_negative, array $y_value, $y_negative, $stop, $class) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + if ($x_length < $y_length) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_length = count($x_value); + $y_length = count($y_value); + } + + $product_value = self::array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int) ($temp - $class::BASE_FULL * $carry); + } + + if ($j < $stop) { + $product_value[$j] = $carry; + } + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int) ($temp - $class::BASE_FULL * $carry); + } + + if ($k < $stop) { + $product_value[$k] = $carry; + } + } + + return [ + self::VALUE => self::trim($product_value), + self::SIGN => $x_negative != $y_negative + ]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php new file mode 100644 index 000000000..aef167de9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php @@ -0,0 +1,46 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Classic Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class Classic extends Base +{ + /** + * Regular Division + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php new file mode 100644 index 000000000..7c81071da --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php @@ -0,0 +1,492 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; +use phpseclib3\Math\BigInteger\Engines\PHP; + +/** + * PHP Dynamic Barrett Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class EvalBarrett extends Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param array $n + * @param array $m + * @param string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + $inline = self::$custom_reduction; + return $inline($n); + } + + /** + * Generate Custom Reduction + * + * @param PHP $m + * @param string $class + * @return callable + */ + protected static function generateCustomReduction(PHP $m, $class) + { + if (isset($n->reduce)) { + self::$custom_reduction = $n->reduce; + return $n->reduce; + } + + $m_length = count($m->value); + + if ($m_length < 5) { + $code = ' + $lhs = new ' . $class . '(); + $lhs->value = $x; + $rhs = new ' . $class . '(); + $rhs->value = [' . + implode(',', array_map('self::float2string', $m->value)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + '; + eval('$func = function ($x) { ' . $code . '};'); + self::$custom_reduction = $func; + //self::$custom_reduction = \Closure::bind($func, $m, $class); + return $func; + } + + $lhs = new $class(); + $lhs_value = &$lhs->value; + + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + + list($u, $m1) = $lhs->divide($m); + + if ($class::BASE != 26) { + $u = $u->value; + } else { + $lhs_value = self::array_repeat(0, 2 * $m_length); + $lhs_value[] = 1; + $rhs = new $class(); + + list($u) = $lhs->divide($m); + $u = $u->value; + } + + $m = $m->value; + $m1 = $m1->value; + + $cutoff = count($m) + (count($m) >> 1); + + $code = ' + if (count($n) > ' . (2 * count($m)) . ') { + $lhs = new ' . $class . '(); + $rhs = new ' . $class . '(); + $lhs->value = $n; + $rhs->value = [' . + implode(',', array_map('self::float2string', $m)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + $lsd = array_slice($n, 0, ' . $cutoff . '); + $msd = array_slice($n, ' . $cutoff . ');'; + + $code.= self::generateInlineTrim('msd'); + $code.= self::generateInlineMultiply('msd', $m1, 'temp', $class); + $code.= self::generateInlineAdd('lsd', 'temp', 'n', $class); + + $code.= '$temp = array_slice($n, ' . (count($m) - 1) . ');'; + $code.= self::generateInlineMultiply('temp', $u, 'temp2', $class); + $code.= self::generateInlineTrim('temp2'); + + $code.= $class::BASE == 26 ? + '$temp = array_slice($temp2, ' . (count($m) + 1) . ');' : + '$temp = array_slice($temp2, ' . ((count($m) >> 1) + 1) . ');'; + $code.= self::generateInlineMultiply('temp', $m, 'temp2', $class); + $code.= self::generateInlineTrim('temp2'); + + /* + if ($class::BASE == 26) { + $code.= '$n = array_slice($n, 0, ' . (count($m) + 1) . '); + $temp2 = array_slice($temp2, 0, ' . (count($m) + 1) . ');'; + } + */ + + $code.= self::generateInlineSubtract2('n', 'temp2', 'temp', $class); + + $subcode = self::generateInlineSubtract1('temp', $m, 'temp2', $class); + $subcode.= '$temp = $temp2;'; + + $code.= self::generateInlineCompare($m, 'temp', $subcode); + + $code.= 'return $temp;'; + + eval('$func = function ($n) { ' . $code . '};'); + + self::$custom_reduction = $func; + + return $func; + + //self::$custom_reduction = \Closure::bind($func, $m, $class); + } + + /** + * Inline Trim + * + * Removes leading zeros + * + * @param string $name + * @return string + */ + private static function generateInlineTrim($name) + { + return ' + for ($i = count($' . $name . ') - 1; $i >= 0; --$i) { + if ($' . $name . '[$i]) { + break; + } + unset($' . $name . '[$i]); + }'; + } + + /** + * Inline Multiply (unknown, known) + * + * @param string $input + * @param array $arr + * @param string $output + * @param string $class + * @return string + */ + private static function generateInlineMultiply($input, array $arr, $output, $class) + { + if (!count($arr)) { + return 'return [];'; + } + + $regular = ' + $length = count($' . $input . '); + if (!$length) { + $' . $output . ' = []; + }else{ + $' . $output . ' = array_fill(0, $length + ' . count($arr) . ', 0); + $carry = 0;'; + + for ($i = 0; $i < count($arr); $i++) { + $regular.= ' + $subtemp = $' . $input . '[0] * ' . $arr[$i]; + $regular.= $i ? ' + $carry;' : ';'; + + $regular.= '$carry = '; + $regular.= $class::BASE === 26 ? + 'intval($subtemp / 0x4000000);' : + '$subtemp >> 31;'; + $regular.= + '$' . $output . '[' . $i . '] = '; + if ($class::BASE === 26) { + $regular.= '(int) ('; + } + $regular.= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular.= $class::BASE === 26 ? ');' : ';'; + } + + $regular.= '$' . $output . '[' . count($arr) . '] = $carry;'; + + $regular.= ' + for ($i = 1; $i < $length; ++$i) {'; + + for ($j = 0; $j < count($arr); $j++) { + $regular.= $j ? '$k++;' : '$k = $i;'; + $regular.= ' + $subtemp = $' . $output . '[$k] + $' . $input . '[$i] * ' . $arr[$j]; + $regular.= $j ? ' + $carry;' : ';'; + + $regular.= '$carry = '; + $regular.= $class::BASE === 26 ? + 'intval($subtemp / 0x4000000);' : + '$subtemp >> 31;'; + $regular.= + '$' . $output . '[$k] = '; + if ($class::BASE === 26) { + $regular.= '(int) ('; + } + $regular.= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular.= $class::BASE === 26 ? ');' : ';'; + } + + $regular.= '$' . $output. '[++$k] = $carry; $carry = 0;'; + + $regular.= '}}'; + + //if (count($arr) < 2 * self::KARATSUBA_CUTOFF) { + //} + + return $regular; + } + + /** + * Inline Addition + * + * @param string $x + * @param string $y + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineAdd($x, $y, $result, $class) + { + $code = ' + $length = max(count($' . $x . '), count($' . $y . ')); + $' . $result . ' = array_pad($' . $x . ', $length + 1, 0); + $_' . $y . ' = array_pad($' . $y . ', $length, 0); + $carry = 0; + for ($i = 0, $j = 1; $j < $length; $i+=2, $j+=2) { + $sum = ($' . $result . '[$j] + $_' . $y . '[$j]) * ' . $class::BASE_FULL . ' + + $' . $result . '[$i] + $_' . $y . '[$i] + + $carry; + $carry = $sum >= ' . self::float2string($class::MAX_DIGIT2) . '; + $sum = $carry ? $sum - ' . self::float2string($class::MAX_DIGIT2) . ' : $sum;'; + + $code.= $class::BASE === 26 ? + '$upper = intval($sum / 0x4000000); $' . $result . '[$i] = (int) ($sum - ' . $class::BASE_FULL . ' * $upper);' : + '$upper = $sum >> 31; $' . $result . '[$i] = $sum - ' . $class::BASE_FULL . ' * $upper;'; + $code.= ' + $' . $result . '[$j] = $upper; + } + if ($j == $length) { + $sum = $' . $result . '[$i] + $_' . $y . '[$i] + $carry; + $carry = $sum >= ' . self::float2string($class::BASE_FULL) . '; + $' . $result . '[$i] = $carry ? $sum - ' . self::float2string($class::BASE_FULL) . ' : $sum; + } + if ($carry) { + for (; $' . $result . '[$i] == ' . $class::MAX_DIGIT . '; ++$i) { + $' . $result . '[$i] = 0; + } + ++$' . $result . '[$i]; + }'; + $code.= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Subtraction 2 + * + * For when $known is more digits than $unknown. This is the harder use case to optimize for. + * + * @param string $known + * @param string $unknown + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract2($known, $unknown, $result, $class) + { + $code = ' + $' . $result .' = $' . $known . '; + $carry = 0; + $size = count($' . $unknown . '); + for ($i = 0, $j = 1; $j < $size; $i+= 2, $j+= 2) { + $sum = ($' . $known . '[$j] - $' . $unknown . '[$j]) * ' . $class::BASE_FULL . ' + $' . $known . '[$i] + - $' . $unknown . '[$i] + - $carry; + $carry = $sum < 0; + if ($carry) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code.= $class::BASE === 26 ? + 'intval($sum / 0x4000000);' : + '$sum >> 31;'; + $code.= '$' . $result . '[$i] = '; + if ($class::BASE === 26) { + $code.= '(int) ('; + } + $code.= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code.= ')'; + } + $code.= '; + $' . $result . '[$j] = $subtemp; + } + if ($j == $size) { + $sum = $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; + $carry = $sum < 0; + $' . $result . '[$i] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i; + } + + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + + $code.= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Subtraction 1 + * + * For when $unknown is more digits than $known. This is the easier use case to optimize for. + * + * @param string $unknown + * @param array $known + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract1($unknown, array $known, $result, $class) + { + $code = '$' . $result . ' = $' . $unknown . ';'; + for ($i = 0, $j = 1; $j < count($known); $i+=2, $j+=2) { + $code.= '$sum = $' . $unknown . '[' . $j . '] * ' . $class::BASE_FULL . ' + $' . $unknown . '[' . $i . '] - '; + $code.= self::float2string($known[$j] * $class::BASE_FULL + $known[$i]); + if ($i != 0) { + $code.= ' - $carry'; + } + + $code.= '; + if ($carry = $sum < 0) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code.= $class::BASE === 26 ? + 'intval($sum / 0x4000000);' : + '$sum >> 31;'; + $code.= ' + $' . $result . '[' . $i . '] = '; + if ($class::BASE === 26) { + $code.= ' (int) ('; + } + $code.= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code.= ')'; + } + $code.= '; + $' . $result . '[' . $j . '] = $subtemp;'; + } + + $code.= '$i = ' . $i . ';'; + + if ($j == count($known)) { + $code.= ' + $sum = $' . $unknown . '[' . $i . '] - ' . $known[$i] . ' - $carry; + $carry = $sum < 0; + $' . $result . '[' . $i . '] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i;'; + } + + $code.= ' + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + $code.= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Comparison + * + * If $unknown >= $known then loop + * + * @param array $known + * @param string $unknown + * @param string $subcode + * @return string + */ + private static function generateInlineCompare(array $known, $unknown, $subcode) + { + $uniqid = uniqid(); + $code = 'loop_' . $uniqid . ': + $clength = count($' . $unknown . '); + switch (true) { + case $clength < ' . count($known) . ': + goto end_' . $uniqid . '; + case $clength > ' . count($known) . ':'; + for ($i = count($known) - 1; $i >= 0; $i--) { + $code.= ' + case $' . $unknown . '[' . $i . '] > ' . $known[$i] . ': + goto subcode_' . $uniqid . '; + case $' . $unknown . '[' . $i . '] < ' . $known[$i] . ': + goto end_' . $uniqid . ';'; + } + $code.= ' + default: + // do subcode + } + + subcode_' . $uniqid . ':' . $subcode . ' + goto loop_' . $uniqid . '; + + end_' . $uniqid . ':'; + + return $code; + } + + /** + * Convert a float to a string + * + * If you do echo floatval(pow(2, 52)) you'll get 4.6116860184274E+18. It /can/ be displayed without a loss of + * precision but displayed in this way there will be precision loss, hence the need for this method. + * + * @param int|float $num + * @return string + */ + private static function float2string($num) + { + if (!is_float($num)) { + return $num; + } + + if ($num < 0) { + return '-' . self::float2string(abs($num)); + } + + $temp = ''; + while ($num) { + $temp = fmod($num, 10) . $temp; + $num = floor($num / 10); + } + + return $temp; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php new file mode 100644 index 000000000..79db314d6 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php @@ -0,0 +1,130 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Montgomery as Progenitor; + +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class Montgomery extends Progenitor +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = array_merge(self::array_repeat(0, count($n)), $x); + $rhs = new $class(); + $rhs->value = $n; + + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $x; + $cache[self::DATA][] = self::modInverse67108864($n, $class); + } + + $k = count($n); + + $result = [self::VALUE => $x]; + + for ($i = 0; $i < $k; ++$i) { + $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $class::regularMultiply([$temp], $n); + $temp = array_merge(self::array_repeat(0, $i), $temp); + $result = $class::addHelper($result[self::VALUE], false, $temp, false); + } + + $result[self::VALUE] = array_slice($result[self::VALUE], $k); + + if (self::compareHelper($result, false, $n, false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], false, $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Modular Inverse of a number mod 2**26 (eg. 67108864) + * + * Based off of the bnpInvDigit function implemented and justified in the following URL: + * + * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} + * + * The following URL provides more info: + * + * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} + * + * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For + * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields + * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't + * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that + * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the + * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to + * 40 bits, which only 64-bit floating points will support. + * + * Thanks to Pedro Gimeno Fortea for input! + * + * @param array $x + * @param string $class + * @return int + */ + protected static function modInverse67108864(array $x, $class) // 2**26 == 67,108,864 + { + $x = -$x[0]; + $result = $x & 0x3; // x**-1 mod 2**2 + $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 + $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 + $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 + $result = $class::BASE == 26 ? + fmod($result * (2 - fmod($x * $result, $class::BASE_FULL)), $class::BASE_FULL) : // x**-1 mod 2**26 + ($result * (2 - ($x * $result) % $class::BASE_FULL)) % $class::BASE_FULL; + return $result & $class::MAX_DIGIT; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php new file mode 100644 index 000000000..31e8af211 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php @@ -0,0 +1,81 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class MontgomeryMult extends Montgomery +{ + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @see self::_prepMontgomery() + * @see self::_montgomery() + * @access private + * @param array $x + * @param array $y + * @param array $m + * @param string $class + * @return array + */ + public static function multiplyReduce(array $x, array $y, array $m, $class) + { + // the following code, although not callable, can be run independently of the above code + // although the above code performed better in my benchmarks the following could might + // perform better under different circumstances. in lieu of deleting it it's just been + // made uncallable + + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + $cache[self::DATA][] = self::modInverse67108864($m, $class); + } + + $n = max(count($x), count($y), count($m)); + $x = array_pad($x, $n, 0); + $y = array_pad($y, $n, 0); + $m = array_pad($m, $n, 0); + $a = [self::VALUE => self::array_repeat(0, $n + 1)]; + for ($i = 0; $i < $n; ++$i) { + $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $temp * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $class::addHelper($class::regularMultiply([$x[$i]], $y), false, $class::regularMultiply([$temp], $m), false); + $a = $class::addHelper($a[self::VALUE], false, $temp[self::VALUE], false); + $a[self::VALUE] = array_slice($a[self::VALUE], 1); + } + if (self::compareHelper($a[self::VALUE], false, $m, false) >= 0) { + $a = $class::subtractHelper($a[self::VALUE], false, $m, false); + } + return $a[self::VALUE]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php new file mode 100644 index 000000000..73f133d06 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php @@ -0,0 +1,63 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Power Of Two Modular Exponentiation Engine + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +abstract class PowerOfTwo extends Base +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return self::reduce($x, $n, $class); + } + + /** + * Power Of Two Reduction + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + + $temp = new $class(); + $temp->value = [1]; + + $result = $lhs->bitwise_and($rhs->subtract($temp)); + return $result->value; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php new file mode 100644 index 000000000..a1b4a7a50 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -0,0 +1,418 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use ParagonIE\ConstantTime\Hex; + +/** + * Pure-PHP 32-bit Engine. + * + * Uses 64-bit floats if int size is 4 bits + * + * @package PHP32 + * @author Jim Wigginton + * @access public + */ +class PHP32 extends PHP +{ + // Constants used by PHP.php + const BASE = 26; + const BASE_FULL = 0x4000000; + const MAX_DIGIT = 0x3FFFFFF; + const MSB = 0x2000000; + + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 10000000; + + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 7; + const MAX_DIGIT2 = 4503599627370496; + /**#@-*/ + + /** + * Modular Exponentiation Engine + * + * @var string + */ + protected static $modexpEngine; + + /** + * Engine Validity Flag + * + * @var bool + */ + protected static $isValidEngine; + + /** + * Primes > 2 and < 1000 + * + * @var array + */ + protected static $primes; + + /** + * BigInteger(0) + * + * @var \phpseclib3\Math\BigInteger\Engines\PHP32 + */ + protected static $zero; + + /** + * BigInteger(1) + * + * @var \phpseclib3\Math\BigInteger\Engines\PHP32 + */ + protected static $one; + + /** + * BigInteger(2) + * + * @var \phpseclib3\Math\BigInteger\Engines\PHP32 + */ + protected static $two; + + /** + * Initialize a PHP32 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + + $val = $this->value; + $this->value = []; + $vals = &$this->value; + $i = strlen($val); + if (!$i) { + return; + } + + while (true) { + $i-= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = substr($val, 0, 4 + $i); + $val = str_pad($val, 4, "\0", STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = unpack('N', substr($val, $i, 4)); + $step = count($vals) & 3; + if ($step) { + $digit>>= 2 * $step; + } + if ($step != 3) { + $digit&= static::MAX_DIGIT; + $i++; + } + $vals[] = $digit; + } + while (end($vals) === 0) { + array_pop($vals); + } + reset($vals); + } + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return PHP_INT_SIZE >= 4; + } + + /** + * Adds two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function add(PHP32 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function subtract(PHP32 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function multiply(PHP32 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP32 $y + * @return PHP32 + */ + public function divide(PHP32 $y) + { + return $this->divideHelper($y); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return false|PHP32 + */ + public function modInverse(PHP32 $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return PHP32[] + */ + public function extendedGCD(PHP32 $n) + { + return $this->extendedGCDHelper($n); + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP32 $n + * @return PHP32 + */ + public function gcd(PHP32 $n) + { + return $this->extendedGCD($n)['gcd']; + } + + /** + * Logical And + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_and(PHP32 $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_or(PHP32 $x) + { + return $this->bitwiseOrHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_xor(PHP32 $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP32 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @access public + * @see self::equals() + */ + public function compare(PHP32 $y) + { + return $this->compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP32 $x + * @return bool + */ + public function equals(PHP32 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + + /** + * Performs modular exponentiation. + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function modPow(PHP32 $e, PHP32 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function powMod(PHP32 $e, PHP32 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP32 $min + * @param PHP32 $max + * @return false|PHP32 + */ + public static function randomRangePrime(PHP32 $min, PHP32 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP32 $min + * @param PHP32 $max + * @return PHP32 + */ + public static function randomRange(PHP32 $min, PHP32 $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Performs exponentiation. + * + * @param PHP32 $n + * @return PHP32 + */ + public function pow(PHP32 $n) + { + return $this->powHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function min(PHP32 ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function max(PHP32 ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP32 $min + * @param PHP32 $max + * @return bool + */ + public function between(PHP32 $min, PHP32 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php new file mode 100644 index 000000000..42d1982d9 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php @@ -0,0 +1,422 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use ParagonIE\ConstantTime\Hex; + +/** + * Pure-PHP 64-bit Engine. + * + * Uses 64-bit integers if int size is 8 bits + * + * @package PHP + * @author Jim Wigginton + * @access public + */ +class PHP64 extends PHP +{ + // Constants used by PHP.php + const BASE = 31; + const BASE_FULL = 0x80000000; + const MAX_DIGIT = 0x7FFFFFFF; + const MSB = 0x40000000; + + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 1000000000; + + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 9; + const MAX_DIGIT2 = 4611686018427387904; + /**#@-*/ + + /** + * Modular Exponentiation Engine + * + * @var string + */ + protected static $modexpEngine; + + /** + * Engine Validity Flag + * + * @var bool + */ + protected static $isValidEngine; + + /** + * Primes > 2 and < 1000 + * + * @var array + */ + protected static $primes; + + /** + * BigInteger(0) + * + * @var \phpseclib3\Math\BigInteger\Engines\PHP64 + */ + protected static $zero; + + /** + * BigInteger(1) + * + * @var \phpseclib3\Math\BigInteger\Engines\PHP64 + */ + protected static $one; + + /** + * BigInteger(2) + * + * @var \phpseclib3\Math\BigInteger\Engines\PHP64 + */ + protected static $two; + + /** + * Initialize a PHP64 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + + $val = $this->value; + $this->value = []; + $vals = &$this->value; + $i = strlen($val); + if (!$i) { + return; + } + + while (true) { + $i-= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = substr($val, 0, 4 + $i); + $val = str_pad($val, 4, "\0", STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = unpack('N', substr($val, $i, 4)); + $step = count($vals) & 7; + if (!$step) { + $digit&= static::MAX_DIGIT; + $i++; + } else { + $shift = 8 - $step; + $digit>>= $shift; + $shift = 32 - $shift; + $digit&= (1 << $shift) - 1; + $temp = $i > 0 ? ord($val[$i - 1]) : 0; + $digit|= ($temp << $shift) & 0x7F000000; + } + $vals[] = $digit; + } + while (end($vals) === 0) { + array_pop($vals); + } + reset($vals); + } + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return PHP_INT_SIZE >= 8; + } + + /** + * Adds two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function add(PHP64 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function subtract(PHP64 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function multiply(PHP64 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP64 $y + * @return PHP64 + */ + public function divide(PHP64 $y) + { + return $this->divideHelper($y); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return false|PHP64 + */ + public function modInverse(PHP64 $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return PHP64[] + */ + public function extendedGCD(PHP64 $n) + { + return $this->extendedGCDHelper($n); + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP64 $n + * @return PHP64 + */ + public function gcd(PHP64 $n) + { + return $this->extendedGCD($n)['gcd']; + } + + /** + * Logical And + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_and(PHP64 $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_or(PHP64 $x) + { + return $this->bitwiseOrHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_xor(PHP64 $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP64 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @access public + * @see self::equals() + */ + public function compare(PHP64 $y) + { + return parent::compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP64 $x + * @return bool + */ + public function equals(PHP64 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + + /** + * Performs modular exponentiation. + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64 + */ + public function modPow(PHP64 $e, PHP64 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64 + */ + public function powMod(PHP64 $e, PHP64 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP64 $min + * @param PHP64 $max + * @return false|PHP64 + */ + public static function randomRangePrime(PHP64 $min, PHP64 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP64 $min + * @param PHP64 $max + * @return PHP64 + */ + public static function randomRange(PHP64 $min, PHP64 $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Performs exponentiation. + * + * @param PHP64 $n + * @return PHP64 + */ + public function pow(PHP64 $n) + { + return $this->powHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function min(PHP64 ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function max(PHP64 ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP64 $min + * @param PHP64 $max + * @return bool + */ + public function between(PHP64 $min, PHP64 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php new file mode 100644 index 000000000..7457b720f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php @@ -0,0 +1,196 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math; + +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Math\Common\FiniteField; +use phpseclib3\Math\BinaryField\Integer; +use phpseclib3\Common\Functions\Strings; + +/** + * Binary Finite Fields + * + * @package Math + * @author Jim Wigginton + * @access public + */ +class BinaryField extends FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Default constructor + */ + public function __construct(...$indices) + { + $m = array_shift($indices); + $val = str_repeat('0', $m) . '1'; + foreach ($indices as $index) { + $val[$index] = '1'; + } + $modulo = static::base2ToBase256(strrev($val)); + + $mStart = 2 * $m - 2; + $t = ceil($m / 8); + $finalMask = chr((1 << ($m % 8)) - 1); + if ($finalMask == "\0") { + $finalMask = "\xFF"; + } + $bitLen = $mStart + 1; + $pad = ceil($bitLen / 8); + $h = $bitLen & 7; + $h = $h ? 8 - $h : 0; + + $r = rtrim(substr($val, 0, -1), '0'); + $u = [static::base2ToBase256(strrev($r))]; + for ($i = 1; $i < 8; $i++) { + $u[] = static::base2ToBase256(strrev(str_repeat('0', $i) . $r)); + } + + // implements algorithm 2.40 (in section 2.3.5) in "Guide to Elliptic Curve Cryptography" + // with W = 8 + $reduce = function($c) use ($u, $mStart, $m, $t, $finalMask, $pad, $h) { + $c = str_pad($c, $pad, "\0", STR_PAD_LEFT); + for ($i = $mStart; $i >= $m;) { + $g = $h >> 3; + $mask = $h & 7; + $mask = $mask ? 1 << (7 - $mask) : 0x80; + for (; $mask > 0; $mask >>= 1, $i--, $h++) { + if (ord($c[$g]) & $mask) { + $temp = $i - $m; + $j = $temp >> 3; + $k = $temp & 7; + $t1 = $j ? substr($c, 0, -$j) : $c; + $length = strlen($t1); + if ($length) { + $t2 = str_pad($u[$k], $length, "\0", STR_PAD_LEFT); + $temp = $t1 ^ $t2; + $c = $j ? substr_replace($c, $temp, 0, $length) : $temp; + } + } + } + } + $c = substr($c, -$t); + if (strlen($c) == $t) { + $c[0] = $c[0] & $finalMask; + } + return ltrim($c, "\0"); + }; + + $this->instanceID = self::$instanceCounter++; + Integer::setModulo($this->instanceID, $modulo); + Integer::setRecurringModuloFunction($this->instanceID, $reduce); + + $this->randomMax = new BigInteger($modulo, 2); + } + + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @param string $num + * @return object + */ + public function newInteger($num) + { + return new Integer($this->instanceID, $num instanceof BigInteger ? $num->toBytes() : $num); + } + + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return object + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return new Integer($this->instanceID, BigInteger::randomRange($one, $this->randomMax)->toBytes()); + } + + /** + * Returns the length of the modulo in bytes + * + * @return integer + */ + public function getLengthInBytes() + { + return strlen(Integer::getModulo($this->instanceID)); + } + + /** + * Returns the length of the modulo in bits + * + * @return integer + */ + public function getLength() + { + return strlen(Integer::getModulo($this->instanceID)) << 3; + } + + /** + * Converts a base-2 string to a base-256 string + * + * @param string $x + * @param integer $size + * @return string + */ + public static function base2ToBase256($x, $size = null) + { + $str = Strings::bits2bin($x); + + $pad = strlen($x) >> 3; + if (strlen($x) & 3) { + $pad++; + } + $str = str_pad($str, $pad, "\0", STR_PAD_LEFT); + if (isset($size)) { + $str = str_pad($str, $size, "\0", STR_PAD_LEFT); + } + + return $str; + } + + /** + * Converts a base-256 string to a base-2 string + * + * @param string $x + * @return string + */ + public static function base256ToBase2($x) + { + if (function_exists('gmp_import')) { + return gmp_strval(gmp_import($x), 2); + } + + return Strings::bin2bits($x); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php new file mode 100644 index 000000000..fc7a11ad2 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php @@ -0,0 +1,520 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\BinaryField; + +use phpseclib3\Math\Common\FiniteField\Integer as Base; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use ParagonIE\ConstantTime\Hex; + +/** + * Binary Finite Fields + * + * @package Math + * @author Jim Wigginton + * @access public + */ +class Integer extends Base +{ + /** + * Holds the BinaryField's value + * + * @var string + */ + protected $value; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Holds the PrimeField's modulo + * + * @var string[] + */ + protected static $modulo; + + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var callable[] + */ + protected static $reduce; + + /** + * Default constructor + */ + public function __construct($instanceID, $num = '') + { + $this->instanceID = $instanceID; + if (!strlen($num)) { + $this->value = ''; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + + /** + * Set the modulo for a given instance + */ + public static function setModulo($instanceID, $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + + /** + * Set the modulo for a given instance + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + } + + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + */ + private static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match'); + } + } + + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + + return $this->value == $x->value; + } + + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + + $a = $this->value; + $b = $x->value; + + $length = max(strlen($a), strlen($b)); + + $a = str_pad($a, $length, "\0", STR_PAD_LEFT); + $b = str_pad($b, $length, "\0", STR_PAD_LEFT); + + return strcmp($a, $b); + } + + /** + * Returns the degree of the polynomial + * + * @param string $x + * @return int + */ + private static function deg($x) + { + $x = ltrim($x, "\0"); + $xbit = decbin(ord($x[0])); + $xlen = $xbit == '0' ? 0 : strlen($xbit); + $len = strlen($x); + if (!$len) { + return -1; + } + return 8 * strlen($x) - 9 + $xlen; + } + + /** + * Perform polynomial division + * + * @return string[] + * @link https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclidean_division + */ + private static function polynomialDivide($x, $y) + { + // in wikipedia's description of the algorithm, lc() is the leading coefficient. over a binary field that's + // always going to be 1. + + $q = chr(0); + $d = static::deg($y); + $r = $x; + while (($degr = static::deg($r)) >= $d) { + $s = '1' . str_repeat('0', $degr - $d); + $s = BinaryField::base2ToBase256($s); + $length = max(strlen($s), strlen($q)); + $q = !isset($q) ? $s : + str_pad($q, $length, "\0", STR_PAD_LEFT) ^ + str_pad($s, $length, "\0", STR_PAD_LEFT); + $s = static::polynomialMultiply($s, $y); + $length = max(strlen($r), strlen($s)); + $r = str_pad($r, $length, "\0", STR_PAD_LEFT) ^ + str_pad($s, $length, "\0", STR_PAD_LEFT); + } + + return [ltrim($q, "\0"), ltrim($r, "\0")]; + } + + /** + * Perform polynomial multiplation in the traditional way + * + * @return string + * @link https://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplication + */ + private static function regularPolynomialMultiply($x, $y) + { + $precomputed = [ltrim($x, "\0")]; + $x = strrev(BinaryField::base256ToBase2($x)); + $y = strrev(BinaryField::base256ToBase2($y)); + if (strlen($x) == strlen($y)) { + $length = strlen($x); + } else { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, '0'); + $y = str_pad($y, $length, '0'); + } + $result = str_repeat('0', 2 * $length - 1); + $result = BinaryField::base2ToBase256($result); + $size = strlen($result); + $x = strrev($x); + + // precompute left shift 1 through 7 + for ($i = 1; $i < 8; $i++) { + $precomputed[$i] = BinaryField::base2ToBase256($x . str_repeat('0', $i)); + } + for ($i = 0; $i < strlen($y); $i++) { + if ($y[$i] == '1') { + $temp = $precomputed[$i & 7] . str_repeat("\0", $i >> 3); + $result^= str_pad($temp, $size, "\0", STR_PAD_LEFT); + } + } + + return $result; + } + + /** + * Perform polynomial multiplation + * + * Uses karatsuba multiplication to reduce x-bit multiplications to a series of 32-bit multiplications + * + * @return string + * @link https://en.wikipedia.org/wiki/Karatsuba_algorithm + */ + private static function polynomialMultiply($x, $y) + { + if (strlen($x) == strlen($y)) { + $length = strlen($x); + } else { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + } + + switch (true) { + case PHP_INT_SIZE == 8 && $length <= 4: + return $length != 4 ? + self::subMultiply(str_pad($x, 4, "\0", STR_PAD_LEFT), str_pad($y, 4, "\0", STR_PAD_LEFT)) : + self::subMultiply($x, $y); + case PHP_INT_SIZE == 4 || $length > 32: + return self::regularPolynomialMultiply($x, $y); + } + + $m = $length >> 1; + + $x1 = substr($x, 0, -$m); + $x0 = substr($x, -$m); + $y1 = substr($y, 0, -$m); + $y0 = substr($y, -$m); + + $z2 = self::polynomialMultiply($x1, $y1); + $z0 = self::polynomialMultiply($x0, $y0); + $z1 = self::polynomialMultiply( + self::subAdd2($x1, $x0), + self::subAdd2($y1, $y0) + ); + + $z1 = self::subAdd3($z1, $z2, $z0); + + $xy = self::subAdd3( + $z2 . str_repeat("\0", 2 * $m), + $z1 . str_repeat("\0", $m), + $z0 + ); + + return ltrim($xy, "\0"); + } + + /** + * Perform polynomial multiplication on 2x 32-bit numbers, returning + * a 64-bit number + * + * @param string $x + * @param string $y + * @return string + * @link https://www.bearssl.org/constanttime.html#ghash-for-gcm + */ + private static function subMultiply($x, $y) + { + $x = unpack('N', $x)[1]; + $y = unpack('N', $y)[1]; + + $x0 = $x & 0x11111111; + $x1 = $x & 0x22222222; + $x2 = $x & 0x44444444; + $x3 = $x & 0x88888888; + + $y0 = $y & 0x11111111; + $y1 = $y & 0x22222222; + $y2 = $y & 0x44444444; + $y3 = $y & 0x88888888; + + $z0 = ($x0 * $y0) ^ ($x1 * $y3) ^ ($x2 * $y2) ^ ($x3 * $y1); + $z1 = ($x0 * $y1) ^ ($x1 * $y0) ^ ($x2 * $y3) ^ ($x3 * $y2); + $z2 = ($x0 * $y2) ^ ($x1 * $y1) ^ ($x2 * $y0) ^ ($x3 * $y3); + $z3 = ($x0 * $y3) ^ ($x1 * $y2) ^ ($x2 * $y1) ^ ($x3 * $y0); + + $z0&= 0x1111111111111111; + $z1&= 0x2222222222222222; + $z2&= 0x4444444444444444; + $z3&= -8608480567731124088; // 0x8888888888888888 gets interpreted as a float + + $z = $z0 | $z1 | $z2 | $z3; + + return pack('J', $z); + } + + /** + * Adds two numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd2($x, $y) + { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + return $x ^ $y; + } + + /** + * Adds three numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd3($x, $y, $z) + { + $length = max(strlen($x), strlen($y), strlen($z)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + $z = str_pad($z, $length, "\0", STR_PAD_LEFT); + return $x ^ $y ^ $z; + } + + /** + * Adds two BinaryFieldIntegers. + * + * @return static + */ + public function add(self $y) + { + static::checkInstance($this, $y); + + $length = strlen(static::$modulo[$this->instanceID]); + + $x = str_pad($this->value, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y->value, $length, "\0", STR_PAD_LEFT); + + return new static($this->instanceID, $x ^ $y); + } + + /** + * Subtracts two BinaryFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + return $this->add($x); + } + + /** + * Multiplies two BinaryFieldIntegers. + * + * @return static + */ + public function multiply(self $y) + { + static::checkInstance($this, $y); + + return new static($this->instanceID, static::polynomialMultiply($this->value, $y->value)); + } + + /** + * Returns the modular inverse of a BinaryFieldInteger + * + * @return static + */ + public function modInverse() + { + $remainder0 = static::$modulo[$this->instanceID]; + $remainder1 = $this->value; + + if ($remainder1 == '') { + return new static($this->instanceID); + } + + $aux0 = "\0"; + $aux1 = "\1"; + while ($remainder1 != "\1") { + list($q, $r) = static::polynomialDivide($remainder0, $remainder1); + $remainder0 = $remainder1; + $remainder1 = $r; + // the auxiliary in row n is given by the sum of the auxiliary in + // row n-2 and the product of the quotient and the auxiliary in row + // n-1 + $temp = static::polynomialMultiply($aux1, $q); + $aux = str_pad($aux0, strlen($temp), "\0", STR_PAD_LEFT) ^ + str_pad($temp, strlen($aux0), "\0", STR_PAD_LEFT); + $aux0 = $aux1; + $aux1 = $aux; + } + + $temp = new static($this->instanceID); + $temp->value = ltrim($aux1, "\0"); + return $temp; + } + + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + + $x = $x->modInverse(); + return $this->multiply($x); + } + + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return object + */ + public function negate() + { + $x = str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); + + return new static($this->instanceID, $x ^ static::$modulo[$this->instanceID]); + } + + /** + * Returns the modulo + * + * @return integer + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + return str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return Hex::encode($this->toBytes()); + } + + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + //return str_pad(BinaryField::base256ToBase2($this->value), strlen(static::$modulo[$this->instanceID]), '0', STR_PAD_LEFT); + return BinaryField::base256ToBase2($this->value); + } + + /** + * Converts an Integer to a BigInteger + * + * @return string + */ + public function toBigInteger() + { + return new BigInteger($this->value, 256); + } + + /** + * __toString() magic method + * + * @access public + */ + public function __toString() + { + return (string) $this->toBigInteger(); + } + + /** + * __debugInfo() magic method + * + * @access public + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php b/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php new file mode 100644 index 000000000..c2294a04c --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\Common; + +/** + * Finite Fields + * + * @package Math + * @author Jim Wigginton + * @access public + */ +abstract class FiniteField +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php b/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php new file mode 100644 index 000000000..d163f5523 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\Common\FiniteField; + +/** + * Finite Field Integer + * + * @package Math + * @author Jim Wigginton + * @access public + */ +abstract class Integer +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php b/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php new file mode 100644 index 000000000..6b85c7247 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php @@ -0,0 +1,114 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math; + +use phpseclib3\Math\Common\FiniteField; +use phpseclib3\Math\PrimeField\Integer; + +/** + * Prime Finite Fields + * + * @package Math + * @author Jim Wigginton + * @access public + */ +class PrimeField extends FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Default constructor + */ + public function __construct(BigInteger $modulo) + { + //if (!$modulo->isPrime()) { + // throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); + //} + + $this->modulo = $modulo; + + $this->instanceID = self::$instanceCounter++; + Integer::setModulo($this->instanceID, $modulo); + Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); + } + + /** + * Use a custom defined modular reduction function + */ + public function setReduction(callable $func) + { + $this->reduce = $func->bindTo($this, $this); + } + + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @return object + */ + public function newInteger(BigInteger $num) + { + return new Integer($this->instanceID, $num); + } + + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return object + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return new Integer($this->instanceID, BigInteger::randomRange($one, Integer::getModulo($this->instanceID))); + } + + /** + * Returns the length of the modulo in bytes + * + * @return integer + */ + public function getLengthInBytes() + { + return Integer::getModulo($this->instanceID)->getLengthInBytes(); + } + + /** + * Returns the length of the modulo in bits + * + * @return integer + */ + public function getLength() + { + return Integer::getModulo($this->instanceID)->getLength(); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php new file mode 100644 index 000000000..c274ff641 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php @@ -0,0 +1,399 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\PrimeField; + +use phpseclib3\Math\Common\FiniteField\Integer as Base; +use phpseclib3\Math\BigInteger; +use ParagonIE\ConstantTime\Hex; + +/** + * Prime Finite Fields + * + * @package Math + * @author Jim Wigginton + * @access public + */ +class Integer extends Base +{ + /** + * Holds the PrimeField's value + * + * @var \phpseclib3\Math\BigInteger + */ + protected $value; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Holds the PrimeField's modulo + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $modulo; + + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var Callable + */ + protected static $reduce; + + /** + * Zero + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $zero; + + /** + * Default constructor + */ + public function __construct($instanceID, BigInteger $num = null) + { + $this->instanceID = $instanceID; + if (!isset($num)) { + $this->value = clone static::$zero; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + + /** + * Set the modulo for a given instance + */ + public static function setModulo($instanceID, BigInteger $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + + /** + * Set the modulo for a given instance + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + if (!isset(static::$zero)) { + static::$zero = new BigInteger(); + } + } + + /** + * Returns the modulo + * + * @return integer + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + */ + public static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match'); + } + } + + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + + return $this->value->equals($x->value); + } + + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + + return $this->value->compare($x->value); + } + + /** + * Adds two PrimeFieldIntegers. + * + * @return static + */ + public function add(self $x) + { + static::checkInstance($this, $x); + + $temp = new static($this->instanceID); + $temp->value = $this->value->add($x->value); + if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) { + $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]); + } + + return $temp; + } + + /** + * Subtracts two PrimeFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + static::checkInstance($this, $x); + + $temp = new static($this->instanceID); + $temp->value = $this->value->subtract($x->value); + if ($temp->value->isNegative()) { + $temp->value = $temp->value->add(static::$modulo[$this->instanceID]); + } + + return $temp; + } + + /** + * Multiplies two PrimeFieldIntegers. + * + * @return static + */ + public function multiply(self $x) + { + static::checkInstance($this, $x); + + return new static($this->instanceID, $this->value->multiply($x->value)); + } + + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + + $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]); + return new static($this->instanceID, $this->value->multiply($denominator)); + } + + /** + * Performs power operation on a PrimeFieldInteger. + * + * @return static + */ + public function pow(BigInteger $x) + { + $temp = new static($this->instanceID); + $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]); + + return $temp; + } + + /** + * Calculates the square root + * + * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm + * @return static|false + */ + public function squareRoot() + { + static $one, $two; + if (!isset($one)) { + $one = new BigInteger(1); + $two = new BigInteger(2); + } + $reduce = static::$reduce[$this->instanceID]; + $p_1 = static::$modulo[$this->instanceID]->subtract($one); + $q = clone $p_1; + $s = BigInteger::scan1divide($q); + list($pow) = $p_1->divide($two); + for ($z = $one; !$z->equals(static::$modulo[$this->instanceID]); $z = $z->add($one)) { + $temp = $z->powMod($pow, static::$modulo[$this->instanceID]); + if ($temp->equals($p_1)) { + break; + } + } + + $m = new BigInteger($s); + $c = $z->powMod($q, static::$modulo[$this->instanceID]); + $t = $this->value->powMod($q, static::$modulo[$this->instanceID]); + list($temp) = $q->add($one)->divide($two); + $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]); + + while (!$t->equals($one)) { + $i = clone $one; + + while (!$t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) { + $i = $i->add($one); + } + + if ($i->compare($m) >= 0) { + return false; + } + $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), static::$modulo[$this->instanceID]); + $m = $i; + $c = $reduce($b->multiply($b)); + $t = $reduce($t->multiply($c)); + $r = $reduce($r->multiply($b)); + } + + return new static($this->instanceID, $r); + } + + /** + * Is Odd? + * + * @return boolean + */ + public function isOdd() + { + return $this->value->isOdd(); + } + + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return object + */ + public function negate() + { + return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value)); + } + + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + $length = static::$modulo[$this->instanceID]->getLengthInBytes(); + return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return Hex::encode($this->toBytes()); + } + + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + // return $this->value->toBits(); + static $length; + if (!isset($length)) { + $length = static::$modulo[$this->instanceID]->getLength(); + } + + return str_pad($this->value->toBits(), $length, '0', STR_PAD_LEFT); + } + + /** + * Returns the w-ary non-adjacent form (wNAF) + * + * @param int $w optional + * @return int[] + */ + public function getNAF($w = 1) + { + $w++; + + $mask = new BigInteger((1 << $w) - 1); + $sub = new BigInteger(1 << $w); + //$sub = new BigInteger(1 << ($w - 1)); + $d = $this->toBigInteger(); + $d_i = []; + + $i = 0; + while ($d->compare(static::$zero) > 0) { + if ($d->isOdd()) { + // start mods + $d_i[$i] = $d->testBit($w - 1) ? + $d->bitwise_and($mask)->subtract($sub) : + //$sub->subtract($d->bitwise_and($mask)) : + $d->bitwise_and($mask); + // end mods + $d = $d->subtract($d_i[$i]); + $d_i[$i] = (int) $d_i[$i]->toString(); + } else { + $d_i[$i] = 0; + } + $shift = !$d->equals(static::$zero) && $d->bitwise_and($mask)->equals(static::$zero) ? $w : 1; // $w or $w + 1? + $d = $d->bitwise_rightShift($shift); + while (--$shift > 0) { + $d_i[++$i] = 0; + } + $i++; + } + + return $d_i; + } + + /** + * Converts an Integer to a BigInteger + * + * @return string + */ + public function toBigInteger() + { + return clone $this->value; + } + + /** + * __toString() magic method + * + * @access public + */ + public function __toString() + { + return (string) $this->value; + } + + /** + * __debugInfo() magic method + * + * @access public + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php new file mode 100644 index 000000000..c04fe7e68 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php @@ -0,0 +1,3134 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $sftp->pwd() . "\r\n"; + * $sftp->put('filename.ext', 'hello, world!'); + * print_r($sftp->nlist()); + * ?> + * + * + * @category Net + * @package SFTP + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Net; + +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Exception\FileNotFoundException; +use phpseclib3\Common\Functions\Strings; + +/** + * Pure-PHP implementations of SFTP. + * + * @package SFTP + * @author Jim Wigginton + * @access public + */ +class SFTP extends SSH2 +{ + /** + * SFTP channel constant + * + * \phpseclib3\Net\SSH2::exec() uses 0 and \phpseclib3\Net\SSH2::read() / \phpseclib3\Net\SSH2::write() use 1. + * + * @see \phpseclib3\Net\SSH2::send_channel_packet() + * @see \phpseclib3\Net\SSH2::get_channel_packet() + * @access private + */ + const CHANNEL = 0x100; + + /** + * Reads data from a local file. + * + * @access public + * @see \phpseclib3\Net\SFTP::put() + */ + const SOURCE_LOCAL_FILE = 1; + /** + * Reads data from a string. + * + * @access public + * @see \phpseclib3\Net\SFTP::put() + */ + // this value isn't really used anymore but i'm keeping it reserved for historical reasons + const SOURCE_STRING = 2; + /** + * Reads data from callback: + * function callback($length) returns string to proceed, null for EOF + * + * @access public + * @see \phpseclib3\Net\SFTP::put() + */ + const SOURCE_CALLBACK = 16; + /** + * Resumes an upload + * + * @access public + * @see \phpseclib3\Net\SFTP::put() + */ + const RESUME = 4; + /** + * Append a local file to an already existing remote file + * + * @access public + * @see \phpseclib3\Net\SFTP::put() + */ + const RESUME_START = 8; + + /** + * Packet Types + * + * @see self::__construct() + * @var array + * @access private + */ + private $packet_types = []; + + /** + * Status Codes + * + * @see self::__construct() + * @var array + * @access private + */ + private $status_codes = []; + + /** + * The Request ID + * + * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support + * concurrent actions, so it's somewhat academic, here. + * + * @var boolean + * @see self::_send_sftp_packet() + * @access private + */ + private $use_request_id = false; + + /** + * The Packet Type + * + * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support + * concurrent actions, so it's somewhat academic, here. + * + * @var int + * @see self::_get_sftp_packet() + * @access private + */ + private $packet_type = -1; + + /** + * Packet Buffer + * + * @var string + * @see self::_get_sftp_packet() + * @access private + */ + private $packet_buffer = ''; + + /** + * Extensions supported by the server + * + * @var array + * @see self::_initChannel() + * @access private + */ + private $extensions = []; + + /** + * Server SFTP version + * + * @var int + * @see self::_initChannel() + * @access private + */ + private $version; + + /** + * Current working directory + * + * @var string + * @see self::realpath() + * @see self::chdir() + * @access private + */ + private $pwd = false; + + /** + * Packet Type Log + * + * @see self::getLog() + * @var array + * @access private + */ + private $packet_type_log = []; + + /** + * Packet Log + * + * @see self::getLog() + * @var array + * @access private + */ + private $packet_log = []; + + /** + * Error information + * + * @see self::getSFTPErrors() + * @see self::getLastSFTPError() + * @var array + * @access private + */ + private $sftp_errors = []; + + /** + * Stat Cache + * + * Rather than always having to open a directory and close it immediately there after to see if a file is a directory + * we'll cache the results. + * + * @see self::_update_stat_cache() + * @see self::_remove_from_stat_cache() + * @see self::_query_stat_cache() + * @var array + * @access private + */ + private $stat_cache = []; + + /** + * Max SFTP Packet Size + * + * @see self::__construct() + * @see self::get() + * @var array + * @access private + */ + private $max_sftp_packet; + + /** + * Stat Cache Flag + * + * @see self::disableStatCache() + * @see self::enableStatCache() + * @var bool + * @access private + */ + private $use_stat_cache = true; + + /** + * Sort Options + * + * @see self::_comparator() + * @see self::setListOrder() + * @var array + * @access private + */ + protected $sortOptions = []; + + /** + * Canonicalization Flag + * + * Determines whether or not paths should be canonicalized before being + * passed on to the remote server. + * + * @see self::enablePathCanonicalization() + * @see self::disablePathCanonicalization() + * @see self::realpath() + * @var bool + * @access private + */ + private $canonicalize_paths = true; + + /** + * Request Buffers + * + * @see self::_get_sftp_packet() + * @var array + * @access private + */ + var $requestBuffer = array(); + + /** + * Preserve timestamps on file downloads / uploads + * + * @see self::get() + * @see self::put() + * @var bool + * @access private + */ + var $preserveTime = false; + + /** + * Default Constructor. + * + * Connects to an SFTP server + * + * @param string $host + * @param int $port + * @param int $timeout + * @return \phpseclib3\Net\SFTP + * @access public + */ + public function __construct($host, $port = 22, $timeout = 10) + { + parent::__construct($host, $port, $timeout); + + $this->max_sftp_packet = 1 << 15; + + $this->packet_types = [ + 1 => 'NET_SFTP_INIT', + 2 => 'NET_SFTP_VERSION', + /* the format of SSH_FXP_OPEN changed between SFTPv4 and SFTPv5+: + SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.1 + pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 */ + 3 => 'NET_SFTP_OPEN', + 4 => 'NET_SFTP_CLOSE', + 5 => 'NET_SFTP_READ', + 6 => 'NET_SFTP_WRITE', + 7 => 'NET_SFTP_LSTAT', + 9 => 'NET_SFTP_SETSTAT', + 11 => 'NET_SFTP_OPENDIR', + 12 => 'NET_SFTP_READDIR', + 13 => 'NET_SFTP_REMOVE', + 14 => 'NET_SFTP_MKDIR', + 15 => 'NET_SFTP_RMDIR', + 16 => 'NET_SFTP_REALPATH', + 17 => 'NET_SFTP_STAT', + /* the format of SSH_FXP_RENAME changed between SFTPv4 and SFTPv5+: + SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 + pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.5 */ + 18 => 'NET_SFTP_RENAME', + 19 => 'NET_SFTP_READLINK', + 20 => 'NET_SFTP_SYMLINK', + + 101=> 'NET_SFTP_STATUS', + 102=> 'NET_SFTP_HANDLE', + /* the format of SSH_FXP_NAME changed between SFTPv3 and SFTPv4+: + SFTPv4+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.4 + pre-SFTPv4 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-7 */ + 103=> 'NET_SFTP_DATA', + 104=> 'NET_SFTP_NAME', + 105=> 'NET_SFTP_ATTRS', + + 200=> 'NET_SFTP_EXTENDED' + ]; + $this->status_codes = [ + 0 => 'NET_SFTP_STATUS_OK', + 1 => 'NET_SFTP_STATUS_EOF', + 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', + 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', + 4 => 'NET_SFTP_STATUS_FAILURE', + 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', + 6 => 'NET_SFTP_STATUS_NO_CONNECTION', + 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', + 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', + 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', + 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', + 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', + 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', + 13 => 'NET_SFTP_STATUS_NO_MEDIA', + 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', + 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', + 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', + 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', + 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', + 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', + 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', + 21 => 'NET_SFTP_STATUS_LINK_LOOP', + 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', + 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', + 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', + 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', + 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', + 27 => 'NET_SFTP_STATUS_DELETE_PENDING', + 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', + 29 => 'NET_SFTP_STATUS_OWNER_INVALID', + 30 => 'NET_SFTP_STATUS_GROUP_INVALID', + 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 + // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why + $this->attributes = [ + 0x00000001 => 'NET_SFTP_ATTR_SIZE', + 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ + 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', + 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', + // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers + // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in + // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. + // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. + (-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 + // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name + // the array for that $this->open5_flags and similarly alter the constant names. + $this->open_flags = [ + 0x00000001 => 'NET_SFTP_OPEN_READ', + 0x00000002 => 'NET_SFTP_OPEN_WRITE', + 0x00000004 => 'NET_SFTP_OPEN_APPEND', + 0x00000008 => 'NET_SFTP_OPEN_CREATE', + 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', + 0x00000020 => 'NET_SFTP_OPEN_EXCL' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 + // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation + $this->file_types = [ + 1 => 'NET_SFTP_TYPE_REGULAR', + 2 => 'NET_SFTP_TYPE_DIRECTORY', + 3 => 'NET_SFTP_TYPE_SYMLINK', + 4 => 'NET_SFTP_TYPE_SPECIAL', + 5 => 'NET_SFTP_TYPE_UNKNOWN', + // the following types were first defined for use in SFTPv5+ + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 + 6 => 'NET_SFTP_TYPE_SOCKET', + 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', + 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', + 9 => 'NET_SFTP_TYPE_FIFO' + ]; + $this->define_array( + $this->packet_types, + $this->status_codes, + $this->attributes, + $this->open_flags, + $this->file_types + ); + + if (!defined('NET_SFTP_QUEUE_SIZE')) { + define('NET_SFTP_QUEUE_SIZE', 32); + } + if (!defined('NET_SFTP_UPLOAD_QUEUE_SIZE')) { + define('NET_SFTP_UPLOAD_QUEUE_SIZE', 1024); + } + } + + /** + * Login + * + * @param string $username + * @param string[] ...$args + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + * @access public + */ + public function login($username, ...$args) + { + if (!parent::login(...func_get_args())) { + return false; + } + + $this->window_size_server_to_client[self::CHANNEL] = $this->window_size; + + $packet = Strings::packSSH2( + 'CsN3', + NET_SSH2_MSG_CHANNEL_OPEN, + 'session', + self::CHANNEL, + $this->window_size, + 0x4000 + ); + + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN; + + $response = $this->get_channel_packet(self::CHANNEL, true); + if ($response === false) { + return false; + } + + $packet = Strings::packSSH2( + 'CNsbs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL], + 'subsystem', + true, + 'sftp' + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $response = $this->get_channel_packet(self::CHANNEL, true); + if ($response === false) { + // from PuTTY's psftp.exe + $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" . + "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" . + "exec sftp-server"; + // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does + // is redundant + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL], + 'exec', + 1, + $command + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $response = $this->get_channel_packet(self::CHANNEL, true); + if ($response === false) { + return false; + } + } + + $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA; + + if (!$this->send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) { + return false; + } + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_VERSION) { + throw new \UnexpectedValueException('Expected NET_SFTP_VERSION. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($this->version) = Strings::unpackSSH2('N', $response); + while (!empty($response)) { + list($key, $value) = Strings::unpackSSH2('ss', $response); + $this->extensions[$key] = $value; + } + + /* + SFTPv4+ defines a 'newline' extension. SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com', + however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's + not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for + one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that + 'newline@vandyke.com' would. + */ + /* + if (isset($this->extensions['newline@vandyke.com'])) { + $this->extensions['newline'] = $this->extensions['newline@vandyke.com']; + unset($this->extensions['newline@vandyke.com']); + } + */ + + $this->use_request_id = true; + + /* + A Note on SFTPv4/5/6 support: + states the following: + + "If the client wishes to interoperate with servers that support noncontiguous version + numbers it SHOULD send '3'" + + Given that the server only sends its version number after the client has already done so, the above + seems to be suggesting that v3 should be the default version. This makes sense given that v3 is the + most popular. + + states the following; + + "If the server did not send the "versions" extension, or the version-from-list was not included, the + server MAY send a status response describing the failure, but MUST then close the channel without + processing any further requests." + + So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and + a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements + v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed + in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib3\Net\SFTP would do is close the + channel and reopen it with a new and updated SSH_FXP_INIT packet. + */ + switch ($this->version) { + case 2: + case 3: + break; + default: + return false; + } + + $this->pwd = $this->realpath('.'); + + $this->update_stat_cache($this->pwd, []); + + return true; + } + + /** + * Disable the stat cache + * + * @access public + */ + function disableStatCache() + { + $this->use_stat_cache = false; + } + + /** + * Enable the stat cache + * + * @access public + */ + public function enableStatCache() + { + $this->use_stat_cache = true; + } + + /** + * Clear the stat cache + * + * @access public + */ + public function clearStatCache() + { + $this->stat_cache = []; + } + + /** + * Enable path canonicalization + * + * @access public + */ + public function enablePathCanonicalization() + { + $this->canonicalize_paths = true; + } + + /** + * Enable path canonicalization + * + * @access public + */ + public function disablePathCanonicalization() + { + $this->canonicalize_paths = false; + } + + /** + * Returns the current directory name + * + * @return mixed + * @access public + */ + public function pwd() + { + return $this->pwd; + } + + /** + * Logs errors + * + * @param string $response + * @param int $status + * @access private + */ + private function logError($response, $status = -1) + { + if ($status == -1) { + list($status) = Strings::unpackSSH2('N', $response); + } + + list($error) = $this->status_codes[$status]; + + if ($this->version > 2) { + list($message) = Strings::unpackSSH2('s', $response); + $this->sftp_errors[] = "$error: $message"; + } else { + $this->sftp_errors[] = $error; + } + } + + /** + * Canonicalize the Server-Side Path Name + * + * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns + * the absolute (canonicalized) path. + * + * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is. + * + * @see self::chdir() + * @see self::disablePathCanonicalization() + * @param string $path + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + * @access public + */ + public function realpath($path) + { + if (!$this->canonicalize_paths) { + return $path; + } + + if ($this->pwd === false) { + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9 + if (!$this->send_sftp_packet(NET_SFTP_REALPATH, Strings::packSSH2('s', $path))) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_NAME: + // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following + // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks + // at is the first part and that part is defined the same in SFTP versions 3 through 6. + list(, $filename) = Strings::unpackSSH2('Ns', $response); + return $filename; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + if (!strlen($path) || $path[0] != '/') { + $path = $this->pwd . '/' . $path; + } + + $path = explode('/', $path); + $new = []; + foreach ($path as $dir) { + if (!strlen($dir)) { + continue; + } + switch ($dir) { + case '..': + array_pop($new); + case '.': + break; + default: + $new[] = $dir; + } + } + + return '/' . implode('/', $new); + } + + /** + * Changes the current directory + * + * @param string $dir + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + * @access public + */ + public function chdir($dir) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + // assume current dir if $dir is empty + if ($dir === '') { + $dir = './'; + // suffix a slash if needed + } elseif ($dir[strlen($dir) - 1] != '/') { + $dir.= '/'; + } + + $dir = $this->realpath($dir); + + // confirm that $dir is, in fact, a valid directory + if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) { + $this->pwd = $dir; + return true; + } + + // we could do a stat on the alleged $dir to see if it's a directory but that doesn't tell us + // the currently logged in user has the appropriate permissions or not. maybe you could see if + // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy + // way to get those with SFTP + + if (!$this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir))) { + return false; + } + + // see \phpseclib3\Net\SFTP::nlist() for a more thorough explanation of the following + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS' . + 'Got packet type: ' . $this->packet_type); + } + + if (!$this->close_handle($handle)) { + return false; + } + + $this->update_stat_cache($dir, []); + + $this->pwd = $dir; + return true; + } + + /** + * Returns a list of files in the given directory + * + * @param string $dir + * @param bool $recursive + * @return mixed + * @access public + */ + public function nlist($dir = '.', $recursive = false) + { + return $this->nlist_helper($dir, $recursive, ''); + } + + /** + * Helper method for nlist + * + * @param string $dir + * @param bool $recursive + * @param string $relativeDir + * @return mixed + * @access private + */ + private function nlist_helper($dir, $recursive, $relativeDir) + { + $files = $this->readlist($dir, false); + + if (!$recursive || $files === false) { + return $files; + } + + $result = []; + foreach ($files as $value) { + if ($value == '.' || $value == '..') { + $result[] = $relativeDir . $value; + continue; + } + if (is_array($this->query_stat_cache($this->realpath($dir . '/' . $value)))) { + $temp = $this->nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); + $temp = is_array($temp) ? $temp : []; + $result = array_merge($result, $temp); + } else { + $result[] = $relativeDir . $value; + } + } + + return $result; + } + + /** + * Returns a detailed list of files in the given directory + * + * @param string $dir + * @param bool $recursive + * @return mixed + * @access public + */ + public function rawlist($dir = '.', $recursive = false) + { + $files = $this->readlist($dir, true); + if (!$recursive || $files === false) { + return $files; + } + + static $depth = 0; + + foreach ($files as $key => $value) { + if ($depth != 0 && $key == '..') { + unset($files[$key]); + continue; + } + $is_directory = false; + if ($key != '.' && $key != '..') { + if ($this->use_stat_cache) { + $is_directory = is_array($this->query_stat_cache($this->realpath($dir . '/' . $key))); + } else { + $stat = $this->lstat($dir . '/' . $key); + $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY; + } + } + + if ($is_directory) { + $depth++; + $files[$key] = $this->rawlist($dir . '/' . $key, true); + $depth--; + } else { + $files[$key] = (object) $value; + } + } + + return $files; + } + + /** + * Reads a list, be it detailed or not, of files in the given directory + * + * @param string $dir + * @param bool $raw + * @return mixed + * @throws \UnexpectedValueException on receipt of unexpected packets + * @access private + */ + private function readlist($dir, $raw = true) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $dir = $this->realpath($dir . '/'); + if ($dir === false) { + return false; + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2 + if (!$this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir))) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2 + // since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that + // represent the length of the string and leave it at that + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: + // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + $this->update_stat_cache($dir, []); + + $contents = []; + while (true) { + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2 + // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many + // SSH_MSG_CHANNEL_DATA messages is not known to me. + if (!$this->send_sftp_packet(NET_SFTP_READDIR, Strings::packSSH2('s', $handle))) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_NAME: + list($count) = Strings::unpackSSH2('N', $response); + for ($i = 0; $i < $count; $i++) { + list($shortname, $longname) = Strings::unpackSSH2('ss', $response); + $attributes = $this->parseAttributes($response); + if (!isset($attributes['type'])) { + $fileType = $this->parseLongname($longname); + if ($fileType) { + $attributes['type'] = $fileType; + } + } + $contents[$shortname] = $attributes + ['filename' => $shortname]; + + if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) { + $this->update_stat_cache($dir . '/' . $shortname, []); + } else { + if ($shortname == '..') { + $temp = $this->realpath($dir . '/..') . '/.'; + } else { + $temp = $dir . '/' . $shortname; + } + $this->update_stat_cache($temp, (object) ['lstat' => $attributes]); + } + // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the + // final SSH_FXP_STATUS packet should tell us that, already. + } + break; + case NET_SFTP_STATUS: + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_EOF) { + $this->logError($response, $status); + return false; + } + break 2; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + if (!$this->close_handle($handle)) { + return false; + } + + if (count($this->sortOptions)) { + uasort($contents, [&$this, 'comparator']); + } + + return $raw ? $contents : array_keys($contents); + } + + /** + * Compares two rawlist entries using parameters set by setListOrder() + * + * Intended for use with uasort() + * + * @param array $a + * @param array $b + * @return int + * @access private + */ + private function comparator($a, $b) + { + switch (true) { + case $a['filename'] === '.' || $b['filename'] === '.': + if ($a['filename'] === $b['filename']) { + return 0; + } + return $a['filename'] === '.' ? -1 : 1; + case $a['filename'] === '..' || $b['filename'] === '..': + if ($a['filename'] === $b['filename']) { + return 0; + } + return $a['filename'] === '..' ? -1 : 1; + case isset($a['type']) && $a['type'] === NET_SFTP_TYPE_DIRECTORY: + if (!isset($b['type'])) { + return 1; + } + if ($b['type'] !== $a['type']) { + return -1; + } + break; + case isset($b['type']) && $b['type'] === NET_SFTP_TYPE_DIRECTORY: + return 1; + } + foreach ($this->sortOptions as $sort => $order) { + if (!isset($a[$sort]) || !isset($b[$sort])) { + if (isset($a[$sort])) { + return -1; + } + if (isset($b[$sort])) { + return 1; + } + return 0; + } + switch ($sort) { + case 'filename': + $result = strcasecmp($a['filename'], $b['filename']); + if ($result) { + return $order === SORT_DESC ? -$result : $result; + } + break; + case 'mode': + $a[$sort]&= 07777; + $b[$sort]&= 07777; + default: + if ($a[$sort] === $b[$sort]) { + break; + } + return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort]; + } + } + } + + /** + * Defines how nlist() and rawlist() will be sorted - if at all. + * + * If sorting is enabled directories and files will be sorted independently with + * directories appearing before files in the resultant array that is returned. + * + * Any parameter returned by stat is a valid sort parameter for this function. + * Filename comparisons are case insensitive. + * + * Examples: + * + * $sftp->setListOrder('filename', SORT_ASC); + * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC); + * $sftp->setListOrder(true); + * Separates directories from files but doesn't do any sorting beyond that + * $sftp->setListOrder(); + * Don't do any sort of sorting + * + * @param string[] ...$args + * @access public + */ + public function setListOrder(...$args) + { + $this->sortOptions = []; + if (empty($args)) { + return; + } + $len = count($args) & 0x7FFFFFFE; + for ($i = 0; $i < $len; $i+=2) { + $this->sortOptions[$args[$i]] = $args[$i + 1]; + } + if (!count($this->sortOptions)) { + $this->sortOptions = ['bogus' => true]; + } + } + + /** + * Save files / directories to cache + * + * @param string $path + * @param mixed $value + * @access private + */ + private function update_stat_cache($path, $value) + { + if ($this->use_stat_cache === false) { + return; + } + + // preg_replace('#^/|/(?=/)|/$#', '', $dir) == str_replace('//', '/', trim($path, '/')) + $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); + + $temp = &$this->stat_cache; + $max = count($dirs) - 1; + foreach ($dirs as $i => $dir) { + // if $temp is an object that means one of two things. + // 1. a file was deleted and changed to a directory behind phpseclib's back + // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to + if (is_object($temp)) { + $temp = []; + } + if (!isset($temp[$dir])) { + $temp[$dir] = []; + } + if ($i === $max) { + if (is_object($temp[$dir]) && is_object($value)) { + if (!isset($value->stat) && isset($temp[$dir]->stat)) { + $value->stat = $temp[$dir]->stat; + } + if (!isset($value->lstat) && isset($temp[$dir]->lstat)) { + $value->lstat = $temp[$dir]->lstat; + } + } + $temp[$dir] = $value; + break; + } + $temp = &$temp[$dir]; + } + } + + /** + * Remove files / directories from cache + * + * @param string $path + * @return bool + * @access private + */ + private function remove_from_stat_cache($path) + { + $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); + + $temp = &$this->stat_cache; + $max = count($dirs) - 1; + foreach ($dirs as $i => $dir) { + if (!is_array($temp)) { + return false; + } + if ($i === $max) { + unset($temp[$dir]); + return true; + } + if (!isset($temp[$dir])) { + return false; + } + $temp = &$temp[$dir]; + } + } + + /** + * Checks cache for path + * + * Mainly used by file_exists + * + * @param string $path + * @return mixed + * @access private + */ + private function query_stat_cache($path) + { + $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); + + $temp = &$this->stat_cache; + foreach ($dirs as $dir) { + if (!is_array($temp)) { + return null; + } + if (!isset($temp[$dir])) { + return null; + } + $temp = &$temp[$dir]; + } + return $temp; + } + + /** + * Returns general information about a file. + * + * Returns an array on success and false otherwise. + * + * @param string $filename + * @return mixed + * @access public + */ + public function stat($filename) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + if ($this->use_stat_cache) { + $result = $this->query_stat_cache($filename); + if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) { + return $result['.']->stat; + } + if (is_object($result) && isset($result->stat)) { + return $result->stat; + } + } + + $stat = $this->stat_helper($filename, NET_SFTP_STAT); + if ($stat === false) { + $this->remove_from_stat_cache($filename); + return false; + } + if (isset($stat['type'])) { + if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename.= '/.'; + } + $this->update_stat_cache($filename, (object) ['stat' => $stat]); + return $stat; + } + + $pwd = $this->pwd; + $stat['type'] = $this->chdir($filename) ? + NET_SFTP_TYPE_DIRECTORY : + NET_SFTP_TYPE_REGULAR; + $this->pwd = $pwd; + + if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename.= '/.'; + } + $this->update_stat_cache($filename, (object) ['stat' => $stat]); + + return $stat; + } + + /** + * Returns general information about a file or symbolic link. + * + * Returns an array on success and false otherwise. + * + * @param string $filename + * @return mixed + * @access public + */ + public function lstat($filename) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + if ($this->use_stat_cache) { + $result = $this->query_stat_cache($filename); + if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) { + return $result['.']->lstat; + } + if (is_object($result) && isset($result->lstat)) { + return $result->lstat; + } + } + + $lstat = $this->stat_helper($filename, NET_SFTP_LSTAT); + if ($lstat === false) { + $this->remove_from_stat_cache($filename); + return false; + } + if (isset($lstat['type'])) { + if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename.= '/.'; + } + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + return $lstat; + } + + $stat = $this->stat_helper($filename, NET_SFTP_STAT); + + if ($lstat != $stat) { + $lstat = array_merge($lstat, ['type' => NET_SFTP_TYPE_SYMLINK]); + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + return $stat; + } + + $pwd = $this->pwd; + $lstat['type'] = $this->chdir($filename) ? + NET_SFTP_TYPE_DIRECTORY : + NET_SFTP_TYPE_REGULAR; + $this->pwd = $pwd; + + if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename.= '/.'; + } + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + + return $lstat; + } + + /** + * Returns general information about a file or symbolic link + * + * Determines information without calling \phpseclib3\Net\SFTP::realpath(). + * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT. + * + * @param string $filename + * @param int $type + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + * @access private + */ + private function stat_helper($filename, $type) + { + // SFTPv4+ adds an additional 32-bit integer field - flags - to the following: + $packet = Strings::packSSH2('s', $filename); + if (!$this->send_sftp_packet($type, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_ATTRS: + return $this->parseAttributes($response); + case NET_SFTP_STATUS: + $this->logError($response); + return false; + } + + throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + /** + * Truncates a file to a given length + * + * @param string $filename + * @param int $new_size + * @return bool + * @access public + */ + public function truncate($filename, $new_size) + { + $attr = pack('N3', NET_SFTP_ATTR_SIZE, $new_size / 4294967296, $new_size); // 4294967296 == 0x100000000 == 1<<32 + + return $this->setstat($filename, $attr, false); + } + + /** + * Sets access and modification time of file. + * + * If the file does not exist, it will be created. + * + * @param string $filename + * @param int $time + * @param int $atime + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + * @access public + */ + public function touch($filename, $time = null, $atime = null) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + if (!isset($time)) { + $time = time(); + } + if (!isset($atime)) { + $atime = $time; + } + + $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL; + $attr = pack('N3', NET_SFTP_ATTR_ACCESSTIME, $time, $atime); + $packet = Strings::packSSH2('sN', $filename, $flags) . $attr; + if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + return $this->close_handle(substr($response, 4)); + case NET_SFTP_STATUS: + $this->logError($response); + break; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + return $this->setstat($filename, $attr, false); + } + + /** + * Changes file or directory owner + * + * Returns true on success or false on error. + * + * @param string $filename + * @param int $uid + * @param bool $recursive + * @return bool + * @access public + */ + public function chown($filename, $uid, $recursive = false) + { + // quoting from , + // "if the owner or group is specified as -1, then that ID is not changed" + $attr = pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1); + + return $this->setstat($filename, $attr, $recursive); + } + + /** + * Changes file or directory group + * + * Returns true on success or false on error. + * + * @param string $filename + * @param int $gid + * @param bool $recursive + * @return bool + * @access public + */ + public function chgrp($filename, $gid, $recursive = false) + { + $attr = pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid); + + return $this->setstat($filename, $attr, $recursive); + } + + /** + * Set permissions on a file. + * + * Returns the new file permissions on success or false on error. + * If $recursive is true than this just returns true or false. + * + * @param int $mode + * @param string $filename + * @param bool $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + * @access public + */ + public function chmod($mode, $filename, $recursive = false) + { + if (is_string($mode) && is_int($filename)) { + $temp = $mode; + $mode = $filename; + $filename = $temp; + } + + $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777); + if (!$this->setstat($filename, $attr, $recursive)) { + return false; + } + if ($recursive) { + return true; + } + + $filename = $this->realpath($filename); + // rather than return what the permissions *should* be, we'll return what they actually are. this will also + // tell us if the file actually exists. + // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following: + $packet = pack('Na*', strlen($filename), $filename); + if (!$this->send_sftp_packet(NET_SFTP_STAT, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_ATTRS: + $attrs = $this->parseAttributes($response); + return $attrs['mode']; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + } + + throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + /** + * Sets information about a file + * + * @param string $filename + * @param string $attr + * @param bool $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + * @access private + */ + private function setstat($filename, $attr, $recursive) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + $this->remove_from_stat_cache($filename); + + if ($recursive) { + $i = 0; + $result = $this->setstat_recursive($filename, $attr, $i); + $this->read_put_responses($i); + return $result; + } + + // SFTPv4+ has an additional byte field - type - that would need to be sent, as well. setting it to + // SSH_FILEXFER_TYPE_UNKNOWN might work. if not, we'd have to do an SSH_FXP_STAT before doing an SSH_FXP_SETSTAT. + if (!$this->send_sftp_packet(NET_SFTP_SETSTAT, Strings::packSSH2('s', $filename) . $attr)) { + return false; + } + + /* + "Because some systems must use separate system calls to set various attributes, it is possible that a failure + response will be returned, but yet some of the attributes may be have been successfully modified. If possible, + servers SHOULD avoid this situation; however, clients MUST be aware that this is possible." + + -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6 + */ + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + return true; + } + + /** + * Recursively sets information on directories on the SFTP server + * + * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. + * + * @param string $path + * @param string $attr + * @param int $i + * @return bool + * @access private + */ + private function setstat_recursive($path, $attr, &$i) + { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + $entries = $this->readlist($path, true); + + if ($entries === false) { + return $this->setstat($path, $attr, false); + } + + // normally $entries would have at least . and .. but it might not if the directories + // permissions didn't allow reading + if (empty($entries)) { + return false; + } + + unset($entries['.'], $entries['..']); + foreach ($entries as $filename => $props) { + if (!isset($props['type'])) { + return false; + } + + $temp = $path . '/' . $filename; + if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { + if (!$this->setstat_recursive($temp, $attr, $i)) { + return false; + } + } else { + if (!$this->send_sftp_packet(NET_SFTP_SETSTAT, Strings::packSSH2('s', $temp) . $attr)) { + return false; + } + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + } + } + + if (!$this->send_sftp_packet(NET_SFTP_SETSTAT, Strings::packSSH2('s', $path) . $attr)) { + return false; + } + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + + return true; + } + + /** + * Return the target of a symbolic link + * + * @param string $link + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + * @access public + */ + public function readlink($link) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $link = $this->realpath($link); + + if (!$this->send_sftp_packet(NET_SFTP_READLINK, Strings::packSSH2('s', $link))) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_NAME: + break; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($count) = Strings::unpackSSH2('N', $response); + // the file isn't a symlink + if (!$count) { + return false; + } + + list($filename) = Strings::unpackSSH2('s', $response); + + return $filename; + } + + /** + * Create a symlink + * + * symlink() creates a symbolic link to the existing target with the specified name link. + * + * @param string $target + * @param string $link + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + * @access public + */ + public function symlink($target, $link) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + //$target = $this->realpath($target); + $link = $this->realpath($link); + + $packet = Strings::packSSH2('ss', $target, $link); + if (!$this->send_sftp_packet(NET_SFTP_SYMLINK, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + return true; + } + + /** + * Creates a directory. + * + * @param string $dir + * @param int $mode + * @param bool $recursive + * @return bool + * @access public + */ + public function mkdir($dir, $mode = -1, $recursive = false) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $dir = $this->realpath($dir); + + if ($recursive) { + $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir)); + if (empty($dirs[0])) { + array_shift($dirs); + $dirs[0] = '/' . $dirs[0]; + } + for ($i = 0; $i < count($dirs); $i++) { + $temp = array_slice($dirs, 0, $i + 1); + $temp = implode('/', $temp); + $result = $this->mkdir_helper($temp, $mode); + } + return $result; + } + + return $this->mkdir_helper($dir, $mode); + } + + /** + * Helper function for directory creation + * + * @param string $dir + * @param int $mode + * @return bool + * @access private + */ + private function mkdir_helper($dir, $mode) + { + // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing) + if (!$this->send_sftp_packet(NET_SFTP_MKDIR, Strings::packSSH2('s', $dir) . "\0\0\0\0")) { + return false; + } + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + if ($mode !== -1) { + $this->chmod($mode, $dir); + } + + return true; + } + + /** + * Removes a directory. + * + * @param string $dir + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + * @access public + */ + public function rmdir($dir) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $dir = $this->realpath($dir); + if ($dir === false) { + return false; + } + + if (!$this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $dir))) { + return false; + } + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED? + $this->logError($response, $status); + return false; + } + + $this->remove_from_stat_cache($dir); + // the following will do a soft delete, which would be useful if you deleted a file + // and then tried to do a stat on the deleted file. the above, in contrast, does + // a hard delete + //$this->update_stat_cache($dir, false); + + return true; + } + + /** + * Uploads a file to the SFTP server. + * + * By default, \phpseclib3\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. + * So, for example, if you set $data to 'filename.ext' and then do \phpseclib3\Net\SFTP::get(), you will get a file, twelve bytes + * long, containing 'filename.ext' as its contents. + * + * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will + * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how + * large $remote_file will be, as well. + * + * Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number of bytes to return, and returns a string if there is some data or null if there is no more data + * + * If $data is a resource then it'll be used as a resource instead. + * + * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take + * care of that, yourself. + * + * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with + * $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following: + * + * self::SOURCE_LOCAL_FILE | self::RESUME + * + * If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace + * self::RESUME with self::RESUME_START. + * + * If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed. + * + * $start and $local_start give you more fine grained control over this process and take precident over self::RESUME + * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle + * of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the + * middle of one. + * + * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE. + * + * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().} + * + * @param string $remote_file + * @param string|resource $data + * @param int $mode + * @param int $start + * @param int $local_start + * @param callable|null $progressCallback + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid + * @throws \phpseclib3\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist + * @return bool + * @access public + */ + public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $remote_file = $this->realpath($remote_file); + if ($remote_file === false) { + return false; + } + + $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; + // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file." + // in practice, it doesn't seem to do that. + //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE; + + if ($start >= 0) { + $offset = $start; + } elseif ($mode & self::RESUME) { + // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called + $size = $this->stat($remote_file)['size']; + $offset = $size !== false ? $size : 0; + } else { + $offset = 0; + $flags|= NET_SFTP_OPEN_TRUNCATE; + } + + $this->remove_from_stat_cache($remote_file); + + $packet = Strings::packSSH2('sNN', $remote_file, $flags, 0); + if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 + $dataCallback = false; + switch (true) { + case $mode & self::SOURCE_CALLBACK: + if (!is_callable($data)) { + throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); + } + $dataCallback = $data; + // do nothing + break; + case is_resource($data): + $mode = $mode & ~self::SOURCE_LOCAL_FILE; + $info = stream_get_meta_data($data); + if ($info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') { + $fp = fopen('php://memory', 'w+'); + stream_copy_to_stream($data, $fp); + rewind($fp); + } else { + $fp = $data; + } + break; + case $mode & self::SOURCE_LOCAL_FILE: + if (!is_file($data)) { + throw new FileNotFoundException("$data is not a valid file"); + } + $fp = @fopen($data, 'rb'); + if (!$fp) { + return false; + } + } + + if (isset($fp)) { + $stat = fstat($fp); + $size = !empty($stat) ? $stat['size'] : 0; + + if ($local_start >= 0) { + fseek($fp, $local_start); + $size-= $local_start; + } + } elseif ($dataCallback) { + $size = 0; + } else { + $size = strlen($data); + } + + $sent = 0; + $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; + + $sftp_packet_size = $this->max_sftp_packet; + // make the SFTP packet be exactly the SFTP packet size by including the bytes in the NET_SFTP_WRITE packets "header" + $sftp_packet_size-= strlen($handle) + 25; + $i = $j = 0; + while ($dataCallback || ($size === 0 || $sent < $size)) { + if ($dataCallback) { + $temp = $dataCallback($sftp_packet_size); + if (is_null($temp)) { + break; + } + } else { + $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size); + if ($temp === false || $temp === '') { + break; + } + } + + $subtemp = $offset + $sent; + $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp); + if (!$this->send_sftp_packet(NET_SFTP_WRITE, $packet, $j)) { + if ($mode & self::SOURCE_LOCAL_FILE) { + fclose($fp); + } + return false; + } + $sent+= strlen($temp); + if (is_callable($progressCallback)) { + $progressCallback($sent); + } + + $i++; + $j++; + if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + $i = 0; + break; + } + $i = 0; + } + } + + if (!$this->read_put_responses($i)) { + if ($mode & self::SOURCE_LOCAL_FILE) { + fclose($fp); + } + $this->close_handle($handle); + return false; + } + + if ($mode & self::SOURCE_LOCAL_FILE) { + if ($this->preserveTime) { + $stat = fstat($fp); + $this->touch($remote_file, $stat['mtime'], $stat['atime']); + } + + if (isset($fp) && is_resource($fp)) { + fclose($fp); + } + } + + return $this->close_handle($handle); + } + + /** + * Reads multiple successive SSH_FXP_WRITE responses + * + * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i + * SSH_FXP_WRITEs, in succession, and then reading $i responses. + * + * @param int $i + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @access private + */ + private function read_put_responses($i) + { + while ($i--) { + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + break; + } + } + + return $i < 0; + } + + /** + * Close handle + * + * @param string $handle + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @access private + */ + private function close_handle($handle) + { + if (!$this->send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) { + return false; + } + + // "The client MUST release all resources associated with the handle regardless of the status." + // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + return true; + } + + /** + * Downloads a file from the SFTP server. + * + * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if + * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the + * operation. + * + * $offset and $length can be used to download files in chunks. + * + * @param string $remote_file + * @param string|bool|resource $local_file + * @param int $offset + * @param int $length + * @param callable|null $progressCallback + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + * @access public + */ + public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $remote_file = $this->realpath($remote_file); + if ($remote_file === false) { + return false; + } + + $packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_READ, 0); + if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + if (is_resource($local_file)) { + $fp = $local_file; + $stat = fstat($fp); + $res_offset = $stat['size']; + } else { + $res_offset = 0; + if ($local_file !== false && !is_callable($local_file)) { + $fp = fopen($local_file, 'wb'); + if (!$fp) { + return false; + } + } else { + $content = ''; + } + } + + $fclose_check = $local_file !== false && !is_callable($local_file) && !is_resource($local_file); + + $start = $offset; + $read = 0; + while (true) { + $i = 0; + + while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) { + $tempoffset = $start + $read; + + $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet; + + $packet = Strings::packSSH2('sN3', $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); + if (!$this->send_sftp_packet(NET_SFTP_READ, $packet, $i)) { + if ($fclose_check) { + fclose($fp); + } + return false; + } + $packet = null; + $read+= $packet_size; + $i++; + } + + if (!$i) { + break; + } + + $packets_sent = $i - 1; + + $clear_responses = false; + while ($i > 0) { + $i--; + + if ($clear_responses) { + $this->get_sftp_packet($packets_sent - $i); + continue; + } else { + $response = $this->get_sftp_packet($packets_sent - $i); + } + + switch ($this->packet_type) { + case NET_SFTP_DATA: + $temp = substr($response, 4); + $offset+= strlen($temp); + if ($local_file === false) { + $content.= $temp; + } elseif (is_callable($local_file)) { + $local_file($temp); + } else { + fputs($fp, $temp); + } + if (is_callable($progressCallback)) { + call_user_func($progressCallback, $offset); + } + $temp = null; + break; + case NET_SFTP_STATUS: + // could, in theory, return false if !strlen($content) but we'll hold off for the time being + $this->logError($response); + $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses + break; + default: + if ($fclose_check) { + fclose($fp); + } + throw new \UnexpectedValueException('Expected NET_SFTP_DATA or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + $response = null; + } + + if ($clear_responses) { + break; + } + } + + if ($length > 0 && $length <= $offset - $start) { + if ($local_file === false) { + $content = substr($content, 0, $length); + } else { + ftruncate($fp, $length + $res_offset); + } + } + + if ($fclose_check) { + fclose($fp); + + if ($this->preserveTime) { + $stat = $this->stat($remote_file); + touch($local_file, $stat['mtime'], $stat['atime']); + } + } + + if (!$this->close_handle($handle)) { + return false; + } + + // if $content isn't set that means a file was written to + return isset($content) ? $content : true; + } + + /** + * Deletes a file on the SFTP server. + * + * @param string $path + * @param bool $recursive + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @access public + */ + public function delete($path, $recursive = true) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + if (is_object($path)) { + // It's an object. Cast it as string before we check anything else. + $path = (string) $path; + } + + if (!is_string($path) || $path == '') { + return false; + } + + $path = $this->realpath($path); + if ($path === false) { + return false; + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 + if (!$this->send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) { + return false; + } + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + if (!$recursive) { + return false; + } + + $i = 0; + $result = $this->delete_recursive($path, $i); + $this->read_put_responses($i); + return $result; + } + + $this->remove_from_stat_cache($path); + + return true; + } + + /** + * Recursively deletes directories on the SFTP server + * + * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. + * + * @param string $path + * @param int $i + * @return bool + * @access private + */ + private function delete_recursive($path, &$i) + { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + $entries = $this->readlist($path, true); + + // normally $entries would have at least . and .. but it might not if the directories + // permissions didn't allow reading + if (empty($entries)) { + return false; + } + + unset($entries['.'], $entries['..']); + foreach ($entries as $filename => $props) { + if (!isset($props['type'])) { + return false; + } + + $temp = $path . '/' . $filename; + if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { + if (!$this->delete_recursive($temp, $i)) { + return false; + } + } else { + if (!$this->send_sftp_packet(NET_SFTP_REMOVE, Strings::packSSH2('s', $temp))) { + return false; + } + $this->remove_from_stat_cache($temp); + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + } + } + + if (!$this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $path))) { + return false; + } + $this->remove_from_stat_cache($path); + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + + return true; + } + + /** + * Checks whether a file or directory exists + * + * @param string $path + * @return bool + * @access public + */ + public function file_exists($path) + { + if ($this->use_stat_cache) { + $path = $this->realpath($path); + + $result = $this->query_stat_cache($path); + + if (isset($result)) { + // return true if $result is an array or if it's an stdClass object + return $result !== false; + } + } + + return $this->stat($path) !== false; + } + + /** + * Tells whether the filename is a directory + * + * @param string $path + * @return bool + * @access public + */ + public function is_dir($path) + { + $result = $this->get_stat_cache_prop($path, 'type'); + if ($result === false) { + return false; + } + return $result === NET_SFTP_TYPE_DIRECTORY; + } + + /** + * Tells whether the filename is a regular file + * + * @param string $path + * @return bool + * @access public + */ + public function is_file($path) + { + $result = $this->get_stat_cache_prop($path, 'type'); + if ($result === false) { + return false; + } + return $result === NET_SFTP_TYPE_REGULAR; + } + + /** + * Tells whether the filename is a symbolic link + * + * @param string $path + * @return bool + * @access public + */ + public function is_link($path) + { + $result = $this->get_lstat_cache_prop($path, 'type'); + if ($result === false) { + return false; + } + return $result === NET_SFTP_TYPE_SYMLINK; + } + + /** + * Tells whether a file exists and is readable + * + * @param string $path + * @return bool + * @access public + */ + public function is_readable($path) + { + $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_READ, 0); + if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + return true; + case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + /** + * Tells whether the filename is writable + * + * @param string $path + * @return bool + * @access public + */ + public function is_writable($path) + { + $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_WRITE, 0); + if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + return true; + case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + return false; + default: + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + /** + * Tells whether the filename is writeable + * + * Alias of is_writable + * + * @param string $path + * @return bool + * @access public + */ + public function is_writeable($path) + { + return $this->is_writable($path); + } + + /** + * Gets last access time of file + * + * @param string $path + * @return mixed + * @access public + */ + public function fileatime($path) + { + return $this->get_stat_cache_prop($path, 'atime'); + } + + /** + * Gets file modification time + * + * @param string $path + * @return mixed + * @access public + */ + public function filemtime($path) + { + return $this->get_stat_cache_prop($path, 'mtime'); + } + + /** + * Gets file permissions + * + * @param string $path + * @return mixed + * @access public + */ + public function fileperms($path) + { + return $this->get_stat_cache_prop($path, 'mode'); + } + + /** + * Gets file owner + * + * @param string $path + * @return mixed + * @access public + */ + public function fileowner($path) + { + return $this->get_stat_cache_prop($path, 'uid'); + } + + /** + * Gets file group + * + * @param string $path + * @return mixed + * @access public + */ + public function filegroup($path) + { + return $this->get_stat_cache_prop($path, 'gid'); + } + + /** + * Gets file size + * + * @param string $path + * @return mixed + * @access public + */ + public function filesize($path) + { + return $this->get_stat_cache_prop($path, 'size'); + } + + /** + * Gets file type + * + * @param string $path + * @return mixed + * @access public + */ + public function filetype($path) + { + $type = $this->get_stat_cache_prop($path, 'type'); + if ($type === false) { + return false; + } + + switch ($type) { + case NET_SFTP_TYPE_BLOCK_DEVICE: + return 'block'; + case NET_SFTP_TYPE_CHAR_DEVICE: + return 'char'; + case NET_SFTP_TYPE_DIRECTORY: + return 'dir'; + case NET_SFTP_TYPE_FIFO: + return 'fifo'; + case NET_SFTP_TYPE_REGULAR: + return 'file'; + case NET_SFTP_TYPE_SYMLINK: + return 'link'; + default: + return false; + } + } + + /** + * Return a stat properity + * + * Uses cache if appropriate. + * + * @param string $path + * @param string $prop + * @return mixed + * @access private + */ + private function get_stat_cache_prop($path, $prop) + { + return $this->get_xstat_cache_prop($path, $prop, 'stat'); + } + + /** + * Return an lstat properity + * + * Uses cache if appropriate. + * + * @param string $path + * @param string $prop + * @return mixed + * @access private + */ + private function get_lstat_cache_prop($path, $prop) + { + return $this->get_xstat_cache_prop($path, $prop, 'lstat'); + } + + /** + * Return a stat or lstat properity + * + * Uses cache if appropriate. + * + * @param string $path + * @param string $prop + * @param string $type + * @return mixed + * @access private + */ + private function get_xstat_cache_prop($path, $prop, $type) + { + if ($this->use_stat_cache) { + $path = $this->realpath($path); + + $result = $this->query_stat_cache($path); + + if (is_object($result) && isset($result->$type)) { + return $result->{$type}[$prop]; + } + } + + $result = $this->$type($path); + + if ($result === false || !isset($result[$prop])) { + return false; + } + + return $result[$prop]; + } + + /** + * Renames a file or a directory on the SFTP server + * + * @param string $oldname + * @param string $newname + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @access public + */ + public function rename($oldname, $newname) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $oldname = $this->realpath($oldname); + $newname = $this->realpath($newname); + if ($oldname === false || $newname === false) { + return false; + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 + $packet = Strings::packSSH2('ss', $oldname, $newname); + if (!$this->send_sftp_packet(NET_SFTP_RENAME, $packet)) { + return false; + } + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + // don't move the stat cache entry over since this operation could very well change the + // atime and mtime attributes + //$this->update_stat_cache($newname, $this->query_stat_cache($oldname)); + $this->remove_from_stat_cache($oldname); + $this->remove_from_stat_cache($newname); + + return true; + } + + /** + * Parse Attributes + * + * See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info. + * + * @param string $response + * @return array + * @access private + */ + protected function parseAttributes(&$response) + { + $attr = []; + list($flags) = Strings::unpackSSH2('N', $response); + + // SFTPv4+ have a type field (a byte) that follows the above flag field + foreach ($this->attributes as $key => $value) { + switch ($flags & $key) { + case NET_SFTP_ATTR_SIZE: // 0x00000001 + // The size attribute is defined as an unsigned 64-bit integer. + // The following will use floats on 32-bit platforms, if necessary. + // As can be seen in the BigInteger class, floats are generally + // IEEE 754 binary64 "double precision" on such platforms and + // as such can represent integers of at least 2^50 without loss + // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB. + list($upper, $size) = Strings::unpackSSH2('NN', $response); + $attr['size'] = $upper ? 4294967296 * $upper : 0; + $attr['size']+= $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; + break; + case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) + list($attr['uid'], $attr['gid']) = Strings::unpackSSH2('NN', $response); + break; + case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 + list($attr['mode']) = Strings::unpackSSH2('N', $response); + $fileType = $this->parseMode($attr['mode']); + if ($fileType !== false) { + $attr+= ['type' => $fileType]; + } + break; + case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 + list($attr['atime'], $attr['mtime']) = Strings::unpackSSH2('NN', $response); + break; + case NET_SFTP_ATTR_EXTENDED: // 0x80000000 + list($count) = Strings::unpackSSH2('N', $response); + for ($i = 0; $i < $count; $i++) { + list($key, $value) = Strings::unpackSSH2('ss', $response); + $attr[$key] = $value; + } + } + } + return $attr; + } + + /** + * Attempt to identify the file type + * + * Quoting the SFTP RFC, "Implementations MUST NOT send bits that are not defined" but they seem to anyway + * + * @param int $mode + * @return int + * @access private + */ + private function parseMode($mode) + { + // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12 + // see, also, http://linux.die.net/man/2/stat + switch ($mode & 0170000) {// ie. 1111 0000 0000 0000 + case 0000000: // no file type specified - figure out the file type using alternative means + return false; + case 0040000: + return NET_SFTP_TYPE_DIRECTORY; + case 0100000: + return NET_SFTP_TYPE_REGULAR; + case 0120000: + return NET_SFTP_TYPE_SYMLINK; + // new types introduced in SFTPv5+ + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 + case 0010000: // named pipe (fifo) + return NET_SFTP_TYPE_FIFO; + case 0020000: // character special + return NET_SFTP_TYPE_CHAR_DEVICE; + case 0060000: // block special + return NET_SFTP_TYPE_BLOCK_DEVICE; + case 0140000: // socket + return NET_SFTP_TYPE_SOCKET; + case 0160000: // whiteout + // "SPECIAL should be used for files that are of + // a known type which cannot be expressed in the protocol" + return NET_SFTP_TYPE_SPECIAL; + default: + return NET_SFTP_TYPE_UNKNOWN; + } + } + + /** + * Parse Longname + * + * SFTPv3 doesn't provide any easy way of identifying a file type. You could try to open + * a file as a directory and see if an error is returned or you could try to parse the + * SFTPv3-specific longname field of the SSH_FXP_NAME packet. That's what this function does. + * The result is returned using the + * {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}. + * + * If the longname is in an unrecognized format bool(false) is returned. + * + * @param string $longname + * @return mixed + * @access private + */ + private function parseLongname($longname) + { + // http://en.wikipedia.org/wiki/Unix_file_types + // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions + if (preg_match('#^[^/]([r-][w-][xstST-]){3}#', $longname)) { + switch ($longname[0]) { + case '-': + return NET_SFTP_TYPE_REGULAR; + case 'd': + return NET_SFTP_TYPE_DIRECTORY; + case 'l': + return NET_SFTP_TYPE_SYMLINK; + default: + return NET_SFTP_TYPE_SPECIAL; + } + } + + return false; + } + + /** + * Sends SFTP Packets + * + * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. + * + * @param int $type + * @param string $data + * @param int $request_id + * @see self::_get_sftp_packet() + * @see self::send_channel_packet() + * @return bool + * @access private + */ + private function send_sftp_packet($type, $data, $request_id = 1) + { + // in SSH2.php the timeout is cumulative per function call. eg. exec() will + // timeout after 10s. but for SFTP.php it's cumulative per packet + $this->curTimeout = $this->timeout; + + $packet = $this->use_request_id ? + pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : + pack('NCa*', strlen($data) + 1, $type, $data); + + $start = microtime(true); + $result = $this->send_channel_packet(self::CHANNEL, $packet); + $stop = microtime(true); + + if (defined('NET_SFTP_LOGGING')) { + $packet_type = '-> ' . $this->packet_types[$type] . + ' (' . round($stop - $start, 4) . 's)'; + if (NET_SFTP_LOGGING == self::LOG_REALTIME) { + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
      ';
      +                        $stop = '
      '; + } + echo $start . $this->format_log([$data], [$packet_type]) . $stop; + @flush(); + @ob_flush(); + } else { + $this->packet_type_log[] = $packet_type; + if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { + $this->packet_log[] = $data; + } + } + } + + return $result; + } + + /** + * Resets a connection for re-use + * + * @param int $reason + * @access private + */ + protected function reset_connection($reason) + { + parent::reset_connection($reason); + $this->use_request_id = false; + $this->pwd = false; + $this->requestBuffer = []; + } + + /** + * Receives SFTP Packets + * + * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. + * + * Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present. + * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA + * messages containing one SFTP packet. + * + * @see self::_send_sftp_packet() + * @return string + * @access private + */ + private function get_sftp_packet($request_id = null) + { + if (isset($request_id) && isset($this->requestBuffer[$request_id])) { + $this->packet_type = $this->requestBuffer[$request_id]['packet_type']; + $temp = $this->requestBuffer[$request_id]['packet']; + unset($this->requestBuffer[$request_id]); + return $temp; + } + + // in SSH2.php the timeout is cumulative per function call. eg. exec() will + // timeout after 10s. but for SFTP.php it's cumulative per packet + $this->curTimeout = $this->timeout; + + $start = microtime(true); + + // SFTP packet length + while (strlen($this->packet_buffer) < 4) { + $temp = $this->get_channel_packet(self::CHANNEL, true); + if (is_bool($temp)) { + $this->packet_type = false; + $this->packet_buffer = ''; + return false; + } + $this->packet_buffer.= $temp; + } + if (strlen($this->packet_buffer) < 4) { + return false; + } + extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4))); + /** @var integer $length */ + + $tempLength = $length; + $tempLength-= strlen($this->packet_buffer); + + + // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h + if ($tempLength > 256 * 1024) { + throw new \RuntimeException('Invalid Size'); + } + + // SFTP packet type and data payload + while ($tempLength > 0) { + $temp = $this->get_channel_packet(self::CHANNEL, true); + if (is_bool($temp)) { + $this->packet_type = false; + $this->packet_buffer = ''; + return false; + } + $this->packet_buffer.= $temp; + $tempLength-= strlen($temp); + } + + $stop = microtime(true); + + $this->packet_type = ord(Strings::shift($this->packet_buffer)); + + if ($this->use_request_id) { + extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))); // remove the request id + $length-= 5; // account for the request id and the packet type + } else { + $length-= 1; // account for the packet type + } + + $packet = Strings::shift($this->packet_buffer, $length); + + if (defined('NET_SFTP_LOGGING')) { + $packet_type = '<- ' . $this->packet_types[$this->packet_type] . + ' (' . round($stop - $start, 4) . 's)'; + if (NET_SFTP_LOGGING == self::LOG_REALTIME) { + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
      ';
      +                        $stop = '
      '; + } + echo $start . $this->format_log([$packet], [$packet_type]) . $stop; + @flush(); + @ob_flush(); + } else { + $this->packet_type_log[] = $packet_type; + if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { + $this->packet_log[] = $packet; + } + } + } + + if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) { + $this->requestBuffer[$packet_id] = array( + 'packet_type' => $this->packet_type, + 'packet' => $packet + ); + return $this->get_sftp_packet($request_id); + } + + return $packet; + } + + /** + * Returns a log of the packets that have been sent and received. + * + * Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') + * + * @access public + * @return array|string + */ + public function getSFTPLog() + { + if (!defined('NET_SFTP_LOGGING')) { + return false; + } + + switch (NET_SFTP_LOGGING) { + case self::LOG_COMPLEX: + return $this->format_log($this->packet_log, $this->packet_type_log); + break; + //case self::LOG_SIMPLE: + default: + return $this->packet_type_log; + } + } + + /** + * Returns all errors + * + * @return array + * @access public + */ + public function getSFTPErrors() + { + return $this->sftp_errors; + } + + /** + * Returns the last error + * + * @return string + * @access public + */ + public function getLastSFTPError() + { + return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : ''; + } + + /** + * Get supported SFTP versions + * + * @return array + * @access public + */ + public function getSupportedVersions() + { + $temp = ['version' => $this->version]; + if (isset($this->extensions['versions'])) { + $temp['extensions'] = $this->extensions['versions']; + } + return $temp; + } + + /** + * Disconnect + * + * @param int $reason + * @return bool + * @access protected + */ + protected function disconnect_helper($reason) + { + $this->pwd = false; + parent::disconnect_helper($reason); + } + + /** + * Enable Date Preservation + * + * @access public + */ + function enableDatePreservation() + { + $this->preserveTime = true; + } + + /** + * Disable Date Preservation + * + * @access public + */ + function disableDatePreservation() + { + $this->preserveTime = false; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php new file mode 100644 index 000000000..89a0e59b2 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php @@ -0,0 +1,794 @@ + + * @copyright 2013 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Net\SFTP; + +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Net\SFTP; +use phpseclib3\Net\SSH2; + +/** + * SFTP Stream Wrapper + * + * @package SFTP + * @author Jim Wigginton + * @access public + */ +class Stream extends SFTP +{ + /** + * SFTP instances + * + * Rather than re-create the connection we re-use instances if possible + * + * @var array + */ + static $instances; + + /** + * SFTP instance + * + * @var object + * @access private + */ + private $sftp; + + /** + * Path + * + * @var string + * @access private + */ + private $path; + + /** + * Mode + * + * @var string + * @access private + */ + private $mode; + + /** + * Position + * + * @var int + * @access private + */ + private $pos; + + /** + * Size + * + * @var int + * @access private + */ + private $size; + + /** + * Directory entries + * + * @var array + * @access private + */ + private $entries; + + /** + * EOF flag + * + * @var bool + * @access private + */ + private $eof; + + /** + * Context resource + * + * Technically this needs to be publicly accessible so PHP can set it directly + * + * @var resource + * @access public + */ + public $context; + + /** + * Notification callback function + * + * @var callable + * @access public + */ + private $notification; + + /** + * Registers this class as a URL wrapper. + * + * @param string $protocol The wrapper name to be registered. + * @return bool True on success, false otherwise. + * @access public + */ + public static function register($protocol = 'sftp') + { + if (in_array($protocol, stream_get_wrappers(), true)) { + return false; + } + return stream_wrapper_register($protocol, get_called_class()); + } + + /** + * The Constructor + * + * @access public + */ + public function __construct() + { + if (defined('NET_SFTP_STREAM_LOGGING')) { + echo "__construct()\r\n"; + } + } + + /** + * Path Parser + * + * Extract a path from a URI and actually connect to an SSH server if appropriate + * + * If "notification" is set as a context parameter the message code for successful login is + * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE. + * + * @param string $path + * @return string + * @access private + */ + protected function parse_path($path) + { + $orig = $path; + extract(parse_url($path) + ['port' => 22]); + if (isset($query)) { + $path.= '?' . $query; + } elseif (preg_match('/(\?|\?#)$/', $orig)) { + $path.= '?'; + } + if (isset($fragment)) { + $path.= '#' . $fragment; + } elseif ($orig[strlen($orig) - 1] == '#') { + $path.= '#'; + } + + if (!isset($host)) { + return false; + } + + if (isset($this->context)) { + $context = stream_context_get_params($this->context); + if (isset($context['notification'])) { + $this->notification = $context['notification']; + } + } + + if (preg_match('/^{[a-z0-9]+}$/i', $host)) { + $host = SSH2::getConnectionByResourceId($host); + if ($host === false) { + return false; + } + $this->sftp = $host; + } else { + if (isset($this->context)) { + $context = stream_context_get_options($this->context); + } + if (isset($context[$scheme]['session'])) { + $sftp = $context[$scheme]['session']; + } + if (isset($context[$scheme]['sftp'])) { + $sftp = $context[$scheme]['sftp']; + } + if (isset($sftp) && $sftp instanceof SFTP) { + $this->sftp = $sftp; + return $path; + } + if (isset($context[$scheme]['username'])) { + $user = $context[$scheme]['username']; + } + if (isset($context[$scheme]['password'])) { + $pass = $context[$scheme]['password']; + } + if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof PrivateKey) { + $pass = $context[$scheme]['privkey']; + } + + if (!isset($user) || !isset($pass)) { + return false; + } + + // casting $pass to a string is necessary in the event that it's a \phpseclib3\Crypt\RSA object + if (isset(self::$instances[$host][$port][$user][(string) $pass])) { + $this->sftp = self::$instances[$host][$port][$user][(string) $pass]; + } else { + $this->sftp = new SFTP($host, $port); + $this->sftp->disableStatCache(); + if (isset($this->notification) && is_callable($this->notification)) { + /* if !is_callable($this->notification) we could do this: + + user_error('fopen(): failed to call user notifier', E_USER_WARNING); + + the ftp wrapper gives errors like that when the notifier isn't callable. + i've opted not to do that, however, since the ftp wrapper gives the line + on which the fopen occurred as the line number - not the line that the + user_error is on. + */ + call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); + call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); + if (!$this->sftp->login($user, $pass)) { + call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0); + return false; + } + call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0); + } else { + if (!$this->sftp->login($user, $pass)) { + return false; + } + } + self::$instances[$host][$port][$user][(string) $pass] = $this->sftp; + } + } + + return $path; + } + + /** + * Opens file or URL + * + * @param string $path + * @param string $mode + * @param int $options + * @param string $opened_path + * @return bool + * @access public + */ + private function _stream_open($path, $mode, $options, &$opened_path) + { + $path = $this->parse_path($path); + + if ($path === false) { + return false; + } + $this->path = $path; + + $this->size = $this->sftp->filesize($path); + $this->mode = preg_replace('#[bt]$#', '', $mode); + $this->eof = false; + + if ($this->size === false) { + if ($this->mode[0] == 'r') { + return false; + } else { + $this->sftp->touch($path); + $this->size = 0; + } + } else { + switch ($this->mode[0]) { + case 'x': + return false; + case 'w': + $this->sftp->truncate($path, 0); + $this->size = 0; + } + } + + $this->pos = $this->mode[0] != 'a' ? 0 : $this->size; + + return true; + } + + /** + * Read from stream + * + * @param int $count + * @return mixed + * @access public + */ + private function _stream_read($count) + { + switch ($this->mode) { + case 'w': + case 'a': + case 'x': + case 'c': + return false; + } + + // commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite + //if ($this->pos >= $this->size) { + // $this->eof = true; + // return false; + //} + + $result = $this->sftp->get($this->path, false, $this->pos, $count); + if (isset($this->notification) && is_callable($this->notification)) { + if ($result === false) { + call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); + return 0; + } + // seems that PHP calls stream_read in 8k chunks + call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size); + } + + if (empty($result)) { // ie. false or empty string + $this->eof = true; + return false; + } + $this->pos+= strlen($result); + + return $result; + } + + /** + * Write to stream + * + * @param string $data + * @return mixed + * @access public + */ + private function _stream_write($data) + { + switch ($this->mode) { + case 'r': + return false; + } + + $result = $this->sftp->put($this->path, $data, SFTP::SOURCE_STRING, $this->pos); + if (isset($this->notification) && is_callable($this->notification)) { + if (!$result) { + call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); + return 0; + } + // seems that PHP splits up strings into 8k blocks before calling stream_write + call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data)); + } + + if ($result === false) { + return false; + } + $this->pos+= strlen($data); + if ($this->pos > $this->size) { + $this->size = $this->pos; + } + $this->eof = false; + return strlen($data); + } + + /** + * Retrieve the current position of a stream + * + * @return int + * @access public + */ + private function _stream_tell() + { + return $this->pos; + } + + /** + * Tests for end-of-file on a file pointer + * + * In my testing there are four classes functions that normally effect the pointer: + * fseek, fputs / fwrite, fgets / fread and ftruncate. + * + * Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof() + * will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof() + * will return false. do fread($fp, 1) and feof() will then return true. + * + * @return bool + * @access public + */ + private function _stream_eof() + { + return $this->eof; + } + + /** + * Seeks to specific location in a stream + * + * @param int $offset + * @param int $whence + * @return bool + * @access public + */ + private function _stream_seek($offset, $whence) + { + switch ($whence) { + case SEEK_SET: + if ($offset >= $this->size || $offset < 0) { + return false; + } + break; + case SEEK_CUR: + $offset+= $this->pos; + break; + case SEEK_END: + $offset+= $this->size; + } + + $this->pos = $offset; + $this->eof = false; + return true; + } + + /** + * Change stream options + * + * @param string $path + * @param int $option + * @param mixed $var + * @return bool + * @access public + */ + private function _stream_metadata($path, $option, $var) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + // stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined + // see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246 + // and https://github.com/php/php-src/blob/master/main/php_streams.h#L592 + switch ($option) { + case 1: // PHP_STREAM_META_TOUCH + return $this->sftp->touch($path, $var[0], $var[1]); + case 2: // PHP_STREAM_OWNER_NAME + case 3: // PHP_STREAM_GROUP_NAME + return false; + case 4: // PHP_STREAM_META_OWNER + return $this->sftp->chown($path, $var); + case 5: // PHP_STREAM_META_GROUP + return $this->sftp->chgrp($path, $var); + case 6: // PHP_STREAM_META_ACCESS + return $this->sftp->chmod($path, $var) !== false; + } + } + + /** + * Retrieve the underlaying resource + * + * @param int $cast_as + * @return resource + * @access public + */ + private function _stream_cast($cast_as) + { + return $this->sftp->fsock; + } + + /** + * Advisory file locking + * + * @param int $operation + * @return bool + * @access public + */ + private function _stream_lock($operation) + { + return false; + } + + /** + * Renames a file or directory + * + * Attempts to rename oldname to newname, moving it between directories if necessary. + * If newname exists, it will be overwritten. This is a departure from what \phpseclib3\Net\SFTP + * does. + * + * @param string $path_from + * @param string $path_to + * @return bool + * @access public + */ + private function _rename($path_from, $path_to) + { + $path1 = parse_url($path_from); + $path2 = parse_url($path_to); + unset($path1['path'], $path2['path']); + if ($path1 != $path2) { + return false; + } + + $path_from = $this->parse_path($path_from); + $path_to = parse_url($path_to); + if ($path_from === false) { + return false; + } + + $path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2 + // "It is an error if there already exists a file with the name specified by newpath." + // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5 + if (!$this->sftp->rename($path_from, $path_to)) { + if ($this->sftp->stat($path_to)) { + return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to); + } + return false; + } + + return true; + } + + /** + * Open directory handle + * + * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and + * removed in 5.4 I'm just going to ignore it. + * + * Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client + * sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting + * the SFTP specs: + * + * The SSH_FXP_NAME response has the following format: + * + * uint32 id + * uint32 count + * repeats count times: + * string filename + * string longname + * ATTRS attrs + * + * @param string $path + * @param int $options + * @return bool + * @access public + */ + private function _dir_opendir($path, $options) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + $this->pos = 0; + $this->entries = $this->sftp->nlist($path); + return $this->entries !== false; + } + + /** + * Read entry from directory handle + * + * @return mixed + * @access public + */ + private function _dir_readdir() + { + if (isset($this->entries[$this->pos])) { + return $this->entries[$this->pos++]; + } + return false; + } + + /** + * Rewind directory handle + * + * @return bool + * @access public + */ + private function _dir_rewinddir() + { + $this->pos = 0; + return true; + } + + /** + * Close directory handle + * + * @return bool + * @access public + */ + private function _dir_closedir() + { + return true; + } + + /** + * Create a directory + * + * Only valid $options is STREAM_MKDIR_RECURSIVE + * + * @param string $path + * @param int $mode + * @param int $options + * @return bool + * @access public + */ + private function _mkdir($path, $mode, $options) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE); + } + + /** + * Removes a directory + * + * Only valid $options is STREAM_MKDIR_RECURSIVE per , however, + * does not have a $recursive parameter as mkdir() does so I don't know how + * STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as + * $options. What does 8 correspond to? + * + * @param string $path + * @param int $options + * @return bool + * @access public + */ + private function _rmdir($path, $options) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + return $this->sftp->rmdir($path); + } + + /** + * Flushes the output + * + * See . Always returns true because \phpseclib3\Net\SFTP doesn't cache stuff before writing + * + * @return bool + * @access public + */ + private function _stream_flush() + { + return true; + } + + /** + * Retrieve information about a file resource + * + * @return mixed + * @access public + */ + private function _stream_stat() + { + $results = $this->sftp->stat($this->path); + if ($results === false) { + return false; + } + return $results; + } + + /** + * Delete a file + * + * @param string $path + * @return bool + * @access public + */ + private function _unlink($path) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + return $this->sftp->delete($path, false); + } + + /** + * Retrieve information about a file + * + * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib3\Net\SFTP\Stream is quiet by default + * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll + * cross that bridge when and if it's reached + * + * @param string $path + * @param int $flags + * @return mixed + * @access public + */ + private function _url_stat($path, $flags) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + $results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path); + if ($results === false) { + return false; + } + + return $results; + } + + /** + * Truncate stream + * + * @param int $new_size + * @return bool + * @access public + */ + private function _stream_truncate($new_size) + { + if (!$this->sftp->truncate($this->path, $new_size)) { + return false; + } + + $this->eof = false; + $this->size = $new_size; + + return true; + } + + /** + * Change stream options + * + * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't. + * The other two aren't supported because of limitations in \phpseclib3\Net\SFTP. + * + * @param int $option + * @param int $arg1 + * @param int $arg2 + * @return bool + * @access public + */ + private function _stream_set_option($option, $arg1, $arg2) + { + return false; + } + + /** + * Close an resource + * + * @access public + */ + private function _stream_close() + { + } + + /** + * __call Magic Method + * + * When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you. + * Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function + * lets you figure that out. + * + * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not + * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method. + * + * @param string $name + * @param array $arguments + * @return mixed + * @access public + */ + public function __call($name, $arguments) + { + if (defined('NET_SFTP_STREAM_LOGGING')) { + echo $name . '('; + $last = count($arguments) - 1; + foreach ($arguments as $i => $argument) { + var_export($argument); + if ($i != $last) { + echo ','; + } + } + echo ")\r\n"; + } + $name = '_' . $name; + if (!method_exists($this, $name)) { + return false; + } + return $this->$name(...$arguments); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php new file mode 100644 index 000000000..8ad3dcc36 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php @@ -0,0 +1,4955 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * + * login('username', $key)) { + * exit('Login Failed'); + * } + * + * echo $ssh->read('username@username:~$'); + * $ssh->write("ls -la\n"); + * echo $ssh->read('username@username:~$'); + * ?> + * + * + * @category Net + * @package SSH2 + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Net; + +use phpseclib3\Crypt\Blowfish; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RC4; +use phpseclib3\Crypt\Rijndael; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\DH; +use phpseclib3\Crypt\TripleDES; +use phpseclib3\Crypt\Twofish; +use phpseclib3\Crypt\ChaCha20; +use phpseclib3\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. +use phpseclib3\System\SSH\Agent; +use phpseclib3\System\SSH\Agent\Identity as AgentIdentity; +use phpseclib3\Exception\NoSupportedAlgorithmsException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Exception\ConnectionClosedException; +use phpseclib3\Exception\UnableToConnectException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Common\Functions\Strings; + +/** + * Pure-PHP implementation of SSHv2. + * + * @package SSH2 + * @author Jim Wigginton + * @access public + */ +class SSH2 +{ + // Execution Bitmap Masks + const MASK_CONSTRUCTOR = 0x00000001; + const MASK_CONNECTED = 0x00000002; + const MASK_LOGIN_REQ = 0x00000004; + const MASK_LOGIN = 0x00000008; + const MASK_SHELL = 0x00000010; + const MASK_WINDOW_ADJUST = 0x00000020; + + /* + * Channel constants + * + * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer + * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with + * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a + * recipient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel + * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snippet: + * The 'recipient channel' is the channel number given in the original + * open request, and 'sender channel' is the channel number allocated by + * the other side. + * + * @see \phpseclib3\Net\SSH2::send_channel_packet() + * @see \phpseclib3\Net\SSH2::get_channel_packet() + * @access private + */ + const CHANNEL_EXEC = 1; // PuTTy uses 0x100 + const CHANNEL_SHELL = 2; + const CHANNEL_SUBSYSTEM = 3; + const CHANNEL_AGENT_FORWARD = 4; + const CHANNEL_KEEP_ALIVE = 5; + + /** + * Returns the message numbers + * + * @access public + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_SIMPLE = 1; + /** + * Returns the message content + * + * @access public + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_COMPLEX = 2; + /** + * Outputs the content real-time + * + * @access public + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_REALTIME = 3; + /** + * Dumps the content real-time to a file + * + * @access public + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_REALTIME_FILE = 4; + /** + * Make sure that the log never gets larger than this + * + * @access public + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_MAX_SIZE = 1048576; // 1024 * 1024 + + /** + * Returns when a string matching $expect exactly is found + * + * @access public + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_SIMPLE = 1; + /** + * Returns when a string matching the regular expression $expect is found + * + * @access public + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_REGEX = 2; + /** + * Returns whenever a data packet is received. + * + * Some data packets may only contain a single character so it may be necessary + * to call read() multiple times when using this option + * + * @access public + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_NEXT = 3; + + /** + * The SSH identifier + * + * @var string + * @access private + */ + private $identifier; + + /** + * The Socket Object + * + * @var object + * @access private + */ + protected $fsock; + + /** + * Execution Bitmap + * + * The bits that are set represent functions that have been called already. This is used to determine + * if a requisite function has been successfully executed. If not, an error should be thrown. + * + * @var int + * @access private + */ + protected $bitmap = 0; + + /** + * Error information + * + * @see self::getErrors() + * @see self::getLastError() + * @var array + * @access private + */ + private $errors = []; + + /** + * Server Identifier + * + * @see self::getServerIdentification() + * @var array|false + * @access private + */ + private $server_identifier = false; + + /** + * Key Exchange Algorithms + * + * @see self::getKexAlgorithims() + * @var array|false + * @access private + */ + private $kex_algorithms = false; + + /** + * Key Exchange Algorithm + * + * @see self::getMethodsNegotiated() + * @var string|false + * @access private + */ + private $kex_algorithm = false; + + /** + * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + * @access private + */ + private $kex_dh_group_size_min = 1536; + + /** + * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + * @access private + */ + private $kex_dh_group_size_preferred = 2048; + + /** + * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + * @access private + */ + private $kex_dh_group_size_max = 4096; + + /** + * Server Host Key Algorithms + * + * @see self::getServerHostKeyAlgorithms() + * @var array|false + * @access private + */ + private $server_host_key_algorithms = false; + + /** + * Encryption Algorithms: Client to Server + * + * @see self::getEncryptionAlgorithmsClient2Server() + * @var array|false + * @access private + */ + private $encryption_algorithms_client_to_server = false; + + /** + * Encryption Algorithms: Server to Client + * + * @see self::getEncryptionAlgorithmsServer2Client() + * @var array|false + * @access private + */ + private $encryption_algorithms_server_to_client = false; + + /** + * MAC Algorithms: Client to Server + * + * @see self::getMACAlgorithmsClient2Server() + * @var array|false + * @access private + */ + private $mac_algorithms_client_to_server = false; + + /** + * MAC Algorithms: Server to Client + * + * @see self::getMACAlgorithmsServer2Client() + * @var array|false + * @access private + */ + private $mac_algorithms_server_to_client = false; + + /** + * Compression Algorithms: Client to Server + * + * @see self::getCompressionAlgorithmsClient2Server() + * @var array|false + * @access private + */ + private $compression_algorithms_client_to_server = false; + + /** + * Compression Algorithms: Server to Client + * + * @see self::getCompressionAlgorithmsServer2Client() + * @var array|false + * @access private + */ + private $compression_algorithms_server_to_client = false; + + /** + * Languages: Server to Client + * + * @see self::getLanguagesServer2Client() + * @var array|false + * @access private + */ + private $languages_server_to_client = false; + + /** + * Languages: Client to Server + * + * @see self::getLanguagesClient2Server() + * @var array|false + * @access private + */ + private $languages_client_to_server = false; + + /** + * Preferred Algorithms + * + * @see self::setPreferredAlgorithms() + * @var array + * @access private + */ + private $preferred = []; + + /** + * Block Size for Server to Client Encryption + * + * "Note that the length of the concatenation of 'packet_length', + * 'padding_length', 'payload', and 'random padding' MUST be a multiple + * of the cipher block size or 8, whichever is larger. This constraint + * MUST be enforced, even when using stream ciphers." + * + * -- http://tools.ietf.org/html/rfc4253#section-6 + * + * @see self::__construct() + * @see self::_send_binary_packet() + * @var int + * @access private + */ + private $encrypt_block_size = 8; + + /** + * Block Size for Client to Server Encryption + * + * @see self::__construct() + * @see self::_get_binary_packet() + * @var int + * @access private + */ + private $decrypt_block_size = 8; + + /** + * Server to Client Encryption Object + * + * @see self::_get_binary_packet() + * @var object + * @access private + */ + private $decrypt = false; + + /** + * Server to Client Length Encryption Object + * + * @see self::_get_binary_packet() + * @var object + * @access private + */ + private $lengthDecrypt = false; + + /** + * Client to Server Encryption Object + * + * @see self::_send_binary_packet() + * @var object + * @access private + */ + private $encrypt = false; + + /** + * Client to Server Length Encryption Object + * + * @see self::_send_binary_packet() + * @var object + * @access private + */ + private $lengthEncrypt = false; + + /** + * Client to Server HMAC Object + * + * @see self::_send_binary_packet() + * @var object + * @access private + */ + private $hmac_create = false; + + /** + * Server to Client HMAC Object + * + * @see self::_get_binary_packet() + * @var object + * @access private + */ + private $hmac_check = false; + + /** + * Size of server to client HMAC + * + * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read. + * For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is + * append it. + * + * @see self::_get_binary_packet() + * @var int + * @access private + */ + private $hmac_size = false; + + /** + * Server Public Host Key + * + * @see self::getServerPublicHostKey() + * @var string + * @access private + */ + private $server_public_host_key; + + /** + * Session identifier + * + * "The exchange hash H from the first key exchange is additionally + * used as the session identifier, which is a unique identifier for + * this connection." + * + * -- http://tools.ietf.org/html/rfc4253#section-7.2 + * + * @see self::_key_exchange() + * @var string + * @access private + */ + private $session_id = false; + + /** + * Exchange hash + * + * The current exchange hash + * + * @see self::_key_exchange() + * @var string + * @access private + */ + private $exchange_hash = false; + + /** + * Message Numbers + * + * @see self::__construct() + * @var array + * @access private + */ + private $message_numbers = []; + + /** + * Disconnection Message 'reason codes' defined in RFC4253 + * + * @see self::__construct() + * @var array + * @access private + */ + private $disconnect_reasons = []; + + /** + * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 + * + * @see self::__construct() + * @var array + * @access private + */ + private $channel_open_failure_reasons = []; + + /** + * Terminal Modes + * + * @link http://tools.ietf.org/html/rfc4254#section-8 + * @see self::__construct() + * @var array + * @access private + */ + private $terminal_modes = []; + + /** + * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes + * + * @link http://tools.ietf.org/html/rfc4254#section-5.2 + * @see self::__construct() + * @var array + * @access private + */ + private $channel_extended_data_type_codes = []; + + /** + * Send Sequence Number + * + * See 'Section 6.4. Data Integrity' of rfc4253 for more info. + * + * @see self::_send_binary_packet() + * @var int + * @access private + */ + private $send_seq_no = 0; + + /** + * Get Sequence Number + * + * See 'Section 6.4. Data Integrity' of rfc4253 for more info. + * + * @see self::_get_binary_packet() + * @var int + * @access private + */ + private $get_seq_no = 0; + + /** + * Server Channels + * + * Maps client channels to server channels + * + * @see self::get_channel_packet() + * @see self::exec() + * @var array + * @access private + */ + protected $server_channels = []; + + /** + * Channel Buffers + * + * If a client requests a packet from one channel but receives two packets from another those packets should + * be placed in a buffer + * + * @see self::get_channel_packet() + * @see self::exec() + * @var array + * @access private + */ + private $channel_buffers = []; + + /** + * Channel Status + * + * Contains the type of the last sent message + * + * @see self::get_channel_packet() + * @var array + * @access private + */ + protected $channel_status = []; + + /** + * Packet Size + * + * Maximum packet size indexed by channel + * + * @see self::send_channel_packet() + * @var array + * @access private + */ + private $packet_size_client_to_server = []; + + /** + * Message Number Log + * + * @see self::getLog() + * @var array + * @access private + */ + private $message_number_log = []; + + /** + * Message Log + * + * @see self::getLog() + * @var array + * @access private + */ + private $message_log = []; + + /** + * The Window Size + * + * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB) + * + * @var int + * @see self::send_channel_packet() + * @see self::exec() + * @access private + */ + protected $window_size = 0x7FFFFFFF; + + /** + * What we resize the window to + * + * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes. + * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so + * we'll just do what PuTTY does + * + * @var int + * @see self::_send_channel_packet() + * @see self::exec() + * @access private + */ + var $window_resize = 0x40000000; + + /** + * Window size, server to client + * + * Window size indexed by channel + * + * @see self::send_channel_packet() + * @var array + * @access private + */ + protected $window_size_server_to_client = []; + + /** + * Window size, client to server + * + * Window size indexed by channel + * + * @see self::get_channel_packet() + * @var array + * @access private + */ + private $window_size_client_to_server = []; + + /** + * Server signature + * + * Verified against $this->session_id + * + * @see self::getServerPublicHostKey() + * @var string + * @access private + */ + private $signature = ''; + + /** + * Server signature format + * + * ssh-rsa or ssh-dss. + * + * @see self::getServerPublicHostKey() + * @var string + * @access private + */ + private $signature_format = ''; + + /** + * Interactive Buffer + * + * @see self::read() + * @var array + * @access private + */ + private $interactiveBuffer = ''; + + /** + * Current log size + * + * Should never exceed self::LOG_MAX_SIZE + * + * @see self::_send_binary_packet() + * @see self::_get_binary_packet() + * @var int + * @access private + */ + private $log_size; + + /** + * Timeout + * + * @see self::setTimeout() + * @access private + */ + protected $timeout; + + /** + * Current Timeout + * + * @see self::get_channel_packet() + * @access private + */ + protected $curTimeout; + + /** + * Keep Alive Interval + * + * @see self::setKeepAlive() + * @access private + */ + var $keepAlive; + + /** + * Real-time log file pointer + * + * @see self::_append_log() + * @var resource + * @access private + */ + private $realtime_log_file; + + /** + * Real-time log file size + * + * @see self::_append_log() + * @var int + * @access private + */ + private $realtime_log_size; + + /** + * Has the signature been validated? + * + * @see self::getServerPublicHostKey() + * @var bool + * @access private + */ + private $signature_validated = false; + + /** + * Real-time log file wrap boolean + * + * @see self::_append_log() + * @access private + */ + private $realtime_log_wrap; + + /** + * Flag to suppress stderr from output + * + * @see self::enableQuietMode() + * @access private + */ + private $quiet_mode = false; + + /** + * Time of first network activity + * + * @var int + * @access private + */ + private $last_packet; + + /** + * Exit status returned from ssh if any + * + * @var int + * @access private + */ + private $exit_status; + + /** + * Flag to request a PTY when using exec() + * + * @var bool + * @see self::enablePTY() + * @access private + */ + private $request_pty = false; + + /** + * Flag set while exec() is running when using enablePTY() + * + * @var bool + * @access private + */ + private $in_request_pty_exec = false; + + /** + * Flag set after startSubsystem() is called + * + * @var bool + * @access private + */ + private $in_subsystem; + + /** + * Contents of stdError + * + * @var string + * @access private + */ + private $stdErrorLog; + + /** + * The Last Interactive Response + * + * @see self::_keyboard_interactive_process() + * @var string + * @access private + */ + private $last_interactive_response = ''; + + /** + * Keyboard Interactive Request / Responses + * + * @see self::_keyboard_interactive_process() + * @var array + * @access private + */ + private $keyboard_requests_responses = []; + + /** + * Banner Message + * + * Quoting from the RFC, "in some jurisdictions, sending a warning message before + * authentication may be relevant for getting legal protection." + * + * @see self::_filter() + * @see self::getBannerMessage() + * @var string + * @access private + */ + private $banner_message = ''; + + /** + * Did read() timeout or return normally? + * + * @see self::isTimeout() + * @var bool + * @access private + */ + private $is_timeout = false; + + /** + * Log Boundary + * + * @see self::_format_log() + * @var string + * @access private + */ + private $log_boundary = ':'; + + /** + * Log Long Width + * + * @see self::_format_log() + * @var int + * @access private + */ + private $log_long_width = 65; + + /** + * Log Short Width + * + * @see self::_format_log() + * @var int + * @access private + */ + private $log_short_width = 16; + + /** + * Hostname + * + * @see self::__construct() + * @see self::_connect() + * @var string + * @access private + */ + private $host; + + /** + * Port Number + * + * @see self::__construct() + * @see self::_connect() + * @var int + * @access private + */ + private $port; + + /** + * Number of columns for terminal window size + * + * @see self::getWindowColumns() + * @see self::setWindowColumns() + * @see self::setWindowSize() + * @var int + * @access private + */ + private $windowColumns = 80; + + /** + * Number of columns for terminal window size + * + * @see self::getWindowRows() + * @see self::setWindowRows() + * @see self::setWindowSize() + * @var int + * @access private + */ + private $windowRows = 24; + + /** + * Crypto Engine + * + * @see self::setCryptoEngine() + * @see self::_key_exchange() + * @var int + * @access private + */ + private static $crypto_engine = false; + + /** + * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario + * + * @var \phpseclib3\System\Ssh\Agent + * @access private + */ + private $agent; + + /** + * Connection storage to replicates ssh2 extension functionality: + * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples} + * + * @var SSH2[] + */ + private static $connections; + + /** + * Send the identification string first? + * + * @var bool + * @access private + */ + private $send_id_string_first = true; + + /** + * Send the key exchange initiation packet first? + * + * @var bool + * @access private + */ + private $send_kex_first = true; + + /** + * Some versions of OpenSSH incorrectly calculate the key size + * + * @var bool + * @access private + */ + private $bad_key_size_fix = false; + + /** + * Should we try to re-connect to re-establish keys? + * + * @var bool + * @access private + */ + private $retry_connect = false; + + /** + * Binary Packet Buffer + * + * @var string|false + * @access private + */ + private $binary_packet_buffer = false; + + /** + * Preferred Signature Format + * + * @var string|false + * @access private + */ + protected $preferred_signature_format = false; + + /** + * Authentication Credentials + * + * @var array + * @access private + */ + protected $auth = []; + + /** + * Default Constructor. + * + * $host can either be a string, representing the host, or a stream resource. + * + * @param mixed $host + * @param int $port + * @param int $timeout + * @see self::login() + * @return SSH2|void + * @access public + */ + public function __construct($host, $port = 22, $timeout = 10) + { + $this->message_numbers = [ + 1 => 'NET_SSH2_MSG_DISCONNECT', + 2 => 'NET_SSH2_MSG_IGNORE', + 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', + 4 => 'NET_SSH2_MSG_DEBUG', + 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', + 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', + 20 => 'NET_SSH2_MSG_KEXINIT', + 21 => 'NET_SSH2_MSG_NEWKEYS', + 30 => 'NET_SSH2_MSG_KEXDH_INIT', + 31 => 'NET_SSH2_MSG_KEXDH_REPLY', + 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', + 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', + 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', + 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', + + 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', + 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', + 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', + 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', + 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', + 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', + 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', + 94 => 'NET_SSH2_MSG_CHANNEL_DATA', + 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', + 96 => 'NET_SSH2_MSG_CHANNEL_EOF', + 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', + 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', + 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', + 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' + ]; + $this->disconnect_reasons = [ + 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', + 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', + 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', + 4 => 'NET_SSH2_DISCONNECT_RESERVED', + 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', + 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', + 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', + 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', + 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', + 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', + 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', + 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', + 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', + 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', + 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' + ]; + $this->channel_open_failure_reasons = [ + 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' + ]; + $this->terminal_modes = [ + 0 => 'NET_SSH2_TTY_OP_END' + ]; + $this->channel_extended_data_type_codes = [ + 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' + ]; + + $this->define_array( + $this->message_numbers, + $this->disconnect_reasons, + $this->channel_open_failure_reasons, + $this->terminal_modes, + $this->channel_extended_data_type_codes, + [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], + [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], + [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', + 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], + // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} + [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', + 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', + 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', + 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', + 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], + // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) + [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', + 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] + ); + + self::$connections[$this->getResourceId()] = $this; + + if (is_resource($host)) { + $this->fsock = $host; + return; + } + + if (is_string($host)) { + $this->host = $host; + $this->port = $port; + $this->timeout = $timeout; + } + } + + /** + * Set Crypto Engine Mode + * + * Possible $engine values: + * OpenSSL, mcrypt, Eval, PHP + * + * @param int $engine + * @access public + */ + public static function setCryptoEngine($engine) + { + self::$crypto_engine = $engine; + } + + /** + * Send Identification String First + * + * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, + * both sides MUST send an identification string". It does not say which side sends it first. In + * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + * @access public + */ + public function sendIdentificationStringFirst() + { + $this->send_id_string_first = true; + } + + /** + * Send Identification String Last + * + * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, + * both sides MUST send an identification string". It does not say which side sends it first. In + * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + * @access public + */ + public function sendIdentificationStringLast() + { + $this->send_id_string_first = false; + } + + /** + * Send SSH_MSG_KEXINIT First + * + * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending + * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory + * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + * @access public + */ + public function sendKEXINITFirst() + { + $this->send_kex_first = true; + } + + /** + * Send SSH_MSG_KEXINIT Last + * + * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending + * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory + * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + * @access public + */ + public function sendKEXINITLast() + { + $this->send_kex_first = false; + } + + /** + * Connect to an SSHv2 server + * + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + * @access private + */ + private function connect() + { + if ($this->bitmap & self::MASK_CONSTRUCTOR) { + return false; + } + + $this->bitmap |= self::MASK_CONSTRUCTOR; + + $this->curTimeout = $this->timeout; + + $this->last_packet = microtime(true); + + if (!is_resource($this->fsock)) { + $start = microtime(true); + // with stream_select a timeout of 0 means that no timeout takes place; + // with fsockopen a timeout of 0 means that you instantly timeout + // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0 + $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout); + if (!$this->fsock) { + $host = $this->host . ':' . $this->port; + throw new UnableToConnectException(rtrim("Cannot connect to $host. Error $errno. $errstr")); + } + $elapsed = microtime(true) - $start; + + if ($this->curTimeout) { + $this->curTimeout-= $elapsed; + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return false; + } + } + } + + $this->identifier = $this->generate_identifier(); + + if ($this->send_id_string_first) { + fputs($this->fsock, $this->identifier . "\r\n"); + } + + /* According to the SSH2 specs, + + "The server MAY send other lines of data before sending the version + string. Each line SHOULD be terminated by a Carriage Return and Line + Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded + in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients + MUST be able to process such lines." */ + $data = ''; + while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) { + $line = ''; + while (true) { + if ($this->curTimeout) { + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return false; + } + $read = [$this->fsock]; + $write = $except = null; + $start = microtime(true); + $sec = floor($this->curTimeout); + $usec = 1000000 * ($this->curTimeout - $sec); + if (@stream_select($read, $write, $except, $sec, $usec) === false) { + $this->is_timeout = true; + return false; + } + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + } + + $temp = stream_get_line($this->fsock, 255, "\n"); + if (strlen($temp) == 255) { + continue; + } + if ($temp === false) { + return false; + } + + $line.= "$temp\n"; + + // quoting RFC4253, "Implementers who wish to maintain + // compatibility with older, undocumented versions of this protocol may + // want to process the identification string without expecting the + // presence of the carriage return character for reasons described in + // Section 5 of this document." + + //if (substr($line, -2) == "\r\n") { + // break; + //} + + break; + } + + $data.= $line; + } + + if (feof($this->fsock)) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed by server'); + } + + $extra = $matches[1]; + + if (defined('NET_SSH2_LOGGING')) { + $this->append_log('<-', $matches[0]); + $this->append_log('->', $this->identifier . "\r\n"); + } + + $this->server_identifier = trim($temp, "\r\n"); + if (strlen($extra)) { + $this->errors[] = $data; + } + + if (version_compare($matches[3], '1.99', '<')) { + $this->bitmap = 0; + throw new UnableToConnectException("Cannot connect to SSH $matches[3] servers"); + } + + if (!$this->send_id_string_first) { + fputs($this->fsock, $this->identifier . "\r\n"); + } + + if (!$this->send_kex_first) { + $response = $this->get_binary_packet(); + if ($response === false) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed by server'); + } + + if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) { + $this->bitmap = 0; + throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + } + + if (!$this->key_exchange($response)) { + return false; + } + } + + if ($this->send_kex_first && !$this->key_exchange()) { + return false; + } + + $this->bitmap|= self::MASK_CONNECTED; + + return true; + } + + /** + * Generates the SSH identifier + * + * You should overwrite this method in your own class if you want to use another identifier + * + * @access protected + * @return string + */ + private function generate_identifier() + { + $identifier = 'SSH-2.0-phpseclib_3.0'; + + $ext = []; + if (extension_loaded('sodium')) { + $ext[] = 'libsodium'; + } + + if (extension_loaded('openssl')) { + $ext[] = 'openssl'; + } elseif (extension_loaded('mcrypt')) { + $ext[] = 'mcrypt'; + } + + if (extension_loaded('gmp')) { + $ext[] = 'gmp'; + } elseif (extension_loaded('bcmath')) { + $ext[] = 'bcmath'; + } + + if (!empty($ext)) { + $identifier .= ' (' . implode(', ', $ext) . ')'; + } + + return $identifier; + } + + /** + * Key Exchange + * + * @return bool + * @param string|bool $kexinit_payload_server optional + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible + * @access private + */ + private function key_exchange($kexinit_payload_server = false) + { + $preferred = $this->preferred; + + $kex_algorithms = isset($preferred['kex']) ? + $preferred['kex'] : + SSH2::getSupportedKEXAlgorithms(); + $server_host_key_algorithms = isset($preferred['hostkey']) ? + $preferred['hostkey'] : + SSH2::getSupportedHostKeyAlgorithms(); + $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ? + $preferred['server_to_client']['crypt'] : + SSH2::getSupportedEncryptionAlgorithms(); + $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ? + $preferred['client_to_server']['crypt'] : + SSH2::getSupportedEncryptionAlgorithms(); + $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ? + $preferred['server_to_client']['mac'] : + SSH2::getSupportedMACAlgorithms(); + $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ? + $preferred['client_to_server']['mac'] : + SSH2::getSupportedMACAlgorithms(); + $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ? + $preferred['server_to_client']['comp'] : + SSH2::getSupportedCompressionAlgorithms(); + $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ? + $preferred['client_to_server']['comp'] : + SSH2::getSupportedCompressionAlgorithms(); + + // some SSH servers have buggy implementations of some of the above algorithms + switch (true) { + case $this->server_identifier == 'SSH-2.0-SSHD': + case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK': + if (!isset($preferred['server_to_client']['mac'])) { + $s2c_mac_algorithms = array_values(array_diff( + $s2c_mac_algorithms, + ['hmac-sha1-96', 'hmac-md5-96'] + )); + } + if (!isset($preferred['client_to_server']['mac'])) { + $c2s_mac_algorithms = array_values(array_diff( + $c2s_mac_algorithms, + ['hmac-sha1-96', 'hmac-md5-96'] + )); + } + } + + $client_cookie = Random::string(16); + + $kexinit_payload_client = pack('Ca*', NET_SSH2_MSG_KEXINIT, $client_cookie); + $kexinit_payload_client.= Strings::packSSH2( + 'L10bN', + $kex_algorithms, + $server_host_key_algorithms, + $c2s_encryption_algorithms, + $s2c_encryption_algorithms, + $c2s_mac_algorithms, + $s2c_mac_algorithms, + $c2s_compression_algorithms, + $s2c_compression_algorithms, + [], // language, client to server + [], // language, server to client + false, // first_kex_packet_follows + 0 // reserved for future extension + ); + + if ($this->send_kex_first) { + $this->send_binary_packet($kexinit_payload_client); + + $kexinit_payload_server = $this->get_binary_packet(); + if ($kexinit_payload_server === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + } + } + + $response = $kexinit_payload_server; + Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) + $server_cookie = Strings::shift($response, 16); + + list( + $this->kex_algorithms, + $this->server_host_key_algorithms, + $this->encryption_algorithms_client_to_server, + $this->encryption_algorithms_server_to_client, + $this->mac_algorithms_client_to_server, + $this->mac_algorithms_server_to_client, + $this->compression_algorithms_client_to_server, + $this->compression_algorithms_server_to_client, + $this->languages_client_to_server, + $this->languages_server_to_client, + $first_kex_packet_follows + ) = Strings::unpackSSH2('L10C', $response); + + if (!$this->send_kex_first) { + $this->send_binary_packet($kexinit_payload_client); + } + + // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange + + // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the + // diffie-hellman key exchange as fast as possible + $decrypt = self::array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); + $decryptKeyLength = $this->encryption_algorithm_to_key_size($decrypt); + if ($decryptKeyLength === null) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found'); + } + + $encrypt = self::array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); + $encryptKeyLength = $this->encryption_algorithm_to_key_size($encrypt); + if ($encryptKeyLength === null) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found'); + } + + // through diffie-hellman key exchange a symmetric key is obtained + $this->kex_algorithm = self::array_intersect_first($kex_algorithms, $this->kex_algorithms); + if ($this->kex_algorithm === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found'); + } + + $server_host_key_algorithm = self::array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); + if ($server_host_key_algorithm === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); + } + + $mac_algorithm_out = self::array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); + if ($mac_algorithm_out === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found'); + } + + $mac_algorithm_in = self::array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); + if ($mac_algorithm_in === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found'); + } + + $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client); + if ($compression_algorithm_in === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found'); + } + $this->decompress = $compression_algorithm_in == 'zlib'; + + $compression_algorithm_out = self::array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_out === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found'); + } + $this->compress = $compression_algorithm_out == 'zlib'; + + switch ($this->kex_algorithm) { + case 'diffie-hellman-group15-sha512': + case 'diffie-hellman-group16-sha512': + case 'diffie-hellman-group17-sha512': + case 'diffie-hellman-group18-sha512': + case 'ecdh-sha2-nistp521': + $kexHash = new Hash('sha512'); + break; + case 'ecdh-sha2-nistp384': + $kexHash = new Hash('sha384'); + break; + case 'diffie-hellman-group-exchange-sha256': + case 'diffie-hellman-group14-sha256': + case 'ecdh-sha2-nistp256': + case 'curve25519-sha256@libssh.org': + case 'curve25519-sha256': + $kexHash = new Hash('sha256'); + break; + default: + $kexHash = new Hash('sha1'); + } + + // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. + + $exchange_hash_rfc4419 = ''; + + if (strpos($this->kex_algorithm, 'curve25519-sha256') === 0 || strpos($this->kex_algorithm, 'ecdh-sha2-nistp') === 0) { + $curve = strpos($this->kex_algorithm, 'curve25519-sha256') === 0 ? + 'Curve25519' : + substr($this->kex_algorithm, 10); + $ourPrivate = EC::createKey($curve); + $ourPublicBytes = $ourPrivate->getPublicKey()->getEncodedCoordinates(); + $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY'; + } else { + if (strpos($this->kex_algorithm, 'diffie-hellman-group-exchange') === 0) { + $dh_group_sizes_packed = pack( + 'NNN', + $this->kex_dh_group_size_min, + $this->kex_dh_group_size_preferred, + $this->kex_dh_group_size_max + ); + $packet = pack( + 'Ca*', + NET_SSH2_MSG_KEXDH_GEX_REQUEST, + $dh_group_sizes_packed + ); + $this->send_binary_packet($packet); + $this->updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type, $primeBytes, $gBytes) = Strings::unpackSSH2('Css', $response); + if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP'); + } + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); + $prime = new BigInteger($primeBytes, -256); + $g = new BigInteger($gBytes, -256); + + $exchange_hash_rfc4419 = $dh_group_sizes_packed . Strings::packSSH2( + 'ss', + $primeBytes, + $gBytes + ); + + $params = DH::createParameters($prime, $g); + $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY'; + } else { + $params = DH::createParameters($this->kex_algorithm); + $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY'; + } + + $keyLength = min($kexHash->getLengthInBytes(), max($encryptKeyLength, $decryptKeyLength)); + + $ourPrivate = DH::createKey($params, 16 * $keyLength); // 2 * 8 * $keyLength + $ourPublic = $ourPrivate->getPublicKey()->toBigInteger(); + $ourPublicBytes = $ourPublic->toBytes(true); + } + + $data = pack('CNa*', constant($clientKexInitMessage), strlen($ourPublicBytes), $ourPublicBytes); + + $this->send_binary_packet($data); + + switch ($clientKexInitMessage) { + case 'NET_SSH2_MSG_KEX_ECDH_INIT': + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); + break; + case 'NET_SSH2_MSG_KEXDH_GEX_INIT': + $this->updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); + } + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + if (!strlen($response)) { + return false; + } + + list( + $type, + $server_public_host_key, + $theirPublicBytes, + $this->signature + ) = Strings::unpackSSH2('Csss', $response); + + if ($type != constant($serverKexReplyMessage)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException("Expected $serverKexReplyMessage"); + } + switch ($serverKexReplyMessage) { + case 'NET_SSH2_MSG_KEX_ECDH_REPLY': + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); + break; + case 'NET_SSH2_MSG_KEXDH_GEX_REPLY': + $this->updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); + } + + $this->server_public_host_key = $server_public_host_key; + list($public_key_format) = Strings::unpackSSH2('s', $server_public_host_key); + + if (strlen($this->signature) < 4) { + return false; + } + $temp = unpack('Nlength', substr($this->signature, 0, 4)); + $this->signature_format = substr($this->signature, 4, $temp['length']); + $keyBytes = DH::computeSecret($ourPrivate, $theirPublicBytes); + if (($keyBytes & "\xFF\x80") === "\x00\x00") { + $keyBytes = substr($keyBytes, 1); + } elseif (($keyBytes[0] & "\x80") === "\x80") { + $keyBytes = "\0$keyBytes"; + } + + $this->exchange_hash = Strings::packSSH2('s5', + $this->identifier, + $this->server_identifier, + $kexinit_payload_client, + $kexinit_payload_server, + $this->server_public_host_key + ); + $this->exchange_hash.= $exchange_hash_rfc4419; + $this->exchange_hash.= Strings::packSSH2('s3', + $ourPublicBytes, + $theirPublicBytes, + $keyBytes + ); + + $this->exchange_hash = $kexHash->hash($this->exchange_hash); + + if ($this->session_id === false) { + $this->session_id = $this->exchange_hash; + } + + switch ($server_host_key_algorithm) { + case 'rsa-sha2-256': + case 'rsa-sha2-512': + //case 'ssh-rsa': + $expected_key_format = 'ssh-rsa'; + break; + default: + $expected_key_format = $server_host_key_algorithm; + } + if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { + switch (true) { + case $this->signature_format == $server_host_key_algorithm: + case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': + case $this->signature_format != 'ssh-rsa': + $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + throw new \RuntimeException('Server Host Key Algorithm Mismatch'); + } + } + + $packet = pack('C', NET_SSH2_MSG_NEWKEYS); + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + if ($type != NET_SSH2_MSG_NEWKEYS) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); + } + + $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); + + $this->encrypt = self::encryption_algorithm_to_crypt_instance($encrypt); + if ($this->encrypt) { + if (self::$crypto_engine) { + $this->encrypt->setPreferredEngine(self::$crypto_engine); + } + if ($this->encrypt->getBlockLengthInBytes()) { + $this->encrypt_block_size = $this->encrypt->getBlockLengthInBytes(); + } + $this->encrypt->disablePadding(); + + if ($this->encrypt->usesIV()) { + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); + while ($this->encrypt_block_size > strlen($iv)) { + $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); + } + $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); + } + + switch ($encrypt) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); + $this->encrypt->fixed = substr($nonce, 0, 4); + $this->encrypt->invocation_counter = substr($nonce, 4, 8); + case 'chacha20-poly1305@openssh.com': + break; + default: + $this->encrypt->enableContinuousBuffer(); + } + + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); + while ($encryptKeyLength > strlen($key)) { + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + switch ($encrypt) { + case 'chacha20-poly1305@openssh.com': + $encryptKeyLength = 32; + $this->lengthEncrypt = self::encryption_algorithm_to_crypt_instance($encrypt); + $this->lengthEncrypt->setKey(substr($key, 32, 32)); + } + $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); + $this->encrypt->name = $encrypt; + } + + $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt); + if ($this->decrypt) { + if (self::$crypto_engine) { + $this->decrypt->setPreferredEngine(self::$crypto_engine); + } + if ($this->decrypt->getBlockLengthInBytes()) { + $this->decrypt_block_size = $this->decrypt->getBlockLengthInBytes(); + } + $this->decrypt->disablePadding(); + + if ($this->decrypt->usesIV()) { + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); + while ($this->decrypt_block_size > strlen($iv)) { + $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); + } + $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); + } + + switch ($decrypt) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + // see https://tools.ietf.org/html/rfc5647#section-7.1 + $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); + $this->decrypt->fixed = substr($nonce, 0, 4); + $this->decrypt->invocation_counter = substr($nonce, 4, 8); + case 'chacha20-poly1305@openssh.com': + break; + default: + $this->decrypt->enableContinuousBuffer(); + } + + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); + while ($decryptKeyLength > strlen($key)) { + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + switch ($decrypt) { + case 'chacha20-poly1305@openssh.com': + $decryptKeyLength = 32; + $this->lengthDecrypt = self::encryption_algorithm_to_crypt_instance($decrypt); + $this->lengthDecrypt->setKey(substr($key, 32, 32)); + } + $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); + $this->decrypt->name = $decrypt; + } + + /* The "arcfour128" algorithm is the RC4 cipher, as described in + [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream + generated by the cipher MUST be discarded, and the first byte of the + first encrypted packet MUST be encrypted using the 1537th byte of + keystream. + + -- http://tools.ietf.org/html/rfc4345#section-4 */ + if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') { + $this->encrypt->encrypt(str_repeat("\0", 1536)); + } + if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') { + $this->decrypt->decrypt(str_repeat("\0", 1536)); + } + + if (!$this->encrypt->usesNonce()) { + list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out); + } else { + $this->hmac_create = new \stdClass; + $this->hmac_create->name = $mac_algorithm_out; + //$mac_algorithm_out = 'none'; + $createKeyLength = 0; + } + + if ($this->hmac_create instanceof Hash) { + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); + while ($createKeyLength > strlen($key)) { + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); + $this->hmac_create->name = $mac_algorithm_out; + $this->hmac_create->etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out); + } + + if (!$this->decrypt->usesNonce()) { + list($this->hmac_check, $checkKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_in); + $this->hmac_size = $this->hmac_check->getLengthInBytes(); + } else { + $this->hmac_check = new \stdClass; + $this->hmac_check->name = $mac_algorithm_in; + //$mac_algorithm_in = 'none'; + $checkKeyLength = 0; + $this->hmac_size = 0; + } + + if ($this->hmac_check instanceof Hash) { + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); + while ($checkKeyLength > strlen($key)) { + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); + $this->hmac_check->name = $mac_algorithm_in; + $this->hmac_check->etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in); + } + + return true; + } + + /** + * Maps an encryption algorithm name to the number of key bytes. + * + * @param string $algorithm Name of the encryption algorithm + * @return int|null Number of bytes as an integer or null for unknown + * @access private + */ + private function encryption_algorithm_to_key_size($algorithm) + { + if ($this->bad_key_size_fix && self::bad_algorithm_candidate($algorithm)) { + return 16; + } + + switch ($algorithm) { + case 'none': + return 0; + case 'aes128-gcm@openssh.com': + case 'aes128-cbc': + case 'aes128-ctr': + case 'arcfour': + case 'arcfour128': + case 'blowfish-cbc': + case 'blowfish-ctr': + case 'twofish128-cbc': + case 'twofish128-ctr': + return 16; + case '3des-cbc': + case '3des-ctr': + case 'aes192-cbc': + case 'aes192-ctr': + case 'twofish192-cbc': + case 'twofish192-ctr': + return 24; + case 'aes256-gcm@openssh.com': + case 'aes256-cbc': + case 'aes256-ctr': + case 'arcfour256': + case 'twofish-cbc': + case 'twofish256-cbc': + case 'twofish256-ctr': + return 32; + case 'chacha20-poly1305@openssh.com': + return 64; + } + return null; + } + + /** + * Maps an encryption algorithm name to an instance of a subclass of + * \phpseclib3\Crypt\Common\SymmetricKey. + * + * @param string $algorithm Name of the encryption algorithm + * @return mixed Instance of \phpseclib3\Crypt\Common\SymmetricKey or null for unknown + * @access private + */ + private static function encryption_algorithm_to_crypt_instance($algorithm) + { + switch ($algorithm) { + case '3des-cbc': + return new TripleDES('cbc'); + case '3des-ctr': + return new TripleDES('ctr'); + case 'aes256-cbc': + case 'aes192-cbc': + case 'aes128-cbc': + return new Rijndael('cbc'); + case 'aes256-ctr': + case 'aes192-ctr': + case 'aes128-ctr': + return new Rijndael('ctr'); + case 'blowfish-cbc': + return new Blowfish('cbc'); + case 'blowfish-ctr': + return new Blowfish('ctr'); + case 'twofish128-cbc': + case 'twofish192-cbc': + case 'twofish256-cbc': + case 'twofish-cbc': + return new Twofish('cbc'); + case 'twofish128-ctr': + case 'twofish192-ctr': + case 'twofish256-ctr': + return new Twofish('ctr'); + case 'arcfour': + case 'arcfour128': + case 'arcfour256': + return new RC4(); + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + return new Rijndael('gcm'); + case 'chacha20-poly1305@openssh.com': + return new ChaCha20(); + } + return null; + } + + /** + * Maps an encryption algorithm name to an instance of a subclass of + * \phpseclib3\Crypt\Hash. + * + * @param string $algorithm Name of the encryption algorithm + * @return mixed Instance of \phpseclib3\Crypt\Hash or null for unknown + * @access private + */ + private static function mac_algorithm_to_hash_instance($algorithm) + { + switch ($algorithm) { + case 'umac-64@openssh.com': + case 'umac-64-etm@openssh.com': + return [new Hash('umac-64'), 16]; + case 'umac-128@openssh.com': + case 'umac-128-etm@openssh.com': + return [new Hash('umac-128'), 16]; + case 'hmac-sha2-512': + case 'hmac-sha2-512-etm@openssh.com': + return [new Hash('sha512'), 64]; + case 'hmac-sha2-256': + case 'hmac-sha2-256-etm@openssh.com': + return [new Hash('sha256'), 32]; + case 'hmac-sha1': + case 'hmac-sha1-etm@openssh.com': + return [new Hash('sha1'), 20]; + case 'hmac-sha1-96': + return [new Hash('sha1-96'), 20]; + case 'hmac-md5': + return [new Hash('md5'), 16]; + case 'hmac-md5-96': + return [new Hash('md5-96'), 16]; + } + } + + /* + * Tests whether or not proposed algorithm has a potential for issues + * + * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html + * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291 + * @param string $algorithm Name of the encryption algorithm + * @return bool + * @access private + */ + private static function bad_algorithm_candidate($algorithm) + { + switch ($algorithm) { + case 'arcfour256': + case 'aes192-ctr': + case 'aes256-ctr': + return true; + } + + return false; + } + + /** + * Login + * + * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA object or an array + * + * @param string $username + * @param string[] ...$args + * @return bool + * @see self::_login() + * @access public + */ + public function login($username, ...$args) + { + $this->auth[] = func_get_args(); + + // try logging with 'none' as an authentication method first since that's what + // PuTTY does + if (substr($this->server_identifier, 0, 13) != 'SSH-2.0-CoreFTP') { + if ($this->sublogin($username)) { + return true; + } + if (!count($args)) { + return false; + } + } + return $this->sublogin($username, ...$args); + } + + /** + * Login Helper + * + * @param string $username + * @param string[] ...$args + * @return bool + * @see self::_login_helper() + * @access private + */ + protected function sublogin($username, ...$args) + { + if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { + if (!$this->connect()) { + return false; + } + } + + if (empty($args)) { + return $this->login_helper($username); + } + + foreach ($args as $arg) { + if ($this->login_helper($username, $arg)) { + return true; + } + } + return false; + } + + /** + * Login Helper + * + * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages.} + * + * @param string $username + * @param string $password + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + * @access private + */ + private function login_helper($username, $password = null) + { + if (!($this->bitmap & self::MASK_CONNECTED)) { + return false; + } + + if (!($this->bitmap & self::MASK_LOGIN_REQ)) { + $packet = Strings::packSSH2('Cs', NET_SSH2_MSG_SERVICE_REQUEST, 'ssh-userauth'); + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + if ($response === false) { + if ($this->retry_connect) { + $this->retry_connect = false; + if (!$this->connect()) { + return false; + } + return $this->login_helper($username, $password); + } + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type, $service) = Strings::unpackSSH2('Cs', $response); + if ($type != NET_SSH2_MSG_SERVICE_ACCEPT || $service != 'ssh-userauth') { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); + } + $this->bitmap |= self::MASK_LOGIN_REQ; + } + + if (strlen($this->last_interactive_response)) { + return !is_string($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password); + } + + if ($password instanceof PrivateKey) { + return $this->privatekey_login($username, $password); + } + + if ($password instanceof Agent) { + return $this->ssh_agent_login($username, $password); + } + + if (is_array($password)) { + if ($this->keyboard_interactive_login($username, $password)) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } + return false; + } + + if (!isset($password)) { + $packet = Strings::packSSH2( + 'Cs3', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'none' + ); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + //case NET_SSH2_MSG_USERAUTH_FAILURE: + default: + return false; + } + } + + if (!is_string($password)) { + throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string'); + } + + $packet = Strings::packSSH2( + 'Cs3bs', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'password', + false, + $password + ); + + // remove the username and password from the logged packet + if (!defined('NET_SSH2_LOGGING')) { + $logged = null; + } else { + $logged = Strings::packSSH2( + 'Cs3bs', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'password', + false, + 'password' + ); + } + + $this->send_binary_packet($packet, $logged); + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); + + list($message) = Strings::unpackSSH2('s', $response); + $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $message; + + return $this->disconnect_helper(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); + case NET_SSH2_MSG_USERAUTH_FAILURE: + // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees + // multi-factor authentication + list($auth_methods, $partial_success) = Strings::unpackSSH2('Lb', $response); + if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) { + if ($this->keyboard_interactive_login($username, $password)) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } + return false; + } + return false; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + } + + return false; + } + + /** + * Login via keyboard-interactive authentication + * + * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator. + * + * @param string $username + * @param string $password + * @return bool + * @access private + */ + private function keyboard_interactive_login($username, $password) + { + $packet = Strings::packSSH2( + 'Cs5', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'keyboard-interactive', + '', // language tag + '' // submethods + ); + $this->send_binary_packet($packet); + + return $this->keyboard_interactive_process($password); + } + + /** + * Handle the keyboard-interactive requests / responses. + * + * @param mixed[] ...$responses + * @return bool + * @throws \RuntimeException on connection error + * @access private + */ + private function keyboard_interactive_process(...$responses) + { + if (strlen($this->last_interactive_response)) { + $response = $this->last_interactive_response; + } else { + $orig = $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_INFO_REQUEST: + list( + , // name; may be empty + , // instruction; may be empty + , // language tag; may be empty + $num_prompts + ) = Strings::unpackSSH2('s3N', $response); + + for ($i = 0; $i < count($responses); $i++) { + if (is_array($responses[$i])) { + foreach ($responses[$i] as $key => $value) { + $this->keyboard_requests_responses[$key] = $value; + } + unset($responses[$i]); + } + } + $responses = array_values($responses); + + if (isset($this->keyboard_requests_responses)) { + for ($i = 0; $i < $num_prompts; $i++) { + list( + $prompt, // prompt - ie. "Password: "; must not be empty + // echo + ) = Strings::unpackSSH2('sC', $response); + foreach ($this->keyboard_requests_responses as $key => $value) { + if (substr($prompt, 0, strlen($key)) == $key) { + $responses[] = $value; + break; + } + } + } + } + + // see http://tools.ietf.org/html/rfc4256#section-3.2 + if (strlen($this->last_interactive_response)) { + $this->last_interactive_response = ''; + } else { + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); + } + + if (!count($responses) && $num_prompts) { + $this->last_interactive_response = $orig; + return false; + } + + /* + After obtaining the requested information from the user, the client + MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message. + */ + // see http://tools.ietf.org/html/rfc4256#section-3.4 + $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); + for ($i = 0; $i < count($responses); $i++) { + $packet.= Strings::packSSH2('s', $responses[$i]); + $logged.= Strings::packSSH2('s', 'dummy-answer'); + } + + $this->send_binary_packet($packet, $logged); + + $this->updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); + + /* + After receiving the response, the server MUST send either an + SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another + SSH_MSG_USERAUTH_INFO_REQUEST message. + */ + // maybe phpseclib should force close the connection after x request / responses? unless something like that is done + // there could be an infinite loop of request / responses. + return $this->keyboard_interactive_process(); + case NET_SSH2_MSG_USERAUTH_SUCCESS: + return true; + case NET_SSH2_MSG_USERAUTH_FAILURE: + return false; + } + + return false; + } + + /** + * Login with an ssh-agent provided key + * + * @param string $username + * @param \phpseclib3\System\SSH\Agent $agent + * @return bool + * @access private + */ + private function ssh_agent_login($username, Agent $agent) + { + $this->agent = $agent; + $keys = $agent->requestIdentities(); + foreach ($keys as $key) { + if ($this->privatekey_login($username, $key)) { + return true; + } + } + + return false; + } + + /** + * Login with an RSA private key + * + * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages.} + * + * @param string $username + * @param \phpseclib3\Crypt\Common\PrivateKey $privatekey + * @return bool + * @throws \RuntimeException on connection error + * @access private + */ + private function privatekey_login($username, PrivateKey $privatekey) + { + $publickey = $privatekey->getPublicKey(); + + if ($publickey instanceof RSA) { + $privatekey = $privatekey->withPadding(RSA::SIGNATURE_PKCS1); + $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa']; + if (isset($this->preferred['hostkey'])) { + $algos = array_intersect($this->preferred['hostkey'] , $algos); + } + $algo = self::array_intersect_first($algos, $this->server_host_key_algorithms); + switch ($algo) { + case 'rsa-sha2-512': + $hash = 'sha512'; + $signatureType = 'rsa-sha2-512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + $signatureType = 'rsa-sha2-256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + $signatureType = 'ssh-rsa'; + } + } else if ($publickey instanceof EC) { + $privatekey = $privatekey->withSignatureFormat('SSH2'); + $curveName = $privatekey->getCurve(); + switch ($curveName) { + case 'Ed25519': + $hash = 'sha512'; + $signatureType = 'ssh-ed25519'; + break; + case 'secp256r1': // nistp256 + $hash = 'sha256'; + $signatureType = 'ecdsa-sha2-nistp256'; + break; + case 'secp384r1': // nistp384 + $hash = 'sha384'; + $signatureType = 'ecdsa-sha2-nistp384'; + break; + case 'secp521r1': // nistp521 + $hash = 'sha512'; + $signatureType = 'ecdsa-sha2-nistp521'; + break; + default: + if (is_array($curveName)) { + throw new UnsupportedCurveException('Specified Curves are not supported by SSH2'); + } + throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported by phpseclib3\'s SSH2 implementation'); + } + } else if ($publickey instanceof DSA) { + $privatekey = $privatekey->withSignatureFormat('SSH2'); + $hash = 'sha1'; + $signatureType = 'ssh-dss'; + } else { + throw new UnsupportedAlgorithmException('Please use either an RSA key, an EC one or a DSA key'); + } + + $publickeyStr = $publickey->toString('OpenSSH', ['binary' => true]); + + $part1 = Strings::packSSH2( + 'Csss', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'publickey' + ); + $part2 = Strings::packSSH2('ss', $signatureType, $publickeyStr); + + $packet = $part1 . chr(0) . $part2; + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_FAILURE: + list($message) = Strings::unpackSSH2('s', $response); + $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $message; + return false; + case NET_SSH2_MSG_USERAUTH_PK_OK: + // we'll just take it on faith that the public key blob and the public key algorithm name are as + // they should be + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); + break; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new ConnectionClosedException('Unexpected response to publickey authentication pt 1'); + } + + $packet = $part1 . chr(1) . $part2; + $privatekey = $privatekey->withHash($hash); + $signature = $privatekey->sign(Strings::packSSH2('s', $this->session_id) . $packet); + if ($publickey instanceof RSA) { + $signature = Strings::packSSH2('ss', $signatureType, $signature); + } + $packet.= Strings::packSSH2('s', $signature); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_FAILURE: + // either the login is bad or the server employs multi-factor authentication + return false; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + } + + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new ConnectionClosedException('Unexpected response to publickey authentication pt 2'); + } + + /** + * Set Timeout + * + * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. + * Setting $timeout to false or 0 will mean there is no timeout. + * + * @param mixed $timeout + * @access public + */ + public function setTimeout($timeout) + { + $this->timeout = $this->curTimeout = $timeout; + } + + /** + * Set Keep Alive + * + * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. + * + * @param int $interval + * @access public + */ + function setKeepAlive($interval) + { + $this->keepAlive = $interval; + } + + /** + * Get the output from stdError + * + * @access public + */ + public function getStdError() + { + return $this->stdErrorLog; + } + + /** + * Execute Command + * + * If $callback is set to false then \phpseclib3\Net\SSH2::get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. + * In all likelihood, this is not a feature you want to be taking advantage of. + * + * @param string $command + * @param Callback $callback + * @return string + * @throws \RuntimeException on connection error + * @access public + */ + public function exec($command, $callback = null) + { + $this->curTimeout = $this->timeout; + $this->is_timeout = false; + $this->stdErrorLog = ''; + + if (!$this->isAuthenticated()) { + return false; + } + + if ($this->in_request_pty_exec) { + throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); + } + + // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to + // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, + // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. + // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info + $this->window_size_server_to_client[self::CHANNEL_EXEC] = $this->window_size; + // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy + // uses 0x4000, that's what will be used here, as well. + $packet_size = 0x4000; + + $packet = Strings::packSSH2( + 'CsN3', + NET_SSH2_MSG_CHANNEL_OPEN, + 'session', + self::CHANNEL_EXEC, + $this->window_size_server_to_client[self::CHANNEL_EXEC], + $packet_size + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN; + + $response = $this->get_channel_packet(self::CHANNEL_EXEC); + if ($response === false) { + return false; + } + + if ($this->request_pty === true) { + $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); + $packet = Strings::packSSH2( + 'CNsCsN4s', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_EXEC], + 'pty-req', + 1, + 'vt100', + $this->windowColumns, + $this->windowRows, + 0, + 0, + $terminal_modes + ); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + break; + case NET_SSH2_MSG_CHANNEL_FAILURE: + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to request pseudo-terminal'); + } + $this->in_request_pty_exec = true; + } + + // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things + // down. the one place where it might be desirable is if you're doing something like \phpseclib3\Net\SSH2::exec('ping localhost &'). + // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then + // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but + // neither will your script. + + // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by + // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the + // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates. + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_EXEC], + 'exec', + 1, + $command + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $response = $this->get_channel_packet(self::CHANNEL_EXEC); + if ($response === false) { + return false; + } + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA; + + if ($callback === false || $this->in_request_pty_exec) { + return true; + } + + $output = ''; + while (true) { + $temp = $this->get_channel_packet(self::CHANNEL_EXEC); + switch (true) { + case $temp === true: + return is_callable($callback) ? true : $output; + case $temp === false: + return false; + default: + if (is_callable($callback)) { + if ($callback($temp) === true) { + $this->close_channel(self::CHANNEL_EXEC); + return true; + } + } else { + $output.= $temp; + } + } + } + } + + /** + * Creates an interactive shell + * + * @see self::read() + * @see self::write() + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + * @access private + */ + private function initShell() + { + if ($this->in_request_pty_exec === true) { + return true; + } + + $this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size; + $packet_size = 0x4000; + + $packet = Strings::packSSH2( + 'CsN3', + NET_SSH2_MSG_CHANNEL_OPEN, + 'session', + self::CHANNEL_SHELL, + $this->window_size_server_to_client[self::CHANNEL_SHELL], + $packet_size + ); + + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_OPEN; + + $response = $this->get_channel_packet(self::CHANNEL_SHELL); + if ($response === false) { + return false; + } + + $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); + $packet = Strings::packSSH2( + 'CNsCsN4s', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SHELL], + 'pty-req', + 1, + 'vt100', + $this->windowColumns, + $this->windowRows, + 0, + 0, + $terminal_modes + ); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + + switch ($type) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + // if a pty can't be opened maybe commands can still be executed + case NET_SSH2_MSG_CHANNEL_FAILURE: + break; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \UnexpectedValueException('Unable to request pseudo-terminal'); + } + + $packet = Strings::packSSH2( + 'CNsb', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SHELL], + 'shell', + true // want reply + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $response = $this->get_channel_packet(self::CHANNEL_SHELL); + if ($response === false) { + return false; + } + + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; + + $this->bitmap |= self::MASK_SHELL; + + return true; + } + + /** + * Return the channel to be used with read() / write() + * + * @see self::read() + * @see self::write() + * @return int + * @access public + */ + private function get_interactive_channel() + { + switch (true) { + case $this->in_subsystem: + return self::CHANNEL_SUBSYSTEM; + case $this->in_request_pty_exec: + return self::CHANNEL_EXEC; + default: + return self::CHANNEL_SHELL; + } + } + + /** + * Return an available open channel + * + * @return int + * @access public + */ + private function get_open_channel() + { + $channel = self::CHANNEL_EXEC; + do { + if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) { + return $channel; + } + } while ($channel++ < self::CHANNEL_SUBSYSTEM); + + return false; + } + + /** + * Request agent forwarding of remote server + * + * @return bool + * @access public + */ + public function requestAgentForwarding() + { + $request_channel = $this->get_open_channel(); + if ($request_channel === false) { + return false; + } + + $packet = Strings::packSSH2( + 'CNsC', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[$request_channel], + 'auth-agent-req@openssh.com', + 1 + ); + + $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $this->send_binary_packet($packet); + + $response = $this->get_channel_packet($request_channel); + if ($response === false) { + return false; + } + + $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; + + return true; + } + + /** + * Returns the output of an interactive shell + * + * Returns when there's a match for $expect, which can take the form of a string literal or, + * if $mode == self::READ_REGEX, a regular expression. + * + * @see self::write() + * @param string $expect + * @param int $mode + * @return string|bool|null + * @throws \RuntimeException on connection error + * @access public + */ + public function read($expect = '', $mode = self::READ_SIMPLE) + { + $this->curTimeout = $this->timeout; + $this->is_timeout = false; + + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } + + $channel = $this->get_interactive_channel(); + + if ($mode == self::READ_NEXT) { + return $this->get_channel_packet($channel); + } + + $match = $expect; + while (true) { + if ($mode == self::READ_REGEX) { + preg_match($expect, substr($this->interactiveBuffer, -1024), $matches); + $match = isset($matches[0]) ? $matches[0] : ''; + } + $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; + if ($pos !== false) { + return Strings::shift($this->interactiveBuffer, $pos + strlen($match)); + } + $response = $this->get_channel_packet($channel); + if (is_bool($response)) { + $this->in_request_pty_exec = false; + return $response ? Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer)) : false; + } + + $this->interactiveBuffer.= $response; + } + } + + /** + * Inputs a command into an interactive shell. + * + * @see self::read() + * @param string $cmd + * @return bool + * @throws \RuntimeException on connection error + * @access public + */ + public function write($cmd) + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } + + return $this->send_channel_packet($this->get_interactive_channel(), $cmd); + } + + /** + * Start a subsystem. + * + * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept + * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened. + * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and + * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented + * if there's sufficient demand for such a feature. + * + * @see self::stopSubsystem() + * @param string $subsystem + * @return bool + * @access public + */ + public function startSubsystem($subsystem) + { + $this->window_size_server_to_client[self::CHANNEL_SUBSYSTEM] = $this->window_size; + + $packet = Strings::packSSH2( + 'CsN3', + NET_SSH2_MSG_CHANNEL_OPEN, + 'session', + self::CHANNEL_SUBSYSTEM, + $this->window_size, + 0x4000 + ); + + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_OPEN; + + $response = $this->get_channel_packet(self::CHANNEL_SUBSYSTEM); + if ($response === false) { + return false; + } + + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SUBSYSTEM], + 'subsystem', + 1, + $subsystem + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $response = $this->get_channel_packet(self::CHANNEL_SUBSYSTEM); + if ($response === false) { + return false; + } + + $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA; + + $this->bitmap |= self::MASK_SHELL; + $this->in_subsystem = true; + + return true; + } + + /** + * Stops a subsystem. + * + * @see self::startSubsystem() + * @return bool + * @access public + */ + public function stopSubsystem() + { + $this->in_subsystem = false; + $this->close_channel(self::CHANNEL_SUBSYSTEM); + return true; + } + + /** + * Closes a channel + * + * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call + * + * @access public + */ + public function reset() + { + $this->close_channel($this->get_interactive_channel()); + } + + /** + * Is timeout? + * + * Did exec() or read() return because they timed out or because they encountered the end? + * + * @access public + */ + public function isTimeout() + { + return $this->is_timeout; + } + + /** + * Disconnect + * + * @access public + */ + public function disconnect() + { + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) { + fclose($this->realtime_log_file); + } + unset(self::$connections[$this->getResourceId()]); + } + + /** + * Destructor. + * + * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call + * disconnect(). + * + * @access public + */ + public function __destruct() + { + $this->disconnect(); + } + + /** + * Is the connection still active? + * + * @return bool + * @access public + */ + public function isConnected() + { + return (bool) ($this->bitmap & self::MASK_CONNECTED); + } + + /** + * Have you successfully been logged in? + * + * @return bool + * @access public + */ + public function isAuthenticated() + { + return (bool) ($this->bitmap & self::MASK_LOGIN); + } + + /** + * Pings a server connection, or tries to reconnect if the connection has gone down + * + * Inspired by http://php.net/manual/en/mysqli.ping.php + * + * @return bool + */ + public function ping() + { + if (!$this->isAuthenticated()) { + if (!empty($this->auth)) { + return $this->reconnect(); + } + return false; + } + + $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE] = $this->window_size; + $packet_size = 0x4000; + $packet = Strings::packSSH2( + 'CsN3', + NET_SSH2_MSG_CHANNEL_OPEN, + 'session', + self::CHANNEL_KEEP_ALIVE, + $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE], + $packet_size + ); + + try { + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN; + + $response = $this->get_channel_packet(self::CHANNEL_KEEP_ALIVE); + } catch (\RuntimeException $e) { + return $this->reconnect(); + } + + $this->close_channel(NET_SSH2_CHANNEL_KEEP_ALIVE); + return true; + } + + /** + * In situ reconnect method + * + * @return boolean + */ + private function reconnect() + { + $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); + $this->retry_connect = true; + if (!$this->connect()) { + return false; + } + foreach ($this->auth as $auth) { + $result = $this->login(...$auth); + } + return $result; + } + + /** + * Resets a connection for re-use + * + * @param int $reason + * @access private + */ + protected function reset_connection($reason) + { + $this->disconnect_helper($reason); + $this->decrypt = $this->encrypt = false; + $this->decrypt_block_size = $this->encrypt_block_size = 8; + $this->hmac_check = $this->hmac_create = false; + $this->hmac_size = false; + $this->session_id = false; + $this->retry_connect = true; + $this->get_seq_no = $this->send_seq_no = 0; + } + + /** + * Gets Binary Packets + * + * See '6. Binary Packet Protocol' of rfc4253 for more info. + * + * @see self::_send_binary_packet() + * @param bool $skip_channel_filter + * @return string + * @access private + */ + private function get_binary_packet($skip_channel_filter = false) + { + if ($skip_channel_filter) { + $read = [$this->fsock]; + $write = $except = null; + + if ($this->curTimeout <= 0) { + if ($this->keepAlive <= 0) { + @stream_select($read, $write, $except, null); + } else { + if (!@stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + return $this->get_binary_packet(true); + } + } + } else { + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return true; + } + + $read = [$this->fsock]; + $write = $except = null; + + $start = microtime(true); + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!@stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + return $this->get_binary_packet(true); + } + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + } + + $sec = floor($this->curTimeout); + $usec = 1000000 * ($this->curTimeout - $sec); + + // this can return a "stream_select(): unable to select [4]: Interrupted system call" error + if (!@stream_select($read, $write, $except, $sec, $usec)) { + $this->is_timeout = true; + return true; + } + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + } + } + + if (!is_resource($this->fsock) || feof($this->fsock)) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed prematurely'); + } + + $start = microtime(true); + $raw = stream_get_contents($this->fsock, $this->decrypt_block_size); + + if (!strlen($raw)) { + return ''; + } + + if ($this->decrypt) { + switch ($this->decrypt->name) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $this->decrypt->setNonce( + $this->decrypt->fixed . + $this->decrypt->invocation_counter + ); + Strings::increment_str($this->decrypt->invocation_counter); + $this->decrypt->setAAD($temp = Strings::shift($raw, 4)); + extract(unpack('Npacket_length', $temp)); + /** + * @var integer $packet_length + */ + + $raw.= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $tag = stream_get_contents($this->fsock, $this->decrypt_block_size); + $this->decrypt->setTag($tag); + $raw = $this->decrypt->decrypt($raw); + $raw = $temp . $raw; + $remaining_length = 0; + break; + case 'chacha20-poly1305@openssh.com': + $nonce = pack('N2', 0, $this->get_seq_no); + + $this->lengthDecrypt->setNonce($nonce); + $temp = $this->lengthDecrypt->decrypt($aad = Strings::shift($raw, 4)); + extract(unpack('Npacket_length', $temp)); + /** + * @var integer $packet_length + */ + + $raw.= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $tag = stream_get_contents($this->fsock, 16); + + $this->decrypt->setNonce($nonce); + $this->decrypt->setCounter(0); + // this is the same approach that's implemented in Salsa20::createPoly1305Key() + // but we don't want to use the same AEAD construction that RFC8439 describes + // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) + $this->decrypt->setPoly1305Key( + $this->decrypt->encrypt(str_repeat("\0", 32)) + ); + $this->decrypt->setAAD($aad); + $this->decrypt->setCounter(1); + $this->decrypt->setTag($tag); + $raw = $this->decrypt->decrypt($raw); + $raw = $temp . $raw; + $remaining_length = 0; + break; + default: + if (!$this->hmac_check instanceof Hash || !$this->hmac_check->etm) { + $raw = $this->decrypt->decrypt($raw); + break; + } + extract(unpack('Npacket_length', $temp = Strings::shift($raw, 4))); + /** + * @var integer $packet_length + */ + $raw.= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $encrypted = $temp . $raw; + $raw = $temp . $this->decrypt->decrypt($raw); + $remaining_length = 0; + } + } + + if (strlen($raw) < 5) { + return false; + } + extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5))); + /** + * @var integer $packet_length + * @var integer $padding_length + */ + + if (!isset($remaining_length)) { + $remaining_length = $packet_length + 4 - $this->decrypt_block_size; + } + + $buffer = $this->read_remaining_bytes($remaining_length); + + if (!isset($stop)) { + $stop = microtime(true); + } + if (strlen($buffer)) { + $raw.= $this->decrypt ? $this->decrypt->decrypt($buffer) : $buffer; + } + + $payload = Strings::shift($raw, $packet_length - $padding_length - 1); + $padding = Strings::shift($raw, $padding_length); // should leave $raw empty + + if ($this->hmac_check instanceof Hash) { + $hmac = stream_get_contents($this->fsock, $this->hmac_size); + if ($hmac === false || strlen($hmac) != $this->hmac_size) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Error reading socket'); + } + + $reconstructed = !$this->hmac_check->etm ? + pack('NCa*', $packet_length, $padding_length, $payload . $padding) : + $encrypted; + if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no)); + if ($hmac != $this->hmac_check->hash($reconstructed)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Invalid UMAC'); + } + } else { + if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Invalid HMAC'); + } + } + } + + //if ($this->decompress) { + // $payload = gzinflate(substr($payload, 2)); + //} + + $this->get_seq_no++; + + if (defined('NET_SSH2_LOGGING')) { + $current = microtime(true); + $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; + $message_number = '<- ' . $message_number . + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; + $this->append_log($message_number, $payload); + $this->last_packet = $current; + } + + return $this->filter($payload, $skip_channel_filter); + } + + /** + * Read Remaining Bytes + * + * @see self::get_binary_packet() + * @param int $remaining_length + * @return string + * @access private + */ + private function read_remaining_bytes($remaining_length) + { + if (!$remaining_length) { + return ''; + } + + $adjustLength = false; + if ($this->decrypt) { + switch (true) { + case $this->decrypt->name == 'aes128-gcm@openssh.com': + case $this->decrypt->name == 'aes256-gcm@openssh.com': + case $this->decrypt->name == 'chacha20-poly1305@openssh.com': + case $this->hmac_check instanceof Hash && $this->hmac_check->etm: + $remaining_length+= $this->decrypt_block_size - 4; + $adjustLength = true; + } + } + + // quoting , + // "implementations SHOULD check that the packet length is reasonable" + // PuTTY uses 0x9000 as the actual max packet size and so to shall we + // don't do this when GCM mode is used since GCM mode doesn't encrypt the length + if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) { + if (!$this->bad_key_size_fix && self::bad_algorithm_candidate($this->decrypt ? $this->decrypt->name : '') && !($this->bitmap & SSH2::MASK_LOGIN)) { + $this->bad_key_size_fix = true; + $this->reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + return false; + } + throw new \RuntimeException('Invalid size'); + } + + if ($adjustLength) { + $remaining_length-= $this->decrypt_block_size - 4; + } + + $buffer = ''; + while ($remaining_length > 0) { + $temp = stream_get_contents($this->fsock, $remaining_length); + if ($temp === false || feof($this->fsock)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new \RuntimeException('Error reading from socket'); + } + $buffer.= $temp; + $remaining_length-= strlen($temp); + } + + return $buffer; + } + + /** + * Filter Binary Packets + * + * Because some binary packets need to be ignored... + * + * @see self::_get_binary_packet() + * @param string $payload + * @param bool $skip_channel_filter + * @return string + * @access private + */ + private function filter($payload, $skip_channel_filter) + { + switch (ord($payload[0])) { + case NET_SSH2_MSG_DISCONNECT: + Strings::shift($payload, 1); + list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); + $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n$message"; + $this->bitmap = 0; + return false; + case NET_SSH2_MSG_IGNORE: + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_DEBUG: + Strings::shift($payload, 2); // second byte is "always_display" + list($message) = Strings::unpackSSH2('s', $payload); + $this->errors[] = "SSH_MSG_DEBUG: $message"; + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_UNIMPLEMENTED: + return false; + case NET_SSH2_MSG_KEXINIT: + if ($this->session_id !== false) { + if (!$this->key_exchange($payload)) { + $this->bitmap = 0; + return false; + } + $payload = $this->get_binary_packet($skip_channel_filter); + } + } + + // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in + if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) { + Strings::shift($payload, 1); + list($this->banner_message) = Strings::unpackSSH2('s', $payload); + $payload = $this->get_binary_packet(); + } + + // only called when we've already logged in + if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { + switch (ord($payload[0])) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + if (strlen($payload) == 31) { + extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); + if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { + if (ord(substr($payload, 9 + $length))) { // want reply + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); + } + $payload = $this->get_binary_packet($skip_channel_filter); + } + } + break; + case NET_SSH2_MSG_CHANNEL_DATA: + case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: + case NET_SSH2_MSG_CHANNEL_CLOSE: + case NET_SSH2_MSG_CHANNEL_EOF: + if (!$skip_channel_filter && !empty($this->server_channels)) { + $this->binary_packet_buffer = $payload; + $this->get_channel_packet(true); + $payload = $this->get_binary_packet(); + } + break; + case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4 + Strings::shift($payload, 1); + list($request_name) = Strings::unpackSSH2('s', $payload); + $this->errors[] = "SSH_MSG_GLOBAL_REQUEST: $request_name"; + + try { + $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE)); + } catch (\RuntimeException $e) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1 + Strings::shift($payload, 1); + list($data, $server_channel) = Strings::unpackSSH2('sN', $payload); + switch ($data) { + case 'auth-agent': + case 'auth-agent@openssh.com': + if (isset($this->agent)) { + $new_channel = self::CHANNEL_AGENT_FORWARD; + + list( + $remote_window_size, + $remote_maximum_packet_size + ) = Strings::unpackSSH2('NN', $payload); + + $this->packet_size_client_to_server[$new_channel] = $remote_window_size; + $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size; + $this->window_size_client_to_server[$new_channel] = $this->window_size; + + $packet_size = 0x4000; + + $packet = pack( + 'CN4', + NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, + $server_channel, + $new_channel, + $packet_size, + $packet_size + ); + + $this->server_channels[$new_channel] = $server_channel; + $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION; + $this->send_binary_packet($packet); + } + break; + default: + $packet = Strings::packSSH2( + 'CN2ss', + NET_SSH2_MSG_CHANNEL_OPEN_FAILURE, + $server_channel, + NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, + '', // description + '' // language tag + ); + + try { + $this->send_binary_packet($packet); + } catch (\RuntimeException $e) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + } + + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST: + Strings::shift($payload, 1); + list($channel, $window_size) = Strings::unpackSSH2('NN', $payload); + + $this->window_size_client_to_server[$channel]+= $window_size; + + $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->get_binary_packet($skip_channel_filter); + } + } + + return $payload; + } + + /** + * Enable Quiet Mode + * + * Suppress stderr from output + * + * @access public + */ + public function enableQuietMode() + { + $this->quiet_mode = true; + } + + /** + * Disable Quiet Mode + * + * Show stderr in output + * + * @access public + */ + public function disableQuietMode() + { + $this->quiet_mode = false; + } + + /** + * Returns whether Quiet Mode is enabled or not + * + * @see self::enableQuietMode() + * @see self::disableQuietMode() + * @access public + * @return bool + */ + public function isQuietModeEnabled() + { + return $this->quiet_mode; + } + + /** + * Enable request-pty when using exec() + * + * @access public + */ + public function enablePTY() + { + $this->request_pty = true; + } + + /** + * Disable request-pty when using exec() + * + * @access public + */ + public function disablePTY() + { + if ($this->in_request_pty_exec) { + $this->close_channel(self::CHANNEL_EXEC); + $this->in_request_pty_exec = false; + } + $this->request_pty = false; + } + + /** + * Returns whether request-pty is enabled or not + * + * @see self::enablePTY() + * @see self::disablePTY() + * @access public + * @return bool + */ + public function isPTYEnabled() + { + return $this->request_pty; + } + + /** + * Gets channel data + * + * Returns the data as a string if it's available and false if not. + * + * @param int $client_channel + * @param bool $skip_extended + * @return mixed + * @throws \RuntimeException on connection error + * @access private + */ + protected function get_channel_packet($client_channel, $skip_extended = false) + { + if (!empty($this->channel_buffers[$client_channel])) { + return array_shift($this->channel_buffers[$client_channel]); + } + + while (true) { + if ($this->binary_packet_buffer !== false) { + $response = $this->binary_packet_buffer; + $this->binary_packet_buffer = false; + } else { + $response = $this->get_binary_packet(true); + if ($response === true && $this->is_timeout) { + if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { + $this->close_channel($client_channel); + } + return true; + } + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + } + + if ($client_channel == -1 && $response === true) { + return true; + } + list($type, $channel) = Strings::unpackSSH2('CN', $response); + + // will not be setup yet on incoming channel open request + if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) { + $this->window_size_server_to_client[$channel]-= strlen($response); + + // resize the window, if appropriate + if ($this->window_size_server_to_client[$channel] < 0) { + // PuTTY does something more analogous to the following: + //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) { + $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize); + $this->send_binary_packet($packet); + $this->window_size_server_to_client[$channel]+= $this->window_resize; + } + + switch ($type) { + case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: + /* + if ($client_channel == self::CHANNEL_EXEC) { + $this->send_channel_packet($client_channel, chr(0)); + } + */ + // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR + list($data_type_code, $data) = Strings::unpackSSH2('Ns', $response); + $this->stdErrorLog.= $data; + if ($skip_extended || $this->quiet_mode) { + continue 2; + } + if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) { + return $data; + } + if (!isset($this->channel_buffers[$channel])) { + $this->channel_buffers[$channel] = []; + } + $this->channel_buffers[$channel][] = $data; + + continue 2; + case NET_SSH2_MSG_CHANNEL_REQUEST: + if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) { + continue 2; + } + list($value) = Strings::unpackSSH2('s', $response); + switch ($value) { + case 'exit-signal': + list( + , // FALSE + $signal_name, + , // core dumped + $error_message + ) = Strings::unpackSSH2('bsbs', $response); + + $this->errors[] = "SSH_MSG_CHANNEL_REQUEST (exit-signal): $signal_name"; + if (strlen($error_message)) { + $this->errors[count($this->errors) - 1].= "\r\n$error_message"; + } + + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF; + + continue 3; + case 'exit-status': + list(, $this->exit_status) = Strings::unpackSSH2('CN', $response); + + // "The client MAY ignore these messages." + // -- http://tools.ietf.org/html/rfc4254#section-6.10 + + continue 3; + default: + // "Some systems may not implement signals, in which case they SHOULD ignore this message." + // -- http://tools.ietf.org/html/rfc4254#section-6.9 + continue 3; + } + } + + switch ($this->channel_status[$channel]) { + case NET_SSH2_MSG_CHANNEL_OPEN: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: + list( + $this->server_channels[$channel], + $window_size, + $this->packet_size_client_to_server[$channel] + ) = Strings::unpackSSH2('NNN', $response); + + if ($window_size < 0) { + $window_size&= 0x7FFFFFFF; + $window_size+= 0x80000000; + } + $this->window_size_client_to_server[$channel] = $window_size; + $result = $client_channel == $channel ? true : $this->get_channel_packet($client_channel, $skip_extended); + $this->on_channel_open(); + return $result; + //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to open channel'); + } + break; + case NET_SSH2_MSG_CHANNEL_REQUEST: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + return true; + case NET_SSH2_MSG_CHANNEL_FAILURE: + return false; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to fulfill channel request'); + } + case NET_SSH2_MSG_CHANNEL_CLOSE: + return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->get_channel_packet($client_channel, $skip_extended); + } + } + + // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA + + switch ($type) { + case NET_SSH2_MSG_CHANNEL_DATA: + /* + if ($channel == self::CHANNEL_EXEC) { + // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server + // this actually seems to make things twice as fast. more to the point, the message right after + // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise. + // in OpenSSH it slows things down but only by a couple thousandths of a second. + $this->send_channel_packet($channel, chr(0)); + } + */ + list($data) = Strings::unpackSSH2('s', $response); + + if ($channel == self::CHANNEL_AGENT_FORWARD) { + $agent_response = $this->agent->forwardData($data); + if (!is_bool($agent_response)) { + $this->send_channel_packet($channel, $agent_response); + } + break; + } + + if ($client_channel == $channel) { + return $data; + } + if (!isset($this->channel_buffers[$channel])) { + $this->channel_buffers[$channel] = []; + } + $this->channel_buffers[$channel][] = $data; + break; + case NET_SSH2_MSG_CHANNEL_CLOSE: + $this->curTimeout = 5; + + if ($this->bitmap & self::MASK_SHELL) { + $this->bitmap&= ~self::MASK_SHELL; + } + if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + } + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + if ($client_channel == $channel) { + return true; + } + case NET_SSH2_MSG_CHANNEL_EOF: + break; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Error reading channel data'); + } + } + } + + /** + * Sends Binary Packets + * + * See '6. Binary Packet Protocol' of rfc4253 for more info. + * + * @param string $data + * @param string $logged + * @see self::_get_binary_packet() + * @return bool + * @access private + */ + protected function send_binary_packet($data, $logged = null) + { + if (!is_resource($this->fsock) || feof($this->fsock)) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed prematurely'); + } + + //if ($this->compress) { + // // the -4 removes the checksum: + // // http://php.net/function.gzcompress#57710 + // $data = substr(gzcompress($data), 0, -4); + //} + + // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9 + $packet_length = strlen($data) + 9; + if ($this->encrypt && $this->encrypt->usesNonce()) { + $packet_length-= 4; + } + // round up to the nearest $this->encrypt_block_size + $packet_length+= (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size; + // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length + $padding_length = $packet_length - strlen($data) - 5; + switch (true) { + case $this->encrypt && $this->encrypt->usesNonce(): + case $this->hmac_create instanceof Hash && $this->hmac_create->etm: + $padding_length+= 4; + $packet_length+= 4; + } + + $padding = Random::string($padding_length); + + // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself + $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding); + + $hmac = ''; + if ($this->hmac_create instanceof Hash && !$this->hmac_create->etm) { + if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); + $hmac = $this->hmac_create->hash($packet); + } else { + $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); + } + } + + if ($this->encrypt) { + switch ($this->encrypt->name) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $this->encrypt->setNonce( + $this->encrypt->fixed . + $this->encrypt->invocation_counter + ); + Strings::increment_str($this->encrypt->invocation_counter); + $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF")); + $packet = $temp . $this->encrypt->encrypt(substr($packet, 4)); + break; + case 'chacha20-poly1305@openssh.com': + $nonce = pack('N2', 0, $this->send_seq_no); + + $this->encrypt->setNonce($nonce); + $this->lengthEncrypt->setNonce($nonce); + + $length = $this->lengthEncrypt->encrypt($packet & "\xFF\xFF\xFF\xFF"); + + $this->encrypt->setCounter(0); + // this is the same approach that's implemented in Salsa20::createPoly1305Key() + // but we don't want to use the same AEAD construction that RFC8439 describes + // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) + $this->encrypt->setPoly1305Key( + $this->encrypt->encrypt(str_repeat("\0", 32)) + ); + $this->encrypt->setAAD($length); + $this->encrypt->setCounter(1); + $packet = $length . $this->encrypt->encrypt(substr($packet, 4)); + break; + default: + $packet = $this->hmac_create instanceof Hash && $this->hmac_create->etm ? + ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) : + $this->encrypt->encrypt($packet); + } + } + + if ($this->hmac_create instanceof Hash && $this->hmac_create->etm) { + if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); + $hmac = $this->hmac_create->hash($packet); + } else { + $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); + } + } + + $this->send_seq_no++; + + $packet.= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac; + + $start = microtime(true); + $sent = @fputs($this->fsock, $packet); + $stop = microtime(true); + + if (defined('NET_SSH2_LOGGING')) { + $current = microtime(true); + $message_number = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN (' . ord($data[0]) . ')'; + $message_number = '-> ' . $message_number . + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; + $this->append_log($message_number, isset($logged) ? $logged : $data); + $this->last_packet = $current; + } + + if (strlen($packet) != $sent) { + $this->bitmap = 0; + throw new \RuntimeException("Only $sent of " . strlen($packet) . " bytes were sent"); + } + } + + /** + * Logs data packets + * + * Makes sure that only the last 1MB worth of packets will be logged + * + * @param string $message_number + * @param string $message + * @access private + */ + private function append_log($message_number, $message) + { + // remove the byte identifying the message type from all but the first two messages (ie. the identification strings) + if (strlen($message_number) > 2) { + Strings::shift($message); + } + + switch (NET_SSH2_LOGGING) { + // useful for benchmarks + case self::LOG_SIMPLE: + $this->message_number_log[] = $message_number; + break; + // the most useful log for SSH2 + case self::LOG_COMPLEX: + $this->message_number_log[] = $message_number; + $this->log_size+= strlen($message); + $this->message_log[] = $message; + while ($this->log_size > self::LOG_MAX_SIZE) { + $this->log_size-= strlen(array_shift($this->message_log)); + array_shift($this->message_number_log); + } + break; + // dump the output out realtime; packets may be interspersed with non packets, + // passwords won't be filtered out and select other packets may not be correctly + // identified + case self::LOG_REALTIME: + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
      ';
      +                        $stop = '
      '; + } + echo $start . $this->format_log([$message], [$message_number]) . $stop; + @flush(); + @ob_flush(); + break; + // basically the same thing as self::LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILENAME + // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. + // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily + // at the beginning of the file + case self::LOG_REALTIME_FILE: + if (!isset($this->realtime_log_file)) { + // PHP doesn't seem to like using constants in fopen() + $filename = NET_SSH2_LOG_REALTIME_FILENAME; + $fp = fopen($filename, 'w'); + $this->realtime_log_file = $fp; + } + if (!is_resource($this->realtime_log_file)) { + break; + } + $entry = $this->format_log([$message], [$message_number]); + if ($this->realtime_log_wrap) { + $temp = "<<< START >>>\r\n"; + $entry.= $temp; + fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp)); + } + $this->realtime_log_size+= strlen($entry); + if ($this->realtime_log_size > self::LOG_MAX_SIZE) { + fseek($this->realtime_log_file, 0); + $this->realtime_log_size = strlen($entry); + $this->realtime_log_wrap = true; + } + fputs($this->realtime_log_file, $entry); + } + } + + /** + * Sends channel data + * + * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate + * + * @param int $client_channel + * @param string $data + * @return bool + * @access private + */ + protected function send_channel_packet($client_channel, $data) + { + while (strlen($data)) { + if (!$this->window_size_client_to_server[$client_channel]) { + $this->bitmap^= self::MASK_WINDOW_ADJUST; + // using an invalid channel will let the buffers be built up for the valid channels + $this->get_channel_packet(-1); + $this->bitmap^= self::MASK_WINDOW_ADJUST; + } + + /* The maximum amount of data allowed is determined by the maximum + packet size for the channel, and the current window size, whichever + is smaller. + -- http://tools.ietf.org/html/rfc4254#section-5.2 */ + $max_size = min( + $this->packet_size_client_to_server[$client_channel], + $this->window_size_client_to_server[$client_channel] + ); + + $temp = Strings::shift($data, $max_size); + $packet = Strings::packSSH2( + 'CNs', + NET_SSH2_MSG_CHANNEL_DATA, + $this->server_channels[$client_channel], + $temp + ); + $this->window_size_client_to_server[$client_channel]-= strlen($temp); + $this->send_binary_packet($packet); + } + + return true; + } + + /** + * Closes and flushes a channel + * + * \phpseclib3\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server + * and for SFTP channels are presumably closed when the client disconnects. This functions is intended + * for SCP more than anything. + * + * @param int $client_channel + * @param bool $want_reply + * @return bool + * @access private + */ + private function close_channel($client_channel, $want_reply = false) + { + // see http://tools.ietf.org/html/rfc4254#section-5.3 + + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + + if (!$want_reply) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + } + + $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + + $this->curTimeout = 5; + + while (!is_bool($this->get_channel_packet($client_channel))) { + } + + if ($this->is_timeout) { + $this->disconnect(); + } + + if ($want_reply) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + } + + if ($this->bitmap & self::MASK_SHELL) { + $this->bitmap&= ~self::MASK_SHELL; + } + } + + /** + * Disconnect + * + * @param int $reason + * @return bool + * @access protected + */ + protected function disconnect_helper($reason) + { + if ($this->bitmap & self::MASK_CONNECTED) { + $data = Strings::packSSH2('CNss', NET_SSH2_MSG_DISCONNECT, $reason, '', ''); + try { + $this->send_binary_packet($data); + } catch (\Exception $e) { + } + } + + $this->bitmap = 0; + if (is_resource($this->fsock) && get_resource_type($this->fsock) == 'stream') { + fclose($this->fsock); + } + + return false; + } + + /** + * Define Array + * + * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of + * named constants from it, using the value as the name of the constant and the index as the value of the constant. + * If any of the constants that would be defined already exists, none of the constants will be defined. + * + * @param mixed[] ...$args + * @access protected + */ + protected function define_array(...$args) + { + foreach ($args as $arg) { + foreach ($arg as $key => $value) { + if (!defined($value)) { + define($value, $key); + } else { + break 2; + } + } + } + } + + /** + * Returns a log of the packets that have been sent and received. + * + * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING') + * + * @access public + * @return array|false|string + */ + public function getLog() + { + if (!defined('NET_SSH2_LOGGING')) { + return false; + } + + switch (NET_SSH2_LOGGING) { + case self::LOG_SIMPLE: + return $this->message_number_log; + case self::LOG_COMPLEX: + $log = $this->format_log($this->message_log, $this->message_number_log); + return PHP_SAPI == 'cli' ? $log : '
      ' . $log . '
      '; + default: + return false; + } + } + + /** + * Formats a log for printing + * + * @param array $message_log + * @param array $message_number_log + * @access private + * @return string + */ + protected function format_log($message_log, $message_number_log) + { + $output = ''; + for ($i = 0; $i < count($message_log); $i++) { + $output.= $message_number_log[$i] . "\r\n"; + $current_log = $message_log[$i]; + $j = 0; + do { + if (strlen($current_log)) { + $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; + } + $fragment = Strings::shift($current_log, $this->log_short_width); + $hex = substr(preg_replace_callback('#.#s', function ($matches) { + return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); + }, $fragment), strlen($this->log_boundary)); + // replace non ASCII printable characters with dots + // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters + // also replace < with a . since < messes up the output on web browsers + $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); + $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; + $j++; + } while (strlen($current_log)); + $output.= "\r\n"; + } + + return $output; + } + + /** + * Helper function for agent->on_channel_open() + * + * Used when channels are created to inform agent + * of said channel opening. Must be called after + * channel open confirmation received + * + * @access private + */ + private function on_channel_open() + { + if (isset($this->agent)) { + $this->agent->registerChannelOpen($this); + } + } + + /** + * Returns the first value of the intersection of two arrays or false if + * the intersection is empty. The order is defined by the first parameter. + * + * @param array $array1 + * @param array $array2 + * @return mixed False if intersection is empty, else intersected value. + * @access private + */ + private static function array_intersect_first($array1, $array2) + { + foreach ($array1 as $value) { + if (in_array($value, $array2)) { + return $value; + } + } + return false; + } + + /** + * Returns all errors + * + * @return string[] + * @access public + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Returns the last error + * + * @return string + * @access public + */ + public function getLastError() + { + $count = count($this->errors); + + if ($count > 0) { + return $this->errors[$count - 1]; + } + } + + /** + * Return the server identification. + * + * @return string + * @access public + */ + public function getServerIdentification() + { + $this->connect(); + + return $this->server_identifier; + } + + /** + * Returns a list of algorithms the server supports + * + * @return array + * @access public + */ + public function getServerAlgorithms() + { + $this->connect(); + + return [ + 'kex' => $this->kex_algorithms, + 'hostkey' => $this->server_host_key_algorithms, + 'client_to_server' => [ + 'crypt' => $this->encryption_algorithms_client_to_server, + 'mac' => $this->mac_algorithms_client_to_server, + 'comp' => $this->compression_algorithms_client_to_server, + 'lang' => $this->languages_client_to_server + ], + 'server_to_client' => [ + 'crypt' => $this->encryption_algorithms_server_to_client, + 'mac' => $this->mac_algorithms_server_to_client, + 'comp' => $this->compression_algorithms_server_to_client, + 'lang' => $this->languages_server_to_client + ] + ]; + } + + /** + * Returns a list of KEX algorithms that phpseclib supports + * + * @return array + * @access public + */ + public static function getSupportedKEXAlgorithms() + { + $kex_algorithms = [ + // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using + // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the + // libssh repository for more information. + 'curve25519-sha256', + 'curve25519-sha256@libssh.org', + + 'ecdh-sha2-nistp256', // RFC 5656 + 'ecdh-sha2-nistp384', // RFC 5656 + 'ecdh-sha2-nistp521', // RFC 5656 + + 'diffie-hellman-group-exchange-sha256',// RFC 4419 + 'diffie-hellman-group-exchange-sha1', // RFC 4419 + + // Diffie-Hellman Key Agreement (DH) using integer modulo prime + // groups. + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', // REQUIRED + 'diffie-hellman-group15-sha512', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group17-sha512', + 'diffie-hellman-group18-sha512', + + 'diffie-hellman-group1-sha1', // REQUIRED + ]; + + return $kex_algorithms; + } + + /** + * Returns a list of host key algorithms that phpseclib supports + * + * @return array + * @access public + */ + public static function getSupportedHostKeyAlgorithms() + { + return [ + 'ssh-ed25519', // https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-02 + 'ecdsa-sha2-nistp256', // RFC 5656 + 'ecdsa-sha2-nistp384', // RFC 5656 + 'ecdsa-sha2-nistp521', // RFC 5656 + 'rsa-sha2-256', // RFC 8332 + 'rsa-sha2-512', // RFC 8332 + 'ssh-rsa', // RECOMMENDED sign Raw RSA Key + 'ssh-dss' // REQUIRED sign Raw DSS Key + ]; + } + + /** + * Returns a list of symmetric key algorithms that phpseclib supports + * + * @return array + * @access public + */ + public static function getSupportedEncryptionAlgorithms() + { + $algos = [ + // from : + 'aes128-gcm@openssh.com', + 'aes256-gcm@openssh.com', + + // from : + 'arcfour256', + 'arcfour128', + + //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key + + // CTR modes from : + 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key + 'aes192-ctr', // RECOMMENDED AES with 192-bit key + 'aes256-ctr', // RECOMMENDED AES with 256-bit key + + // from : + // one of the big benefits of chacha20-poly1305 is speed. the problem is... + // libsodium doesn't generate the poly1305 keys in the way ssh does and openssl's PHP bindings don't even + // seem to support poly1305 currently. so even if libsodium or openssl are being used for the chacha20 + // part, pure-PHP has to be used for the poly1305 part and that's gonna cause a big slow down. + // speed-wise it winds up being faster to use AES (when openssl or mcrypt are available) and some HMAC + // (which is always gonna be super fast to compute thanks to the hash extension, which + // "is bundled and compiled into PHP by default") + 'chacha20-poly1305@openssh.com', + + 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key + 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key + 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key + + 'aes128-cbc', // RECOMMENDED AES with a 128-bit key + 'aes192-cbc', // OPTIONAL AES with a 192-bit key + 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key + + 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key + 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key + 'twofish256-cbc', + 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc" + // (this is being retained for historical reasons) + + 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode + + 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode + + '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode + + '3des-cbc', // REQUIRED three-key 3DES in CBC mode + + //'none' // OPTIONAL no encryption; NOT RECOMMENDED + ]; + + if (self::$crypto_engine) { + $engines = [self::$crypto_engine]; + } else { + $engines = [ + 'libsodium', + 'OpenSSL (GCM)', + 'OpenSSL', + 'mcrypt', + 'Eval', + 'PHP' + ]; + } + + $ciphers = []; + + foreach ($engines as $engine) { + foreach ($algos as $algo) { + $obj = self::encryption_algorithm_to_crypt_instance($algo); + if ($obj instanceof Rijndael ) { + $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo)); + } + switch ($algo) { + case 'chacha20-poly1305@openssh.com': + case 'arcfour128': + case 'arcfour256': + if ($engine != 'Eval') { + continue 2; + } + break; + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + if ($engine == 'OpenSSL') { + continue 2; + } + $obj->setNonce('dummydummydu'); + } + if ($obj->isValidEngine($engine)) { + $algos = array_diff($algos, [$algo]); + $ciphers[] = $algo; + } + } + } + + return $ciphers; + } + + /** + * Returns a list of MAC algorithms that phpseclib supports + * + * @return array + * @access public + */ + public static function getSupportedMACAlgorithms() + { + return [ + 'hmac-sha2-256-etm@openssh.com', + 'hmac-sha2-512-etm@openssh.com', + 'umac-64-etm@openssh.com', + 'umac-128-etm@openssh.com', + 'hmac-sha1-etm@openssh.com', + + // from : + 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32) + 'hmac-sha2-512',// OPTIONAL HMAC-SHA512 (digest length = key length = 64) + + // from : + 'umac-64@openssh.com', + 'umac-128@openssh.com', + + 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20) + 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20) + 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16) + 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16) + //'none' // OPTIONAL no MAC; NOT RECOMMENDED + ]; + } + + /** + * Returns a list of compression algorithms that phpseclib supports + * + * @return array + * @access public + */ + public static function getSupportedCompressionAlgorithms() + { + return [ + 'none' // REQUIRED no compression + //'zlib' // OPTIONAL ZLIB (LZ77) compression + ]; + } + + /** + * Return list of negotiated algorithms + * + * Uses the same format as https://www.php.net/ssh2-methods-negotiated + * + * @return array + * @access public + */ + public function getAlgorithmsNegotiated() + { + $this->connect(); + + return [ + 'kex' => $this->kex_algorithm, + 'hostkey' => $this->signature_format, + 'client_to_server' => [ + 'crypt' => $this->encrypt->name, + 'mac' => $this->hmac_create->name, + 'comp' => 'none', + ], + 'server_to_client' => [ + 'crypt' => $this->decrypt->name, + 'mac' => $this->hmac_check->name, + 'comp' => 'none', + ] + ]; + } + + /** + * Accepts an associative array with up to four parameters as described at + * + * + * @param array $methods + * @access public + */ + public function setPreferredAlgorithms(array $methods) + { + $preferred = $methods; + + if (isset($preferred['kex'])) { + $preferred['kex'] = array_intersect( + $preferred['kex'], + static::getSupportedKEXAlgorithms() + ); + } + + if (isset($preferred['hostkey'])) { + $preferred['hostkey'] = array_intersect( + $preferred['hostkey'], + static::getSupportedHostKeyAlgorithms() + ); + } + + $keys = ['client_to_server', 'server_to_client']; + foreach ($keys as $key) { + if (isset($preferred[$key])) { + $a = &$preferred[$key]; + if (isset($a['crypt'])) { + $a['crypt'] = array_intersect( + $a['crypt'], + static::getSupportedEncryptionAlgorithms() + ); + } + if (isset($a['comp'])) { + $a['comp'] = array_intersect( + $a['comp'], + static::getSupportedCompressionAlgorithms() + ); + } + if (isset($a['mac'])) { + $a['mac'] = array_intersect( + $a['mac'], + static::getSupportedMACAlgorithms() + ); + } + } + } + + $keys = [ + 'kex', + 'hostkey', + 'client_to_server/crypt', + 'client_to_server/comp', + 'client_to_server/mac', + 'server_to_client/crypt', + 'server_to_client/comp', + 'server_to_client/mac', + ]; + foreach ($keys as $key) { + $p = $preferred; + $m = $methods; + + $subkeys = explode('/', $key); + foreach ($subkeys as $subkey) { + if (!isset($p[$subkey])) { + continue 2; + } + $p = $p[$subkey]; + $m = $m[$subkey]; + } + + if (count($p) != count($m)) { + $diff = array_diff($m, $p); + $msg = count($diff) == 1 ? + ' is not a supported algorithm' : + ' are not supported algorithms'; + throw new UnsupportedAlgorithmException(implode(', ', $diff) . $msg); + } + } + + $this->preferred = $preferred; + } + + /** + * Returns the banner message. + * + * Quoting from the RFC, "in some jurisdictions, sending a warning message before + * authentication may be relevant for getting legal protection." + * + * @return string + * @access public + */ + public function getBannerMessage() + { + return $this->banner_message; + } + + /** + * Returns the server public host key. + * + * Caching this the first time you connect to a server and checking the result on subsequent connections + * is recommended. Returns false if the server signature is not signed correctly with the public host key. + * + * @return mixed + * @throws \RuntimeException on badly formatted keys + * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format + * @access public + */ + public function getServerPublicHostKey() + { + if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { + if (!$this->connect()) { + return false; + } + } + + $signature = $this->signature; + $server_public_host_key = base64_encode($this->server_public_host_key); + + if ($this->signature_validated) { + return $this->bitmap ? + $this->signature_format . ' ' . $server_public_host_key : + false; + } + + $this->signature_validated = true; + + switch ($this->signature_format) { + case 'ssh-ed25519': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + $key = EC::loadFormat('OpenSSH', $server_public_host_key) + ->withSignatureFormat('SSH2'); + switch ($this->signature_format) { + case 'ssh-ed25519': + $hash = 'sha512'; + break; + case 'ecdsa-sha2-nistp256': + $hash = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + $hash = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + $hash = 'sha512'; + } + $key = $key->withHash($hash); + break; + case 'ssh-dss': + $key = DSA::loadFormat('OpenSSH', $server_public_host_key) + ->withSignatureFormat('SSH2') + ->withHash('sha1'); + break; + case 'ssh-rsa': + case 'rsa-sha2-256': + case 'rsa-sha2-512': + if (strlen($signature) < 15) { + return false; + } + Strings::shift($signature, 11); + $temp = unpack('Nlength', Strings::shift($signature, 4)); + $signature = Strings::shift($signature, $temp['length']); + + $key = RSA::loadFormat('OpenSSH', $server_public_host_key) + ->withPadding(RSA::SIGNATURE_PKCS1); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $hash = 'sha512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + } + $key = $key->withHash($hash); + break; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + throw new NoSupportedAlgorithmsException('Unsupported signature format'); + } + + if (!$key->verify($this->exchange_hash, $signature)) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + }; + + return $this->signature_format . ' ' . $server_public_host_key; + } + + /** + * Returns the exit status of an SSH command or false. + * + * @return false|int + * @access public + */ + public function getExitStatus() + { + if (is_null($this->exit_status)) { + return false; + } + return $this->exit_status; + } + + /** + * Returns the number of columns for the terminal window size. + * + * @return int + * @access public + */ + public function getWindowColumns() + { + return $this->windowColumns; + } + + /** + * Returns the number of rows for the terminal window size. + * + * @return int + * @access public + */ + public function getWindowRows() + { + return $this->windowRows; + } + + /** + * Sets the number of columns for the terminal window size. + * + * @param int $value + * @access public + */ + public function setWindowColumns($value) + { + $this->windowColumns = $value; + } + + /** + * Sets the number of rows for the terminal window size. + * + * @param int $value + * @access public + */ + public function setWindowRows($value) + { + $this->windowRows = $value; + } + + /** + * Sets the number of columns and rows for the terminal window size. + * + * @param int $columns + * @param int $rows + * @access public + */ + public function setWindowSize($columns = 80, $rows = 24) + { + $this->windowColumns = $columns; + $this->windowRows = $rows; + } + + /** + * To String Magic Method + * + * @return string + * @access public + */ + public function __toString() + { + return $this->getResourceId(); + } + + /** + * Get Resource ID + * + * We use {} because that symbols should not be in URL according to + * {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}. + * It will safe us from any conflicts, because otherwise regexp will + * match all alphanumeric domains. + * + * @return string + */ + public function getResourceId() + { + return '{' . spl_object_hash($this) . '}'; + } + + /** + * Return existing connection + * + * @param string $id + * + * @return bool|SSH2 will return false if no such connection + */ + public static function getConnectionByResourceId($id) + { + return isset(self::$connections[$id]) ? self::$connections[$id] : false; + } + + /** + * Return all excising connections + * + * @return SSH2[] + */ + public static function getConnections() + { + return self::$connections; + } + + /* + * Update packet types in log history + * + * @param string $old + * @param string $new + * @access private + */ + private function updateLogHistory($old, $new) + { + if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) { + $this->message_number_log[count($this->message_number_log) - 1] = str_replace( + $old, + $new, + $this->message_number_log[count($this->message_number_log) - 1] + ); + } + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php new file mode 100644 index 000000000..d2b955ae5 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php @@ -0,0 +1,297 @@ + + * login('username', $agent)) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * @category System + * @package SSH\Agent + * @author Jim Wigginton + * @copyright 2014 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH; + +use phpseclib3\Crypt\RSA; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\System\SSH\Agent\Identity; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\PublicKeyLoader; + +/** + * Pure-PHP ssh-agent client identity factory + * + * requestIdentities() method pumps out \phpseclib3\System\SSH\Agent\Identity objects + * + * @package SSH\Agent + * @author Jim Wigginton + * @access public + */ +class Agent +{ + use Common\Traits\ReadBytes; + + // Message numbers + + // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) + const SSH_AGENTC_REQUEST_IDENTITIES = 11; + // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). + const SSH_AGENT_IDENTITIES_ANSWER = 12; + // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3) + const SSH_AGENTC_SIGN_REQUEST = 13; + // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) + const SSH_AGENT_SIGN_RESPONSE = 14; + + // Agent forwarding status + + // no forwarding requested and not active + const FORWARD_NONE = 0; + // request agent forwarding when opportune + const FORWARD_REQUEST = 1; + // forwarding has been request and is active + const FORWARD_ACTIVE = 2; + + /** + * Unused + */ + const SSH_AGENT_FAILURE = 5; + + /** + * Socket Resource + * + * @var resource + * @access private + */ + private $fsock; + + /** + * Agent forwarding status + * + * @var int + * @access private + */ + private $forward_status = self::FORWARD_NONE; + + /** + * Buffer for accumulating forwarded authentication + * agent data arriving on SSH data channel destined + * for agent unix socket + * + * @var string + * @access private + */ + private $socket_buffer = ''; + + /** + * Tracking the number of bytes we are expecting + * to arrive for the agent socket on the SSH data + * channel + * + * @var int + * @access private + */ + private $expected_bytes = 0; + + /** + * The current request channel + * + * @var int + * @access private + */ + private $request_channel; + + /** + * Default Constructor + * + * @return \phpseclib3\System\SSH\Agent + * @throws \phpseclib3\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found + * @throws \RuntimeException on connection errors + * @access public + */ + public function __construct($address = null) + { + if (!$address) { + switch (true) { + case isset($_SERVER['SSH_AUTH_SOCK']): + $address = $_SERVER['SSH_AUTH_SOCK']; + break; + case isset($_ENV['SSH_AUTH_SOCK']): + $address = $_ENV['SSH_AUTH_SOCK']; + break; + default: + throw new BadConfigurationException('SSH_AUTH_SOCK not found'); + } + } + + $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); + if (!$this->fsock) { + throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); + } + } + + /** + * Request Identities + * + * See "2.5.2 Requesting a list of protocol 2 keys" + * Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects + * + * @return array + * @throws \RuntimeException on receipt of unexpected packets + * @access public + */ + public function requestIdentities() + { + if (!$this->fsock) { + return []; + } + + $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); + if (strlen($packet) != fputs($this->fsock, $packet)) { + throw new \RuntimeException('Connection closed while requesting identities'); + } + + $length = current(unpack('N', $this->readBytes(4))); + $packet = $this->readBytes($length); + + list($type, $keyCount) = Strings::unpackSSH2('CN', $packet); + if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { + throw new \RuntimeException('Unable to request identities'); + } + + $identities = []; + for ($i = 0; $i < $keyCount; $i++) { + list($key_blob, $comment) = Strings::unpackSSH2('ss', $packet); + $temp = $key_blob; + list($key_type) = Strings::unpackSSH2('s', $temp); + switch ($key_type) { + case 'ssh-rsa': + case 'ssh-dss': + case 'ssh-ed25519': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + $key = PublicKeyLoader::load($key_type . ' ' . base64_encode($key_blob)); + } + // resources are passed by reference by default + if (isset($key)) { + $identity = (new Identity($this->fsock)) + ->withPublicKey($key) + ->withPublicKeyBlob($key_blob); + $identities[] = $identity; + unset($key); + } + } + + return $identities; + } + + /** + * Signal that agent forwarding should + * be requested when a channel is opened + * + * @param \phpseclib3\Net\SSH2 $ssh + * @return bool + * @access public + */ + public function startSSHForwarding($ssh) + { + if ($this->forward_status == self::FORWARD_NONE) { + $this->forward_status = self::FORWARD_REQUEST; + } + } + + /** + * Request agent forwarding of remote server + * + * @param \phpseclib3\Net\SSH2 $ssh + * @return bool + * @access private + */ + private function request_forwarding($ssh) + { + if (!$ssh->requestAgentForwarding()) { + return false; + } + + $this->forward_status = self::FORWARD_ACTIVE; + + return true; + } + + /** + * On successful channel open + * + * This method is called upon successful channel + * open to give the SSH Agent an opportunity + * to take further action. i.e. request agent forwarding + * + * @param \phpseclib3\Net\SSH2 $ssh + * @access private + */ + public function registerChannelOpen($ssh) + { + if ($this->forward_status == self::FORWARD_REQUEST) { + $this->request_forwarding($ssh); + } + } + + /** + * Forward data to SSH Agent and return data reply + * + * @param string $data + * @return string Data from SSH Agent + * @throws \RuntimeException on connection errors + * @access public + */ + public function forwardData($data) + { + if ($this->expected_bytes > 0) { + $this->socket_buffer.= $data; + $this->expected_bytes -= strlen($data); + } else { + $agent_data_bytes = current(unpack('N', $data)); + $current_data_bytes = strlen($data); + $this->socket_buffer = $data; + if ($current_data_bytes != $agent_data_bytes + 4) { + $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes; + return false; + } + } + + if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { + throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); + } + + $this->socket_buffer = ''; + $this->expected_bytes = 0; + + $agent_reply_bytes = current(unpack('N', $this->readBytes(4))); + + $agent_reply_data = $this->readBytes($agent_reply_bytes); + $agent_reply_data = current(unpack('a*', $agent_reply_data)); + + return pack('Na*', $agent_reply_bytes, $agent_reply_data); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php new file mode 100644 index 000000000..20b0a958f --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php @@ -0,0 +1,336 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH\Agent; + +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\System\SSH\Agent; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\PrivateKey; + +/** + * Pure-PHP ssh-agent client identity object + * + * Instantiation should only be performed by \phpseclib3\System\SSH\Agent class. + * This could be thought of as implementing an interface that phpseclib3\Crypt\RSA + * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something. + * The methods in this interface would be getPublicKey and sign since those are the + * methods phpseclib looks for to perform public key authentication. + * + * @package SSH\Agent + * @author Jim Wigginton + * @access internal + */ +class Identity implements PrivateKey +{ + use \phpseclib3\System\SSH\Common\Traits\ReadBytes; + + // Signature Flags + // See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 + const SSH_AGENT_RSA2_256 = 2; + const SSH_AGENT_RSA2_512 = 4; + + /** + * Key Object + * + * @var \phpseclib3\Crypt\RSA + * @access private + * @see self::getPublicKey() + */ + private $key; + + /** + * Key Blob + * + * @var string + * @access private + * @see self::sign() + */ + private $key_blob; + + /** + * Socket Resource + * + * @var resource + * @access private + * @see self::sign() + */ + private $fsock; + + /** + * Signature flags + * + * @var int + * @access private + * @see self::sign() + * @see self::setHash() + */ + private $flags = 0; + + /** + * Curve Aliases + * + * @var array + * @access private + */ + private static $curveAliases = [ + 'secp256r1' => 'nistp256', + 'secp384r1' => 'nistp384', + 'secp521r1' => 'nistp521', + 'Ed25519' => 'Ed25519' + ]; + + /** + * Default Constructor. + * + * @param resource $fsock + * @return \phpseclib3\System\SSH\Agent\Identity + * @access private + */ + public function __construct($fsock) + { + $this->fsock = $fsock; + } + + /** + * Set Public Key + * + * Called by \phpseclib3\System\SSH\Agent::requestIdentities() + * + * @param \phpseclib3\Crypt\Common\PublicKey $key + * @access private + */ + public function withPublicKey($key) + { + if ($key instanceof EC) { + if (is_array($key->getCurve()) || !isset(self::$curveAliases[$key->getCurve()])) { + throw new UnsupportedAlgorithmException('The only supported curves are nistp256, nistp384, nistp512 and Ed25519'); + } + } + + $new = clone $this; + $new->key = $key; + return $new; + } + + /** + * Set Public Key + * + * Called by \phpseclib3\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key + * but this saves a small amount of computation. + * + * @param string $key_blob + * @access private + */ + public function withPublicKeyBlob($key_blob) + { + $new = clone $this; + $new->key_blob = $key_blob; + return $new; + } + + /** + * Get Public Key + * + * Wrapper for $this->key->getPublicKey() + * + * @param string $type optional + * @return mixed + * @access public + */ + public function getPublicKey($type = 'PKCS8') + { + return $this->key; + } + + /** + * Sets the hash + * + * @param string $hash + * @access public + */ + public function withHash($hash) + { + $new = clone $this; + + $hash = strtolower($hash); + + if ($this->key instanceof RSA) { + $new->flags = 0; + switch ($hash) { + case 'sha1': + break; + case 'sha256': + $new->flags = self::SSH_AGENT_RSA2_256; + break; + case 'sha512': + $new->flags = self::SSH_AGENT_RSA2_512; + break; + default: + throw new UnsupportedAlgorithmException('The only supported hashes for RSA are sha1, sha256 and sha512'); + } + } + if ($this->key instanceof EC) { + switch ($this->key->getCurve()) { + case 'secp256r1': + $expectedHash = 'sha256'; + break; + case 'secp384r1': + $expectedHash = 'sha384'; + break; + //case 'secp521r1': + //case 'Ed25519': + default: + $expectedHash = 'sha512'; + } + if ($hash != $expectedHash) { + throw new UnsupportedAlgorithmException('The only supported hash for ' . self::$curveAliases[$key->getCurve()] . ' is ' . $expectedHash); + } + } + if ($this->key instanceof DSA) { + if ($hash != 'sha1') { + throw new UnsupportedAlgorithmException('The only supported hash for DSA is sha1'); + } + } + return $new; + } + + /** + * Sets the padding + * + * Only PKCS1 padding is supported + * + * @param string $padding + * @access public + */ + public function withPadding($padding) + { + if (!$this->key instanceof RSA) { + throw new UnsupportedAlgorithmException('Only RSA keys support padding'); + } + if ($padding != RSA::SIGNATURE_PKCS1 && $padding != RSA::SIGNATURE_RELAXED_PKCS1) { + throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures'); + } + return $this; + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @access public + * @param string $format + */ + public function withSignatureFormat($format) + { + if ($this->key instanceof RSA) { + throw new UnsupportedAlgorithmException('Only DSA and EC keys support signature format setting'); + } + if ($format != 'SSH2') { + throw new UnsupportedAlgorithmException('Only SSH2-formatted signatures are currently supported'); + } + + return $this; + } + + /** + * Returns the curve + * + * Returns a string if it's a named curve, an array if not + * + * @access public + * @return string|array + */ + public function getCurve() + { + if (!$this->key instanceof EC) { + throw new UnsupportedAlgorithmException('Only EC keys have curves'); + } + + return $this->key->getCurve(); + } + + /** + * Create a signature + * + * See "2.6.2 Protocol 2 private key signature request" + * + * @param string $message + * @return string + * @throws \RuntimeException on connection errors + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @access public + */ + public function sign($message) + { + // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE + $packet = Strings::packSSH2( + 'CssN', + Agent::SSH_AGENTC_SIGN_REQUEST, + $this->key_blob, + $message, + $this->flags + ); + $packet = Strings::packSSH2('s', $packet); + if (strlen($packet) != fputs($this->fsock, $packet)) { + throw new \RuntimeException('Connection closed during signing'); + } + + $length = current(unpack('N', $this->readBytes(4))); + $packet = $this->readBytes($length); + + list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet); + if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { + throw new \RuntimeException('Unable to retrieve signature'); + } + + if (!$this->key instanceof RSA) { + return $signature_blob; + } + + list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob); + + return $signature_blob; + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); + } + + /** + * Sets the password + * + * @access public + * @param string|boolean $password + */ + public function withPassword($password = false) + { + throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php new file mode 100644 index 000000000..297808e42 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php @@ -0,0 +1,42 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH\Common\Traits; + +/** + * ReadBytes trait + * + * @package SSH + * @author Jim Wigginton + * @access public + */ +trait ReadBytes +{ + /** + * Read data + * + * @param int $length + * @throws \RuntimeException on connection errors + * @access public + */ + public function readBytes($length) + { + $temp = fread($this->fsock, $length); + if (strlen($temp) != $length) { + throw new \RuntimeException("Expected $length bytes; got " . strlen($temp)); + } + return $temp; + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php new file mode 100644 index 000000000..bd4ba0b5a --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php @@ -0,0 +1,20 @@ + Date: Wed, 3 Feb 2021 10:22:34 +0100 Subject: fix wrong operand --- Zotlabs/Lib/Enotify.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index 3a24cd349..d2a0f0abc 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -43,7 +43,7 @@ class Enotify { dbesc($params['to_xchan']) ); } - if ($x & $y) { + if ($x && $y) { $sender = $x[0]; $recip = $y[0]; } else { -- cgit v1.2.3 From a6162d3134cd7fcde4f45064b75f90008a7f8177 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 4 Feb 2021 21:01:25 +0100 Subject: downgrade phpseclib to version 2 --- composer.json | 2 +- composer.lock | 139 +- include/crypto.php | 97 +- vendor/composer/ClassLoader.php | 32 + vendor/composer/InstalledVersions.php | 151 +- vendor/composer/autoload_classmap.php | 368 +- vendor/composer/autoload_psr4.php | 3 +- vendor/composer/autoload_real.php | 2 +- vendor/composer/autoload_static.php | 377 +- vendor/composer/installed.json | 145 +- vendor/composer/installed.php | 36 +- vendor/paragonie/constant_time_encoding/.gitignore | 2 - .../paragonie/constant_time_encoding/.travis.yml | 24 - .../paragonie/constant_time_encoding/LICENSE.txt | 48 - vendor/paragonie/constant_time_encoding/README.md | 84 - .../paragonie/constant_time_encoding/composer.json | 51 - .../constant_time_encoding/phpunit.xml.dist | 13 - vendor/paragonie/constant_time_encoding/psalm.xml | 9 - .../constant_time_encoding/src/Base32.php | 471 --- .../constant_time_encoding/src/Base32Hex.php | 111 - .../constant_time_encoding/src/Base64.php | 271 -- .../constant_time_encoding/src/Base64DotSlash.php | 88 - .../src/Base64DotSlashOrdered.php | 82 - .../constant_time_encoding/src/Base64UrlSafe.php | 95 - .../constant_time_encoding/src/Binary.php | 85 - .../src/EncoderInterface.php | 52 - .../constant_time_encoding/src/Encoding.php | 260 -- .../paragonie/constant_time_encoding/src/Hex.php | 159 - .../constant_time_encoding/src/RFC4648.php | 175 - vendor/paragonie/random_compat/LICENSE | 22 - vendor/paragonie/random_compat/build-phar.sh | 5 - vendor/paragonie/random_compat/composer.json | 34 - .../random_compat/dist/random_compat.phar.pubkey | 5 - .../dist/random_compat.phar.pubkey.asc | 11 - vendor/paragonie/random_compat/lib/random.php | 32 - .../paragonie/random_compat/other/build_phar.php | 57 - vendor/paragonie/random_compat/psalm-autoload.php | 9 - vendor/paragonie/random_compat/psalm.xml | 19 - vendor/phpseclib/phpseclib/.github/FUNDING.yml | 12 - vendor/phpseclib/phpseclib/README.md | 4 +- vendor/phpseclib/phpseclib/composer.json | 8 +- .../phpseclib/Common/Functions/Strings.php | 387 -- vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php | 61 +- .../phpseclib/phpseclib/Crypt/Blowfish.php | 339 +- .../phpseclib/phpseclib/Crypt/ChaCha20.php | 797 ---- .../phpseclib/Crypt/Common/AsymmetricKey.php | 492 --- .../phpseclib/Crypt/Common/BlockCipher.php | 27 - .../Crypt/Common/Formats/Keys/OpenSSH.php | 234 -- .../phpseclib/Crypt/Common/Formats/Keys/PKCS.php | 80 - .../phpseclib/Crypt/Common/Formats/Keys/PKCS1.php | 223 -- .../phpseclib/Crypt/Common/Formats/Keys/PKCS8.php | 702 ---- .../phpseclib/Crypt/Common/Formats/Keys/PuTTY.php | 261 -- .../Crypt/Common/Formats/Signature/Raw.php | 66 - .../phpseclib/Crypt/Common/PrivateKey.php | 30 - .../phpseclib/phpseclib/Crypt/Common/PublicKey.php | 29 - .../phpseclib/Crypt/Common/StreamCipher.php | 59 - .../phpseclib/Crypt/Common/SymmetricKey.php | 3271 ----------------- .../phpseclib/Crypt/Common/Traits/Fingerprint.php | 62 - .../Crypt/Common/Traits/PasswordProtected.php | 51 - vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php | 502 +-- vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php | 400 -- .../phpseclib/Crypt/DH/Formats/Keys/PKCS1.php | 83 - .../phpseclib/Crypt/DH/Formats/Keys/PKCS8.php | 157 - .../phpseclib/phpseclib/Crypt/DH/Parameters.php | 40 - .../phpseclib/phpseclib/Crypt/DH/PrivateKey.php | 82 - .../phpseclib/phpseclib/Crypt/DH/PublicKey.php | 53 - vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php | 344 -- .../phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php | 126 - .../phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php | 151 - .../phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php | 170 - .../phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php | 118 - .../phpseclib/Crypt/DSA/Formats/Keys/Raw.php | 92 - .../phpseclib/Crypt/DSA/Formats/Keys/XML.php | 133 - .../phpseclib/Crypt/DSA/Formats/Signature/ASN1.php | 68 - .../phpseclib/Crypt/DSA/Formats/Signature/Raw.php | 29 - .../phpseclib/Crypt/DSA/Formats/Signature/SSH2.php | 78 - .../phpseclib/phpseclib/Crypt/DSA/Parameters.php | 40 - .../phpseclib/phpseclib/Crypt/DSA/PrivateKey.php | 159 - .../phpseclib/phpseclib/Crypt/DSA/PublicKey.php | 91 - vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php | 477 --- .../phpseclib/Crypt/EC/BaseCurves/Base.php | 220 -- .../phpseclib/Crypt/EC/BaseCurves/Binary.php | 378 -- .../phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php | 325 -- .../phpseclib/Crypt/EC/BaseCurves/Montgomery.php | 285 -- .../phpseclib/Crypt/EC/BaseCurves/Prime.php | 774 ---- .../Crypt/EC/BaseCurves/TwistedEdwards.php | 219 -- .../phpseclib/Crypt/EC/Curves/Curve25519.php | 64 - .../phpseclib/Crypt/EC/Curves/Curve448.php | 71 - .../phpseclib/Crypt/EC/Curves/Ed25519.php | 334 -- .../phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php | 267 -- .../phpseclib/Crypt/EC/Curves/brainpoolP160r1.php | 36 - .../phpseclib/Crypt/EC/Curves/brainpoolP160t1.php | 49 - .../phpseclib/Crypt/EC/Curves/brainpoolP192r1.php | 36 - .../phpseclib/Crypt/EC/Curves/brainpoolP192t1.php | 36 - .../phpseclib/Crypt/EC/Curves/brainpoolP224r1.php | 36 - .../phpseclib/Crypt/EC/Curves/brainpoolP224t1.php | 36 - .../phpseclib/Crypt/EC/Curves/brainpoolP256r1.php | 36 - .../phpseclib/Crypt/EC/Curves/brainpoolP256t1.php | 36 - .../phpseclib/Crypt/EC/Curves/brainpoolP320r1.php | 42 - .../phpseclib/Crypt/EC/Curves/brainpoolP320t1.php | 42 - .../phpseclib/Crypt/EC/Curves/brainpoolP384r1.php | 48 - .../phpseclib/Crypt/EC/Curves/brainpoolP384t1.php | 48 - .../phpseclib/Crypt/EC/Curves/brainpoolP512r1.php | 48 - .../phpseclib/Crypt/EC/Curves/brainpoolP512t1.php | 48 - .../phpseclib/Crypt/EC/Curves/nistb233.php | 20 - .../phpseclib/Crypt/EC/Curves/nistb409.php | 20 - .../phpseclib/Crypt/EC/Curves/nistk163.php | 20 - .../phpseclib/Crypt/EC/Curves/nistk233.php | 20 - .../phpseclib/Crypt/EC/Curves/nistk283.php | 20 - .../phpseclib/Crypt/EC/Curves/nistk409.php | 20 - .../phpseclib/Crypt/EC/Curves/nistp192.php | 20 - .../phpseclib/Crypt/EC/Curves/nistp224.php | 20 - .../phpseclib/Crypt/EC/Curves/nistp256.php | 20 - .../phpseclib/Crypt/EC/Curves/nistp384.php | 20 - .../phpseclib/Crypt/EC/Curves/nistp521.php | 20 - .../phpseclib/Crypt/EC/Curves/nistt571.php | 20 - .../phpseclib/Crypt/EC/Curves/prime192v1.php | 20 - .../phpseclib/Crypt/EC/Curves/prime192v2.php | 36 - .../phpseclib/Crypt/EC/Curves/prime192v3.php | 36 - .../phpseclib/Crypt/EC/Curves/prime239v1.php | 36 - .../phpseclib/Crypt/EC/Curves/prime239v2.php | 36 - .../phpseclib/Crypt/EC/Curves/prime239v3.php | 36 - .../phpseclib/Crypt/EC/Curves/prime256v1.php | 20 - .../phpseclib/Crypt/EC/Curves/secp112r1.php | 36 - .../phpseclib/Crypt/EC/Curves/secp112r2.php | 37 - .../phpseclib/Crypt/EC/Curves/secp128r1.php | 36 - .../phpseclib/Crypt/EC/Curves/secp128r2.php | 37 - .../phpseclib/Crypt/EC/Curves/secp160k1.php | 48 - .../phpseclib/Crypt/EC/Curves/secp160r1.php | 36 - .../phpseclib/Crypt/EC/Curves/secp160r2.php | 37 - .../phpseclib/Crypt/EC/Curves/secp192k1.php | 47 - .../phpseclib/Crypt/EC/Curves/secp192r1.php | 80 - .../phpseclib/Crypt/EC/Curves/secp224k1.php | 47 - .../phpseclib/Crypt/EC/Curves/secp224r1.php | 36 - .../phpseclib/Crypt/EC/Curves/secp256k1.php | 51 - .../phpseclib/Crypt/EC/Curves/secp256r1.php | 36 - .../phpseclib/Crypt/EC/Curves/secp384r1.php | 54 - .../phpseclib/Crypt/EC/Curves/secp521r1.php | 48 - .../phpseclib/Crypt/EC/Curves/sect113r1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect113r2.php | 36 - .../phpseclib/Crypt/EC/Curves/sect131r1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect131r2.php | 36 - .../phpseclib/Crypt/EC/Curves/sect163k1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect163r1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect163r2.php | 36 - .../phpseclib/Crypt/EC/Curves/sect193r1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect193r2.php | 36 - .../phpseclib/Crypt/EC/Curves/sect233k1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect233r1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect239k1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect283k1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect283r1.php | 36 - .../phpseclib/Crypt/EC/Curves/sect409k1.php | 39 - .../phpseclib/Crypt/EC/Curves/sect409r1.php | 39 - .../phpseclib/Crypt/EC/Curves/sect571k1.php | 43 - .../phpseclib/Crypt/EC/Curves/sect571r1.php | 43 - .../phpseclib/Crypt/EC/Formats/Keys/Common.php | 555 --- .../Crypt/EC/Formats/Keys/MontgomeryPrivate.php | 108 - .../Crypt/EC/Formats/Keys/MontgomeryPublic.php | 79 - .../phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php | 216 -- .../phpseclib/Crypt/EC/Formats/Keys/PKCS1.php | 203 -- .../phpseclib/Crypt/EC/Formats/Keys/PKCS8.php | 249 -- .../phpseclib/Crypt/EC/Formats/Keys/PuTTY.php | 146 - .../phpseclib/Crypt/EC/Formats/Keys/XML.php | 484 --- .../phpseclib/Crypt/EC/Formats/Keys/libsodium.php | 122 - .../phpseclib/Crypt/EC/Formats/Signature/ASN1.php | 68 - .../phpseclib/Crypt/EC/Formats/Signature/Raw.php | 29 - .../phpseclib/Crypt/EC/Formats/Signature/SSH2.php | 100 - .../phpseclib/phpseclib/Crypt/EC/Parameters.php | 40 - .../phpseclib/phpseclib/Crypt/EC/PrivateKey.php | 258 -- .../phpseclib/phpseclib/Crypt/EC/PublicKey.php | 177 - .../phpseclib/phpseclib/phpseclib/Crypt/Hash.php | 1555 +++----- .../phpseclib/phpseclib/Crypt/PublicKeyLoader.php | 64 - vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php | 399 +- vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php | 157 +- vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php | 3282 ++++++++++++++--- .../phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php | 242 -- .../phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php | 140 - .../phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php | 167 - .../phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php | 149 - .../phpseclib/Crypt/RSA/Formats/Keys/PSS.php | 250 -- .../phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php | 130 - .../phpseclib/Crypt/RSA/Formats/Keys/Raw.php | 108 - .../phpseclib/Crypt/RSA/Formats/Keys/XML.php | 173 - .../phpseclib/phpseclib/Crypt/RSA/PrivateKey.php | 556 --- .../phpseclib/phpseclib/Crypt/RSA/PublicKey.php | 507 --- .../phpseclib/phpseclib/phpseclib/Crypt/Random.php | 150 +- .../phpseclib/phpseclib/Crypt/Rijndael.php | 662 ++-- .../phpseclib/phpseclib/Crypt/Salsa20.php | 529 --- .../phpseclib/phpseclib/Crypt/TripleDES.php | 226 +- .../phpseclib/phpseclib/Crypt/Twofish.php | 424 ++- .../Exception/BadConfigurationException.php | 26 - .../phpseclib/Exception/BadDecryptionException.php | 26 - .../phpseclib/Exception/BadModeException.php | 26 - .../Exception/ConnectionClosedException.php | 26 - .../phpseclib/Exception/FileNotFoundException.php | 26 - .../Exception/InconsistentSetupException.php | 26 - .../Exception/InsufficientSetupException.php | 26 - .../phpseclib/Exception/NoKeyLoadedException.php | 26 - .../Exception/NoSupportedAlgorithmsException.php | 26 - .../Exception/UnableToConnectException.php | 26 - .../Exception/UnsupportedAlgorithmException.php | 26 - .../Exception/UnsupportedCurveException.php | 26 - .../Exception/UnsupportedFormatException.php | 26 - .../Exception/UnsupportedOperationException.php | 26 - vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php | 87 +- vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php | 469 +-- .../phpseclib/phpseclib/File/ASN1/Element.php | 16 +- .../phpseclib/File/ASN1/Maps/AccessDescription.php | 36 - .../File/ASN1/Maps/AdministrationDomainName.php | 40 - .../File/ASN1/Maps/AlgorithmIdentifier.php | 39 - .../phpseclib/File/ASN1/Maps/AnotherName.php | 41 - .../phpseclib/File/ASN1/Maps/Attribute.php | 41 - .../phpseclib/File/ASN1/Maps/AttributeType.php | 30 - .../File/ASN1/Maps/AttributeTypeAndValue.php | 36 - .../phpseclib/File/ASN1/Maps/AttributeValue.php | 30 - .../phpseclib/File/ASN1/Maps/Attributes.php | 35 - .../File/ASN1/Maps/AuthorityInfoAccessSyntax.php | 35 - .../File/ASN1/Maps/AuthorityKeyIdentifier.php | 49 - .../phpseclib/File/ASN1/Maps/BaseDistance.php | 30 - .../phpseclib/File/ASN1/Maps/BasicConstraints.php | 43 - .../ASN1/Maps/BuiltInDomainDefinedAttribute.php | 36 - .../ASN1/Maps/BuiltInDomainDefinedAttributes.php | 35 - .../File/ASN1/Maps/BuiltInStandardAttributes.php | 71 - .../phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php | 30 - .../File/ASN1/Maps/CRLDistributionPoints.php | 35 - .../phpseclib/File/ASN1/Maps/CRLNumber.php | 30 - .../phpseclib/File/ASN1/Maps/CRLReason.php | 45 - .../phpseclib/File/ASN1/Maps/CertPolicyId.php | 30 - .../phpseclib/File/ASN1/Maps/Certificate.php | 37 - .../phpseclib/File/ASN1/Maps/CertificateIssuer.php | 30 - .../phpseclib/File/ASN1/Maps/CertificateList.php | 37 - .../File/ASN1/Maps/CertificatePolicies.php | 35 - .../File/ASN1/Maps/CertificateSerialNumber.php | 30 - .../File/ASN1/Maps/CertificationRequest.php | 37 - .../File/ASN1/Maps/CertificationRequestInfo.php | 45 - .../File/ASN1/Maps/Characteristic_two.php | 40 - .../phpseclib/File/ASN1/Maps/CountryName.php | 40 - .../phpseclib/phpseclib/File/ASN1/Maps/Curve.php | 40 - .../phpseclib/File/ASN1/Maps/DHParameter.php | 42 - .../phpseclib/File/ASN1/Maps/DSAParams.php | 37 - .../phpseclib/File/ASN1/Maps/DSAPrivateKey.php | 40 - .../phpseclib/File/ASN1/Maps/DSAPublicKey.php | 30 - .../phpseclib/File/ASN1/Maps/DigestInfo.php | 38 - .../phpseclib/File/ASN1/Maps/DirectoryString.php | 39 - .../phpseclib/File/ASN1/Maps/DisplayText.php | 38 - .../phpseclib/File/ASN1/Maps/DistributionPoint.php | 49 - .../File/ASN1/Maps/DistributionPointName.php | 44 - .../phpseclib/File/ASN1/Maps/DssSigValue.php | 36 - .../phpseclib/File/ASN1/Maps/ECParameters.php | 49 - .../phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php | 30 - .../phpseclib/File/ASN1/Maps/ECPrivateKey.php | 52 - .../phpseclib/File/ASN1/Maps/EDIPartyName.php | 46 - .../phpseclib/File/ASN1/Maps/EcdsaSigValue.php | 36 - .../phpseclib/File/ASN1/Maps/EncryptedData.php | 30 - .../File/ASN1/Maps/EncryptedPrivateKeyInfo.php | 36 - .../phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php | 35 - .../phpseclib/File/ASN1/Maps/Extension.php | 47 - .../File/ASN1/Maps/ExtensionAttribute.php | 46 - .../File/ASN1/Maps/ExtensionAttributes.php | 35 - .../phpseclib/File/ASN1/Maps/Extensions.php | 37 - .../phpseclib/File/ASN1/Maps/FieldElement.php | 30 - .../phpseclib/phpseclib/File/ASN1/Maps/FieldID.php | 39 - .../phpseclib/File/ASN1/Maps/GeneralName.php | 84 - .../phpseclib/File/ASN1/Maps/GeneralNames.php | 35 - .../phpseclib/File/ASN1/Maps/GeneralSubtree.php | 46 - .../phpseclib/File/ASN1/Maps/GeneralSubtrees.php | 35 - .../phpseclib/File/ASN1/Maps/HashAlgorithm.php | 30 - .../File/ASN1/Maps/HoldInstructionCode.php | 30 - .../phpseclib/File/ASN1/Maps/InvalidityDate.php | 30 - .../phpseclib/File/ASN1/Maps/IssuerAltName.php | 30 - .../File/ASN1/Maps/IssuingDistributionPoint.php | 72 - .../phpseclib/File/ASN1/Maps/KeyIdentifier.php | 30 - .../phpseclib/File/ASN1/Maps/KeyPurposeId.php | 30 - .../phpseclib/File/ASN1/Maps/KeyUsage.php | 43 - .../phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php | 30 - .../phpseclib/phpseclib/File/ASN1/Maps/Name.php | 35 - .../phpseclib/File/ASN1/Maps/NameConstraints.php | 44 - .../phpseclib/File/ASN1/Maps/NetworkAddress.php | 30 - .../phpseclib/File/ASN1/Maps/NoticeReference.php | 41 - .../File/ASN1/Maps/NumericUserIdentifier.php | 30 - .../phpseclib/File/ASN1/Maps/ORAddress.php | 37 - .../phpseclib/File/ASN1/Maps/OneAsymmetricKey.php | 52 - .../phpseclib/File/ASN1/Maps/OrganizationName.php | 30 - .../File/ASN1/Maps/OrganizationalUnitNames.php | 35 - .../phpseclib/File/ASN1/Maps/OtherPrimeInfo.php | 38 - .../phpseclib/File/ASN1/Maps/OtherPrimeInfos.php | 36 - .../phpseclib/File/ASN1/Maps/PBEParameter.php | 38 - .../phpseclib/File/ASN1/Maps/PBES2params.php | 38 - .../phpseclib/File/ASN1/Maps/PBKDF2params.php | 45 - .../phpseclib/File/ASN1/Maps/PBMAC1params.php | 38 - .../phpseclib/File/ASN1/Maps/PKCS9String.php | 36 - .../phpseclib/File/ASN1/Maps/Pentanomial.php | 37 - .../phpseclib/File/ASN1/Maps/PersonalName.php | 58 - .../phpseclib/File/ASN1/Maps/PolicyInformation.php | 42 - .../phpseclib/File/ASN1/Maps/PolicyMappings.php | 41 - .../phpseclib/File/ASN1/Maps/PolicyQualifierId.php | 30 - .../File/ASN1/Maps/PolicyQualifierInfo.php | 36 - .../phpseclib/File/ASN1/Maps/PostalAddress.php | 36 - .../phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php | 30 - .../phpseclib/File/ASN1/Maps/PrivateDomainName.php | 36 - .../phpseclib/File/ASN1/Maps/PrivateKey.php | 30 - .../phpseclib/File/ASN1/Maps/PrivateKeyInfo.php | 45 - .../File/ASN1/Maps/PrivateKeyUsagePeriod.php | 44 - .../phpseclib/File/ASN1/Maps/PublicKey.php | 30 - .../File/ASN1/Maps/PublicKeyAndChallenge.php | 36 - .../phpseclib/File/ASN1/Maps/PublicKeyInfo.php | 39 - .../phpseclib/File/ASN1/Maps/RC2CBCParameter.php | 41 - .../phpseclib/File/ASN1/Maps/RDNSequence.php | 42 - .../phpseclib/File/ASN1/Maps/RSAPrivateKey.php | 48 - .../phpseclib/File/ASN1/Maps/RSAPublicKey.php | 36 - .../phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php | 62 - .../phpseclib/File/ASN1/Maps/ReasonFlags.php | 43 - .../File/ASN1/Maps/RelativeDistinguishedName.php | 41 - .../File/ASN1/Maps/RevokedCertificate.php | 39 - .../File/ASN1/Maps/SignedPublicKeyAndChallenge.php | 37 - .../phpseclib/File/ASN1/Maps/SpecifiedECDomain.php | 49 - .../phpseclib/File/ASN1/Maps/SubjectAltName.php | 30 - .../File/ASN1/Maps/SubjectDirectoryAttributes.php | 35 - .../File/ASN1/Maps/SubjectInfoAccessSyntax.php | 35 - .../File/ASN1/Maps/SubjectPublicKeyInfo.php | 36 - .../phpseclib/File/ASN1/Maps/TBSCertList.php | 58 - .../phpseclib/File/ASN1/Maps/TBSCertificate.php | 69 - .../File/ASN1/Maps/TerminalIdentifier.php | 30 - .../phpseclib/phpseclib/File/ASN1/Maps/Time.php | 36 - .../phpseclib/File/ASN1/Maps/Trinomial.php | 30 - .../phpseclib/File/ASN1/Maps/UniqueIdentifier.php | 30 - .../phpseclib/File/ASN1/Maps/UserNotice.php | 42 - .../phpseclib/File/ASN1/Maps/Validity.php | 36 - .../File/ASN1/Maps/netscape_ca_policy_url.php | 30 - .../File/ASN1/Maps/netscape_cert_type.php | 44 - .../phpseclib/File/ASN1/Maps/netscape_comment.php | 30 - vendor/phpseclib/phpseclib/phpseclib/File/X509.php | 2834 ++++++++++----- .../phpseclib/phpseclib/Math/BigInteger.php | 3819 +++++++++++++++++--- .../phpseclib/Math/BigInteger/Engines/BCMath.php | 742 ---- .../Math/BigInteger/Engines/BCMath/Base.php | 116 - .../Math/BigInteger/Engines/BCMath/BuiltIn.php | 44 - .../BigInteger/Engines/BCMath/DefaultEngine.php | 29 - .../Math/BigInteger/Engines/BCMath/OpenSSL.php | 29 - .../Engines/BCMath/Reductions/Barrett.php | 193 - .../Engines/BCMath/Reductions/EvalBarrett.php | 117 - .../phpseclib/Math/BigInteger/Engines/Engine.php | 1219 ------- .../phpseclib/Math/BigInteger/Engines/GMP.php | 751 ---- .../Math/BigInteger/Engines/GMP/DefaultEngine.php | 44 - .../phpseclib/Math/BigInteger/Engines/OpenSSL.php | 75 - .../phpseclib/Math/BigInteger/Engines/PHP.php | 1316 ------- .../phpseclib/Math/BigInteger/Engines/PHP/Base.php | 149 - .../Math/BigInteger/Engines/PHP/DefaultEngine.php | 29 - .../Math/BigInteger/Engines/PHP/Montgomery.php | 93 - .../Math/BigInteger/Engines/PHP/OpenSSL.php | 29 - .../BigInteger/Engines/PHP/Reductions/Barrett.php | 284 -- .../BigInteger/Engines/PHP/Reductions/Classic.php | 46 - .../Engines/PHP/Reductions/EvalBarrett.php | 492 --- .../Engines/PHP/Reductions/Montgomery.php | 130 - .../Engines/PHP/Reductions/MontgomeryMult.php | 81 - .../Engines/PHP/Reductions/PowerOfTwo.php | 63 - .../phpseclib/Math/BigInteger/Engines/PHP32.php | 418 --- .../phpseclib/Math/BigInteger/Engines/PHP64.php | 422 --- .../phpseclib/phpseclib/Math/BinaryField.php | 196 - .../phpseclib/Math/BinaryField/Integer.php | 520 --- .../phpseclib/Math/Common/FiniteField.php | 26 - .../phpseclib/Math/Common/FiniteField/Integer.php | 26 - .../phpseclib/phpseclib/Math/PrimeField.php | 114 - .../phpseclib/Math/PrimeField/Integer.php | 399 -- vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php | 1091 +++--- .../phpseclib/phpseclib/Net/SFTP/Stream.php | 126 +- vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php | 3202 ++++++++-------- .../phpseclib/phpseclib/System/SSH/Agent.php | 208 +- .../phpseclib/System/SSH/Agent/Identity.php | 277 +- .../System/SSH/Common/Traits/ReadBytes.php | 42 - vendor/phpseclib/phpseclib/phpseclib/bootstrap.php | 8 +- 371 files changed, 13215 insertions(+), 44562 deletions(-) delete mode 100644 vendor/paragonie/constant_time_encoding/.gitignore delete mode 100644 vendor/paragonie/constant_time_encoding/.travis.yml delete mode 100644 vendor/paragonie/constant_time_encoding/LICENSE.txt delete mode 100644 vendor/paragonie/constant_time_encoding/README.md delete mode 100644 vendor/paragonie/constant_time_encoding/composer.json delete mode 100644 vendor/paragonie/constant_time_encoding/phpunit.xml.dist delete mode 100644 vendor/paragonie/constant_time_encoding/psalm.xml delete mode 100644 vendor/paragonie/constant_time_encoding/src/Base32.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Base32Hex.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Base64.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Binary.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/EncoderInterface.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Encoding.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/Hex.php delete mode 100644 vendor/paragonie/constant_time_encoding/src/RFC4648.php delete mode 100644 vendor/paragonie/random_compat/LICENSE delete mode 100755 vendor/paragonie/random_compat/build-phar.sh delete mode 100644 vendor/paragonie/random_compat/composer.json delete mode 100644 vendor/paragonie/random_compat/dist/random_compat.phar.pubkey delete mode 100644 vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc delete mode 100644 vendor/paragonie/random_compat/lib/random.php delete mode 100644 vendor/paragonie/random_compat/other/build_phar.php delete mode 100644 vendor/paragonie/random_compat/psalm-autoload.php delete mode 100644 vendor/paragonie/random_compat/psalm.xml delete mode 100644 vendor/phpseclib/phpseclib/.github/FUNDING.yml delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php delete mode 100644 vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php diff --git a/composer.json b/composer.json index 8aecd896a..f5654858d 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "twbs/bootstrap": "^4.3.1", "blueimp/jquery-file-upload": "^10.3", "desandro/imagesloaded": "^4.1", - "phpseclib/phpseclib": "~3.0" + "phpseclib/phpseclib": "~2.0" }, "require-dev": { "phpunit/phpunit": "^9.4", diff --git a/composer.lock b/composer.lock index 466aa08b7..fcd90e12d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "49baaaa19b27cdfbb644c7ab94b45bce", + "content-hash": "bc4a925533b7fe89fd5c8e94075835c6", "packages": [ { "name": "blueimp/jquery-file-upload", @@ -513,123 +513,6 @@ }, "time": "2019-12-02T02:32:27+00:00" }, - { - "name": "paragonie/constant_time_encoding", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", - "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", - "shasum": "" - }, - "require": { - "php": "^7|^8" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" - }, - "type": "library", - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base16", - "base32", - "base32_decode", - "base32_encode", - "base64", - "base64_decode", - "base64_encode", - "bin2hex", - "encoding", - "hex", - "hex2bin", - "rfc4648" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "source": "https://github.com/paragonie/constant_time_encoding" - }, - "time": "2020-12-06T15:14:20+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "time": "2020-10-15T08:29:30+00:00" - }, { "name": "pear/text_languagedetect", "version": "v1.0.1", @@ -680,26 +563,24 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.4", + "version": "2.0.30", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9" + "reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/845a2275e886ba9fb386c8f59cb383dd9c8963e9", - "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/136b9ca7eebef78be14abf90d65c5e57b6bc5d36", + "reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36", "shasum": "" }, "require": { - "paragonie/constant_time_encoding": "^1|^2", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" + "php": ">=5.3.3" }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^5.7|^6.0|^9.4", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { @@ -714,7 +595,7 @@ "phpseclib/bootstrap.php" ], "psr-4": { - "phpseclib3\\": "phpseclib/" + "phpseclib\\": "phpseclib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -771,7 +652,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.4" + "source": "https://github.com/phpseclib/phpseclib/tree/2.0.30" }, "funding": [ { @@ -787,7 +668,7 @@ "type": "tidelift" } ], - "time": "2021-01-25T19:02:05+00:00" + "time": "2020-12-17T05:42:04+00:00" }, { "name": "psr/log", diff --git a/include/crypto.php b/include/crypto.php index 39bfd8d43..0d3a5842d 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -1,5 +1,8 @@ 0) ? true : false); @@ -110,7 +113,7 @@ function CAST5CFB_decrypt($data,$key,$iv) { function crypto_encapsulate($data,$pubkey,$alg='aes256cbc') { $fn = strtoupper($alg) . '_encrypt'; - + if($alg === 'aes256cbc') return aes_encapsulate($data,$pubkey); @@ -150,7 +153,7 @@ function other_encapsulate($data,$pubkey,$alg) { // assurance of security since it is meaningless if the source algorithms // have been compromised. Also none of this matters if RSA has been // compromised by state actors and evidence is mounting that this has - // already happened. + // already happened. $result = [ 'encrypted' => true ]; $key = openssl_random_pseudo_bytes(256); @@ -177,11 +180,11 @@ function other_encapsulate($data,$pubkey,$alg) { function crypto_methods() { - // aes256cbc is provided for compatibility with earlier zot implementations which assume 32-byte key and 16-byte iv. + // aes256cbc is provided for compatibility with earlier zot implementations which assume 32-byte key and 16-byte iv. // other_encapsulate() now produces these longer keys/ivs by default so that it is difficult to guess a - // particular implementation or choice of underlying implementations based on the key/iv length. + // particular implementation or choice of underlying implementations based on the key/iv length. // The actual methods are responsible for deriving the actual key/iv from the provided parameters; - // possibly by truncation or segmentation - though many other methods could be used. + // possibly by truncation or segmentation - though many other methods could be used. $r = [ 'aes256ctr.oaep', 'camellia256cfb.oaep', 'cast5cfb.oaep', 'aes256ctr', 'camellia256cfb', 'cast5cfb', 'aes256cbc', 'aes128cbc', 'cast5cbc' ]; call_hooks('crypto_methods',$r); @@ -280,13 +283,13 @@ function new_keypair($bits) { $openssl_options = array( 'digest_alg' => 'sha1', 'private_key_bits' => $bits, - 'encrypt_key' => false + 'encrypt_key' => false ); $conf = get_config('system','openssl_conf_file'); if($conf) $openssl_options['config'] = $conf; - + $result = openssl_pkey_new($openssl_options); if(empty($result)) { @@ -321,7 +324,7 @@ function DerToPem($Der, $Private=false) $result = "-----BEGIN {$title}-----\n"; $result .= $body . "\n"; $result .= "-----END {$title}-----\n"; - + return $result; } @@ -338,7 +341,7 @@ function DerToRsa($Der) $result = "-----BEGIN {$title}-----\n"; $result .= $body . "\n"; $result .= "-----END {$title}-----\n"; - + return $result; } @@ -383,11 +386,24 @@ function pkcs1_encode($Modulus,$PublicExponent) { // http://stackoverflow.com/questions/27568570/how-to-convert-raw-modulus-exponent-to-rsa-public-key-pem-format -function metopem($m,$e) { - $der = pkcs8_encode($m,$e); +/** + * @param string $m modulo + * @param string $e exponent + * @return string + */ +function metopem($m, $e) { + + $key = PublicKeyLoader::load([ + 'e' => new BigInteger($e, 256), + 'n' => new BigInteger($m, 256) + ]); + hz_syslog('metopem: ' . $key->toString('PKCS8')); + return $key->toString('PKCS8'); + +/* $der = pkcs8_encode($m,$e); $key = DerToPem($der,false); - return $key; -} + return $key;*/ +} function pubrsatome($key,&$m,&$e) { @@ -406,16 +422,44 @@ function pubrsatome($key,&$m,&$e) { function rsatopem($key) { - pubrsatome($key,$m,$e); - return(metopem($m,$e)); + + $key = PublicKeyLoader::load($key); + hz_syslog('rsatopem: ' . $key->toString('PKCS8')); + + return $key->toString('PKCS8'); + + +/* pubrsatome($key,$m,$e); + return(metopem($m,$e));*/ } function pemtorsa($key) { - pemtome($key,$m,$e); - return(metorsa($m,$e)); + $key = PublicKeyLoader::load($key); + hz_syslog('pemtorsa: ' . $key->toString('PKCS1')); + + return $key->toString('PKCS1'); + +/* pemtome($key,$m,$e); + return(metorsa($m,$e));*/ + } function pemtome($key,&$m,&$e) { + + $key = PublicKeyLoader::load($key); + $m = new BigInteger($key->n, 256); + $e = new BigInteger($key->e, 256); + + +/* $rsa = new RSA(); + $rsa->loadKey($key); + $rsa->setPublicKey(); + + $modulus = $rsa->modulus->toBytes(); + $exponent = $rsa->exponent->toBytes(); + + + $lines = explode("\n",$key); unset($lines[0]); unset($lines[count($lines)]); @@ -424,14 +468,23 @@ function pemtome($key,&$m,&$e) { $r = ASN_BASE::parseASNString($x); $m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData); - $e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData); + $e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);*/ } function metorsa($m,$e) { - $der = pkcs1_encode($m,$e); + + $key = PublicKeyLoader::load([ + 'e' => new BigInteger($e, 256), + 'n' => new BigInteger($m, 256) + ]); + hz_syslog('metorsa: ' . $key->toString('PKCS8')); + + return $key->toString('PKCS8'); + +/* $der = pkcs1_encode($m,$e); $key = DerToRsa($der); - return $key; -} + return $key;*/ +} diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 1a58957d2..4d989a212 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -42,6 +42,8 @@ namespace Composer\Autoload; */ class ClassLoader { + private $vendorDir; + // PSR-4 private $prefixLengthsPsr4 = array(); private $prefixDirsPsr4 = array(); @@ -57,6 +59,13 @@ class ClassLoader private $missingClasses = array(); private $apcuPrefix; + private static $registeredLoaders = array(); + + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -300,6 +309,15 @@ class ClassLoader public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + //no-op + } elseif ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** @@ -308,6 +326,10 @@ class ClassLoader public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** @@ -367,6 +389,16 @@ class ClassLoader return $file; } + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + private function findFileWithExtension($class, $ext) { // PSR-4 lookup diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index d46574ac8..97df88926 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -12,6 +12,7 @@ namespace Composer; +use Composer\Autoload\ClassLoader; use Composer\Semver\VersionParser; @@ -24,12 +25,12 @@ class InstalledVersions private static $installed = array ( 'root' => array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', + 'pretty_version' => 'dev-5.2RC', + 'version' => 'dev-5.2RC', 'aliases' => array ( ), - 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', + 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -115,24 +116,6 @@ private static $installed = array ( ), 'reference' => 'c83178d49e372ca967d1a8c77ae4e051b3a3c75c', ), - 'paragonie/constant_time_encoding' => - array ( - 'pretty_version' => 'v2.4.0', - 'version' => '2.4.0.0', - 'aliases' => - array ( - ), - 'reference' => 'f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c', - ), - 'paragonie/random_compat' => - array ( - 'pretty_version' => 'v9.99.100', - 'version' => '9.99.100.0', - 'aliases' => - array ( - ), - 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', - ), 'pear/text_languagedetect' => array ( 'pretty_version' => 'v1.0.1', @@ -144,12 +127,12 @@ private static $installed = array ( ), 'phpseclib/phpseclib' => array ( - 'pretty_version' => '3.0.4', - 'version' => '3.0.4.0', + 'pretty_version' => '2.0.30', + 'version' => '2.0.30.0', 'aliases' => array ( ), - 'reference' => '845a2275e886ba9fb386c8f59cb383dd9c8963e9', + 'reference' => '136b9ca7eebef78be14abf90d65c5e57b6bc5d36', ), 'psr/log' => array ( @@ -284,15 +267,17 @@ private static $installed = array ( ), 'zotlabs/hubzilla' => array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', + 'pretty_version' => 'dev-5.2RC', + 'version' => 'dev-5.2RC', 'aliases' => array ( ), - 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', + 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', ), ), ); +private static $canGetVendors; +private static $installedByVendor = array(); @@ -302,7 +287,17 @@ private static $installed = array ( public static function getInstalledPackages() { -return array_keys(self::$installed['versions']); +$packages = array(); +foreach (self::getInstalled() as $installed) { +$packages[] = array_keys($installed['versions']); +} + + +if (1 === \count($packages)) { +return $packages[0]; +} + +return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); } @@ -315,7 +310,13 @@ return array_keys(self::$installed['versions']); public static function isInstalled($packageName) { -return isset(self::$installed['versions'][$packageName]); +foreach (self::getInstalled() as $installed) { +if (isset($installed['versions'][$packageName])) { +return true; +} +} + +return false; } @@ -350,42 +351,50 @@ return $provided->matches($constraint); public static function getVersionRanges($packageName) { -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; } $ranges = array(); -if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { -$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; +if (isset($installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = $installed['versions'][$packageName]['pretty_version']; } -if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { -$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); +if (array_key_exists('aliases', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); } -if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { -$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); +if (array_key_exists('replaced', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); } -if (array_key_exists('provided', self::$installed['versions'][$packageName])) { -$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); +if (array_key_exists('provided', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); } return implode(' || ', $ranges); } +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + public static function getVersion($packageName) { -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; } -if (!isset(self::$installed['versions'][$packageName]['version'])) { +if (!isset($installed['versions'][$packageName]['version'])) { return null; } -return self::$installed['versions'][$packageName]['version']; +return $installed['versions'][$packageName]['version']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } @@ -394,15 +403,19 @@ return self::$installed['versions'][$packageName]['version']; public static function getPrettyVersion($packageName) { -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; } -if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { +if (!isset($installed['versions'][$packageName]['pretty_version'])) { return null; } -return self::$installed['versions'][$packageName]['pretty_version']; +return $installed['versions'][$packageName]['pretty_version']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } @@ -411,15 +424,19 @@ return self::$installed['versions'][$packageName]['pretty_version']; public static function getReference($packageName) { -if (!isset(self::$installed['versions'][$packageName])) { -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; } -if (!isset(self::$installed['versions'][$packageName]['reference'])) { +if (!isset($installed['versions'][$packageName]['reference'])) { return null; } -return self::$installed['versions'][$packageName]['reference']; +return $installed['versions'][$packageName]['reference']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } @@ -428,7 +445,9 @@ return self::$installed['versions'][$packageName]['reference']; public static function getRootPackage() { -return self::$installed['root']; +$installed = self::getInstalled(); + +return $installed[0]['root']; } @@ -463,5 +482,33 @@ return self::$installed; public static function reload($data) { self::$installed = $data; +self::$installedByVendor = array(); +} + + + + +private static function getInstalled() +{ +if (null === self::$canGetVendors) { +self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); +} + +$installed = array(); + +if (self::$canGetVendors) { + +foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { +if (isset(self::$installedByVendor[$vendorDir])) { +$installed[] = self::$installedByVendor[$vendorDir]; +} elseif (is_file($vendorDir.'/composer/installed.php')) { +$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; +} +} +} + +$installed[] = self::$installed; + +return $installed; } } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 1eef57c4a..da2dfa8f4 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -376,17 +376,6 @@ return array( 'OAuth2\\TokenType\\Bearer' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php', 'OAuth2\\TokenType\\Mac' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php', 'OAuth2\\TokenType\\TokenTypeInterface' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/TokenTypeInterface.php', - 'ParagonIE\\ConstantTime\\Base32' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32.php', - 'ParagonIE\\ConstantTime\\Base32Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32Hex.php', - 'ParagonIE\\ConstantTime\\Base64' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64.php', - 'ParagonIE\\ConstantTime\\Base64DotSlash' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64DotSlash.php', - 'ParagonIE\\ConstantTime\\Base64DotSlashOrdered' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php', - 'ParagonIE\\ConstantTime\\Base64UrlSafe' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64UrlSafe.php', - 'ParagonIE\\ConstantTime\\Binary' => $vendorDir . '/paragonie/constant_time_encoding/src/Binary.php', - 'ParagonIE\\ConstantTime\\EncoderInterface' => $vendorDir . '/paragonie/constant_time_encoding/src/EncoderInterface.php', - 'ParagonIE\\ConstantTime\\Encoding' => $vendorDir . '/paragonie/constant_time_encoding/src/Encoding.php', - 'ParagonIE\\ConstantTime\\Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Hex.php', - 'ParagonIE\\ConstantTime\\RFC4648' => $vendorDir . '/paragonie/constant_time_encoding/src/RFC4648.php', 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', @@ -395,9 +384,6 @@ return array( 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/DummyTest.php', - 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php', 'Ramsey\\Collection\\AbstractArray' => $vendorDir . '/ramsey/collection/src/AbstractArray.php', 'Ramsey\\Collection\\AbstractCollection' => $vendorDir . '/ramsey/collection/src/AbstractCollection.php', 'Ramsey\\Collection\\AbstractSet' => $vendorDir . '/ramsey/collection/src/AbstractSet.php', @@ -1146,6 +1132,7 @@ return array( 'Zotlabs\\Lib\\IConfig' => $baseDir . '/Zotlabs/Lib/IConfig.php', 'Zotlabs\\Lib\\Img_filesize' => $baseDir . '/Zotlabs/Lib/Img_filesize.php', 'Zotlabs\\Lib\\JSalmon' => $baseDir . '/Zotlabs/Lib/JSalmon.php', + 'Zotlabs\\Lib\\Keyutils' => $baseDir . '/Zotlabs/Lib/Keyutils.php', 'Zotlabs\\Lib\\LDSignatures' => $baseDir . '/Zotlabs/Lib/LDSignatures.php', 'Zotlabs\\Lib\\Libsync' => $baseDir . '/Zotlabs/Lib/Libsync.php', 'Zotlabs\\Lib\\Libzot' => $baseDir . '/Zotlabs/Lib/Libzot.php', @@ -1744,333 +1731,28 @@ return array( 'Zotlabs\\Zot\\IHandler' => $baseDir . '/Zotlabs/Zot/IHandler.php', 'Zotlabs\\Zot\\Receiver' => $baseDir . '/Zotlabs/Zot/Receiver.php', 'Zotlabs\\Zot\\ZotHandler' => $baseDir . '/Zotlabs/Zot/ZotHandler.php', - 'phpseclib3\\Common\\Functions\\Strings' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php', - 'phpseclib3\\Crypt\\AES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', - 'phpseclib3\\Crypt\\Blowfish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', - 'phpseclib3\\Crypt\\ChaCha20' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php', - 'phpseclib3\\Crypt\\Common\\AsymmetricKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php', - 'phpseclib3\\Crypt\\Common\\BlockCipher' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Signature\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php', - 'phpseclib3\\Crypt\\Common\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php', - 'phpseclib3\\Crypt\\Common\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php', - 'phpseclib3\\Crypt\\Common\\StreamCipher' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php', - 'phpseclib3\\Crypt\\Common\\SymmetricKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php', - 'phpseclib3\\Crypt\\Common\\Traits\\Fingerprint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php', - 'phpseclib3\\Crypt\\Common\\Traits\\PasswordProtected' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php', - 'phpseclib3\\Crypt\\DES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', - 'phpseclib3\\Crypt\\DH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH.php', - 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\DH\\Parameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php', - 'phpseclib3\\Crypt\\DH\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php', - 'phpseclib3\\Crypt\\DH\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php', - 'phpseclib3\\Crypt\\DSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\XML' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php', - 'phpseclib3\\Crypt\\DSA\\Parameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php', - 'phpseclib3\\Crypt\\DSA\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php', - 'phpseclib3\\Crypt\\DSA\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php', - 'phpseclib3\\Crypt\\EC' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Binary' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\KoblitzPrime' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Montgomery' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Prime' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\TwistedEdwards' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Curve25519' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Curve448' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Ed25519' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Ed448' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512t1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistb233' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistb409' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk163' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk233' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk283' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk409' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp192' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp224' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp256' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp384' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp521' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistt571' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime192v1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime192v2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime192v3' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime239v1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime239v2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime239v3' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime256v1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp112r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp112r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp128r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp128r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp160k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp160r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp160r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp192k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp192r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp224k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp224r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp256k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp256r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp384r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp521r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect113r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect113r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect131r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect131r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect163k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect163r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect163r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect193r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect193r2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect233k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect233r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect239k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect283k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect283r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect409k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect409r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect571k1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect571r1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\Common' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPrivate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPublic' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\XML' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\libsodium' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php', - 'phpseclib3\\Crypt\\EC\\Parameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php', - 'phpseclib3\\Crypt\\EC\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php', - 'phpseclib3\\Crypt\\EC\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php', - 'phpseclib3\\Crypt\\Hash' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', - 'phpseclib3\\Crypt\\PublicKeyLoader' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php', - 'phpseclib3\\Crypt\\RC2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', - 'phpseclib3\\Crypt\\RC4' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', - 'phpseclib3\\Crypt\\RSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\MSBLOB' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\OpenSSH' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS8' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PSS' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PuTTY' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\Raw' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\XML' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php', - 'phpseclib3\\Crypt\\RSA\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php', - 'phpseclib3\\Crypt\\RSA\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php', - 'phpseclib3\\Crypt\\Random' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', - 'phpseclib3\\Crypt\\Rijndael' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', - 'phpseclib3\\Crypt\\Salsa20' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php', - 'phpseclib3\\Crypt\\TripleDES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', - 'phpseclib3\\Crypt\\Twofish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', - 'phpseclib3\\Exception\\BadConfigurationException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php', - 'phpseclib3\\Exception\\BadDecryptionException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php', - 'phpseclib3\\Exception\\BadModeException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php', - 'phpseclib3\\Exception\\ConnectionClosedException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php', - 'phpseclib3\\Exception\\FileNotFoundException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php', - 'phpseclib3\\Exception\\InconsistentSetupException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php', - 'phpseclib3\\Exception\\InsufficientSetupException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php', - 'phpseclib3\\Exception\\NoKeyLoadedException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php', - 'phpseclib3\\Exception\\NoSupportedAlgorithmsException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php', - 'phpseclib3\\Exception\\UnableToConnectException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php', - 'phpseclib3\\Exception\\UnsupportedAlgorithmException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php', - 'phpseclib3\\Exception\\UnsupportedCurveException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php', - 'phpseclib3\\Exception\\UnsupportedFormatException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php', - 'phpseclib3\\Exception\\UnsupportedOperationException' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php', - 'phpseclib3\\File\\ANSI' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', - 'phpseclib3\\File\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', - 'phpseclib3\\File\\ASN1\\Element' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', - 'phpseclib3\\File\\ASN1\\Maps\\AccessDescription' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php', - 'phpseclib3\\File\\ASN1\\Maps\\AdministrationDomainName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php', - 'phpseclib3\\File\\ASN1\\Maps\\AlgorithmIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\AnotherName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php', - 'phpseclib3\\File\\ASN1\\Maps\\Attribute' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php', - 'phpseclib3\\File\\ASN1\\Maps\\AttributeType' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php', - 'phpseclib3\\File\\ASN1\\Maps\\AttributeTypeAndValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\AttributeValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\Attributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\AuthorityInfoAccessSyntax' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php', - 'phpseclib3\\File\\ASN1\\Maps\\AuthorityKeyIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\BaseDistance' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php', - 'phpseclib3\\File\\ASN1\\Maps\\BasicConstraints' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php', - 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttribute' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php', - 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\BuiltInStandardAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\CPSuri' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php', - 'phpseclib3\\File\\ASN1\\Maps\\CRLDistributionPoints' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php', - 'phpseclib3\\File\\ASN1\\Maps\\CRLNumber' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php', - 'phpseclib3\\File\\ASN1\\Maps\\CRLReason' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertPolicyId' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php', - 'phpseclib3\\File\\ASN1\\Maps\\Certificate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificateIssuer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificateList' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificatePolicies' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificateSerialNumber' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequest' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequestInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\Characteristic_two' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php', - 'phpseclib3\\File\\ASN1\\Maps\\CountryName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php', - 'phpseclib3\\File\\ASN1\\Maps\\Curve' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php', - 'phpseclib3\\File\\ASN1\\Maps\\DHParameter' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php', - 'phpseclib3\\File\\ASN1\\Maps\\DSAParams' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php', - 'phpseclib3\\File\\ASN1\\Maps\\DSAPrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\DSAPublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\DigestInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\DirectoryString' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php', - 'phpseclib3\\File\\ASN1\\Maps\\DisplayText' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php', - 'phpseclib3\\File\\ASN1\\Maps\\DistributionPoint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php', - 'phpseclib3\\File\\ASN1\\Maps\\DistributionPointName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php', - 'phpseclib3\\File\\ASN1\\Maps\\DssSigValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\ECParameters' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php', - 'phpseclib3\\File\\ASN1\\Maps\\ECPoint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php', - 'phpseclib3\\File\\ASN1\\Maps\\ECPrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\EDIPartyName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php', - 'phpseclib3\\File\\ASN1\\Maps\\EcdsaSigValue' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\EncryptedData' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php', - 'phpseclib3\\File\\ASN1\\Maps\\EncryptedPrivateKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\ExtKeyUsageSyntax' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php', - 'phpseclib3\\File\\ASN1\\Maps\\Extension' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php', - 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttribute' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php', - 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\Extensions' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php', - 'phpseclib3\\File\\ASN1\\Maps\\FieldElement' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php', - 'phpseclib3\\File\\ASN1\\Maps\\FieldID' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralNames' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtree' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtrees' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php', - 'phpseclib3\\File\\ASN1\\Maps\\HashAlgorithm' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php', - 'phpseclib3\\File\\ASN1\\Maps\\HoldInstructionCode' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php', - 'phpseclib3\\File\\ASN1\\Maps\\InvalidityDate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php', - 'phpseclib3\\File\\ASN1\\Maps\\IssuerAltName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php', - 'phpseclib3\\File\\ASN1\\Maps\\IssuingDistributionPoint' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php', - 'phpseclib3\\File\\ASN1\\Maps\\KeyIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\KeyPurposeId' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php', - 'phpseclib3\\File\\ASN1\\Maps\\KeyUsage' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php', - 'phpseclib3\\File\\ASN1\\Maps\\MaskGenAlgorithm' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php', - 'phpseclib3\\File\\ASN1\\Maps\\Name' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php', - 'phpseclib3\\File\\ASN1\\Maps\\NameConstraints' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php', - 'phpseclib3\\File\\ASN1\\Maps\\NetworkAddress' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php', - 'phpseclib3\\File\\ASN1\\Maps\\NoticeReference' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php', - 'phpseclib3\\File\\ASN1\\Maps\\NumericUserIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\ORAddress' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php', - 'phpseclib3\\File\\ASN1\\Maps\\OneAsymmetricKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\OrganizationName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php', - 'phpseclib3\\File\\ASN1\\Maps\\OrganizationalUnitNames' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php', - 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfos' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBEParameter' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBES2params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBKDF2params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBMAC1params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php', - 'phpseclib3\\File\\ASN1\\Maps\\PKCS9String' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php', - 'phpseclib3\\File\\ASN1\\Maps\\Pentanomial' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php', - 'phpseclib3\\File\\ASN1\\Maps\\PersonalName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyInformation' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyMappings' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierId' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\PostalAddress' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php', - 'phpseclib3\\File\\ASN1\\Maps\\Prime_p' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateDomainName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyUsagePeriod' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php', - 'phpseclib3\\File\\ASN1\\Maps\\PublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyAndChallenge' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php', - 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\RC2CBCParameter' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php', - 'phpseclib3\\File\\ASN1\\Maps\\RDNSequence' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php', - 'phpseclib3\\File\\ASN1\\Maps\\RSAPrivateKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\RSAPublicKey' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\RSASSA_PSS_params' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php', - 'phpseclib3\\File\\ASN1\\Maps\\ReasonFlags' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php', - 'phpseclib3\\File\\ASN1\\Maps\\RelativeDistinguishedName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php', - 'phpseclib3\\File\\ASN1\\Maps\\RevokedCertificate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php', - 'phpseclib3\\File\\ASN1\\Maps\\SignedPublicKeyAndChallenge' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php', - 'phpseclib3\\File\\ASN1\\Maps\\SpecifiedECDomain' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectAltName' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectDirectoryAttributes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectInfoAccessSyntax' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectPublicKeyInfo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\TBSCertList' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php', - 'phpseclib3\\File\\ASN1\\Maps\\TBSCertificate' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php', - 'phpseclib3\\File\\ASN1\\Maps\\TerminalIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\Time' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php', - 'phpseclib3\\File\\ASN1\\Maps\\Trinomial' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php', - 'phpseclib3\\File\\ASN1\\Maps\\UniqueIdentifier' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\UserNotice' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php', - 'phpseclib3\\File\\ASN1\\Maps\\Validity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php', - 'phpseclib3\\File\\ASN1\\Maps\\netscape_ca_policy_url' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php', - 'phpseclib3\\File\\ASN1\\Maps\\netscape_cert_type' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php', - 'phpseclib3\\File\\ASN1\\Maps\\netscape_comment' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php', - 'phpseclib3\\File\\X509' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/X509.php', - 'phpseclib3\\Math\\BigInteger' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\BuiltIn' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\DefaultEngine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\OpenSSL' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\Barrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\EvalBarrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\Engine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\GMP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\GMP\\DefaultEngine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\OpenSSL' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP32' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP64' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\DefaultEngine' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Montgomery' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\OpenSSL' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Barrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Classic' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\EvalBarrett' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Montgomery' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\MontgomeryMult' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\PowerOfTwo' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php', - 'phpseclib3\\Math\\BinaryField' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BinaryField.php', - 'phpseclib3\\Math\\BinaryField\\Integer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php', - 'phpseclib3\\Math\\Common\\FiniteField' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php', - 'phpseclib3\\Math\\Common\\FiniteField\\Integer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php', - 'phpseclib3\\Math\\PrimeField' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/PrimeField.php', - 'phpseclib3\\Math\\PrimeField\\Integer' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php', - 'phpseclib3\\Net\\SFTP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', - 'phpseclib3\\Net\\SFTP\\Stream' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', - 'phpseclib3\\Net\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', - 'phpseclib3\\System\\SSH\\Agent' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', - 'phpseclib3\\System\\SSH\\Agent\\Identity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', - 'phpseclib3\\System\\SSH\\Common\\Traits\\ReadBytes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php', + 'phpseclib\\Crypt\\AES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', + 'phpseclib\\Crypt\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php', + 'phpseclib\\Crypt\\Blowfish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', + 'phpseclib\\Crypt\\DES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', + 'phpseclib\\Crypt\\Hash' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', + 'phpseclib\\Crypt\\RC2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', + 'phpseclib\\Crypt\\RC4' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', + 'phpseclib\\Crypt\\RSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', + 'phpseclib\\Crypt\\Random' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', + 'phpseclib\\Crypt\\Rijndael' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', + 'phpseclib\\Crypt\\TripleDES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', + 'phpseclib\\Crypt\\Twofish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', + 'phpseclib\\File\\ANSI' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', + 'phpseclib\\File\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', + 'phpseclib\\File\\ASN1\\Element' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', + 'phpseclib\\File\\X509' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/X509.php', + 'phpseclib\\Math\\BigInteger' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', + 'phpseclib\\Net\\SCP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SCP.php', + 'phpseclib\\Net\\SFTP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', + 'phpseclib\\Net\\SFTP\\Stream' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', + 'phpseclib\\Net\\SSH1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH1.php', + 'phpseclib\\Net\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', + 'phpseclib\\System\\SSH\\Agent' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', + 'phpseclib\\System\\SSH\\Agent\\Identity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 973842971..b6a4c826f 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -6,7 +6,7 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - 'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), + 'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'Zotlabs\\' => array($baseDir . '/Zotlabs'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Sabre\\Xml\\' => array($vendorDir . '/sabre/xml/lib'), @@ -21,7 +21,6 @@ return array( 'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'), 'Ramsey\\Collection\\' => array($vendorDir . '/ramsey/collection/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), - 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), 'Michelf\\' => array($vendorDir . '/michelf/php-markdown/Michelf'), 'League\\HTMLToMarkdown\\' => array($vendorDir . '/league/html-to-markdown/src'), 'ID3Parser\\' => array($vendorDir . '/lukasreschke/id3parser/src'), diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 264e26beb..fbfac821c 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -25,7 +25,7 @@ class ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d require __DIR__ . '/platform_check.php'; spl_autoload_register(array('ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); spl_autoload_unregister(array('ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index eb0766ee9..5abdb7dce 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -23,7 +23,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d public static $prefixLengthsPsr4 = array ( 'p' => array ( - 'phpseclib3\\' => 11, + 'phpseclib\\' => 10, ), 'Z' => array ( @@ -50,7 +50,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'P' => array ( 'Psr\\Log\\' => 8, - 'ParagonIE\\ConstantTime\\' => 23, ), 'M' => array ( @@ -79,7 +78,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d ); public static $prefixDirsPsr4 = array ( - 'phpseclib3\\' => + 'phpseclib\\' => array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', ), @@ -139,10 +138,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d array ( 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', ), - 'ParagonIE\\ConstantTime\\' => - array ( - 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', - ), 'Michelf\\' => array ( 0 => __DIR__ . '/..' . '/michelf/php-markdown/Michelf', @@ -571,17 +566,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'OAuth2\\TokenType\\Bearer' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php', 'OAuth2\\TokenType\\Mac' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php', 'OAuth2\\TokenType\\TokenTypeInterface' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/TokenTypeInterface.php', - 'ParagonIE\\ConstantTime\\Base32' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32.php', - 'ParagonIE\\ConstantTime\\Base32Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32Hex.php', - 'ParagonIE\\ConstantTime\\Base64' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64.php', - 'ParagonIE\\ConstantTime\\Base64DotSlash' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64DotSlash.php', - 'ParagonIE\\ConstantTime\\Base64DotSlashOrdered' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php', - 'ParagonIE\\ConstantTime\\Base64UrlSafe' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64UrlSafe.php', - 'ParagonIE\\ConstantTime\\Binary' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Binary.php', - 'ParagonIE\\ConstantTime\\EncoderInterface' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/EncoderInterface.php', - 'ParagonIE\\ConstantTime\\Encoding' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Encoding.php', - 'ParagonIE\\ConstantTime\\Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Hex.php', - 'ParagonIE\\ConstantTime\\RFC4648' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/RFC4648.php', 'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php', @@ -590,9 +574,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/DummyTest.php', - 'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php', 'Ramsey\\Collection\\AbstractArray' => __DIR__ . '/..' . '/ramsey/collection/src/AbstractArray.php', 'Ramsey\\Collection\\AbstractCollection' => __DIR__ . '/..' . '/ramsey/collection/src/AbstractCollection.php', 'Ramsey\\Collection\\AbstractSet' => __DIR__ . '/..' . '/ramsey/collection/src/AbstractSet.php', @@ -1341,6 +1322,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Lib\\IConfig' => __DIR__ . '/../..' . '/Zotlabs/Lib/IConfig.php', 'Zotlabs\\Lib\\Img_filesize' => __DIR__ . '/../..' . '/Zotlabs/Lib/Img_filesize.php', 'Zotlabs\\Lib\\JSalmon' => __DIR__ . '/../..' . '/Zotlabs/Lib/JSalmon.php', + 'Zotlabs\\Lib\\Keyutils' => __DIR__ . '/../..' . '/Zotlabs/Lib/Keyutils.php', 'Zotlabs\\Lib\\LDSignatures' => __DIR__ . '/../..' . '/Zotlabs/Lib/LDSignatures.php', 'Zotlabs\\Lib\\Libsync' => __DIR__ . '/../..' . '/Zotlabs/Lib/Libsync.php', 'Zotlabs\\Lib\\Libzot' => __DIR__ . '/../..' . '/Zotlabs/Lib/Libzot.php', @@ -1939,335 +1921,30 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Zot\\IHandler' => __DIR__ . '/../..' . '/Zotlabs/Zot/IHandler.php', 'Zotlabs\\Zot\\Receiver' => __DIR__ . '/../..' . '/Zotlabs/Zot/Receiver.php', 'Zotlabs\\Zot\\ZotHandler' => __DIR__ . '/../..' . '/Zotlabs/Zot/ZotHandler.php', - 'phpseclib3\\Common\\Functions\\Strings' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php', - 'phpseclib3\\Crypt\\AES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', - 'phpseclib3\\Crypt\\Blowfish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', - 'phpseclib3\\Crypt\\ChaCha20' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php', - 'phpseclib3\\Crypt\\Common\\AsymmetricKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php', - 'phpseclib3\\Crypt\\Common\\BlockCipher' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\Common\\Formats\\Signature\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php', - 'phpseclib3\\Crypt\\Common\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php', - 'phpseclib3\\Crypt\\Common\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php', - 'phpseclib3\\Crypt\\Common\\StreamCipher' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php', - 'phpseclib3\\Crypt\\Common\\SymmetricKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php', - 'phpseclib3\\Crypt\\Common\\Traits\\Fingerprint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php', - 'phpseclib3\\Crypt\\Common\\Traits\\PasswordProtected' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php', - 'phpseclib3\\Crypt\\DES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', - 'phpseclib3\\Crypt\\DH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH.php', - 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\DH\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\DH\\Parameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php', - 'phpseclib3\\Crypt\\DH\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php', - 'phpseclib3\\Crypt\\DH\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php', - 'phpseclib3\\Crypt\\DSA' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Keys\\XML' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php', - 'phpseclib3\\Crypt\\DSA\\Formats\\Signature\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php', - 'phpseclib3\\Crypt\\DSA\\Parameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php', - 'phpseclib3\\Crypt\\DSA\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php', - 'phpseclib3\\Crypt\\DSA\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php', - 'phpseclib3\\Crypt\\EC' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Binary' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\KoblitzPrime' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Montgomery' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\Prime' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php', - 'phpseclib3\\Crypt\\EC\\BaseCurves\\TwistedEdwards' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Curve25519' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Curve448' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Ed25519' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php', - 'phpseclib3\\Crypt\\EC\\Curves\\Ed448' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP160t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP192t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP224t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP256t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP320t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP384t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\brainpoolP512t1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistb233' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistb409' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk163' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk233' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk283' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistk409' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp192' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp224' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp256' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp384' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistp521' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php', - 'phpseclib3\\Crypt\\EC\\Curves\\nistt571' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime192v1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime192v2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime192v3' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime239v1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime239v2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime239v3' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php', - 'phpseclib3\\Crypt\\EC\\Curves\\prime256v1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp112r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp112r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp128r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp128r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp160k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp160r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp160r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp192k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp192r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp224k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp224r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp256k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp256r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp384r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\secp521r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect113r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect113r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect131r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect131r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect163k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect163r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect163r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect193r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect193r2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect233k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect233r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect239k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect283k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect283r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect409k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect409r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect571k1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php', - 'phpseclib3\\Crypt\\EC\\Curves\\sect571r1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\Common' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPrivate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\MontgomeryPublic' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\XML' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Keys\\libsodium' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php', - 'phpseclib3\\Crypt\\EC\\Formats\\Signature\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php', - 'phpseclib3\\Crypt\\EC\\Parameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php', - 'phpseclib3\\Crypt\\EC\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php', - 'phpseclib3\\Crypt\\EC\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php', - 'phpseclib3\\Crypt\\Hash' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', - 'phpseclib3\\Crypt\\PublicKeyLoader' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php', - 'phpseclib3\\Crypt\\RC2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', - 'phpseclib3\\Crypt\\RC4' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', - 'phpseclib3\\Crypt\\RSA' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\MSBLOB' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\OpenSSH' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PKCS8' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PSS' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\PuTTY' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\Raw' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php', - 'phpseclib3\\Crypt\\RSA\\Formats\\Keys\\XML' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php', - 'phpseclib3\\Crypt\\RSA\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php', - 'phpseclib3\\Crypt\\RSA\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php', - 'phpseclib3\\Crypt\\Random' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', - 'phpseclib3\\Crypt\\Rijndael' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', - 'phpseclib3\\Crypt\\Salsa20' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php', - 'phpseclib3\\Crypt\\TripleDES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', - 'phpseclib3\\Crypt\\Twofish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', - 'phpseclib3\\Exception\\BadConfigurationException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php', - 'phpseclib3\\Exception\\BadDecryptionException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php', - 'phpseclib3\\Exception\\BadModeException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php', - 'phpseclib3\\Exception\\ConnectionClosedException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php', - 'phpseclib3\\Exception\\FileNotFoundException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php', - 'phpseclib3\\Exception\\InconsistentSetupException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php', - 'phpseclib3\\Exception\\InsufficientSetupException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php', - 'phpseclib3\\Exception\\NoKeyLoadedException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php', - 'phpseclib3\\Exception\\NoSupportedAlgorithmsException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php', - 'phpseclib3\\Exception\\UnableToConnectException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php', - 'phpseclib3\\Exception\\UnsupportedAlgorithmException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php', - 'phpseclib3\\Exception\\UnsupportedCurveException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php', - 'phpseclib3\\Exception\\UnsupportedFormatException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php', - 'phpseclib3\\Exception\\UnsupportedOperationException' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php', - 'phpseclib3\\File\\ANSI' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', - 'phpseclib3\\File\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', - 'phpseclib3\\File\\ASN1\\Element' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', - 'phpseclib3\\File\\ASN1\\Maps\\AccessDescription' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php', - 'phpseclib3\\File\\ASN1\\Maps\\AdministrationDomainName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php', - 'phpseclib3\\File\\ASN1\\Maps\\AlgorithmIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\AnotherName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php', - 'phpseclib3\\File\\ASN1\\Maps\\Attribute' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php', - 'phpseclib3\\File\\ASN1\\Maps\\AttributeType' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php', - 'phpseclib3\\File\\ASN1\\Maps\\AttributeTypeAndValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\AttributeValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\Attributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\AuthorityInfoAccessSyntax' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php', - 'phpseclib3\\File\\ASN1\\Maps\\AuthorityKeyIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\BaseDistance' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php', - 'phpseclib3\\File\\ASN1\\Maps\\BasicConstraints' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php', - 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttribute' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php', - 'phpseclib3\\File\\ASN1\\Maps\\BuiltInDomainDefinedAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\BuiltInStandardAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\CPSuri' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php', - 'phpseclib3\\File\\ASN1\\Maps\\CRLDistributionPoints' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php', - 'phpseclib3\\File\\ASN1\\Maps\\CRLNumber' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php', - 'phpseclib3\\File\\ASN1\\Maps\\CRLReason' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertPolicyId' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php', - 'phpseclib3\\File\\ASN1\\Maps\\Certificate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificateIssuer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificateList' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificatePolicies' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificateSerialNumber' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequest' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php', - 'phpseclib3\\File\\ASN1\\Maps\\CertificationRequestInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\Characteristic_two' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php', - 'phpseclib3\\File\\ASN1\\Maps\\CountryName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php', - 'phpseclib3\\File\\ASN1\\Maps\\Curve' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php', - 'phpseclib3\\File\\ASN1\\Maps\\DHParameter' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php', - 'phpseclib3\\File\\ASN1\\Maps\\DSAParams' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php', - 'phpseclib3\\File\\ASN1\\Maps\\DSAPrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\DSAPublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\DigestInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\DirectoryString' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php', - 'phpseclib3\\File\\ASN1\\Maps\\DisplayText' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php', - 'phpseclib3\\File\\ASN1\\Maps\\DistributionPoint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php', - 'phpseclib3\\File\\ASN1\\Maps\\DistributionPointName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php', - 'phpseclib3\\File\\ASN1\\Maps\\DssSigValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\ECParameters' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php', - 'phpseclib3\\File\\ASN1\\Maps\\ECPoint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php', - 'phpseclib3\\File\\ASN1\\Maps\\ECPrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\EDIPartyName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php', - 'phpseclib3\\File\\ASN1\\Maps\\EcdsaSigValue' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php', - 'phpseclib3\\File\\ASN1\\Maps\\EncryptedData' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php', - 'phpseclib3\\File\\ASN1\\Maps\\EncryptedPrivateKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\ExtKeyUsageSyntax' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php', - 'phpseclib3\\File\\ASN1\\Maps\\Extension' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php', - 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttribute' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php', - 'phpseclib3\\File\\ASN1\\Maps\\ExtensionAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\Extensions' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php', - 'phpseclib3\\File\\ASN1\\Maps\\FieldElement' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php', - 'phpseclib3\\File\\ASN1\\Maps\\FieldID' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralNames' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtree' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php', - 'phpseclib3\\File\\ASN1\\Maps\\GeneralSubtrees' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php', - 'phpseclib3\\File\\ASN1\\Maps\\HashAlgorithm' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php', - 'phpseclib3\\File\\ASN1\\Maps\\HoldInstructionCode' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php', - 'phpseclib3\\File\\ASN1\\Maps\\InvalidityDate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php', - 'phpseclib3\\File\\ASN1\\Maps\\IssuerAltName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php', - 'phpseclib3\\File\\ASN1\\Maps\\IssuingDistributionPoint' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php', - 'phpseclib3\\File\\ASN1\\Maps\\KeyIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\KeyPurposeId' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php', - 'phpseclib3\\File\\ASN1\\Maps\\KeyUsage' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php', - 'phpseclib3\\File\\ASN1\\Maps\\MaskGenAlgorithm' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php', - 'phpseclib3\\File\\ASN1\\Maps\\Name' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php', - 'phpseclib3\\File\\ASN1\\Maps\\NameConstraints' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php', - 'phpseclib3\\File\\ASN1\\Maps\\NetworkAddress' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php', - 'phpseclib3\\File\\ASN1\\Maps\\NoticeReference' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php', - 'phpseclib3\\File\\ASN1\\Maps\\NumericUserIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\ORAddress' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php', - 'phpseclib3\\File\\ASN1\\Maps\\OneAsymmetricKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\OrganizationName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php', - 'phpseclib3\\File\\ASN1\\Maps\\OrganizationalUnitNames' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php', - 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\OtherPrimeInfos' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBEParameter' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBES2params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBKDF2params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php', - 'phpseclib3\\File\\ASN1\\Maps\\PBMAC1params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php', - 'phpseclib3\\File\\ASN1\\Maps\\PKCS9String' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php', - 'phpseclib3\\File\\ASN1\\Maps\\Pentanomial' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php', - 'phpseclib3\\File\\ASN1\\Maps\\PersonalName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyInformation' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyMappings' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierId' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php', - 'phpseclib3\\File\\ASN1\\Maps\\PolicyQualifierInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\PostalAddress' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php', - 'phpseclib3\\File\\ASN1\\Maps\\Prime_p' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateDomainName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\PrivateKeyUsagePeriod' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php', - 'phpseclib3\\File\\ASN1\\Maps\\PublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyAndChallenge' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php', - 'phpseclib3\\File\\ASN1\\Maps\\PublicKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\RC2CBCParameter' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php', - 'phpseclib3\\File\\ASN1\\Maps\\RDNSequence' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php', - 'phpseclib3\\File\\ASN1\\Maps\\RSAPrivateKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\RSAPublicKey' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php', - 'phpseclib3\\File\\ASN1\\Maps\\RSASSA_PSS_params' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php', - 'phpseclib3\\File\\ASN1\\Maps\\ReasonFlags' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php', - 'phpseclib3\\File\\ASN1\\Maps\\RelativeDistinguishedName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php', - 'phpseclib3\\File\\ASN1\\Maps\\RevokedCertificate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php', - 'phpseclib3\\File\\ASN1\\Maps\\SignedPublicKeyAndChallenge' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php', - 'phpseclib3\\File\\ASN1\\Maps\\SpecifiedECDomain' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectAltName' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectDirectoryAttributes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectInfoAccessSyntax' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php', - 'phpseclib3\\File\\ASN1\\Maps\\SubjectPublicKeyInfo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php', - 'phpseclib3\\File\\ASN1\\Maps\\TBSCertList' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php', - 'phpseclib3\\File\\ASN1\\Maps\\TBSCertificate' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php', - 'phpseclib3\\File\\ASN1\\Maps\\TerminalIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\Time' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php', - 'phpseclib3\\File\\ASN1\\Maps\\Trinomial' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php', - 'phpseclib3\\File\\ASN1\\Maps\\UniqueIdentifier' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php', - 'phpseclib3\\File\\ASN1\\Maps\\UserNotice' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php', - 'phpseclib3\\File\\ASN1\\Maps\\Validity' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php', - 'phpseclib3\\File\\ASN1\\Maps\\netscape_ca_policy_url' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php', - 'phpseclib3\\File\\ASN1\\Maps\\netscape_cert_type' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php', - 'phpseclib3\\File\\ASN1\\Maps\\netscape_comment' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php', - 'phpseclib3\\File\\X509' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/X509.php', - 'phpseclib3\\Math\\BigInteger' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\BuiltIn' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\DefaultEngine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\OpenSSL' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\Barrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\BCMath\\Reductions\\EvalBarrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\Engine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\GMP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\GMP\\DefaultEngine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\OpenSSL' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP32' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP64' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\DefaultEngine' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Montgomery' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\OpenSSL' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Barrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Classic' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\EvalBarrett' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\Montgomery' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\MontgomeryMult' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php', - 'phpseclib3\\Math\\BigInteger\\Engines\\PHP\\Reductions\\PowerOfTwo' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php', - 'phpseclib3\\Math\\BinaryField' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BinaryField.php', - 'phpseclib3\\Math\\BinaryField\\Integer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php', - 'phpseclib3\\Math\\Common\\FiniteField' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php', - 'phpseclib3\\Math\\Common\\FiniteField\\Integer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php', - 'phpseclib3\\Math\\PrimeField' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/PrimeField.php', - 'phpseclib3\\Math\\PrimeField\\Integer' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php', - 'phpseclib3\\Net\\SFTP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', - 'phpseclib3\\Net\\SFTP\\Stream' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', - 'phpseclib3\\Net\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', - 'phpseclib3\\System\\SSH\\Agent' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', - 'phpseclib3\\System\\SSH\\Agent\\Identity' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', - 'phpseclib3\\System\\SSH\\Common\\Traits\\ReadBytes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php', + 'phpseclib\\Crypt\\AES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', + 'phpseclib\\Crypt\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php', + 'phpseclib\\Crypt\\Blowfish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', + 'phpseclib\\Crypt\\DES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', + 'phpseclib\\Crypt\\Hash' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', + 'phpseclib\\Crypt\\RC2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', + 'phpseclib\\Crypt\\RC4' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', + 'phpseclib\\Crypt\\RSA' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', + 'phpseclib\\Crypt\\Random' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', + 'phpseclib\\Crypt\\Rijndael' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', + 'phpseclib\\Crypt\\TripleDES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', + 'phpseclib\\Crypt\\Twofish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', + 'phpseclib\\File\\ANSI' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', + 'phpseclib\\File\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', + 'phpseclib\\File\\ASN1\\Element' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', + 'phpseclib\\File\\X509' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/X509.php', + 'phpseclib\\Math\\BigInteger' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', + 'phpseclib\\Net\\SCP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SCP.php', + 'phpseclib\\Net\\SFTP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', + 'phpseclib\\Net\\SFTP\\Stream' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', + 'phpseclib\\Net\\SSH1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SSH1.php', + 'phpseclib\\Net\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', + 'phpseclib\\System\\SSH\\Agent' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', + 'phpseclib\\System\\SSH\\Agent\\Identity' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 06d6df515..3fa4a6fac 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -506,129 +506,6 @@ ], "install-path": "../michelf/php-markdown" }, - { - "name": "paragonie/constant_time_encoding", - "version": "v2.4.0", - "version_normalized": "2.4.0.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", - "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", - "shasum": "" - }, - "require": { - "php": "^7|^8" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" - }, - "time": "2020-12-06T15:14:20+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base16", - "base32", - "base32_decode", - "base32_encode", - "base64", - "base64_decode", - "base64_encode", - "bin2hex", - "encoding", - "hex", - "hex2bin", - "rfc4648" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "source": "https://github.com/paragonie/constant_time_encoding" - }, - "install-path": "../paragonie/constant_time_encoding" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "version_normalized": "9.99.100.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "time": "2020-10-15T08:29:30+00:00", - "type": "library", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "install-path": "../paragonie/random_compat" - }, { "name": "pear/text_languagedetect", "version": "v1.0.1", @@ -682,27 +559,25 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.4", - "version_normalized": "3.0.4.0", + "version": "2.0.30", + "version_normalized": "2.0.30.0", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9" + "reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/845a2275e886ba9fb386c8f59cb383dd9c8963e9", - "reference": "845a2275e886ba9fb386c8f59cb383dd9c8963e9", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/136b9ca7eebef78be14abf90d65c5e57b6bc5d36", + "reference": "136b9ca7eebef78be14abf90d65c5e57b6bc5d36", "shasum": "" }, "require": { - "paragonie/constant_time_encoding": "^1|^2", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" + "php": ">=5.3.3" }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^5.7|^6.0|^9.4", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { @@ -711,7 +586,7 @@ "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." }, - "time": "2021-01-25T19:02:05+00:00", + "time": "2020-12-17T05:42:04+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -719,7 +594,7 @@ "phpseclib/bootstrap.php" ], "psr-4": { - "phpseclib3\\": "phpseclib/" + "phpseclib\\": "phpseclib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -776,7 +651,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.4" + "source": "https://github.com/phpseclib/phpseclib/tree/2.0.30" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index d8bea317c..9ddb06cc3 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,12 +1,12 @@ array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', + 'pretty_version' => 'dev-5.2RC', + 'version' => 'dev-5.2RC', 'aliases' => array ( ), - 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', + 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -92,24 +92,6 @@ ), 'reference' => 'c83178d49e372ca967d1a8c77ae4e051b3a3c75c', ), - 'paragonie/constant_time_encoding' => - array ( - 'pretty_version' => 'v2.4.0', - 'version' => '2.4.0.0', - 'aliases' => - array ( - ), - 'reference' => 'f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c', - ), - 'paragonie/random_compat' => - array ( - 'pretty_version' => 'v9.99.100', - 'version' => '9.99.100.0', - 'aliases' => - array ( - ), - 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', - ), 'pear/text_languagedetect' => array ( 'pretty_version' => 'v1.0.1', @@ -121,12 +103,12 @@ ), 'phpseclib/phpseclib' => array ( - 'pretty_version' => '3.0.4', - 'version' => '3.0.4.0', + 'pretty_version' => '2.0.30', + 'version' => '2.0.30.0', 'aliases' => array ( ), - 'reference' => '845a2275e886ba9fb386c8f59cb383dd9c8963e9', + 'reference' => '136b9ca7eebef78be14abf90d65c5e57b6bc5d36', ), 'psr/log' => array ( @@ -261,12 +243,12 @@ ), 'zotlabs/hubzilla' => array ( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', + 'pretty_version' => 'dev-5.2RC', + 'version' => 'dev-5.2RC', 'aliases' => array ( ), - 'reference' => '08c9152abdfa90da09931bdcc6e6c81ea243434c', + 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', ), ), ); diff --git a/vendor/paragonie/constant_time_encoding/.gitignore b/vendor/paragonie/constant_time_encoding/.gitignore deleted file mode 100644 index e0caea8fc..000000000 --- a/vendor/paragonie/constant_time_encoding/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.idea/ -vendor/ \ No newline at end of file diff --git a/vendor/paragonie/constant_time_encoding/.travis.yml b/vendor/paragonie/constant_time_encoding/.travis.yml deleted file mode 100644 index 117c114a1..000000000 --- a/vendor/paragonie/constant_time_encoding/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: php -sudo: false - -matrix: - fast_finish: true - include: - - php: "7.1" - - php: "7.2" - - php: "7.3" - - php: "7.4" - - php: "8.0" - - php: "nightly" - allow_failures: - - php: "nightly" - - php: "7.4" - - php: "8.0" - -install: - - composer self-update - - composer update - -script: - - vendor/bin/phpunit - - vendor/bin/psalm diff --git a/vendor/paragonie/constant_time_encoding/LICENSE.txt b/vendor/paragonie/constant_time_encoding/LICENSE.txt deleted file mode 100644 index f424f5ecc..000000000 --- a/vendor/paragonie/constant_time_encoding/LICENSE.txt +++ /dev/null @@ -1,48 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 - 2020 Paragon Initiative Enterprises - -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. - ------------------------------------------------------------------------------- -This library was based on the work of Steve "Sc00bz" Thomas. ------------------------------------------------------------------------------- - -The MIT License (MIT) - -Copyright (c) 2014 Steve Thomas - -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/vendor/paragonie/constant_time_encoding/README.md b/vendor/paragonie/constant_time_encoding/README.md deleted file mode 100644 index d7db2a2d0..000000000 --- a/vendor/paragonie/constant_time_encoding/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Constant-Time Encoding - -[![Build Status](https://travis-ci.org/paragonie/constant_time_encoding.svg?branch=master)](https://travis-ci.org/paragonie/constant_time_encoding) -[![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) -[![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) -[![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) -[![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding) - -Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding), -this library aims to offer character encoding functions that do not leak -information about what you are encoding/decoding via processor cache -misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html). - -Our fork offers the following enchancements: - -* `mbstring.func_overload` resistance -* Unit tests -* Composer- and Packagist-ready -* Base16 encoding -* Base32 encoding -* Uses `pack()` and `unpack()` instead of `chr()` and `ord()` - -## PHP Version Requirements - -Version 2 of this library should work on **PHP 7** or newer. For PHP 5 -support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x). - -If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`. - -## How to Install - -```sh -composer require paragonie/constant_time_encoding -``` - -## How to Use - -```php -use \ParagonIE\ConstantTime\Encoding; - -// possibly (if applicable): -// require 'vendor/autoload.php'; - -$data = random_bytes(32); -echo Encoding::base64Encode($data), "\n"; -echo Encoding::base32EncodeUpper($data), "\n"; -echo Encoding::base32Encode($data), "\n"; -echo Encoding::hexEncode($data), "\n"; -echo Encoding::hexEncodeUpper($data), "\n"; -``` - -Example output: - -``` -1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= -2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ==== -2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== -d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1 -D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1 -``` - -If you only need a particular variant, you can just reference the -required class like so: - -```php -use \ParagonIE\ConstantTime\Base64; -use \ParagonIE\ConstantTime\Base32; - -$data = random_bytes(32); -echo Base64::encode($data), "\n"; -echo Base32::encode($data), "\n"; -``` - -Example output: - -``` -1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= -2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== -``` - -## Support Contracts - -If your company uses this library in their products or services, you may be -interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). diff --git a/vendor/paragonie/constant_time_encoding/composer.json b/vendor/paragonie/constant_time_encoding/composer.json deleted file mode 100644 index 583fe366f..000000000 --- a/vendor/paragonie/constant_time_encoding/composer.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "paragonie/constant_time_encoding", - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base64", - "encoding", - "rfc4648", - "base32", - "base16", - "hex", - "bin2hex", - "hex2bin", - "base64_encode", - "base64_decode", - "base32_encode", - "base32_decode" - ], - "license": "MIT", - "type": "library", - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "support": { - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "email": "info@paragonie.com", - "source": "https://github.com/paragonie/constant_time_encoding" - }, - "require": { - "php": "^7|^8" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" - }, - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - } -} diff --git a/vendor/paragonie/constant_time_encoding/phpunit.xml.dist b/vendor/paragonie/constant_time_encoding/phpunit.xml.dist deleted file mode 100644 index 4d090343e..000000000 --- a/vendor/paragonie/constant_time_encoding/phpunit.xml.dist +++ /dev/null @@ -1,13 +0,0 @@ - - - - - ./src - - - - - ./tests - - - diff --git a/vendor/paragonie/constant_time_encoding/psalm.xml b/vendor/paragonie/constant_time_encoding/psalm.xml deleted file mode 100644 index 0a17264b0..000000000 --- a/vendor/paragonie/constant_time_encoding/psalm.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/vendor/paragonie/constant_time_encoding/src/Base32.php b/vendor/paragonie/constant_time_encoding/src/Base32.php deleted file mode 100644 index 7784bafbf..000000000 --- a/vendor/paragonie/constant_time_encoding/src/Base32.php +++ /dev/null @@ -1,471 +0,0 @@ - 96 && $src < 123) $ret += $src - 97 + 1; // -64 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96); - - // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 - $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 5-bit integers - * into 8-bit integers. - * - * Uppercase variant. - * - * @param int $src - * @return int - */ - protected static function decode5BitsUpper(int $src): int - { - $ret = -1; - - // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); - - // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 - $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode5Bits(int $src): string - { - $diff = 0x61; - - // if ($src > 25) $ret -= 72; - $diff -= ((25 - $src) >> 8) & 73; - - return \pack('C', $src + $diff); - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * Uppercase variant. - * - * @param int $src - * @return string - */ - protected static function encode5BitsUpper(int $src): string - { - $diff = 0x41; - - // if ($src > 25) $ret -= 40; - $diff -= ((25 - $src) >> 8) & 41; - - return \pack('C', $src + $diff); - } - - - /** - * Base32 decoding - * - * @param string $src - * @param bool $upper - * @param bool $strictPadding - * @return string - * @throws \TypeError - * @psalm-suppress RedundantCondition - */ - protected static function doDecode(string $src, bool $upper = false, bool $strictPadding = false): string - { - // We do this to reduce code duplication: - $method = $upper - ? 'decode5BitsUpper' - : 'decode5Bits'; - - // Remove padding - $srcLen = Binary::safeStrlen($src); - if ($srcLen === 0) { - return ''; - } - if ($strictPadding) { - if (($srcLen & 7) === 0) { - for ($j = 0; $j < 7; ++$j) { - if ($src[$srcLen - 1] === '=') { - $srcLen--; - } else { - break; - } - } - } - if (($srcLen & 7) === 1) { - throw new \RangeException( - 'Incorrect padding' - ); - } - } else { - $src = \rtrim($src, '='); - $srcLen = Binary::safeStrlen($src); - } - - $err = 0; - $dest = ''; - // Main loop (no padding): - for ($i = 0; $i + 8 <= $srcLen; $i += 8) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); - /** @var int $c0 */ - $c0 = static::$method($chunk[1]); - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - /** @var int $c5 */ - $c5 = static::$method($chunk[6]); - /** @var int $c6 */ - $c6 = static::$method($chunk[7]); - /** @var int $c7 */ - $c7 = static::$method($chunk[8]); - - $dest .= \pack( - 'CCCCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff, - (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff, - (($c6 << 5) | ($c7 ) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); - /** @var int $c0 */ - $c0 = static::$method($chunk[1]); - - if ($i + 6 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - /** @var int $c5 */ - $c5 = static::$method($chunk[6]); - /** @var int $c6 */ - $c6 = static::$method($chunk[7]); - - $dest .= \pack( - 'CCCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff, - (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; - } elseif ($i + 5 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - /** @var int $c5 */ - $c5 = static::$method($chunk[6]); - - $dest .= \pack( - 'CCCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff, - (($c4 << 7) | ($c5 << 2) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; - } elseif ($i + 4 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - - $dest .= \pack( - 'CCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; - } elseif ($i + 3 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - - $dest .= \pack( - 'CC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3) >> 8; - } elseif ($i + 2 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - - $dest .= \pack( - 'CC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2) >> 8; - } elseif ($i + 1 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - - $dest .= \pack( - 'C', - (($c0 << 3) | ($c1 >> 2) ) & 0xff - ); - $err |= ($c0 | $c1) >> 8; - } else { - $dest .= \pack( - 'C', - (($c0 << 3) ) & 0xff - ); - $err |= ($c0) >> 8; - } - } - /** @var bool $check */ - $check = ($err === 0); - if (!$check) { - throw new \RangeException( - 'Base32::doDecode() only expects characters in the correct base32 alphabet' - ); - } - return $dest; - } - - /** - * Base32 Encoding - * - * @param string $src - * @param bool $upper - * @param bool $pad - * @return string - * @throws \TypeError - */ - protected static function doEncode(string $src, bool $upper = false, $pad = true): string - { - // We do this to reduce code duplication: - $method = $upper - ? 'encode5BitsUpper' - : 'encode5Bits'; - - $dest = ''; - $srcLen = Binary::safeStrlen($src); - - // Main loop (no padding): - for ($i = 0; $i + 5 <= $srcLen; $i += 5) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5)); - $b0 = $chunk[1]; - $b1 = $chunk[2]; - $b2 = $chunk[3]; - $b3 = $chunk[4]; - $b4 = $chunk[5]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . - static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . - static::$method((($b3 >> 2) ) & 31) . - static::$method((($b3 << 3) | ($b4 >> 5)) & 31) . - static::$method( $b4 & 31); - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); - $b0 = $chunk[1]; - if ($i + 3 < $srcLen) { - $b1 = $chunk[2]; - $b2 = $chunk[3]; - $b3 = $chunk[4]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . - static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . - static::$method((($b3 >> 2) ) & 31) . - static::$method((($b3 << 3) ) & 31); - if ($pad) { - $dest .= '='; - } - } elseif ($i + 2 < $srcLen) { - $b1 = $chunk[2]; - $b2 = $chunk[3]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . - static::$method((($b2 << 1) ) & 31); - if ($pad) { - $dest .= '==='; - } - } elseif ($i + 1 < $srcLen) { - $b1 = $chunk[2]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) ) & 31); - if ($pad) { - $dest .= '===='; - } - } else { - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method( ($b0 << 2) & 31); - if ($pad) { - $dest .= '======'; - } - } - } - return $dest; - } -} diff --git a/vendor/paragonie/constant_time_encoding/src/Base32Hex.php b/vendor/paragonie/constant_time_encoding/src/Base32Hex.php deleted file mode 100644 index 68fdad52c..000000000 --- a/vendor/paragonie/constant_time_encoding/src/Base32Hex.php +++ /dev/null @@ -1,111 +0,0 @@ - 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); - - // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 - $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 5-bit integers - * into 8-bit integers. - * - * @param int $src - * @return int - */ - protected static function decode5BitsUpper(int $src): int - { - $ret = -1; - - // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); - - // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 - $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode5Bits(int $src): string - { - $src += 0x30; - - // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 - $src += ((0x39 - $src) >> 8) & 39; - - return \pack('C', $src); - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * Uppercase variant. - * - * @param int $src - * @return string - */ - protected static function encode5BitsUpper(int $src): string - { - $src += 0x30; - - // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 - $src += ((0x39 - $src) >> 8) & 7; - - return \pack('C', $src); - } -} \ No newline at end of file diff --git a/vendor/paragonie/constant_time_encoding/src/Base64.php b/vendor/paragonie/constant_time_encoding/src/Base64.php deleted file mode 100644 index 4739e4895..000000000 --- a/vendor/paragonie/constant_time_encoding/src/Base64.php +++ /dev/null @@ -1,271 +0,0 @@ - $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3)); - $b0 = $chunk[1]; - $b1 = $chunk[2]; - $b2 = $chunk[3]; - - $dest .= - static::encode6Bits( $b0 >> 2 ) . - static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . - static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . - static::encode6Bits( $b2 & 63); - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); - $b0 = $chunk[1]; - if ($i + 1 < $srcLen) { - $b1 = $chunk[2]; - $dest .= - static::encode6Bits($b0 >> 2) . - static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . - static::encode6Bits(($b1 << 2) & 63); - if ($pad) { - $dest .= '='; - } - } else { - $dest .= - static::encode6Bits( $b0 >> 2) . - static::encode6Bits(($b0 << 4) & 63); - if ($pad) { - $dest .= '=='; - } - } - } - return $dest; - } - - /** - * decode from base64 into binary - * - * Base64 character set "./[A-Z][a-z][0-9]" - * - * @param string $encodedString - * @param bool $strictPadding - * @return string - * @throws \RangeException - * @throws \TypeError - * @psalm-suppress RedundantCondition - */ - public static function decode(string $encodedString, bool $strictPadding = false): string - { - // Remove padding - $srcLen = Binary::safeStrlen($encodedString); - if ($srcLen === 0) { - return ''; - } - - if ($strictPadding) { - if (($srcLen & 3) === 0) { - if ($encodedString[$srcLen - 1] === '=') { - $srcLen--; - if ($encodedString[$srcLen - 1] === '=') { - $srcLen--; - } - } - } - if (($srcLen & 3) === 1) { - throw new \RangeException( - 'Incorrect padding' - ); - } - if ($encodedString[$srcLen - 1] === '=') { - throw new \RangeException( - 'Incorrect padding' - ); - } - } else { - $encodedString = \rtrim($encodedString, '='); - $srcLen = Binary::safeStrlen($encodedString); - } - - $err = 0; - $dest = ''; - // Main loop (no padding): - for ($i = 0; $i + 4 <= $srcLen; $i += 4) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, 4)); - $c0 = static::decode6Bits($chunk[1]); - $c1 = static::decode6Bits($chunk[2]); - $c2 = static::decode6Bits($chunk[3]); - $c3 = static::decode6Bits($chunk[4]); - - $dest .= \pack( - 'CCC', - ((($c0 << 2) | ($c1 >> 4)) & 0xff), - ((($c1 << 4) | ($c2 >> 2)) & 0xff), - ((($c2 << 6) | $c3 ) & 0xff) - ); - $err |= ($c0 | $c1 | $c2 | $c3) >> 8; - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i)); - $c0 = static::decode6Bits($chunk[1]); - - if ($i + 2 < $srcLen) { - $c1 = static::decode6Bits($chunk[2]); - $c2 = static::decode6Bits($chunk[3]); - $dest .= \pack( - 'CC', - ((($c0 << 2) | ($c1 >> 4)) & 0xff), - ((($c1 << 4) | ($c2 >> 2)) & 0xff) - ); - $err |= ($c0 | $c1 | $c2) >> 8; - } elseif ($i + 1 < $srcLen) { - $c1 = static::decode6Bits($chunk[2]); - $dest .= \pack( - 'C', - ((($c0 << 2) | ($c1 >> 4)) & 0xff) - ); - $err |= ($c0 | $c1) >> 8; - } elseif ($i < $srcLen && $strictPadding) { - $err |= 1; - } - } - /** @var bool $check */ - $check = ($err === 0); - if (!$check) { - throw new \RangeException( - 'Base64::decode() only expects characters in the correct base64 alphabet' - ); - } - return $dest; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 6-bit integers - * into 8-bit integers. - * - * Base64 character set: - * [A-Z] [a-z] [0-9] + / - * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f - * - * @param int $src - * @return int - */ - protected static function decode6Bits(int $src): int - { - $ret = -1; - - // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); - - // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); - - // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); - - // if ($src == 0x2b) $ret += 62 + 1; - $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; - - // if ($src == 0x2f) ret += 63 + 1; - $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $diff = 0x41; - - // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 - $diff += ((25 - $src) >> 8) & 6; - - // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 - $diff -= ((51 - $src) >> 8) & 75; - - // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 - $diff -= ((61 - $src) >> 8) & 15; - - // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 - $diff += ((62 - $src) >> 8) & 3; - - return \pack('C', $src + $diff); - } -} diff --git a/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php b/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php deleted file mode 100644 index 8ad2e2bf1..000000000 --- a/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php +++ /dev/null @@ -1,88 +0,0 @@ - 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 - $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45); - - // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62); - - // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68); - - // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $src += 0x2e; - - // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 - $src += ((0x2f - $src) >> 8) & 17; - - // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 - $src += ((0x5a - $src) >> 8) & 6; - - // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 - $src -= ((0x7a - $src) >> 8) & 75; - - return \pack('C', $src); - } -} diff --git a/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php deleted file mode 100644 index dd1459e85..000000000 --- a/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php +++ /dev/null @@ -1,82 +0,0 @@ - 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 - $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45); - - // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52); - - // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $src += 0x2e; - - // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 - $src += ((0x39 - $src) >> 8) & 7; - - // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 - $src += ((0x5a - $src) >> 8) & 6; - - return \pack('C', $src); - } -} diff --git a/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php deleted file mode 100644 index 1a4107527..000000000 --- a/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php +++ /dev/null @@ -1,95 +0,0 @@ - 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); - - // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); - - // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); - - // if ($src == 0x2c) $ret += 62 + 1; - $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; - - // if ($src == 0x5f) ret += 63 + 1; - $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $diff = 0x41; - - // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 - $diff += ((25 - $src) >> 8) & 6; - - // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 - $diff -= ((51 - $src) >> 8) & 75; - - // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 - $diff -= ((61 - $src) >> 8) & 13; - - // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 - $diff += ((62 - $src) >> 8) & 49; - - return \pack('C', $src + $diff); - } -} diff --git a/vendor/paragonie/constant_time_encoding/src/Binary.php b/vendor/paragonie/constant_time_encoding/src/Binary.php deleted file mode 100644 index 38dbc4e66..000000000 --- a/vendor/paragonie/constant_time_encoding/src/Binary.php +++ /dev/null @@ -1,85 +0,0 @@ - $chunk */ - $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 1)); - /** @var int $c */ - $c = $chunk[1] & 0xf; - /** @var int $b */ - $b = $chunk[1] >> 4; - - $hex .= pack( - 'CC', - (87 + $b + ((($b - 10) >> 8) & ~38)), - (87 + $c + ((($c - 10) >> 8) & ~38)) - ); - } - return $hex; - } - - /** - * Convert a binary string into a hexadecimal string without cache-timing - * leaks, returning uppercase letters (as per RFC 4648) - * - * @param string $binString (raw binary) - * @return string - * @throws \TypeError - */ - public static function encodeUpper(string $binString): string - { - /** @var string $hex */ - $hex = ''; - /** @var int $len */ - $len = Binary::safeStrlen($binString); - - for ($i = 0; $i < $len; ++$i) { - /** @var array $chunk */ - $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 2)); - /** @var int $c */ - $c = $chunk[1] & 0xf; - /** @var int $b */ - $b = $chunk[1] >> 4; - - $hex .= pack( - 'CC', - (55 + $b + ((($b - 10) >> 8) & ~6)), - (55 + $c + ((($c - 10) >> 8) & ~6)) - ); - } - return $hex; - } - - /** - * Convert a hexadecimal string into a binary string without cache-timing - * leaks - * - * @param string $encodedString - * @param bool $strictPadding - * @return string (raw binary) - * @throws \RangeException - */ - public static function decode(string $encodedString, bool $strictPadding = false): string - { - /** @var int $hex_pos */ - $hex_pos = 0; - /** @var string $bin */ - $bin = ''; - /** @var int $c_acc */ - $c_acc = 0; - /** @var int $hex_len */ - $hex_len = Binary::safeStrlen($encodedString); - /** @var int $state */ - $state = 0; - if (($hex_len & 1) !== 0) { - if ($strictPadding) { - throw new \RangeException( - 'Expected an even number of hexadecimal characters' - ); - } else { - $encodedString = '0' . $encodedString; - ++$hex_len; - } - } - - /** @var array $chunk */ - $chunk = \unpack('C*', $encodedString); - while ($hex_pos < $hex_len) { - ++$hex_pos; - /** @var int $c */ - $c = $chunk[$hex_pos]; - /** @var int $c_num */ - $c_num = $c ^ 48; - /** @var int $c_num0 */ - $c_num0 = ($c_num - 10) >> 8; - /** @var int $c_alpha */ - $c_alpha = ($c & ~32) - 55; - /** @var int $c_alpha0 */ - $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; - - if (($c_num0 | $c_alpha0) === 0) { - throw new \RangeException( - 'Expected hexadecimal character' - ); - } - /** @var int $c_val */ - $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); - if ($state === 0) { - $c_acc = $c_val * 16; - } else { - $bin .= \pack('C', $c_acc | $c_val); - } - $state ^= 1; - } - return $bin; - } -} diff --git a/vendor/paragonie/constant_time_encoding/src/RFC4648.php b/vendor/paragonie/constant_time_encoding/src/RFC4648.php deleted file mode 100644 index 492cad00e..000000000 --- a/vendor/paragonie/constant_time_encoding/src/RFC4648.php +++ /dev/null @@ -1,175 +0,0 @@ - "Zm9v" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base64Encode(string $str): string - { - return Base64::encode($str); - } - - /** - * RFC 4648 Base64 decoding - * - * "Zm9v" -> "foo" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base64Decode(string $str): string - { - return Base64::decode($str, true); - } - - /** - * RFC 4648 Base64 (URL Safe) encoding - * - * "foo" -> "Zm9v" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base64UrlSafeEncode(string $str): string - { - return Base64UrlSafe::encode($str); - } - - /** - * RFC 4648 Base64 (URL Safe) decoding - * - * "Zm9v" -> "foo" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base64UrlSafeDecode(string $str): string - { - return Base64UrlSafe::decode($str, true); - } - - /** - * RFC 4648 Base32 encoding - * - * "foo" -> "MZXW6===" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base32Encode(string $str): string - { - return Base32::encodeUpper($str); - } - - /** - * RFC 4648 Base32 encoding - * - * "MZXW6===" -> "foo" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base32Decode(string $str): string - { - return Base32::decodeUpper($str, true); - } - - /** - * RFC 4648 Base32-Hex encoding - * - * "foo" -> "CPNMU===" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base32HexEncode(string $str): string - { - return Base32::encodeUpper($str); - } - - /** - * RFC 4648 Base32-Hex decoding - * - * "CPNMU===" -> "foo" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base32HexDecode(string $str): string - { - return Base32::decodeUpper($str, true); - } - - /** - * RFC 4648 Base16 decoding - * - * "foo" -> "666F6F" - * - * @param string $str - * @return string - * @throws \TypeError - */ - public static function base16Encode(string $str): string - { - return Hex::encodeUpper($str); - } - - /** - * RFC 4648 Base16 decoding - * - * "666F6F" -> "foo" - * - * @param string $str - * @return string - */ - public static function base16Decode(string $str): string - { - return Hex::decode($str, true); - } -} \ No newline at end of file diff --git a/vendor/paragonie/random_compat/LICENSE b/vendor/paragonie/random_compat/LICENSE deleted file mode 100644 index 45c7017df..000000000 --- a/vendor/paragonie/random_compat/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Paragon Initiative Enterprises - -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/vendor/paragonie/random_compat/build-phar.sh b/vendor/paragonie/random_compat/build-phar.sh deleted file mode 100755 index b4a5ba31c..000000000 --- a/vendor/paragonie/random_compat/build-phar.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) - -php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/vendor/paragonie/random_compat/composer.json b/vendor/paragonie/random_compat/composer.json deleted file mode 100644 index f2b9c4e51..000000000 --- a/vendor/paragonie/random_compat/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "paragonie/random_compat", - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "random", - "polyfill", - "pseudorandom" - ], - "license": "MIT", - "type": "library", - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "support": { - "issues": "https://github.com/paragonie/random_compat/issues", - "email": "info@paragonie.com", - "source": "https://github.com/paragonie/random_compat" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "vimeo/psalm": "^1", - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - } -} diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey deleted file mode 100644 index eb50ebfcd..000000000 --- a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm -pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p -+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc ------END PUBLIC KEY----- diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc deleted file mode 100644 index 6a1d7f300..000000000 --- a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.22 (MingW32) - -iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip -QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg -1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW -NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA -NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV -JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= -=B6+8 ------END PGP SIGNATURE----- diff --git a/vendor/paragonie/random_compat/lib/random.php b/vendor/paragonie/random_compat/lib/random.php deleted file mode 100644 index c7731a56f..000000000 --- a/vendor/paragonie/random_compat/lib/random.php +++ /dev/null @@ -1,32 +0,0 @@ -buildFromDirectory(dirname(__DIR__).'/lib'); -rename( - dirname(__DIR__).'/lib/index.php', - dirname(__DIR__).'/lib/random.php' -); - -/** - * If we pass an (optional) path to a private key as a second argument, we will - * sign the Phar with OpenSSL. - * - * If you leave this out, it will produce an unsigned .phar! - */ -if ($argc > 1) { - if (!@is_readable($argv[1])) { - echo 'Could not read the private key file:', $argv[1], "\n"; - exit(255); - } - $pkeyFile = file_get_contents($argv[1]); - - $private = openssl_get_privatekey($pkeyFile); - if ($private !== false) { - $pkey = ''; - openssl_pkey_export($private, $pkey); - $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); - - /** - * Save the corresponding public key to the file - */ - if (!@is_readable($dist.'/random_compat.phar.pubkey')) { - $details = openssl_pkey_get_details($private); - file_put_contents( - $dist.'/random_compat.phar.pubkey', - $details['key'] - ); - } - } else { - echo 'An error occurred reading the private key from OpenSSL.', "\n"; - exit(255); - } -} diff --git a/vendor/paragonie/random_compat/psalm-autoload.php b/vendor/paragonie/random_compat/psalm-autoload.php deleted file mode 100644 index d71d1b818..000000000 --- a/vendor/paragonie/random_compat/psalm-autoload.php +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/vendor/phpseclib/phpseclib/.github/FUNDING.yml b/vendor/phpseclib/phpseclib/.github/FUNDING.yml deleted file mode 100644 index dc4ccd96e..000000000 --- a/vendor/phpseclib/phpseclib/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: terrafrost -patreon: phpseclib -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: "packagist/phpseclib/phpseclib" -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/vendor/phpseclib/phpseclib/README.md b/vendor/phpseclib/phpseclib/README.md index 7df111bf5..099486dc9 100644 --- a/vendor/phpseclib/phpseclib/README.md +++ b/vendor/phpseclib/phpseclib/README.md @@ -1,6 +1,6 @@ # phpseclib - PHP Secure Communications Library -[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=3.0)](https://travis-ci.com/phpseclib/phpseclib) +[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.com/phpseclib/phpseclib) ## Supporting phpseclib @@ -19,7 +19,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / ## Documentation * [Documentation / Manual](https://phpseclib.com/) -* [API Documentation](https://api.phpseclib.com/3.0/) (generated by Doctum) +* [API Documentation](https://api.phpseclib.com/2.0/) (generated by Doctum) ## Branches diff --git a/vendor/phpseclib/phpseclib/composer.json b/vendor/phpseclib/phpseclib/composer.json index 34dc9993d..08b9c7c91 100644 --- a/vendor/phpseclib/phpseclib/composer.json +++ b/vendor/phpseclib/phpseclib/composer.json @@ -51,13 +51,11 @@ } ], "require": { - "paragonie/constant_time_encoding": "^1|^2", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" + "php": ">=5.3.3" }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^5.7|^6.0|^9.4", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { @@ -71,7 +69,7 @@ "phpseclib/bootstrap.php" ], "psr-4": { - "phpseclib3\\": "phpseclib/" + "phpseclib\\": "phpseclib/" } } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php b/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php deleted file mode 100644 index 666fce59f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php +++ /dev/null @@ -1,387 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Common\Functions; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\Common\FiniteField; - -/** - * Common String Functions - * - * @package Functions\Strings - * @author Jim Wigginton - */ -abstract class Strings -{ - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @access public - * @return string - */ - public static function shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } - - /** - * String Pop - * - * Inspired by array_pop - * - * @param string $string - * @param int $index - * @access public - * @return string - */ - public static function pop(&$string, $index = 1) - { - $substr = substr($string, -$index); - $string = substr($string, 0, -$index); - return $substr; - } - - /** - * Parse SSH2-style string - * - * Returns either an array or a boolean if $data is malformed. - * - * Valid characters for $format are as follows: - * - * C = byte - * b = boolean (true/false) - * N = uint32 - * s = string - * i = mpint - * L = name-list - * - * uint64 is not supported. - * - * @param string $format - * @param string $data - * @return mixed - */ - public static function unpackSSH2($format, &$data) - { - $format = self::formatPack($format); - $result = []; - for ($i = 0; $i < strlen($format); $i++) { - switch ($format[$i]) { - case 'C': - case 'b': - if (!strlen($data)) { - throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); - } - break; - case 'N': - case 'i': - case 's': - case 'L': - if (strlen($data) < 4) { - throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); - } - break; - default: - throw new \InvalidArgumentException('$format contains an invalid character'); - } - switch ($format[$i]) { - case 'C': - $result[] = ord(self::shift($data)); - continue 2; - case 'b': - $result[] = ord(self::shift($data)) != 0; - continue 2; - case 'N': - list(, $temp) = unpack('N', self::shift($data, 4)); - $result[] = $temp; - continue 2; - } - list(, $length) = unpack('N', self::shift($data, 4)); - if (strlen($data) < $length) { - throw new \LengthException("$length bytes needed; " . strlen($data) . ' bytes available'); - } - $temp = self::shift($data, $length); - switch ($format[$i]) { - case 'i': - $result[] = new BigInteger($temp, -256); - break; - case 's': - $result[] = $temp; - break; - case 'L': - $result[] = explode(',', $temp); - } - } - - return $result; - } - - /** - * Create SSH2-style string - * - * @param string[] ...$elements - * @access public - * @return mixed - */ - public static function packSSH2(...$elements) - { - $format = self::formatPack($elements[0]); - array_shift($elements); - if (strlen($format) != count($elements)) { - throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); - } - $result = ''; - for ($i = 0; $i < strlen($format); $i++) { - $element = $elements[$i]; - switch ($format[$i]) { - case 'C': - if (!is_int($element)) { - throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); - } - $result.= pack('C', $element); - break; - case 'b': - if (!is_bool($element)) { - throw new \InvalidArgumentException('A boolean parameter was expected.'); - } - $result.= $element ? "\1" : "\0"; - break; - case 'N': - if (is_float($element)) { - $element = (int) $element; - } - if (!is_int($element)) { - throw new \InvalidArgumentException('An integer was expected.'); - } - $result.= pack('N', $element); - break; - case 's': - if (!self::is_stringable($element)) { - throw new \InvalidArgumentException('A string was expected.'); - } - $result.= pack('Na*', strlen($element), $element); - break; - case 'i': - if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) { - throw new \InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.'); - } - $element = $element->toBytes(true); - $result.= pack('Na*', strlen($element), $element); - break; - case 'L': - if (!is_array($element)) { - throw new \InvalidArgumentException('An array was expected.'); - } - $element = implode(',', $element); - $result.= pack('Na*', strlen($element), $element); - break; - default: - throw new \InvalidArgumentException('$format contains an invalid character'); - } - } - return $result; - } - - /** - * Expand a pack string - * - * Converts C5 to CCCCC, for example. - * - * @access private - * @param string $format - * @return string - */ - private static function formatPack($format) - { - $parts = preg_split('#(\d+)#', $format, -1, PREG_SPLIT_DELIM_CAPTURE); - $format = ''; - for ($i = 1; $i < count($parts); $i+=2) { - $format.= substr($parts[$i - 1], 0, -1) . str_repeat(substr($parts[$i - 1], -1), $parts[$i]); - } - $format.= $parts[$i - 1]; - - return $format; - } - - /** - * Convert binary data into bits - * - * bin2hex / hex2bin refer to base-256 encoded data as binary, whilst - * decbin / bindec refer to base-2 encoded data as binary. For the purposes - * of this function, bin refers to base-256 encoded data whilst bits refers - * to base-2 encoded data - * - * @access public - * @param string $x - * @return string - */ - public static function bits2bin($x) - { - /* - // the pure-PHP approach is faster than the GMP approach - if (function_exists('gmp_export')) { - return strlen($x) ? gmp_export(gmp_init($x, 2)) : gmp_init(0); - } - */ - - if (preg_match('#[^01]#', $x)) { - throw new \RuntimeException('The only valid characters are 0 and 1'); - } - - if (!defined('PHP_INT_MIN')) { - define('PHP_INT_MIN', ~PHP_INT_MAX); - } - - $length = strlen($x); - if (!$length) { - return ''; - } - $block_size = PHP_INT_SIZE << 3; - $pad = $block_size - ($length % $block_size); - if ($pad != $block_size) { - $x = str_repeat('0', $pad) . $x; - } - - $parts = str_split($x, $block_size); - $str = ''; - foreach ($parts as $part) { - $xor = $part[0] == '1' ? PHP_INT_MIN : 0; - $part[0] = '0'; - $str.= pack( - PHP_INT_SIZE == 4 ? 'N' : 'J', - $xor ^ eval('return 0b' . $part . ';') - ); - } - return ltrim($str, "\0"); - } - - /** - * Convert bits to binary data - * - * @access public - * @param string $x - * @return string - */ - public static function bin2bits($x) - { - /* - // the pure-PHP approach is slower than the GMP approach BUT - // i want to the pure-PHP version to be easily unit tested as well - if (function_exists('gmp_import')) { - return gmp_strval(gmp_import($x), 2); - } - */ - - $len = strlen($x); - $mod = $len % PHP_INT_SIZE; - if ($mod) { - $x = str_pad($x, $len + PHP_INT_SIZE - $mod, "\0", STR_PAD_LEFT); - } - - $bits = ''; - if (PHP_INT_SIZE == 4) { - $digits = unpack('N*', $x); - foreach ($digits as $digit) { - $bits.= sprintf('%032b', $digit); - } - } else { - $digits = unpack('J*', $x); - foreach ($digits as $digit) { - $bits.= sprintf('%064b', $digit); - } - } - - return ltrim($bits, '0'); - } - - /** - * Switch Endianness Bit Order - * - * @access public - * @param string $x - * @return string - */ - public static function switchEndianness($x) - { - $r = ''; - // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits - for ($i = strlen($x) - 1; $i >= 0; $i--) { - $b = ord($x[$i]); - $p1 = ($b * 0x0802) & 0x22110; - $p2 = ($b * 0x8020) & 0x88440; - $r.= chr( - (($p1 | $p2) * 0x10101) >> 16 - ); - } - return $r; - } - - /** - * Increment the current string - * - * @param string $var - * @return string - * @access public - */ - public static function increment_str(&$var) - { - for ($i = 4; $i <= strlen($var); $i+= 4) { - $temp = substr($var, -$i, 4); - switch ($temp) { - case "\xFF\xFF\xFF\xFF": - $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); - break; - case "\x7F\xFF\xFF\xFF": - $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); - return $var; - default: - $temp = unpack('Nnum', $temp); - $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); - return $var; - } - } - - $remainder = strlen($var) % 4; - - if ($remainder == 0) { - return $var; - } - - $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); - $temp = substr(pack('N', $temp['num'] + 1), -$remainder); - $var = substr_replace($var, $temp, 0, $remainder); - - return $var; - } - - /** - * Find whether the type of a variable is string (or could be converted to one) - * - * @param string|object $var - * @return boolean - * @access public - */ - public static function is_stringable($var) - { - return is_string($var) || (is_object($var) && method_exists($var, '__toString')); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php index 23ea6e146..7d8cb8b03 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php @@ -16,7 +16,7 @@ * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()} * is called, again, at which point, it'll be recalculated. * - * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't + * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't * make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function, * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one). * @@ -25,7 +25,7 @@ * setKey('abcdefghijklmnop'); * @@ -47,7 +47,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of AES. @@ -61,37 +61,35 @@ class AES extends Rijndael /** * Dummy function * - * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. + * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. * - * @see \phpseclib3\Crypt\Rijndael::setBlockLength() + * @see \phpseclib\Crypt\Rijndael::setBlockLength() * @access public * @param int $length - * @throws \BadMethodCallException anytime it's called */ - public function setBlockLength($length) + function setBlockLength($length) { - throw new \BadMethodCallException('The block length cannot be set for AES.'); + return; } /** * Sets the key length * - * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length + * Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to + * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. * - * @see \phpseclib3\Crypt\Rijndael:setKeyLength() + * @see \phpseclib\Crypt\Rijndael:setKeyLength() * @access public * @param int $length - * @throws \LengthException if the key length isn't supported */ - public function setKeyLength($length) + function setKeyLength($length) { switch ($length) { - case 128: - case 192: - case 256: + case 160: + $length = 192; break; - default: - throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); + case 224: + $length = 256; } parent::setKeyLength($length); } @@ -101,23 +99,28 @@ class AES extends Rijndael * * Rijndael supports five different key lengths, AES only supports three. * - * @see \phpseclib3\Crypt\Rijndael:setKey() + * @see \phpseclib\Crypt\Rijndael:setKey() * @see setKeyLength() * @access public * @param string $key - * @throws \LengthException if the key length isn't supported */ - public function setKey($key) + function setKey($key) { - switch (strlen($key)) { - case 16: - case 24: - case 32: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); - } - parent::setKey($key); + + if (!$this->explicit_key_length) { + $length = strlen($key); + switch (true) { + case $length <= 16: + $this->key_length = 16; + break; + case $length <= 24: + $this->key_length = 24; + break; + default: + $this->key_length = 32; + } + $this->_setEngine(); + } } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php index c75d983ab..74cc49de8 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php @@ -16,7 +16,7 @@ * setKey('12345678901234567890123456789012'); * @@ -35,9 +35,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of Blowfish. @@ -47,34 +45,34 @@ use phpseclib3\Crypt\Common\BlockCipher; * @author Hans-Juergen Petrich * @access public */ -class Blowfish extends BlockCipher +class Blowfish extends Base { /** * Block Length of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @see \phpseclib\Crypt\Base::block_size * @var int * @access private */ - protected $block_size = 8; + var $block_size = 8; /** * The mcrypt specific name of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib\Crypt\Base::cipher_name_mcrypt * @var string * @access private */ - protected $cipher_name_mcrypt = 'blowfish'; + var $cipher_name_mcrypt = 'blowfish'; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @see \phpseclib\Crypt\Base::cfb_init_len * @var int * @access private */ - protected $cfb_init_len = 500; + var $cfb_init_len = 500; /** * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each @@ -84,7 +82,7 @@ class Blowfish extends BlockCipher * @access private * @var array */ - private static $sbox0 = [ + var $sbox0 = array( 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, @@ -117,7 +115,7 @@ class Blowfish extends BlockCipher 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - ]; + ); /** * S-Box 1 @@ -125,7 +123,7 @@ class Blowfish extends BlockCipher * @access private * @var array */ - private static $sbox1 = [ + var $sbox1 = array( 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, @@ -158,7 +156,7 @@ class Blowfish extends BlockCipher 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - ]; + ); /** * S-Box 2 @@ -166,7 +164,7 @@ class Blowfish extends BlockCipher * @access private * @var array */ - private static $sbox2 = [ + var $sbox2 = array( 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, @@ -199,7 +197,7 @@ class Blowfish extends BlockCipher 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - ]; + ); /** * S-Box 3 @@ -207,7 +205,7 @@ class Blowfish extends BlockCipher * @access private * @var array */ - private static $sbox3 = [ + var $sbox3 = array( 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, @@ -240,7 +238,7 @@ class Blowfish extends BlockCipher 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - ]; + ); /** * P-Array consists of 18 32-bit subkeys @@ -248,11 +246,11 @@ class Blowfish extends BlockCipher * @var array * @access private */ - private static $parray = [ + var $parray = array( 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b - ]; + ); /** * The BCTX-working Array @@ -262,7 +260,7 @@ class Blowfish extends BlockCipher * @var array * @access private */ - private $bctx; + var $bctx; /** * Holds the last used key @@ -270,36 +268,20 @@ class Blowfish extends BlockCipher * @var array * @access private */ - private $kl; + var $kl; /** * The Key Length (in bytes) - * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk - * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could - * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once.} * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() + * @see \phpseclib\Crypt\Base::setKeyLength() * @var int * @access private + * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once. */ - protected $key_length = 16; - - /** - * Default Constructor. - * - * @param string $mode - * @access public - * @throws \InvalidArgumentException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode'); - } - } + var $key_length = 16; /** * Sets the key length. @@ -309,28 +291,30 @@ class Blowfish extends BlockCipher * @access public * @param int $length */ - public function setKeyLength($length) + function setKeyLength($length) { - if ($length < 32 || $length > 448) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported'); + if ($length < 32) { + $this->key_length = 4; + } elseif ($length > 448) { + $this->key_length = 56; + } else { + $this->key_length = $length >> 3; } - $this->key_length = $length >> 3; - parent::setKeyLength($length); } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * @see \phpseclib\Crypt\Base::isValidEngine() * @param int $engine - * @access protected + * @access public * @return bool */ - protected function isValidEngineHelper($engine) + function isValidEngine($engine) { if ($engine == self::ENGINE_OPENSSL) { if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) { @@ -339,37 +323,37 @@ class Blowfish extends BlockCipher if ($this->key_length < 16) { return false; } - self::$cipher_name_openssl_ecb = 'bf-ecb'; - $this->cipher_name_openssl = 'bf-' . $this->openssl_translate_mode(); + $this->cipher_name_openssl_ecb = 'bf-ecb'; + $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode(); } - return parent::isValidEngineHelper($engine); + return parent::isValidEngine($engine); } /** * Setup the key (expansion) * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + * @see \phpseclib\Crypt\Base::_setupKey() * @access private */ - protected function setupKey() + function _setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key']) { // already expanded return; } - $this->kl = ['key' => $this->key]; + $this->kl = array('key' => $this->key); /* key-expanding p[] and S-Box building sb[] */ - $this->bctx = [ - 'p' => [], - 'sb' => [ - self::$sbox0, - self::$sbox1, - self::$sbox2, - self::$sbox3 - ] - ]; + $this->bctx = array( + 'p' => array(), + 'sb' => array( + $this->sbox0, + $this->sbox1, + $this->sbox2, + $this->sbox3 + ) + ); // unpack binary string in unsigned chars $key = array_values(unpack('C*', $this->key)); @@ -382,20 +366,20 @@ class Blowfish extends BlockCipher $j = 0; } } - $this->bctx['p'][] = self::$parray[$i] ^ $data; + $this->bctx['p'][] = $this->parray[$i] ^ $data; } // encrypt the zero-string, replace P1 and P2 with the encrypted data, // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys $data = "\0\0\0\0\0\0\0\0"; for ($i = 0; $i < 18; $i += 2) { - list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data))); $this->bctx['p'][$i ] = $l; $this->bctx['p'][$i + 1] = $r; } for ($i = 0; $i < 4; ++$i) { for ($j = 0; $j < 256; $j += 2) { - list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data))); $this->bctx['sb'][$i][$j ] = $l; $this->bctx['sb'][$i][$j + 1] = $r; } @@ -409,31 +393,31 @@ class Blowfish extends BlockCipher * @param string $in * @return string */ - protected function encryptBlock($in) + function _encryptBlock($in) { - $p = $this->bctx['p']; - // extract($this->bctx['sb'], EXTR_PREFIX_ALL, 'sb'); // slower - $sb_0 = $this->bctx['sb'][0]; - $sb_1 = $this->bctx['sb'][1]; - $sb_2 = $this->bctx['sb'][2]; - $sb_3 = $this->bctx['sb'][3]; - - $in = unpack('N*', $in); + $p = $this->bctx["p"]; + // extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower + $sb_0 = $this->bctx["sb"][0]; + $sb_1 = $this->bctx["sb"][1]; + $sb_2 = $this->bctx["sb"][2]; + $sb_3 = $this->bctx["sb"][3]; + + $in = unpack("N*", $in); $l = $in[1]; $r = $in[2]; for ($i = 0; $i < 16; $i+= 2) { $l^= $p[$i]; - $r^= self::safe_intval((self::safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ + $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ $sb_2[$l >> 8 & 0xff]) + $sb_3[$l & 0xff]); $r^= $p[$i + 1]; - $l^= self::safe_intval((self::safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ + $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ $sb_2[$r >> 8 & 0xff]) + $sb_3[$r & 0xff]); } - return pack('N*', $r ^ $p[17], $l ^ $p[16]); + return pack("N*", $r ^ $p[17], $l ^ $p[16]); } /** @@ -443,114 +427,145 @@ class Blowfish extends BlockCipher * @param string $in * @return string */ - protected function decryptBlock($in) + function _decryptBlock($in) { - $p = $this->bctx['p']; - $sb_0 = $this->bctx['sb'][0]; - $sb_1 = $this->bctx['sb'][1]; - $sb_2 = $this->bctx['sb'][2]; - $sb_3 = $this->bctx['sb'][3]; + $p = $this->bctx["p"]; + $sb_0 = $this->bctx["sb"][0]; + $sb_1 = $this->bctx["sb"][1]; + $sb_2 = $this->bctx["sb"][2]; + $sb_3 = $this->bctx["sb"][3]; - $in = unpack('N*', $in); + $in = unpack("N*", $in); $l = $in[1]; $r = $in[2]; for ($i = 17; $i > 2; $i-= 2) { $l^= $p[$i]; - $r^= self::safe_intval((self::safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ + $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ $sb_2[$l >> 8 & 0xff]) + $sb_3[$l & 0xff]); $r^= $p[$i - 1]; - $l^= self::safe_intval((self::safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ + $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ $sb_2[$r >> 8 & 0xff]) + $sb_3[$r & 0xff]); } - return pack('N*', $r ^ $p[0], $l ^ $p[1]); + return pack("N*", $r ^ $p[0], $l ^ $p[1]); } /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() + * @see \phpseclib\Crypt\Base::_setupInlineCrypt() * @access private */ - protected function setupInlineCrypt() + function _setupInlineCrypt() { - $p = $this->bctx['p']; - $init_crypt = ' - static $sb_0, $sb_1, $sb_2, $sb_3; - if (!$sb_0) { - $sb_0 = $this->bctx["sb"][0]; - $sb_1 = $this->bctx["sb"][1]; - $sb_2 = $this->bctx["sb"][2]; - $sb_3 = $this->bctx["sb"][3]; - } - '; + $lambda_functions =& self::_getLambdaFunctions(); - $safeint = self::safe_intval_inline(); + // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. + // (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit) + // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. + $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); - // Generating encrypt code: - $encrypt_block = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - '; - for ($i = 0; $i < 16; $i+= 2) { + // Generation of a unique hash for our generated code + $code_hash = "Crypt_Blowfish, {$this->mode}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); + } + + $safeint = $this->safe_intval_inline(); + + if (!isset($lambda_functions[$code_hash])) { + switch (true) { + case $gen_hi_opt_code: + $p = $this->bctx['p']; + $init_crypt = ' + static $sb_0, $sb_1, $sb_2, $sb_3; + if (!$sb_0) { + $sb_0 = $self->bctx["sb"][0]; + $sb_1 = $self->bctx["sb"][1]; + $sb_2 = $self->bctx["sb"][2]; + $sb_3 = $self->bctx["sb"][3]; + } + '; + break; + default: + $p = array(); + for ($i = 0; $i < 18; ++$i) { + $p[] = '$p_' . $i; + } + $init_crypt = ' + list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"]; + list(' . implode(',', $p) . ') = $self->bctx["p"]; + + '; + } + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + for ($i = 0; $i < 16; $i+= 2) { + $encrypt_block.= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i + 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } $encrypt_block.= ' - $l^= ' . $p[$i] . '; - $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]') . '; - - $r^= ' . $p[$i + 1] . '; - $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]') . '; + $in = pack("N*", + $r ^ ' . $p[17] . ', + $l ^ ' . $p[16] . ' + ); '; - } - $encrypt_block.= ' - $in = pack("N*", - $r ^ ' . $p[17] . ', - $l ^ ' . $p[16] . ' - ); - '; - // Generating decrypt code: - $decrypt_block = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - '; - for ($i = 17; $i > 2; $i-= 2) { + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + + for ($i = 17; $i > 2; $i-= 2) { + $decrypt_block.= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i - 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } + $decrypt_block.= ' - $l^= ' . $p[$i] . '; - $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]') . '; - - $r^= ' . $p[$i - 1] . '; - $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]') . '; + $in = pack("N*", + $r ^ ' . $p[0] . ', + $l ^ ' . $p[1] . ' + ); '; - } - $decrypt_block.= ' - $in = pack("N*", - $r ^ ' . $p[0] . ', - $l ^ ' . $p[1] . ' + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( + array( + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ) ); - '; - - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'init_encrypt' => '', - 'init_decrypt' => '', - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); + } + $this->inline_crypt = $lambda_functions[$code_hash]; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php deleted file mode 100644 index 0bf1c2eba..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php +++ /dev/null @@ -1,797 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\BadDecryptionException; - -/** - * Pure-PHP implementation of ChaCha20. - * - * @package ChaCha20 - * @author Jim Wigginton - * @access public - */ -class ChaCha20 extends Salsa20 -{ - /** - * The OpenSSL specific name of the cipher - * - * @var string - */ - protected $cipher_name_openssl = 'chacha20'; - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param int $engine - * @access protected - * @return bool - */ - protected function isValidEngineHelper($engine) - { - switch ($engine) { - case self::ENGINE_LIBSODIUM: - // PHP 7.2.0 (30 Nov 2017) added support for libsodium - - // we could probably make it so that if $this->counter == 0 then the first block would be done with either OpenSSL - // or PHP and then subsequent blocks would then be done with libsodium but idk - it's not a high priority atm - - // we could also make it so that if $this->counter == 0 and $this->continuousBuffer then do the first string - // with libsodium and subsequent strings with openssl or pure-PHP but again not a high priority - return function_exists('sodium_crypto_aead_chacha20poly1305_ietf_encrypt') && - $this->key_length == 32 && - (($this->usePoly1305 && !isset($this->poly1305Key) && $this->counter == 0) || $this->counter == 1) && - !$this->continuousBuffer; - case self::ENGINE_OPENSSL: - // OpenSSL 1.1.0 (released 25 Aug 2016) added support for chacha20. - // PHP didn't support OpenSSL 1.1.0 until 7.0.19 (11 May 2017) - - // if you attempt to provide openssl with a 128 bit key (as opposed to a 256 bit key) openssl will null - // pad the key to 256 bits and still use the expansion constant for 256-bit keys. the fact that - // openssl treats the IV as both the counter and nonce, however, let's us use openssl in continuous mode - // whereas libsodium does not - if ($this->key_length != 32) { - return false; - } - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Encrypts a message. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @see self::crypt() - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - $this->setup(); - - if ($this->engine == self::ENGINE_LIBSODIUM) { - return $this->encrypt_with_libsodium($plaintext); - } - - return parent::encrypt($plaintext); - } - - /** - * Decrypts a message. - * - * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). - * At least if the continuous buffer is disabled. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see self::crypt() - * @param string $ciphertext - * @return string $plaintext - */ - public function decrypt($ciphertext) - { - $this->setup(); - - if ($this->engine == self::ENGINE_LIBSODIUM) { - return $this->decrypt_with_libsodium($ciphertext); - } - - return parent::decrypt($ciphertext); - } - - /** - * Encrypts a message with libsodium - * - * @see self::encrypt() - * @param string $plaintext - * @return string $text - */ - private function encrypt_with_libsodium($plaintext) - { - $params = [$plaintext, $this->aad, $this->nonce, $this->key]; - $ciphertext = strlen($this->nonce) == 8 ? - sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : - sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); - if (!$this->usePoly1305) { - return substr($ciphertext, 0, strlen($plaintext)); - } - - $newciphertext = substr($ciphertext, 0, strlen($plaintext)); - - $this->newtag = $this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12 ? - substr($ciphertext, strlen($plaintext)) : - $this->poly1305($newciphertext); - - return $newciphertext; - } - - /** - * Decrypts a message with libsodium - * - * @see self::decrypt() - * @param string $ciphertext - * @return string $text - */ - private function decrypt_with_libsodium($ciphertext) - { - $params = [$ciphertext, $this->aad, $this->nonce, $this->key]; - - if (isset($this->poly1305Key)) { - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - if ($this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12) { - $plaintext = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$params); - $this->oldtag = false; - if ($plaintext === false) { - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - return $plaintext; - } - $newtag = $this->poly1305($ciphertext); - if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { - $this->oldtag = false; - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - $this->oldtag = false; - } - - $plaintext = strlen($this->nonce) == 8 ? - sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : - sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); - - return substr($plaintext, 0, strlen($ciphertext)); - } - - /** - * Sets the nonce. - * - * @param string $nonce - */ - public function setNonce($nonce) - { - if (!is_string($nonce)) { - throw new \UnexpectedValueException('The nonce should be a string'); - } - - /* - from https://tools.ietf.org/html/rfc7539#page-7 - - "Note also that the original ChaCha had a 64-bit nonce and 64-bit - block count. We have modified this here to be more consistent with - recommendations in Section 3.2 of [RFC5116]." - */ - switch (strlen($nonce)) { - case 8: // 64 bits - case 12: // 96 bits - break; - default: - throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported'); - } - - $this->nonce = $nonce; - $this->changed = true; - $this->setEngine(); - } - - /** - * Setup the self::ENGINE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setNonce() - * - * - First run of encrypt() / decrypt() with no init-settings - * - * @see self::setKey() - * @see self::setNonce() - * @see self::disableContinuousBuffer() - */ - protected function setup() - { - if (!$this->changed) { - return; - } - - $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; - - $this->changed = $this->nonIVChanged = false; - - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - if ($this->usePoly1305 && !isset($this->poly1305Key)) { - $this->usingGeneratedPoly1305Key = true; - if ($this->engine == self::ENGINE_LIBSODIUM) { - return; - } - $this->createPoly1305Key(); - } - - $key = $this->key; - if (strlen($key) == 16) { - $constant = 'expand 16-byte k'; - $key.= $key; - } else { - $constant = 'expand 32-byte k'; - } - - $this->p1 = $constant . $key; - $this->p2 = $this->nonce; - if (strlen($this->nonce) == 8) { - $this->p2 = "\0\0\0\0" . $this->p2; - } - } - - /** - * The quarterround function - * - * @param int $a - * @param int $b - * @param int $c - * @param int $d - */ - protected static function quarterRound(&$a, &$b, &$c, &$d) - { - $a+= $b; $d = self::leftRotate($d ^ $a, 16); - $c+= $d; $b = self::leftRotate($b ^ $c, 12); - $a+= $b; $d = self::leftRotate($d ^ $a, 8); - $c+= $d; $b = self::leftRotate($b ^ $c, 7); - } - - /** - * The doubleround function - * - * @param int $x0 (by reference) - * @param int $x1 (by reference) - * @param int $x2 (by reference) - * @param int $x3 (by reference) - * @param int $x4 (by reference) - * @param int $x5 (by reference) - * @param int $x6 (by reference) - * @param int $x7 (by reference) - * @param int $x8 (by reference) - * @param int $x9 (by reference) - * @param int $x10 (by reference) - * @param int $x11 (by reference) - * @param int $x12 (by reference) - * @param int $x13 (by reference) - * @param int $x14 (by reference) - * @param int $x15 (by reference) - */ - protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) - { - // columnRound - static::quarterRound($x0, $x4, $x8, $x12); - static::quarterRound($x1, $x5, $x9, $x13); - static::quarterRound($x2, $x6, $x10, $x14); - static::quarterRound($x3, $x7, $x11, $x15); - // rowRound - static::quarterRound($x0, $x5, $x10, $x15); - static::quarterRound($x1, $x6, $x11, $x12); - static::quarterRound($x2, $x7, $x8, $x13); - static::quarterRound($x3, $x4, $x9, $x14); - } - - /** - * The Salsa20 hash function function - * - * On my laptop this loop unrolled / function dereferenced version of parent::salsa20 encrypts 1mb of text in - * 0.65s vs the 0.85s that it takes with the parent method. - * - * If we were free to assume that the host OS would always be 64-bits then the if condition in leftRotate could - * be eliminated and we could knock this done to 0.60s. - * - * For comparison purposes, RC4 takes 0.16s and AES in CTR mode with the Eval engine takes 0.48s. - * AES in CTR mode with the PHP engine takes 1.19s. Salsa20 / ChaCha20 do not benefit as much from the Eval - * approach due to the fact that there are a lot less variables to de-reference, fewer loops to unroll, etc - * - * @param string $x - */ - protected static function salsa20($x) - { - list(, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15) = unpack('V*', $x); - $z0 = $x0; - $z1 = $x1; - $z2 = $x2; - $z3 = $x3; - $z4 = $x4; - $z5 = $x5; - $z6 = $x6; - $z7 = $x7; - $z8 = $x8; - $z9 = $x9; - $z10 = $x10; - $z11 = $x11; - $z12 = $x12; - $z13 = $x13; - $z14 = $x14; - $z15 = $x15; - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12); - $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8); - $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7); - - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12); - $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8); - $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7); - - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12); - $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8); - $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7); - - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12); - $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8); - $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12); - $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8); - $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7); - - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12); - $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8); - $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7); - - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12); - $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8); - $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7); - - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12); - $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8); - $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7); - - $x0+= $z0; - $x1+= $z1; - $x2+= $z2; - $x3+= $z3; - $x4+= $z4; - $x5+= $z5; - $x6+= $z6; - $x7+= $z7; - $x8+= $z8; - $x9+= $z9; - $x10+= $z10; - $x11+= $z11; - $x12+= $z12; - $x13+= $z13; - $x14+= $z14; - $x15+= $z15; - - return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php deleted file mode 100644 index 9c368ebb8..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php +++ /dev/null @@ -1,492 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Exception\NoKeyLoadedException; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\ECDSA; - -/** - * Base Class for all asymmetric cipher classes - * - * @package AsymmetricKey - * @author Jim Wigginton - */ -abstract class AsymmetricKey -{ - /** - * Precomputed Zero - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected static $zero; - - /** - * Precomputed One - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected static $one; - - /** - * Format of the loaded key - * - * @var string - * @access private - */ - protected $format; - - /** - * Hash function - * - * @var \phpseclib3\Crypt\Hash - * @access private - */ - protected $hash; - - /** - * HMAC function - * - * @var \phpseclib3\Crypt\Hash - * @access private - */ - private $hmac; - - /** - * Supported plugins (lower case) - * - * @see self::initialize_static_variables() - * @var array - * @access private - */ - private static $plugins = []; - - /** - * Invisible plugins - * - * @see self::initialize_static_variables() - * @var array - * @access private - */ - private static $invisiblePlugins = []; - - /** - * Supported signature formats (lower case) - * - * @see self::initialize_static_variables() - * @var array - * @access private - */ - private static $signatureFormats = []; - - /** - * Supported signature formats (original case) - * - * @see self::initialize_static_variables() - * @var array - * @access private - */ - private static $signatureFileFormats = []; - - /** - * Available Engines - * - * @var boolean[] - * @access private - */ - protected static $engines = []; - - /** - * The constructor - */ - protected function __construct() - { - self::initialize_static_variables(); - - $this->hash = new Hash('sha256'); - $this->hmac = new Hash('sha256'); - } - - /** - * Initialize static variables - */ - protected static function initialize_static_variables() - { - if (!isset(self::$zero)) { - self::$zero= new BigInteger(0); - self::$one = new BigInteger(1); - } - - self::loadPlugins('Keys'); - if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') { - self::loadPlugins('Signature'); - } - } - - /** - * Load the key - * - * @param string $key - * @param string $password optional - * @return AsymmetricKey - */ - public static function load($key, $password = false) - { - self::initialize_static_variables(); - - $components = false; - foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { - if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) { - continue; - } - try { - $components = $format::load($key, $password); - } catch (\Exception $e) { - $components = false; - } - if ($components !== false) { - break; - } - } - - if ($components === false) { - throw new NoKeyLoadedException('Unable to read key'); - } - - $components['format'] = $format; - $new = static::onLoad($components); - $new->format = $format; - return $new instanceof PrivateKey ? - $new->withPassword($password) : - $new; - } - - /** - * Load the key, assuming a specific format - * - * @param string $type - * @param string $key - * @param string $password optional - * @return AsymmetricKey - */ - public static function loadFormat($type, $key, $password = false) - { - self::initialize_static_variables(); - - $components = false; - $format = strtolower($type); - if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) { - $format = self::$plugins[static::ALGORITHM]['Keys'][$format]; - $components = $format::load($key, $password); - } - - if ($components === false) { - throw new NoKeyLoadedException('Unable to read key'); - } - - $components['format'] = $format; - - $new = static::onLoad($components); - $new->format = $format; - return $new instanceof PrivateKey ? - $new->withPassword($password) : - $new; - } - - /** - * Validate Plugin - * - * @access private - * @param string $format - * @param string $type - * @param string $method optional - * @return mixed - */ - protected static function validatePlugin($format, $type, $method = NULL) - { - $type = strtolower($type); - if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) { - throw new UnsupportedFormatException("$type is not a supported format"); - } - $type = self::$plugins[static::ALGORITHM][$format][$type]; - if (isset($method) && !method_exists($type, $method)) { - throw new UnsupportedFormatException("$type does not implement $method"); - } - - return $type; - } - - /** - * Load Plugins - * - * @access private - * @param string $format - */ - private static function loadPlugins($format) - { - if (!isset(self::$plugins[static::ALGORITHM][$format])) { - self::$plugins[static::ALGORITHM][$format] = []; - foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) { - if ($file->getExtension() != 'php') { - continue; - } - $name = $file->getBasename('.php'); - $type = 'phpseclib3\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name; - $reflect = new \ReflectionClass($type); - if ($reflect->isTrait()) { - continue; - } - self::$plugins[static::ALGORITHM][$format][strtolower($name)] = $type; - if ($reflect->hasConstant('IS_INVISIBLE')) { - self::$invisiblePlugins[static::ALGORITHM][] = $type; - } - } - } - } - - /** - * Returns a list of supported formats. - * - * @access public - * @return array - */ - public static function getSupportedKeyFormats() - { - self::initialize_static_variables(); - - return self::$plugins[static::ALGORITHM]['Keys']; - } - - /** - * Add a fileformat plugin - * - * The plugin needs to either already be loaded or be auto-loadable. - * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin. - * - * @see self::load() - * @param string $fullname - * @access public - * @return bool - */ - public static function addFileFormat($fullname) - { - self::initialize_static_variables(); - - if (class_exists($fullname)) { - $meta = new \ReflectionClass($fullname); - $shortname = $meta->getShortName(); - self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname; - if ($meta->hasConstant('IS_INVISIBLE')) { - self::$invisiblePlugins[static::ALGORITHM] = strtolower($name); - } - } - } - - /** - * Returns the format of the loaded key. - * - * If the key that was loaded wasn't in a valid or if the key was auto-generated - * with RSA::createKey() then this will throw an exception. - * - * @see self::load() - * @access public - * @return mixed - */ - public function getLoadedFormat() - { - if (empty($this->format)) { - throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); - } - - $meta = new \ReflectionClass($this->format); - return $meta->getShortName(); - } - - /** - * Tests engine validity - * - * @access public - */ - public static function useBestEngine() - { - static::$engines = [ - 'PHP' => true, - 'OpenSSL' => extension_loaded('openssl'), - // this test can be satisfied by either of the following: - // http://php.net/manual/en/book.sodium.php - // https://github.com/paragonie/sodium_compat - 'libsodium' => function_exists('sodium_crypto_sign_keypair') - ]; - - return static::$engines; - } - - /** - * Flag to use internal engine only (useful for unit testing) - * - * @access public - */ - public static function useInternalEngine() - { - static::$engines = [ - 'PHP' => true, - 'OpenSSL' => false, - 'libsodium' => false - ]; - } - - /** - * __toString() magic method - * - * @return string - */ - public function __toString() - { - return $this->toString('PKCS8'); - } - - /** - * Determines which hashing function should be used - * - * @access public - * @param string $hash - */ - public function withHash($hash) - { - $new = clone $this; - - $new->hash = new Hash($hash); - $new->hmac = new Hash($hash); - - return $new; - } - - /** - * Returns the hash algorithm currently being used - * - * @access public - */ - public function getHash() - { - return clone $this->hash; - } - - /** - * Compute the pseudorandom k for signature generation, - * using the process specified for deterministic DSA. - * - * @access public - * @param string $h1 - * @return string - */ - protected function computek($h1) - { - $v = str_repeat("\1", strlen($h1)); - - $k = str_repeat("\0", strlen($h1)); - - $x = $this->int2octets($this->x); - $h1 = $this->bits2octets($h1); - - $this->hmac->setKey($k); - $k = $this->hmac->hash($v . "\0" . $x . $h1); - $this->hmac->setKey($k); - $v = $this->hmac->hash($v); - $k = $this->hmac->hash($v . "\1" . $x . $h1); - $this->hmac->setKey($k); - $v = $this->hmac->hash($v); - - $qlen = $this->q->getLengthInBytes(); - - while (true) { - $t = ''; - while (strlen($t) < $qlen) { - $v = $this->hmac->hash($v); - $t = $t . $v; - } - $k = $this->bits2int($t); - - if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) { - break; - } - $k = $this->hmac->hash($v . "\0"); - $this->hmac->setKey($k); - $v = $this->hmac->hash($v); - } - - return $k; - } - - /** - * Integer to Octet String - * - * @access private - * @param \phpseclib3\Math\BigInteger $v - * @return string - */ - private function int2octets($v) - { - $out = $v->toBytes(); - $rolen = $this->q->getLengthInBytes(); - if (strlen($out) < $rolen) { - return str_pad($out, $rolen, "\0", STR_PAD_LEFT); - } else if (strlen($out) > $rolen) { - return substr($out, -$rolen); - } else { - return $out; - } - } - - /** - * Bit String to Integer - * - * @access private - * @param string $in - * @return \phpseclib3\Math\BigInteger - */ - protected function bits2int($in) - { - $v = new BigInteger($in, 256); - $vlen = strlen($in) << 3; - $qlen = $this->q->getLength(); - if ($vlen > $qlen) { - return $v->bitwise_rightShift($vlen - $qlen); - } - return $v; - } - - /** - * Bit String to Octet String - * - * @access private - * @param string $in - * @return string - */ - private function bits2octets($in) - { - $z1 = $this->bits2int($in); - $z2 = $z1->subtract($this->q); - return $z2->compare(self::$zero) < 0 ? - $this->int2octets($z1) : - $this->int2octets($z2); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php deleted file mode 100644 index a8ed74d86..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * Base Class for all block cipher classes - * - * @package BlockCipher - * @author Jim Wigginton - */ -abstract class BlockCipher extends SymmetricKey -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php deleted file mode 100644 index 7c51dd391..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Random; -use phpseclib3\Exception\UnsupportedFormatException; - -/** - * OpenSSH Formatted RSA Key Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class OpenSSH -{ - /** - * Default comment - * - * @var string - * @access private - */ - protected static $comment = 'phpseclib-generated-key'; - - /** - * Binary key flag - * - * @var bool - * @access private - */ - protected static $binary = false; - - /** - * Sets the default comment - * - * @access public - * @param string $comment - */ - public static function setComment($comment) - { - self::$comment = str_replace(["\r", "\n"], '', $comment); - } - - /** - * Break a public or private key down into its constituent components - * - * $type can be either ssh-dss or ssh-rsa - * - * @access public - * @param string $key - * @param string $password - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - // key format is described here: - // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD - - if (strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== false) { - $key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key); - $key = Base64::decode($key); - $magic = Strings::shift($key, 15); - if ($magic != "openssh-key-v1\0") { - throw new \RuntimeException('Expected openssh-key-v1'); - } - list($ciphername, $kdfname, $kdfoptions, $numKeys) = Strings::unpackSSH2('sssN', $key); - if ($numKeys != 1) { - // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys - // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass - // that to the appropriate key loading parser $numKey times or something - throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); - } - if (strlen($kdfoptions) || $kdfname != 'none' || $ciphername != 'none') { - /* - OpenSSH private keys use a customized version of bcrypt. specifically, instead of encrypting - OrpheanBeholderScryDoubt 64 times OpenSSH's bcrypt variant encrypts - OxychromaticBlowfishSwatDynamite 64 times. so we can't use crypt(). - - bcrypt is basically Blowfish with an altered key expansion. whereas Blowfish just runs the - key through the key expansion bcrypt interleaves the key expansion with the salt and - password. this renders openssl / mcrypt unusuable. this forces us to use a pure-PHP implementation - of bcrypt. the problem with that is that pure-PHP is too slow to be practically useful. - - in addition to encrypting a different string 64 times the OpenSSH implementation also performs bcrypt - from scratch $rounds times. calling crypt() 64x with bcrypt takes 0.7s. PHP is going to be naturally - slower. pure-PHP is 215x slower than OpenSSL for AES and pure-PHP is 43x slower for bcrypt. - 43 * 0.7 = 30s. no one wants to wait 30s to load a private key. - - another way to think about this.. according to wikipedia's article on Blowfish, - "Each new key requires pre-processing equivalent to encrypting about 4 kilobytes of text". - key expansion is done (9+64*2)*160 times. multiply that by 4 and it turns out that Blowfish, - OpenSSH style, is the equivalent of encrypting ~80mb of text. - - more supporting evidence: sodium_compat does not implement Argon2 (another password hashing - algorithm) because "It's not feasible to polyfill scrypt or Argon2 into PHP and get reasonable - performance. Users would feel motivated to select parameters that downgrade security to avoid - denial of service (DoS) attacks. The only winning move is not to play" - -- https://github.com/paragonie/sodium_compat/blob/master/README.md - */ - throw new \RuntimeException('Encrypted OpenSSH private keys are not supported'); - //list($salt, $rounds) = Strings::unpackSSH2('sN', $kdfoptions); - } - - list($publicKey, $paddedKey) = Strings::unpackSSH2('ss', $key); - list($type) = Strings::unpackSSH2('s', $publicKey); - list($checkint1, $checkint2) = Strings::unpackSSH2('NN', $paddedKey); - // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. - if ($checkint1 != $checkint2) { - throw new \RuntimeException('The two checkints do not match'); - } - self::checkType($type); - - return compact('type', 'publicKey', 'paddedKey'); - } - - $parts = explode(' ', $key, 3); - - if (!isset($parts[1])) { - $key = base64_decode($parts[0]); - $comment = isset($parts[1]) ? $parts[1] : false; - } else { - $asciiType = $parts[0]; - self::checkType($parts[0]); - $key = base64_decode($parts[1]); - $comment = isset($parts[2]) ? $parts[2] : false; - } - if ($key === false) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - list($type) = Strings::unpackSSH2('s', $key); - self::checkType($type); - if (isset($asciiType) && $asciiType != $type) { - throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); - } - if (strlen($key) <= 4) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $publicKey = $key; - - return compact('type', 'publicKey', 'comment'); - } - - /** - * Toggle between binary and printable keys - * - * Printable keys are what are generated by default. These are the ones that go in - * $HOME/.ssh/authorized_key. - * - * @access public - * @param bool $enabled - */ - public static function setBinaryOutput($enabled) - { - self::$binary = $enabled; - } - - /** - * Checks to see if the type is valid - * - * @access private - * @param string $candidate - */ - private static function checkType($candidate) - { - if (!in_array($candidate, static::$types)) { - throw new \RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types)); - } - } - - /** - * Wrap a private key appropriately - * - * @access public - * @param string $publicKey - * @param string $privateKey - * @param string $password - * @param array $options - * @return string - */ - protected static function wrapPrivateKey($publicKey, $privateKey, $password, $options) - { - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('Encrypted OpenSSH private keys are not supported'); - } - - list(, $checkint) = unpack('N', Random::string(4)); - - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - $paddedKey = Strings::packSSH2('NN', $checkint, $checkint) . - $privateKey . - Strings::packSSH2('s', $comment); - - /* - from http://tools.ietf.org/html/rfc4253#section-6 : - - Note that the length of the concatenation of 'packet_length', - 'padding_length', 'payload', and 'random padding' MUST be a multiple - of the cipher block size or 8, whichever is larger. - */ - $paddingLength = (7 * strlen($paddedKey)) % 8; - for ($i = 1; $i <= $paddingLength; $i++) { - $paddedKey.= chr($i); - } - $key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey); - $key = "openssh-key-v1\0$key"; - - return "-----BEGIN OPENSSH PRIVATE KEY-----\r\n" . - chunk_split(Base64::encode($key), 70) . - "-----END OPENSSH PRIVATE KEY-----"; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php deleted file mode 100644 index 3550cc531..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -/** - * PKCS1 Formatted Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class PKCS -{ - /** - * Auto-detect the format - */ - const MODE_ANY = 0; - /** - * Require base64-encoded PEM's be supplied - */ - const MODE_PEM = 1; - /** - * Require raw DER's be supplied - */ - const MODE_DER = 2; - /**#@-*/ - - /** - * Is the key a base-64 encoded PEM, DER or should it be auto-detected? - * - * @access private - * @var int - */ - protected static $format = self::MODE_ANY; - - /** - * Require base64-encoded PEM's be supplied - * - * @access public - */ - public static function requirePEM() - { - self::$format = self::MODE_PEM; - } - - /** - * Require raw DER's be supplied - * - * @access public - */ - public static function requireDER() - { - self::$format = self::MODE_DER; - } - - /** - * Accept any format and auto detect the format - * - * This is the default setting - * - * @access public - */ - public static function requireAny() - { - self::$format = self::MODE_ANY; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php deleted file mode 100644 index a362d938b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,223 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\AES; -use phpseclib3\Crypt\DES; -use phpseclib3\Crypt\TripleDES; -use phpseclib3\File\ASN1; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\UnsupportedAlgorithmException; - -/** - * PKCS1 Formatted Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class PKCS1 extends PKCS -{ - /** - * Default encryption algorithm - * - * @var string - * @access private - */ - private static $defaultEncryptionAlgorithm = 'AES-128-CBC'; - - /** - * Sets the default encryption algorithm - * - * @access public - * @param string $algo - */ - public static function setEncryptionAlgorithm($algo) - { - self::$defaultEncryptionAlgorithm = $algo; - } - - /** - * Returns the mode constant corresponding to the mode string - * - * @access public - * @param string $mode - * @return int - * @throws \UnexpectedValueException if the block cipher mode is unsupported - */ - private static function getEncryptionMode($mode) - { - switch ($mode) { - case 'CBC': - case 'ECB': - case 'CFB': - case 'OFB': - case 'CTR': - return $mode; - } - throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); - } - - /** - * Returns a cipher object corresponding to a string - * - * @access public - * @param string $algo - * @return string - * @throws \UnexpectedValueException if the encryption algorithm is unsupported - */ - private static function getEncryptionObject($algo) - { - $modes = '(CBC|ECB|CFB|OFB|CTR)'; - switch (true) { - case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches): - $cipher = new AES(self::getEncryptionMode($matches[2])); - $cipher->setKeyLength($matches[1]); - return $cipher; - case preg_match("#^DES-EDE3-$modes$#", $algo, $matches): - return new TripleDES(self::getEncryptionMode($matches[1])); - case preg_match("#^DES-$modes$#", $algo, $matches): - return new DES(self::getEncryptionMode($matches[1])); - default: - throw new UnsupportedAlgorithmException($algo . ' is not a supported algorithm'); - } - } - - /** - * Generate a symmetric key for PKCS#1 keys - * - * @access private - * @param string $password - * @param string $iv - * @param int $length - * @return string - */ - private static function generateSymmetricKey($password, $iv, $length) - { - $symkey = ''; - $iv = substr($iv, 0, 8); - while (strlen($symkey) < $length) { - $symkey.= md5($symkey . $password . $iv, true); - } - return substr($symkey, 0, $length); - } - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - protected static function load($key, $password) - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is - "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to - protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding - two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: - - http://tools.ietf.org/html/rfc1421#section-4.6.1.1 - http://tools.ietf.org/html/rfc1421#section-4.6.1.3 - - DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. - DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation - function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's - own implementation. ie. the implementation *is* the standard and any bugs that may exist in that - implementation are part of the standard, as well. - - * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ - if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { - $iv = Hex::decode(trim($matches[2])); - // remove the Proc-Type / DEK-Info sections as they're no longer needed - $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); - $ciphertext = ASN1::extractBER($key); - if ($ciphertext === false) { - $ciphertext = $key; - } - $crypto = self::getEncryptionObject($matches[1]); - $crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3)); - $crypto->setIV($iv); - $key = $crypto->decrypt($ciphertext); - } else { - if (self::$format != self::MODE_DER) { - $decoded = ASN1::extractBER($key); - if ($decoded !== false) { - $key = $decoded; - } elseif (self::$format == self::MODE_PEM) { - throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); - } - } - } - - return $key; - } - - /** - * Wrap a private key appropriately - * - * @access public - * @param string $key - * @param string $type - * @param string $password - * @param array $options optional - * @return string - */ - protected static function wrapPrivateKey($key, $type, $password, array $options = []) - { - if (empty($password) || !is_string($password)) { - return "-----BEGIN $type PRIVATE KEY-----\r\n" . - chunk_split(Base64::encode($key), 64) . - "-----END $type PRIVATE KEY-----"; - } - - $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; - - $cipher = self::getEncryptionObject($encryptionAlgorithm); - $iv = Random::string($cipher->getBlockLength() >> 3); - $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); - $cipher->setIV($iv); - $iv = strtoupper(Hex::encode($iv)); - return "-----BEGIN $type PRIVATE KEY-----\r\n" . - "Proc-Type: 4,ENCRYPTED\r\n" . - "DEK-Info: " . $encryptionAlgorithm. ",$iv\r\n" . - "\r\n" . - chunk_split(Base64::encode($cipher->encrypt($key)), 64) . - "-----END $type PRIVATE KEY-----"; - } - - /** - * Wrap a public key appropriately - * - * @access public - * @param string $key - * @param string $type - * @return string - */ - protected static function wrapPublicKey($key, $type) - { - return "-----BEGIN $type PUBLIC KEY-----\r\n" . - chunk_split(Base64::encode($key), 64) . - "-----END $type PUBLIC KEY-----"; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php deleted file mode 100644 index cb6d83ced..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,702 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Crypt\DES; -use phpseclib3\Crypt\RC2; -use phpseclib3\Crypt\RC4; -use phpseclib3\Crypt\AES; -use phpseclib3\Crypt\TripleDES; -use phpseclib3\Crypt\Random; -use phpseclib3\Math\BigInteger; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\UnsupportedAlgorithmException; - -/** - * PKCS#8 Formatted Key Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class PKCS8 extends PKCS -{ - /** - * Default encryption algorithm - * - * @var string - * @access private - */ - private static $defaultEncryptionAlgorithm = 'id-PBES2'; - - /** - * Default encryption scheme - * - * Only used when defaultEncryptionAlgorithm is id-PBES2 - * - * @var string - * @access private - */ - private static $defaultEncryptionScheme = 'aes128-CBC-PAD'; - - /** - * Default PRF - * - * Only used when defaultEncryptionAlgorithm is id-PBES2 - * - * @var string - * @access private - */ - private static $defaultPRF = 'id-hmacWithSHA256'; - - /** - * Default Iteration Count - * - * @var int - * @access private - */ - private static $defaultIterationCount = 2048; - - /** - * OIDs loaded - * - * @var bool - * @access private - */ - private static $oidsLoaded = false; - - /** - * Sets the default encryption algorithm - * - * @access public - * @param string $algo - */ - public static function setEncryptionAlgorithm($algo) - { - self::$defaultEncryptionAlgorithm = $algo; - } - - /** - * Sets the default encryption algorithm for PBES2 - * - * @access public - * @param string $algo - */ - public static function setEncryptionScheme($algo) - { - self::$defaultEncryptionScheme = $algo; - } - - /** - * Sets the iteration count - * - * @access public - * @param int $count - */ - public static function setIterationCount($count) - { - self::$defaultIterationCount = $count; - } - - /** - * Sets the PRF for PBES2 - * - * @access public - * @param string $algo - */ - public static function setPRF($algo) - { - self::$defaultPRF = $algo; - } - - /** - * Returns a SymmetricKey object based on a PBES1 $algo - * - * @return \phpseclib3\Crypt\Common\SymmetricKey - * @access public - * @param string $algo - */ - private static function getPBES1EncryptionObject($algo) - { - $algo = preg_match('#^pbeWith(?:MD2|MD5|SHA1|SHA)And(.*?)-CBC$#', $algo, $matches) ? - $matches[1] : - substr($algo, 13); // strlen('pbeWithSHAAnd') == 13 - - switch ($algo) { - case 'DES': - $cipher = new DES('cbc'); - break; - case 'RC2': - $cipher = new RC2('cbc'); - break; - case '3-KeyTripleDES': - $cipher = new TripleDES('cbc'); - break; - case '2-KeyTripleDES': - $cipher = new TripleDES('cbc'); - $cipher->setKeyLength(128); - break; - case '128BitRC2': - $cipher = new RC2('cbc'); - $cipher->setKeyLength(128); - break; - case '40BitRC2': - $cipher = new RC2('cbc'); - $cipher->setKeyLength(40); - break; - case '128BitRC4': - $cipher = new RC4(); - $cipher->setKeyLength(128); - break; - case '40BitRC4': - $cipher = new RC4(); - $cipher->setKeyLength(40); - break; - default: - throw new UnsupportedAlgorithmException("$algo is not a supported algorithm"); - } - - return $cipher; - } - - /** - * Returns a hash based on a PBES1 $algo - * - * @return string - * @access public - * @param string $algo - */ - private static function getPBES1Hash($algo) - { - if (preg_match('#^pbeWith(MD2|MD5|SHA1|SHA)And.*?-CBC$#', $algo, $matches)) { - return $matches[1] == 'SHA' ? 'sha1' : $matches[1]; - } - - return 'sha1'; - } - - /** - * Returns a KDF baesd on a PBES1 $algo - * - * @return string - * @access public - * @param string $algo - */ - private static function getPBES1KDF($algo) - { - switch ($algo) { - case 'pbeWithMD2AndDES-CBC': - case 'pbeWithMD2AndRC2-CBC': - case 'pbeWithMD5AndDES-CBC': - case 'pbeWithMD5AndRC2-CBC': - case 'pbeWithSHA1AndDES-CBC': - case 'pbeWithSHA1AndRC2-CBC': - return 'pbkdf1'; - } - - return 'pkcs12'; - } - - /** - * Returns a SymmetricKey object baesd on a PBES2 $algo - * - * @return SymmetricKey - * @access public - * @param string $algo - */ - private static function getPBES2EncryptionObject($algo) - { - switch ($algo) { - case 'desCBC': - $cipher = new TripleDES('cbc'); - break; - case 'des-EDE3-CBC': - $cipher = new TripleDES('cbc'); - break; - case 'rc2CBC': - $cipher = new RC2('cbc'); - // in theory this can be changed - $cipher->setKeyLength(128); - break; - case 'rc5-CBC-PAD': - throw new UnsupportedAlgorithmException('rc5-CBC-PAD is not supported for PBES2 PKCS#8 keys'); - case 'aes128-CBC-PAD': - case 'aes192-CBC-PAD': - case 'aes256-CBC-PAD': - $cipher = new AES('cbc'); - $cipher->setKeyLength(substr($algo, 3, 3)); - break; - default: - throw new UnsupportedAlgorithmException("$algo is not supported"); - } - - return $cipher; - } - - /** - * Initialize static variables - * - * @access private - */ - private static function initialize_static_variables() - { - if (!static::$childOIDsLoaded) { - ASN1::loadOIDs(is_array(static::OID_NAME) ? - array_combine(static::OID_NAME, static::OID_VALUE) : - [static::OID_NAME => static::OID_VALUE] - ); - static::$childOIDsLoaded = true; - } - if (!self::$oidsLoaded) { - // from https://tools.ietf.org/html/rfc2898 - ASN1::loadOIDs([ - // PBES1 encryption schemes - 'pbeWithMD2AndDES-CBC' => '1.2.840.113549.1.5.1', - 'pbeWithMD2AndRC2-CBC' => '1.2.840.113549.1.5.4', - 'pbeWithMD5AndDES-CBC' => '1.2.840.113549.1.5.3', - 'pbeWithMD5AndRC2-CBC' => '1.2.840.113549.1.5.6', - 'pbeWithSHA1AndDES-CBC'=> '1.2.840.113549.1.5.10', - 'pbeWithSHA1AndRC2-CBC'=> '1.2.840.113549.1.5.11', - - // from PKCS#12: - // https://tools.ietf.org/html/rfc7292 - 'pbeWithSHAAnd128BitRC4' => '1.2.840.113549.1.12.1.1', - 'pbeWithSHAAnd40BitRC4' => '1.2.840.113549.1.12.1.2', - 'pbeWithSHAAnd3-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.3', - 'pbeWithSHAAnd2-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.4', - 'pbeWithSHAAnd128BitRC2-CBC' => '1.2.840.113549.1.12.1.5', - 'pbeWithSHAAnd40BitRC2-CBC' => '1.2.840.113549.1.12.1.6', - - 'id-PBKDF2' => '1.2.840.113549.1.5.12', - 'id-PBES2' => '1.2.840.113549.1.5.13', - 'id-PBMAC1' => '1.2.840.113549.1.5.14', - - // from PKCS#5 v2.1: - // http://www.rsa.com/rsalabs/pkcs/files/h11302-wp-pkcs5v2-1-password-based-cryptography-standard.pdf - 'id-hmacWithSHA1' => '1.2.840.113549.2.7', - 'id-hmacWithSHA224' => '1.2.840.113549.2.8', - 'id-hmacWithSHA256' => '1.2.840.113549.2.9', - 'id-hmacWithSHA384'=> '1.2.840.113549.2.10', - 'id-hmacWithSHA512'=> '1.2.840.113549.2.11', - 'id-hmacWithSHA512-224'=> '1.2.840.113549.2.12', - 'id-hmacWithSHA512-256'=> '1.2.840.113549.2.13', - - 'desCBC' => '1.3.14.3.2.7', - 'des-EDE3-CBC' => '1.2.840.113549.3.7', - 'rc2CBC' => '1.2.840.113549.3.2', - 'rc5-CBC-PAD' => '1.2.840.113549.3.9', - - 'aes128-CBC-PAD' => '2.16.840.1.101.3.4.1.2', - 'aes192-CBC-PAD'=> '2.16.840.1.101.3.4.1.22', - 'aes256-CBC-PAD'=> '2.16.840.1.101.3.4.1.42' - ]); - self::$oidsLoaded = true; - } - } - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - protected static function load($key, $password = '') - { - $decoded = self::preParse($key); - - $meta = []; - - $decrypted = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP); - if (strlen($password) && is_array($decrypted)) { - $algorithm = $decrypted['encryptionAlgorithm']['algorithm']; - switch ($algorithm) { - // PBES1 - case 'pbeWithMD2AndDES-CBC': - case 'pbeWithMD2AndRC2-CBC': - case 'pbeWithMD5AndDES-CBC': - case 'pbeWithMD5AndRC2-CBC': - case 'pbeWithSHA1AndDES-CBC': - case 'pbeWithSHA1AndRC2-CBC': - case 'pbeWithSHAAnd3-KeyTripleDES-CBC': - case 'pbeWithSHAAnd2-KeyTripleDES-CBC': - case 'pbeWithSHAAnd128BitRC2-CBC': - case 'pbeWithSHAAnd40BitRC2-CBC': - case 'pbeWithSHAAnd128BitRC4': - case 'pbeWithSHAAnd40BitRC4': - $cipher = self::getPBES1EncryptionObject($algorithm); - $hash = self::getPBES1Hash($algorithm); - $kdf = self::getPBES1KDF($algorithm); - - $meta['meta']['algorithm'] = $algorithm; - - $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP)); - $iterationCount = (int) $iterationCount->toString(); - $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); - $key = $cipher->decrypt($decrypted['encryptedData']); - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER 2'); - } - - break; - case 'id-PBES2': - $meta['meta']['algorithm'] = $algorithm; - - $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); - extract($temp); - - $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); - $meta['meta']['cipher'] = $encryptionScheme['algorithm']; - - $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); - extract($temp); - - if (!$cipher instanceof RC2) { - $cipher->setIV($encryptionScheme['parameters']['octetString']); - } else { - $temp = ASN1::decodeBER($encryptionScheme['parameters']); - extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP)); - $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); - switch ($effectiveKeyLength) { - case 160: - $effectiveKeyLength = 40; - break; - case 120: - $effectiveKeyLength = 64; - break; - case 58: - $effectiveKeyLength = 128; - break; - //default: // should be >= 256 - } - $cipher->setIV($iv); - $cipher->setKeyLength($effectiveKeyLength); - } - - $meta['meta']['keyDerivationFunc'] = $keyDerivationFunc['algorithm']; - switch ($keyDerivationFunc['algorithm']) { - case 'id-PBKDF2': - $temp = ASN1::decodeBER($keyDerivationFunc['parameters']); - $prf = ['algorithm' => 'id-hmacWithSHA1']; - $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); - extract($params); - $meta['meta']['prf'] = $prf['algorithm']; - $hash = str_replace('-', '/', substr($prf['algorithm'], 11)); - $params = [ - $password, - 'pbkdf2', - $hash, - $salt, - (int) $iterationCount->toString() - ]; - if (isset($keyLength)) { - $params[] = (int) $keyLength->toString(); - } - $cipher->setPassword(...$params); - $key = $cipher->decrypt($decrypted['encryptedData']); - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER 3'); - } - break; - default: - throw new UnsupportedAlgorithmException('Only PBKDF2 is supported for PBES2 PKCS#8 keys'); - } - break; - case 'id-PBMAC1': - //$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - //$value = ASN1::asn1map($temp[0], Maps\PBMAC1params::MAP); - // since i can't find any implementation that does PBMAC1 it is unsupported - throw new UnsupportedAlgorithmException('Only PBES1 and PBES2 PKCS#8 keys are supported.'); - // at this point we'll assume that the key conforms to PublicKeyInfo - } - } - - $private = ASN1::asn1map($decoded[0], Maps\OneAsymmetricKey::MAP); - if (is_array($private)) { - if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) { - $temp = $decoded[0]['content'][1]['content'][1]; - $private['privateKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); - } - if (is_array(static::OID_NAME)) { - if (!in_array($private['privateKeyAlgorithm']['algorithm'], static::OID_NAME)) { - throw new UnsupportedAlgorithmException($private['privateKeyAlgorithm']['algorithm'] . ' is not a supported key type'); - } - } else { - if ($private['privateKeyAlgorithm']['algorithm'] != static::OID_NAME) { - throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $private['privateKeyAlgorithm']['algorithm'] . ' key'); - } - } - if (isset($private['publicKey'])) { - if ($private['publicKey'][0] != "\0") { - throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0])); - } - $private['publicKey'] = substr($private['publicKey'], 1); - } - return $private + $meta; - } - - // EncryptedPrivateKeyInfo and PublicKeyInfo have largely identical "signatures". the only difference - // is that the former has an octet string and the later has a bit string. the first byte of a bit - // string represents the number of bits in the last byte that are to be ignored but, currently, - // bit strings wanting a non-zero amount of bits trimmed are not supported - $public = ASN1::asn1map($decoded[0], Maps\PublicKeyInfo::MAP); - - if (is_array($public)) { - if ($public['publicKey'][0] != "\0") { - throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0])); - } - if (is_array(static::OID_NAME)) { - if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { - throw new UnsupportedAlgorithmException($public['publicKeyAlgorithm']['algorithm'] . ' is not a supported key type'); - } - } else { - if ($public['publicKeyAlgorithm']['algorithm'] != static::OID_NAME) { - throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $public['publicKeyAlgorithm']['algorithm'] . ' key'); - } - } - if (isset($public['publicKeyAlgorithm']['parameters']) && !$public['publicKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][0]['content'][1])) { - $temp = $decoded[0]['content'][0]['content'][1]; - $public['publicKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); - } - $public['publicKey'] = substr($public['publicKey'], 1); - return $public; - } - - throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); - } - - /** - * Wrap a private key appropriately - * - * @access public - * @param string $key - * @param string $attr - * @param mixed $params - * @param string $password - * @param string $oid optional - * @param string $publicKey optional - * @param array $options optional - * @return string - */ - protected static function wrapPrivateKey($key, $attr, $params, $password, $oid = null, $publicKey = '', array $options = []) - { - self::initialize_static_variables(); - - $key = [ - 'version' => 'v1', - 'privateKeyAlgorithm' => [ - 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid, - 'parameters' => $params - ], - 'privateKey' => $key - ]; - if (!empty($attr)) { - $key['attributes'] = $attr; - } - if (!empty($publicKey)) { - $key['version'] = 'v2'; - $key['publicKey'] = $publicKey; - } - $key = ASN1::encodeDER($key, Maps\OneAsymmetricKey::MAP); - if (!empty($password) && is_string($password)) { - $salt = Random::string(8); - - $iterationCount = isset($options['iterationCount']) ? $options['iterationCount'] : self::$defaultIterationCount; - $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; - $encryptionScheme = isset($options['encryptionScheme']) ? $options['encryptionScheme'] : self::$defaultEncryptionScheme; - $prf = isset($options['PRF']) ? $options['PRF'] : self::$defaultPRF; - - if ($encryptionAlgorithm == 'id-PBES2') { - $crypto = self::getPBES2EncryptionObject($encryptionScheme); - $hash = str_replace('-', '/', substr($prf, 11)); - $kdf = 'pbkdf2'; - $iv = Random::string($crypto->getBlockLength() >> 3); - - $PBKDF2params = [ - 'salt' => $salt, - 'iterationCount' => $iterationCount, - 'prf' => ['algorithm' => $prf, 'parameters' => null] - ]; - $PBKDF2params = ASN1::encodeDER($PBKDF2params, Maps\PBKDF2params::MAP); - - if (!$crypto instanceof RC2) { - $params = ['octetString' => $iv]; - } else { - $params = [ - 'rc2ParametersVersion' => 58, - 'iv' => $iv - ]; - $params = ASN1::encodeDER($params, Maps\RC2CBCParameter::MAP); - $params = new ASN1\Element($params); - } - - $params = [ - 'keyDerivationFunc' => [ - 'algorithm' => 'id-PBKDF2', - 'parameters' => new ASN1\Element($PBKDF2params) - ], - 'encryptionScheme' => [ - 'algorithm' => $encryptionScheme, - 'parameters' => $params - ] - ]; - $params = ASN1::encodeDER($params, Maps\PBES2params::MAP); - - $crypto->setIV($iv); - } else { - $crypto = self::getPBES1EncryptionObject($encryptionAlgorithm); - $hash = self::getPBES1Hash($encryptionAlgorithm); - $kdf = self::getPBES1KDF($encryptionAlgorithm); - - $params = [ - 'salt' => $salt, - 'iterationCount' => $iterationCount - ]; - $params = ASN1::encodeDER($params, Maps\PBEParameter::MAP); - } - $crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount); - $key = $crypto->encrypt($key); - - $key = [ - 'encryptionAlgorithm' => [ - 'algorithm' => $encryptionAlgorithm, - 'parameters' => new ASN1\Element($params) - ], - 'encryptedData' => $key - ]; - - $key = ASN1::encodeDER($key, Maps\EncryptedPrivateKeyInfo::MAP); - - return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . - chunk_split(Base64::encode($key), 64) . - "-----END ENCRYPTED PRIVATE KEY-----"; - } - - return "-----BEGIN PRIVATE KEY-----\r\n" . - chunk_split(Base64::encode($key), 64) . - "-----END PRIVATE KEY-----"; - } - - /** - * Wrap a public key appropriately - * - * @access public - * @param string $key - * @param mixed $params - * @param string $oid - * @return string - */ - protected static function wrapPublicKey($key, $params, $oid = null) - { - self::initialize_static_variables(); - - $key = [ - 'publicKeyAlgorithm' => [ - 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid, - 'parameters' => $params - ], - 'publicKey' => "\0" . $key - ]; - - $key = ASN1::encodeDER($key, Maps\PublicKeyInfo::MAP); - - return "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(Base64::encode($key), 64) . - "-----END PUBLIC KEY-----"; - } - - /** - * Perform some preliminary parsing of the key - * - * @param string $key - * @return array - */ - private static function preParse(&$key) - { - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (self::$format != self::MODE_DER) { - $decoded = ASN1::extractBER($key); - if ($decoded !== false) { - $key = $decoded; - } elseif (self::$format == self::MODE_PEM) { - throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); - } - } - - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - return $decoded; - } - - /** - * Returns the encryption parameters used by the key - * - * @param string $key - * @return array - */ - public static function extractEncryptionAlgorithm($key) - { - $decoded = self::preParse($key); - - $r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP); - if (!is_array($r)) { - throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); - } - - if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { - $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); - $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP); - - $kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; - switch ($kdf['algorithm']) { - case 'id-PBKDF2': - $decoded = ASN1::decodeBER($kdf['parameters']->element); - $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); - } - } - - return $r['encryptionAlgorithm']; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php deleted file mode 100644 index ccd06f75e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,261 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Crypt\AES; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\UnsupportedAlgorithmException; - -/** - * PuTTY Formatted Key Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class PuTTY -{ - /** - * Default comment - * - * @var string - * @access private - */ - private static $comment = 'phpseclib-generated-key'; - - /** - * Sets the default comment - * - * @access public - * @param string $comment - */ - public static function setComment($comment) - { - self::$comment = str_replace(["\r", "\n"], '', $comment); - } - - /** - * Generate a symmetric key for PuTTY keys - * - * @access public - * @param string $password - * @param int $length - * @return string - */ - private static function generateSymmetricKey($password, $length) - { - $symkey = ''; - $sequence = 0; - while (strlen($symkey) < $length) { - $temp = pack('Na*', $sequence++, $password); - $symkey.= Hex::decode(sha1($temp)); - } - return substr($symkey, 0, $length); - } - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password - * @return array - */ - public static function load($key, $password) - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== false) { - $lines = preg_split('#[\r\n]+#', $key); - switch (true) { - case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': - throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); - case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': - throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); - } - $lines = array_splice($lines, 1, -1); - $lines = array_map(function ($line) { - return rtrim($line, "\r\n"); - }, $lines); - $data = $current = ''; - $values = []; - $in_value = false; - foreach ($lines as $line) { - switch (true) { - case preg_match('#^(.*?): (.*)#', $line, $match): - $in_value = $line[strlen($line) - 1] == '\\'; - $current = strtolower($match[1]); - $values[$current] = $in_value ? substr($match[2], 0, -1) : $match[2]; - break; - case $in_value: - $in_value = $line[strlen($line) - 1] == '\\'; - $values[$current].= $in_value ? substr($line, 0, -1) : $line; - break; - default: - $data.= $line; - } - } - - $components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data); - if ($components === false) { - throw new \UnexpectedValueException('Unable to decode public key'); - } - $components+= $values; - $components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']); - - return $components; - } - - $components = []; - - $key = preg_split('#\r\n|\r|\n#', trim($key)); - $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0])); - $components['type'] = $type; - if (!in_array($type, static::$types)) { - $error = count(static::$types) == 1 ? - 'Only ' . static::$types[0] . ' keys are supported. ' : - ''; - throw new UnsupportedAlgorithmException($error . 'This is an unsupported ' . $type . ' key'); - } - $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); - $components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); - - $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); - $public = Base64::decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); - - $source = Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); - - extract(unpack('Nlength', Strings::shift($public, 4))); - $newtype = Strings::shift($public, $length); - if ($newtype != $type) { - throw new \RuntimeException('The binary type does not match the human readable type field'); - } - - $components['public'] = $public; - - $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4])); - $private = Base64::decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength)))); - - switch ($encryption) { - case 'aes256-cbc': - $symkey = self::generateSymmetricKey($password, 32); - $crypto = new AES('cbc'); - } - - $hashkey = 'putty-private-key-file-mac-key'; - - if ($encryption != 'none') { - $hashkey.= $password; - $crypto->setKey($symkey); - $crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3)); - $crypto->disablePadding(); - $private = $crypto->decrypt($private); - } - - $source.= Strings::packSSH2('s', $private); - - $hash = new Hash('sha1'); - $hash->setKey(sha1($hashkey, true)); - $hmac = trim(preg_replace('#Private-MAC: (.+)#', '$1', $key[$publicLength + $privateLength + 5])); - $hmac = Hex::decode($hmac); - - if (!hash_equals($hash->hash($source), $hmac)) { - throw new \UnexpectedValueException('MAC validation error'); - } - - $components['private'] = $private; - - return $components; - } - - /** - * Wrap a private key appropriately - * - * @access private - * @param string $public - * @param string $private - * @param string $type - * @param string $password - * @param array $options optional - * @return string - */ - protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) - { - $encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none'; - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - - $key = "PuTTY-User-Key-File-2: " . $type . "\r\nEncryption: "; $key.= $encryption; - $key.= "\r\nComment: " . $comment . "\r\n"; - - $public = Strings::packSSH2('s', $type) . $public; - - $source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public); - - $public = Base64::encode($public); - $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; - $key.= chunk_split($public, 64); - - if (empty($password) && !is_string($password)) { - $source.= Strings::packSSH2('s', $private); - $hashkey = 'putty-private-key-file-mac-key'; - } else { - $private.= Random::string(16 - (strlen($private) & 15)); - $source.= Strings::packSSH2('s', $private); - $crypto = new AES('cbc'); - - $crypto->setKey(self::generateSymmetricKey($password, 32)); - $crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3)); - $crypto->disablePadding(); - $private = $crypto->encrypt($private); - $hashkey = 'putty-private-key-file-mac-key' . $password; - } - - $private = Base64::encode($private); - $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; - $key.= chunk_split($private, 64); - $hash = new Hash('sha1'); - $hash->setKey(sha1($hashkey, true)); - $key.= 'Private-MAC: ' . Hex::encode($hash->hash($source)) . "\r\n"; - - return $key; - } - - /** - * Wrap a public key appropriately - * - * This is basically the format described in RFC 4716 (https://tools.ietf.org/html/rfc4716) - * - * @access private - * @param string $key - * @param string $type - * @return string - */ - protected static function wrapPublicKey($key, $type) - { - $key = pack('Na*a*', strlen($type), $type, $key); - $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . - 'Comment: "' . str_replace(['\\', '"'], ['\\\\', '\"'], self::$comment) . "\"\r\n" . - chunk_split(Base64::encode($key), 64) . - '---- END SSH2 PUBLIC KEY ----'; - return $key; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php deleted file mode 100644 index 13e56e3b5..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Signature; - -use phpseclib3\Math\BigInteger; - -/** - * Raw Signature Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class Raw -{ - /** - * Loads a signature - * - * @access public - * @param array $sig - * @return array|bool - */ - public static function load($sig) - { - switch (true) { - case !is_array($sig): - case !isset($sig['r']) || !isset($sig['s']): - case !$sig['r'] instanceof BigInteger: - case !$sig['s'] instanceof BigInteger: - return false; - } - - return [ - 'r' => $sig['r'], - 's' => $sig['s'] - ]; - } - - /** - * Returns a signature in the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - return compact('r', 's'); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php deleted file mode 100644 index 007123283..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * PrivateKey interface - * - * @package Common - * @author Jim Wigginton - * @access public - */ -interface PrivateKey -{ - public function sign($message); - //public function decrypt($ciphertext); - public function getPublicKey(); - public function toString($type, array $options = []); - public function withPassword($string); -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php deleted file mode 100644 index 0696de18c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * PublicKey interface - * - * @package Common - * @author Jim Wigginton - * @access public - */ -interface PublicKey -{ - public function verify($message, $signature); - //public function encrypt($plaintext); - public function toString($type, array $options = []); - public function getFingerprint($algorithm); -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php deleted file mode 100644 index f4d076d06..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * Base Class for all stream cipher classes - * - * @package StreamCipher - * @author Jim Wigginton - */ -abstract class StreamCipher extends SymmetricKey -{ - /** - * Block Length of the cipher - * - * Stream ciphers do not have a block size - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size - * @var int - * @access private - */ - protected $block_size = 0; - - /** - * Default Constructor. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @return \phpseclib3\Crypt\Common\StreamCipher - */ - public function __construct() - { - parent::__construct('stream'); - } - - /** - * Stream ciphers not use an IV - * - * @access public - * @return bool - */ - public function usesIV() - { - return false; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php deleted file mode 100644 index 76019337f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php +++ /dev/null @@ -1,3271 +0,0 @@ - - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -use phpseclib3\Crypt\Hash; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\BinaryField; -use phpseclib3\Math\PrimeField; -use phpseclib3\Exception\BadDecryptionException; -use phpseclib3\Exception\BadModeException; -use phpseclib3\Exception\InconsistentSetupException; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\UnsupportedAlgorithmException; - -/** - * Base Class for all \phpseclib3\Crypt\* cipher classes - * - * @package Base - * @author Jim Wigginton - * @author Hans-Juergen Petrich - */ -abstract class SymmetricKey -{ - /** - * Encrypt / decrypt using the Counter mode. - * - * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CTR = -1; - /** - * Encrypt / decrypt using the Electronic Code Book mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_ECB = 1; - /** - * Encrypt / decrypt using the Code Book Chaining mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CBC = 2; - /** - * Encrypt / decrypt using the Cipher Feedback mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CFB = 3; - /** - * Encrypt / decrypt using the Cipher Feedback mode (8bit) - * - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CFB8 = 38; - /** - * Encrypt / decrypt using the Output Feedback mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_OFB = 4; - /** - * Encrypt / decrypt using Galois/Counter mode. - * - * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_GCM = 5; - /** - * Encrypt / decrypt using streaming mode. - * - * @access public - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_STREAM = 6; - - /** - * Mode Map - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const MODE_MAP = [ - 'ctr' => self::MODE_CTR, - 'ecb' => self::MODE_ECB, - 'cbc' => self::MODE_CBC, - 'cfb' => self::MODE_CFB, - 'cfb8' => self::MODE_CFB8, - 'ofb' => self::MODE_OFB, - 'gcm' => self::MODE_GCM, - 'stream' => self::MODE_STREAM - ]; - - /** - * Base value for the internal implementation $engine switch - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_INTERNAL = 1; - /** - * Base value for the eval() implementation $engine switch - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_EVAL = 2; - /** - * Base value for the mcrypt implementation $engine switch - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_MCRYPT = 3; - /** - * Base value for the openssl implementation $engine switch - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_OPENSSL = 4; - /** - * Base value for the libsodium implementation $engine switch - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_LIBSODIUM = 5; - /** - * Base value for the openssl / gcm implementation $engine switch - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_OPENSSL_GCM = 6; - - /** - * Engine Reverse Map - * - * @access private - * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() - */ - const ENGINE_MAP = [ - self::ENGINE_INTERNAL => 'PHP', - self::ENGINE_EVAL => 'Eval', - self::ENGINE_MCRYPT => 'mcrypt', - self::ENGINE_OPENSSL => 'OpenSSL', - self::ENGINE_LIBSODIUM => 'libsodium', - self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)' - ]; - - /** - * The Encryption Mode - * - * @see self::__construct() - * @var int - * @access private - */ - protected $mode; - - /** - * The Block Length of the block cipher - * - * @var int - * @access private - */ - protected $block_size = 16; - - /** - * The Key - * - * @see self::setKey() - * @var string - * @access private - */ - protected $key = false; - - /** - * The Initialization Vector - * - * @see self::setIV() - * @var string - * @access private - */ - private $iv = false; - - /** - * A "sliding" Initialization Vector - * - * @see self::enableContinuousBuffer() - * @see self::clearBuffers() - * @var string - * @access private - */ - protected $encryptIV; - - /** - * A "sliding" Initialization Vector - * - * @see self::enableContinuousBuffer() - * @see self::clearBuffers() - * @var string - * @access private - */ - protected $decryptIV; - - /** - * Continuous Buffer status - * - * @see self::enableContinuousBuffer() - * @var bool - * @access private - */ - protected $continuousBuffer = false; - - /** - * Encryption buffer for CTR, OFB and CFB modes - * - * @see self::encrypt() - * @see self::clearBuffers() - * @var array - * @access private - */ - protected $enbuffer; - - /** - * Decryption buffer for CTR, OFB and CFB modes - * - * @see self::decrypt() - * @see self::clearBuffers() - * @var array - * @access private - */ - protected $debuffer; - - /** - * mcrypt resource for encryption - * - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. - * - * @see self::encrypt() - * @var resource - * @access private - */ - private $enmcrypt; - - /** - * mcrypt resource for decryption - * - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. - * - * @see self::decrypt() - * @var resource - * @access private - */ - private $demcrypt; - - /** - * Does the enmcrypt resource need to be (re)initialized? - * - * @see \phpseclib3\Crypt\Twofish::setKey() - * @see \phpseclib3\Crypt\Twofish::setIV() - * @var bool - * @access private - */ - private $enchanged = true; - - /** - * Does the demcrypt resource need to be (re)initialized? - * - * @see \phpseclib3\Crypt\Twofish::setKey() - * @see \phpseclib3\Crypt\Twofish::setIV() - * @var bool - * @access private - */ - private $dechanged = true; - - /** - * mcrypt resource for CFB mode - * - * mcrypt's CFB mode, in (and only in) buffered context, - * is broken, so phpseclib implements the CFB mode by it self, - * even when the mcrypt php extension is available. - * - * In order to do the CFB-mode work (fast) phpseclib - * use a separate ECB-mode mcrypt resource. - * - * @link http://phpseclib.sourceforge.net/cfb-demo.phps - * @see self::encrypt() - * @see self::decrypt() - * @see self::setupMcrypt() - * @var resource - * @access private - */ - private $ecb; - - /** - * Optimizing value while CFB-encrypting - * - * Only relevant if $continuousBuffer enabled - * and $engine == self::ENGINE_MCRYPT - * - * It's faster to re-init $enmcrypt if - * $buffer bytes > $cfb_init_len than - * using the $ecb resource furthermore. - * - * This value depends of the chosen cipher - * and the time it would be needed for it's - * initialization [by mcrypt_generic_init()] - * which, typically, depends on the complexity - * on its internaly Key-expanding algorithm. - * - * @see self::encrypt() - * @var int - * @access private - */ - protected $cfb_init_len = 600; - - /** - * Does internal cipher state need to be (re)initialized? - * - * @see self::setKey() - * @see self::setIV() - * @see self::disableContinuousBuffer() - * @var bool - * @access private - */ - protected $changed = true; - - /** - * Does Eval engie need to be (re)initialized? - * - * @see self::setup() - * @var bool - * @access private - */ - protected $nonIVChanged = true; - - /** - * Padding status - * - * @see self::enablePadding() - * @var bool - * @access private - */ - private $padding = true; - - /** - * Is the mode one that is paddable? - * - * @see self::__construct() - * @var bool - * @access private - */ - private $paddable = false; - - /** - * Holds which crypt engine internaly should be use, - * which will be determined automatically on __construct() - * - * Currently available $engines are: - * - self::ENGINE_LIBSODIUM (very fast, php-extension: libsodium, extension_loaded('libsodium') required) - * - self::ENGINE_OPENSSL_GCM (very fast, php-extension: openssl, extension_loaded('openssl') required) - * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) - * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) - * - self::ENGINE_EVAL (medium, pure php-engine, no php-extension required) - * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) - * - * @see self::setEngine() - * @see self::encrypt() - * @see self::decrypt() - * @var int - * @access private - */ - protected $engine; - - /** - * Holds the preferred crypt engine - * - * @see self::setEngine() - * @see self::setPreferredEngine() - * @var int - * @access private - */ - private $preferredEngine; - - /** - * The mcrypt specific name of the cipher - * - * Only used if $engine == self::ENGINE_MCRYPT - * - * @link http://www.php.net/mcrypt_module_open - * @link http://www.php.net/mcrypt_list_algorithms - * @see self::setupMcrypt() - * @var string - * @access private - */ - protected $cipher_name_mcrypt; - - /** - * The openssl specific name of the cipher - * - * Only used if $engine == self::ENGINE_OPENSSL - * - * @link http://www.php.net/openssl-get-cipher-methods - * @var string - * @access private - */ - protected $cipher_name_openssl; - - /** - * The openssl specific name of the cipher in ECB mode - * - * If OpenSSL does not support the mode we're trying to use (CTR) - * it can still be emulated with ECB mode. - * - * @link http://www.php.net/openssl-get-cipher-methods - * @var string - * @access private - */ - protected static $cipher_name_openssl_ecb; - - /** - * The default salt used by setPassword() - * - * @see self::setPassword() - * @var string - * @access private - */ - private $password_default_salt = 'phpseclib/salt'; - - /** - * The name of the performance-optimized callback function - * - * Used by encrypt() / decrypt() - * only if $engine == self::ENGINE_INTERNAL - * - * @see self::encrypt() - * @see self::decrypt() - * @see self::setupInlineCrypt() - * @var Callback - * @access private - */ - protected $inline_crypt; - - /** - * If OpenSSL can be used in ECB but not in CTR we can emulate CTR - * - * @see self::openssl_ctr_process() - * @var bool - * @access private - */ - private $openssl_emulate_ctr = false; - - /** - * Don't truncate / null pad key - * - * @see self::clearBuffers() - * @var bool - * @access private - */ - private $skip_key_adjustment = false; - - /** - * Has the key length explicitly been set or should it be derived from the key, itself? - * - * @see self::setKeyLength() - * @var bool - * @access private - */ - protected $explicit_key_length = false; - - /** - * Hash subkey for GHASH - * - * @see self::setupGCM() - * @see self::ghash() - * @var BinaryField\Integer - * @access private - */ - private $h; - - /** - * Additional authenticated data - * - * @var string - * @access private - */ - protected $aad = ''; - - /** - * Authentication Tag produced after a round of encryption - * - * @var string - * @access private - */ - protected $newtag = false; - - /** - * Authentication Tag to be verified during decryption - * - * @var string - * @access private - */ - protected $oldtag = false; - - /** - * GCM Binary Field - * - * @see self::__construct() - * @see self::ghash() - * @var BinaryField - * @access private - */ - private static $gcmField; - - /** - * Poly1305 Prime Field - * - * @see self::enablePoly1305() - * @see self::poly1305() - * @var PrimeField - * @access private - */ - private static $poly1305Field; - - /** - * Poly1305 Key - * - * @see self::setPoly1305Key() - * @see self::poly1305() - * @var string - * @access private - */ - protected $poly1305Key; - - /** - * Poly1305 Flag - * - * @see self::setPoly1305Key() - * @see self::enablePoly1305() - * @var boolean - * @access private - */ - protected $usePoly1305 = false; - - /** - * The Original Initialization Vector - * - * GCM uses the nonce to build the IV but we want to be able to distinguish between nonce-derived - * IV's and user-set IV's - * - * @see self::setIV() - * @var string - * @access private - */ - private $origIV = false; - - /** - * Nonce - * - * Only used with GCM. We could re-use setIV() but nonce's can be of a different length and - * toggling between GCM and other modes could be more complicated if we re-used setIV() - * - * @see self::setNonce() - * @var string - * @access private - */ - protected $nonce = false; - - /** - * Default Constructor. - * - * $mode could be: - * - * - ecb - * - * - cbc - * - * - ctr - * - * - cfb - * - * - cfb8 - * - * - ofb - * - * - gcm - * - * @param string $mode - * @access public - * @throws BadModeException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - $mode = strtolower($mode); - // necessary because of 5.6 compatibility; we can't do isset(self::MODE_MAP[$mode]) in 5.6 - $map = self::MODE_MAP; - if (!isset($map[$mode])) { - throw new BadModeException('No valid mode has been specified'); - } - - $mode = self::MODE_MAP[$mode]; - - // $mode dependent settings - switch ($mode) { - case self::MODE_ECB: - case self::MODE_CBC: - $this->paddable = true; - break; - case self::MODE_CTR: - case self::MODE_CFB: - case self::MODE_CFB8: - case self::MODE_OFB: - case self::MODE_STREAM: - $this->paddable = false; - break; - case self::MODE_GCM: - if ($this->block_size != 16) { - throw new BadModeException('GCM is only valid for block ciphers with a block size of 128 bits'); - } - if (!isset(self::$gcmField)) { - self::$gcmField = new BinaryField(128, 7, 2, 1, 0); - } - $this->paddable = false; - break; - default: - throw new BadModeException('No valid mode has been specified'); - } - - $this->mode = $mode; - } - - /** - * Sets the initialization vector. - * - * setIV() is not required when ecb or gcm modes are being used. - * - * {@internal Can be overwritten by a sub class, but does not have to be} - * - * @access public - * @param string $iv - * @throws \LengthException if the IV length isn't equal to the block size - * @throws \BadMethodCallException if an IV is provided when one shouldn't be - */ - public function setIV($iv) - { - if ($this->mode == self::MODE_ECB) { - throw new \BadMethodCallException('This mode does not require an IV.'); - } - - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('Use setNonce instead'); - } - - if (!$this->usesIV()) { - throw new \BadMethodCallException('This algorithm does not use an IV.'); - } - - if (strlen($iv) != $this->block_size) { - throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required'); - } - - $this->iv = $this->origIV = $iv; - $this->changed = true; - } - - /** - * Enables Poly1305 mode. - * - * Once enabled Poly1305 cannot be disabled. - * - * @access public - * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode - */ - public function enablePoly1305() - { - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); - } - - $this->usePoly1305 = true; - } - - /** - * Enables Poly1305 mode. - * - * Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key - * will be made. - * - * @access public - * @param string $key optional - * @throws \LengthException if the key isn't long enough - * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode - */ - public function setPoly1305Key($key = null) - { - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); - } - - if (!is_string($key) || strlen($key) != 32) { - throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); - } - - if (!isset(self::$poly1305Field)) { - // 2^130-5 - self::$poly1305Field = new PrimeField(new BigInteger('3fffffffffffffffffffffffffffffffb', 16)); - } - - $this->poly1305Key = $key; - $this->usePoly1305 = true; - } - - /** - * Sets the nonce. - * - * setNonce() is only required when gcm is used - * - * @access public - * @param string $nonce - * @throws \BadMethodCallException if an nonce is provided when one shouldn't be - */ - public function setNonce($nonce) - { - if ($this->mode != self::MODE_GCM) { - throw new \BadMethodCallException('Nonces are only used in GCM mode.'); - } - - $this->nonce = $nonce; - $this->setEngine(); - } - - /** - * Sets additional authenticated data - * - * setAAD() is only used by gcm or in poly1305 mode - * - * @access public - * @param string $aad - * @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized - */ - public function setAAD($aad) - { - if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { - throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); - } - - $this->aad = $aad; - } - - /** - * Returns whether or not the algorithm uses an IV - * - * @access public - * @return bool - */ - public function usesIV() - { - return $this->mode != self::MODE_GCM && $this->mode != self::MODE_ECB; - } - - /** - * Returns whether or not the algorithm uses a nonce - * - * @access public - * @return bool - */ - public function usesNonce() - { - return $this->mode == self::MODE_GCM; - } - - /** - * Returns the current key length in bits - * - * @access public - * @return int - */ - public function getKeyLength() - { - return $this->key_length << 3; - } - - /** - * Returns the current block length in bits - * - * @access public - * @return int - */ - public function getBlockLength() - { - return $this->block_size << 3; - } - - /** - * Returns the current block length in bytes - * - * @access public - * @return int - */ - public function getBlockLengthInBytes() - { - return $this->block_size; - } - - /** - * Sets the key length. - * - * Keys with explicitly set lengths need to be treated accordingly - * - * @access public - * @param int $length - */ - public function setKeyLength($length) - { - $this->explicit_key_length = $length >> 3; - - if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) { - $this->key = false; - throw new InconsistentSetupException('Key has already been set and is not ' .$this->explicit_key_length . ' bytes long'); - } - } - - /** - * Sets the key. - * - * The min/max length(s) of the key depends on the cipher which is used. - * If the key not fits the length(s) of the cipher it will paded with null bytes - * up to the closest valid key length. If the key is more than max length, - * we trim the excess bits. - * - * If the key is not explicitly set, it'll be assumed to be all null bytes. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @access public - * @param string $key - */ - public function setKey($key) - { - if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { - throw new InconsistentSetupException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); - } - - $this->key = $key; - $this->key_length = strlen($key); - $this->setEngine(); - } - - /** - * Sets the password. - * - * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: - * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: - * $hash, $salt, $count, $dkLen - * - * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see Crypt/Hash.php - * @param string $password - * @param string $method - * @param string[] ...$func_args - * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length - * @return bool - * @access public - */ - public function setPassword($password, $method = 'pbkdf2', ...$func_args) - { - $key = ''; - - $method = strtolower($method); - switch ($method) { - case 'pkcs12': // from https://tools.ietf.org/html/rfc7292#appendix-B.2 - case 'pbkdf1': - case 'pbkdf2': - // Hash function - $hash = isset($func_args[0]) ? strtolower($func_args[0]) : 'sha1'; - $hashObj = new Hash(); - $hashObj->setHash($hash); - - // WPA and WPA2 use the SSID as the salt - $salt = isset($func_args[1]) ? $func_args[1] : $this->password_default_salt; - - // RFC2898#section-4.2 uses 1,000 iterations by default - // WPA and WPA2 use 4,096. - $count = isset($func_args[2]) ? $func_args[2] : 1000; - - // Keylength - if (isset($func_args[3])) { - if ($func_args[3] <= 0) { - throw new \LengthException('Derived key length cannot be longer 0 or less'); - } - $dkLen = $func_args[3]; - } else { - $key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length; - $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length; - } - - switch (true) { - case $method == 'pkcs12': - /* - In this specification, however, all passwords are created from - BMPStrings with a NULL terminator. This means that each character in - the original BMPString is encoded in 2 bytes in big-endian format - (most-significant byte first). There are no Unicode byte order - marks. The 2 bytes produced from the last character in the BMPString - are followed by 2 additional bytes with the value 0x00. - - -- https://tools.ietf.org/html/rfc7292#appendix-B.1 - */ - $password = "\0". chunk_split($password, 1, "\0") . "\0"; - - /* - This standard specifies 3 different values for the ID byte mentioned - above: - - 1. If ID=1, then the pseudorandom bits being produced are to be used - as key material for performing encryption or decryption. - - 2. If ID=2, then the pseudorandom bits being produced are to be used - as an IV (Initial Value) for encryption or decryption. - - 3. If ID=3, then the pseudorandom bits being produced are to be used - as an integrity key for MACing. - */ - // Construct a string, D (the "diversifier"), by concatenating v/8 - // copies of ID. - $blockLength = $hashObj->getBlockLengthInBytes(); - $d1 = str_repeat(chr(1), $blockLength); - $d2 = str_repeat(chr(2), $blockLength); - $s = ''; - if (strlen($salt)) { - while (strlen($s) < $blockLength) { - $s.= $salt; - } - } - $s = substr($s, 0, $blockLength); - - $p = ''; - if (strlen($password)) { - while (strlen($p) < $blockLength) { - $p.= $password; - } - } - $p = substr($p, 0, $blockLength); - - $i = $s . $p; - - $this->setKey(self::pkcs12helper($dkLen, $hashObj, $i, $d1, $count)); - if ($this->usesIV()) { - $this->setIV(self::pkcs12helper($this->block_size, $hashObj, $i, $d2, $count)); - } - - return true; - case $method == 'pbkdf1': - if ($dkLen > $hashObj->getLengthInBytes()) { - throw new \LengthException('Derived key length cannot be longer than the hash length'); - } - $t = $password . $salt; - for ($i = 0; $i < $count; ++$i) { - $t = $hashObj->hash($t); - } - $key = substr($t, 0, $dkLen); - - $this->setKey(substr($key, 0, $dkLen >> 1)); - if ($this->usesIV()) { - $this->setIV(substr($key, $dkLen >> 1)); - } - - return true; - case !in_array($hash, hash_algos()): - $i = 1; - $hashObj->setKey($password); - while (strlen($key) < $dkLen) { - $f = $u = $hashObj->hash($salt . pack('N', $i++)); - for ($j = 2; $j <= $count; ++$j) { - $u = $hashObj->hash($u); - $f^= $u; - } - $key.= $f; - } - $key = substr($key, 0, $dkLen); - break; - default: - $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true); - } - break; - default: - throw new UnsupportedAlgorithmException($method . ' is not a supported password hashing method'); - } - - $this->setKey($key); - - return true; - } - - /** - * PKCS#12 KDF Helper Function - * - * As discussed here: - * - * {@link https://tools.ietf.org/html/rfc7292#appendix-B} - * - * @see self::setPassword() - * @access private - * @param int $n - * @param \phpseclib3\Crypt\Hash $hashObj - * @param string $i - * @param string $d - * @param int $count - * @return string $a - */ - private static function pkcs12helper($n, $hashObj, $i, $d, $count) - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - $blockLength = $hashObj->getBlockLength() >> 3; - - $c = ceil($n / $hashObj->getLengthInBytes()); - $a = ''; - for ($j = 1; $j <= $c; $j++) { - $ai = $d . $i; - for ($k = 0; $k < $count; $k++) { - $ai = $hashObj->hash($ai); - } - $b = ''; - while (strlen($b) < $blockLength) { - $b.= $ai; - } - $b = substr($b, 0, $blockLength); - $b = new BigInteger($b, 256); - $newi = ''; - for ($k = 0; $k < strlen($i); $k+= $blockLength) { - $temp = substr($i, $k, $blockLength); - $temp = new BigInteger($temp, 256); - $temp->setPrecision($blockLength << 3); - $temp = $temp->add($b); - $temp = $temp->add($one); - $newi.= $temp->toBytes(false); - } - $i = $newi; - $a.= $ai; - } - - return substr($a, 0, $n); - } - - /** - * Encrypts a message. - * - * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher - * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's - * necessary are discussed in the following - * URL: - * - * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} - * - * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. - * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that - * length. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::decrypt() - * @access public - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - if ($this->paddable) { - $plaintext = $this->pad($plaintext); - } - - $this->setup(); - - if ($this->mode == self::MODE_GCM) { - $oldIV = $this->iv; - Strings::increment_str($this->iv); - $cipher = new static('ctr'); - $cipher->setKey($this->key); - $cipher->setIV($this->iv); - $ciphertext = $cipher->encrypt($plaintext); - - $s = $this->ghash( - self::nullPad128($this->aad) . - self::nullPad128($ciphertext) . - self::len64($this->aad) . - self::len64($ciphertext) - ); - $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; - $this->newtag = $cipher->encrypt($s); - return $ciphertext; - } - - if (isset($this->poly1305Key)) { - $cipher = clone $this; - unset($cipher->poly1305Key); - $this->usePoly1305 = false; - $ciphertext = $cipher->encrypt($plaintext); - $this->newtag = $this->poly1305($ciphertext); - return $ciphertext; - } - - if ($this->engine === self::ENGINE_OPENSSL) { - switch ($this->mode) { - case self::MODE_STREAM: - return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - case self::MODE_ECB: - return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - case self::MODE_CBC: - $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); - if ($this->continuousBuffer) { - $this->encryptIV = substr($result, -$this->block_size); - } - return $result; - case self::MODE_CTR: - return $this->openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); - case self::MODE_CFB: - // cfb loosely routines inspired by openssl's: - // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} - $ciphertext = ''; - if ($this->continuousBuffer) { - $iv = &$this->encryptIV; - $pos = &$this->enbuffer['pos']; - } else { - $iv = $this->encryptIV; - $pos = 0; - } - $len = strlen($plaintext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $this->block_size - $pos; - if ($len >= $max) { - $i = $max; - $len-= $max; - $pos = 0; - } else { - $i = $len; - $pos+= $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $ciphertext = substr($iv, $orig_pos) ^ $plaintext; - $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); - $plaintext = substr($plaintext, $i); - } - - $overflow = $len % $this->block_size; - - if ($overflow) { - $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $iv = Strings::pop($ciphertext, $this->block_size); - - $size = $len - $overflow; - $block = $iv ^ substr($plaintext, -$overflow); - $iv = substr_replace($iv, $block, 0, $overflow); - $ciphertext.= $block; - $pos = $overflow; - } elseif ($len) { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $iv = substr($ciphertext, -$this->block_size); - } - - return $ciphertext; - case self::MODE_CFB8: - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); - if ($this->continuousBuffer) { - if (($len = strlen($ciphertext)) >= $this->block_size) { - $this->encryptIV = substr($ciphertext, -$this->block_size); - } else { - $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); - } - } - return $ciphertext; - case self::MODE_OFB: - return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); - } - } - - if ($this->engine === self::ENGINE_MCRYPT) { - if ($this->enchanged) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); - $this->enchanged = false; - } - - // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} - // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's - // rewritten CFB implementation the above outputs the same thing twice. - if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { - $block_size = $this->block_size; - $iv = &$this->encryptIV; - $pos = &$this->enbuffer['pos']; - $len = strlen($plaintext); - $ciphertext = ''; - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len-= $max; - $pos = 0; - } else { - $i = $len; - $pos+= $len; - $len = 0; - } - $ciphertext = substr($iv, $orig_pos) ^ $plaintext; - $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); - $this->enbuffer['enmcrypt_init'] = true; - } - if ($len >= $block_size) { - if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { - if ($this->enbuffer['enmcrypt_init'] === true) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $iv); - $this->enbuffer['enmcrypt_init'] = false; - } - $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); - $iv = substr($ciphertext, -$block_size); - $len%= $block_size; - } else { - while ($len >= $block_size) { - $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); - $ciphertext.= $iv; - $len-= $block_size; - $i+= $block_size; - } - } - } - - if ($len) { - $iv = @mcrypt_generic($this->ecb, $iv); - $block = $iv ^ substr($plaintext, -$len); - $iv = substr_replace($iv, $block, 0, $len); - $ciphertext.= $block; - $pos = $len; - } - - return $ciphertext; - } - - $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext); - - if (!$this->continuousBuffer) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); - } - - return $ciphertext; - } - - if ($this->engine === self::ENGINE_EVAL) { - $inline = $this->inline_crypt; - return $inline('encrypt', $plaintext); - } - - $buffer = &$this->enbuffer; - $block_size = $this->block_size; - $ciphertext = ''; - switch ($this->mode) { - case self::MODE_ECB: - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $ciphertext.= $this->encryptBlock(substr($plaintext, $i, $block_size)); - } - break; - case self::MODE_CBC: - $xor = $this->encryptIV; - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $block = substr($plaintext, $i, $block_size); - $block = $this->encryptBlock($block ^ $xor); - $xor = $block; - $ciphertext.= $block; - } - if ($this->continuousBuffer) { - $this->encryptIV = $xor; - } - break; - case self::MODE_CTR: - $xor = $this->encryptIV; - if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'].= $this->encryptBlock($xor); - } - Strings::increment_str($xor); - $key = Strings::shift($buffer['ciphertext'], $block_size); - $ciphertext.= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $block = substr($plaintext, $i, $block_size); - $key = $this->encryptBlock($xor); - Strings::increment_str($xor); - $ciphertext.= $block ^ $key; - } - } - if ($this->continuousBuffer) { - $this->encryptIV = $xor; - if ($start = strlen($plaintext) % $block_size) { - $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; - } - } - break; - case self::MODE_CFB: - // cfb loosely routines inspired by openssl's: - // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} - if ($this->continuousBuffer) { - $iv = &$this->encryptIV; - $pos = &$buffer['pos']; - } else { - $iv = $this->encryptIV; - $pos = 0; - } - $len = strlen($plaintext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len-= $max; - $pos = 0; - } else { - $i = $len; - $pos+= $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $ciphertext = substr($iv, $orig_pos) ^ $plaintext; - $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); - } - while ($len >= $block_size) { - $iv = $this->encryptBlock($iv) ^ substr($plaintext, $i, $block_size); - $ciphertext.= $iv; - $len-= $block_size; - $i+= $block_size; - } - if ($len) { - $iv = $this->encryptBlock($iv); - $block = $iv ^ substr($plaintext, $i); - $iv = substr_replace($iv, $block, 0, $len); - $ciphertext.= $block; - $pos = $len; - } - break; - case self::MODE_CFB8: - $ciphertext = ''; - $len = strlen($plaintext); - $iv = $this->encryptIV; - - for ($i = 0; $i < $len; ++$i) { - $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); - $iv = substr($iv, 1) . $c; - } - - if ($this->continuousBuffer) { - if ($len >= $block_size) { - $this->encryptIV = substr($ciphertext, -$block_size); - } else { - $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len); - } - } - break; - case self::MODE_OFB: - $xor = $this->encryptIV; - if (strlen($buffer['xor'])) { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['xor'])) { - $xor = $this->encryptBlock($xor); - $buffer['xor'].= $xor; - } - $key = Strings::shift($buffer['xor'], $block_size); - $ciphertext.= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $xor = $this->encryptBlock($xor); - $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor; - } - $key = $xor; - } - if ($this->continuousBuffer) { - $this->encryptIV = $xor; - if ($start = strlen($plaintext) % $block_size) { - $buffer['xor'] = substr($key, $start) . $buffer['xor']; - } - } - break; - case self::MODE_STREAM: - $ciphertext = $this->encryptBlock($plaintext); - break; - } - - return $ciphertext; - } - - /** - * Decrypts a message. - * - * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until - * it is. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::encrypt() - * @access public - * @param string $ciphertext - * @return string $plaintext - * @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size - */ - public function decrypt($ciphertext) - { - if ($this->paddable && strlen($ciphertext) % $this->block_size) { - throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); - } - - $this->setup(); - - if ($this->mode == self::MODE_GCM || isset($this->poly1305Key)) { - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - - if (isset($this->poly1305Key)) { - $newtag = $this->poly1305($ciphertext); - } else { - $oldIV = $this->iv; - Strings::increment_str($this->iv); - $cipher = new static('ctr'); - $cipher->setKey($this->key); - $cipher->setIV($this->iv); - $plaintext = $cipher->decrypt($ciphertext); - - $s = $this->ghash( - self::nullPad128($this->aad) . - self::nullPad128($ciphertext) . - self::len64($this->aad) . - self::len64($ciphertext) - ); - $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; - $newtag = $cipher->encrypt($s); - } - if ($this->oldtag != substr($newtag, 0, strlen($newtag))) { - $cipher = clone $this; - unset($cipher->poly1305Key); - $this->usePoly1305 = false; - $plaintext = $cipher->decrypt($ciphertext); - $this->oldtag = false; - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - $this->oldtag = false; - return $plaintext; - } - - if ($this->engine === self::ENGINE_OPENSSL) { - switch ($this->mode) { - case self::MODE_STREAM: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - break; - case self::MODE_ECB: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - break; - case self::MODE_CBC: - $offset = $this->block_size; - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); - if ($this->continuousBuffer) { - $this->decryptIV = substr($ciphertext, -$offset, $this->block_size); - } - break; - case self::MODE_CTR: - $plaintext = $this->openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); - break; - case self::MODE_CFB: - // cfb loosely routines inspired by openssl's: - // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} - $plaintext = ''; - if ($this->continuousBuffer) { - $iv = &$this->decryptIV; - $pos = &$this->buffer['pos']; - } else { - $iv = $this->decryptIV; - $pos = 0; - } - $len = strlen($ciphertext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $this->block_size - $pos; - if ($len >= $max) { - $i = $max; - $len-= $max; - $pos = 0; - } else { - $i = $len; - $pos+= $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize - $plaintext = substr($iv, $orig_pos) ^ $ciphertext; - $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); - $ciphertext = substr($ciphertext, $i); - } - $overflow = $len % $this->block_size; - if ($overflow) { - $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - if ($len - $overflow) { - $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); - } - $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $plaintext.= $iv ^ substr($ciphertext, -$overflow); - $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); - $pos = $overflow; - } elseif ($len) { - $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $iv = substr($ciphertext, -$this->block_size); - } - break; - case self::MODE_CFB8: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); - if ($this->continuousBuffer) { - if (($len = strlen($ciphertext)) >= $this->block_size) { - $this->decryptIV = substr($ciphertext, -$this->block_size); - } else { - $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); - } - } - break; - case self::MODE_OFB: - $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); - } - - return $this->paddable ? $this->unpad($plaintext) : $plaintext; - } - - if ($this->engine === self::ENGINE_MCRYPT) { - $block_size = $this->block_size; - if ($this->dechanged) { - @mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); - $this->dechanged = false; - } - - if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { - $iv = &$this->decryptIV; - $pos = &$this->debuffer['pos']; - $len = strlen($ciphertext); - $plaintext = ''; - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len-= $max; - $pos = 0; - } else { - $i = $len; - $pos+= $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $plaintext = substr($iv, $orig_pos) ^ $ciphertext; - $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); - } - if ($len >= $block_size) { - $cb = substr($ciphertext, $i, $len - $len % $block_size); - $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; - $iv = substr($cb, -$block_size); - $len%= $block_size; - } - if ($len) { - $iv = @mcrypt_generic($this->ecb, $iv); - $plaintext.= $iv ^ substr($ciphertext, -$len); - $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); - $pos = $len; - } - - return $plaintext; - } - - $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext); - - if (!$this->continuousBuffer) { - @mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); - } - - return $this->paddable ? $this->unpad($plaintext) : $plaintext; - } - - if ($this->engine === self::ENGINE_EVAL) { - $inline = $this->inline_crypt; - return $inline('decrypt', $ciphertext); - } - - $block_size = $this->block_size; - - $buffer = &$this->debuffer; - $plaintext = ''; - switch ($this->mode) { - case self::MODE_ECB: - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $plaintext.= $this->decryptBlock(substr($ciphertext, $i, $block_size)); - } - break; - case self::MODE_CBC: - $xor = $this->decryptIV; - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $block = substr($ciphertext, $i, $block_size); - $plaintext.= $this->decryptBlock($block) ^ $xor; - $xor = $block; - } - if ($this->continuousBuffer) { - $this->decryptIV = $xor; - } - break; - case self::MODE_CTR: - $xor = $this->decryptIV; - if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $block = substr($ciphertext, $i, $block_size); - if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'].= $this->encryptBlock($xor); - } - Strings::increment_str($xor); - $key = Strings::shift($buffer['ciphertext'], $block_size); - $plaintext.= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $block = substr($ciphertext, $i, $block_size); - $key = $this->encryptBlock($xor); - Strings::increment_str($xor); - $plaintext.= $block ^ $key; - } - } - if ($this->continuousBuffer) { - $this->decryptIV = $xor; - if ($start = strlen($ciphertext) % $block_size) { - $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; - } - } - break; - case self::MODE_CFB: - if ($this->continuousBuffer) { - $iv = &$this->decryptIV; - $pos = &$buffer['pos']; - } else { - $iv = $this->decryptIV; - $pos = 0; - } - $len = strlen($ciphertext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len-= $max; - $pos = 0; - } else { - $i = $len; - $pos+= $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $plaintext = substr($iv, $orig_pos) ^ $ciphertext; - $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); - } - while ($len >= $block_size) { - $iv = $this->encryptBlock($iv); - $cb = substr($ciphertext, $i, $block_size); - $plaintext.= $iv ^ $cb; - $iv = $cb; - $len-= $block_size; - $i+= $block_size; - } - if ($len) { - $iv = $this->encryptBlock($iv); - $plaintext.= $iv ^ substr($ciphertext, $i); - $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len); - $pos = $len; - } - break; - case self::MODE_CFB8: - $plaintext = ''; - $len = strlen($ciphertext); - $iv = $this->decryptIV; - - for ($i = 0; $i < $len; ++$i) { - $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); - $iv = substr($iv, 1) . $ciphertext[$i]; - } - - if ($this->continuousBuffer) { - if ($len >= $block_size) { - $this->decryptIV = substr($ciphertext, -$block_size); - } else { - $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len); - } - } - break; - case self::MODE_OFB: - $xor = $this->decryptIV; - if (strlen($buffer['xor'])) { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $block = substr($ciphertext, $i, $block_size); - if (strlen($block) > strlen($buffer['xor'])) { - $xor = $this->encryptBlock($xor); - $buffer['xor'].= $xor; - } - $key = Strings::shift($buffer['xor'], $block_size); - $plaintext.= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $xor = $this->encryptBlock($xor); - $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor; - } - $key = $xor; - } - if ($this->continuousBuffer) { - $this->decryptIV = $xor; - if ($start = strlen($ciphertext) % $block_size) { - $buffer['xor'] = substr($key, $start) . $buffer['xor']; - } - } - break; - case self::MODE_STREAM: - $plaintext = $this->decryptBlock($ciphertext); - break; - } - return $this->paddable ? $this->unpad($plaintext) : $plaintext; - } - - /** - * Get the authentication tag - * - * Only used in GCM or Poly1305 mode - * - * @see self::encrypt() - * @param int $length optional - * @return string - * @access public - * @throws \LengthException if $length isn't of a sufficient length - * @throws \RuntimeException if GCM mode isn't being used - */ - public function getTag($length = 16) - { - if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { - throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); - } - - if ($this->newtag === false) { - throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); - } - - // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it - // were 0 you might as well be doing CTR and less than 4 provides minimal security that could be trivially - // easily brute forced. - // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 - // for more info - if ($length < 4 || $length > 16) { - throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); - } - - return $length == 16 ? - $this->newtag : - substr($this->newtag, 0, $length); - } - - /** - * Sets the authentication tag - * - * Only used in GCM mode - * - * @see self::decrypt() - * @param string $tag - * @access public - * @throws \LengthException if $length isn't of a sufficient length - * @throws \RuntimeException if GCM mode isn't being used - */ - public function setTag($tag) - { - if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { - $this->createPoly1305Key(); - } - - if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { - throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); - } - - $length = strlen($tag); - if ($length < 4 || $length > 16) { - throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); - } - $this->oldtag = $tag; - } - - /** - * Get the IV - * - * mcrypt requires an IV even if ECB is used - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $iv - * @return string - * @access private - */ - protected function getIV($iv) - { - return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv; - } - - /** - * OpenSSL CTR Processor - * - * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream - * for CTR is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() - * and SymmetricKey::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this - * function will emulate CTR with ECB when necessary. - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $plaintext - * @param string $encryptIV - * @param array $buffer - * @return string - * @access private - */ - private function openssl_ctr_process($plaintext, &$encryptIV, &$buffer) - { - $ciphertext = ''; - - $block_size = $this->block_size; - $key = $this->key; - - if ($this->openssl_emulate_ctr) { - $xor = $encryptIV; - if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'].= openssl_encrypt($xor, static::$cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - } - Strings::increment_str($xor); - $otp = Strings::shift($buffer['ciphertext'], $block_size); - $ciphertext.= $block ^ $otp; - } - } else { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $block = substr($plaintext, $i, $block_size); - $otp = openssl_encrypt($xor, static::$cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - Strings::increment_str($xor); - $ciphertext.= $block ^ $otp; - } - } - if ($this->continuousBuffer) { - $encryptIV = $xor; - if ($start = strlen($plaintext) % $block_size) { - $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; - } - } - - return $ciphertext; - } - - if (strlen($buffer['ciphertext'])) { - $ciphertext = $plaintext ^ Strings::shift($buffer['ciphertext'], strlen($plaintext)); - $plaintext = substr($plaintext, strlen($ciphertext)); - - if (!strlen($plaintext)) { - return $ciphertext; - } - } - - $overflow = strlen($plaintext) % $block_size; - if ($overflow) { - $plaintext2 = Strings::pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 - $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - $temp = Strings::pop($encrypted, $block_size); - $ciphertext.= $encrypted . ($plaintext2 ^ $temp); - if ($this->continuousBuffer) { - $buffer['ciphertext'] = substr($temp, $overflow); - $encryptIV = $temp; - } - } elseif (!strlen($buffer['ciphertext'])) { - $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - $temp = Strings::pop($ciphertext, $block_size); - if ($this->continuousBuffer) { - $encryptIV = $temp; - } - } - if ($this->continuousBuffer) { - $encryptIV = openssl_decrypt($encryptIV, static::$cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - if ($overflow) { - Strings::increment_str($encryptIV); - } - } - - return $ciphertext; - } - - /** - * OpenSSL OFB Processor - * - * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream - * for OFB is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() - * and SymmetricKey::decrypt(). - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $plaintext - * @param string $encryptIV - * @param array $buffer - * @return string - * @access private - */ - private function openssl_ofb_process($plaintext, &$encryptIV, &$buffer) - { - if (strlen($buffer['xor'])) { - $ciphertext = $plaintext ^ $buffer['xor']; - $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); - $plaintext = substr($plaintext, strlen($ciphertext)); - } else { - $ciphertext = ''; - } - - $block_size = $this->block_size; - - $len = strlen($plaintext); - $key = $this->key; - $overflow = $len % $block_size; - - if (strlen($plaintext)) { - if ($overflow) { - $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - $xor = Strings::pop($ciphertext, $block_size); - if ($this->continuousBuffer) { - $encryptIV = $xor; - } - $ciphertext.= Strings::shift($xor, $overflow) ^ substr($plaintext, -$overflow); - if ($this->continuousBuffer) { - $buffer['xor'] = $xor; - } - } else { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - if ($this->continuousBuffer) { - $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); - } - } - } - - return $ciphertext; - } - - /** - * phpseclib <-> OpenSSL Mode Mapper - * - * May need to be overwritten by classes extending this one in some cases - * - * @return string - * @access private - */ - protected function openssl_translate_mode() - { - switch ($this->mode) { - case self::MODE_ECB: - return 'ecb'; - case self::MODE_CBC: - return 'cbc'; - case self::MODE_CTR: - case self::MODE_GCM: - return 'ctr'; - case self::MODE_CFB: - return 'cfb'; - case self::MODE_CFB8: - return 'cfb8'; - case self::MODE_OFB: - return 'ofb'; - } - } - - /** - * Pad "packets". - * - * Block ciphers working by encrypting between their specified [$this->]block_size at a time - * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to - * pad the input so that it is of the proper length. - * - * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, - * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping - * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is - * transmitted separately) - * - * @see self::disablePadding() - * @access public - */ - public function enablePadding() - { - $this->padding = true; - } - - /** - * Do not pad packets. - * - * @see self::enablePadding() - * @access public - */ - public function disablePadding() - { - $this->padding = false; - } - - /** - * Treat consecutive "packets" as if they are a continuous buffer. - * - * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets - * will yield different outputs: - * - * - * echo $rijndael->encrypt(substr($plaintext, 0, 16)); - * echo $rijndael->encrypt(substr($plaintext, 16, 16)); - * - * - * echo $rijndael->encrypt($plaintext); - * - * - * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates - * another, as demonstrated with the following: - * - * - * $rijndael->encrypt(substr($plaintext, 0, 16)); - * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); - * - * - * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); - * - * - * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different - * outputs. The reason is due to the fact that the initialization vector's change after every encryption / - * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. - * - * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\*() object changes after each - * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that - * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), - * however, they are also less intuitive and more likely to cause you problems. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::disableContinuousBuffer() - * @access public - */ - public function enableContinuousBuffer() - { - if ($this->mode == self::MODE_ECB) { - return; - } - - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('This mode does not run in continuous mode'); - } - - $this->continuousBuffer = true; - - $this->setEngine(); - } - - /** - * Treat consecutive packets as if they are a discontinuous buffer. - * - * The default behavior. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::enableContinuousBuffer() - * @access public - */ - public function disableContinuousBuffer() - { - if ($this->mode == self::MODE_ECB) { - return; - } - if (!$this->continuousBuffer) { - return; - } - - $this->continuousBuffer = false; - - $this->setEngine(); - } - - /** - * Test for engine validity - * - * @see self::__construct() - * @param int $engine - * @access private - * @return bool - */ - protected function isValidEngineHelper($engine) - { - switch ($engine) { - case self::ENGINE_OPENSSL: - $this->openssl_emulate_ctr = false; - $result = $this->cipher_name_openssl && - extension_loaded('openssl'); - if (!$result) { - return false; - } - - $methods = openssl_get_cipher_methods(); - if (in_array($this->cipher_name_openssl, $methods)) { - return true; - } - // not all of openssl's symmetric cipher's support ctr. for those - // that don't we'll emulate it - switch ($this->mode) { - case self::MODE_CTR: - if (in_array(static::$cipher_name_openssl_ecb, $methods)) { - $this->openssl_emulate_ctr = true; - return true; - } - } - return false; - case self::ENGINE_MCRYPT: - return $this->cipher_name_mcrypt && - extension_loaded('mcrypt') && - in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms()); - case self::ENGINE_EVAL: - return method_exists($this, 'setupInlineCrypt'); - case self::ENGINE_INTERNAL: - return true; - } - - return false; - } - - /** - * Test for engine validity - * - * @see self::__construct() - * @param string $engine - * @access public - * @return bool - */ - public function isValidEngine($engine) - { - static $reverseMap; - if (!isset($reverseMap)) { - $reverseMap = array_map('strtolower', self::ENGINE_MAP); - $reverseMap = array_flip($reverseMap); - } - $engine = strtolower($engine); - if (!isset($reverseMap[$engine])) { - return false; - } - - return $this->isValidEngineHelper($reverseMap[$engine]); - } - - /** - * Sets the preferred crypt engine - * - * Currently, $engine could be: - * - * - libsodium[very fast] - * - * - OpenSSL [very fast] - * - * - mcrypt [fast] - * - * - Eval [slow] - * - * - PHP [slowest] - * - * If the preferred crypt engine is not available the fastest available one will be used - * - * @see self::__construct() - * @param string $engine - * @access public - */ - public function setPreferredEngine($engine) - { - static $reverseMap; - if (!isset($reverseMap)) { - $reverseMap = array_map('strtolower', self::ENGINE_MAP); - $reverseMap = array_flip($reverseMap); - } - $engine = strtolower($engine); - $this->preferredEngine = isset($reverseMap[$engine]) ? $reverseMap[$engine] : self::ENGINE_LIBSODIUM; - - $this->setEngine(); - } - - /** - * Returns the engine currently being utilized - * - * @see self::setEngine() - * @access public - */ - public function getEngine() - { - return self::ENGINE_MAP[$this->engine]; - } - - /** - * Sets the engine as appropriate - * - * @see self::__construct() - * @access private - */ - protected function setEngine() - { - $this->engine = null; - - $candidateEngines = [ - self::ENGINE_LIBSODIUM, - self::ENGINE_OPENSSL_GCM, - self::ENGINE_OPENSSL, - self::ENGINE_MCRYPT, - self::ENGINE_EVAL - ]; - if (isset($this->preferredEngine)) { - $temp = [$this->preferredEngine]; - $candidateEngines = array_merge( - $temp, - array_diff($candidateEngines, $temp) - ); - } - foreach ($candidateEngines as $engine) { - if ($this->isValidEngineHelper($engine)) { - $this->engine = $engine; - break; - } - } - if (!$this->engine) { - $this->engine = self::ENGINE_INTERNAL; - } - - if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { - // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, - // (re)open them with the module named in $this->cipher_name_mcrypt - @mcrypt_module_close($this->enmcrypt); - @mcrypt_module_close($this->demcrypt); - $this->enmcrypt = null; - $this->demcrypt = null; - - if ($this->ecb) { - @mcrypt_module_close($this->ecb); - $this->ecb = null; - } - } - - $this->changed = $this->nonIVChanged = true; - } - - /** - * Encrypts a block - * - * Note: Must be extended by the child \phpseclib3\Crypt\* class - * - * @access private - * @param string $in - * @return string - */ - abstract protected function encryptBlock($in); - - /** - * Decrypts a block - * - * Note: Must be extended by the child \phpseclib3\Crypt\* class - * - * @access private - * @param string $in - * @return string - */ - abstract protected function decryptBlock($in); - - /** - * Setup the key (expansion) - * - * Only used if $engine == self::ENGINE_INTERNAL - * - * Note: Must extend by the child \phpseclib3\Crypt\* class - * - * @see self::setup() - * @access private - */ - abstract protected function setupKey(); - - /** - * Setup the self::ENGINE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine and flush all $buffers - * Used (only) if $engine == self::ENGINE_INTERNAL - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setIV() - * - * - disableContinuousBuffer() - * - * - First run of encrypt() / decrypt() with no init-settings - * - * {@internal setup() is always called before en/decryption.} - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::setKey() - * @see self::setIV() - * @see self::disableContinuousBuffer() - * @access private - */ - protected function setup() - { - if (!$this->changed) { - return; - } - - $this->changed = false; - - if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { - $this->createPoly1305Key(); - } - - $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true]; - //$this->newtag = $this->oldtag = false; - - if ($this->usesNonce()) { - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - if ($this->mode == self::MODE_GCM && !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { - $this->setupGCM(); - } - } else { - $this->iv = $this->origIV; - } - - if ($this->iv === false && !in_array($this->mode, [self::MODE_STREAM, self::MODE_ECB])) { - if ($this->mode != self::MODE_GCM || !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { - throw new InsufficientSetupException('No IV has been defined'); - } - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - $this->encryptIV = $this->decryptIV = $this->iv; - - switch ($this->engine) { - case self::ENGINE_MCRYPT: - $this->enchanged = $this->dechanged = true; - - if (!isset($this->enmcrypt)) { - static $mcrypt_modes = [ - self::MODE_CTR => 'ctr', - self::MODE_ECB => MCRYPT_MODE_ECB, - self::MODE_CBC => MCRYPT_MODE_CBC, - self::MODE_CFB => 'ncfb', - self::MODE_CFB8 => MCRYPT_MODE_CFB, - self::MODE_OFB => MCRYPT_MODE_NOFB, - self::MODE_STREAM => MCRYPT_MODE_STREAM, - ]; - - $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - - // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() - // to workaround mcrypt's broken ncfb implementation in buffered mode - // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} - if ($this->mode == self::MODE_CFB) { - $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); - } - } // else should mcrypt_generic_deinit be called? - - if ($this->mode == self::MODE_CFB) { - @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); - } - break; - case self::ENGINE_INTERNAL: - $this->setupKey(); - break; - case self::ENGINE_EVAL: - if ($this->nonIVChanged) { - $this->setupKey(); - $this->setupInlineCrypt(); - } - } - - $this->nonIVChanged = false; - } - - /** - * Pads a string - * - * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. - * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to - * chr($this->block_size - (strlen($text) % $this->block_size) - * - * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless - * and padding will, hence forth, be enabled. - * - * @see self::unpad() - * @param string $text - * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size - * @access private - * @return string - */ - protected function pad($text) - { - $length = strlen($text); - - if (!$this->padding) { - if ($length % $this->block_size == 0) { - return $text; - } else { - throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); - } - } - - $pad = $this->block_size - ($length % $this->block_size); - - return str_pad($text, $length + $pad, chr($pad)); - } - - /** - * Unpads a string. - * - * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong - * and false will be returned. - * - * @see self::pad() - * @param string $text - * @throws \LengthException if the ciphertext's length is not a multiple of the block size - * @access private - * @return string - */ - protected function unpad($text) - { - if (!$this->padding) { - return $text; - } - - $length = ord($text[strlen($text) - 1]); - - if (!$length || $length > $this->block_size) { - throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); - } - - return substr($text, 0, -$length); - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * Stores the created (or existing) callback function-name - * in $this->inline_crypt - * - * Internally for phpseclib developers: - * - * _setupInlineCrypt() would be called only if: - * - * - $this->engine === self::ENGINE_EVAL - * - * - each time on _setup(), after(!) _setupKey() - * - * - * This ensures that _setupInlineCrypt() has always a - * full ready2go initializated internal cipher $engine state - * where, for example, the keys already expanded, - * keys/block_size calculated and such. - * - * It is, each time if called, the responsibility of _setupInlineCrypt(): - * - * - to set $this->inline_crypt to a valid and fully working callback function - * as a (faster) replacement for encrypt() / decrypt() - * - * - NOT to create unlimited callback functions (for memory reasons!) - * no matter how often _setupInlineCrypt() would be called. At some - * point of amount they must be generic re-useable. - * - * - the code of _setupInlineCrypt() it self, - * and the generated callback code, - * must be, in following order: - * - 100% safe - * - 100% compatible to encrypt()/decrypt() - * - using only php5+ features/lang-constructs/php-extensions if - * compatibility (down to php4) or fallback is provided - * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) - * - >= 10% faster than encrypt()/decrypt() [which is, by the way, - * the reason for the existence of _setupInlineCrypt() :-)] - * - memory-nice - * - short (as good as possible) - * - * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. - * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib3\Crypt\* class. - * - The following variable names are reserved: - * - $_* (all variable names prefixed with an underscore) - * - $self (object reference to it self. Do not use $this, but $self instead) - * - $in (the content of $in has to en/decrypt by the generated code) - * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only - * - * {@internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()} - * - * @see self::setup() - * @see self::createInlineCryptFunction() - * @see self::encrypt() - * @see self::decrypt() - * @access private - */ - //protected function setupInlineCrypt(); - - /** - * Creates the performance-optimized function for en/decrypt() - * - * Internally for phpseclib developers: - * - * _createInlineCryptFunction(): - * - * - merge the $cipher_code [setup'ed by _setupInlineCrypt()] - * with the current [$this->]mode of operation code - * - * - create the $inline function, which called by encrypt() / decrypt() - * as its replacement to speed up the en/decryption operations. - * - * - return the name of the created $inline callback function - * - * - used to speed up en/decryption - * - * - * - * The main reason why can speed up things [up to 50%] this way are: - * - * - using variables more effective then regular. - * (ie no use of expensive arrays but integers $k_0, $k_1 ... - * or even, for example, the pure $key[] values hardcoded) - * - * - avoiding 1000's of function calls of ie _encryptBlock() - * but inlining the crypt operations. - * in the mode of operation for() loop. - * - * - full loop unroll the (sometimes key-dependent) rounds - * avoiding this way ++$i counters and runtime-if's etc... - * - * The basic code architectur of the generated $inline en/decrypt() - * lambda function, in pseudo php, is: - * - * - * +----------------------------------------------------------------------------------------------+ - * | callback $inline = create_function: | - * | lambda_function_0001_crypt_ECB($action, $text) | - * | { | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_crypt']; // general init code. | - * | // ie: $sbox'es declarations used for | - * | // encrypt and decrypt'ing. | - * | | - * | switch ($action) { | - * | case 'encrypt': | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | - * | ie: specified $key or $box | - * | declarations for encrypt'ing. | - * | | - * | foreach ($ciphertext) { | - * | $in = $block_size of $ciphertext; | - * | | - * | INSERT PHP CODE OF: | - * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | - * | // strlen($in) == $this->block_size | - * | // here comes the cipher algorithm in action | - * | // for encryption. | - * | // $cipher_code['encrypt_block'] has to | - * | // encrypt the content of the $in variable | - * | | - * | $plaintext .= $in; | - * | } | - * | return $plaintext; | - * | | - * | case 'decrypt': | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_decrypt']; // decrypt sepcific init code | - * | ie: specified $key or $box | - * | declarations for decrypt'ing. | - * | foreach ($plaintext) { | - * | $in = $block_size of $plaintext; | - * | | - * | INSERT PHP CODE OF: | - * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | - * | // strlen($in) == $this->block_size | - * | // here comes the cipher algorithm in action | - * | // for decryption. | - * | // $cipher_code['decrypt_block'] has to | - * | // decrypt the content of the $in variable | - * | $ciphertext .= $in; | - * | } | - * | return $ciphertext; | - * | } | - * | } | - * +----------------------------------------------------------------------------------------------+ - * - * - * See also the \phpseclib3\Crypt\*::_setupInlineCrypt()'s for - * productive inline $cipher_code's how they works. - * - * Structure of: - * - * $cipher_code = [ - * 'init_crypt' => (string) '', // optional - * 'init_encrypt' => (string) '', // optional - * 'init_decrypt' => (string) '', // optional - * 'encrypt_block' => (string) '', // required - * 'decrypt_block' => (string) '' // required - * ]; - * - * - * @see self::setupInlineCrypt() - * @see self::encrypt() - * @see self::decrypt() - * @param array $cipher_code - * @access private - * @return string (the name of the created callback function) - */ - protected function createInlineCryptFunction($cipher_code) - { - $block_size = $this->block_size; - - // optional - $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : ''; - $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : ''; - $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : ''; - // required - $encrypt_block = $cipher_code['encrypt_block']; - $decrypt_block = $cipher_code['decrypt_block']; - - // Generating mode of operation inline code, - // merged with the $cipher_code algorithm - // for encrypt- and decryption. - switch ($this->mode) { - case self::MODE_ECB: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $in = substr($_text, $_i, '.$block_size.'); - '.$encrypt_block.' - $_ciphertext.= $in; - } - - return $_ciphertext; - '; - - $decrypt = $init_decrypt . ' - $_plaintext = ""; - $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); - $_ciphertext_len = strlen($_text); - - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $in = substr($_text, $_i, '.$block_size.'); - '.$decrypt_block.' - $_plaintext.= $in; - } - - return $this->unpad($_plaintext); - '; - break; - case self::MODE_CTR: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - $_xor = $this->encryptIV; - $_buffer = &$this->enbuffer; - if (strlen($_buffer["ciphertext"])) { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); - if (strlen($_block) > strlen($_buffer["ciphertext"])) { - $in = $_xor; - '.$encrypt_block.' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_buffer["ciphertext"].= $in; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], '.$block_size.'); - $_ciphertext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); - $in = $_xor; - '.$encrypt_block.' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_key = $in; - $_ciphertext.= $_block ^ $_key; - } - } - if ($this->continuousBuffer) { - $this->encryptIV = $_xor; - if ($_start = $_plaintext_len % '.$block_size.') { - $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; - } - } - - return $_ciphertext; - '; - - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_ciphertext_len = strlen($_text); - $_xor = $this->decryptIV; - $_buffer = &$this->debuffer; - - if (strlen($_buffer["ciphertext"])) { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); - if (strlen($_block) > strlen($_buffer["ciphertext"])) { - $in = $_xor; - '.$encrypt_block.' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_buffer["ciphertext"].= $in; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], '.$block_size.'); - $_plaintext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); - $in = $_xor; - '.$encrypt_block.' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_key = $in; - $_plaintext.= $_block ^ $_key; - } - } - if ($this->continuousBuffer) { - $this->decryptIV = $_xor; - if ($_start = $_ciphertext_len % '.$block_size.') { - $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; - } - } - - return $_plaintext; - '; - break; - case self::MODE_CFB: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_buffer = &$this->enbuffer; - - if ($this->continuousBuffer) { - $_iv = &$this->encryptIV; - $_pos = &$_buffer["pos"]; - } else { - $_iv = $this->encryptIV; - $_pos = 0; - } - $_len = strlen($_text); - $_i = 0; - if ($_pos) { - $_orig_pos = $_pos; - $_max = '.$block_size.' - $_pos; - if ($_len >= $_max) { - $_i = $_max; - $_len-= $_max; - $_pos = 0; - } else { - $_i = $_len; - $_pos+= $_len; - $_len = 0; - } - $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; - $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); - } - while ($_len >= '.$block_size.') { - $in = $_iv; - '.$encrypt_block.'; - $_iv = $in ^ substr($_text, $_i, '.$block_size.'); - $_ciphertext.= $_iv; - $_len-= '.$block_size.'; - $_i+= '.$block_size.'; - } - if ($_len) { - $in = $_iv; - '.$encrypt_block.' - $_iv = $in; - $_block = $_iv ^ substr($_text, $_i); - $_iv = substr_replace($_iv, $_block, 0, $_len); - $_ciphertext.= $_block; - $_pos = $_len; - } - return $_ciphertext; - '; - - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_buffer = &$this->debuffer; - - if ($this->continuousBuffer) { - $_iv = &$this->decryptIV; - $_pos = &$_buffer["pos"]; - } else { - $_iv = $this->decryptIV; - $_pos = 0; - } - $_len = strlen($_text); - $_i = 0; - if ($_pos) { - $_orig_pos = $_pos; - $_max = '.$block_size.' - $_pos; - if ($_len >= $_max) { - $_i = $_max; - $_len-= $_max; - $_pos = 0; - } else { - $_i = $_len; - $_pos+= $_len; - $_len = 0; - } - $_plaintext = substr($_iv, $_orig_pos) ^ $_text; - $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); - } - while ($_len >= '.$block_size.') { - $in = $_iv; - '.$encrypt_block.' - $_iv = $in; - $cb = substr($_text, $_i, '.$block_size.'); - $_plaintext.= $_iv ^ $cb; - $_iv = $cb; - $_len-= '.$block_size.'; - $_i+= '.$block_size.'; - } - if ($_len) { - $in = $_iv; - '.$encrypt_block.' - $_iv = $in; - $_plaintext.= $_iv ^ substr($_text, $_i); - $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); - $_pos = $_len; - } - - return $_plaintext; - '; - break; - case self::MODE_CFB8: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_len = strlen($_text); - $_iv = $this->encryptIV; - - for ($_i = 0; $_i < $_len; ++$_i) { - $in = $_iv; - '.$encrypt_block.' - $_ciphertext .= ($_c = $_text[$_i] ^ $in); - $_iv = substr($_iv, 1) . $_c; - } - - if ($this->continuousBuffer) { - if ($_len >= '.$block_size.') { - $this->encryptIV = substr($_ciphertext, -'.$block_size.'); - } else { - $this->encryptIV = substr($this->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len); - } - } - - return $_ciphertext; - '; - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_len = strlen($_text); - $_iv = $this->decryptIV; - - for ($_i = 0; $_i < $_len; ++$_i) { - $in = $_iv; - '.$encrypt_block.' - $_plaintext .= $_text[$_i] ^ $in; - $_iv = substr($_iv, 1) . $_text[$_i]; - } - - if ($this->continuousBuffer) { - if ($_len >= '.$block_size.') { - $this->decryptIV = substr($_text, -'.$block_size.'); - } else { - $this->decryptIV = substr($this->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len); - } - } - - return $_plaintext; - '; - break; - case self::MODE_OFB: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - $_xor = $this->encryptIV; - $_buffer = &$this->enbuffer; - - if (strlen($_buffer["xor"])) { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); - if (strlen($_block) > strlen($_buffer["xor"])) { - $in = $_xor; - '.$encrypt_block.' - $_xor = $in; - $_buffer["xor"].= $_xor; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], '.$block_size.'); - $_ciphertext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $in = $_xor; - '.$encrypt_block.' - $_xor = $in; - $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor; - } - $_key = $_xor; - } - if ($this->continuousBuffer) { - $this->encryptIV = $_xor; - if ($_start = $_plaintext_len % '.$block_size.') { - $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; - } - } - return $_ciphertext; - '; - - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_ciphertext_len = strlen($_text); - $_xor = $this->decryptIV; - $_buffer = &$this->debuffer; - - if (strlen($_buffer["xor"])) { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); - if (strlen($_block) > strlen($_buffer["xor"])) { - $in = $_xor; - '.$encrypt_block.' - $_xor = $in; - $_buffer["xor"].= $_xor; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], '.$block_size.'); - $_plaintext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $in = $_xor; - '.$encrypt_block.' - $_xor = $in; - $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor; - } - $_key = $_xor; - } - if ($this->continuousBuffer) { - $this->decryptIV = $_xor; - if ($_start = $_ciphertext_len % '.$block_size.') { - $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; - } - } - return $_plaintext; - '; - break; - case self::MODE_STREAM: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - '.$encrypt_block.' - return $_ciphertext; - '; - $decrypt = $init_decrypt . ' - $_plaintext = ""; - '.$decrypt_block.' - return $_plaintext; - '; - break; - // case self::MODE_CBC: - default: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - - $in = $this->encryptIV; - - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $in = substr($_text, $_i, '.$block_size.') ^ $in; - '.$encrypt_block.' - $_ciphertext.= $in; - } - - if ($this->continuousBuffer) { - $this->encryptIV = $in; - } - - return $_ciphertext; - '; - - $decrypt = $init_decrypt . ' - $_plaintext = ""; - $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); - $_ciphertext_len = strlen($_text); - - $_iv = $this->decryptIV; - - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $in = $_block = substr($_text, $_i, '.$block_size.'); - '.$decrypt_block.' - $_plaintext.= $in ^ $_iv; - $_iv = $_block; - } - - if ($this->continuousBuffer) { - $this->decryptIV = $_iv; - } - - return $this->unpad($_plaintext); - '; - break; - } - - // Before discrediting this, please read the following: - // @see https://github.com/phpseclib/phpseclib/issues/1293 - // @see https://github.com/phpseclib/phpseclib/pull/1143 - eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};'); - - return \Closure::bind($func, $this, static::class); - } - - /** - * Convert float to int - * - * On ARM CPUs converting floats to ints doesn't always work - * - * @access private - * @param string $x - * @return int - */ - protected static function safe_intval($x) - { - switch (true) { - case is_int($x): - // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding" - case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': - return $x; - } - return (fmod($x, 0x80000000) & 0x7FFFFFFF) | - ((fmod(floor($x / 0x80000000), 2) & 1) << 31); - } - - /** - * eval()'able string for in-line float to int - * - * @access private - * @return string - */ - protected static function safe_intval_inline() - { - switch (true) { - case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: - case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': - return '%s'; - break; - default: - $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; - return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; - } - } - - /** - * Sets up GCM parameters - * - * See steps 1-2 of https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=23 - * for more info - * - * @access private - */ - private function setupGCM() - { - // don't keep on re-calculating $this->h - if (!$this->h || $this->h->key != $this->key) { - $cipher = new static('ecb'); - $cipher->setKey($this->key); - $cipher->disablePadding(); - - $this->h = self::$gcmField->newInteger( - Strings::switchEndianness($cipher->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")) - ); - $this->h->key = $this->key; - } - - if (strlen($this->nonce) == 12) { - $this->iv = $this->nonce . "\0\0\0\1"; - } else { - $this->iv = $this->ghash( - self::nullPad128($this->nonce) . str_repeat("\0", 8) . self::len64($this->nonce) - ); - } - } - - /** - * Performs GHASH operation - * - * See https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=20 - * for more info - * - * @see self::decrypt() - * @see self::encrypt() - * @access private - * @param string $x - * @return string - */ - private function ghash($x) - { - $h = $this->h; - $y = ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"]; - $x = str_split($x, 16); - $n = 0; - // the switchEndianness calls are necessary because the multiplication algorithm in BinaryField/Integer - // interprets strings as polynomials in big endian order whereas in GCM they're interpreted in little - // endian order per https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=19. - // big endian order is what binary field elliptic curves use per http://www.secg.org/sec1-v2.pdf#page=18. - - // we could switchEndianness here instead of in the while loop but doing so in the while loop seems like it - // might be slightly more performant - //$x = Strings::switchEndianness($x); - foreach ($x as $xn) { - $xn = Strings::switchEndianness($xn); - $t = $y[$n] ^ $xn; - $temp = self::$gcmField->newInteger($t); - $y[++$n] = $temp->multiply($h)->toBytes(); - $y[$n] = substr($y[$n], 1); - } - $y[$n] = Strings::switchEndianness($y[$n]); - return $y[$n]; - } - - /** - * Returns the bit length of a string in a packed format - * - * @see self::decrypt() - * @see self::encrypt() - * @see self::setupGCM() - * @access private - * @param string $str - * @return string - */ - private static function len64($str) - { - return "\0\0\0\0" . pack('N', 8 * strlen($str)); - } - - /** - * NULL pads a string to be a multiple of 128 - * - * @see self::decrypt() - * @see self::encrypt() - * @see self::setupGCM() - * @access private - * @param string $str - * @return string - */ - protected static function nullPad128($str) - { - $len = strlen($str); - return $str . str_repeat("\0", 16 * ceil($len / 16) - $len); - } - - /** - * Calculates Poly1305 MAC - * - * On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation - * it takes 1.2s. - * - * @see self::decrypt() - * @see self::encrypt() - * @access private - * @param string $text - * @return string - */ - protected function poly1305($text) - { - $s = $this->poly1305Key; // strlen($this->poly1305Key) == 32 - $r = Strings::shift($s, 16); - $r = strrev($r); - $r&= "\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xff"; - $s = strrev($s); - - $r = self::$poly1305Field->newInteger(new BigInteger($r, 256)); - $s = self::$poly1305Field->newInteger(new BigInteger($s, 256)); - $a = self::$poly1305Field->newInteger(new BigInteger()); - - $blocks = str_split($text, 16); - foreach ($blocks as $block) { - $n = strrev($block . chr(1)); - $n = self::$poly1305Field->newInteger(new BigInteger($n, 256)); - $a = $a->add($n); - $a = $a->multiply($r); - } - $r = $a->toBigInteger()->add($s->toBigInteger()); - $mask = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; - return strrev($r->toBytes()) & $mask; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php deleted file mode 100644 index 0db9c84ab..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Traits; - -use phpseclib3\Crypt\Hash; - -/** - * Fingerprint Trait for Private Keys - * - * @package Common - * @author Jim Wigginton - * @access public - */ -trait Fingerprint -{ - /** - * Returns the public key's fingerprint - * - * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is - * no public key currently loaded, false is returned. - * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) - * - * @access public - * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned - * for invalid values. - * @return mixed - */ - public function getFingerprint($algorithm = 'md5') - { - $type = self::validatePlugin('Keys', 'OpenSSH', 'savePublicKey'); - if ($type === false) { - return false; - } - $key = $this->toString('OpenSSH', ['binary' => true]); - if ($key === false) { - return false; - } - switch ($algorithm) { - case 'sha256': - $hash = new Hash('sha256'); - $base = base64_encode($hash->hash($key)); - return substr($base, 0, strlen($base) - 1); - case 'md5': - return substr(chunk_split(md5($key), 2, ':'), 0, -1); - default: - return false; - } - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php deleted file mode 100644 index 058f9b949..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Traits; - -/** - * Password Protected Trait for Private Keys - * - * @package Common - * @author Jim Wigginton - * @access public - */ -trait PasswordProtected -{ - /** - * Password - * - * @var string|bool - */ - private $password = false; - - /** - * Sets the password - * - * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. - * Or rather, pass in $password such that empty($password) && !is_string($password) is true. - * - * @see self::createKey() - * @see self::load() - * @access public - * @param string|boolean $password - */ - public function withPassword($password = false) - { - $new = clone $this; - $new->password = $password; - return $new; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php index cbde382fd..9a8225fb5 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php @@ -18,7 +18,7 @@ * setKey('abcdefgh'); * @@ -40,10 +40,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; -use phpseclib3\Exception\BadModeException; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of DES. @@ -52,87 +49,85 @@ use phpseclib3\Exception\BadModeException; * @author Jim Wigginton * @access public */ -class DES extends BlockCipher +class DES extends Base { + /**#@+ + * @access private + * @see \phpseclib\Crypt\DES::_setupKey() + * @see \phpseclib\Crypt\DES::_processBlock() + */ /** * Contains $keys[self::ENCRYPT] - * - * @access private - * @see \phpseclib3\Crypt\DES::setupKey() - * @see \phpseclib3\Crypt\DES::processBlock() */ const ENCRYPT = 0; /** * Contains $keys[self::DECRYPT] - * - * @access private - * @see \phpseclib3\Crypt\DES::setupKey() - * @see \phpseclib3\Crypt\DES::processBlock() */ const DECRYPT = 1; + /**#@-*/ /** * Block Length of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @see \phpseclib\Crypt\Base::block_size * @var int * @access private */ - protected $block_size = 8; + var $block_size = 8; /** * Key Length (in bytes) * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() + * @see \phpseclib\Crypt\Base::setKeyLength() * @var int * @access private */ - protected $key_length = 8; + var $key_length = 8; /** * The mcrypt specific name of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib\Crypt\Base::cipher_name_mcrypt * @var string * @access private */ - protected $cipher_name_mcrypt = 'des'; + var $cipher_name_mcrypt = 'des'; /** * The OpenSSL names of the cipher / modes * - * @see \phpseclib3\Crypt\Common\SymmetricKey::openssl_mode_names + * @see \phpseclib\Crypt\Base::openssl_mode_names * @var array * @access private */ - protected $openssl_mode_names = [ + var $openssl_mode_names = array( self::MODE_ECB => 'des-ecb', self::MODE_CBC => 'des-cbc', self::MODE_CFB => 'des-cfb', self::MODE_OFB => 'des-ofb' // self::MODE_CTR is undefined for DES - ]; + ); /** * Optimizing value while CFB-encrypting * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @see \phpseclib\Crypt\Base::cfb_init_len * @var int * @access private */ - protected $cfb_init_len = 500; + var $cfb_init_len = 500; /** * Switch for DES/3DES encryption * * Used only if $engine == self::ENGINE_INTERNAL * - * @see self::setupKey() - * @see self::processBlock() + * @see self::_setupKey() + * @see self::_processBlock() * @var int * @access private */ - protected $des_rounds = 1; + var $des_rounds = 1; /** * max possible size of $key @@ -141,16 +136,16 @@ class DES extends BlockCipher * @var string * @access private */ - protected $key_length_max = 8; + var $key_length_max = 8; /** * The Key Schedule * - * @see self::setupKey() + * @see self::_setupKey() * @var array * @access private */ - private $keys; + var $keys; /** * Shuffle table. @@ -159,12 +154,12 @@ class DES extends BlockCipher * with each byte containing all bits in the same state as the * corresponding bit in the index value. * - * @see self::processBlock() - * @see self::setupKey() + * @see self::_processBlock() + * @see self::_setupKey() * @var array * @access private */ - protected static $shuffle = [ + var $shuffle = array( "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", @@ -293,7 +288,7 @@ class DES extends BlockCipher "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - ]; + ); /** * IP mapping helper table. @@ -303,7 +298,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $ipmap = [ + var $ipmap = array( 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, @@ -336,7 +331,7 @@ class DES extends BlockCipher 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF - ]; + ); /** * Inverse IP mapping helper table. @@ -345,7 +340,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $invipmap = [ + var $invipmap = array( 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, @@ -378,7 +373,7 @@ class DES extends BlockCipher 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF - ]; + ); /** * Pre-permuted S-box1 @@ -389,7 +384,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox1 = [ + var $sbox1 = array( 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, 0x00000200, 0x00808200, 0x00808202, 0x00000200, @@ -406,7 +401,7 @@ class DES extends BlockCipher 0x00800002, 0x00000202, 0x00008202, 0x00808200, 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002 - ]; + ); /** * Pre-permuted S-box2 @@ -414,7 +409,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox2 = [ + var $sbox2 = array( 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, 0x40000010, 0x40084010, 0x40084000, 0x40000000, @@ -431,7 +426,7 @@ class DES extends BlockCipher 0x00080010, 0x40004010, 0x40000010, 0x00080010, 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000 - ]; + ); /** * Pre-permuted S-box3 @@ -439,7 +434,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox3 = [ + var $sbox3 = array( 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, 0x00010004, 0x04000004, 0x04000004, 0x00010000, @@ -456,7 +451,7 @@ class DES extends BlockCipher 0x00000004, 0x00010104, 0x00010100, 0x04000004, 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100 - ]; + ); /** * Pre-permuted S-box4 @@ -464,7 +459,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox4 = [ + var $sbox4 = array( 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, 0x00000000, 0x00401000, 0x00401000, 0x80401040, @@ -481,7 +476,7 @@ class DES extends BlockCipher 0x80400000, 0x80001000, 0x00401040, 0x80400040, 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040 - ]; + ); /** * Pre-permuted S-box5 @@ -489,7 +484,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox5 = [ + var $sbox5 = array( 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, 0x20040080, 0x00040000, 0x01000080, 0x20040080, @@ -506,7 +501,7 @@ class DES extends BlockCipher 0x01040000, 0x00000000, 0x20040000, 0x21000000, 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080 - ]; + ); /** * Pre-permuted S-box6 @@ -514,7 +509,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox6 = [ + var $sbox6 = array( 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, 0x10002000, 0x00202008, 0x00200000, 0x10000008, @@ -531,7 +526,7 @@ class DES extends BlockCipher 0x00000008, 0x00002000, 0x10200000, 0x00202008, 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008 - ]; + ); /** * Pre-permuted S-box7 @@ -539,7 +534,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox7 = [ + var $sbox7 = array( 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, 0x02100401, 0x00100000, 0x00000000, 0x02000001, @@ -556,7 +551,7 @@ class DES extends BlockCipher 0x00100400, 0x00000000, 0x00000001, 0x02100401, 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001 - ]; + ); /** * Pre-permuted S-box8 @@ -564,7 +559,7 @@ class DES extends BlockCipher * @var array * @access private */ - protected static $sbox8 = [ + var $sbox8 = array( 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, 0x00020020, 0x08020000, 0x08020820, 0x00020800, @@ -581,61 +576,51 @@ class DES extends BlockCipher 0x08020000, 0x08000800, 0x08000820, 0x00000000, 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800 - ]; - - /** - * Default Constructor. - * - * @param string $mode - * @access public - * @throws BadModeException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } + ); /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * @see \phpseclib\Crypt\Base::isValidEngine() * @param int $engine - * @access protected + * @access public * @return bool */ - protected function isValidEngineHelper($engine) + function isValidEngine($engine) { if ($this->key_length_max == 8) { if ($engine == self::ENGINE_OPENSSL) { - self::$cipher_name_openssl_ecb = 'des-ecb'; - $this->cipher_name_openssl = 'des-' . $this->openssl_translate_mode(); + $this->cipher_name_openssl_ecb = 'des-ecb'; + $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode(); } } - return parent::isValidEngineHelper($engine); + return parent::isValidEngine($engine); } /** * Sets the key. * - * Keys must be 64-bits long or 8 bytes long. + * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we + * only use the first eight, if $key has more then eight characters in it, and pad $key with the + * null byte if it is less then eight characters long. * * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * If the key is not explicitly set, it'll be assumed to be all zero's. + * + * @see \phpseclib\Crypt\Base::setKey() * @access public * @param string $key */ - public function setKey($key) + function setKey($key) { - if (!($this instanceof TripleDES) && strlen($key) != 8) { - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported'); + // We check/cut here only up to max length of the key. + // Key padding to the proper length will be done in _setupKey() + if (strlen($key) > $this->key_length_max) { + $key = substr($key, 0, $this->key_length_max); } // Sets the key @@ -645,31 +630,31 @@ class DES extends BlockCipher /** * Encrypts a block * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib\Crypt\Base::_encryptBlock() + * @see \phpseclib\Crypt\Base::encrypt() * @see self::encrypt() * @access private * @param string $in * @return string */ - protected function encryptBlock($in) + function _encryptBlock($in) { - return $this->processBlock($in, self::ENCRYPT); + return $this->_processBlock($in, self::ENCRYPT); } /** * Decrypts a block * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see \phpseclib\Crypt\Base::_decryptBlock() + * @see \phpseclib\Crypt\Base::decrypt() * @see self::decrypt() * @access private * @param string $in * @return string */ - protected function decryptBlock($in) + function _decryptBlock($in) { - return $this->processBlock($in, self::DECRYPT); + return $this->_processBlock($in, self::DECRYPT); } /** @@ -679,29 +664,29 @@ class DES extends BlockCipher * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general * idea of what this function does. * - * @see self::encryptBlock() - * @see self::decryptBlock() + * @see self::_encryptBlock() + * @see self::_decryptBlock() * @access private * @param string $block * @param int $mode * @return string */ - private function processBlock($block, $mode) + function _processBlock($block, $mode) { static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; if (!$sbox1) { - $sbox1 = array_map('intval', self::$sbox1); - $sbox2 = array_map('intval', self::$sbox2); - $sbox3 = array_map('intval', self::$sbox3); - $sbox4 = array_map('intval', self::$sbox4); - $sbox5 = array_map('intval', self::$sbox5); - $sbox6 = array_map('intval', self::$sbox6); - $sbox7 = array_map('intval', self::$sbox7); - $sbox8 = array_map('intval', self::$sbox8); + $sbox1 = array_map("intval", $this->sbox1); + $sbox2 = array_map("intval", $this->sbox2); + $sbox3 = array_map("intval", $this->sbox3); + $sbox4 = array_map("intval", $this->sbox4); + $sbox5 = array_map("intval", $this->sbox5); + $sbox6 = array_map("intval", $this->sbox6); + $sbox7 = array_map("intval", $this->sbox7); + $sbox8 = array_map("intval", $this->sbox8); /* Merge $shuffle with $[inv]ipmap */ for ($i = 0; $i < 256; ++$i) { - $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; - $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; + $shuffleip[] = $this->shuffle[$this->ipmap[$i]]; + $shuffleinvip[] = $this->shuffle[$this->invipmap[$i]]; } } @@ -710,7 +695,7 @@ class DES extends BlockCipher // Do the initial IP permutation. $t = unpack('Nl/Nr', $block); - list($l, $r) = [$t['l'], $t['r']]; + list($l, $r) = array($t['l'], $t['r']); $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | @@ -722,7 +707,7 @@ class DES extends BlockCipher // Extract L0 and R0. $t = unpack('Nl/Nr', $block); - list($l, $r) = [$t['l'], $t['r']]; + list($l, $r) = array($t['l'], $t['r']); for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { // Perform the 16 steps. @@ -764,22 +749,22 @@ class DES extends BlockCipher /** * Creates the key schedule * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @see \phpseclib\Crypt\Base::_setupKey() * @access private */ - protected function setupKey() + function _setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) { // already expanded return; } - $this->kl = ['key' => $this->key, 'des_rounds' => $this->des_rounds]; + $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds); - static $shifts = [ // number of key bits shifted per round + static $shifts = array( // number of key bits shifted per round 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 - ]; + ); - static $pc1map = [ + static $pc1map = array( 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C, 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E, 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C, @@ -812,16 +797,16 @@ class DES extends BlockCipher 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE, 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC, 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE - ]; + ); // Mapping tables for the PC-2 transformation. - static $pc2mapc1 = [ + static $pc2mapc1 = array( 0x00000000, 0x00000400, 0x00200000, 0x00200400, 0x00000001, 0x00000401, 0x00200001, 0x00200401, 0x02000000, 0x02000400, 0x02200000, 0x02200400, 0x02000001, 0x02000401, 0x02200001, 0x02200401 - ]; - static $pc2mapc2 = [ + ); + static $pc2mapc2 = array( 0x00000000, 0x00000800, 0x08000000, 0x08000800, 0x00010000, 0x00010800, 0x08010000, 0x08010800, 0x00000000, 0x00000800, 0x08000000, 0x08000800, @@ -886,8 +871,8 @@ class DES extends BlockCipher 0x01050110, 0x01050910, 0x09050110, 0x09050910, 0x01040110, 0x01040910, 0x09040110, 0x09040910, 0x01050110, 0x01050910, 0x09050110, 0x09050910 - ]; - static $pc2mapc3 = [ + ); + static $pc2mapc3 = array( 0x00000000, 0x00000004, 0x00001000, 0x00001004, 0x00000000, 0x00000004, 0x00001000, 0x00001004, 0x10000000, 0x10000004, 0x10001000, 0x10001004, @@ -952,8 +937,8 @@ class DES extends BlockCipher 0x20080022, 0x20080026, 0x20081022, 0x20081026, 0x30080022, 0x30080026, 0x30081022, 0x30081026, 0x30080022, 0x30080026, 0x30081022, 0x30081026 - ]; - static $pc2mapc4 = [ + ); + static $pc2mapc4 = array( 0x00000000, 0x00100000, 0x00000008, 0x00100008, 0x00000200, 0x00100200, 0x00000208, 0x00100208, 0x00000000, 0x00100000, 0x00000008, 0x00100008, @@ -1018,14 +1003,14 @@ class DES extends BlockCipher 0x04022200, 0x04122200, 0x04022208, 0x04122208, 0x04022000, 0x04122000, 0x04022008, 0x04122008, 0x04022200, 0x04122200, 0x04022208, 0x04122208 - ]; - static $pc2mapd1 = [ + ); + static $pc2mapd1 = array( 0x00000000, 0x00000001, 0x08000000, 0x08000001, 0x00200000, 0x00200001, 0x08200000, 0x08200001, 0x00000002, 0x00000003, 0x08000002, 0x08000003, 0x00200002, 0x00200003, 0x08200002, 0x08200003 - ]; - static $pc2mapd2 = [ + ); + static $pc2mapd2 = array( 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x04000000, 0x04100000, 0x04000800, 0x04100800, @@ -1090,8 +1075,8 @@ class DES extends BlockCipher 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04 - ]; - static $pc2mapd3 = [ + ); + static $pc2mapd3 = array( 0x00000000, 0x00010000, 0x02000000, 0x02010000, 0x00000020, 0x00010020, 0x02000020, 0x02010020, 0x00040000, 0x00050000, 0x02040000, 0x02050000, @@ -1156,8 +1141,8 @@ class DES extends BlockCipher 0x20002030, 0x20012030, 0x22002030, 0x22012030, 0x20042010, 0x20052010, 0x22042010, 0x22052010, 0x20042030, 0x20052030, 0x22042030, 0x22052030 - ]; - static $pc2mapd4 = [ + ); + static $pc2mapd4 = array( 0x00000000, 0x00000400, 0x01000000, 0x01000400, 0x00000000, 0x00000400, 0x01000000, 0x01000400, 0x00000100, 0x00000500, 0x01000100, 0x01000500, @@ -1222,32 +1207,32 @@ class DES extends BlockCipher 0x10081008, 0x10081408, 0x11081008, 0x11081408, 0x10081108, 0x10081508, 0x11081108, 0x11081508, 0x10081108, 0x10081508, 0x11081108, 0x11081508 - ]; + ); - $keys = []; + $keys = array(); for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { // pad the key and remove extra characters as appropriate. $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0"); // Perform the PC/1 transformation and compute C and D. $t = unpack('Nl/Nr', $key); - list($l, $r) = [$t['l'], $t['r']]; - $key = (self::$shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | - (self::$shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | - (self::$shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | - (self::$shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | - (self::$shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | - (self::$shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | - (self::$shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | - (self::$shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); + list($l, $r) = array($t['l'], $t['r']); + $key = ($this->shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | + ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | + ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | + ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | + ($this->shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | + ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | + ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | + ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); $key = unpack('Nc/Nd', $key); $c = ( $key['c'] >> 4) & 0x0FFFFFFF; $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F); - $keys[$des_round] = [ - self::ENCRYPT => [], + $keys[$des_round] = array( + self::ENCRYPT => array(), self::DECRYPT => array_fill(0, 32, 0) - ]; + ); for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) { $c <<= $shifts[$i]; $c = ($c | ($c >> 28)) & 0x0FFFFFFF; @@ -1274,7 +1259,7 @@ class DES extends BlockCipher switch ($this->des_rounds) { case 3: // 3DES keys - $this->keys = [ + $this->keys = array( self::ENCRYPT => array_merge( $keys[0][self::ENCRYPT], $keys[1][self::DECRYPT], @@ -1285,127 +1270,174 @@ class DES extends BlockCipher $keys[1][self::ENCRYPT], $keys[0][self::DECRYPT] ) - ]; + ); break; // case 1: // DES keys default: - $this->keys = [ + $this->keys = array( self::ENCRYPT => $keys[0][self::ENCRYPT], self::DECRYPT => $keys[0][self::DECRYPT] - ]; + ); } } /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + * @see \phpseclib\Crypt\Base::_setupInlineCrypt() * @access private */ - protected function setupInlineCrypt() + function _setupInlineCrypt() { + $lambda_functions =& self::_getLambdaFunctions(); + // Engine configuration for: // - DES ($des_rounds == 1) or // - 3DES ($des_rounds == 3) $des_rounds = $this->des_rounds; - $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; - if (!$sbox1) { - $sbox1 = array_map("intval", self::$sbox1); - $sbox2 = array_map("intval", self::$sbox2); - $sbox3 = array_map("intval", self::$sbox3); - $sbox4 = array_map("intval", self::$sbox4); - $sbox5 = array_map("intval", self::$sbox5); - $sbox6 = array_map("intval", self::$sbox6); - $sbox7 = array_map("intval", self::$sbox7); - $sbox8 = array_map("intval", self::$sbox8);' - /* Merge $shuffle with $[inv]ipmap */ . ' - for ($i = 0; $i < 256; ++$i) { - $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; - $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; - } - } - '; + // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. + // (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit) + // (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit) + // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one + $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); - $k = [ - self::ENCRYPT => $this->keys[self::ENCRYPT], - self::DECRYPT => $this->keys[self::DECRYPT] - ]; - $init_encrypt = ''; - $init_decrypt = ''; + // Generation of a unique hash for our generated code + $code_hash = "Crypt_DES, $des_rounds, {$this->mode}"; + if ($gen_hi_opt_code) { + // For hi-optimized code, we create for each combination of + // $mode, $des_rounds and $this->key its own encrypt/decrypt function. + // After max 10 hi-optimized functions, we create generic + // (still very fast.. but not ultra) functions for each $mode/$des_rounds + // Currently 2 * 5 generic functions will be then max. possible. + $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); + } - // Creating code for en- and decryption. - $crypt_block = []; - foreach ([self::ENCRYPT, self::DECRYPT] as $c) { - /* Do the initial IP permutation. */ - $crypt_block[$c] = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - $in = unpack("N*", - ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") - ); - ' . /* Extract L0 and R0 */ ' - $l = $in[1]; - $r = $in[2]; + // Is there a re-usable $lambda_functions in there? If not, we have to create it. + if (!isset($lambda_functions[$code_hash])) { + // Init code for both, encrypt and decrypt. + $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; + if (!$sbox1) { + $sbox1 = array_map("intval", $self->sbox1); + $sbox2 = array_map("intval", $self->sbox2); + $sbox3 = array_map("intval", $self->sbox3); + $sbox4 = array_map("intval", $self->sbox4); + $sbox5 = array_map("intval", $self->sbox5); + $sbox6 = array_map("intval", $self->sbox6); + $sbox7 = array_map("intval", $self->sbox7); + $sbox8 = array_map("intval", $self->sbox8);' + /* Merge $shuffle with $[inv]ipmap */ . ' + for ($i = 0; $i < 256; ++$i) { + $shuffleip[] = $self->shuffle[$self->ipmap[$i]]; + $shuffleinvip[] = $self->shuffle[$self->invipmap[$i]]; + } + } '; - $l = '$l'; - $r = '$r'; + switch (true) { + case $gen_hi_opt_code: + // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers. + // No futher initialisation of the $keys schedule is necessary. + // That is the extra performance boost. + $k = array( + self::ENCRYPT => $this->keys[self::ENCRYPT], + self::DECRYPT => $this->keys[self::DECRYPT] + ); + $init_encrypt = ''; + $init_decrypt = ''; + break; + default: + // In generic optimized code mode, we have to use, as the best compromise [currently], + // our key schedule as $ke/$kd arrays. (with hardcoded indexes...) + $k = array( + self::ENCRYPT => array(), + self::DECRYPT => array() + ); + for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) { + $k[self::ENCRYPT][$i] = '$ke[' . $i . ']'; + $k[self::DECRYPT][$i] = '$kd[' . $i . ']'; + } + $init_encrypt = '$ke = $self->keys[$self::ENCRYPT];'; + $init_decrypt = '$kd = $self->keys[$self::DECRYPT];'; + break; + } + + // Creating code for en- and decryption. + $crypt_block = array(); + foreach (array(self::ENCRYPT, self::DECRYPT) as $c) { + /* Do the initial IP permutation. */ + $crypt_block[$c] = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + $in = unpack("N*", + ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") + ); + ' . /* Extract L0 and R0 */ ' + $l = $in[1]; + $r = $in[2]; + '; + + $l = '$l'; + $r = '$r'; - // Perform DES or 3DES. - for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { - // Perform the 16 steps. - for ($i = 0; $i < 16; ++$i) { - // start of "the Feistel (F) function" - see the following URL: - // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png - // Merge key schedule. - $crypt_block[$c].= ' - $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; - $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . - /* S-box indexing. */ - $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ - $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ - $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ - $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; - '; - // end of "the Feistel (F) function" + // Perform DES or 3DES. + for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { + // Perform the 16 steps. + for ($i = 0; $i < 16; ++$i) { + // start of "the Feistel (F) function" - see the following URL: + // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png + // Merge key schedule. + $crypt_block[$c].= ' + $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; + $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . + /* S-box indexing. */ + $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; + '; + // end of "the Feistel (F) function" - // swap L & R - list($l, $r) = [$r, $l]; + // swap L & R + list($l, $r) = array($r, $l); + } + list($l, $r) = array($r, $l); } - list($l, $r) = [$r, $l]; + + // Perform the inverse IP permutation. + $crypt_block[$c].= '$in = + ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + '; } - // Perform the inverse IP permutation. - $crypt_block[$c].= '$in = - ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); - '; + // Creates the inline-crypt function + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( + array( + 'init_crypt' => $init_crypt, + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $crypt_block[self::ENCRYPT], + 'decrypt_block' => $crypt_block[self::DECRYPT] + ) + ); } - // Creates the inline-crypt function - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'init_encrypt' => $init_encrypt, - 'init_decrypt' => $init_decrypt, - 'encrypt_block' => $crypt_block[self::ENCRYPT], - 'decrypt_block' => $crypt_block[self::DECRYPT] - ] - ); + // Set the inline-crypt function as callback in: $this->inline_crypt + $this->inline_crypt = $lambda_functions[$code_hash]; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php deleted file mode 100644 index 9337200cf..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php +++ /dev/null @@ -1,400 +0,0 @@ - - * - * - * - * @category Crypt - * @package DH - * @author Jim Wigginton - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Exception\NoKeyLoadedException; -use phpseclib3\Exception\UnsupportedOperationException; -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\DH\PrivateKey; -use phpseclib3\Crypt\DH\PublicKey; -use phpseclib3\Crypt\DH\Parameters; -use phpseclib3\Math\BigInteger; - -/** - * Pure-PHP (EC)DH implementation - * - * @package DH - * @author Jim Wigginton - * @access public - */ -abstract class DH extends AsymmetricKey -{ - /** - * Algorithm Name - * - * @var string - * @access private - */ - const ALGORITHM = 'DH'; - - /** - * DH prime - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $prime; - - /** - * DH Base - * - * Prime divisor of p-1 - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $base; - - /** - * Create DH parameters - * - * This method is a bit polymorphic. It can take any of the following: - * - two BigInteger's (prime and base) - * - an integer representing the size of the prime in bits (the base is assumed to be 2) - * - a string (eg. diffie-hellman-group14-sha1) - * - * @access public - * @return \phpseclib3\Crypt\DH|bool - */ - public static function createParameters(...$args) - { - $params = new Parameters; - if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) { - //if (!$args[0]->isPrime()) { - // throw new \InvalidArgumentException('The first parameter should be a prime number'); - //} - $params->prime = $args[0]; - $params->base = $args[1]; - return $params; - } elseif (count($args) == 1 && is_numeric($args[0])) { - $params->prime = BigInteger::randomPrime($args[0]); - $params->base = new BigInteger(2); - return $params; - } elseif (count($args) != 1 || !is_string($args[0])) { - throw new \InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string'); - } - switch ($args[0]) { - // see http://tools.ietf.org/html/rfc2409#section-6.2 and - // http://tools.ietf.org/html/rfc2412, appendex E - case 'diffie-hellman-group1-sha1': - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; - break; - // see http://tools.ietf.org/html/rfc3526#section-3 - case 'diffie-hellman-group14-sha1': // 2048-bit MODP Group - case 'diffie-hellman-group14-sha256': - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-4 - case 'diffie-hellman-group15-sha512': // 3072-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-5 - case 'diffie-hellman-group16-sha512': // 4096-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . - '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . - 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . - '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . - '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-6 - case 'diffie-hellman-group17-sha512': // 6144-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . - '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . - 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . - '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . - '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . - 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . - 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . - 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . - 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . - '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . - 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . - 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . - '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-7 - case 'diffie-hellman-group18-sha512': // 8192-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . - '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . - 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . - '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . - '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . - 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . - 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . - 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . - 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . - '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . - 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . - 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . - '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4' . - '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED' . - '2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652D' . - 'E3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B' . - '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6' . - '6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851D' . - 'F9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92' . - '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA' . - '9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF'; - break; - default: - throw new \InvalidArgumentException('Invalid named prime provided'); - } - - $params->prime = new BigInteger($prime, 16); - $params->base = new BigInteger(2); - - return $params; - } - - /** - * Create public / private key pair. - * - * The rationale for the second parameter is described in http://tools.ietf.org/html/rfc4419#section-6.2 : - * - * "To increase the speed of the key exchange, both client and server may - * reduce the size of their private exponents. It should be at least - * twice as long as the key material that is generated from the shared - * secret. For more details, see the paper by van Oorschot and Wiener - * [VAN-OORSCHOT]." - * - * $length is in bits - * - * @param Parameters $params - * @param int $length optional - * @access public - * @return DH\PrivateKey - */ - public static function createKey(Parameters $params, $length = 0) - { - $one = new BigInteger(1); - if ($length) { - $max = $one->bitwise_leftShift($length); - $max = $max->subtract($one); - } else { - $max = $params->prime->subtract($one); - } - - $key = new PrivateKey; - $key->prime = $params->prime; - $key->base = $params->base; - $key->privateKey = BigInteger::randomRange($one, $max); - $key->publicKey = $key->base->powMod($key->privateKey, $key->prime); - return $key; - } - - /** - * Compute Shared Secret - * - * @param PrivateKey|EC $private - * @param PublicKey|BigInteger|string $public - * @access public - * @return mixed - */ - public static function computeSecret($private, $public) - { - if ($private instanceof PrivateKey) { // DH\PrivateKey - switch (true) { - case $public instanceof PublicKey: - if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) { - throw new \InvalidArgumentException('The public and private key do not share the same prime and / or base numbers'); - } - return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true); - case is_string($public): - $public = new BigInteger($public, -256); - case $public instanceof BigInteger: - return $public->powMod($private->privateKey, $private->prime)->toBytes(true); - default: - throw new \InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string'); - } - } - - if ($private instanceof EC\PrivateKey) { - switch (true) { - case $public instanceof EC\PublicKey: - $public = $public->getEncodedCoordinates(); - case is_string($public): - $point = $private->multiply($public); - switch ($private->getCurve()) { - case 'Curve25519': - case 'Curve448': - $secret = $point; - break; - default: - // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned - $secret = substr($point, 1, (strlen($point) - 1) >> 1); - } - /* - if (($secret[0] & "\x80") === "\x80") { - $secret = "\0$secret"; - } - */ - return $secret; - default: - throw new \InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)'); - } - } - } - - /** - * Load the key - * - * @param string $key - * @param string $password optional - * @return AsymmetricKey - */ - public static function load($key, $password = false) - { - try { - return EC::load($key, $password); - } catch (NoKeyLoadedException $e) {} - - return parent::load($key, $password); - } - - /** - * OnLoad Handler - * - * @return bool - * @access protected - * @param array $components - */ - protected static function onLoad($components) - { - if (!isset($components['privateKey']) && !isset($components['publicKey'])) { - $new = new Parameters; - } else { - $new = isset($components['privateKey']) ? - new PrivateKey : - new PublicKey; - } - - $new->prime = $components['prime']; - $new->base = $components['base']; - - if (isset($components['privateKey'])) { - $new->privateKey = $components['privateKey']; - } - if (isset($components['publicKey'])) { - $new->publicKey = $components['publicKey']; - } - - return $new; - } - - /** - * Determines which hashing function should be used - * - * @access public - * @param string $hash - */ - public function withHash($hash) - { - throw new UnsupportedOperationException('DH does not use a hash algorithm'); - } - - /** - * Returns the hash algorithm currently being used - * - * @access public - */ - public function getHash() - { - throw new UnsupportedOperationException('DH does not use a hash algorithm'); - } - - /** - * Returns the parameters - * - * A public / private key is only returned if the currently loaded "key" contains an x or y - * value. - * - * @see self::getPublicKey() - * @access public - * @return mixed - */ - public function getParameters() - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - $key = $type::saveParameters($this->prime, $this->base); - return self::load($key, 'PKCS1'); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php deleted file mode 100644 index 368b187fe..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; - -/** - * "PKCS1" Formatted DH Key Handler - * - * @package DH - * @author Jim Wigginton - * @access public - */ -abstract class PKCS1 extends Progenitor -{ - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); - if (!is_array($components)) { - throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); - } - - return $components; - } - - /** - * Convert EC parameters to the appropriate format - * - * @access public - * @return string - */ - public static function saveParameters(BigInteger $prime, BigInteger $base, array $options = []) - { - $params = [ - 'prime' => $prime, - 'base' => $base - ]; - $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); - - return "-----BEGIN DH PARAMETERS-----\r\n" . - chunk_split(base64_encode($params), 64) . - "-----END DH PARAMETERS-----\r\n"; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php deleted file mode 100644 index e69fcee6e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,157 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Common\Functions\Strings; - -/** - * PKCS#8 Formatted DH Key Handler - * - * @package DH - * @author Jim Wigginton - * @access public - */ -abstract class PKCS8 extends Progenitor -{ - /** - * OID Name - * - * @var string - * @access private - */ - const OID_NAME = 'dhKeyAgreement'; - - /** - * OID Value - * - * @var string - * @access private - */ - const OID_VALUE = '1.2.840.113549.1.3.1'; - - /** - * Child OIDs loaded - * - * @var bool - * @access private - */ - protected static $childOIDsLoaded = false; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $isPublic = strpos($key, 'PUBLIC') !== false; - - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; - - switch (true) { - case !$isPublic && $type == 'publicKey': - throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); - case $isPublic && $type == 'privateKey': - throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); - } - - $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER of parameters'); - } - $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); - if (!is_array($components)) { - throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); - } - - $decoded = ASN1::decodeBER($key[$type]); - switch (true) { - case empty($decoded): - case !is_array($decoded): - case !isset($decoded[0]['content']): - case !$decoded[0]['content'] instanceof BigInteger: - throw new \RuntimeException('Unable to decode BER of parameters'); - } - $components[$type] = $decoded[0]['content']; - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $prime - * @param \phpseclib3\Math\BigInteger $base - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Math\BigInteger $publicKey - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $prime, BigInteger $base, BigInteger $privateKey, BigInteger $publicKey, $password = '', array $options = []) - { - $params = [ - 'prime' => $prime, - 'base' => $base - ]; - $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($privateKey, ['type' => ASN1::TYPE_INTEGER]); - return self::wrapPrivateKey($key, [], $params, $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $prime - * @param \phpseclib3\Math\BigInteger $base - * @param \phpseclib3\Math\BigInteger $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $prime, BigInteger $base, BigInteger $publicKey, array $options = []) - { - $params = [ - 'prime' => $prime, - 'base' => $base - ]; - $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($publicKey, ['type' => ASN1::TYPE_INTEGER]); - return self::wrapPublicKey($key, $params); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php deleted file mode 100644 index d36283d03..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH; - -use phpseclib3\Crypt\DH; - -/** - * DH Parameters - * - * @package DH - * @author Jim Wigginton - * @access public - */ -class Parameters extends DH -{ - /** - * Returns the parameters - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type = 'PKCS1', array $options = []) - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - return $type::saveParameters($this->prime, $this->base, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php deleted file mode 100644 index 8756b4197..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH; - -use phpseclib3\Crypt\DH; -use phpseclib3\Crypt\Common; - -/** - * DH Private Key - * - * @package DH - * @author Jim Wigginton - * @access public - */ -class PrivateKey extends DH -{ - use Common\Traits\PasswordProtected; - - /** - * Private Key - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $privateKey; - - /** - * Public Key - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $publicKey; - - /** - * Returns the public key - * - * @access public - * @return DH - */ - public function getPublicKey() - { - $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); - - if (!isset($this->publicKey)) { - $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); - } - - $key = $type::savePublicKey($this->prime, $this->base, $this->publicKey); - - return DH::loadFormat('PKCS8', $key); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); - - if (!isset($this->publicKey)) { - $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); - } - - return $type::savePrivateKey($this->prime, $this->base, $this->privateKey, $this->publicKey, $this->password, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php deleted file mode 100644 index 9670e28a1..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH; - -use phpseclib3\Crypt\DH; -use phpseclib3\Crypt\Common; - -/** - * DH Public Key - * - * @package DH - * @author Jim Wigginton - * @access public - */ -class PublicKey extends DH -{ - use Common\Traits\Fingerprint; - - /** - * Returns the public key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - return $type::savePublicKey($this->prime, $this->base, $this->publicKey, $options); - } - - /** - * Returns the public key as a BigInteger - * - * @return \phpseclib3\Math\BigInteger - */ - public function toBigInteger() - { - return $this->publicKey; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php deleted file mode 100644 index b368d83f5..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php +++ /dev/null @@ -1,344 +0,0 @@ - - * getPublicKey(); - * - * $plaintext = 'terrafrost'; - * - * $signature = $private->sign($plaintext); - * - * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; - * ?> - * - * - * @category Crypt - * @package DSA - * @author Jim Wigginton - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\DSA\PrivateKey; -use phpseclib3\Crypt\DSA\PublicKey; -use phpseclib3\Crypt\DSA\Parameters; -use phpseclib3\Math\BigInteger; -use phpseclib3\Exception\InsufficientSetupException; - -/** - * Pure-PHP FIPS 186-4 compliant implementation of DSA. - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -abstract class DSA extends AsymmetricKey -{ - /** - * Algorithm Name - * - * @var string - * @access private - */ - const ALGORITHM = 'DSA'; - - /** - * DSA Prime P - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $p; - - /** - * DSA Group Order q - * - * Prime divisor of p-1 - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $q; - - /** - * DSA Group Generator G - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $g; - - /** - * DSA public key value y - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $y; - - /** - * Signature Format - * - * @var string - * @access private - */ - protected $sigFormat; - - /** - * Signature Format (Short) - * - * @var string - * @access private - */ - protected $shortFormat; - - /** - * Create DSA parameters - * - * @access public - * @param int $L - * @param int $N - * @return \phpseclib3\Crypt\DSA|bool - */ - public static function createParameters($L = 2048, $N = 224) - { - self::initialize_static_variables(); - - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - switch (true) { - case $N == 160: - /* - in FIPS 186-1 and 186-2 N was fixed at 160 whereas K had an upper bound of 1024. - RFC 4253 (SSH Transport Layer Protocol) references FIPS 186-2 and as such most - SSH DSA implementations only support keys with an N of 160. - puttygen let's you set the size of L (but not the size of N) and uses 2048 as the - default L value. that's not really compliant with any of the FIPS standards, however, - for the purposes of maintaining compatibility with puttygen, we'll support it - */ - //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160: - // FIPS 186-3 changed this as follows: - //case $L == 1024 && $N == 160: - case $L == 2048 && $N == 224: - case $L == 2048 && $N == 256: - case $L == 3072 && $N == 256: - break; - default: - throw new \InvalidArgumentException('Invalid values for N and L'); - } - - $two = new BigInteger(2); - - $q = BigInteger::randomPrime($N); - $divisor = $q->multiply($two); - - do { - $x = BigInteger::random($L); - list(, $c) = $x->divide($divisor); - $p = $x->subtract($c->subtract(self::$one)); - } while ($p->getLength() != $L || !$p->isPrime()); - - $p_1 = $p->subtract(self::$one); - list($e) = $p_1->divide($q); - - // quoting http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#page=50 , - // "h could be obtained from a random number generator or from a counter that - // changes after each use". PuTTY (sshdssg.c) starts h off at 1 and increments - // it on each loop. wikipedia says "commonly h = 2 is used" so we'll just do that - $h = clone $two; - while (true) { - $g = $h->powMod($e, $p); - if (!$g->equals(self::$one)) { - break; - } - $h = $h->add(self::$one); - } - - $dsa = new Parameters; - $dsa->p = $p; - $dsa->q = $q; - $dsa->g = $g; - - return $dsa; - } - - /** - * Create public / private key pair. - * - * This method is a bit polymorphic. It can take a DSA/Parameters object, L / N as two distinct parameters or - * no parameters (at which point L and N will be generated with this method) - * - * Returns the private key, from which the publickey can be extracted - * - * @param int[] ...$args - * @access public - * @return DSA\PrivateKey - */ - public static function createKey(...$args) - { - self::initialize_static_variables(); - - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - if (count($args) == 2 && is_int($args[0]) && is_int($args[1])) { - $params = self::createParameters($args[0], $args[1]); - } else if (count($args) == 1 && $args[0] instanceof Parameters) { - $params = $args[0]; - } else if (!count($args)) { - $params = self::createParameters(); - } else { - throw new InsufficientSetupException('Valid parameters are either two integers (L and N), a single DSA object or no parameters at all.'); - } - - $private = new PrivateKey; - $private->p = $params->p; - $private->q = $params->q; - $private->g = $params->g; - - $private->x = BigInteger::randomRange(self::$one, $private->q->subtract(self::$one)); - $private->y = $private->g->powMod($private->x, $private->p); - - //$public = clone $private; - //unset($public->x); - - return $private - ->withHash($params->hash->getHash()) - ->withSignatureFormat($params->shortFormat); - } - - /** - * OnLoad Handler - * - * @return bool - * @access protected - * @param array $components - */ - protected static function onLoad($components) - { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - if (!isset($components['x']) && !isset($components['y'])) { - $new = new Parameters; - } else if (isset($components['x'])) { - $new = new PrivateKey; - $new->x = $components['x']; - } else { - $new = new PublicKey; - } - - $new->p = $components['p']; - $new->q = $components['q']; - $new->g = $components['g']; - - if (isset($components['y'])) { - $new->y = $components['y']; - } - - return $new; - } - - /** - * Constructor - * - * PublicKey and PrivateKey objects can only be created from abstract RSA class - */ - protected function __construct() - { - $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); - $this->shortFormat = 'ASN1'; - - parent::__construct(); - } - - /** - * Returns the key size - * - * More specifically, this L (the length of DSA Prime P) and N (the length of DSA Group Order q) - * - * @access public - * @return array - */ - public function getLength() - { - return ['L' => $this->p->getLength(), 'N' => $this->q->getLength()]; - } - - /** - * Returns the current engine being used - * - * @see self::useInternalEngine() - * @see self::useBestEngine() - * @access public - * @return string - */ - public function getEngine() - { - return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? - 'OpenSSL' : 'PHP'; - } - - /** - * Returns the parameters - * - * A public / private key is only returned if the currently loaded "key" contains an x or y - * value. - * - * @see self::getPublicKey() - * @access public - * @return mixed - */ - public function getParameters() - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - $key = $type::saveParameters($this->p, $this->q, $this->g); - return DSA::load($key, 'PKCS1') - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - } - - /** - * Determines the signature padding mode - * - * Valid values are: ASN1, SSH2, Raw - * - * @access public - * @param string $format - */ - public function withSignatureFormat($format) - { - $new = clone $this; - $new->shortFormat = $format; - $new->sigFormat = self::validatePlugin('Signature', $format); - return $new; - } - - /** - * Returns the signature format currently being used - * - * @access public - */ - public function getSignatureFormat() - { - return $this->shortFormat; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php deleted file mode 100644 index bf2d9860c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; - -/** - * OpenSSH Formatted DSA Key Handler - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -abstract class OpenSSH extends Progenitor -{ - /** - * Supported Key Types - * - * @var array - */ - protected static $types = ['ssh-dss']; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $parsed = parent::load($key, $password); - - if (isset($parsed['paddedKey'])) { - list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); - if ($type != $parsed['type']) { - throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); - } - - list($p, $q, $g, $y, $x, $comment) = Strings::unpackSSH2('i5s', $parsed['paddedKey']); - - return compact('p', 'q', 'g', 'y', 'x', 'comment'); - } - - list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $parsed['publicKey']); - - $comment = $parsed['comment']; - - return compact('p', 'q', 'g', 'y', 'comment'); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) - { - if ($q->getLength() != 160) { - throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); - } - - // from : - // string "ssh-dss" - // mpint p - // mpint q - // mpint g - // mpint y - $DSAPublicKey = Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $DSAPublicKey; - } - - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - $DSAPublicKey = 'ssh-dss ' . base64_encode($DSAPublicKey) . ' ' . $comment; - - return $DSAPublicKey; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) - { - $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => true]); - $privateKey = Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php deleted file mode 100644 index 757487377..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use ParagonIE\ConstantTime\Base64; - -/** - * PKCS#1 Formatted DSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class PKCS1 extends Progenitor -{ - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - $key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); - if (is_array($key)) { - return $key; - } - - $key = ASN1::asn1map($decoded[0], Maps\DSAPrivateKey::MAP); - if (is_array($key)) { - return $key; - } - - $key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); - if (is_array($key)) { - return $key; - } - - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - /** - * Convert DSA parameters to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @return string - */ - public static function saveParameters(BigInteger $p, BigInteger $q, BigInteger $g) - { - $key = [ - 'p' => $p, - 'q' => $q, - 'g' => $g - ]; - - $key = ASN1::encodeDER($key, Maps\DSAParams::MAP); - - return "-----BEGIN DSA PARAMETERS-----\r\n" . - chunk_split(Base64::encode($key), 64) . - "-----END DSA PARAMETERS-----\r\n"; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) - { - $key = [ - 'version' => 0, - 'p' => $p, - 'q' => $q, - 'g' => $g, - 'y' => $y, - 'x' => $x - ]; - - $key = ASN1::encodeDER($key, Maps\DSAPrivateKey::MAP); - - return self::wrapPrivateKey($key, 'DSA', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); - - return self::wrapPublicKey($key, 'DSA'); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php deleted file mode 100644 index 71f66eb06..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,170 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Common\Functions\Strings; - -/** - * PKCS#8 Formatted DSA Key Handler - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -abstract class PKCS8 extends Progenitor -{ - /** - * OID Name - * - * @var string - * @access private - */ - const OID_NAME = 'id-dsa'; - - /** - * OID Value - * - * @var string - * @access private - */ - const OID_VALUE = '1.2.840.10040.4.1'; - - /** - * Child OIDs loaded - * - * @var bool - * @access private - */ - protected static $childOIDsLoaded = false; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $isPublic = strpos($key, 'PUBLIC') !== false; - - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; - - switch (true) { - case !$isPublic && $type == 'publicKey': - throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); - case $isPublic && $type == 'privateKey': - throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); - } - - $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER of parameters'); - } - $components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); - if (!is_array($components)) { - throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); - } - - $decoded = ASN1::decodeBER($key[$type]); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - $var = $type == 'privateKey' ? 'x' : 'y'; - $components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); - if (!$components[$var] instanceof BigInteger) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - if (isset($key['meta'])) { - $components['meta'] = $key['meta']; - } - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) - { - $params = [ - 'p' => $p, - 'q' => $q, - 'g' => $g - ]; - $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($x, Maps\DSAPublicKey::MAP); - return self::wrapPrivateKey($key, [], $params, $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) - { - $params = [ - 'p' => $p, - 'q' => $q, - 'g' => $g - ]; - $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); - return self::wrapPublicKey($key, $params); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php deleted file mode 100644 index 5f71e6840..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,118 +0,0 @@ - 160 kinda useless, hence this handlers not supporting such keys. - * - * PHP version 5 - * - * @category Crypt - * @package DSA - * @author Jim Wigginton - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; - -/** - * PuTTY Formatted DSA Key Handler - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -abstract class PuTTY extends Progenitor -{ - /** - * Public Handler - * - * @var string - * @access private - */ - const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH'; - - /** - * Algorithm Identifier - * - * @var array - * @access private - */ - protected static $types = ['ssh-dss']; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $components = parent::load($key, $password); - if (!isset($components['private'])) { - return $components; - } - extract($components); - unset($components['public'], $components['private']); - - list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $public); - list($x) = Strings::unpackSSH2('i', $private); - - return compact('p', 'q', 'g', 'y', 'x', 'comment'); - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = false, array $options = []) - { - if ($q->getLength() != 160) { - throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); - } - - $public = Strings::packSSH2('iiii', $p, $q, $g, $y); - $private = Strings::packSSH2('i', $x); - - return self::wrapPrivateKey($public, $private, 'ssh-dsa', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - if ($q->getLength() != 160) { - throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); - } - - return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dsa'); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php deleted file mode 100644 index 04eba721b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; - -/** - * Raw DSA Key Handler - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -abstract class Raw -{ - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param array $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!is_array($key)) { - throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); - } - - switch (true) { - case !isset($key['p']) || !isset($key['q']) || !isset($key['g']): - case !$key['p'] instanceof BigInteger: - case !$key['q'] instanceof BigInteger: - case !$key['g'] instanceof BigInteger: - case !isset($key['x']) && !isset($key['y']): - case isset($key['x']) && !$key['x'] instanceof BigInteger: - case isset($key['y']) && !$key['y'] instanceof BigInteger: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; - - return array_intersect_key($key, $options); - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '') - { - return compact('p', 'q', 'g', 'y', 'x'); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - return compact('p', 'q', 'g', 'y'); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php deleted file mode 100644 index 42b3bbb99..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; - -/** - * XML Formatted DSA Key Handler - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -abstract class XML -{ - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $use_errors = libxml_use_internal_errors(true); - - $dom = new \DOMDocument(); - if (substr($key, 0, 5) != '' . $key . ''; - } - if (!$dom->loadXML($key)) { - throw new \UnexpectedValueException('Key does not appear to contain XML'); - } - $xpath = new \DOMXPath($dom); - $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; - foreach ($keys as $key) { - // $dom->getElementsByTagName($key) is case-sensitive - $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); - if (!$temp->length) { - continue; - } - $value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256); - switch ($key) { - case 'p': // a prime modulus meeting the [DSS] requirements - // Parameters P, Q, and G can be public and common to a group of users. They might be known - // from application context. As such, they are optional but P and Q must either both appear - // or both be absent - $components['p'] = $value; - break; - case 'q': // an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 - $components['q'] = $value; - break; - case 'g': // an integer with certain properties with respect to P and Q - $components['g'] = $value; - break; - case 'y': // G**X mod P (where X is part of the private key and not made public) - $components['y'] = $value; - // the remaining options do not do anything - case 'j': // (P - 1) / Q - // Parameter J is available for inclusion solely for efficiency as it is calculatable from - // P and Q - case 'seed': // a DSA prime generation seed - // Parameters seed and pgenCounter are used in the DSA prime number generation algorithm - // specified in [DSS]. As such, they are optional but must either both be present or both - // be absent - case 'pgencounter': // a DSA prime generation counter - } - } - - libxml_use_internal_errors($use_errors); - - if (!isset($components['y'])) { - throw new \UnexpectedValueException('Key is missing y component'); - } - - switch (true) { - case !isset($components['p']): - case !isset($components['q']): - case !isset($components['g']): - return ['y' => $components['y']]; - } - - return $components; - } - - /** - * Convert a public key to the appropriate format - * - * See https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue - * - * @access public - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - return "\r\n" . - '

      ' . Base64::encode($p->toBytes()) . "

      \r\n" . - ' ' . Base64::encode($q->toBytes()) . "\r\n" . - ' ' . Base64::encode($g->toBytes()) . "\r\n" . - ' ' . Base64::encode($y->toBytes()) . "\r\n" . - '
      '; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php deleted file mode 100644 index a9c29a346..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Signature; - -use phpseclib3\Math\BigInteger; -use phpseclib3\File\ASN1 as Encoder; -use phpseclib3\File\ASN1\Maps; - -/** - * ASN1 Signature Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class ASN1 -{ - /** - * Loads a signature - * - * @access public - * @param string $sig - * @return array|bool - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $decoded = Encoder::decodeBER($sig); - if (empty($decoded)) { - return false; - } - $components = Encoder::asn1map($decoded[0], Maps\DssSigValue::MAP); - - return $components; - } - - /** - * Returns a signature in the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - return Encoder::encodeDER(compact('r', 's'), Maps\DssSigValue::MAP); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php deleted file mode 100644 index e362e41bb..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Signature; - -use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; - -/** - * Raw DSA Signature Handler - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -abstract class Raw extends Progenitor -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php deleted file mode 100644 index 39f1f6cef..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Signature; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; - -/** - * SSH2 Signature Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class SSH2 -{ - /** - * Loads a signature - * - * @access public - * @param string $sig - * @return mixed - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $result = Strings::unpackSSH2('ss', $sig); - if ($result === false) { - return false; - } - list($type, $blob) = $result; - if ($type != 'ssh-dss' || strlen($blob) != 40) { - return false; - } - - return [ - 'r' => new BigInteger(substr($blob, 0, 20), 256), - 's' => new BigInteger(substr($blob, 20), 256) - ]; - } - - /** - * Returns a signature in the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - if ($r->getLength() > 160 || $s->getLength() > 160) { - return false; - } - return Strings::packSSH2('ss', 'ssh-dss', - str_pad($r->toBytes(), 20, "\0", STR_PAD_LEFT) . - str_pad($s->toBytes(), 20, "\0", STR_PAD_LEFT) - ); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php deleted file mode 100644 index 3f36e9624..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA; - -use phpseclib3\Crypt\DSA; - -/** - * DSA Parameters - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -class Parameters extends DSA -{ - /** - * Returns the parameters - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type = 'PKCS1', array $options = []) - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - return $type::saveParameters($this->p, $this->q, $this->g, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php deleted file mode 100644 index c976f2cf6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA; - -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common; - -/** - * DSA Private Key - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -class PrivateKey extends DSA implements Common\PrivateKey -{ - use Common\Traits\PasswordProtected; - - /** - * DSA secret exponent x - * - * @var \phpseclib3\Math\BigInteger - * @access private - */ - protected $x; - - /** - * Returns the public key - * - * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key - * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. - * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this - * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g - * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified - * by getting a DSA PKCS8 public key: - * - * "openssl dsa -in private.dsa -pubout -outform PEM" - * - * ie. just swap out rsa with dsa in the rsa command above. - * - * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA - * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature - * without the parameters and the PKCS1 DSA public key format does not include the parameters. - * - * @see self::getPrivateKey() - * @access public - * @return mixed - */ - public function getPublicKey() - { - $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); - - if (!isset($this->y)) { - $this->y = $this->g->powMod($this->x, $this->p); - } - - $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); - - return DSA::loadFormat('PKCS8', $key) - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - } - - /** - * Create a signature - * - * @see self::verify() - * @access public - * @param string $message - * @return mixed - */ - public function sign($message) - { - $format = $this->sigFormat; - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $signature = ''; - $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); - - if ($result) { - if ($this->shortFormat == 'ASN1') { - return $signature; - } - - extract(ASN1Signature::load($signature)); - - return $format::save($r, $s); - } - } - - $h = $this->hash->hash($message); - $h = $this->bits2int($h); - - while (true) { - $k = BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); - $r = $this->g->powMod($k, $this->p); - list(, $r) = $r->divide($this->q); - if ($r->equals(self::$zero)) { - continue; - } - $kinv = $k->modInverse($this->q); - $temp = $h->add($this->x->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($this->q); - if (!$s->equals(self::$zero)) { - break; - } - } - - // the following is an RFC6979 compliant implementation of deterministic DSA - // it's unused because it's mainly intended for use when a good CSPRNG isn't - // available. if phpseclib's CSPRNG isn't good then even key generation is - // suspect - /* - $h1 = $this->hash->hash($message); - $k = $this->computek($h1); - $r = $this->g->powMod($k, $this->p); - list(, $r) = $r->divide($this->q); - $kinv = $k->modInverse($this->q); - $h1 = $this->bits2int($h1); - $temp = $h1->add($this->x->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($this->q); - */ - - return $format::save($r, $s); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); - - if (!isset($this->y)) { - $this->y = $this->g->powMod($this->x, $this->p); - } - - return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php deleted file mode 100644 index 156476f06..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA; - -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; -use phpseclib3\Crypt\Common; - -/** - * DSA Public Key - * - * @package DSA - * @author Jim Wigginton - * @access public - */ -class PublicKey extends DSA implements Common\PublicKey -{ - use Common\Traits\Fingerprint; - - /** - * Verify a signature - * - * @see self::verify() - * @access public - * @param string $message - * @param string $signature - * @return mixed - */ - public function verify($message, $signature) - { - $format = $this->sigFormat; - - $params = $format::load($signature); - if ($params === false || count($params) != 2) { - return false; - } - extract($params); - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; - - $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash()); - - if ($result != -1) { - return (bool) $result; - } - } - - $q_1 = $this->q->subtract(self::$one); - if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) { - return false; - } - - $w = $s->modInverse($this->q); - $h = $this->hash->hash($message); - $h = $this->bits2int($h); - list(, $u1) = $h->multiply($w)->divide($this->q); - list(, $u2) = $r->multiply($w)->divide($this->q); - $v1 = $this->g->powMod($u1, $this->p); - $v2 = $this->y->powMod($u2, $this->p); - list(, $v) = $v1->multiply($v2)->divide($this->p); - list(, $v) = $v->divide($this->q); - - return $v->equals($r); - } - - /** - * Returns the public key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php deleted file mode 100644 index 2c0ab1979..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php +++ /dev/null @@ -1,477 +0,0 @@ - - * getPublicKey(); - * - * $plaintext = 'terrafrost'; - * - * $signature = $private->sign($plaintext); - * - * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; - * ?> - * - * - * @category Crypt - * @package EC - * @author Jim Wigginton - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\EC\PrivateKey; -use phpseclib3\Crypt\EC\PublicKey; -use phpseclib3\Crypt\EC\Parameters; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Curves\Ed448; -use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; -use phpseclib3\File\ASN1\Maps\ECParameters; -use phpseclib3\File\ASN1; -use phpseclib3\Math\BigInteger; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Exception\UnsupportedOperationException; - -/** - * Pure-PHP implementation of EC. - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class EC extends AsymmetricKey -{ - /** - * Algorithm Name - * - * @var string - * @access private - */ - const ALGORITHM = 'EC'; - - /** - * Public Key QA - * - * @var object[] - */ - protected $QA; - - /** - * Curve - * - * @var \phpseclib3\Crypt\EC\BaseCurves\Base - */ - protected $curve; - - /** - * Signature Format - * - * @var string - * @access private - */ - protected $format; - - /** - * Signature Format (Short) - * - * @var string - * @access private - */ - protected $shortFormat; - - /** - * Curve Name - * - * @var string - */ - private $curveName; - - /** - * Curve Order - * - * Used for deterministic ECDSA - * - * @var \phpseclib3\Math\BigInteger - */ - protected $q; - - /** - * Alias for the private key - * - * Used for deterministic ECDSA. AsymmetricKey expects $x. I don't like x because - * with x you have x * the base point yielding an (x, y)-coordinate that is the - * public key. But the x is different depending on which side of the equal sign - * you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate. - * - * @var \phpseclib3\Math\BigInteger - */ - protected $x; - - /** - * Context - * - * @var string - */ - protected $context; - - /** - * Create public / private key pair. - * - * @access public - * @param string $curve - * @return \phpseclib3\Crypt\EC\PrivateKey - */ - public static function createKey($curve) - { - self::initialize_static_variables(); - - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - $curve = strtolower($curve); - if (self::$engines['libsodium'] && $curve == 'ed25519' && function_exists('sodium_crypto_sign_keypair')) { - $kp = sodium_crypto_sign_keypair(); - - $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp)); - //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp)); - - $privatekey->curveName = 'Ed25519'; - //$publickey->curveName = $curve; - - return $privatekey; - } - - $privatekey = new PrivateKey; - - $curveName = $curve; - if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) { - $curveName = ucfirst($curveName); - } elseif (substr($curveName, 0, 10) == 'brainpoolp') { - $curveName = 'brainpoolP' . substr($curveName, 10); - } - $curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; - - if (!class_exists($curve)) { - throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported'); - } - - $reflect = new \ReflectionClass($curve); - $curveName = $reflect->isFinal() ? - $reflect->getParentClass()->getShortName() : - $reflect->getShortName(); - - $curve = new $curve(); - $privatekey->dA = $dA = $curve->createRandomMultiplier(); - if ($curve instanceof Curve25519 && self::$engines['libsodium']) { - //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000'); - //$QA = sodium_crypto_scalarmult($dA->toBytes(), $r); - $QA = sodium_crypto_box_publickey_from_secretkey($dA->toBytes()); - $privatekey->QA = [$curve->convertInteger(new BigInteger(strrev($QA), 256))]; - } else { - $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA); - } - $privatekey->curve = $curve; - - //$publickey = clone $privatekey; - //unset($publickey->dA); - //unset($publickey->x); - - $privatekey->curveName = $curveName; - //$publickey->curveName = $curveName; - - if ($privatekey->curve instanceof TwistedEdwardsCurve) { - return $privatekey->withHash($curve::HASH); - } - - return $privatekey; - } - - /** - * OnLoad Handler - * - * @return bool - * @access protected - * @param array $components - */ - protected static function onLoad($components) - { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - if (!isset($components['dA']) && !isset($components['QA'])) { - $new = new Parameters; - $new->curve = $components['curve']; - return $new; - } - - $new = isset($components['dA']) ? - new PrivateKey : - new PublicKey; - $new->curve = $components['curve']; - $new->QA = $components['QA']; - - if (isset($components['dA'])) { - $new->dA = $components['dA']; - } - - if ($new->curve instanceof TwistedEdwardsCurve) { - return $new->withHash($components['curve']::HASH); - } - - return $new; - } - - /** - * Constructor - * - * PublicKey and PrivateKey objects can only be created from abstract RSA class - */ - protected function __construct() - { - $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); - $this->shortFormat = 'ASN1'; - - parent::__construct(); - } - - /** - * Returns the curve - * - * Returns a string if it's a named curve, an array if not - * - * @access public - * @return string|array - */ - public function getCurve() - { - if ($this->curveName) { - return $this->curveName; - } - - if ($this->curve instanceof MontgomeryCurve) { - $this->curveName = $this->curve instanceof Curve25519 ? 'Curve25519' : 'Curve448'; - return $this->curveName; - } - - if ($this->curve instanceof TwistedEdwardsCurve) { - $this->curveName = $this->curve instanceof Ed25519 ? 'Ed25519' : 'Ed448'; - return $this->curveName; - } - - $params = $this->getParameters()->toString('PKCS8', ['namedCurve' => true]); - $decoded = ASN1::extractBER($params); - $decoded = ASN1::decodeBER($decoded); - $decoded = ASN1::asn1map($decoded[0], ECParameters::MAP); - if (isset($decoded['namedCurve'])) { - $this->curveName = $decoded['namedCurve']; - return $decoded['namedCurve']; - } - - if (!$namedCurves) { - PKCS1::useSpecifiedCurve(); - } - - return $decoded; - } - - /** - * Returns the key size - * - * Quoting https://tools.ietf.org/html/rfc5656#section-2, - * - * "The size of a set of elliptic curve domain parameters on a prime - * curve is defined as the number of bits in the binary representation - * of the field order, commonly denoted by p. Size on a - * characteristic-2 curve is defined as the number of bits in the binary - * representation of the field, commonly denoted by m. A set of - * elliptic curve domain parameters defines a group of order n generated - * by a base point P" - * - * @access public - * @return int - */ - public function getLength() - { - return $this->curve->getLength(); - } - - /** - * Returns the current engine being used - * - * @see self::useInternalEngine() - * @see self::useBestEngine() - * @access public - * @return string - */ - public function getEngine() - { - if ($this->curve instanceof TwistedEdwardsCurve) { - return $this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context) ? - 'libsodium' : 'PHP'; - } - - return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? - 'OpenSSL' : 'PHP'; - } - - /** - * Returns the public key coordinates as a string - * - * Used by ECDH - * - * @return string - */ - public function getEncodedCoordinates() - { - if ($this->curve instanceof MontgomeryCurve) { - return strrev($this->QA[0]->toBytes(true)); - } - if ($this->curve instanceof TwistedEdwardsCurve) { - return $this->curve->encodePoint($this->QA); - } - return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true); - } - - /** - * Returns the parameters - * - * @see self::getPublicKey() - * @access public - * @param string $type optional - * @return mixed - */ - public function getParameters($type = 'PKCS1') - { - $type = self::validatePlugin('Keys', $type, 'saveParameters'); - - $key = $type::saveParameters($this->curve); - - return EC::load($key, 'PKCS1') - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - } - - /** - * Determines the signature padding mode - * - * Valid values are: ASN1, SSH2, Raw - * - * @access public - * @param string $format - */ - public function withSignatureFormat($format) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - - $new = clone $this; - $new->shortFormat = $format; - $new->sigFormat = self::validatePlugin('Signature', $format); - return $new; - } - - /** - * Returns the signature format currently being used - * - * @access public - */ - public function getSignatureFormat() - { - return $this->shortFormat; - } - - /** - * Sets the context - * - * Used by Ed25519 / Ed448. - * - * @see self::sign() - * @see self::verify() - * @access public - * @param string $context optional - */ - public function withContext($context = null) - { - if (!$this->curve instanceof TwistedEdwardsCurve) { - throw new UnsupportedCurveException('Only Ed25519 and Ed448 support contexts'); - } - - $new = clone $this; - if (!isset($context)) { - $new->context = null; - return $new; - } - if (!is_string($context)) { - throw new \InvalidArgumentException('setContext expects a string'); - } - if (strlen($context) > 255) { - throw new \LengthException('The context is supposed to be, at most, 255 bytes long'); - } - $new->context = $context; - return $new; - } - - /** - * Returns the signature format currently being used - * - * @access public - */ - public function getContext() - { - return $this->context; - } - - /** - * Determines which hashing function should be used - * - * @access public - * @param string $hash - */ - public function withHash($hash) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - if ($this->curve instanceof Ed25519 && $hash != 'sha512') { - throw new UnsupportedAlgorithmException('Ed25519 only supports sha512 as a hash'); - } - if ($this->curve instanceof Ed448 && $hash != 'shake256-912') { - throw new UnsupportedAlgorithmException('Ed448 only supports shake256 with a length of 114 bytes'); - } - - return parent::withHash($hash); - } - - /** - * __toString() magic method - * - * @return string - */ - public function __toString() - { - if ($this->curve instanceof MontgomeryCurve) { - return ''; - } - - return parent::__toString(); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php deleted file mode 100644 index 6102c0630..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php +++ /dev/null @@ -1,220 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\Common\FiniteField; -use phpseclib3\Math\BigInteger; - -/** - * Base - * - * @package Prime - * @author Jim Wigginton - * @access public - */ -abstract class Base -{ - /** - * Doubles - * - * @var object[] - */ - protected $doubles; - - /** - * NAF Points - * - * @var int[] - */ - private $naf; - - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Finite Field Integer factory - * - * @var \phpseclib3\Math\FiniteField\Integer - */ - protected $factory; - - /** - * Returns a random integer - * - * @return object - */ - public function randomInteger() - { - return $this->factory->randomInteger(); - } - - /** - * Converts a BigInteger to a FiniteField integer - * - * @return object - */ - public function convertInteger(BigInteger $x) - { - return $this->factory->newInteger($x); - } - - /** - * Returns the length, in bytes, of the modulo - * - * @return integer - */ - public function getLengthInBytes() - { - return $this->factory->getLengthInBytes(); - } - - /** - * Returns the length, in bits, of the modulo - * - * @return integer - */ - public function getLength() - { - return $this->factory->getLength(); - } - - /** - * Multiply a point on the curve by a scalar - * - * Uses the montgomery ladder technique as described here: - * - * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder - * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 - * - * @return array - */ - public function multiplyPoint(array $p, FiniteField\Integer $d) - { - $alreadyInternal = isset($p[2]); - $r = $alreadyInternal ? - [[], $p] : - [[], $this->convertToInternal($p)]; - - $d = $d->toBits(); - for ($i = 0; $i < strlen($d); $i++) { - $d_i = (int) $d[$i]; - $r[1 - $d_i] = $this->addPoint($r[0], $r[1]); - $r[$d_i] = $this->doublePoint($r[$d_i]); - } - - return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]); - } - - /** - * Creates a random scalar multiplier - * - * @return FiniteField - */ - public function createRandomMultiplier() - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - $dA = BigInteger::randomRange($one, $this->order->subtract($one)); - return $this->factory->newInteger($dA); - } - - /** - * Sets the Order - */ - public function setOrder(BigInteger $order) - { - $this->order = $order; - } - - /** - * Returns the Order - * - * @return \phpseclib3\Math\BigInteger - */ - public function getOrder() - { - return $this->order; - } - - /** - * Use a custom defined modular reduction function - * - * @return object - */ - public function setReduction(callable $func) - { - $this->factory->setReduction($func); - } - - /** - * Returns the affine point - * - * @return object[] - */ - public function convertToAffine(array $p) - { - return $p; - } - - /** - * Converts an affine point to a jacobian coordinate - * - * @return object[] - */ - public function convertToInternal(array $p) - { - return $p; - } - - /** - * Negates a point - * - * @return object[] - */ - public function negatePoint(array $p) - { - $temp = [ - $p[0], - $p[1]->negate() - ]; - if (isset($p[2])) { - $temp[] = $p[2]; - } - return $temp; - } - - /** - * Multiply and Add Points - * - * @return int[] - */ - public function multiplyAddPoints(array $points, array $scalars) - { - $p1 = $this->convertToInternal($points[0]); - $p2 = $this->convertToInternal($points[1]); - $p1 = $this->multiplyPoint($p1, $scalars[0]); - $p2 = $this->multiplyPoint($p2, $scalars[1]); - $r = $this->addPoint($p1, $p2); - return $this->convertToAffine($r); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php deleted file mode 100644 index d984ba4b4..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php +++ /dev/null @@ -1,378 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BinaryField; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\BinaryField\Integer as BinaryInteger; - -/** - * Curves over y^2 + x*y = x^3 + a*x^2 + b - * - * @package Binary - * @author Jim Wigginton - * @access public - */ -class Binary extends Base -{ - /** - * Binary Field Integer factory - * - * @var \phpseclib3\Math\BinaryField - */ - protected $factory; - - /** - * Cofficient for x^1 - * - * @var object - */ - protected $a; - - /** - * Cofficient for x^0 - * - * @var object - */ - protected $b; - - /** - * Base Point - * - * @var object - */ - protected $p; - - /** - * The number one over the specified finite field - * - * @var object - */ - protected $one; - - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Sets the modulo - */ - public function setModulo(...$modulo) - { - $this->modulo = $modulo; - $this->factory = new BinaryField(...$modulo); - - $this->one = $this->factory->newInteger("\1"); - } - - /** - * Set coefficients a and b - * - * @param string $a - * @param string $b - */ - public function setCoefficients($a, $b) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger(pack('H*', $a)); - $this->b = $this->factory->newInteger(pack('H*', $b)); - } - - /** - * Set x and y coordinates for the base point - * - * @param string|BinaryInteger $x - * @param string|BinaryInteger $y - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !is_string($x) && !$x instanceof BinaryInteger: - throw new \UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); - case !is_string($y) && !$y instanceof BinaryInteger: - throw new \UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x, - is_string($y) ? $this->factory->newInteger(pack('H*', $y)) : $y - ]; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - if (!isset($p[2]) || !isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); - } - - // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html - - list($x1, $y1, $z1) = $p; - list($x2, $y2, $z2) = $q; - - $o1 = $z1->multiply($z1); - $b = $x2->multiply($o1); - - if ($z2->equals($this->one)) { - $d = $y2->multiply($o1)->multiply($z1); - $e = $x1->add($b); - $f = $y1->add($d); - $z3 = $e->multiply($z1); - $h = $f->multiply($x2)->add($z3->multiply($y2)); - $i = $f->add($z3); - $g = $z3->multiply($z3); - $p1 = $this->a->multiply($g); - $p2 = $f->multiply($i); - $p3 = $e->multiply($e)->multiply($e); - $x3 = $p1->add($p2)->add($p3); - $y3 = $i->multiply($x3)->add($g->multiply($h)); - - return [$x3, $y3, $z3]; - } - - $o2 = $z2->multiply($z2); - $a = $x1->multiply($o2); - $c = $y1->multiply($o2)->multiply($z2); - $d = $y2->multiply($o1)->multiply($z1); - $e = $a->add($b); - $f = $c->add($d); - $g = $e->multiply($z1); - $h = $f->multiply($x2)->add($g->multiply($y2)); - $z3 = $g->multiply($z2); - $i = $f->add($z3); - $p1 = $this->a->multiply($z3->multiply($z3)); - $p2 = $f->multiply($i); - $p3 = $e->multiply($e)->multiply($e); - $x3 = $p1->add($p2)->add($p3); - $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h)); - - return [$x3, $y3, $z3]; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - if (!isset($p[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html - - list($x1, $y1, $z1) = $p; - - $a = $x1->multiply($x1); - $b = $a->multiply($a); - - if ($z1->equals($this->one)) { - $x3 = $b->add($this->b); - $z3 = clone $x1; - $p1 = $a->add($y1)->add($z3)->multiply($this->b); - $p2 = $a->add($y1)->multiply($b); - $y3 = $p1->add($p2); - - return [$x3, $y3, $z3]; - } - - $c = $z1->multiply($z1); - $d = $c->multiply($c); - $x3 = $b->add($this->b->multiply($d->multiply($d))); - $z3 = $x1->multiply($c); - $p1 = $b->multiply($z3); - $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3); - $y3 = $p1->add($p2); - - return [$x3, $y3, $z3]; - } - - /** - * Returns the X coordinate and the derived Y coordinate - * - * Not supported because it is covered by patents. - * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html , - * - * "Due to patent issues the compressed option is disabled by default for binary curves - * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at - * compile time." - * - * @return array - */ - public function derivePoint($m) - { - throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $lhs = $y->multiply($y); - $lhs = $lhs->add($x->multiply($y)); - $x2 = $x->multiply($x); - $x3 = $x2->multiply($x); - $rhs = $x3->add($this->a->multiply($x2))->add($this->b); - - return $lhs->equals($rhs); - } - - /** - * Returns the modulo - * - * @return \phpseclib3\Math\BigInteger - */ - public function getModulo() - { - return $this->modulo; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getA() - { - return $this->a; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getB() - { - return $this->b; - } - - /** - * Returns the affine point - * - * A Jacobian Coordinate is of the form (x, y, z). - * To convert a Jacobian Coordinate to an Affine Point - * you do (x / z^2, y / z^3) - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[2])) { - return $p; - } - list($x, $y, $z) = $p; - $z = $this->one->divide($z); - $z2 = $z->multiply($z); - return [ - $x->multiply($z2), - $y->multiply($z2)->multiply($z) - ]; - } - - /** - * Converts an affine point to a jacobian coordinate - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - $p['fresh'] = true; - return $p; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php deleted file mode 100644 index 0a93f5126..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php +++ /dev/null @@ -1,325 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\PrimeField; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField\Integer as PrimeInteger; - -/** - * Curves over y^2 = x^3 + b - * - * @package KoblitzPrime - * @author Jim Wigginton - * @access public - */ -class KoblitzPrime extends Prime -{ - // don't overwrite setCoefficients() with one that only accepts one parameter so that - // one might be able to switch between KoblitzPrime and Prime more easily (for benchmarking - // purposes). - - /** - * Multiply and Add Points - * - * Uses a efficiently computable endomorphism to achieve a slight speedup - * - * Adapted from https://git.io/vxbrP - * - * @return int[] - */ - public function multiplyAddPoints(array $points, array $scalars) - { - static $zero, $one, $two; - if (!isset($two)) { - $two = new BigInteger(2); - $one = new BigInteger(1); - } - - if (!isset($this->beta)) { - // get roots - $inv = $this->one->divide($this->two)->negate(); - $s = $this->three->negate()->squareRoot()->multiply($inv); - $betas = [ - $inv->add($s), - $inv->subtract($s) - ]; - $this->beta = $betas[0]->compare($betas[1]) < 0 ? $betas[0] : $betas[1]; - //echo strtoupper($this->beta->toHex(true)) . "\n"; exit; - } - - if (!isset($this->basis)) { - $factory = new PrimeField($this->order); - $tempOne = $factory->newInteger($one); - $tempTwo = $factory->newInteger($two); - $tempThree = $factory->newInteger(new BigInteger(3)); - - $inv = $tempOne->divide($tempTwo)->negate(); - $s = $tempThree->negate()->squareRoot()->multiply($inv); - - $lambdas = [ - $inv->add($s), - $inv->subtract($s) - ]; - - $lhs = $this->multiplyPoint($this->p, $lambdas[0])[0]; - $rhs = $this->p[0]->multiply($this->beta); - $lambda = $lhs->equals($rhs) ? $lambdas[0] : $lambdas[1]; - - $this->basis = static::extendedGCD($lambda->toBigInteger(), $this->order); - ///* - foreach ($this->basis as $basis) { - echo strtoupper($basis['a']->toHex(true)) . "\n"; - echo strtoupper($basis['b']->toHex(true)) . "\n\n"; - } - exit; - //*/ - } - - $npoints = $nscalars = []; - for ($i = 0; $i < count($points); $i++) { - $p = $points[$i]; - $k = $scalars[$i]->toBigInteger(); - - // begin split - list($v1, $v2) = $this->basis; - - $c1 = $v2['b']->multiply($k); - list($c1, $r) = $c1->divide($this->order); - if ($this->order->compare($r->multiply($two)) <= 0) { - $c1 = $c1->add($one); - } - - $c2 = $v1['b']->negate()->multiply($k); - list($c2, $r) = $c2->divide($this->order); - if ($this->order->compare($r->multiply($two)) <= 0) { - $c2 = $c2->add($one); - } - - $p1 = $c1->multiply($v1['a']); - $p2 = $c2->multiply($v2['a']); - $q1 = $c1->multiply($v1['b']); - $q2 = $c2->multiply($v2['b']); - - $k1 = $k->subtract($p1)->subtract($p2); - $k2 = $q1->add($q2)->negate(); - // end split - - $beta = [ - $p[0]->multiply($this->beta), - $p[1], - clone $this->one - ]; - - if (isset($p['naf'])) { - $beta['naf'] = array_map(function($p) { - return [ - $p[0]->multiply($this->beta), - $p[1], - clone $this->one - ]; - }, $p['naf']); - $beta['nafwidth'] = $p['nafwidth']; - } - - if ($k1->isNegative()) { - $k1 = $k1->negate(); - $p = $this->negatePoint($p); - } - - if ($k2->isNegative()) { - $k2 = $k2->negate(); - $beta = $this->negatePoint($beta); - } - - $pos = 2 * $i; - $npoints[$pos] = $p; - $nscalars[$pos] = $this->factory->newInteger($k1); - - $pos++; - $npoints[$pos] = $beta; - $nscalars[$pos] = $this->factory->newInteger($k2); - } - - return parent::multiplyAddPoints($npoints, $nscalars); - } - - /** - * Returns the numerator and denominator of the slope - * - * @return FiniteField[] - */ - protected function doublePointHelper(array $p) - { - $numerator = $this->three->multiply($p[0])->multiply($p[0]); - $denominator = $this->two->multiply($p[1]); - return [$numerator, $denominator]; - } - - /** - * Doubles a jacobian coordinate on the curve - * - * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - * - * @return FiniteField[] - */ - protected function jacobianDoublePoint(array $p) - { - list($x1, $y1, $z1) = $p; - $a = $x1->multiply($x1); - $b = $y1->multiply($y1); - $c = $b->multiply($b); - $d = $x1->add($b); - $d = $d->multiply($d)->subtract($a)->subtract($c)->multiply($this->two); - $e = $this->three->multiply($a); - $f = $e->multiply($e); - $x3 = $f->subtract($this->two->multiply($d)); - $y3 = $e->multiply($d->subtract($x3))->subtract( - $this->eight->multiply($c)); - $z3 = $this->two->multiply($y1)->multiply($z1); - return [$x3, $y3, $z3]; - } - - /** - * Doubles a "fresh" jacobian coordinate on the curve - * - * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl - * - * @return FiniteField[] - */ - protected function jacobianDoublePointMixed(array $p) - { - list($x1, $y1) = $p; - $xx = $x1->multiply($x1); - $yy = $y1->multiply($y1); - $yyyy = $yy->multiply($yy); - $s = $x1->add($yy); - $s = $s->multiply($s)->subtract($xx)->subtract($yyyy)->multiply($this->two); - $m = $this->three->multiply($xx); - $t = $m->multiply($m)->subtract($this->two->multiply($s)); - $x3 = $t; - $y3 = $s->subtract($t); - $y3 = $m->multiply($y3)->subtract($this->eight->multiply($yyyy)); - $z3 = $this->two->multiply($y1); - return [$x3, $y3, $z3]; - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $lhs = $y->multiply($y); - $temp = $x->multiply($x)->multiply($x); - $rhs = $temp->add($this->b); - - return $lhs->equals($rhs); - } - - /** - * Calculates the parameters needed from the Euclidean algorithm as discussed at - * http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=148 - * - * @param BigInteger $u - * @param BigInteger $v - * @return BigInteger[] - */ - protected static function extendedGCD(BigInteger $u, BigInteger $v) - { - $one = new BigInteger(1); - $zero = new BigInteger(); - - $a = clone $one; - $b = clone $zero; - $c = clone $zero; - $d = clone $one; - - $stop = $v->bitwise_rightShift($v->getLength() >> 1); - - $a1 = clone $zero; - $b1 = clone $zero; - $a2 = clone $zero; - $b2 = clone $zero; - - $postGreatestIndex = 0; - - while (!$v->equals($zero)) { - list($q) = $u->divide($v); - - $temp = $u; - $u = $v; - $v = $temp->subtract($v->multiply($q)); - - $temp = $a; - $a = $c; - $c = $temp->subtract($a->multiply($q)); - - $temp = $b; - $b = $d; - $d = $temp->subtract($b->multiply($q)); - - if ($v->compare($stop) > 0) { - $a0 = $v; - $b0 = $c; - } else { - $postGreatestIndex++; - } - - if ($postGreatestIndex == 1) { - $a1 = $v; - $b1 = $c->negate(); - } - - if ($postGreatestIndex == 2) { - $rhs = $a0->multiply($a0)->add($b0->multiply($b0)); - $lhs = $v->multiply($v)->add($b->multiply($b)); - if ($lhs->compare($rhs) <= 0) { - $a2 = $a0; - $b2 = $b0->negate(); - } else { - $a2 = $v; - $b2 = $c->negate(); - } - - break; - } - } - - return [ - ['a' => $a1, 'b' => $b1], - ['a' => $a2, 'b' => $b2] - ]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php deleted file mode 100644 index b4bba650a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php +++ /dev/null @@ -1,285 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\PrimeField; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Math\PrimeField\Integer as PrimeInteger; - -/** - * Curves over y^2 = x^3 + a*x + x - * - * @package EC - * @author Jim Wigginton - * @access public - */ -class Montgomery extends Base -{ - /** - * Prime Field Integer factory - * - * @var \phpseclib3\Math\PrimeField - */ - protected $factory; - - /** - * Cofficient for x - * - * @var object - */ - protected $a; - - /** - * Constant used for point doubling - * - * @var object - */ - protected $a24; - - /** - * The Number Zero - * - * @var object - */ - protected $zero; - - /** - * The Number One - * - * @var object - */ - protected $one; - - /** - * Base Point - * - * @var object - */ - protected $p; - - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Sets the modulo - */ - public function setModulo(BigInteger $modulo) - { - $this->modulo = $modulo; - $this->factory = new PrimeField($modulo); - $this->zero = $this->factory->newInteger(new BigInteger()); - $this->one = $this->factory->newInteger(new BigInteger(1)); - } - - /** - * Set coefficients a - */ - public function setCoefficients(BigInteger $a) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger($a); - $two = $this->factory->newInteger(new BigInteger(2)); - $four = $this->factory->newInteger(new BigInteger(4)); - $this->a24 = $this->a->subtract($two)->divide($four); - } - - /** - * Set x and y coordinates for the base point - * - * @param BigInteger|PrimeInteger $x - * @param BigInteger|PrimeInteger $y - * @return PrimeInteger[] - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !$x instanceof BigInteger && !$x instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - case !$y instanceof BigInteger && !$y instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, - $y instanceof BigInteger ? $this->factory->newInteger($y) : $y - ]; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Doubles and adds a point on a curve - * - * See https://tools.ietf.org/html/draft-ietf-tls-curve25519-01#appendix-A.1.3 - * - * @return FiniteField[][] - */ - private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - return []; - } - - if (!isset($p[1])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); - } - - list($x2, $z2) = $p; - list($x3, $z3) = $q; - - $a = $x2->add($z2); - $aa = $a->multiply($a); - $b = $x2->subtract($z2); - $bb = $b->multiply($b); - $e = $aa->subtract($bb); - $c = $x3->add($z3); - $d = $x3->subtract($z3); - $da = $d->multiply($a); - $cb = $c->multiply($b); - $temp = $da->add($cb); - $x5 = $temp->multiply($temp); - $temp = $da->subtract($cb); - $z5 = $x1->multiply($temp->multiply($temp)); - $x4 = $aa->multiply($bb); - $temp = static::class == Curve25519::class ? $bb : $aa; - $z4 = $e->multiply($temp->add($this->a24->multiply($e))); - - return [ - [$x4, $z4], - [$x5, $z5] - ]; - } - - /** - * Multiply a point on the curve by a scalar - * - * Uses the montgomery ladder technique as described here: - * - * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder - * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 - * - * @return array - */ - public function multiplyPoint(array $p, Integer $d) - { - $p1 = [$this->one, $this->zero]; - $alreadyInternal = isset($x[1]); - $p2 = $this->convertToInternal($p); - $x = $p[0]; - - $b = $d->toBits(); - $b = str_pad($b, 256, '0', STR_PAD_LEFT); - for ($i = 0; $i < strlen($b); $i++) { - $b_i = (int) $b[$i]; - if ($b_i) { - list($p2, $p1) = $this->doubleAndAddPoint($p2, $p1, $x); - } else { - list($p1, $p2) = $this->doubleAndAddPoint($p1, $p2, $x); - } - } - - return $alreadyInternal ? $p1 : $this->convertToAffine($p1); - } - - /** - * Converts an affine point to an XZ coordinate - * - * From https://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html - * - * XZ coordinates represent x y as X Z satsfying the following equations: - * - * x=X/Z - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (empty($p)) { - return [clone $this->zero, clone $this->one]; - } - - if (isset($p[1])) { - return $p; - } - - $p[1] = clone $this->one; - - return $p; - } - - /** - * Returns the affine point - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[1])) { - return $p; - } - list($x, $z) = $p; - return [$x->divide($z)]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php deleted file mode 100644 index 07606cfa7..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php +++ /dev/null @@ -1,774 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\PrimeField; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField\Integer as PrimeInteger; - -/** - * Curves over y^2 = x^3 + a*x + b - * - * @package Prime - * @author Jim Wigginton - * @access public - */ -class Prime extends Base -{ - /** - * Prime Field Integer factory - * - * @var \phpseclib3\Math\PrimeFields - */ - protected $factory; - - /** - * Cofficient for x^1 - * - * @var object - */ - protected $a; - - /** - * Cofficient for x^0 - * - * @var object - */ - protected $b; - - /** - * Base Point - * - * @var object - */ - protected $p; - - /** - * The number one over the specified finite field - * - * @var object - */ - protected $one; - - /** - * The number two over the specified finite field - * - * @var object - */ - protected $two; - - /** - * The number three over the specified finite field - * - * @var object - */ - protected $three; - - /** - * The number four over the specified finite field - * - * @var object - */ - protected $four; - - /** - * The number eight over the specified finite field - * - * @var object - */ - protected $eight; - - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Sets the modulo - */ - public function setModulo(BigInteger $modulo) - { - $this->modulo = $modulo; - $this->factory = new PrimeField($modulo); - $this->two = $this->factory->newInteger(new BigInteger(2)); - $this->three = $this->factory->newInteger(new BigInteger(3)); - // used by jacobian coordinates - $this->one = $this->factory->newInteger(new BigInteger(1)); - $this->four = $this->factory->newInteger(new BigInteger(4)); - $this->eight = $this->factory->newInteger(new BigInteger(8)); - } - - /** - * Set coefficients a and b - */ - public function setCoefficients(BigInteger $a, BigInteger $b) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger($a); - $this->b = $this->factory->newInteger($b); - } - - /** - * Set x and y coordinates for the base point - * - * @param BigInteger|PrimeInteger $x - * @param BigInteger|PrimeInteger $y - * @return PrimeInteger[] - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !$x instanceof BigInteger && !$x instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - case !$y instanceof BigInteger && !$y instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, - $y instanceof BigInteger ? $this->factory->newInteger($y) : $y - ]; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Adds two "fresh" jacobian form on the curve - * - * @return FiniteField[] - */ - protected function jacobianAddPointMixedXY(array $p, array $q) - { - list($u1, $s1) = $p; - list($u2, $s2) = $q; - if ($u1->equals($u2)) { - if (!$s1->equals($s2)) { - return []; - } else { - return $this->doublePoint($p); - } - } - $h = $u2->subtract($u1); - $r = $s2->subtract($s1); - $h2 = $h->multiply($h); - $h3 = $h2->multiply($h); - $v = $u1->multiply($h2); - $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); - $y3 = $r->multiply( - $v->subtract($x3))->subtract( - $s1->multiply($h3)); - return [$x3, $y3, $h]; - } - - /** - * Adds one "fresh" jacobian form on the curve - * - * The second parameter should be the "fresh" one - * - * @return FiniteField[] - */ - protected function jacobianAddPointMixedX(array $p, array $q) - { - list($u1, $s1, $z1) = $p; - list($x2, $y2) = $q; - - $z12 = $z1->multiply($z1); - - $u2 = $x2->multiply($z12); - $s2 = $y2->multiply($z12->multiply($z1)); - if ($u1->equals($u2)) { - if (!$s1->equals($s2)) { - return []; - } else { - return $this->doublePoint($p); - } - } - $h = $u2->subtract($u1); - $r = $s2->subtract($s1); - $h2 = $h->multiply($h); - $h3 = $h2->multiply($h); - $v = $u1->multiply($h2); - $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); - $y3 = $r->multiply( - $v->subtract($x3))->subtract( - $s1->multiply($h3)); - $z3 = $h->multiply($z1); - return [$x3, $y3, $z3]; - } - - /** - * Adds two jacobian coordinates on the curve - * - * @return FiniteField[] - */ - protected function jacobianAddPoint(array $p, array $q) - { - list($x1, $y1, $z1) = $p; - list($x2, $y2, $z2) = $q; - - $z12 = $z1->multiply($z1); - $z22 = $z2->multiply($z2); - - $u1 = $x1->multiply($z22); - $u2 = $x2->multiply($z12); - $s1 = $y1->multiply($z22->multiply($z2)); - $s2 = $y2->multiply($z12->multiply($z1)); - if ($u1->equals($u2)) { - if (!$s1->equals($s2)) { - return []; - } else { - return $this->doublePoint($p); - } - } - $h = $u2->subtract($u1); - $r = $s2->subtract($s1); - $h2 = $h->multiply($h); - $h3 = $h2->multiply($h); - $v = $u1->multiply($h2); - $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); - $y3 = $r->multiply( - $v->subtract($x3))->subtract( - $s1->multiply($h3)); - $z3 = $h->multiply($z1)->multiply($z2); - return [$x3, $y3, $z3]; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - // use jacobian coordinates - if (isset($p[2]) && isset($q[2])) { - if (isset($p['fresh']) && isset($q['fresh'])) { - return $this->jacobianAddPointMixedXY($p, $q); - } - if (isset($p['fresh'])) { - return $this->jacobianAddPointMixedX($q, $p); - } - if (isset($q['fresh'])) { - return $this->jacobianAddPointMixedX($p, $q); - } - return $this->jacobianAddPoint($p, $q); - } - - if (isset($p[2]) || isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - if (!$p[1]->equals($q[1])) { - return []; - } else { // eg. doublePoint - list($numerator, $denominator) = $this->doublePointHelper($p); - } - } else { - $numerator = $q[1]->subtract($p[1]); - $denominator = $q[0]->subtract($p[0]); - } - $slope = $numerator->divide($denominator); - $x = $slope->multiply($slope)->subtract($p[0])->subtract($q[0]); - $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); - - return [$x, $y]; - } - - /** - * Returns the numerator and denominator of the slope - * - * @return FiniteField[] - */ - protected function doublePointHelper(array $p) - { - $numerator = $this->three->multiply($p[0])->multiply($p[0])->add($this->a); - $denominator = $this->two->multiply($p[1]); - return [$numerator, $denominator]; - } - - /** - * Doubles a jacobian coordinate on the curve - * - * @return FiniteField[] - */ - protected function jacobianDoublePoint(array $p) - { - list($x, $y, $z) = $p; - $x2 = $x->multiply($x); - $y2 = $y->multiply($y); - $z2 = $z->multiply($z); - $s = $this->four->multiply($x)->multiply($y2); - $m1 = $this->three->multiply($x2); - $m2 = $this->a->multiply($z2->multiply($z2)); - $m = $m1->add($m2); - $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); - $y1 = $m->multiply($s->subtract($x1))->subtract( - $this->eight->multiply($y2->multiply($y2))); - $z1 = $this->two->multiply($y)->multiply($z); - return [$x1, $y1, $z1]; - } - - /** - * Doubles a "fresh" jacobian coordinate on the curve - * - * @return FiniteField[] - */ - protected function jacobianDoublePointMixed(array $p) - { - list($x, $y) = $p; - $x2 = $x->multiply($x); - $y2 = $y->multiply($y); - $s = $this->four->multiply($x)->multiply($y2); - $m1 = $this->three->multiply($x2); - $m = $m1->add($this->a); - $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); - $y1 = $m->multiply($s->subtract($x1))->subtract( - $this->eight->multiply($y2->multiply($y2))); - $z1 = $this->two->multiply($y); - return [$x1, $y1, $z1]; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - // use jacobian coordinates - if (isset($p[2])) { - if (isset($p['fresh'])) { - return $this->jacobianDoublePointMixed($p); - } - return $this->jacobianDoublePoint($p); - } - - list($numerator, $denominator) = $this->doublePointHelper($p); - - $slope = $numerator->divide($denominator); - - $x = $slope->multiply($slope)->subtract($p[0])->subtract($p[0]); - $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); - - return [$x, $y]; - } - - /** - * Returns the X coordinate and the derived Y coordinate - * - * @return array - */ - public function derivePoint($m) - { - $y = ord(Strings::shift($m)); - $x = new BigInteger($m, 256); - $xp = $this->convertInteger($x); - switch ($y) { - case 2: $ypn = false; break; - case 3: $ypn = true; break; - default: - throw new \RuntimeException('Coordinate not in recognized format'); - } - $temp = $xp->multiply($this->a); - $temp = $xp->multiply($xp)->multiply($xp)->add($temp); - $temp = $temp->add($this->b); - $b = $temp->squareRoot(); - if (!$b) { - throw new \RuntimeException('Unable to derive Y coordinate'); - } - $bn = $b->isOdd(); - $yp = $ypn == $bn ? $b : $b->negate(); - return [$xp, $yp]; - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $lhs = $y->multiply($y); - $temp = $x->multiply($this->a); - $temp = $x->multiply($x)->multiply($x)->add($temp); - $rhs = $temp->add($this->b); - - return $lhs->equals($rhs); - } - - /** - * Returns the modulo - * - * @return \phpseclib3\Math\BigInteger - */ - public function getModulo() - { - return $this->modulo; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getA() - { - return $this->a; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getB() - { - return $this->b; - } - - /** - * Multiply and Add Points - * - * Adapted from https://git.io/vxPUH - * - * @return int[] - */ - public function multiplyAddPoints(array $points, array $scalars) - { - $length = count($points); - - foreach ($points as &$point) { - $point = $this->convertToInternal($point); - } - - $wnd = [$this->getNAFPoints($points[0], 7)]; - $wndWidth = [isset($points[0]['nafwidth']) ? $points[0]['nafwidth'] : 7]; - for ($i = 1; $i < $length; $i++) { - $wnd[] = $this->getNAFPoints($points[$i], 1); - $wndWidth[] = isset($points[$i]['nafwidth']) ? $points[$i]['nafwidth'] : 1; - } - - $naf = []; - - // comb all window NAFs - - $max = 0; - for ($i = $length - 1; $i >= 1; $i-= 2) { - $a = $i - 1; - $b = $i; - if ($wndWidth[$a] != 1 || $wndWidth[$b] != 1) { - $naf[$a] = $scalars[$a]->getNAF($wndWidth[$a]); - $naf[$b] = $scalars[$b]->getNAF($wndWidth[$b]); - $max = max(count($naf[$a]), count($naf[$b]), $max); - continue; - } - - $comb = [ - $points[$a], // 1 - null, // 3 - null, // 5 - $points[$b] // 7 - ]; - - $comb[1] = $this->addPoint($points[$a], $points[$b]); - $comb[2] = $this->addPoint($points[$a], $this->negatePoint($points[$b])); - - $index = [ - -3, /* -1 -1 */ - -1, /* -1 0 */ - -5, /* -1 1 */ - -7, /* 0 -1 */ - 0, /* 0 -1 */ - 7, /* 0 1 */ - 5, /* 1 -1 */ - 1, /* 1 0 */ - 3 /* 1 1 */ - ]; - - $jsf = self::getJSFPoints($scalars[$a], $scalars[$b]); - - $max = max(count($jsf[0]), $max); - if ($max > 0) { - $naf[$a] = array_fill(0, $max, 0); - $naf[$b] = array_fill(0, $max, 0); - } else { - $naf[$a] = []; - $naf[$b] = []; - } - - for ($j = 0; $j < $max; $j++) { - $ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0; - $jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0; - - $naf[$a][$j] = $index[3 * ($ja + 1) + $jb + 1]; - $naf[$b][$j] = 0; - $wnd[$a] = $comb; - } - } - - $acc = []; - $temp = [0, 0, 0, 0]; - for ($i = $max; $i >= 0; $i--) { - $k = 0; - while ($i >= 0) { - $zero = true; - for ($j = 0; $j < $length; $j++) { - $temp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0; - if ($temp[$j] != 0) { - $zero = false; - } - } - if (!$zero) { - break; - } - $k++; - $i--; - } - - if ($i >= 0) { - $k++; - } - while ($k--) { - $acc = $this->doublePoint($acc); - } - - if ($i < 0) { - break; - } - - for ($j = 0; $j < $length; $j++) { - $z = $temp[$j]; - $p = null; - if ($z == 0) { - continue; - } - $p = $z > 0 ? - $wnd[$j][($z - 1) >> 1] : - $this->negatePoint($wnd[$j][(-$z - 1) >> 1]); - $acc = $this->addPoint($acc, $p); - } - } - - return $this->convertToAffine($acc); - } - - /** - * Precomputes NAF points - * - * Adapted from https://git.io/vxY1f - * - * @return int[] - */ - private function getNAFPoints($point, $wnd) - { - if (isset($point['naf'])) { - return $point['naf']; - } - - $res = [$point]; - $max = (1 << $wnd) - 1; - $dbl = $max == 1 ? null : $this->doublePoint($point); - for ($i = 1; $i < $max; $i++) { - $res[] = $this->addPoint($res[$i - 1], $dbl); - } - - $point['naf'] = $res; - - /* - $str = ''; - foreach ($res as $re) { - $re[0] = bin2hex($re[0]->toBytes()); - $re[1] = bin2hex($re[1]->toBytes()); - $str.= " ['$re[0]', '$re[1]'],\r\n"; - } - file_put_contents('temp.txt', $str); - exit; - */ - - return $res; - } - - /** - * Precomputes points in Joint Sparse Form - * - * Adapted from https://git.io/vxrpD - * - * @return int[] - */ - private static function getJSFPoints(Integer $k1, Integer $k2) - { - static $three; - if (!isset($three)) { - $three = new BigInteger(3); - } - - $jsf = [[], []]; - $k1 = $k1->toBigInteger(); - $k2 = $k2->toBigInteger(); - $d1 = 0; - $d2 = 0; - - while ($k1->compare(new BigInteger(-$d1)) > 0 || $k2->compare(new BigInteger(-$d2)) > 0) { - // first phase - $m14 = $k1->testBit(0) + 2 * $k1->testBit(1); - $m14+= $d1; - $m14&= 3; - - $m24 = $k2->testBit(0) + 2 * $k2->testBit(1); - $m24+= $d2; - $m24&= 3; - - if ($m14 == 3) { - $m14 = -1; - } - if ($m24 == 3) { - $m24 = -1; - } - - $u1 = 0; - if ($m14 & 1) { // if $m14 is odd - $m8 = $k1->testBit(0) + 2 * $k1->testBit(1) + 4 * $k1->testBit(2); - $m8+= $d1; - $m8&= 7; - $u1 = ($m8 == 3 || $m8 == 5) && $m24 == 2 ? -$m14 : $m14; - } - $jsf[0][] = $u1; - - $u2 = 0; - if ($m24 & 1) { // if $m24 is odd - $m8 = $k2->testBit(0) + 2 * $k2->testBit(1) + 4 * $k2->testBit(2); - $m8+= $d2; - $m8&= 7; - $u2 = ($m8 == 3 || $m8 == 5) && $m14 == 2 ? -$m24 : $m24; - } - $jsf[1][] = $u2; - - // second phase - if (2 * $d1 == $u1 + 1) { - $d1 = 1 - $d1; - } - if (2 * $d2 == $u2 + 1) { - $d2 = 1 - $d2; - } - $k1 = $k1->bitwise_rightShift(1); - $k2 = $k2->bitwise_rightShift(1); - } - - return $jsf; - } - - /** - * Returns the affine point - * - * A Jacobian Coordinate is of the form (x, y, z). - * To convert a Jacobian Coordinate to an Affine Point - * you do (x / z^2, y / z^3) - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[2])) { - return $p; - } - list($x, $y, $z) = $p; - $z = $this->one->divide($z); - $z2 = $z->multiply($z); - return [ - $x->multiply($z2), - $y->multiply($z2)->multiply($z) - ]; - } - - /** - * Converts an affine point to a jacobian coordinate - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - $p['fresh'] = true; - return $p; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php deleted file mode 100644 index ff4ff2d4f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php +++ /dev/null @@ -1,219 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\PrimeField; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField\Integer as PrimeInteger; - -/** - * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 - * - * @package Prime - * @author Jim Wigginton - * @access public - */ -class TwistedEdwards extends Base -{ - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * Cofficient for x^2 - * - * @var object - */ - protected $a; - - /** - * Cofficient for x^2*y^2 - * - * @var object - */ - protected $d; - - /** - * Base Point - * - * @var object[] - */ - protected $p; - - /** - * The number zero over the specified finite field - * - * @var object - */ - protected $zero; - - /** - * The number one over the specified finite field - * - * @var object - */ - protected $one; - - /** - * The number two over the specified finite field - * - * @var object - */ - protected $two; - - /** - * Sets the modulo - */ - public function setModulo(BigInteger $modulo) - { - $this->modulo = $modulo; - $this->factory = new PrimeField($modulo); - $this->zero = $this->factory->newInteger(new BigInteger(0)); - $this->one = $this->factory->newInteger(new BigInteger(1)); - $this->two = $this->factory->newInteger(new BigInteger(2)); - } - - /** - * Set coefficients a and b - */ - public function setCoefficients(BigInteger $a, BigInteger $d) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger($a); - $this->d = $this->factory->newInteger($d); - } - - /** - * Set x and y coordinates for the base point - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !$x instanceof BigInteger && !$x instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - case !$y instanceof BigInteger && !$y instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, - $y instanceof BigInteger ? $this->factory->newInteger($y) : $y - ]; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getA() - { - return $this->a; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getD() - { - return $this->d; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Returns the affine point - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[2])) { - return $p; - } - list($x, $y, $z) = $p; - $z = $this->one->divide($z); - return [ - $x->multiply($z), - $y->multiply($z) - ]; - } - - /** - * Returns the modulo - * - * @return \phpseclib3\Math\BigInteger - */ - public function getModulo() - { - return $this->modulo; - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $x2 = $x->multiply($x); - $y2 = $y->multiply($y); - - $lhs = $this->a->multiply($x2)->add($y2); - $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); - - return $lhs->equals($rhs); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php deleted file mode 100644 index 06842d8cd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery; -use phpseclib3\Math\BigInteger; - -class Curve25519 extends Montgomery -{ - public function __construct() - { - // 2^255 - 19 - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); - $this->a24 = $this->factory->newInteger(new BigInteger('121666')); - $this->p = [$this->factory->newInteger(new BigInteger(9))]; - // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed - $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); - - /* - $this->setCoefficients( - new BigInteger('486662'), // a - ); - $this->setBasePoint( - new BigInteger(9), - new BigInteger('14781619447589544791020593568409986887264606134616475288964881837755586237401') - ); - */ - } - - /** - * Multiply a point on the curve by a scalar - * - * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 - * - * @return array - */ - public function multiplyPoint(array $p, Integer $d) - { - //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); - //return [$this->factory->newInteger(new BigInteger($r, 256))]; - - $d = $d->toBytes(); - $d&= "\xF8" . str_repeat("\xFF", 30) . "\x7F"; - $d = strrev($d); - $d|= "\x40"; - $d = $this->factory->newInteger(new BigInteger($d, -256)); - - return parent::multiplyPoint($p, $d); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php deleted file mode 100644 index 7dcf70847..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery; -use phpseclib3\Math\BigInteger; - -class Curve448 extends Montgomery -{ - public function __construct() - { - // 2^448 - 2^224 - 1 - $this->setModulo(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->a24 = $this->factory->newInteger(new BigInteger('39081')); - $this->p = [$this->factory->newInteger(new BigInteger(5))]; - // 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d - $this->setOrder(new BigInteger( - '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16)); - - /* - $this->setCoefficients( - new BigInteger('156326'), // a - ); - $this->setBasePoint( - new BigInteger(5), - new BigInteger( - '355293926785568175264127502063783334808976399387714271831880898' . - '435169088786967410002932673765864550910142774147268105838985595290' . - '606362') - ); - */ - } - - /** - * Multiply a point on the curve by a scalar - * - * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 - * - * @return array - */ - public function multiplyPoint(array $p, Integer $d) - { - //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); - //return [$this->factory->newInteger(new BigInteger($r, 256))]; - - $d = $d->toBytes(); - $d[0] = $d[0] & "\xFC"; - $d = strrev($d); - $d|= "\x80"; - $d = $this->factory->newInteger(new BigInteger($d, 256)); - - return parent::multiplyPoint($p, $d); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php deleted file mode 100644 index d4c3e37a1..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php +++ /dev/null @@ -1,334 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; - -class Ed25519 extends TwistedEdwards -{ - const HASH = 'sha512'; - /* - Per https://tools.ietf.org/html/rfc8032#page-6 EdDSA has several parameters, one of which is b: - - 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b - bits, and EdDSA signatures have exactly 2*b bits. b is - recommended to be a multiple of 8, so public key and signature - lengths are an integral number of octets. - - SIZE corresponds to b - */ - const SIZE = 32; - - public function __construct() - { - // 2^255 - 19 - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); - $this->setCoefficients( - // -1 - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC', 16), // a - // -121665/121666 - new BigInteger('52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3', 16) // d - ); - $this->setBasePoint( - new BigInteger('216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A', 16), - new BigInteger('6666666666666666666666666666666666666666666666666666666666666658', 16) - ); - $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); - // algorithm 14.47 from http://cacr.uwaterloo.ca/hac/about/chap14.pdf#page=16 - /* - $this->setReduction(function($x) { - $parts = $x->bitwise_split(255); - $className = $this->className; - - if (count($parts) > 2) { - list(, $r) = $x->divide($className::$modulo); - return $r; - } - - $zero = new BigInteger(); - $c = new BigInteger(19); - - switch (count($parts)) { - case 2: - list($qi, $ri) = $parts; - break; - case 1: - $qi = $zero; - list($ri) = $parts; - break; - case 0: - return $zero; - } - $r = $ri; - - while ($qi->compare($zero) > 0) { - $temp = $qi->multiply($c)->bitwise_split(255); - if (count($temp) == 2) { - list($qi, $ri) = $temp; - } else { - $qi = $zero; - list($ri) = $temp; - } - $r = $r->add($ri); - } - - while ($r->compare($className::$modulo) > 0) { - $r = $r->subtract($className::$modulo); - } - return $r; - }); - */ - } - - /** - * Recover X from Y - * - * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.1.3 - * - * Used by EC\Keys\Common.php - * - * @param BigInteger $y - * @param boolean $sign - * @return object[] - */ - public function recoverX(BigInteger $y, $sign) - { - $y = $this->factory->newInteger($y); - - $y2 = $y->multiply($y); - $u = $y2->subtract($this->one); - $v = $this->d->multiply($y2)->add($this->one); - $x2 = $u->divide($v); - if ($x2->equals($this->zero)) { - if ($sign) { - throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); - } - return clone $this->zero; - } - // find the square root - /* we don't do $x2->squareRoot() because, quoting from - https://tools.ietf.org/html/rfc8032#section-5.1.1: - - "For point decoding or "decompression", square roots modulo p are - needed. They can be computed using the Tonelli-Shanks algorithm or - the special case for p = 5 (mod 8). To find a square root of a, - first compute the candidate root x = a^((p+3)/8) (mod p)." - */ - $exp = $this->getModulo()->add(new BigInteger(3)); - $exp = $exp->bitwise_rightShift(3); - $x = $x2->pow($exp); - - // If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a square root. - if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { - $temp = $this->getModulo()->subtract(new BigInteger(1)); - $temp = $temp->bitwise_rightShift(2); - $temp = $this->two->pow($temp); - $x = $x->multiply($temp); - if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { - throw new \RuntimeException('Unable to recover X coordinate'); - } - } - if ($x->isOdd() != $sign) { - $x = $x->negate(); - } - - return [$x, $y]; - } - - /** - * Extract Secret Scalar - * - * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.1.5 - * - * Used by the various key handlers - * - * @param string $str - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function extractSecret($str) - { - if (strlen($str) != 32) { - throw new \LengthException('Private Key should be 32-bytes long'); - } - // 1. Hash the 32-byte private key using SHA-512, storing the digest in - // a 64-octet large buffer, denoted h. Only the lower 32 bytes are - // used for generating the public key. - $hash = new Hash('sha512'); - $h = $hash->hash($str); - $h = substr($h, 0, 32); - // 2. Prune the buffer: The lowest three bits of the first octet are - // cleared, the highest bit of the last octet is cleared, and the - // second highest bit of the last octet is set. - $h[0] = $h[0] & chr(0xF8); - $h = strrev($h); - $h[0] = ($h[0] & chr(0x3F)) | chr(0x40); - // 3. Interpret the buffer as the little-endian integer, forming a - // secret scalar s. - $dA = new BigInteger($h, 256); - $dA = $this->factory->newInteger($dA); - - $dA->secret = $str; - return $dA; - } - - /** - * Encode a point as a string - * - * @param array $point - * @return string - */ - public function encodePoint($point) - { - list($x, $y) = $point; - $y = $y->toBytes(); - $y[0] = $y[0] & chr(0x7F); - if ($x->isOdd()) { - $y[0] = $y[0] | chr(0x80); - } - $y = strrev($y); - - return $y; - } - - /** - * Creates a random scalar multiplier - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function createRandomMultiplier() - { - return $this->extractSecret(Random::string(32)); - } - - /** - * Converts an affine point to an extended homogeneous coordinate - * - * From https://tools.ietf.org/html/rfc8032#section-5.1.4 : - * - * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), - * with x = X/Z, y = Y/Z, x * y = T/Z. - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (empty($p)) { - return [clone $this->zero, clone $this->one, clone $this->one, clone $this->zero]; - } - - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - $p[3] = $p[0]->multiply($p[1]); - - return $p; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - if (!isset($p[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - // from https://tools.ietf.org/html/rfc8032#page-12 - - list($x1, $y1, $z1, $t1) = $p; - - $a = $x1->multiply($x1); - $b = $y1->multiply($y1); - $c = $this->two->multiply($z1)->multiply($z1); - $h = $a->add($b); - $temp = $x1->add($y1); - $e = $h->subtract($temp->multiply($temp)); - $g = $a->subtract($b); - $f = $c->add($g); - - $x3 = $e->multiply($f); - $y3 = $g->multiply($h); - $t3 = $e->multiply($h); - $z3 = $f->multiply($g); - - return [$x3, $y3, $z3, $t3]; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - if (!isset($p[2]) || !isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); - } - - // from https://tools.ietf.org/html/rfc8032#page-12 - - list($x1, $y1, $z1, $t1) = $p; - list($x2, $y2, $z2, $t2) = $q; - - $a = $y1->subtract($x1)->multiply($y2->subtract($x2)); - $b = $y1->add($x1)->multiply($y2->add($x2)); - $c = $t1->multiply($this->two)->multiply($this->d)->multiply($t2); - $d = $z1->multiply($this->two)->multiply($z2); - $e = $b->subtract($a); - $f = $d->subtract($c); - $g = $d->add($c); - $h = $b->add($a); - - $x3 = $e->multiply($f); - $y3 = $g->multiply($h); - $t3 = $e->multiply($h); - $z3 = $f->multiply($g); - - return [$x3, $y3, $z3, $t3]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php deleted file mode 100644 index 80ed33a8b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php +++ /dev/null @@ -1,267 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; - -class Ed448 extends TwistedEdwards -{ - const HASH = 'shake256-912'; - const SIZE = 57; - - public function __construct() - { - // 2^448 - 2^224 - 1 - $this->setModulo(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger(1), - // -39081 - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756', 16) - ); - $this->setBasePoint( - new BigInteger('4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324' . - 'A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E', 16), - new BigInteger('693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E' . - '05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14', 16) - ); - $this->setOrder(new BigInteger( - '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16)); - } - - /** - * Recover X from Y - * - * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.2.3 - * - * Used by EC\Keys\Common.php - * - * @param BigInteger $y - * @param boolean $sign - * @return object[] - */ - public function recoverX(BigInteger $y, $sign) - { - $y = $this->factory->newInteger($y); - - $y2 = $y->multiply($y); - $u = $y2->subtract($this->one); - $v = $this->d->multiply($y2)->subtract($this->one); - $x2 = $u->divide($v); - if ($x2->equals($this->zero)) { - if ($sign) { - throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); - } - return clone $this->zero; - } - // find the square root - $exp = $this->getModulo()->add(new BigInteger(1)); - $exp = $exp->bitwise_rightShift(2); - $x = $x2->pow($exp); - - if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { - throw new \RuntimeException('Unable to recover X coordinate'); - } - if ($x->isOdd() != $sign) { - $x = $x->negate(); - } - - return [$x, $y]; - } - - /** - * Extract Secret Scalar - * - * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.2.5 - * - * Used by the various key handlers - * - * @param string $str - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function extractSecret($str) - { - if (strlen($str) != 57) { - throw new \LengthException('Private Key should be 57-bytes long'); - } - // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the - // digest in a 114-octet large buffer, denoted h. Only the lower 57 - // bytes are used for generating the public key. - $hash = new Hash('shake256-912'); - $h = $hash->hash($str); - $h = substr($h, 0, 57); - // 2. Prune the buffer: The two least significant bits of the first - // octet are cleared, all eight bits the last octet are cleared, and - // the highest bit of the second to last octet is set. - $h[0] = $h[0] & chr(0xFC); - $h = strrev($h); - $h[0] = "\0"; - $h[1] = $h[1] | chr(0x80); - // 3. Interpret the buffer as the little-endian integer, forming a - // secret scalar s. - $dA = new BigInteger($h, 256); - $dA = $this->factory->newInteger($dA); - - $dA->secret = $str; - return $dA; - } - - /** - * Encode a point as a string - * - * @param array $point - * @return string - */ - public function encodePoint($point) - { - list($x, $y) = $point; - $y = "\0" . $y->toBytes(); - if ($x->isOdd()) { - $y[0] = $y[0] | chr(0x80); - } - $y = strrev($y); - - return $y; - } - - /** - * Creates a random scalar multiplier - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function createRandomMultiplier() - { - return $this->extractSecret(Random::string(57)); - } - - /** - * Converts an affine point to an extended homogeneous coordinate - * - * From https://tools.ietf.org/html/rfc8032#section-5.2.4 : - * - * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), - * with x = X/Z, y = Y/Z, x * y = T/Z. - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (empty($p)) { - return [clone $this->zero, clone $this->one, clone $this->one]; - } - - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - - return $p; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - if (!isset($p[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - // from https://tools.ietf.org/html/rfc8032#page-18 - - list($x1, $y1, $z1) = $p; - - $b = $x1->add($y1); - $b = $b->multiply($b); - $c = $x1->multiply($x1); - $d = $y1->multiply($y1); - $e = $c->add($d); - $h = $z1->multiply($z1); - $j = $e->subtract($this->two->multiply($h)); - - $x3 = $b->subtract($e)->multiply($j); - $y3 = $c->subtract($d)->multiply($e); - $z3 = $e->multiply($j); - - return [$x3, $y3, $z3]; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - if (!isset($p[2]) || !isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); - } - - // from https://tools.ietf.org/html/rfc8032#page-17 - - list($x1, $y1, $z1) = $p; - list($x2, $y2, $z2) = $q; - - $a = $z1->multiply($z2); - $b = $a->multiply($a); - $c = $x1->multiply($x2); - $d = $y1->multiply($y2); - $e = $this->d->multiply($c)->multiply($d); - $f = $b->subtract($e); - $g = $b->add($e); - $h = $x1->add($y1)->multiply($x2->add($y2)); - - $x3 = $a->multiply($f)->multiply($h->subtract($c)->subtract($d)); - $y3 = $a->multiply($g)->multiply($d->subtract($c)); - $z3 = $f->multiply($g); - - return [$x3, $y3, $z3]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php deleted file mode 100644 index 23a4e6d27..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP160r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); - $this->setCoefficients( - new BigInteger('340E7BE2A280EB74E2BE61BADA745D97E8F7C300', 16), - new BigInteger('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16) - ); - $this->setBasePoint( - new BigInteger('BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3', 16), - new BigInteger('1667CB477A1A8EC338F94741669C976316DA6321', 16) - ); - $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php deleted file mode 100644 index beafc34ba..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP160t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); - $this->setCoefficients( - new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620C', 16), // eg. -3 - new BigInteger('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16) - ); - $this->setBasePoint( - new BigInteger('B199B13B9B34EFC1397E64BAEB05ACC265FF2378', 16), - new BigInteger('ADD6718B7C7C1961F0991B842443772152C9E0AD', 16) - ); - $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php deleted file mode 100644 index 11afdadb0..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP192r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); - $this->setCoefficients( - new BigInteger('6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF', 16), - new BigInteger('469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9', 16) - ); - $this->setBasePoint( - new BigInteger('C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6', 16), - new BigInteger('14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F', 16) - ); - $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php deleted file mode 100644 index 71f956f29..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP192t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); - $this->setCoefficients( - new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294', 16), // eg. -3 - new BigInteger('13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79', 16) - ); - $this->setBasePoint( - new BigInteger('3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129', 16), - new BigInteger('097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9', 16) - ); - $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php deleted file mode 100644 index 83e49b026..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP224r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); - $this->setCoefficients( - new BigInteger('68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43', 16), - new BigInteger('2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B', 16) - ); - $this->setBasePoint( - new BigInteger('0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D', 16), - new BigInteger('58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD', 16) - ); - $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php deleted file mode 100644 index 97032a48c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP224t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); - $this->setCoefficients( - new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC', 16), // eg. -3 - new BigInteger('4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D', 16) - ); - $this->setBasePoint( - new BigInteger('6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580', 16), - new BigInteger('0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C', 16) - ); - $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php deleted file mode 100644 index 0d3860041..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP256r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); - $this->setCoefficients( - new BigInteger('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16), - new BigInteger('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16) - ); - $this->setBasePoint( - new BigInteger('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16), - new BigInteger('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16) - ); - $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php deleted file mode 100644 index 9c1d1cdbe..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP256t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); - $this->setCoefficients( - new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374', 16), // eg. -3 - new BigInteger('662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04', 16) - ); - $this->setBasePoint( - new BigInteger('A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4', 16), - new BigInteger('2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE', 16) - ); - $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php deleted file mode 100644 index a6253a714..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP320r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . - '2B9EC7893EC28FCD412B1F1B32E27', 16)); - $this->setCoefficients( - new BigInteger('3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4' . - '92F375A97D860EB4', 16), - new BigInteger('520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981' . - '6F5EB4AC8FB1F1A6', 16) - ); - $this->setBasePoint( - new BigInteger('43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7' . - '10AF8D0D39E20611', 16), - new BigInteger('14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7' . - 'D35245D1692E8EE1', 16) - ); - $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . - '82EC7EE8658E98691555B44C59311', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php deleted file mode 100644 index e62771859..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP320t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . - '2B9EC7893EC28FCD412B1F1B32E27', 16)); - $this->setCoefficients( - new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28' . - 'FCD412B1F1B32E24', 16), // eg. -3 - new BigInteger('A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE' . - 'B5B4FEF422340353', 16) - ); - $this->setBasePoint( - new BigInteger('925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF' . - '3357F624A21BED52', 16), - new BigInteger('63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B' . - '1B9BC0455FB0D2C3', 16) - ); - $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . - '82EC7EE8658E98691555B44C59311', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php deleted file mode 100644 index 5bc8a6d53..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP384r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . - '1874700133107EC53', 16)); - $this->setCoefficients( - new BigInteger( - '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503' . - 'AD4EB04A8C7DD22CE2826', 16), - new BigInteger( - '4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DB' . - 'C9943AB78696FA504C11', 16) - ); - $this->setBasePoint( - new BigInteger( - '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D' . - '646AAEF87B2E247D4AF1E', 16), - new BigInteger( - '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E464621779' . - '1811142820341263C5315', 16) - ); - $this->setOrder(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . - '03B883202E9046565', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php deleted file mode 100644 index 8bd4a790f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP384t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . - '1874700133107EC53', 16)); - $this->setCoefficients( - new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901' . - 'D1A71874700133107EC50', 16), // eg. -3 - new BigInteger( - '7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B8' . - '8805CED70355A33B471EE', 16) - ); - $this->setBasePoint( - new BigInteger( - '18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946' . - 'A5F54D8D0AA2F418808CC', 16), - new BigInteger( - '25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC' . - '2B2912675BF5B9E582928', 16) - ); - $this->setOrder(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . - '03B883202E9046565', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php deleted file mode 100644 index 8d22120fa..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP512r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . - '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16)); - $this->setCoefficients( - new BigInteger( - '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA82' . - '53AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA', 16), - new BigInteger( - '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C' . - '1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723', 16) - ); - $this->setBasePoint( - new BigInteger( - '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D' . - '0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822', 16), - new BigInteger( - '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5' . - 'F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892', 16) - ); - $this->setOrder(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . - '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php deleted file mode 100644 index 8566182e4..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP512t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . - '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16)); - $this->setCoefficients( - new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . - '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0', 16), // eg. -3 - new BigInteger( - '7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA23049' . - '76540F6450085F2DAE145C22553B465763689180EA2571867423E', 16) - ); - $this->setBasePoint( - new BigInteger( - '640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CD' . - 'B3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA', 16), - new BigInteger( - '5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEE' . - 'F216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332', 16) - ); - $this->setOrder(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . - '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php deleted file mode 100644 index a2e974ace..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistb233 extends sect233r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php deleted file mode 100644 index c3f25829f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistb409 extends sect409r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php deleted file mode 100644 index 2d3add6eb..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk163 extends sect163k1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php deleted file mode 100644 index 05efea40b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk233 extends sect233k1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php deleted file mode 100644 index 95420587e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk283 extends sect283k1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php deleted file mode 100644 index eb55ce7bd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk409 extends sect409k1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php deleted file mode 100644 index c600d79fb..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp192 extends secp192r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php deleted file mode 100644 index 5c4320ecf..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp224 extends secp224r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php deleted file mode 100644 index 56d0b5ad3..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp256 extends secp256r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php deleted file mode 100644 index 7a45babfc..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp384 extends secp384r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php deleted file mode 100644 index 167b058f6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp521 extends secp521r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php deleted file mode 100644 index df92a3951..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistt571 extends sect571k1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php deleted file mode 100644 index d329122a8..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class prime192v1 extends secp192r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php deleted file mode 100644 index f5dbfa6bf..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime192v2 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), - new BigInteger('CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', 16) - ); - $this->setBasePoint( - new BigInteger('EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', 16), - new BigInteger('6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php deleted file mode 100644 index 0bd83d372..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime192v3 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), - new BigInteger('22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', 16) - ); - $this->setBasePoint( - new BigInteger('7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', 16), - new BigInteger('38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php deleted file mode 100644 index e42e69256..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime239v1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), - new BigInteger('6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', 16) - ); - $this->setBasePoint( - new BigInteger('0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', 16), - new BigInteger('7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', 16) - ); - $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php deleted file mode 100644 index ad6a3a866..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime239v2 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), - new BigInteger('617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', 16) - ); - $this->setBasePoint( - new BigInteger('38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', 16), - new BigInteger('5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', 16) - ); - $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php deleted file mode 100644 index ad41cfe02..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime239v3 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), - new BigInteger('255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', 16) - ); - $this->setBasePoint( - new BigInteger('6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', 16), - new BigInteger('1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', 16) - ); - $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php deleted file mode 100644 index 8440514aa..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class prime256v1 extends secp256r1 -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php deleted file mode 100644 index 4f0600180..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp112r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); - $this->setCoefficients( - new BigInteger('DB7C2ABF62E35E668076BEAD2088', 16), - new BigInteger('659EF8BA043916EEDE8911702B22', 16) - ); - $this->setBasePoint( - new BigInteger('09487239995A5EE76B55F9C2F098', 16), - new BigInteger('A89CE5AF8724C0A23E0E0FF77500', 16) - ); - $this->setOrder(new BigInteger('DB7C2ABF62E35E7628DFAC6561C5', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php deleted file mode 100644 index e23e6b54d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp112r2 extends Prime -{ - public function __construct() - { - // same modulo as secp112r1 - $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); - $this->setCoefficients( - new BigInteger('6127C24C05F38A0AAAF65C0EF02C', 16), - new BigInteger('51DEF1815DB5ED74FCC34C85D709', 16) - ); - $this->setBasePoint( - new BigInteger('4BA30AB5E892B4E1649DD0928643', 16), - new BigInteger('ADCD46F5882E3747DEF36E956E97', 16) - ); - $this->setOrder(new BigInteger('36DF0AAFD8B8D7597CA10520D04B', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php deleted file mode 100644 index afe1336be..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp128r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC', 16), - new BigInteger('E87579C11079F43DD824993C2CEE5ED3', 16) - ); - $this->setBasePoint( - new BigInteger('161FF7528B899B2D0C28607CA52C5B86', 16), - new BigInteger('CF5AC8395BAFEB13C02DA292DDED7A83', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFE0000000075A30D1B9038A115', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php deleted file mode 100644 index 4e2719b12..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp128r2 extends Prime -{ - public function __construct() - { - // same as secp128r1 - $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('D6031998D1B3BBFEBF59CC9BBFF9AEE1', 16), - new BigInteger('5EEEFCA380D02919DC2C6558BB6D8A5D', 16) - ); - $this->setBasePoint( - new BigInteger('7B6AA5D85E572983E6FB32A7CDEBC140', 16), - new BigInteger('27B6916A894D3AEE7106FE805FC34B44', 16) - ); - $this->setOrder(new BigInteger('3FFFFFFF7FFFFFFFBE0024720613B5A3', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php deleted file mode 100644 index 80ff73e32..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -class secp160k1 extends KoblitzPrime -{ - public function __construct() - { - // same as secp160r2 - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); - $this->setCoefficients( - new BigInteger('0000000000000000000000000000000000000000', 16), - new BigInteger('0000000000000000000000000000000000000007', 16) - ); - $this->setBasePoint( - new BigInteger('3B4C382CE37AA192A4019E763036F4F5DD4D7EBB', 16), - new BigInteger('938CF935318FDCED6BC28286531733C3F03C4FEE', 16) - ); - $this->setOrder(new BigInteger('0100000000000000000001B8FA16DFAB9ACA16B6B3', 16)); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('0096341F1138933BC2F505', -16), - 'b' => new BigInteger('FF6E9D0418C67BB8D5F562', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('01BDCB3A09AAAABEAFF4A8', -16), - 'b' => new BigInteger('04D12329FF0EF498EA67', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('645B7345A143464942CC46D7CF4D5D1E1E6CBB68', -16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php deleted file mode 100644 index 5d7739c48..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp160r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC', 16), - new BigInteger('1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45', 16) - ); - $this->setBasePoint( - new BigInteger('4A96B5688EF573284664698968C38BB913CBFC82', 16), - new BigInteger('23A628553168947D59DCC912042351377AC5FB32', 16) - ); - $this->setOrder(new BigInteger('0100000000000000000001F4C8F927AED3CA752257', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php deleted file mode 100644 index 9b2789b41..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp160r2 extends Prime -{ - public function __construct() - { - // same as secp160k1 - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70', 16), - new BigInteger('B4E134D3FB59EB8BAB57274904664D5AF50388BA', 16) - ); - $this->setBasePoint( - new BigInteger('52DCB034293A117E1F4FF11B30F7199D3144CE6D', 16), - new BigInteger('FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E', 16) - ); - $this->setOrder(new BigInteger('0100000000000000000000351EE786A818F3A1A16B', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php deleted file mode 100644 index 79ff610cf..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -class secp192k1 extends KoblitzPrime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37', 16)); - $this->setCoefficients( - new BigInteger('000000000000000000000000000000000000000000000000', 16), - new BigInteger('000000000000000000000000000000000000000000000003', 16) - ); - $this->setBasePoint( - new BigInteger('DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D', 16), - new BigInteger('9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D', 16)); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('00B3FB3400DEC5C4ADCEB8655C', -16), - 'b' => new BigInteger('8EE96418CCF4CFC7124FDA0F', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('01D90D03E8F096B9948B20F0A9', -16), - 'b' => new BigInteger('42E49819ABBA9474E1083F6B', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('447A96E6C647963E2F7809FEAAB46947F34B0AA3CA0BBA74', -16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php deleted file mode 100644 index be7d38987..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp192r1 extends Prime -{ - public function __construct() - { - $modulo = new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16); - $this->setModulo($modulo); - - // algorithm 2.27 from http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=66 - /* in theory this should be faster than regular modular reductions save for one small issue. - to convert to / from base-2**8 with BCMath you have to call bcmul() and bcdiv() a lot. - to convert to / from base-2**8 with PHP64 you have to call base256_rshift() a lot. - in short, converting to / from base-2**8 is pretty expensive and that expense is - enough to offset whatever else might be gained by a simplified reduction algorithm. - now, if PHP supported unsigned integers things might be different. no bit-shifting - would be required for the PHP engine and it'd be a lot faster. but as is, BigInteger - uses base-2**31 or base-2**26 depending on whether or not the system is has a 32-bit - or a 64-bit OS. - */ - /* - $m_length = $this->getLengthInBytes(); - $this->setReduction(function($c) use ($m_length) { - $cBytes = $c->toBytes(); - $className = $this->className; - - if (strlen($cBytes) > 2 * $m_length) { - list(, $r) = $c->divide($className::$modulo); - return $r; - } - - $c = str_pad($cBytes, 48, "\0", STR_PAD_LEFT); - $c = array_reverse(str_split($c, 8)); - - $null = "\0\0\0\0\0\0\0\0"; - $s1 = new BigInteger($c[2] . $c[1] . $c[0], 256); - $s2 = new BigInteger($null . $c[3] . $c[3], 256); - $s3 = new BigInteger($c[4] . $c[4] . $null, 256); - $s4 = new BigInteger($c[5] . $c[5] . $c[5], 256); - - $r = $s1->add($s2)->add($s3)->add($s4); - while ($r->compare($className::$modulo) >= 0) { - $r = $r->subtract($className::$modulo); - } - - return $r; - }); - */ - - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), - new BigInteger('64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', 16) - ); - $this->setBasePoint( - new BigInteger('188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', 16), - new BigInteger('07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php deleted file mode 100644 index 6a2b9a82c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -class secp224k1 extends KoblitzPrime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D', 16)); - $this->setCoefficients( - new BigInteger('00000000000000000000000000000000000000000000000000000000', 16), - new BigInteger('00000000000000000000000000000000000000000000000000000005', 16) - ); - $this->setBasePoint( - new BigInteger('A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C', 16), - new BigInteger('7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5', 16) - ); - $this->setOrder(new BigInteger('010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7', 16)); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('00B8ADF1378A6EB73409FA6C9C637D', -16), - 'b' => new BigInteger('94730F82B358A3776A826298FA6F', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('01DCE8D2EC6184CAF0A972769FCC8B', -16), - 'b' => new BigInteger('4D2100BA3DC75AAB747CCF355DEC', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('01F178FFA4B17C89E6F73AECE2AAD57AF4C0A748B63C830947B27E04', -16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php deleted file mode 100644 index 23ac22979..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp224r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', 16), - new BigInteger('B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', 16) - ); - $this->setBasePoint( - new BigInteger('B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', 16), - new BigInteger('BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php deleted file mode 100644 index 958a48479..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -//use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -//class secp256k1 extends Prime -class secp256k1 extends KoblitzPrime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16)); - $this->setCoefficients( - new BigInteger('0000000000000000000000000000000000000000000000000000000000000000', 16), - new BigInteger('0000000000000000000000000000000000000000000000000000000000000007', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)); - $this->setBasePoint( - new BigInteger('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), - new BigInteger('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16) - ); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16), - 'b' => new BigInteger('FF1BBC8129FEF177D790AB8056F5401B3D', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('114CA50F7A8E2F3F657C1108D9D44CFD8', -16), - 'b' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE', -16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php deleted file mode 100644 index f929f4fa9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp256r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16), - new BigInteger('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16) - ); - $this->setBasePoint( - new BigInteger('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', 16), - new BigInteger('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php deleted file mode 100644 index 8c01a761c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp384r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', - 16 - )); - $this->setCoefficients( - new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', - 16 - ), - new BigInteger( - 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', - 16 - ) - ); - $this->setBasePoint( - new BigInteger( - 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', - 16 - ), - new BigInteger( - '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', - 16 - ) - ); - $this->setOrder(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', - 16 - )); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php deleted file mode 100644 index 8c2b9bbd1..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp521r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFF', 16)); - $this->setCoefficients( - new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFC', 16), - new BigInteger('0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF1' . - '09E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B50' . - '3F00', 16) - ); - $this->setBasePoint( - new BigInteger('00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D' . - '3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5' . - 'BD66', 16), - new BigInteger('011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E' . - '662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1' . - '6650', 16) - ); - $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138' . - '6409', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php deleted file mode 100644 index 958082a35..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect113r1 extends Binary -{ - public function __construct() - { - $this->setModulo(113, 9, 0); - $this->setCoefficients( - '003088250CA6E7C7FE649CE85820F7', - '00E8BEE4D3E2260744188BE0E9C723' - ); - $this->setBasePoint( - '009D73616F35F4AB1407D73562C10F', - '00A52830277958EE84D1315ED31886' - ); - $this->setOrder(new BigInteger('0100000000000000D9CCEC8A39E56F', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php deleted file mode 100644 index 9683c28f0..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect113r2 extends Binary -{ - public function __construct() - { - $this->setModulo(113, 9, 0); - $this->setCoefficients( - '00689918DBEC7E5A0DD6DFC0AA55C7', - '0095E9A9EC9B297BD4BF36E059184F' - ); - $this->setBasePoint( - '01A57A6A7B26CA5EF52FCDB8164797', - '00B3ADC94ED1FE674C06E695BABA1D' - ); - $this->setOrder(new BigInteger('010000000000000108789B2496AF93', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php deleted file mode 100644 index f1585b7f3..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect131r1 extends Binary -{ - public function __construct() - { - $this->setModulo(131, 8, 3, 2, 0); - $this->setCoefficients( - '07A11B09A76B562144418FF3FF8C2570B8', - '0217C05610884B63B9C6C7291678F9D341' - ); - $this->setBasePoint( - '0081BAF91FDF9833C40F9C181343638399', - '078C6E7EA38C001F73C8134B1B4EF9E150' - ); - $this->setOrder(new BigInteger('0400000000000000023123953A9464B54D', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php deleted file mode 100644 index ecf7f99e0..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect131r2 extends Binary -{ - public function __construct() - { - $this->setModulo(131, 8, 3, 2, 0); - $this->setCoefficients( - '03E5A88919D7CAFCBF415F07C2176573B2', - '04B8266A46C55657AC734CE38F018F2192' - ); - $this->setBasePoint( - '0356DCD8F2F95031AD652D23951BB366A8', - '0648F06D867940A5366D9E265DE9EB240F' - ); - $this->setOrder(new BigInteger('0400000000000000016954A233049BA98F', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php deleted file mode 100644 index cf51933b9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect163k1 extends Binary -{ - public function __construct() - { - $this->setModulo(163, 7, 6, 3, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000001', - '000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8', - '0289070FB05D38FF58321F2E800536D538CCDAA3D9' - ); - $this->setOrder(new BigInteger('04000000000000000000020108A2E0CC0D99F8A5EF', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php deleted file mode 100644 index ca1c00ff2..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect163r1 extends Binary -{ - public function __construct() - { - $this->setModulo(163, 7, 6, 3, 0); - $this->setCoefficients( - '07B6882CAAEFA84F9554FF8428BD88E246D2782AE2', - '0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9' - ); - $this->setBasePoint( - '0369979697AB43897789566789567F787A7876A654', - '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883' - ); - $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B', 16)); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php deleted file mode 100644 index c473b9408..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect163r2 extends Binary -{ - public function __construct() - { - $this->setModulo(163, 7, 6, 3, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000001', - '020A601907B8C953CA1481EB10512F78744A3205FD' - ); - $this->setBasePoint( - '03F0EBA16286A2D57EA0991168D4994637E8343E36', - '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1' - ); - $this->setOrder(new BigInteger('040000000000000000000292FE77E70C12A4234C33', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php deleted file mode 100644 index 830f1ba2d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect193r1 extends Binary -{ - public function __construct() - { - $this->setModulo(193, 15, 0); - $this->setCoefficients( - '0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01', - '00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814' - ); - $this->setBasePoint( - '01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1', - '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05' - ); - $this->setOrder(new BigInteger('01000000000000000000000000C7F34A778F443ACC920EBA49', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php deleted file mode 100644 index 6bf2462b6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect193r2 extends Binary -{ - public function __construct() - { - $this->setModulo(193, 15, 0); - $this->setCoefficients( - '0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B', - '00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE' - ); - $this->setBasePoint( - '00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F', - '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C' - ); - $this->setOrder(new BigInteger('010000000000000000000000015AAB561B005413CCD4EE99D5', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php deleted file mode 100644 index 7a42f299b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect233k1 extends Binary -{ - public function __construct() - { - $this->setModulo(233, 74, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126', - '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3' - ); - $this->setOrder(new BigInteger('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php deleted file mode 100644 index 86d910c11..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect233r1 extends Binary -{ - public function __construct() - { - $this->setModulo(233, 74, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000001', - '0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD' - ); - $this->setBasePoint( - '00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B', - '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052' - ); - $this->setOrder(new BigInteger('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php deleted file mode 100644 index 1c8fcd1f0..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect239k1 extends Binary -{ - public function __construct() - { - $this->setModulo(239, 158, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC', - '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA' - ); - $this->setOrder(new BigInteger('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php deleted file mode 100644 index fdd48226f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect283k1 extends Binary -{ - public function __construct() - { - $this->setModulo(283, 12, 7, 5, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836', - '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259' - ); - $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php deleted file mode 100644 index 32a52e66b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect283r1 extends Binary -{ - public function __construct() - { - $this->setModulo(283, 12, 7, 5, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000001', - '027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5' - ); - $this->setBasePoint( - '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053', - '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4' - ); - $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307', 16)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php deleted file mode 100644 index d9c798a27..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect409k1 extends Binary -{ - public function __construct() - { - $this->setModulo(409, 87, 0); - $this->setCoefficients( - '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746', - '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B' - ); - $this->setOrder(new BigInteger( - '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F' . - '83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF', 16 - )); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php deleted file mode 100644 index c441180c7..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect409r1 extends Binary -{ - public function __construct() - { - $this->setModulo(409, 87, 0); - $this->setCoefficients( - '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', - '0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F' - ); - $this->setBasePoint( - '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7', - '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706' - ); - $this->setOrder(new BigInteger( - '010000000000000000000000000000000000000000000000000001E2' . - 'AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173', 16 - )); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php deleted file mode 100644 index c1dd4f11c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect571k1 extends Binary -{ - public function __construct() - { - $this->setModulo(571, 10, 5, 2, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000000' . - '000000000000000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000000000000000000' . - '000000000000000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709584' . - '93B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972', - '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0' . - 'AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3' - ); - $this->setOrder(new BigInteger( - '020000000000000000000000000000000000000000000000000000000000000000000000' . - '131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001', 16 - )); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php deleted file mode 100644 index 95239342b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect571r1 extends Binary -{ - public function __construct() - { - $this->setModulo(571, 10, 5, 2, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000000' . - '000000000000000000000000000000000000000000000000000000000000000000000001', - '02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD' . - '8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A' - ); - $this->setBasePoint( - '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950' . - 'F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19', - '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43' . - 'BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B' - ); - $this->setOrder(new BigInteger( - '03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'E661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47', 16 - )); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php deleted file mode 100644 index 1993002fc..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php +++ /dev/null @@ -1,555 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; -use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Exception\UnsupportedCurveException; - -/** - * Generic EC Key Parsing Helper functions - * - * @package EC - * @author Jim Wigginton - * @access public - */ -trait Common -{ - /** - * Curve OIDs - * - * @var array - */ - private static $curveOIDs = []; - - /** - * Child OIDs loaded - * - * @var bool - */ - protected static $childOIDsLoaded = false; - - /** - * Use Named Curves - * - * @var bool - */ - private static $useNamedCurves = true; - - /** - * Initialize static variables - */ - private static function initialize_static_variables() - { - if (empty(self::$curveOIDs)) { - // the sec* curves are from the standards for efficient cryptography group - // sect* curves are curves over binary finite fields - // secp* curves are curves over prime finite fields - // sec*r* curves are regular curves; sec*k* curves are koblitz curves - // brainpool*r* curves are regular prime finite field curves - // brainpool*t* curves are twisted versions of the brainpool*r* curves - self::$curveOIDs = [ - 'prime192v1' => '1.2.840.10045.3.1.1', // J.5.1, example 1 (aka secp192r1) - 'prime192v2' => '1.2.840.10045.3.1.2', // J.5.1, example 2 - 'prime192v3' => '1.2.840.10045.3.1.3', // J.5.1, example 3 - 'prime239v1' => '1.2.840.10045.3.1.4', // J.5.2, example 1 - 'prime239v2' => '1.2.840.10045.3.1.5', // J.5.2, example 2 - 'prime239v3' => '1.2.840.10045.3.1.6', // J.5.2, example 3 - 'prime256v1' => '1.2.840.10045.3.1.7', // J.5.3, example 1 (aka secp256r1) - - // https://tools.ietf.org/html/rfc5656#section-10 - 'nistp256' => '1.2.840.10045.3.1.7', // aka secp256r1 - 'nistp384' => '1.3.132.0.34', // aka secp384r1 - 'nistp521' => '1.3.132.0.35', // aka secp521r1 - - 'nistk163' => '1.3.132.0.1', // aka sect163k1 - 'nistp192' => '1.2.840.10045.3.1.1', // aka secp192r1 - 'nistp224' => '1.3.132.0.33', // aka secp224r1 - 'nistk233' => '1.3.132.0.26', // aka sect233k1 - 'nistb233' => '1.3.132.0.27', // aka sect233r1 - 'nistk283' => '1.3.132.0.16', // aka sect283k1 - 'nistk409' => '1.3.132.0.36', // aka sect409k1 - 'nistb409' => '1.3.132.0.37', // aka sect409r1 - 'nistt571' => '1.3.132.0.38', // aka sect571k1 - - // from https://tools.ietf.org/html/rfc5915 - 'secp192r1' => '1.2.840.10045.3.1.1', // aka prime192v1 - 'sect163k1' => '1.3.132.0.1', - 'sect163r2' => '1.3.132.0.15', - 'secp224r1' => '1.3.132.0.33', - 'sect233k1'=> '1.3.132.0.26', - 'sect233r1'=> '1.3.132.0.27', - 'secp256r1' => '1.2.840.10045.3.1.7', // aka prime256v1 - 'sect283k1' => '1.3.132.0.16', - 'sect283r1' => '1.3.132.0.17', - 'secp384r1' => '1.3.132.0.34', - 'sect409k1' => '1.3.132.0.36', - 'sect409r1' => '1.3.132.0.37', - 'secp521r1' => '1.3.132.0.35', - 'sect571k1' => '1.3.132.0.38', - 'sect571r1' => '1.3.132.0.39', - // from http://www.secg.org/SEC2-Ver-1.0.pdf - 'secp112r1' => '1.3.132.0.6', - 'secp112r2' => '1.3.132.0.7', - 'secp128r1' => '1.3.132.0.28', - 'secp128r2' => '1.3.132.0.29', - 'secp160k1' => '1.3.132.0.9', - 'secp160r1' => '1.3.132.0.8', - 'secp160r2' => '1.3.132.0.30', - 'secp192k1' => '1.3.132.0.31', - 'secp224k1' => '1.3.132.0.32', - 'secp256k1' => '1.3.132.0.10', - - 'sect113r1' => '1.3.132.0.4', - 'sect113r2' => '1.3.132.0.5', - 'sect131r1' => '1.3.132.0.22', - 'sect131r2' => '1.3.132.0.23', - 'sect163r1' => '1.3.132.0.2', - 'sect193r1' => '1.3.132.0.24', - 'sect193r2' => '1.3.132.0.25', - 'sect239k1' => '1.3.132.0.3', - - // from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf#page=36 - /* - 'c2pnb163v1' => '1.2.840.10045.3.0.1', // J.4.1, example 1 - 'c2pnb163v2' => '1.2.840.10045.3.0.2', // J.4.1, example 2 - 'c2pnb163v3' => '1.2.840.10045.3.0.3', // J.4.1, example 3 - 'c2pnb172w1' => '1.2.840.10045.3.0.4', // J.4.2, example 1 - 'c2tnb191v1' => '1.2.840.10045.3.0.5', // J.4.3, example 1 - 'c2tnb191v2' => '1.2.840.10045.3.0.6', // J.4.3, example 2 - 'c2tnb191v3' => '1.2.840.10045.3.0.7', // J.4.3, example 3 - 'c2onb191v4' => '1.2.840.10045.3.0.8', // J.4.3, example 4 - 'c2onb191v5' => '1.2.840.10045.3.0.9', // J.4.3, example 5 - 'c2pnb208w1' => '1.2.840.10045.3.0.10', // J.4.4, example 1 - 'c2tnb239v1' => '1.2.840.10045.3.0.11', // J.4.5, example 1 - 'c2tnb239v2' => '1.2.840.10045.3.0.12', // J.4.5, example 2 - 'c2tnb239v3' => '1.2.840.10045.3.0.13', // J.4.5, example 3 - 'c2onb239v4' => '1.2.840.10045.3.0.14', // J.4.5, example 4 - 'c2onb239v5' => '1.2.840.10045.3.0.15', // J.4.5, example 5 - 'c2pnb272w1' => '1.2.840.10045.3.0.16', // J.4.6, example 1 - 'c2pnb304w1' => '1.2.840.10045.3.0.17', // J.4.7, example 1 - 'c2tnb359v1' => '1.2.840.10045.3.0.18', // J.4.8, example 1 - 'c2pnb368w1' => '1.2.840.10045.3.0.19', // J.4.9, example 1 - 'c2tnb431r1' => '1.2.840.10045.3.0.20', // J.4.10, example 1 - */ - - // http://www.ecc-brainpool.org/download/Domain-parameters.pdf - // https://tools.ietf.org/html/rfc5639 - 'brainpoolP160r1' => '1.3.36.3.3.2.8.1.1.1', - 'brainpoolP160t1' => '1.3.36.3.3.2.8.1.1.2', - 'brainpoolP192r1' => '1.3.36.3.3.2.8.1.1.3', - 'brainpoolP192t1' => '1.3.36.3.3.2.8.1.1.4', - 'brainpoolP224r1' => '1.3.36.3.3.2.8.1.1.5', - 'brainpoolP224t1' => '1.3.36.3.3.2.8.1.1.6', - 'brainpoolP256r1' => '1.3.36.3.3.2.8.1.1.7', - 'brainpoolP256t1' => '1.3.36.3.3.2.8.1.1.8', - 'brainpoolP320r1' => '1.3.36.3.3.2.8.1.1.9', - 'brainpoolP320t1' => '1.3.36.3.3.2.8.1.1.10', - 'brainpoolP384r1' => '1.3.36.3.3.2.8.1.1.11', - 'brainpoolP384t1' => '1.3.36.3.3.2.8.1.1.12', - 'brainpoolP512r1' => '1.3.36.3.3.2.8.1.1.13', - 'brainpoolP512t1' => '1.3.36.3.3.2.8.1.1.14' - ]; - ASN1::loadOIDs([ - 'prime-field' => '1.2.840.10045.1.1', - 'characteristic-two-field' => '1.2.840.10045.1.2', - 'characteristic-two-basis' => '1.2.840.10045.1.2.3', - // per http://www.secg.org/SEC1-Ver-1.0.pdf#page=84, gnBasis "not used here" - 'gnBasis' => '1.2.840.10045.1.2.3.1', // NULL - 'tpBasis' => '1.2.840.10045.1.2.3.2', // Trinomial - 'ppBasis' => '1.2.840.10045.1.2.3.3' // Pentanomial - ] + self::$curveOIDs); - } - } - - /** - * Explicitly set the curve - * - * If the key contains an implicit curve phpseclib needs the curve - * to be explicitly provided - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - */ - public static function setImplicitCurve(BaseCurve $curve) - { - self::$implicitCurve = $curve; - } - - /** - * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based - * on the curve parameters - * - * @param array $params - * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false - */ - protected static function loadCurveByParam(array $params) - { - if (count($params) > 1) { - throw new \RuntimeException('No parameters are present'); - } - if (isset($params['namedCurve'])) { - $curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve']; - if (!class_exists($curve)) { - throw new UnsupportedCurveException('Named Curve of ' . $params['namedCurve'] . ' is not supported'); - } - return new $curve(); - } - if (isset($params['implicitCurve'])) { - if (!isset(self::$implicitCurve)) { - throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); - } - return self::$implicitCurve; - } - if (isset($params['specifiedCurve'])) { - $data = $params['specifiedCurve']; - switch ($data['fieldID']['fieldType']) { - case 'prime-field': - $curve = new PrimeCurve(); - $curve->setModulo($data['fieldID']['parameters']); - $curve->setCoefficients( - new BigInteger($data['curve']['a'], 256), - new BigInteger($data['curve']['b'], 256) - ); - $point = self::extractPoint("\0" . $data['base'], $curve); - $curve->setBasePoint(...$point); - $curve->setOrder($data['order']); - return $curve; - case 'characteristic-two-field': - $curve = new BinaryCurve(); - $params = ASN1::decodeBER($data['fieldID']['parameters']); - $params = ASN1::asn1map($params[0], Maps\Characteristic_two::MAP); - $modulo = [(int) $params['m']->toString()]; - switch ($params['basis']) { - case 'tpBasis': - $modulo[] = (int) $params['parameters']->toString(); - break; - case 'ppBasis': - $temp = ASN1::decodeBER($params['parameters']); - $temp = ASN1::asn1map($temp[0], Maps\Pentanomial::MAP); - $modulo[] = (int) $temp['k3']->toString(); - $modulo[] = (int) $temp['k2']->toString(); - $modulo[] = (int) $temp['k1']->toString(); - } - $modulo[] = 0; - $curve->setModulo(...$modulo); - $len = ceil($modulo[0] / 8); - $curve->setCoefficients( - Hex::encode($data['curve']['a']), - Hex::encode($data['curve']['b']) - ); - $point = self::extractPoint("\0" . $data['base'], $curve); - $curve->setBasePoint(...$point); - $curve->setOrder($data['order']); - return $curve; - default: - throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); - } - } - throw new \RuntimeException('No valid parameters are present'); - } - - /** - * Extract points from a string - * - * Supports both compressed and uncompressed points - * - * @param string $str - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @return object[] - */ - public static function extractPoint($str, BaseCurve $curve) - { - if ($curve instanceof TwistedEdwardsCurve) { - // first step of point deciding as discussed at the following URL's: - // https://tools.ietf.org/html/rfc8032#section-5.1.3 - // https://tools.ietf.org/html/rfc8032#section-5.2.3 - $y = $str; - $y = strrev($y); - $sign = (bool) (ord($y[0]) & 0x80); - $y[0] = $y[0] & chr(0x7F); - $y = new BigInteger($y, 256); - if ($y->compare($curve->getModulo()) >= 0) { - throw new \RuntimeException('The Y coordinate should not be >= the modulo'); - } - $point = $curve->recoverX($y, $sign); - if (!$curve->verifyPoint($point)) { - throw new \RuntimeException('Unable to verify that point exists on curve'); - } - return $point; - } - - // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, - // currently, bit strings wanting a non-zero amount of bits trimmed are not supported - if (($val = Strings::shift($str)) != "\0") { - throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Hex::encode($val)); - } - if ($str == "\0") { - return []; - } - - $keylen = strlen($str); - $order = $curve->getLengthInBytes(); - // point compression is being used - if ($keylen == $order + 1) { - return $curve->derivePoint($str); - } - - // point compression is not being used - if ($keylen == 2 * $order + 1) { - preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); - list(, $w, $x, $y) = $matches; - if ($w != "\4") { - throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Hex::encode($val)); - } - $point = [ - $curve->convertInteger(new BigInteger($x, 256)), - $curve->convertInteger(new BigInteger($y, 256)) - ]; - - if (!$curve->verifyPoint($point)) { - throw new \RuntimeException('Unable to verify that point exists on curve'); - } - - return $point; - } - - throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); - } - - /** - * Encode Parameters - * - * @todo Maybe at some point this could be moved to __toString() for each of the curves? - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param bool $returnArray optional - * @param array $options optional - * @return string|false - */ - private static function encodeParameters(BaseCurve $curve, $returnArray = false, array $options = []) - { - $useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves; - - $reflect = new \ReflectionClass($curve); - $name = $reflect->getShortName(); - if ($useNamedCurves) { - if (isset(self::$curveOIDs[$name])) { - if ($reflect->isFinal()) { - $reflect = $reflect->getParentClass(); - $name = $reflect->getShortName(); - } - return $returnArray ? - ['namedCurve' => $name] : - ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP); - } - foreach (new \DirectoryIterator(__DIR__ . '/../../Curves/') as $file) { - if ($file->getExtension() != 'php') { - continue; - } - $testName = $file->getBasename('.php'); - $class = 'phpseclib3\Crypt\EC\Curves\\' . $testName; - $reflect = new \ReflectionClass($class); - if ($reflect->isFinal()) { - continue; - } - $candidate = new $class(); - switch ($name) { - case 'Prime': - if (!$candidate instanceof PrimeCurve) { - break; - } - if (!$candidate->getModulo()->equals($curve->getModulo())) { - break; - } - if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { - break; - } - if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { - break; - } - - list($candidateX, $candidateY) = $candidate->getBasePoint(); - list($curveX, $curveY) = $curve->getBasePoint(); - if ($candidateX->toBytes() != $curveX->toBytes()) { - break; - } - if ($candidateY->toBytes() != $curveY->toBytes()) { - break; - } - - return $returnArray ? - ['namedCurve' => $testName] : - ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); - case 'Binary': - if (!$candidate instanceof BinaryCurve) { - break; - } - if ($candidate->getModulo() != $curve->getModulo()) { - break; - } - if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { - break; - } - if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { - break; - } - - list($candidateX, $candidateY) = $candidate->getBasePoint(); - list($curveX, $curveY) = $curve->getBasePoint(); - if ($candidateX->toBytes() != $curveX->toBytes()) { - break; - } - if ($candidateY->toBytes() != $curveY->toBytes()) { - break; - } - - return $returnArray ? - ['namedCurve' => $testName] : - ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); - } - } - } - - $order = $curve->getOrder(); - // we could try to calculate the order thusly: - // https://crypto.stackexchange.com/a/27914/4520 - // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm - if (!$order) { - throw new \RuntimeException('Specified Curves need the order to be specified'); - } - $point = $curve->getBasePoint(); - $x = $point[0]->toBytes(); - $y = $point[1]->toBytes(); - - if ($curve instanceof PrimeCurve) { - /* - * valid versions are: - * - * ecdpVer1: - * - neither the curve or the base point are generated verifiably randomly. - * ecdpVer2: - * - curve and base point are generated verifiably at random and curve.seed is present - * ecdpVer3: - * - base point is generated verifiably at random but curve is not. curve.seed is present - */ - // other (optional) parameters can be calculated using the methods discused at - // https://crypto.stackexchange.com/q/28947/4520 - $data = [ - 'version' => 'ecdpVer1', - 'fieldID' => [ - 'fieldType' => 'prime-field', - 'parameters' => $curve->getModulo() - ], - 'curve' => [ - 'a' => $curve->getA()->toBytes(), - 'b' => $curve->getB()->toBytes() - ], - 'base' => "\4" . $x . $y, - 'order' => $order - ]; - - return $returnArray ? - ['specifiedCurve' => $data] : - ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); - } - if ($curve instanceof BinaryCurve) { - $modulo = $curve->getModulo(); - $basis = count($modulo); - $m = array_shift($modulo); - array_pop($modulo); // the last parameter should always be 0 - //rsort($modulo); - switch ($basis) { - case 3: - $basis = 'tpBasis'; - $modulo = new BigInteger($modulo[0]); - break; - case 5: - $basis = 'ppBasis'; - // these should be in strictly ascending order (hence the commented out rsort above) - $modulo = [ - 'k1' => new BigInteger($modulo[2]), - 'k2' => new BigInteger($modulo[1]), - 'k3' => new BigInteger($modulo[0]) - ]; - $modulo = ASN1::encodeDER($modulo, Maps\Pentanomial::MAP); - $modulo = new ASN1\Element($modulo); - } - $params = ASN1::encodeDER([ - 'm' => new BigInteger($m), - 'basis' => $basis, - 'parameters' => $modulo - ], Maps\Characteristic_two::MAP); - $params = new ASN1\Element($params); - $a = ltrim($curve->getA()->toBytes(), "\0"); - if (!strlen($a)) { - $a = "\0"; - } - $b = ltrim($curve->getB()->toBytes(), "\0"); - if (!strlen($b)) { - $b = "\0"; - } - $data = [ - 'version' => 'ecdpVer1', - 'fieldID' => [ - 'fieldType' => 'characteristic-two-field', - 'parameters' => $params - ], - 'curve' => [ - 'a' => $a, - 'b' => $b - ], - 'base' => "\4" . $x . $y, - 'order' => $order - ]; - - return $returnArray ? - ['specifiedCurve' => $data] : - ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); - } - - throw new UnsupportedCurveException('Curve cannot be serialized'); - } - - /** - * Use Specified Curve - * - * A specified curve has all the coefficients, the base points, etc, explicitely included. - * A specified curve is a more verbose way of representing a curve - */ - public static function useSpecifiedCurve() - { - self::$useNamedCurves = false; - } - - /** - * Use Named Curve - * - * A named curve does not include any parameters. It is up to the EC parameters to - * know what the coefficients, the base points, etc, are from the name of the curve. - * A named curve is a more concise way of representing a curve - */ - public static function useNamedCurve() - { - self::$useNamedCurves = true; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php deleted file mode 100644 index b0c850100..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Curves\Curve448; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Math\BigInteger; -use phpseclib3\Exception\UnsupportedFormatException; - -/** - * Montgomery Curve Private Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class MontgomeryPrivate -{ - /** - * Is invisible flag - * - * @access private - */ - const IS_INVISIBLE = true; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - switch (strlen($key)) { - case 32: - $curve = new Curve25519; - break; - case 56: - $curve = new Curve448; - break; - default: - throw new \LengthException('The only supported lengths are 32 and 56'); - } - - $components = ['curve' => $curve]; - $components['dA'] = $components['curve']->convertInteger(new BigInteger($key, 256)); - // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) - $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @access public - * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @return string - */ - public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) - { - return strrev($publicKey[0]->toBytes()); - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $password optional - * @return string - */ - public static function savePrivateKey(Integer $privateKey, MontgomeryCurve $curve, array $publicKey, $password = '') - { - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); - } - - return $privateKey->toBytes(); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php deleted file mode 100644 index 72dc80b17..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Curves\Curve448; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Math\BigInteger; - -/** - * Montgomery Public Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class MontgomeryPublic -{ - /** - * Is invisible flag - * - * @access private - */ - const IS_INVISIBLE = true; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - switch (strlen($key)) { - case 32: - $curve = new Curve25519; - break; - case 56: - $curve = new Curve448; - break; - default: - throw new \LengthException('The only supported lengths are 32 and 56'); - } - - $components = ['curve' => $curve]; - $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($key), 256))]; - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @access public - * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @return string - */ - public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) - { - return strrev($publicKey[0]->toBytes()); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php deleted file mode 100644 index 5372e11bb..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,216 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Math\Common\FiniteField\Integer; - -/** - * OpenSSH Formatted EC Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class OpenSSH extends Progenitor -{ - use Common; - - /** - * Supported Key Types - * - * @var array - */ - protected static $types = [ - 'ecdsa-sha2-nistp256', - 'ecdsa-sha2-nistp384', - 'ecdsa-sha2-nistp521', - 'ssh-ed25519' - ]; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $parsed = parent::load($key, $password); - - if (isset($parsed['paddedKey'])) { - $paddedKey = $parsed['paddedKey']; - list($type) = Strings::unpackSSH2('s', $paddedKey); - if ($type != $parsed['type']) { - throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); - } - if ($type == 'ssh-ed25519' ) { - list(, $key, $comment) = Strings::unpackSSH2('sss', $paddedKey); - $key = libsodium::load($key); - $key['comment'] = $comment; - return $key; - } - list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey); - $curve = self::loadCurveByParam(['namedCurve' => $curveName]); - return [ - 'curve' => $curve, - 'dA' => $curve->convertInteger($privateKey), - 'QA' => self::extractPoint("\0$publicKey", $curve), - 'comment' => $comment - ]; - } - - if ($parsed['type'] == 'ssh-ed25519') { - if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") { - throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); - } - - $curve = new Ed25519(); - $qa = self::extractPoint($parsed['publicKey'], $curve); - } else { - list($curveName, $publicKey) = Strings::unpackSSH2('ss', $parsed['publicKey']); - $curveName = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; - $curve = new $curveName(); - - $qa = self::extractPoint("\0" . $publicKey, $curve); - } - - return [ - 'curve' => $curve, - 'QA' => $qa, - 'comment' => $parsed['comment'] - ]; - } - - /** - * Returns the alias that corresponds to a curve - * - * @return string - */ - private static function getAlias(BaseCurve $curve) - { - self::initialize_static_variables(); - - $reflect = new \ReflectionClass($curve); - $name = $reflect->getShortName(); - - $oid = self::$curveOIDs[$name]; - $aliases = array_filter(self::$curveOIDs, function($v) use ($oid) { - return $v == $oid; - }); - $aliases = array_keys($aliases); - - for ($i = 0; $i < count($aliases); $i++) { - if (in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) { - $alias = $aliases[$i]; - break; - } - } - - if (!isset($alias)) { - throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports'); - } - - return $alias; - } - - /** - * Convert an EC public key to the appropriate format - * - * @access public - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) - { - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - - if ($curve instanceof Ed25519) { - $key = Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey)); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $key; - } - - $key = 'ssh-ed25519 ' . base64_encode($key) . ' ' . $comment; - return $key; - } - - $alias = self::getAlias($curve); - - $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - $key = Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $key; - } - - $key = 'ecdsa-sha2-' . $alias . ' ' . base64_encode($key) . ' ' . $comment; - - return $key; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey - * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) - { - if ($curve instanceof Ed25519) { - if (!isset($privateKey->secret)) { - throw new \RuntimeException('Private Key does not have a secret set'); - } - if (strlen($privateKey->secret) != 32) { - throw new \RuntimeException('Private Key secret is not of the correct length'); - } - - $pubKey = $curve->encodePoint($publicKey); - - $publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey); - $privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $privateKey->secret . $pubKey); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } - - $alias = self::getAlias($curve); - - $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => true]); - - $privateKey = Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php deleted file mode 100644 index b28492bcd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,203 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Math\BigInteger; -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Common\Functions\Strings; - -/** - * "PKCS1" (RFC5915) Formatted EC Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class PKCS1 extends Progenitor -{ - use Common; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) { - $components = []; - - preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches); - $decoded = parent::load($matches[0], $password); - $decoded = ASN1::decodeBER($decoded); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - $ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); - if (!is_array($ecPrivate)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - if (isset($ecPrivate['parameters'])) { - $components['curve'] = self::loadCurveByParam($ecPrivate['parameters']); - } - - preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches); - $decoded = parent::load($matches[0], ''); - $decoded = ASN1::decodeBER($decoded); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - $ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); - if (!is_array($ecParams)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - $ecParams = self::loadCurveByParam($ecParams); - - // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes - // even if the modulo is the same - if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) { - throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); - } - - if (!isset($components['curve'])) { - $components['curve'] = $ecParams; - } - - $temp = new BigInteger($ecPrivate['privateKey'], 256); - $components['dA'] = $components['curve']->convertInteger($temp); - $components['QA'] = isset($ecPrivate['publicKey']) ? - self::extractPoint($ecPrivate['publicKey'], $components['curve']) : - $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - - return $components; - } - - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - $key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); - if (is_array($key)) { - return ['curve' => self::loadCurveByParam($key)]; - } - - $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); - if (!is_array($key)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - if (!isset($key['parameters'])) { - throw new \RuntimeException('Key cannot be loaded without parameters'); - } - - $components = []; - $components['curve'] = self::loadCurveByParam($key['parameters']); - $temp = new BigInteger($key['privateKey'], 256); - $components['dA'] = $components['curve']->convertInteger($temp); - $components['QA'] = isset($ecPrivate['publicKey']) ? - self::extractPoint($ecPrivate['publicKey'], $components['curve']) : - $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - - return $components; - } - - /** - * Convert EC parameters to the appropriate format - * - * @access public - * @return string - */ - public static function saveParameters(BaseCurve $curve, array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); - } - - $key = self::encodeParameters($curve, false, $options); - - return "-----BEGIN EC PARAMETERS-----\r\n" . - chunk_split(Base64::encode($key), 64) . - "-----END EC PARAMETERS-----\r\n"; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('TwistedEdwards Curves are not supported'); - } - - $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - $key = [ - 'version' => 'ecPrivkeyVer1', - 'privateKey' => $privateKey->toBytes(), - 'parameters' => new ASN1\Element(self::encodeParameters($curve)), - 'publicKey' => "\0" . $publicKey - ]; - - $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); - - return self::wrapPrivateKey($key, 'EC', $password, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php deleted file mode 100644 index 247beedb2..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,249 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Curves\Ed448; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Common\Functions\Strings; - -/** - * PKCS#8 Formatted EC Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class PKCS8 extends Progenitor -{ - use Common; - - /** - * OID Name - * - * @var array - * @access private - */ - const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448']; - - /** - * OID Value - * - * @var string - * @access private - */ - const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113']; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - // initialize_static_variables() is defined in both the trait and the parent class - // when it's defined in two places it's the traits one that's called - // the parent one is needed, as well, but the parent one is called by other methods - // in the parent class as needed and in the context of the parent it's the parent - // one that's called - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $isPublic = strpos($key, 'PUBLIC') !== false; - - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; - - switch (true) { - case !$isPublic && $type == 'publicKey': - throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); - case $isPublic && $type == 'privateKey': - throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); - } - - switch ($key[$type . 'Algorithm']['algorithm']) { - case 'id-Ed25519': - case 'id-Ed448': - return self::loadEdDSA($key); - } - - $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); - $params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); - if (!$params) { - throw new \RuntimeException('Unable to decode the parameters using Maps\ECParameters'); - } - - $components = []; - $components['curve'] = self::loadCurveByParam($params); - - if ($isPublic) { - $components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']); - - return $components; - } - - $decoded = ASN1::decodeBER($key['privateKey']); - $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); - if (isset($key['parameters']) && $params != $key['parameters']) { - throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); - } - - $temp = new BigInteger($key['privateKey'], 256); - $components['dA'] = $components['curve']->convertInteger($temp); - - $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); - - return $components; - } - - /** - * Break a public or private EdDSA key down into its constituent components - * - * @return array - */ - private static function loadEdDSA(array $key) - { - $components = []; - - if (isset($key['privateKey'])) { - $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); - - // 0x04 == octet string - // 0x20 == length (32 bytes) - if (substr($key['privateKey'], 0, 2) != "\x04\x20") { - throw new \RuntimeException('The first two bytes of the private key field should be 0x0420'); - } - $components['dA'] = $components['curve']->extractSecret(substr($key['privateKey'], 2)); - } - - if (isset($key['publicKey'])) { - if (!isset($components['curve'])) { - $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); - } - - $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); - } - - if (isset($key['privateKey']) && !isset($components['QA'])) { - $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - } - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @access public - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('Montgomery Curves are not supported'); - } - - if ($curve instanceof TwistedEdwardsCurve) { - return self::wrapPublicKey( - $curve->encodePoint($publicKey), - null, - $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' - ); - } - - $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); - - $key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - return self::wrapPublicKey($key, $params, 'id-ecPublicKey'); - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('Montgomery Curves are not supported'); - } - - if ($curve instanceof TwistedEdwardsCurve) { - return self::wrapPrivateKey( - "\x04\x20" . $privateKey->secret, - [], - null, - $password, - $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448', - "\0" . $curve->encodePoint($publicKey) - ); - } - - $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); - - $key = [ - 'version' => 'ecPrivkeyVer1', - 'privateKey' => $privateKey->toBytes(), - //'parameters' => $params, - 'publicKey' => "\0" . $publicKey - ]; - - $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); - - return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php deleted file mode 100644 index 181ab76c9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; - -/** - * PuTTY Formatted EC Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class PuTTY extends Progenitor -{ - use Common; - - /** - * Public Handler - * - * @var string - * @access private - */ - const PUBLIC_HANDLER = 'phpseclib3\Crypt\EC\Formats\Keys\OpenSSH'; - - /** - * Supported Key Types - * - * @var array - * @access private - */ - protected static $types = [ - 'ecdsa-sha2-nistp256', - 'ecdsa-sha2-nistp384', - 'ecdsa-sha2-nistp521', - 'ssh-ed25519' - ]; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $components = parent::load($key, $password); - if (!isset($components['private'])) { - return $components; - } - - $private = $components['private']; - - $temp = Base64::encode(Strings::packSSH2('s', $components['type']) . $components['public']); - $components = OpenSSH::load($components['type'] . ' ' . $temp . ' ' . $components['comment']); - - if ($components['curve'] instanceof TwistedEdwardsCurve) { - if (Strings::shift($private, 4) != "\0\0\0\x20") { - throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); - } - $components['dA'] = $components['curve']->extractSecret($private); - } else { - list($temp) = Strings::unpackSSH2('i', $private); - $components['dA'] = $components['curve']->convertInteger($temp); - } - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = false, array $options = []) - { - self::initialize_static_variables(); - - $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); - $name = $public[0]; - $public = Base64::decode($public[1]); - list(, $length) = unpack('N', Strings::shift($public, 4)); - Strings::shift($public, $length); - - // PuTTY pads private keys with a null byte per the following: - // https://github.com/github/putty/blob/a3d14d77f566a41fc61dfdc5c2e0e384c9e6ae8b/sshecc.c#L1926 - if (!$curve instanceof TwistedEdwardsCurve) { - $private = $privateKey->toBytes(); - if (!(strlen($privateKey->toBits()) & 7)) { - $private ="\0$private"; - } - } - - $private = $curve instanceof TwistedEdwardsCurve ? - Strings::packSSH2('s', $privateKey->secret) : - Strings::packSSH2('s', $private); - - return self::wrapPrivateKey($public, $private, $name, $password, $options); - } - - /** - * Convert an EC public key to the appropriate format - * - * @access public - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField[] $publicKey - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey) - { - $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); - $type = $public[0]; - $public = Base64::decode($public[1]); - list(, $length) = unpack('N', Strings::shift($public, 4)); - Strings::shift($public, $length); - - return self::wrapPublicKey($public, $type); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php deleted file mode 100644 index d6d8018ad..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php +++ /dev/null @@ -1,484 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\UnsupportedCurveException; - -/** - * XML Formatted EC Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class XML -{ - use Common; - - /** - * Default namespace - * - * @var string - */ - private static $namespace; - - /** - * Flag for using RFC4050 syntax - * - * @var bool - */ - private static $rfc4050 = false; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $use_errors = libxml_use_internal_errors(true); - - $temp = self::isolateNamespace($key, 'http://www.w3.org/2009/xmldsig11#'); - if ($temp) { - $key = $temp; - } - - $temp = self::isolateNamespace($key, 'http://www.w3.org/2001/04/xmldsig-more#'); - if ($temp) { - $key = $temp; - } - - $dom = new \DOMDocument(); - if (substr($key, 0, 5) != '' . $key . ''; - } - - if (!$dom->loadXML($key)) { - libxml_use_internal_errors($use_errors); - throw new \UnexpectedValueException('Key does not appear to contain XML'); - } - $xpath = new \DOMXPath($dom); - libxml_use_internal_errors($use_errors); - $curve = self::loadCurveByParam($xpath); - - $pubkey = self::query($xpath, 'publickey', 'Public Key is not present'); - - $QA = self::query($xpath, 'ecdsakeyvalue')->length ? - self::extractPointRFC4050($xpath, $curve) : - self::extractPoint("\0" . $pubkey, $curve); - - libxml_use_internal_errors($use_errors); - - return compact('curve', 'QA'); - } - - /** - * Case-insensitive xpath query - * - * @param \DOMXPath $xpath - * @param string $name - * @param string $error optional - * @param bool $decode optional - * @return \DOMNodeList - */ - private static function query($xpath, $name, $error = null, $decode = true) - { - $query = '/'; - $names = explode('/', $name); - foreach ($names as $name) { - $query.= "/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$name']"; - } - $result = $xpath->query($query); - if (!isset($error)) { - return $result; - } - - if (!$result->length) { - throw new \RuntimeException($error); - } - return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; - } - - /** - * Finds the first element in the relevant namespace, strips the namespacing and returns the XML for that element. - * - * @param string $xml - * @param string $ns - */ - private static function isolateNamespace($xml, $ns) - { - $dom = new \DOMDocument(); - if (!$dom->loadXML($xml)) { - return false; - } - $xpath = new \DOMXPath($dom); - $nodes = $xpath->query("//*[namespace::*[.='$ns'] and not(../namespace::*[.='$ns'])]"); - if (!$nodes->length) { - return false; - } - $node = $nodes->item(0); - $ns_name = $node->lookupPrefix($ns); - $node->removeAttributeNS($ns, $ns_name); - return $dom->saveXML($node); - } - - /** - * Decodes the value - * - * @param string $value - */ - private static function decodeValue($value) - { - return Base64::decode(str_replace(["\r", "\n", ' ', "\t"], '', $value)); - } - - /** - * Extract points from an XML document - * - * @param \DOMXPath $xpath - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @return object[] - */ - private static function extractPointRFC4050(\DOMXPath $xpath, BaseCurve $curve) - { - $x = self::query($xpath, 'publickey/x'); - $y = self::query($xpath, 'publickey/y'); - if (!$x->length || !$x->item(0)->hasAttribute('Value')) { - throw new \RuntimeException('Public Key / X coordinate not found'); - } - if (!$y->length || !$y->item(0)->hasAttribute('Value')) { - throw new \RuntimeException('Public Key / Y coordinate not found'); - } - $point = [ - $curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))), - $curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))) - ]; - if (!$curve->verifyPoint($point)) { - throw new \RuntimeException('Unable to verify that point exists on curve'); - } - return $point; - } - - /** - * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based - * on the curve parameters - * - * @param \DomXPath $xpath - * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false - */ - private static function loadCurveByParam(\DOMXPath $xpath) - { - $namedCurve = self::query($xpath, 'namedcurve'); - if ($namedCurve->length == 1) { - $oid = $namedCurve->item(0)->getAttribute('URN'); - $oid = preg_replace('#[^\d.]#', '', $oid); - $name = array_search($oid, self::$curveOIDs); - if ($name === false) { - throw new UnsupportedCurveException('Curve with OID of ' . $oid . ' is not supported'); - } - - $curve = '\phpseclib3\Crypt\EC\Curves\\' . $name; - if (!class_exists($curve)) { - throw new UnsupportedCurveException('Named Curve of ' . $name . ' is not supported'); - } - return new $curve(); - } - - $params = self::query($xpath, 'explicitparams'); - if ($params->length) { - return self::loadCurveByParamRFC4050($xpath); - } - - $params = self::query($xpath, 'ecparameters'); - if (!$params->length) { - throw new \RuntimeException('No parameters are present'); - } - - $fieldTypes = [ - 'prime-field' => ['fieldid/prime/p'], - 'gnb' => ['fieldid/gnb/m'], - 'tnb' => ['fieldid/tnb/k'], - 'pnb' => ['fieldid/pnb/k1', 'fieldid/pnb/k2', 'fieldid/pnb/k3'], - 'unknown' => [] - ]; - - foreach ($fieldTypes as $type => $queries) { - foreach ($queries as $query) { - $result = self::query($xpath, $query); - if (!$result->length) { - continue 2; - } - $param = preg_replace('#.*/#', '', $query); - $$param = self::decodeValue($result->item(0)->textContent); - } - break; - } - - $a = self::query($xpath, 'curve/a', 'A coefficient is not present'); - $b = self::query($xpath, 'curve/b', 'B coefficient is not present'); - $base = self::query($xpath, 'base', 'Base point is not present'); - $order = self::query($xpath, 'order', 'Order is not present'); - - switch ($type) { - case 'prime-field': - $curve = new PrimeCurve(); - $curve->setModulo(new BigInteger($p, 256)); - $curve->setCoefficients( - new BigInteger($a, 256), - new BigInteger($b, 256) - ); - $point = self::extractPoint("\0" . $base, $curve); - $curve->setBasePoint(...$point); - $curve->setOrder(new BigInteger($order, 256)); - return $curve; - case 'gnb': - case 'tnb': - case 'pnb': - default: - throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); - } - } - - /** - * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based - * on the curve parameters - * - * @param \DomXPath $xpath - * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false - */ - private static function loadCurveByParamRFC4050(\DOMXPath $xpath) - { - $fieldTypes = [ - 'prime-field' => ['primefieldparamstype/p'], - 'unknown' => [] - ]; - - foreach ($fieldTypes as $type => $queries) { - foreach ($queries as $query) { - $result = self::query($xpath, $query); - if (!$result->length) { - continue 2; - } - $param = preg_replace('#.*/#', '', $query); - $$param = $result->item(0)->textContent; - } - break; - } - - $a = self::query($xpath, 'curveparamstype/a', 'A coefficient is not present', false); - $b = self::query($xpath, 'curveparamstype/b', 'B coefficient is not present', false); - $x = self::query($xpath, 'basepointparams/basepoint/ecpointtype/x', 'Base Point X is not present', false); - $y = self::query($xpath, 'basepointparams/basepoint/ecpointtype/y', 'Base Point Y is not present', false); - $order = self::query($xpath, 'order', 'Order is not present', false); - - switch ($type) { - case 'prime-field': - $curve = new PrimeCurve(); - - $p = str_replace(["\r", "\n", ' ', "\t"], '', $p); - $curve->setModulo(new BigInteger($p)); - - $a = str_replace(["\r", "\n", ' ', "\t"], '', $a); - $b = str_replace(["\r", "\n", ' ', "\t"], '', $b); - $curve->setCoefficients( - new BigInteger($a), - new BigInteger($b) - ); - - $x = str_replace(["\r", "\n", ' ', "\t"], '', $x); - $y = str_replace(["\r", "\n", ' ', "\t"], '', $y); - $curve->setBasePoint( - new BigInteger($x), - new BigInteger($y) - ); - - $order = str_replace(["\r", "\n", ' ', "\t"], '', $order); - $curve->setOrder(new BigInteger($order)); - return $curve; - default: - throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); - } - } - - /** - * Sets the namespace. dsig11 is the most common one. - * - * Set to null to unset. Used only for creating public keys. - * - * @param string $namespace - */ - public static function setNamespace($namespace) - { - self::$namespace = $namespace; - } - - /** - * Uses the XML syntax specified in https://tools.ietf.org/html/rfc4050 - */ - public static function enableRFC4050Syntax() - { - self::$rfc4050 = true; - } - - /** - * Uses the XML syntax specified in https://www.w3.org/TR/xmldsig-core/#sec-ECParameters - */ - public static function disableRFC4050Syntax() - { - self::$rfc4050 = false; - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); - } - - if (empty(static::$namespace)) { - $pre = $post = ''; - } else { - $pre = static::$namespace . ':'; - $post = ':' . static::$namespace; - } - - if (self::$rfc4050) { - return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" . - self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . - '<' . $pre . 'PublicKey>' . "\r\n" . - '<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" . - '<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" . - '' . "\r\n" . - ''; - } - - $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" . - self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . - '<' . $pre . 'PublicKey>' . Base64::encode($publicKey) . '' . "\r\n" . - ''; - } - - /** - * Encode Parameters - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param string $pre - * @param array $options optional - * @return string|false - */ - private static function encodeXMLParameters(BaseCurve $curve, $pre, array $options = []) - { - $result = self::encodeParameters($curve, true, $options); - - if (isset($result['namedCurve'])) { - $namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />'; - return self::$rfc4050 ? - '' . str_replace('URI', 'URN', $namedCurve) . '' : - $namedCurve; - } - - if (self::$rfc4050) { - $xml = '<' . $pre . 'ExplicitParams>' . "\r\n" . - '<' . $pre . 'FieldParams>' . "\r\n"; - $temp = $result['specifiedCurve']; - switch ($temp['fieldID']['fieldType']) { - case 'prime-field': - $xml.= '<' . $pre . 'PrimeFieldParamsType>' . "\r\n" . - '<' . $pre . 'P>' . $temp['fieldID']['parameters'] . '' . "\r\n" . - '' . "\r\n"; - $a = $curve->getA(); - $b = $curve->getB(); - list($x, $y) = $curve->getBasePoint(); - break; - default: - throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); - } - $xml.= '' . "\r\n" . - '<' . $pre . 'CurveParamsType>' . "\r\n" . - '<' . $pre . 'A>' . $a . '' . "\r\n" . - '<' . $pre . 'B>' . $b . '' . "\r\n" . - '' . "\r\n" . - '<' . $pre . 'BasePointParams>' . "\r\n" . - '<' . $pre . 'BasePoint>' . "\r\n" . - '<' . $pre . 'ECPointType>' . "\r\n" . - '<' . $pre . 'X>' . $x . '' . "\r\n" . - '<' . $pre . 'Y>' . $y . '' . "\r\n" . - '' . "\r\n" . - '' . "\r\n" . - '<' . $pre . 'Order>' . $curve->getOrder() . '' . "\r\n" . - '' . "\r\n" . - '' . "\r\n"; - - return $xml; - } - - if (isset($result['specifiedCurve'])) { - $xml = '<' . $pre . 'ECParameters>' . "\r\n" . - '<' . $pre . 'FieldID>' . "\r\n"; - $temp = $result['specifiedCurve']; - switch ($temp['fieldID']['fieldType']) { - case 'prime-field': - $xml.= '<' . $pre . 'Prime>' . "\r\n" . - '<' . $pre . 'P>' . Base64::encode($temp['fieldID']['parameters']->toBytes()) . '' . "\r\n" . - '' . "\r\n" ; - break; - default: - throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); - } - $xml.= '' . "\r\n" . - '<' . $pre . 'Curve>' . "\r\n" . - '<' . $pre . 'A>' . Base64::encode($temp['curve']['a']) . '' . "\r\n" . - '<' . $pre . 'B>' . Base64::encode($temp['curve']['b']) . '' . "\r\n" . - '' . "\r\n" . - '<' . $pre . 'Base>' . Base64::encode($temp['base']) . '' . "\r\n" . - '<' . $pre . 'Order>' . Base64::encode($temp['order']) . '' . "\r\n" . - ''; - return $xml; - } - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php deleted file mode 100644 index b8be19444..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Exception\UnsupportedFormatException; - -/** - * libsodium Key Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class libsodium -{ - use Common; - - /** - * Is invisible flag - * - * @access private - */ - const IS_INVISIBLE = true; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - switch (strlen($key)) { - case 32: - $public = $key; - break; - case 64: - $private = substr($key, 0, 32); - $public = substr($key, -32); - break; - case 96: - $public = substr($key, -32); - if (substr($key, 32, 32) != $public) { - throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); - } - $private = substr($key, 0, 32); - break; - default: - throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); - } - - $curve = new Ed25519(); - $components = ['curve' => $curve]; - if (isset($private)) { - $components['dA'] = $curve->extractSecret($private); - } - $components['QA'] = isset($public) ? - self::extractPoint($public, $curve) : - $curve->multiplyPoint($curve->getBasePoint(), $components['dA']); - - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @access public - * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @return string - */ - public static function savePublicKey(Ed25519 $curve, array $publicKey) - { - return $curve->encodePoint($publicKey); - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey - * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $password optional - * @return string - */ - public static function savePrivateKey(Integer $privateKey, Ed25519 $curve, array $publicKey, $password = '') - { - if (!isset($privateKey->secret)) { - throw new \RuntimeException('Private Key does not have a secret set'); - } - if (strlen($privateKey->secret) != 32) { - throw new \RuntimeException('Private Key secret is not of the correct length'); - } - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('libsodium private keys do not support encryption'); - } - return $privateKey->secret . $curve->encodePoint($publicKey); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php deleted file mode 100644 index 3509eb61e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Signature; - -use phpseclib3\Math\BigInteger; -use phpseclib3\File\ASN1 as Encoder; -use phpseclib3\File\ASN1\Maps\EcdsaSigValue; - -/** - * ASN1 Signature Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class ASN1 -{ - /** - * Loads a signature - * - * @access public - * @param string $sig - * @return array - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $decoded = Encoder::decodeBER($sig); - if (empty($decoded)) { - return false; - } - $components = Encoder::asn1map($decoded[0], EcdsaSigValue::MAP); - - return $components; - } - - /** - * Returns a signature in the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - return Encoder::encodeDER(compact('r', 's'), EcdsaSigValue::MAP); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php deleted file mode 100644 index eebef46b2..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Signature; - -use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; - -/** - * Raw DSA Signature Handler - * - * @package EC - * @author Jim Wigginton - * @access public - */ -abstract class Raw extends Progenitor -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php deleted file mode 100644 index 261100dbe..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Signature; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; - -/** - * SSH2 Signature Handler - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class SSH2 -{ - /** - * Loads a signature - * - * @access public - * @param string $sig - * @return mixed - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $result = Strings::unpackSSH2('ss', $sig); - if ($result === false) { - return false; - } - list($type, $blob) = $result; - switch ($type) { - // see https://tools.ietf.org/html/rfc5656#section-3.1.2 - case 'ecdsa-sha2-nistp256': - case 'ecdsa-sha2-nistp384': - case 'ecdsa-sha2-nistp521': - break; - default: - return false; - } - - $result = Strings::unpackSSH2('ii', $blob); - if ($result === false) { - return false; - } - - return [ - 'r' => $result[0], - 's' => $result[1] - ]; - } - - /** - * Returns a signature in the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @param string $curve - * @return string - */ - public static function save(BigInteger $r, BigInteger $s, $curve) - { - switch ($curve) { - case 'secp256r1': - $curve = 'nistp256'; - break; - case 'secp384r1': - $curve = 'nistp384'; - break; - case 'secp521r1': - $curve = 'nistp521'; - break; - default: - return false; - } - - $blob = Strings::packSSH2('ii', $r, $s); - - return Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php deleted file mode 100644 index 96527c754..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC; - -use phpseclib3\Crypt\EC; - -/** - * EC Parameters - * - * @package EC - * @author Jim Wigginton - * @access public - */ -class Parameters extends EC -{ - /** - * Returns the parameters - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type = 'PKCS1', array $options = []) - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - return $type::saveParameters($this->curve, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php deleted file mode 100644 index 4ffa5fdf5..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php +++ /dev/null @@ -1,258 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC; - -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; -use phpseclib3\Crypt\Common; -use phpseclib3\Exception\UnsupportedOperationException; -use phpseclib3\Common\Functions\Strings; - -/** - * EC Private Key - * - * @package EC - * @author Jim Wigginton - * @access public - */ -class PrivateKey extends EC implements Common\PrivateKey -{ - use Common\Traits\PasswordProtected; - - /** - * Private Key dA - * - * sign() converts this to a BigInteger so one might wonder why this is a FiniteFieldInteger instead of - * a BigInteger. That's because a FiniteFieldInteger, when converted to a byte string, is null padded by - * a certain amount whereas a BigInteger isn't. - * - * @var object - */ - protected $dA; - - /** - * Multiplies an encoded point by the private key - * - * Used by ECDH - * - * @param string $coordinates - * @return string - */ - public function multiply($coordinates) - { - if ($this->curve instanceof MontgomeryCurve) { - if ($this->curve instanceof Curve25519 && self::$engines['libsodium']) { - return sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates); - } - - $point = [$this->curve->convertInteger(new BigInteger(strrev($coordinates), 256))]; - $point = $this->curve->multiplyPoint($point, $this->dA); - return strrev($point[0]->toBytes(true)); - } - if (!$this->curve instanceof TwistedEdwardsCurve) { - $coordinates = "\0$coordinates"; - } - $point = PKCS1::extractPoint($coordinates, $this->curve); - $point = $this->curve->multiplyPoint($point, $this->dA); - if ($this->curve instanceof TwistedEdwardsCurve) { - return $this->curve->encodePoint($point); - } - if (empty($point)) { - throw new \RuntimeException('The infinity point is invalid'); - } - return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true); - } - - /** - * Create a signature - * - * @see self::verify() - * @access public - * @param string $message - * @return mixed - */ - public function sign($message) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - - $dA = $this->dA->toBigInteger(); - - $order = $this->curve->getOrder(); - - $shortFormat = $this->shortFormat; - $format = $this->sigFormat; - if ($format === false) { - return false; - } - - if ($this->curve instanceof TwistedEdwardsCurve) { - if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { - $result = sodium_crypto_sign_detached($message, $this->toString('libsodium')); - return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result) : $result; - } - - // contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not. - // quoting https://tools.ietf.org/html/rfc8032#section-8.5 , - // "The Ed25519ph and Ed448ph variants ... SHOULD NOT be used" - $A = $this->curve->encodePoint($this->QA); - $curve = $this->curve; - $hash = new Hash($curve::HASH); - - $secret = substr($hash->hash($this->dA->secret), $curve::SIZE); - - if ($curve instanceof Ed25519) { - $dom = !isset($this->context) ? '' : - 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; - } else { - $context = isset($this->context) ? $this->context : ''; - $dom = 'SigEd448' . "\0" . chr(strlen($context)) . $context; - } - // SHA-512(dom2(F, C) || prefix || PH(M)) - $r = $hash->hash($dom . $secret . $message); - $r = strrev($r); - $r = new BigInteger($r, 256); - list(, $r) = $r->divide($order); - $R = $curve->multiplyPoint($curve->getBasePoint(), $curve->convertInteger($r)); - $R = $curve->encodePoint($R); - $k = $hash->hash($dom . $R . $A . $message); - $k = strrev($k); - $k = new BigInteger($k, 256); - list(, $k) = $k->divide($order); - $S = $k->multiply($dA)->add($r); - list(, $S) = $S->divide($order); - $S = str_pad(strrev($S->toBytes()), $curve::SIZE, "\0"); - return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $R . $S) : $R . $S; - } - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $signature = ''; - // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long - // supported signing / verification - // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; - // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even - // has curve-specific optimizations - $result = openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); - - if ($result) { - if ($shortFormat == 'ASN1') { - return $signature; - } - - extract(ASN1Signature::load($signature)); - - return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); - } - } - - $e = $this->hash->hash($message); - $e = new BigInteger($e, 256); - - $Ln = $this->hash->getLength() - $order->getLength(); - $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; - - while (true) { - $k = BigInteger::randomRange(self::$one, $order->subtract(self::$one)); - list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $this->curve->convertInteger($k)); - $x = $x->toBigInteger(); - list(, $r) = $x->divide($order); - if ($r->equals(self::$zero)) { - continue; - } - $kinv = $k->modInverse($order); - $temp = $z->add($dA->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($order); - if (!$s->equals(self::$zero)) { - break; - } - } - - // the following is an RFC6979 compliant implementation of deterministic ECDSA - // it's unused because it's mainly intended for use when a good CSPRNG isn't - // available. if phpseclib's CSPRNG isn't good then even key generation is - // suspect - /* - // if this were actually being used it'd probably be better if this lived in load() and createKey() - $this->q = $this->curve->getOrder(); - $dA = $this->dA->toBigInteger(); - $this->x = $dA; - - $h1 = $this->hash->hash($message); - $k = $this->computek($h1); - list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $this->curve->convertInteger($k)); - $x = $x->toBigInteger(); - list(, $r) = $x->divide($this->q); - $kinv = $k->modInverse($this->q); - $h1 = $this->bits2int($h1); - $temp = $h1->add($dA->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($this->q); - */ - - return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); - - return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->password, $options); - } - - /** - * Returns the public key - * - * @see self::getPrivateKey() - * @access public - * @return mixed - */ - public function getPublicKey() - { - $format = 'PKCS8'; - if ($this->curve instanceof MontgomeryCurve) { - $format = 'MontgomeryPublic'; - } - - $type = self::validatePlugin('Keys', $format, 'savePublicKey'); - - $key = $type::savePublicKey($this->curve, $this->QA); - $key = EC::loadFormat($format, $key); - if ($this->curve instanceof MontgomeryCurve) { - return $key; - } - $key = $key - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - if ($this->curve instanceof TwistedEdwardsCurve) { - $key = $key->withContext($this->context); - } - return $key; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php deleted file mode 100644 index 2cb92ab68..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php +++ /dev/null @@ -1,177 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC; - -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\Hash; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; -use phpseclib3\Crypt\Common; -use phpseclib3\Exception\UnsupportedOperationException; -use phpseclib3\Common\Functions\Strings; - -/** - * EC Public Key - * - * @package EC - * @author Jim Wigginton - * @access public - */ -class PublicKey extends EC implements Common\PublicKey -{ - use Common\Traits\Fingerprint; - - /** - * Verify a signature - * - * @see self::verify() - * @access public - * @param string $message - * @param string $signature - * @return mixed - */ - public function verify($message, $signature) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - - $shortFormat = $this->shortFormat; - $format = $this->sigFormat; - if ($format === false) { - return false; - } - - $order = $this->curve->getOrder(); - - if ($this->curve instanceof TwistedEdwardsCurve) { - if ($shortFormat == 'SSH2') { - list(, $signature) = Strings::unpackSSH2('ss', $signature); - } - - if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { - return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium')); - } - - $curve = $this->curve; - if (strlen($signature) != 2 * $curve::SIZE) { - return false; - } - - $R = substr($signature, 0, $curve::SIZE); - $S = substr($signature, $curve::SIZE); - - try { - $R = PKCS1::extractPoint($R, $curve); - $R = $this->curve->convertToInternal($R); - } catch (\Exception $e) { - return false; - } - - $S = strrev($S); - $S = new BigInteger($S, 256); - - if ($S->compare($order) >= 0) { - return false; - } - - $A = $curve->encodePoint($this->QA); - - if ($curve instanceof Ed25519) { - $dom2 = !isset($this->context) ? '' : - 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; - } else { - $context = isset($this->context) ? $this->context : ''; - $dom2 = 'SigEd448' . "\0" . chr(strlen($context)) . $context; - } - - $hash = new Hash($curve::HASH); - $k = $hash->hash($dom2 . substr($signature, 0, $curve::SIZE) . $A . $message); - $k = strrev($k); - $k = new BigInteger($k, 256); - list(, $k) = $k->divide($order); - - $qa = $curve->convertToInternal($this->QA); - - $lhs = $curve->multiplyPoint($curve->getBasePoint(), $curve->convertInteger($S)); - $rhs = $curve->multiplyPoint($qa, $curve->convertInteger($k)); - $rhs = $curve->addPoint($rhs, $R); - $rhs = $curve->convertToAffine($rhs); - - return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]); - } - - $params = $format::load($signature); - if ($params === false || count($params) != 2) { - return false; - } - extract($params); - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; - - $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); - - if ($result != -1) { - return (bool) $result; - } - } - - $n_1 = $order->subtract(self::$one); - if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) { - return false; - } - - $e = $this->hash->hash($message); - $e = new BigInteger($e, 256); - - $Ln = $this->hash->getLength() - $order->getLength(); - $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; - - $w = $s->modInverse($order); - list(, $u1) = $z->multiply($w)->divide($order); - list(, $u2) = $r->multiply($w)->divide($order); - - $u1 = $this->curve->convertInteger($u1); - $u2 = $this->curve->convertInteger($u2); - - list($x1, $y1) = $this->curve->multiplyAddPoints( - [$this->curve->getBasePoint(), $this->QA], - [$u1, $u2] - ); - - $x1 = $x1->toBigInteger(); - list(, $x1) = $x1->divide($order); - - return $x1->equals($r); - } - - /** - * Returns the public key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - return $type::savePublicKey($this->curve, $this->QA, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php index 706de2147..248b65ef7 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php @@ -1,19 +1,26 @@ * setKey('abcdefg'); * @@ -24,69 +31,59 @@ * @category Crypt * @package Hash * @author Jim Wigginton - * @copyright 2015 Jim Wigginton - * @author Andreas Fischer - * @copyright 2015 Andreas Fischer + * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; +namespace phpseclib\Crypt; -use phpseclib3\Math\BigInteger; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\AES; -use phpseclib3\Math\PrimeField; +use phpseclib\Math\BigInteger; /** + * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions. + * * @package Hash * @author Jim Wigginton - * @author Andreas Fischer * @access public */ class Hash { - /** - * Padding Types - * + /**#@+ * @access private + * @see \phpseclib\Crypt\Hash::__construct() */ - //const PADDING_KECCAK = 1; - /** - * Padding Types - * - * @access private + * Toggles the internal implementation */ - const PADDING_SHA3 = 2; - + const MODE_INTERNAL = 1; /** - * Padding Types - * - * @access private + * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+. */ - const PADDING_SHAKE = 3; + const MODE_MHASH = 2; + /** + * Toggles the hash() implementation, which works on PHP 5.1.2+. + */ + const MODE_HASH = 3; + /**#@-*/ /** - * Padding Type - * - * Only used by SHA3 + * Hash Parameter * + * @see self::setHash() * @var int * @access private */ - private $paddingType = 0; + var $hashParam; /** - * Hash Parameter + * Byte-length of compression blocks / key (Internal HMAC) * - * @see self::setHash() + * @see self::setAlgorithm() * @var int * @access private */ - private $hashParam; + var $b; /** * Byte-length of hash output (Internal HMAC) @@ -95,7 +92,7 @@ class Hash * @var int * @access private */ - private $length; + var $l = false; /** * Hash Algorithm @@ -104,7 +101,7 @@ class Hash * @var string * @access private */ - private $algo; + var $hash; /** * Key @@ -113,24 +110,7 @@ class Hash * @var string * @access private */ - private $key = false; - - /** - * Nonce - * - * @see self::setNonce() - * @var string - * @access private - */ - private $nonce = false; - - /** - * Hash Parameters - * - * @var array - * @access private - */ - private $parameters = []; + var $key = false; /** * Computed Key @@ -139,83 +119,57 @@ class Hash * @var string * @access private */ - private $computedKey = false; + var $computedKey = false; /** * Outer XOR (Internal HMAC) * - * Used only for sha512/* - * - * @see self::hash() + * @see self::setKey() * @var string * @access private */ - private $opad; + var $opad; /** * Inner XOR (Internal HMAC) * - * Used only for sha512/* - * - * @see self::hash() + * @see self::setKey() * @var string * @access private */ - private $ipad; - - /** - * Recompute AES Key - * - * Used only for umac - * - * @see self::hash() - * @var boolean - * @access private - */ - private $recomputeAESKey; - - /** - * umac cipher object - * - * @see self::hash() - * @var \phpseclib3\Crypt\AES - * @access private - */ - private $c; + var $ipad; /** - * umac pad + * Engine * - * @see self::hash() + * @see self::setHash() * @var string * @access private */ - private $pad; - - /**#@+ - * UMAC variables - * - * @var PrimeField - */ - private static $factory36; - private static $factory64; - private static $factory128; - private static $offset64; - private static $offset128; - private static $marker64; - private static $marker128; - private static $maxwordrange64; - private static $maxwordrange128; - /**#@-*/ + var $engine; /** * Default Constructor. * * @param string $hash + * @return \phpseclib\Crypt\Hash * @access public */ - public function __construct($hash = 'sha256') + function __construct($hash = 'sha1') { + if (!defined('CRYPT_HASH_MODE')) { + switch (true) { + case extension_loaded('hash'): + define('CRYPT_HASH_MODE', self::MODE_HASH); + break; + case extension_loaded('mhash'): + define('CRYPT_HASH_MODE', self::MODE_MHASH); + break; + default: + define('CRYPT_HASH_MODE', self::MODE_INTERNAL); + } + } + $this->setHash($hash); } @@ -227,32 +181,10 @@ class Hash * @access public * @param string $key */ - public function setKey($key = false) + function setKey($key = false) { $this->key = $key; - $this->computeKey(); - $this->recomputeAESKey = true; - } - - /** - * Sets the nonce for UMACs - * - * Keys can be of any length. - * - * @access public - * @param string $nonce - */ - public function setNonce($nonce = false) - { - switch (true) { - case !is_string($nonce): - case strlen($nonce) > 0 && strlen($nonce) <= 16: - $this->recomputeAESKey = true; - $this->nonce = $nonce; - return; - } - - throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive'); + $this->_computeKey(); } /** @@ -267,21 +199,28 @@ class Hash * * @access private */ - private function computeKey() + function _computeKey() { if ($this->key === false) { $this->computedKey = false; return; } - if (strlen($this->key) <= $this->getBlockLengthInBytes()) { + if (strlen($this->key) <= $this->b) { $this->computedKey = $this->key; return; } - $this->computedKey = is_array($this->algo) ? - call_user_func($this->algo, $this->key) : - hash($this->algo, $this->key, true); + switch ($this->engine) { + case self::MODE_MHASH: + $this->computedKey = mhash($this->hash, $this->key); + break; + case self::MODE_HASH: + $this->computedKey = hash($this->hash, $this->key, true); + break; + case self::MODE_INTERNAL: + $this->computedKey = call_user_func($this->hash, $this->key); + } } /** @@ -292,7 +231,7 @@ class Hash * @access public * @return string */ - public function getHash() + function getHash() { return $this->hashParam; } @@ -303,588 +242,165 @@ class Hash * @access public * @param string $hash */ - public function setHash($hash) + function setHash($hash) { $this->hashParam = $hash = strtolower($hash); switch ($hash) { - case 'umac-32': - case 'umac-64': - case 'umac-96': - case 'umac-128': - $this->blockSize = 128; - $this->length = abs(substr($hash, -3)) >> 3; - $this->algo = 'umac'; - return; - case 'md2-96': case 'md5-96': case 'sha1-96': - case 'sha224-96': case 'sha256-96': - case 'sha384-96': case 'sha512-96': - case 'sha512/224-96': - case 'sha512/256-96': $hash = substr($hash, 0, -3); - $this->length = 12; // 96 / 8 = 12 + $this->l = 12; // 96 / 8 = 12 break; case 'md2': case 'md5': - $this->length = 16; + $this->l = 16; break; case 'sha1': - $this->length = 20; - break; - case 'sha224': - case 'sha512/224': - case 'sha3-224': - $this->length = 28; + $this->l = 20; break; case 'sha256': - case 'sha512/256': - case 'sha3-256': - $this->length = 32; + $this->l = 32; break; case 'sha384': - case 'sha3-384': - $this->length = 48; + $this->l = 48; break; case 'sha512': - case 'sha3-512': - $this->length = 64; - break; - default: - if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) { - $this->paddingType = self::PADDING_SHAKE; - $hash = $matches[1]; - $this->length = $matches[2] >> 3; - } else { - throw new UnsupportedAlgorithmException( - "$hash is not a supported algorithm" - ); - } + $this->l = 64; } switch ($hash) { - case 'md2': case 'md2-96': - $this->blockSize = 128; - break; + case 'md2': + $this->b = 16; case 'md5-96': case 'sha1-96': case 'sha224-96': case 'sha256-96': + case 'md2': case 'md5': case 'sha1': case 'sha224': case 'sha256': - $this->blockSize = 512; - break; - case 'sha3-224': - $this->blockSize = 1152; // 1600 - 2*224 - break; - case 'sha3-256': - case 'shake256': - $this->blockSize = 1088; // 1600 - 2*256 + $this->b = 64; break; - case 'sha3-384': - $this->blockSize = 832; // 1600 - 2*384 - break; - case 'sha3-512': - $this->blockSize = 576; // 1600 - 2*512 + default: + $this->b = 128; + } + + switch ($hash) { + case 'md2': + $this->engine = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ? + self::MODE_HASH : self::MODE_INTERNAL; break; - case 'shake128': - $this->blockSize = 1344; // 1600 - 2*128 + case 'sha384': + case 'sha512': + $this->engine = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE; break; default: - $this->blockSize = 1024; + $this->engine = CRYPT_HASH_MODE; } - if (in_array(substr($hash, 0, 5), ['sha3-', 'shake'])) { - // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": - // http://php.net/ChangeLog-7.php#7.1.0 - if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0,5) == 'shake') { - //preg_match('#(\d+)$#', $hash, $matches); - //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize - //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize - if (!$this->paddingType) { - $this->paddingType = self::PADDING_SHA3; + switch ($this->engine) { + case self::MODE_MHASH: + switch ($hash) { + case 'md5': + $this->hash = MHASH_MD5; + break; + case 'sha256': + $this->hash = MHASH_SHA256; + break; + case 'sha1': + default: + $this->hash = MHASH_SHA1; } - $this->parameters = [ - 'capacity' => 1600 - $this->blockSize, - 'rate' => $this->blockSize, - 'length' => $this->length, - 'padding' => $this->paddingType - ]; - $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32']; - } - } - - if ($hash == 'sha512/224' || $hash == 'sha512/256') { - // PHP 7.1.0 introduced sha512/224 and sha512/256 support: - // http://php.net/ChangeLog-7.php#7.1.0 - if (version_compare(PHP_VERSION, '7.1.0') < 0) { - // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24 - $initial = $hash == 'sha512/256' ? - [ - '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD', - '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2' - ] : - [ - '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF', - '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1' - ]; - for ($i = 0; $i < 8; $i++) { - $initial[$i] = new BigInteger($initial[$i], 16); - $initial[$i]->setPrecision(64); + $this->_computeKey(self::MODE_MHASH); + return; + case self::MODE_HASH: + switch ($hash) { + case 'md5': + $this->hash = 'md5'; + return; + case 'md2': + case 'sha256': + case 'sha384': + case 'sha512': + $this->hash = $hash; + return; + case 'sha1': + default: + $this->hash = 'sha1'; } - - $this->parameters = compact('initial'); - - $hash = ['phpseclib3\Crypt\Hash', 'sha512']; - } - } - - if (is_array($hash)) { - $b = $this->blockSize >> 3; - $this->ipad = str_repeat(chr(0x36), $b); - $this->opad = str_repeat(chr(0x5C), $b); - } - - $this->algo = $hash; - - $this->computeKey(); - } - - /** - * KDF: Key-Derivation Function - * - * The key-derivation function generates pseudorandom bits used to key the hash functions. - * - * @param int $index a non-negative integer less than 2^64 - * @param int $numbytes a non-negative integer less than 2^64 - * @return string string of length numbytes bytes - */ - private function kdf($index, $numbytes) - { - $this->c->setIV(pack('N4', 0, $index, 0, 1)); - - return $this->c->encrypt(str_repeat("\0", $numbytes)); - } - - /** - * PDF Algorithm - * - * @return string string of length taglen bytes. - */ - private function pdf() - { - $k = $this->key; - $nonce = $this->nonce; - $taglen = $this->length; - - // - // Extract and zero low bit(s) of Nonce if needed - // - if ($taglen <= 8) { - $last = strlen($nonce) - 1; - $mask = $taglen == 4 ? "\3" : "\1"; - $index = $nonce[$last] & $mask; - $nonce[$last] = $nonce[$last] ^ $index; - } - - // - // Make Nonce BLOCKLEN bytes by appending zeroes if needed - // - $nonce = str_pad($nonce, 16, "\0"); - - // - // Generate subkey, encipher and extract indexed substring - // - $kp = $this->kdf(0, 16); - $c = new AES('ctr'); - $c->disablePadding(); - $c->setKey($kp); - $c->setIV($nonce); - $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); - - // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you - // unpack() doesn't leak timing info - return $taglen <= 8 ? - substr($t, unpack('C', $index)[1] * $taglen, $taglen) : - substr($t, 0, $taglen); - } - - /** - * UHASH Algorithm - * - * @param string $m string of length less than 2^67 bits. - * @param int $taglen the integer 4, 8, 12 or 16. - * @return string string of length taglen bytes. - */ - private function uhash($m, $taglen) - { - // - // One internal iteration per 4 bytes of output - // - $iters = $taglen >> 2; - - // - // Define total key needed for all iterations using KDF. - // L1Key reuses most key material between iterations. - // - //$L1Key = $this->kdf(1, 1024 + ($iters - 1) * 16); - $L1Key = $this->kdf(1, (1024 + ($iters - 1)) * 16); - $L2Key = $this->kdf(2, $iters * 24); - $L3Key1 = $this->kdf(3, $iters * 64); - $L3Key2 = $this->kdf(4, $iters * 4); - - // - // For each iteration, extract key and do three-layer hash. - // If bytelength(M) <= 1024, then skip L2-HASH. - // - $y = ''; - for ($i = 0; $i < $iters; $i++) { - $L1Key_i = substr($L1Key, $i * 16, 1024); - $L2Key_i = substr($L2Key, $i * 24, 24); - $L3Key1_i = substr($L3Key1, $i * 64, 64); - $L3Key2_i = substr($L3Key2, $i * 4, 4); - - $a = self::L1Hash($L1Key_i, $m); - $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a); - $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b); - $y.= $c; - } - - return $y; - } - - /** - * L1-HASH Algorithm - * - * The first-layer hash breaks the message into 1024-byte chunks and - * hashes each with a function called NH. Concatenating the results - * forms a string, which is up to 128 times shorter than the original. - * - * @param string $k string of length 1024 bytes. - * @param string $m string of length less than 2^67 bits. - * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes. - */ - private static function L1Hash($k, $m) - { - // - // Break M into 1024 byte chunks (final chunk may be shorter) - // - $m = str_split($m, 1024); - - // - // For each chunk, except the last: endian-adjust, NH hash - // and add bit-length. Use results to build Y. - // - $length = new BigInteger(1024 * 8); - $y = ''; - for ($i = 0; $i < count($m) - 1; $i++) { - $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP - $y.= static::nh($k, $m[$i], $length); - } - - // - // For the last chunk: pad to 32-byte boundary, endian-adjust, - // NH hash and add bit-length. Concatenate the result to Y. - // - $length = strlen($m[$i]); - $pad = 32 - ($length % 32); - $pad = max(32, $length + $pad % 32); - $m[$i] = str_pad($m[$i], $pad, "\0"); // zeropad - $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP - - $y.= static::nh($k, $m[$i], new BigInteger($length * 8)); - - return $y; - } - - /** - * NH Algorithm - * - * @param string $k string of length 1024 bytes. - * @param string $m string with length divisible by 32 bytes. - * @return string string of length 8 bytes. - */ - private static function nh($k, $m, $length) - { - $toUInt32 = function($x) { - $x = new BigInteger($x, 256); - $x->setPrecision(32); - return $x; - }; - - // - // Break M and K into 4-byte chunks - // - //$t = strlen($m) >> 2; - $m = str_split($m, 4); - $t = count($m); - $k = str_split($k, 4); - $k = array_pad(array_slice($k, 0, $t), $t, 0); - - $m = array_map($toUInt32, $m); - $k = array_map($toUInt32, $k); - - // - // Perform NH hash on the chunks, pairing words for multiplication - // which are 4 apart to accommodate vector-parallelism. - // - $y = new BigInteger; - $y->setPrecision(64); - $i = 0; - while ($i < $t) { - $temp = $m[$i]->add($k[$i]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 4]->add($k[$i + 4])); - $y = $y->add($temp); - - $temp = $m[$i + 1]->add($k[$i + 1]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 5]->add($k[$i + 5])); - $y = $y->add($temp); - - $temp = $m[$i + 2]->add($k[$i + 2]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 6]->add($k[$i + 6])); - $y = $y->add($temp); - - $temp = $m[$i + 3]->add($k[$i + 3]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 7]->add($k[$i + 7])); - $y = $y->add($temp); - - $i+= 8; - } - - return $y->add($length)->toBytes(); - } - - /** - * L2-HASH: Second-Layer Hash - * - * The second-layer rehashes the L1-HASH output using a polynomial hash - * called POLY. If the L1-HASH output is long, then POLY is called once - * on a prefix of the L1-HASH output and called using different settings - * on the remainder. (This two-step hashing of the L1-HASH output is - * needed only if the message length is greater than 16 megabytes.) - * Careful implementation of POLY is necessary to avoid a possible - * timing attack (see Section 6.6 for more information). - * - * @param string $k string of length 24 bytes. - * @param string $m string of length less than 2^64 bytes. - * @return string string of length 16 bytes. - */ - private static function L2Hash($k, $m) - { - // - // Extract keys and restrict to special key-sets - // - $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; - $k64 = new BigInteger($k64, 256); - $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; - $k128 = new BigInteger($k128, 256); - - // - // If M is no more than 2^17 bytes, hash under 64-bit prime, - // otherwise, hash first 2^17 bytes under 64-bit prime and - // remainder under 128-bit prime. - // - if (strlen($m) <= 0x20000) { // 2^14 64-bit words - $y = self::poly(64, self::$maxwordrange64, $k64, $m); - } else { - $m_1 = substr($m, 0, 0x20000); // 1 << 17 - $m_2 = substr($m, 0x20000) . "\x80"; - $length = strlen($m_2); - $pad = 16 - ($length % 16); - $pad%= 16; - $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad - $y = self::poly(64, self::$maxwordrange64, $k64, $m_1); - $y = str_pad($y, 16, "\0", STR_PAD_LEFT); - $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2); - } - - return str_pad($y, 16, "\0", STR_PAD_LEFT); - } - - /** - * POLY Algorithm - * - * @param int $wordbits the integer 64 or 128. - * @param BigInteger $maxwordrange positive integer less than 2^wordbits. - * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1. - * @param string $m string with length divisible by (wordbits / 8) bytes. - * @return integer in the range 0 ... prime(wordbits) - 1. - */ - private static function poly($wordbits, $maxwordrange, $k, $m) - { - // - // Define constants used for fixing out-of-range words - // - $wordbytes = $wordbits >> 3; - if ($wordbits == 128) { - $factory = self::$factory128; - $offset = self::$offset128; - $marker = self::$marker128; - } else { - $factory = self::$factory64; - $offset = self::$offset64; - $marker = self::$marker64; + $this->_computeKey(self::MODE_HASH); + return; } - $k = $factory->newInteger($k); - - // - // Break M into chunks of length wordbytes bytes - // - $m_i = str_split($m, $wordbytes); - - // - // Each input word m is compared with maxwordrange. If not smaller - // then 'marker' and (m - offset), both in range, are hashed. - // - $y = $factory->newInteger(new BigInteger(1)); - foreach ($m_i as $m) { - $m = $factory->newInteger(new BigInteger($m, 256)); - if ($m->compare($maxwordrange) >= 0) { - $y = $k->multiply($y)->add($marker); - $y = $k->multiply($y)->add($m->subtract($offset)); - } else { - $y = $k->multiply($y)->add($m); - } + switch ($hash) { + case 'md2': + $this->hash = array($this, '_md2'); + break; + case 'md5': + $this->hash = array($this, '_md5'); + break; + case 'sha256': + $this->hash = array($this, '_sha256'); + break; + case 'sha384': + case 'sha512': + $this->hash = array($this, '_sha512'); + break; + case 'sha1': + default: + $this->hash = array($this, '_sha1'); } - return $y->toBytes(); - } - - /** - * L3-HASH: Third-Layer Hash - * - * The output from L2-HASH is 16 bytes long. This final hash function - * hashes the 16-byte string to a fixed length of 4 bytes. - * - * @param string $k1 string of length 64 bytes. - * @param string $k2 string of length 4 bytes. - * @param string $m string of length 16 bytes. - * @return string string of length 4 bytes. - */ - private static function L3Hash($k1, $k2, $m) - { - $factory = self::$factory36; - - $y = $factory->newInteger(new BigInteger()); - for ($i = 0; $i < 8; $i++) { - $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256)); - $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256)); - $y = $y->add($m_i->multiply($k_i)); - } - $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT); - $y = $y ^ $k2; + $this->ipad = str_repeat(chr(0x36), $this->b); + $this->opad = str_repeat(chr(0x5C), $this->b); - return $y; + $this->_computeKey(self::MODE_INTERNAL); } /** - * Compute the Hash / HMAC / UMAC. + * Compute the HMAC. * * @access public * @param string $text * @return string */ - public function hash($text) + function hash($text) { - $algo = $this->algo; - if ($algo == 'umac') { - if ($this->recomputeAESKey) { - if (!is_string($this->nonce)) { - throw new InsufficientSetupException('No nonce has been set'); - } - if (!is_string($this->key)) { - throw new InsufficientSetupException('No key has been set'); - } - if (strlen($this->key) != 16) { - throw new \LengthException('Key must be 16 bytes long'); - } - - if (!isset(self::$maxwordrange64)) { - $one = new BigInteger(1); - - $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256); - self::$factory36 = new PrimeField($prime36); - - $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256); - self::$factory64 = new PrimeField($prime64); - - $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256); - self::$factory128 = new PrimeField($prime128); - - self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256); - self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64)); - self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256); - self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128)); - - self::$marker64 = self::$factory64->newInteger($prime64->subtract($one)); - self::$marker128 = self::$factory128->newInteger($prime128->subtract($one)); - - $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32)); - self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64); - - $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96)); - self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128); - } - - $this->c = new AES('ctr'); - $this->c->disablePadding(); - $this->c->setKey($this->key); - - $this->pad = $this->pdf(); - - $this->recomputeAESKey = false; + if (!empty($this->key) || is_string($this->key)) { + switch ($this->engine) { + case self::MODE_MHASH: + $output = mhash($this->hash, $text, $this->computedKey); + break; + case self::MODE_HASH: + $output = hash_hmac($this->hash, $text, $this->computedKey, true); + break; + case self::MODE_INTERNAL: + $key = str_pad($this->computedKey, $this->b, chr(0)); // step 1 + $temp = $this->ipad ^ $key; // step 2 + $temp .= $text; // step 3 + $temp = call_user_func($this->hash, $temp); // step 4 + $output = $this->opad ^ $key; // step 5 + $output.= $temp; // step 6 + $output = call_user_func($this->hash, $output); // step 7 } - - $hashedmessage = $this->uhash($text, $this->length); - return $hashedmessage ^ $this->pad; - } - - if (is_array($algo)) { - if (empty($this->key) || !is_string($this->key)) { - return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); + } else { + switch ($this->engine) { + case self::MODE_MHASH: + $output = mhash($this->hash, $text); + break; + case self::MODE_HASH: + $output = hash($this->hash, $text, true); + break; + case self::MODE_INTERNAL: + $output = call_user_func($this->hash, $text); } - - // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 - - $key = str_pad($this->computedKey, $b, chr(0)); - $temp = $this->ipad ^ $key; - $temp .= $text; - $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); - $output = $this->opad ^ $key; - $output.= $temp; - $output = $algo($output, ...array_values($this->parameters)); - - return substr($output, 0, $this->length); } - $output = !empty($this->key) || is_string($this->key) ? - hash_hmac($algo, $text, $this->computedKey, true) : - hash($algo, $text, true); - - return strlen($output) > $this->length - ? substr($output, 0, $this->length) - : $output; - } - - /** - * Returns the hash length (in bits) - * - * @access public - * @return int - */ - public function getLength() - { - return $this->length << 3; + return substr($output, 0, $this->l); } /** @@ -893,444 +409,248 @@ class Hash * @access public * @return int */ - public function getLengthInBytes() + function getLength() { - return $this->length; + return $this->l; } /** - * Returns the block length (in bits) + * Wrapper for MD5 * - * @access public - * @return int - */ - public function getBlockLength() - { - return $this->blockSize; - } - - /** - * Returns the block length (in bytes) - * - * @access public - * @return int + * @access private + * @param string $m */ - public function getBlockLengthInBytes() + function _md5($m) { - return $this->blockSize >> 3; + return pack('H*', md5($m)); } /** - * Pads SHA3 based on the mode + * Wrapper for SHA1 * * @access private - * @param int $padLength - * @param int $padType - * @return string + * @param string $m */ - private static function sha3_pad($padLength, $padType) + function _sha1($m) { - switch ($padType) { - //case self::PADDING_KECCAK: - // $temp = chr(0x06) . str_repeat("\0", $padLength - 1); - // $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); - // return $temp - case self::PADDING_SHAKE: - $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); - $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); - return $temp; - //case self::PADDING_SHA3: - default: - // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36 - return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80); - } + return pack('H*', sha1($m)); } /** - * Pure-PHP 32-bit implementation of SHA3 + * Pure-PHP implementation of MD2 * - * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation - * of SHA3 will *not* work on PHP 64-bit. This is because this implementation - * employees bitwise NOTs and bitwise left shifts. And the round constants only work - * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and - * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow - * things down. - * - * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees - * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed - * 64-bit integers, which complicates addition, whereas that limitation isn't an issue - * for SHA3. - * - * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is - * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and - * capacity c". This is relevant because, altho the KECCAK standard defines a mode - * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3 + * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}. * * @access private - * @param string $p - * @param int $c - * @param int $r - * @param int $d - * @param int $padType + * @param string $m */ - private static function sha3_32($p, $c, $r, $d, $padType) + function _md2($m) { - $block_size = $r >> 3; - $padLength = $block_size - (strlen($p) % $block_size); - $num_ints = $block_size >> 2; - - $p.= static::sha3_pad($padLength, $padType); - - $n = strlen($p) / $r; // number of blocks - - $s = [ - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] - ]; - - $p = str_split($p, $block_size); - - foreach ($p as $pi) { - $pi = unpack('V*', $pi); - $x = $y = 0; - for ($i = 1; $i <= $num_ints; $i+=2) { - $s[$x][$y][0]^= $pi[$i + 1]; - $s[$x][$y][1]^= $pi[$i]; - if (++$y == 5) { - $y = 0; - $x++; - } - } - static::processSHA3Block32($s); - } + static $s = array( + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 + ); + + // Step 1. Append Padding Bytes + $pad = 16 - (strlen($m) & 0xF); + $m.= str_repeat(chr($pad), $pad); - $z = ''; - $i = $j = 0; - while (strlen($z) < $d) { - $z.= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]); - if ($j == 5) { - $j = 0; - $i++; - if ($i == 5) { - $i = 0; - static::processSHA3Block32($s); - } + $length = strlen($m); + + // Step 2. Append Checksum + $c = str_repeat(chr(0), 16); + $l = chr(0); + for ($i = 0; $i < $length; $i+= 16) { + for ($j = 0; $j < 16; $j++) { + // RFC1319 incorrectly states that C[j] should be set to S[c xor L] + //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]); + // per , however, C[j] should be set to S[c xor L] xor C[j] + $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j])); + $l = $c[$j]; } } + $m.= $c; - return $z; - } + $length+= 16; - /** - * 32-bit block processing method for SHA3 - * - * @access private - * @param array $s - */ - private static function processSHA3Block32(&$s) - { - static $rotationOffsets = [ - [ 0, 1, 62, 28, 27], - [36, 44, 6, 55, 20], - [ 3, 10, 43, 25, 39], - [41, 45, 15, 21, 8], - [18, 2, 61, 56, 14] - ]; - - // the standards give these constants in hexadecimal notation. it's tempting to want to use - // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive - // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead - static $roundConstants = [ - [0, 1], - [0, 32898], - [-2147483648, 32906], - [-2147483648, -2147450880], - [0, 32907], - [0, -2147483647], - [-2147483648, -2147450751], - [-2147483648, 32777], - [0, 138], - [0, 136], - [0, -2147450871], - [0, -2147483638], - [0, -2147450741], - [-2147483648, 139], - [-2147483648, 32905], - [-2147483648, 32771], - [-2147483648, 32770], - [-2147483648, 128], - [0, 32778], - [-2147483648, -2147483638], - [-2147483648, -2147450751], - [-2147483648, 32896], - [0, -2147483647], - [-2147483648, -2147450872] - ]; - - for ($round = 0; $round < 24; $round++) { - // theta step - $parity = $rotated = []; - for ($i = 0; $i < 5; $i++) { - $parity[] = [ - $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0], - $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1] - ]; - $rotated[] = static::rotateLeft32($parity[$i], 1); - } + // Step 3. Initialize MD Buffer + $x = str_repeat(chr(0), 48); - $temp = [ - [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]], - [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]], - [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]], - [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]], - [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]] - ]; - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $s[$i][$j][0]^= $temp[$j][0]; - $s[$i][$j][1]^= $temp[$j][1]; - } + // Step 4. Process Message in 16-Byte Blocks + for ($i = 0; $i < $length; $i+= 16) { + for ($j = 0; $j < 16; $j++) { + $x[$j + 16] = $m[$i + $j]; + $x[$j + 32] = $x[$j + 16] ^ $x[$j]; } - - $st = $s; - - // rho and pi steps - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]); + $t = chr(0); + for ($j = 0; $j < 18; $j++) { + for ($k = 0; $k < 48; $k++) { + $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]); + //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]); } + $t = chr(ord($t) + $j); } - - // chi step - for ($i = 0; $i < 5; $i++) { - $s[$i][0] = [ - $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]), - $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1]) - ]; - $s[$i][1] = [ - $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]), - $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1]) - ]; - $s[$i][2] = [ - $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]), - $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1]) - ]; - $s[$i][3] = [ - $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]), - $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1]) - ]; - $s[$i][4] = [ - $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]), - $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1]) - ]; - } - - // iota step - $s[0][0][0]^= $roundConstants[$round][0]; - $s[0][0][1]^= $roundConstants[$round][1]; } - } - /** - * Rotate 32-bit int - * - * @access private - * @param array $x - * @param int $shift - */ - private static function rotateLeft32($x, $shift) - { - if ($shift < 32) { - list($hi, $lo) = $x; - } else { - $shift-= 32; - list($lo, $hi) = $x; - } - - return [ - ($hi << $shift) | (($lo >> (32 - $shift)) & (1 << $shift) - 1), - ($lo << $shift) | (($hi >> (32 - $shift)) & (1 << $shift) - 1) - ]; + // Step 5. Output + return substr($x, 0, 16); } /** - * Pure-PHP 64-bit implementation of SHA3 + * Pure-PHP implementation of SHA256 + * + * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}. * * @access private - * @param string $p - * @param int $c - * @param int $r - * @param int $d - * @param int $padType + * @param string $m */ - private static function sha3_64($p, $c, $r, $d, $padType) + function _sha256($m) { - $block_size = $r >> 3; - $padLength = $block_size - (strlen($p) % $block_size); - $num_ints = $block_size >> 2; - - $p.= static::sha3_pad($padLength, $padType); - - $n = strlen($p) / $r; // number of blocks - - $s = [ - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0] - ]; - - $p = str_split($p, $block_size); - - foreach ($p as $pi) { - $pi = unpack('P*', $pi); - $x = $y = 0; - foreach ($pi as $subpi) { - $s[$x][$y++]^= $subpi; - if ($y == 5) { - $y = 0; - $x++; - } - } - static::processSHA3Block64($s); + if (extension_loaded('suhosin')) { + return pack('H*', sha256($m)); } - $z = ''; - $i = $j = 0; - while (strlen($z) < $d) { - $z.= pack('P', $s[$i][$j++]); - if ($j == 5) { - $j = 0; - $i++; - if ($i == 5) { - $i = 0; - static::processSHA3Block64($s); - } - } - } + // Initialize variables + $hash = array( + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 + ); + // Initialize table of round constants + // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311) + static $k = array( + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ); - return $z; - } + // Pre-processing + $length = strlen($m); + // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64 + $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F)); + $m[$length] = chr(0x80); + // we don't support hashing strings 512MB long + $m.= pack('N2', 0, $length << 3); - /** - * 64-bit block processing method for SHA3 - * - * @access private - * @param array $s - */ - private static function processSHA3Block64(&$s) - { - static $rotationOffsets = [ - [ 0, 1, 62, 28, 27], - [36, 44, 6, 55, 20], - [ 3, 10, 43, 25, 39], - [41, 45, 15, 21, 8], - [18, 2, 61, 56, 14] - ]; - - static $roundConstants = [ - 1, - 32898, - -9223372036854742902, - -9223372034707259392, - 32907, - 2147483649, - -9223372034707259263, - -9223372036854743031, - 138, - 136, - 2147516425, - 2147483658, - 2147516555, - -9223372036854775669, - -9223372036854742903, - -9223372036854743037, - -9223372036854743038, - -9223372036854775680, - 32778, - -9223372034707292150, - -9223372034707259263, - -9223372036854742912, - 2147483649, - -9223372034707259384 - ]; - - for ($round = 0; $round < 24; $round++) { - // theta step - $parity = []; - for ($i = 0; $i < 5; $i++) { - $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i]; - } - $temp = [ - $parity[4] ^ static::rotateLeft64($parity[1], 1), - $parity[0] ^ static::rotateLeft64($parity[2], 1), - $parity[1] ^ static::rotateLeft64($parity[3], 1), - $parity[2] ^ static::rotateLeft64($parity[4], 1), - $parity[3] ^ static::rotateLeft64($parity[0], 1) - ]; - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $s[$i][$j]^= $temp[$j]; - } + // Process the message in successive 512-bit chunks + $chunks = str_split($m, 64); + foreach ($chunks as $chunk) { + $w = array(); + for ($i = 0; $i < 16; $i++) { + extract(unpack('Ntemp', $this->_string_shift($chunk, 4))); + $w[] = $temp; } - $st = $s; - - // rho and pi steps - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]); - } + // Extend the sixteen 32-bit words into sixty-four 32-bit words + for ($i = 16; $i < 64; $i++) { + // @codingStandardsIgnoreStart + $s0 = $this->_rightRotate($w[$i - 15], 7) ^ + $this->_rightRotate($w[$i - 15], 18) ^ + $this->_rightShift( $w[$i - 15], 3); + $s1 = $this->_rightRotate($w[$i - 2], 17) ^ + $this->_rightRotate($w[$i - 2], 19) ^ + $this->_rightShift( $w[$i - 2], 10); + // @codingStandardsIgnoreEnd + $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1); } - // chi step - for ($i = 0; $i < 5; $i++) { - $s[$i] = [ - $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]), - $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]), - $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]), - $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]), - $st[$i][4] ^ (~$st[$i][0] & $st[$i][1]) - ]; + // Initialize hash value for this chunk + list($a, $b, $c, $d, $e, $f, $g, $h) = $hash; + + // Main loop + for ($i = 0; $i < 64; $i++) { + $s0 = $this->_rightRotate($a, 2) ^ + $this->_rightRotate($a, 13) ^ + $this->_rightRotate($a, 22); + $maj = ($a & $b) ^ + ($a & $c) ^ + ($b & $c); + $t2 = $this->_add($s0, $maj); + + $s1 = $this->_rightRotate($e, 6) ^ + $this->_rightRotate($e, 11) ^ + $this->_rightRotate($e, 25); + $ch = ($e & $f) ^ + ($this->_not($e) & $g); + $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]); + + $h = $g; + $g = $f; + $f = $e; + $e = $this->_add($d, $t1); + $d = $c; + $c = $b; + $b = $a; + $a = $this->_add($t1, $t2); } - // iota step - $s[0][0]^= $roundConstants[$round]; + // Add this chunk's hash to result so far + $hash = array( + $this->_add($hash[0], $a), + $this->_add($hash[1], $b), + $this->_add($hash[2], $c), + $this->_add($hash[3], $d), + $this->_add($hash[4], $e), + $this->_add($hash[5], $f), + $this->_add($hash[6], $g), + $this->_add($hash[7], $h) + ); } - } - /** - * Rotate 64-bit int - * - * @access private - * @param int $x - * @param int $shift - */ - private static function rotateLeft64($x, $shift) - { - return ($x << $shift) | (($x >> (64 - $shift)) & ((1 << $shift) - 1)); + // Produce the final hash value (big-endian) + return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]); } /** - * Pure-PHP implementation of SHA512 + * Pure-PHP implementation of SHA384 and SHA512 * * @access private * @param string $m - * @param array $hash - * @return string */ - private static function sha512($m, $hash) + function _sha512($m) { - static $k; + static $init384, $init512, $k; if (!isset($k)) { + // Initialize variables + $init384 = array( // initial values for SHA384 + 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939', + '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4' + ); + $init512 = array( // initial values for SHA512 + '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1', + '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179' + ); + + for ($i = 0; $i < 8; $i++) { + $init384[$i] = new BigInteger($init384[$i], 16); + $init384[$i]->setPrecision(64); + $init512[$i] = new BigInteger($init512[$i], 16); + $init512[$i]->setPrecision(64); + } + // Initialize table of round constants // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) - $k = [ + $k = array( '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', @@ -1351,13 +671,15 @@ class Hash '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' - ]; + ); for ($i = 0; $i < 80; $i++) { $k[$i] = new BigInteger($k[$i], 16); } } + $hash = $this->l == 48 ? $init384 : $init512; + // Pre-processing $length = strlen($m); // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 @@ -1369,92 +691,92 @@ class Hash // Process the message in successive 1024-bit chunks $chunks = str_split($m, 128); foreach ($chunks as $chunk) { - $w = []; + $w = array(); for ($i = 0; $i < 16; $i++) { - $temp = new BigInteger(Strings::shift($chunk, 8), 256); + $temp = new BigInteger($this->_string_shift($chunk, 8), 256); $temp->setPrecision(64); $w[] = $temp; } // Extend the sixteen 32-bit words into eighty 32-bit words for ($i = 16; $i < 80; $i++) { - $temp = [ + $temp = array( $w[$i - 15]->bitwise_rightRotate(1), $w[$i - 15]->bitwise_rightRotate(8), $w[$i - 15]->bitwise_rightShift(7) - ]; + ); $s0 = $temp[0]->bitwise_xor($temp[1]); $s0 = $s0->bitwise_xor($temp[2]); - $temp = [ + $temp = array( $w[$i - 2]->bitwise_rightRotate(19), $w[$i - 2]->bitwise_rightRotate(61), $w[$i - 2]->bitwise_rightShift(6) - ]; + ); $s1 = $temp[0]->bitwise_xor($temp[1]); $s1 = $s1->bitwise_xor($temp[2]); - $w[$i] = clone $w[$i - 16]; + $w[$i] = $w[$i - 16]->copy(); $w[$i] = $w[$i]->add($s0); $w[$i] = $w[$i]->add($w[$i - 7]); $w[$i] = $w[$i]->add($s1); } // Initialize hash value for this chunk - $a = clone $hash[0]; - $b = clone $hash[1]; - $c = clone $hash[2]; - $d = clone $hash[3]; - $e = clone $hash[4]; - $f = clone $hash[5]; - $g = clone $hash[6]; - $h = clone $hash[7]; + $a = $hash[0]->copy(); + $b = $hash[1]->copy(); + $c = $hash[2]->copy(); + $d = $hash[3]->copy(); + $e = $hash[4]->copy(); + $f = $hash[5]->copy(); + $g = $hash[6]->copy(); + $h = $hash[7]->copy(); // Main loop for ($i = 0; $i < 80; $i++) { - $temp = [ + $temp = array( $a->bitwise_rightRotate(28), $a->bitwise_rightRotate(34), $a->bitwise_rightRotate(39) - ]; + ); $s0 = $temp[0]->bitwise_xor($temp[1]); $s0 = $s0->bitwise_xor($temp[2]); - $temp = [ + $temp = array( $a->bitwise_and($b), $a->bitwise_and($c), $b->bitwise_and($c) - ]; + ); $maj = $temp[0]->bitwise_xor($temp[1]); $maj = $maj->bitwise_xor($temp[2]); $t2 = $s0->add($maj); - $temp = [ + $temp = array( $e->bitwise_rightRotate(14), $e->bitwise_rightRotate(18), $e->bitwise_rightRotate(41) - ]; + ); $s1 = $temp[0]->bitwise_xor($temp[1]); $s1 = $s1->bitwise_xor($temp[2]); - $temp = [ + $temp = array( $e->bitwise_and($f), $g->bitwise_and($e->bitwise_not()) - ]; + ); $ch = $temp[0]->bitwise_xor($temp[1]); $t1 = $h->add($s1); $t1 = $t1->add($ch); $t1 = $t1->add($k[$i]); $t1 = $t1->add($w[$i]); - $h = clone $g; - $g = clone $f; - $f = clone $e; + $h = $g->copy(); + $g = $f->copy(); + $f = $e->copy(); $e = $d->add($t1); - $d = clone $c; - $c = clone $b; - $b = clone $a; + $d = $c->copy(); + $c = $b->copy(); + $b = $a->copy(); $a = $t1->add($t2); } // Add this chunk's hash to result so far - $hash = [ + $hash = array( $hash[0]->add($a), $hash[1]->add($b), $hash[2]->add($c), @@ -1463,22 +785,109 @@ class Hash $hash[5]->add($f), $hash[6]->add($g), $hash[7]->add($h) - ]; + ); } // Produce the final hash value (big-endian) - // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) + // (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . - $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes(); + $hash[4]->toBytes() . $hash[5]->toBytes(); + if ($this->l != 48) { + $temp.= $hash[6]->toBytes() . $hash[7]->toBytes(); + } return $temp; } /** - * __toString() magic method + * Right Rotate + * + * @access private + * @param int $int + * @param int $amt + * @see self::_sha256() + * @return int + */ + function _rightRotate($int, $amt) + { + $invamt = 32 - $amt; + $mask = (1 << $invamt) - 1; + return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask); + } + + /** + * Right Shift + * + * @access private + * @param int $int + * @param int $amt + * @see self::_sha256() + * @return int + */ + function _rightShift($int, $amt) + { + $mask = (1 << (32 - $amt)) - 1; + return ($int >> $amt) & $mask; + } + + /** + * Not + * + * @access private + * @param int $int + * @see self::_sha256() + * @return int + */ + function _not($int) + { + return ~$int & 0xFFFFFFFF; + } + + /** + * Add + * + * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the + * possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster. + * + * @return int + * @see self::_sha256() + * @access private + */ + function _add() + { + static $mod; + if (!isset($mod)) { + $mod = pow(2, 32); + } + + $result = 0; + $arguments = func_get_args(); + foreach ($arguments as $argument) { + $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument; + } + + if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') { + return fmod($result, $mod); + } + + return (fmod($result, 0x80000000) & 0x7FFFFFFF) | + ((fmod(floor($result / 0x80000000), 2) & 1) << 31); + } + + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + * @access private */ - public function __toString() + function _string_shift(&$string, $index = 1) { - return $this->getHash(); + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php deleted file mode 100644 index c7c7e0af4..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Exception\NoKeyLoadedException; -use phpseclib3\File\X509; - -/** - * PublicKeyLoader - * - * @package Common - * @author Jim Wigginton - * @access public - */ -abstract class PublicKeyLoader -{ - /** - * Loads a public or private key - * - * @return AsymmetricKey - * @access public - * @param string|array $key - * @param string $password optional - */ - public static function load($key, $password = false) - { - try { - return EC::load($key, $password); - } catch (NoKeyLoadedException $e) {} - - try { - return RSA::load($key, $password); - } catch (NoKeyLoadedException $e) {} - - try { - return DSA::load($key, $password); - } catch (NoKeyLoadedException $e) {} - - try { - $x509 = new X509(); - $x509->loadX509($key); - $key = $x509->getPublicKey(); - if ($key) { - return $key; - } - } catch (\Exception $e) {} - - throw new NoKeyLoadedException('Unable to read key'); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php index 813eeca45..b2b9d48ea 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php @@ -16,7 +16,7 @@ * setKey('abcdefgh'); * @@ -33,10 +33,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; -use phpseclib3\Exception\BadModeException; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of RC2. @@ -44,109 +41,106 @@ use phpseclib3\Exception\BadModeException; * @package RC2 * @access public */ -class RC2 extends BlockCipher +class RC2 extends Base { /** * Block Length of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @see \phpseclib\Crypt\Base::block_size * @var int * @access private */ - protected $block_size = 8; + var $block_size = 8; /** * The Key * - * @see \phpseclib3\Crypt\Common\SymmetricKey::key + * @see \phpseclib\Crypt\Base::key * @see self::setKey() * @var string * @access private */ - protected $key; + var $key; /** * The Original (unpadded) Key * - * @see \phpseclib3\Crypt\Common\SymmetricKey::key + * @see \phpseclib\Crypt\Base::key * @see self::setKey() * @see self::encrypt() * @see self::decrypt() * @var string * @access private */ - private $orig_key; + var $orig_key; /** * Don't truncate / null pad key * - * @see \phpseclib3\Crypt\Common\SymmetricKey::clearBuffers() + * @see \phpseclib\Crypt\Base::_clearBuffers() * @var bool * @access private */ - private $skip_key_adjustment = true; + var $skip_key_adjustment = true; /** * Key Length (in bytes) * - * @see \phpseclib3\Crypt\RC2::setKeyLength() + * @see \phpseclib\Crypt\RC2::setKeyLength() * @var int * @access private */ - protected $key_length = 16; // = 128 bits + var $key_length = 16; // = 128 bits /** * The mcrypt specific name of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib\Crypt\Base::cipher_name_mcrypt * @var string * @access private */ - protected $cipher_name_mcrypt = 'rc2'; + var $cipher_name_mcrypt = 'rc2'; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @see \phpseclib\Crypt\Base::cfb_init_len * @var int * @access private */ - protected $cfb_init_len = 500; + var $cfb_init_len = 500; /** * The key length in bits. * - * {@internal Should be in range [1..1024].} - * - * {@internal Changing this value after setting the key has no effect.} - * * @see self::setKeyLength() * @see self::setKey() * @var int * @access private + * @internal Should be in range [1..1024]. + * @internal Changing this value after setting the key has no effect. */ - private $default_key_length = 1024; + var $default_key_length = 1024; /** * The key length in bits. * - * {@internal Should be in range [1..1024].} - * * @see self::isValidEnine() * @see self::setKey() * @var int * @access private + * @internal Should be in range [1..1024]. */ - private $current_key_length; + var $current_key_length; /** * The Key Schedule * - * @see self::setupKey() + * @see self::_setupKey() * @var array * @access private */ - private $keys; + var $keys; /** * Key expansion randomization table. @@ -156,7 +150,7 @@ class RC2 extends BlockCipher * @var array * @access private */ - private static $pitable = [ + var $pitable = array( 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, @@ -221,7 +215,7 @@ class RC2 extends BlockCipher 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD - ]; + ); /** * Inverse key expansion randomization table. @@ -230,7 +224,7 @@ class RC2 extends BlockCipher * @var array * @access private */ - private static $invpitable = [ + var $invpitable = array( 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66, 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4, 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20, @@ -263,46 +257,30 @@ class RC2 extends BlockCipher 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75, 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87, 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6 - ]; - - /** - * Default Constructor. - * - * @param string $mode - * @access public - * @throws \InvalidArgumentException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } + ); /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @see \phpseclib\Crypt\Base::__construct() * @param int $engine - * @access protected + * @access public * @return bool */ - protected function isValidEngineHelper($engine) + function isValidEngine($engine) { switch ($engine) { case self::ENGINE_OPENSSL: if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { return false; } - self::$cipher_name_openssl_ecb = 'rc2-ecb'; - $this->cipher_name_openssl = 'rc2-' . $this->openssl_translate_mode(); + $this->cipher_name_openssl_ecb = 'rc2-ecb'; + $this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode(); } - return parent::isValidEngineHelper($engine); + return parent::isValidEngine($engine); } /** @@ -310,20 +288,23 @@ class RC2 extends BlockCipher * * Valid key lengths are 8 to 1024. * Calling this function after setting the key has no effect until the next - * \phpseclib3\Crypt\RC2::setKey() call. + * \phpseclib\Crypt\RC2::setKey() call. * * @access public * @param int $length in bits - * @throws \LengthException if the key length isn't supported */ - public function setKeyLength($length) + function setKeyLength($length) { - if ($length < 8 || $length > 1024) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); + if ($length < 8) { + $this->default_key_length = 1; + } elseif ($length > 1024) { + $this->default_key_length = 128; + } else { + $this->default_key_length = $length; } + $this->current_key_length = $this->default_key_length; - $this->default_key_length = $this->current_key_length = $length; - $this->explicit_key_length = $length >> 3; + parent::setKeyLength($length); } /** @@ -332,7 +313,7 @@ class RC2 extends BlockCipher * @access public * @return int */ - public function getKeyLength() + function getKeyLength() { return $this->current_key_length; } @@ -345,29 +326,26 @@ class RC2 extends BlockCipher * has more then 128 bytes in it, and set $key to a single null byte if * it is empty. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * If the key is not explicitly set, it'll be assumed to be a single + * null byte. + * + * @see \phpseclib\Crypt\Base::setKey() * @access public * @param string $key - * @param int|boolean $t1 optional Effective key length in bits. - * @throws \LengthException if the key length isn't supported + * @param int $t1 optional Effective key length in bits. */ - public function setKey($key, $t1 = false) + function setKey($key, $t1 = 0) { $this->orig_key = $key; - if ($t1 === false) { + if ($t1 <= 0) { $t1 = $this->default_key_length; + } elseif ($t1 > 1024) { + $t1 = 1024; } - - if ($t1 < 1 || $t1 > 1024) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); - } - $this->current_key_length = $t1; - if (strlen($key) < 1 || strlen($key) > 128) { - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported'); - } - + // Key byte count should be 1..128. + $key = strlen($key) ? substr($key, 0, 128) : "\x00"; $t = strlen($key); // The mcrypt RC2 implementation only supports effective key length @@ -382,7 +360,7 @@ class RC2 extends BlockCipher $tm = 0xFF >> (8 * $t8 - $t1); // Expand key. - $pitable = self::$pitable; + $pitable = $this->pitable; for ($i = $t; $i < 128; $i++) { $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]]; } @@ -393,26 +371,23 @@ class RC2 extends BlockCipher } // Prepare the key for mcrypt. - $l[0] = self::$invpitable[$l[0]]; + $l[0] = $this->invpitable[$l[0]]; array_unshift($l, 'C*'); - $this->key = pack(...$l); - $this->key_length = strlen($this->key); - $this->changed = $this->nonIVChanged = true; - $this->setEngine(); + parent::setKey(call_user_func_array('pack', $l)); } /** * Encrypts a message. * - * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::encrypt, with some additional OpenSSL handling code + * Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code * * @see self::decrypt() * @access public * @param string $plaintext * @return string $ciphertext */ - public function encrypt($plaintext) + function encrypt($plaintext) { if ($this->engine == self::ENGINE_OPENSSL) { $temp = $this->key; @@ -428,14 +403,14 @@ class RC2 extends BlockCipher /** * Decrypts a message. * - * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::decrypt, with some additional OpenSSL handling code + * Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code * * @see self::encrypt() * @access public * @param string $ciphertext * @return string $plaintext */ - public function decrypt($ciphertext) + function decrypt($ciphertext) { if ($this->engine == self::ENGINE_OPENSSL) { $temp = $this->key; @@ -451,18 +426,18 @@ class RC2 extends BlockCipher /** * Encrypts a block * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib\Crypt\Base::_encryptBlock() + * @see \phpseclib\Crypt\Base::encrypt() * @access private * @param string $in * @return string */ - protected function encryptBlock($in) + function _encryptBlock($in) { list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); $keys = $this->keys; $limit = 20; - $actions = [$limit => 44, 44 => 64]; + $actions = array($limit => 44, 44 => 64); $j = 0; for (;;) { @@ -496,18 +471,18 @@ class RC2 extends BlockCipher /** * Decrypts a block * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see \phpseclib\Crypt\Base::_decryptBlock() + * @see \phpseclib\Crypt\Base::decrypt() * @access private * @param string $in * @return string */ - protected function decryptBlock($in) + function _decryptBlock($in) { list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); $keys = $this->keys; $limit = 44; - $actions = [$limit => 20, 20 => 0]; + $actions = array($limit => 20, 20 => 0); $j = 64; for (;;) { @@ -538,22 +513,37 @@ class RC2 extends BlockCipher return pack('vvvv', $r0, $r1, $r2, $r3); } + /** + * Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine + * + * @see \phpseclib\Crypt\Base::_setupMcrypt() + * @access private + */ + function _setupMcrypt() + { + if (!isset($this->key)) { + $this->setKey(''); + } + + parent::_setupMcrypt(); + } + /** * Creates the key schedule * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @see \phpseclib\Crypt\Base::_setupKey() * @access private */ - protected function setupKey() + function _setupKey() { if (!isset($this->key)) { $this->setKey(''); } - // Key has already been expanded in \phpseclib3\Crypt\RC2::setKey(): + // Key has already been expanded in \phpseclib\Crypt\RC2::setKey(): // Only the first value must be altered. $l = unpack('Ca/Cb/v*', $this->key); - array_unshift($l, self::$pitable[$l['a']] | ($l['b'] << 8)); + array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8)); unset($l['a']); unset($l['b']); $this->keys = $l; @@ -562,108 +552,137 @@ class RC2 extends BlockCipher /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + * @see \phpseclib\Crypt\Base::_setupInlineCrypt() * @access private */ - protected function setupInlineCrypt() + function _setupInlineCrypt() { - // Init code for both, encrypt and decrypt. - $init_crypt = '$keys = $this->keys;'; - - $keys = $this->keys; - - // $in is the current 8 bytes block which has to be en/decrypt - $encrypt_block = $decrypt_block = ' - $in = unpack("v4", $in); - $r0 = $in[1]; - $r1 = $in[2]; - $r2 = $in[3]; - $r3 = $in[4]; - '; - - // Create code for encryption. - $limit = 20; - $actions = [$limit => 44, 44 => 64]; - $j = 0; - - for (;;) { - // Mixing round. - $encrypt_block .= ' - $r0 = (($r0 + ' . $keys[$j++] . ' + - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; - $r0 |= $r0 >> 16; - $r1 = (($r1 + ' . $keys[$j++] . ' + - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; - $r1 |= $r1 >> 16; - $r2 = (($r2 + ' . $keys[$j++] . ' + - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; - $r2 |= $r2 >> 16; - $r3 = (($r3 + ' . $keys[$j++] . ' + - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; - $r3 |= $r3 >> 16;'; + $lambda_functions =& self::_getLambdaFunctions(); + + // The first 10 generated $lambda_functions will use the $keys hardcoded as integers + // for the mixing rounds, for better inline crypt performance [~20% faster]. + // But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10. + // (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit) + $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); + + // Generation of a unique hash for our generated code + $code_hash = "Crypt_RC2, {$this->mode}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); + } - if ($j === $limit) { - if ($limit === 64) { - break; - } + // Is there a re-usable $lambda_functions in there? + // If not, we have to create it. + if (!isset($lambda_functions[$code_hash])) { + // Init code for both, encrypt and decrypt. + $init_crypt = '$keys = $self->keys;'; + + switch (true) { + case $gen_hi_opt_code: + $keys = $this->keys; + default: + $keys = array(); + foreach ($this->keys as $k => $v) { + $keys[$k] = '$keys[' . $k . ']'; + } + } - // Mashing round. + // $in is the current 8 bytes block which has to be en/decrypt + $encrypt_block = $decrypt_block = ' + $in = unpack("v4", $in); + $r0 = $in[1]; + $r1 = $in[2]; + $r2 = $in[3]; + $r3 = $in[4]; + '; + + // Create code for encryption. + $limit = 20; + $actions = array($limit => 44, 44 => 64); + $j = 0; + + for (;;) { + // Mixing round. $encrypt_block .= ' - $r0 += $keys[$r3 & 0x3F]; - $r1 += $keys[$r0 & 0x3F]; - $r2 += $keys[$r1 & 0x3F]; - $r3 += $keys[$r2 & 0x3F];'; - $limit = $actions[$limit]; + $r0 = (($r0 + ' . $keys[$j++] . ' + + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; + $r0 |= $r0 >> 16; + $r1 = (($r1 + ' . $keys[$j++] . ' + + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; + $r1 |= $r1 >> 16; + $r2 = (($r2 + ' . $keys[$j++] . ' + + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; + $r2 |= $r2 >> 16; + $r3 = (($r3 + ' . $keys[$j++] . ' + + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; + $r3 |= $r3 >> 16;'; + + if ($j === $limit) { + if ($limit === 64) { + break; + } + + // Mashing round. + $encrypt_block .= ' + $r0 += $keys[$r3 & 0x3F]; + $r1 += $keys[$r0 & 0x3F]; + $r2 += $keys[$r1 & 0x3F]; + $r3 += $keys[$r2 & 0x3F];'; + $limit = $actions[$limit]; + } } - } - $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; - // Create code for decryption. - $limit = 44; - $actions = [$limit => 20, 20 => 0]; - $j = 64; - - for (;;) { - // R-mixing round. - $decrypt_block .= ' - $r3 = ($r3 | ($r3 << 16)) >> 5; - $r3 = ($r3 - ' . $keys[--$j] . ' - - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; - $r2 = ($r2 | ($r2 << 16)) >> 3; - $r2 = ($r2 - ' . $keys[--$j] . ' - - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; - $r1 = ($r1 | ($r1 << 16)) >> 2; - $r1 = ($r1 - ' . $keys[--$j] . ' - - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; - $r0 = ($r0 | ($r0 << 16)) >> 1; - $r0 = ($r0 - ' . $keys[--$j] . ' - - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; - - if ($j === $limit) { - if ($limit === 0) { - break; - } + // Create code for decryption. + $limit = 44; + $actions = array($limit => 20, 20 => 0); + $j = 64; - // R-mashing round. + for (;;) { + // R-mixing round. $decrypt_block .= ' - $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; - $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; - $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; - $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; - $limit = $actions[$limit]; + $r3 = ($r3 | ($r3 << 16)) >> 5; + $r3 = ($r3 - ' . $keys[--$j] . ' - + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; + $r2 = ($r2 | ($r2 << 16)) >> 3; + $r2 = ($r2 - ' . $keys[--$j] . ' - + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; + $r1 = ($r1 | ($r1 << 16)) >> 2; + $r1 = ($r1 - ' . $keys[--$j] . ' - + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; + $r0 = ($r0 | ($r0 << 16)) >> 1; + $r0 = ($r0 - ' . $keys[--$j] . ' - + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; + + if ($j === $limit) { + if ($limit === 0) { + break; + } + + // R-mashing round. + $decrypt_block .= ' + $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; + $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; + $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; + $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; + $limit = $actions[$limit]; + } } - } - $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + + // Creates the inline-crypt function + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( + array( + 'init_crypt' => $init_crypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ) + ); + } - // Creates the inline-crypt function - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); + // Set the inline-crypt function as callback in: $this->inline_crypt + $this->inline_crypt = $lambda_functions[$code_hash]; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php index d2d3a71c0..25e4ff854 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php @@ -20,7 +20,7 @@ * setKey('abcdefgh'); * @@ -42,9 +42,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\StreamCipher; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of RC4. @@ -53,37 +51,54 @@ use phpseclib3\Crypt\Common\StreamCipher; * @author Jim Wigginton * @access public */ -class RC4 extends StreamCipher +class RC4 extends Base { - /** + /**#@+ * @access private - * @see \phpseclib3\Crypt\RC4::_crypt() - */ + * @see \phpseclib\Crypt\RC4::_crypt() + */ const ENCRYPT = 0; + const DECRYPT = 1; + /**#@-*/ /** + * Block Length of the cipher + * + * RC4 is a stream cipher + * so we the block_size to 0 + * + * @see \phpseclib\Crypt\Base::block_size + * @var int * @access private - * @see \phpseclib3\Crypt\RC4::_crypt() */ - const DECRYPT = 1; + var $block_size = 0; /** * Key Length (in bytes) * - * @see \phpseclib3\Crypt\RC4::setKeyLength() + * @see \phpseclib\Crypt\RC4::setKeyLength() * @var int * @access private */ - protected $key_length = 128; // = 1024 bits + var $key_length = 128; // = 1024 bits /** * The mcrypt specific name of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib\Crypt\Base::cipher_name_mcrypt * @var string * @access private */ - protected $cipher_name_mcrypt = 'arcfour'; + var $cipher_name_mcrypt = 'arcfour'; + + /** + * Holds whether performance-optimized $inline_crypt() can/should be used. + * + * @see \phpseclib\Crypt\Base::inline_crypt + * @var mixed + * @access private + */ + var $use_inline_crypt = false; // currently not available /** * The Key @@ -92,7 +107,7 @@ class RC4 extends StreamCipher * @var string * @access private */ - protected $key; + var $key; /** * The Key Stream for decryption and encryption @@ -101,24 +116,35 @@ class RC4 extends StreamCipher * @var array * @access private */ - private $stream; + var $stream; + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. + * + * @see \phpseclib\Crypt\Base::__construct() + * @return \phpseclib\Crypt\RC4 + * @access public + */ + function __construct() + { + parent::__construct(Base::MODE_STREAM); + } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @see \phpseclib\Crypt\Base::__construct() * @param int $engine - * @access protected + * @access public * @return bool */ - protected function isValidEngineHelper($engine) + function isValidEngine($engine) { - if ($engine == self::ENGINE_OPENSSL) { - if ($this->continuousBuffer) { - return false; - } + if ($engine == Base::ENGINE_OPENSSL) { if (version_compare(PHP_VERSION, '5.3.7') >= 0) { $this->cipher_name_openssl = 'rc4-40'; } else { @@ -138,27 +164,30 @@ class RC4 extends StreamCipher } } - return parent::isValidEngineHelper($engine); + return parent::isValidEngine($engine); } /** - * Sets the key length + * Dummy function. * - * Keys can be between 1 and 256 bytes long. + * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1]. + * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before + * calling setKey(). + * + * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol, + * the IV's are relatively easy to predict, an attack described by + * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir} + * can be used to quickly guess at the rest of the key. The following links elaborate: + * + * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009} + * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack} * + * @param string $iv + * @see self::setKey() * @access public - * @param int $length - * @throws \LengthException if the key length is invalid */ - public function setKeyLength($length) + function setIV($iv) { - if ($length < 8 || $length > 2048) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported'); - } - - $this->key_length = $length >> 3; - - parent::setKeyLength($length); } /** @@ -167,33 +196,36 @@ class RC4 extends StreamCipher * Keys can be between 1 and 256 bytes long. * * @access public - * @param string $key + * @param int $length */ - public function setKey($key) + function setKeyLength($length) { - $length = strlen($key); - if ($length < 1 || $length > 256) { - throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); + if ($length < 8) { + $this->key_length = 1; + } elseif ($length > 2048) { + $this->key_length = 256; + } else { + $this->key_length = $length >> 3; } - parent::setKey($key); + parent::setKeyLength($length); } /** * Encrypts a message. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @see self::crypt() + * @see \phpseclib\Crypt\Base::decrypt() + * @see self::_crypt() * @access public * @param string $plaintext * @return string $ciphertext */ - public function encrypt($plaintext) + function encrypt($plaintext) { - if ($this->engine != self::ENGINE_INTERNAL) { + if ($this->engine != Base::ENGINE_INTERNAL) { return parent::encrypt($plaintext); } - return $this->crypt($plaintext, self::ENCRYPT); + return $this->_crypt($plaintext, self::ENCRYPT); } /** @@ -202,18 +234,18 @@ class RC4 extends StreamCipher * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). * At least if the continuous buffer is disabled. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see self::crypt() + * @see \phpseclib\Crypt\Base::encrypt() + * @see self::_crypt() * @access public * @param string $ciphertext * @return string $plaintext */ - public function decrypt($ciphertext) + function decrypt($ciphertext) { - if ($this->engine != self::ENGINE_INTERNAL) { + if ($this->engine != Base::ENGINE_INTERNAL) { return parent::decrypt($ciphertext); } - return $this->crypt($ciphertext, self::DECRYPT); + return $this->_crypt($ciphertext, self::DECRYPT); } /** @@ -222,7 +254,7 @@ class RC4 extends StreamCipher * @access private * @param string $in */ - protected function encryptBlock($in) + function _encryptBlock($in) { // RC4 does not utilize this method } @@ -233,7 +265,7 @@ class RC4 extends StreamCipher * @access private * @param string $in */ - protected function decryptBlock($in) + function _decryptBlock($in) { // RC4 does not utilize this method } @@ -241,10 +273,10 @@ class RC4 extends StreamCipher /** * Setup the key (expansion) * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + * @see \phpseclib\Crypt\Base::_setupKey() * @access private */ - protected function setupKey() + function _setupKey() { $key = $this->key; $keyLength = strlen($key); @@ -257,12 +289,12 @@ class RC4 extends StreamCipher $keyStream[$j] = $temp; } - $this->stream = []; - $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = [ + $this->stream = array(); + $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = array( 0, // index $i 0, // index $j $keyStream - ]; + ); } /** @@ -275,10 +307,11 @@ class RC4 extends StreamCipher * @param int $mode * @return string $text */ - private function crypt($text, $mode) + function _crypt($text, $mode) { if ($this->changed) { - $this->setup(); + $this->_setup(); + $this->changed = false; } $stream = &$this->stream[$mode]; diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php index 9ff33e677..17e2b8329 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -8,43 +8,39 @@ * Here's an example of how to encrypt and decrypt text with this library: * * getPublicKey(); + * $rsa = new \phpseclib\Crypt\RSA(); + * extract($rsa->createKey()); * - * $plaintext = 'terrafrost'; + * $plaintext = 'terrafrost'; * - * $ciphertext = $public->encrypt($plaintext); + * $rsa->loadKey($privatekey); + * $ciphertext = $rsa->encrypt($plaintext); * - * echo $private->decrypt($ciphertext); + * $rsa->loadKey($publickey); + * echo $rsa->decrypt($ciphertext); * ?> * * * Here's an example of how to create signatures and verify signatures with this library: * * getPublicKey(); + * $rsa = new \phpseclib\Crypt\RSA(); + * extract($rsa->createKey()); * - * $plaintext = 'terrafrost'; + * $plaintext = 'terrafrost'; * - * $signature = $private->sign($plaintext); + * $rsa->loadKey($privatekey); + * $signature = $rsa->sign($plaintext); * - * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * $rsa->loadKey($publickey); + * echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified'; * ?> * * - * One thing to consider when using this: so phpseclib uses PSS mode by default. - * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So - * should phpseclib save to the id-RSASSA-PSS format by default or the - * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better - * because SSH doesn't use PSS and idk how many SSH servers would be able to - * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS - * format is used by default (unless you change it up to use PKCS1 instead) - * * @category Crypt * @package RSA * @author Jim Wigginton @@ -53,15 +49,9 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; +namespace phpseclib\Crypt; -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\RSA\PrivateKey; -use phpseclib3\Crypt\RSA\PublicKey; -use phpseclib3\Math\BigInteger; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Exception\InconsistentSetupException; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib\Math\BigInteger; /** * Pure-PHP PKCS#1 compliant implementation of RSA. @@ -70,38 +60,28 @@ use phpseclib3\Crypt\RSA\Formats\Keys\PSS; * @author Jim Wigginton * @access public */ -abstract class RSA extends AsymmetricKey +class RSA { - /** - * Algorithm Name - * - * @var string - * @access private + /**#@+ + * @access public + * @see self::encrypt() + * @see self::decrypt() */ - const ALGORITHM = 'RSA'; - /** * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} * (OAEP) for encryption / decryption. * - * Uses sha256 by default + * Uses sha1 by default. * * @see self::setHash() * @see self::setMGFHash() - * @access public - * @see self::encrypt() - * @see self::decrypt() */ const ENCRYPTION_OAEP = 1; /** * Use PKCS#1 padding. * - * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards + * Although self::ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards * compatibility with protocols (like SSH-1) written before OAEP's introduction. - * - * @access public - * @see self::encrypt() - * @see self::decrypt() */ const ENCRYPTION_PKCS1 = 2; /** @@ -109,93 +89,282 @@ abstract class RSA extends AsymmetricKey * * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. - * - * @access public - * @see self::encrypt() - * @see self::decrypt() */ - const ENCRYPTION_NONE = 4; + const ENCRYPTION_NONE = 3; + /**#@-*/ + /**#@+ + * @access public + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ /** * Use the Probabilistic Signature Scheme for signing * - * Uses sha256 and 0 as the salt length + * Uses sha1 by default. * * @see self::setSaltLength() * @see self::setMGFHash() - * @see self::setHash() - * @see self::sign() - * @see self::verify() - * @see self::setHash() - * @access public */ - const SIGNATURE_PSS = 16; + const SIGNATURE_PSS = 1; /** - * Use a relaxed version of PKCS#1 padding for signature verification + * Use the PKCS#1 scheme by default. * - * @see self::sign() - * @see self::verify() - * @see self::setHash() - * @access public + * Although self::SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards + * compatibility with protocols (like SSH-2) written before PSS's introduction. + */ + const SIGNATURE_PKCS1 = 2; + /**#@-*/ + + /**#@+ + * @access private + * @see \phpseclib\Crypt\RSA::createKey() + */ + /** + * ASN1 Integer + */ + const ASN1_INTEGER = 2; + /** + * ASN1 Bit String + */ + const ASN1_BITSTRING = 3; + /** + * ASN1 Octet String + */ + const ASN1_OCTETSTRING = 4; + /** + * ASN1 Object Identifier + */ + const ASN1_OBJECT = 6; + /** + * ASN1 Sequence (with the constucted bit set) + */ + const ASN1_SEQUENCE = 48; + /**#@-*/ + + /**#@+ + * @access private + * @see \phpseclib\Crypt\RSA::__construct() + */ + /** + * To use the pure-PHP implementation */ - const SIGNATURE_RELAXED_PKCS1 = 32; + const MODE_INTERNAL = 1; /** - * Use PKCS#1 padding for signature verification + * To use the OpenSSL library * - * @see self::sign() - * @see self::verify() - * @see self::setHash() + * (if enabled; otherwise, the internal implementation will be used) + */ + const MODE_OPENSSL = 2; + /**#@-*/ + + /**#@+ + * @access public + * @see \phpseclib\Crypt\RSA::createKey() + * @see \phpseclib\Crypt\RSA::setPrivateKeyFormat() + */ + /** + * PKCS#1 formatted private key + * + * Used by OpenSSH + */ + const PRIVATE_FORMAT_PKCS1 = 0; + /** + * PuTTY formatted private key + */ + const PRIVATE_FORMAT_PUTTY = 1; + /** + * XML formatted private key + */ + const PRIVATE_FORMAT_XML = 2; + /** + * PKCS#8 formatted private key + */ + const PRIVATE_FORMAT_PKCS8 = 8; + /** + * OpenSSH formatted private key + */ + const PRIVATE_FORMAT_OPENSSH = 9; + /**#@-*/ + + /**#@+ * @access public + * @see \phpseclib\Crypt\RSA::createKey() + * @see \phpseclib\Crypt\RSA::setPublicKeyFormat() + */ + /** + * Raw public key + * + * An array containing two \phpseclib\Math\BigInteger objects. + * + * The exponent can be indexed with any of the following: + * + * 0, e, exponent, publicExponent + * + * The modulus can be indexed with any of the following: + * + * 1, n, modulo, modulus + */ + const PUBLIC_FORMAT_RAW = 3; + /** + * PKCS#1 formatted public key (raw) + * + * Used by File/X509.php + * + * Has the following header: + * + * -----BEGIN RSA PUBLIC KEY----- + * + * Analogous to ssh-keygen's pem format (as specified by -m) + */ + const PUBLIC_FORMAT_PKCS1 = 4; + const PUBLIC_FORMAT_PKCS1_RAW = 4; + /** + * XML formatted public key + */ + const PUBLIC_FORMAT_XML = 5; + /** + * OpenSSH formatted public key + * + * Place in $HOME/.ssh/authorized_keys + */ + const PUBLIC_FORMAT_OPENSSH = 6; + /** + * PKCS#1 formatted public key (encapsulated) + * + * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set) + * + * Has the following header: + * + * -----BEGIN PUBLIC KEY----- + * + * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8 + * is specific to private keys it's basically creating a DER-encoded wrapper + * for keys. This just extends that same concept to public keys (much like ssh-keygen) */ - const SIGNATURE_PKCS1 = 64; + const PUBLIC_FORMAT_PKCS8 = 7; + /**#@-*/ /** - * Encryption padding mode + * Precomputed Zero * - * @var int + * @var \phpseclib\Math\BigInteger * @access private */ - protected $encryptionPadding = self::ENCRYPTION_OAEP; + var $zero; /** - * Signature padding mode + * Precomputed One * - * @var int + * @var \phpseclib\Math\BigInteger * @access private */ - protected $signaturePadding = self::SIGNATURE_PSS; + var $one; /** - * Length of hash function output + * Private Key Format * * @var int * @access private */ - protected $hLen; + var $privateKeyFormat = self::PRIVATE_FORMAT_PKCS1; /** - * Length of salt + * Public Key Format * * @var int + * @access public + */ + var $publicKeyFormat = self::PUBLIC_FORMAT_PKCS8; + + /** + * Modulus (ie. n) + * + * @var \phpseclib\Math\BigInteger + * @access private + */ + var $modulus; + + /** + * Modulus length + * + * @var \phpseclib\Math\BigInteger + * @access private + */ + var $k; + + /** + * Exponent (ie. e or d) + * + * @var \phpseclib\Math\BigInteger * @access private */ - protected $sLen; + var $exponent; /** - * Label + * Primes for Chinese Remainder Theorem (ie. p and q) + * + * @var array + * @access private + */ + var $primes; + + /** + * Exponents for Chinese Remainder Theorem (ie. dP and dQ) + * + * @var array + * @access private + */ + var $exponents; + + /** + * Coefficients for Chinese Remainder Theorem (ie. qInv) + * + * @var array + * @access private + */ + var $coefficients; + + /** + * Hash name * * @var string * @access private */ - protected $label = ''; + var $hashName; + + /** + * Hash function + * + * @var \phpseclib\Crypt\Hash + * @access private + */ + var $hash; + + /** + * Length of hash function output + * + * @var int + * @access private + */ + var $hLen; + + /** + * Length of salt + * + * @var int + * @access private + */ + var $sLen; /** * Hash function for the Mask Generation Function * - * @var \phpseclib3\Crypt\Hash + * @var \phpseclib\Crypt\Hash * @access private */ - protected $mgfHash; + var $mgfHash; /** * Length of MGF hash function output @@ -203,136 +372,295 @@ abstract class RSA extends AsymmetricKey * @var int * @access private */ - protected $mgfHLen; + var $mgfHLen; /** - * Modulus (ie. n) + * Encryption mode * - * @var \phpseclib3\Math\BigInteger + * @var int * @access private */ - protected $modulus; + var $encryptionMode = self::ENCRYPTION_OAEP; /** - * Modulus length + * Signature mode * - * @var \phpseclib3\Math\BigInteger + * @var int * @access private */ - protected $k; + var $signatureMode = self::SIGNATURE_PSS; /** - * Exponent (ie. e or d) + * Public Exponent * - * @var \phpseclib3\Math\BigInteger + * @var mixed * @access private */ - protected $exponent; + var $publicExponent = false; /** - * Default public exponent + * Password * - * @var int - * @link http://en.wikipedia.org/wiki/65537_%28number%29 + * @var string * @access private */ - private static $defaultExponent = 65537; + var $password = false; /** - * Enable Blinding? + * Components + * + * For use with parsing XML formatted keys. PHP's XML Parser functions use utilized - instead of PHP's DOM functions - + * because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't. * - * @var bool + * @see self::_start_element_handler() + * @var array * @access private */ - protected static $enableBlinding = true; + var $components = array(); /** - * Smallest Prime + * Current String * - * Per , this number ought not result in primes smaller - * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime - * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if - * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is - * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's - * a chance neither gmp nor OpenSSL are installed) + * For use with parsing XML formatted keys. * - * @var int + * @see self::_character_handler() + * @see self::_stop_element_handler() + * @var mixed * @access private */ - private static $smallestPrime = 4096; + var $current; /** - * Sets the public exponent for key generation + * OpenSSL configuration file name. * - * This will be 65537 unless changed. + * Set to null to use system configuration file. + * @see self::createKey() + * @var mixed + * @Access public + */ + var $configFile; + + /** + * Public key comment field. * - * @access public - * @param int $val + * @var string + * @access private */ - public static function setExponent($val) - { - self::$defaultExponent = $val; - } + var $comment = 'phpseclib-generated-key'; /** - * Sets the smallest prime number in bits. Used for key generation + * The constructor * - * This will be 4096 unless changed. + * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason + * \phpseclib\Crypt\RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires + * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late. * + * @return \phpseclib\Crypt\RSA * @access public - * @param int $val */ - public static function setSmallestPrime($val) + function __construct() { - self::$smallestPrime = $val; + $this->configFile = dirname(__FILE__) . '/../openssl.cnf'; + + if (!defined('CRYPT_RSA_MODE')) { + switch (true) { + // Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular, + // Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger + // can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either. + case defined('MATH_BIGINTEGER_OPENSSL_DISABLE'): + define('CRYPT_RSA_MODE', self::MODE_INTERNAL); + break; + case extension_loaded('openssl') && file_exists($this->configFile): + // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work + $versions = array(); + + // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems) + if (strpos(ini_get('disable_functions'), 'phpinfo') === false) { + ob_start(); + @phpinfo(); + $content = ob_get_contents(); + ob_end_clean(); + + preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches); + + if (!empty($matches[1])) { + for ($i = 0; $i < count($matches[1]); $i++) { + $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i]))); + + // Remove letter part in OpenSSL version + if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) { + $versions[$matches[1][$i]] = $fullVersion; + } else { + $versions[$matches[1][$i]] = $m[0]; + } + } + } + } + + // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+ + switch (true) { + case !isset($versions['Header']): + case !isset($versions['Library']): + case $versions['Header'] == $versions['Library']: + case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0: + define('CRYPT_RSA_MODE', self::MODE_OPENSSL); + break; + default: + define('CRYPT_RSA_MODE', self::MODE_INTERNAL); + define('MATH_BIGINTEGER_OPENSSL_DISABLE', true); + } + break; + default: + define('CRYPT_RSA_MODE', self::MODE_INTERNAL); + } + } + + $this->zero = new BigInteger(); + $this->one = new BigInteger(1); + + $this->hash = new Hash('sha1'); + $this->hLen = $this->hash->getLength(); + $this->hashName = 'sha1'; + $this->mgfHash = new Hash('sha1'); + $this->mgfHLen = $this->mgfHash->getLength(); } /** - * Create a private key + * Create public / private key pair * - * The public key can be extracted from the private key + * Returns an array with the following three elements: + * - 'privatekey': The private key. + * - 'publickey': The public key. + * - 'partialkey': A partially computed key (if the execution time exceeded $timeout). + * Will need to be passed back to \phpseclib\Crypt\RSA::createKey() as the third parameter for further processing. * - * @return RSA * @access public * @param int $bits + * @param int $timeout + * @param array $partial */ - public static function createKey($bits = 2048) + function createKey($bits = 1024, $timeout = false, $partial = array()) { - self::initialize_static_variables(); + if (!defined('CRYPT_RSA_EXPONENT')) { + // http://en.wikipedia.org/wiki/65537_%28number%29 + define('CRYPT_RSA_EXPONENT', '65537'); + } + // per , this number ought not result in primes smaller + // than 256 bits. as a consequence if the key you're trying to create is 1024 bits and you've set CRYPT_RSA_SMALLEST_PRIME + // to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). at least if + // CRYPT_RSA_MODE is set to self::MODE_INTERNAL. if CRYPT_RSA_MODE is set to self::MODE_OPENSSL then + // CRYPT_RSA_SMALLEST_PRIME is ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key + // generation when there's a chance neither gmp nor OpenSSL are installed) + if (!defined('CRYPT_RSA_SMALLEST_PRIME')) { + define('CRYPT_RSA_SMALLEST_PRIME', 4096); + } + + // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum + if (CRYPT_RSA_MODE == self::MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) { + $config = array(); + if (isset($this->configFile)) { + $config['config'] = $this->configFile; + } + $rsa = openssl_pkey_new(array('private_key_bits' => $bits) + $config); + openssl_pkey_export($rsa, $privatekey, null, $config); + $publickey = openssl_pkey_get_details($rsa); + $publickey = $publickey['key']; + + $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, self::PRIVATE_FORMAT_PKCS1))); + $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1))); + + // clear the buffer of error strings stemming from a minimalistic openssl.cnf + while (openssl_error_string() !== false) { + } + + return array( + 'privatekey' => $privatekey, + 'publickey' => $publickey, + 'partialkey' => false + ); + } static $e; if (!isset($e)) { - $e = new BigInteger(self::$defaultExponent); + $e = new BigInteger(CRYPT_RSA_EXPONENT); } - $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be - if ($regSize > self::$smallestPrime) { - $num_primes = floor($bits / self::$smallestPrime); - $regSize = self::$smallestPrime; + extract($this->_generateMinMax($bits)); + $absoluteMin = $min; + $temp = $bits >> 1; // divide by two to see how many bits P and Q would be + if ($temp > CRYPT_RSA_SMALLEST_PRIME) { + $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME); + $temp = CRYPT_RSA_SMALLEST_PRIME; } else { $num_primes = 2; } + extract($this->_generateMinMax($temp + $bits % $temp)); + $finalMax = $max; + extract($this->_generateMinMax($temp)); - $n = clone self::$one; - $exponents = $coefficients = $primes = []; - $lcm = [ - 'top' => clone self::$one, - 'bottom' => false - ]; + $generator = new BigInteger(); + + $n = $this->one->copy(); + if (!empty($partial)) { + extract(unserialize($partial)); + } else { + $exponents = $coefficients = $primes = array(); + $lcm = array( + 'top' => $this->one->copy(), + 'bottom' => false + ); + } + + $start = time(); + $i0 = count($primes) + 1; do { - for ($i = 1; $i <= $num_primes; $i++) { - if ($i != $num_primes) { - $primes[$i] = BigInteger::randomPrime($regSize); + for ($i = $i0; $i <= $num_primes; $i++) { + if ($timeout !== false) { + $timeout-= time() - $start; + $start = time(); + if ($timeout <= 0) { + return array( + 'privatekey' => '', + 'publickey' => '', + 'partialkey' => serialize(array( + 'primes' => $primes, + 'coefficients' => $coefficients, + 'lcm' => $lcm, + 'exponents' => $exponents + )) + ); + } + } + + if ($i == $num_primes) { + list($min, $temp) = $absoluteMin->divide($n); + if (!$temp->equals($this->zero)) { + $min = $min->add($this->one); // ie. ceil() + } + $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout); } else { - extract(BigInteger::minMaxBits($bits)); - /** @var BigInteger $min - * @var BigInteger $max - */ - list($min) = $min->divide($n); - $min = $min->add(self::$one); - list($max) = $max->divide($n); - $primes[$i] = BigInteger::randomRangePrime($min, $max); + $primes[$i] = $generator->randomPrime($min, $max, $timeout); + } + + if ($primes[$i] === false) { // if we've reached the timeout + if (count($primes) > 1) { + $partialkey = ''; + } else { + array_pop($primes); + $partialkey = serialize(array( + 'primes' => $primes, + 'coefficients' => $coefficients, + 'lcm' => $lcm, + 'exponents' => $exponents + )); + } + + return array( + 'privatekey' => '', + 'publickey' => '', + 'partialkey' => $partialkey + ); } // the first coefficient is calculated differently from the rest @@ -343,27 +671,24 @@ abstract class RSA extends AsymmetricKey $n = $n->multiply($primes[$i]); - $temp = $primes[$i]->subtract(self::$one); + $temp = $primes[$i]->subtract($this->one); // textbook RSA implementations use Euler's totient function instead of the least common multiple. // see http://en.wikipedia.org/wiki/Euler%27s_totient_function $lcm['top'] = $lcm['top']->multiply($temp); $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp); + + $exponents[$i] = $e->modInverse($temp); } list($temp) = $lcm['top']->divide($lcm['bottom']); $gcd = $temp->gcd($e); $i0 = 1; - } while (!$gcd->equals(self::$one)); - - $coefficients[2] = $primes[2]->modInverse($primes[1]); + } while (!$gcd->equals($this->one)); $d = $e->modInverse($temp); - foreach ($primes as $i => $prime) { - $temp = $prime->subtract(self::$one); - $exponents[$i] = $e->modInverse($temp); - } + $coefficients[2] = $primes[2]->modInverse($primes[1]); // from : // RSAPrivateKey ::= SEQUENCE { @@ -378,460 +703,2505 @@ abstract class RSA extends AsymmetricKey // coefficient INTEGER, -- (inverse of q) mod p // otherPrimeInfos OtherPrimeInfos OPTIONAL // } - $privatekey = new PrivateKey; - $privatekey->modulus = $n; - $privatekey->k = $bits >> 3; - $privatekey->publicExponent = $e; - $privatekey->exponent = $d; - $privatekey->privateExponent = $e; - $privatekey->primes = $primes; - $privatekey->exponents = $exponents; - $privatekey->coefficients = $coefficients; - - /* - $publickey = new PublicKey; - $publickey->modulus = $n; - $publickey->k = $bits >> 3; - $publickey->exponent = $e; - $publickey->publicExponent = $e; - $publickey->isPublic = true; - */ - return $privatekey; + return array( + 'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients), + 'publickey' => $this->_convertPublicKey($n, $e), + 'partialkey' => false + ); } /** - * OnLoad Handler + * Convert a private key to the appropriate format. * - * @return bool - * @access protected - * @param array $components + * @access private + * @see self::setPrivateKeyFormat() + * @param Math_BigInteger $n + * @param Math_BigInteger $e + * @param Math_BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @return string */ - protected static function onLoad($components) + function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients) { - $key = $components['isPublicKey'] ? - new PublicKey : - new PrivateKey; + $signed = $this->privateKeyFormat != self::PRIVATE_FORMAT_XML; + $num_primes = count($primes); + $raw = array( + 'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi + 'modulus' => $n->toBytes($signed), + 'publicExponent' => $e->toBytes($signed), + 'privateExponent' => $d->toBytes($signed), + 'prime1' => $primes[1]->toBytes($signed), + 'prime2' => $primes[2]->toBytes($signed), + 'exponent1' => $exponents[1]->toBytes($signed), + 'exponent2' => $exponents[2]->toBytes($signed), + 'coefficient' => $coefficients[2]->toBytes($signed) + ); + + // if the format in question does not support multi-prime rsa and multi-prime rsa was used, + // call _convertPublicKey() instead. + switch ($this->privateKeyFormat) { + case self::PRIVATE_FORMAT_XML: + if ($num_primes != 2) { + return false; + } + return "\r\n" . + ' ' . base64_encode($raw['modulus']) . "\r\n" . + ' ' . base64_encode($raw['publicExponent']) . "\r\n" . + '

      ' . base64_encode($raw['prime1']) . "

      \r\n" . + ' ' . base64_encode($raw['prime2']) . "\r\n" . + ' ' . base64_encode($raw['exponent1']) . "\r\n" . + ' ' . base64_encode($raw['exponent2']) . "\r\n" . + ' ' . base64_encode($raw['coefficient']) . "\r\n" . + ' ' . base64_encode($raw['privateExponent']) . "\r\n" . + '
      '; + break; + case self::PRIVATE_FORMAT_PUTTY: + if ($num_primes != 2) { + return false; + } + $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: "; + $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none'; + $key.= $encryption; + $key.= "\r\nComment: " . $this->comment . "\r\n"; + $public = pack( + 'Na*Na*Na*', + strlen('ssh-rsa'), + 'ssh-rsa', + strlen($raw['publicExponent']), + $raw['publicExponent'], + strlen($raw['modulus']), + $raw['modulus'] + ); + $source = pack( + 'Na*Na*Na*Na*', + strlen('ssh-rsa'), + 'ssh-rsa', + strlen($encryption), + $encryption, + strlen($this->comment), + $this->comment, + strlen($public), + $public + ); + $public = base64_encode($public); + $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; + $key.= chunk_split($public, 64); + $private = pack( + 'Na*Na*Na*Na*', + strlen($raw['privateExponent']), + $raw['privateExponent'], + strlen($raw['prime1']), + $raw['prime1'], + strlen($raw['prime2']), + $raw['prime2'], + strlen($raw['coefficient']), + $raw['coefficient'] + ); + if (empty($this->password) && !is_string($this->password)) { + $source.= pack('Na*', strlen($private), $private); + $hashkey = 'putty-private-key-file-mac-key'; + } else { + $private.= Random::string(16 - (strlen($private) & 15)); + $source.= pack('Na*', strlen($private), $private); + $sequence = 0; + $symkey = ''; + while (strlen($symkey) < 32) { + $temp = pack('Na*', $sequence++, $this->password); + $symkey.= pack('H*', sha1($temp)); + } + $symkey = substr($symkey, 0, 32); + $crypto = new AES(); + + $crypto->setKey($symkey); + $crypto->disablePadding(); + $private = $crypto->encrypt($private); + $hashkey = 'putty-private-key-file-mac-key' . $this->password; + } - $key->modulus = $components['modulus']; - $key->publicExponent = $components['publicExponent']; - $key->k = $key->modulus->getLengthInBytes(); + $private = base64_encode($private); + $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; + $key.= chunk_split($private, 64); + $hash = new Hash('sha1'); + $hash->setKey(pack('H*', sha1($hashkey))); + $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n"; + + return $key; + case self::PRIVATE_FORMAT_OPENSSH: + if ($num_primes != 2) { + return false; + } + $publicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']); + $privateKey = pack( + 'Na*Na*Na*Na*Na*Na*Na*', + strlen('ssh-rsa'), + 'ssh-rsa', + strlen($raw['modulus']), + $raw['modulus'], + strlen($raw['publicExponent']), + $raw['publicExponent'], + strlen($raw['privateExponent']), + $raw['privateExponent'], + strlen($raw['coefficient']), + $raw['coefficient'], + strlen($raw['prime1']), + $raw['prime1'], + strlen($raw['prime2']), + $raw['prime2'] + ); + $checkint = Random::string(4); + $paddedKey = pack( + 'a*Na*', + $checkint . $checkint . $privateKey, + strlen($this->comment), + $this->comment + ); + $paddingLength = (7 * strlen($paddedKey)) % 8; + for ($i = 1; $i <= $paddingLength; $i++) { + $paddedKey.= chr($i); + } + $key = pack( + 'Na*Na*Na*NNa*Na*', + strlen('none'), + 'none', + strlen('none'), + 'none', + 0, + '', + 1, + strlen($publicKey), + $publicKey, + strlen($paddedKey), + $paddedKey + ); + $key = "openssh-key-v1\0$key"; + + return "-----BEGIN OPENSSH PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($key), 70) . + "-----END OPENSSH PRIVATE KEY-----"; + default: // eg. self::PRIVATE_FORMAT_PKCS1 + $components = array(); + foreach ($raw as $name => $value) { + $components[$name] = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value); + } - if ($components['isPublicKey'] || !isset($components['privateExponent'])) { - $key->exponent = $key->publicExponent; - } else { - $key->privateExponent = $components['privateExponent']; - $key->exponent = $key->privateExponent; - $key->primes = $components['primes']; - $key->exponents = $components['exponents']; - $key->coefficients = $components['coefficients']; - } - - if ($components['format'] == PSS::class) { - // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is - // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib - // uses PSS padding by default. it assumes the more secure method by default and altho it provides - // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent - // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that - // not only does it defaults to the most secure methods - it doesn't even let you choose less - // secure methods - //$key = $key->withPadding(self::SIGNATURE_PSS); - if (isset($components['hash'])) { - $key = $key->withHash($components['hash']); - } - if (isset($components['MGFHash'])) { - $key = $key->withMGFHash($components['MGFHash']); - } - if (isset($components['saltLength'])) { - $key = $key->withSaltLength($components['saltLength']); - } - } + $RSAPrivateKey = implode('', $components); + + if ($num_primes > 2) { + $OtherPrimeInfos = ''; + for ($i = 3; $i <= $num_primes; $i++) { + // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo + // + // OtherPrimeInfo ::= SEQUENCE { + // prime INTEGER, -- ri + // exponent INTEGER, -- di + // coefficient INTEGER -- ti + // } + $OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true)); + $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true)); + $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true)); + $OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo); + } + $RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos); + } - return $key; - } + $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + + if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) { + $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $RSAPrivateKey = pack( + 'Ca*a*Ca*a*', + self::ASN1_INTEGER, + "\01\00", + $rsaOID, + 4, + $this->_encodeLength(strlen($RSAPrivateKey)), + $RSAPrivateKey + ); + $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + if (!empty($this->password) || is_string($this->password)) { + $salt = Random::string(8); + $iterationCount = 2048; + + $crypto = new DES(); + $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount); + $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey); + + $parameters = pack( + 'Ca*a*Ca*N', + self::ASN1_OCTETSTRING, + $this->_encodeLength(strlen($salt)), + $salt, + self::ASN1_INTEGER, + $this->_encodeLength(4), + $iterationCount + ); + $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03"; + + $encryptionAlgorithm = pack( + 'Ca*a*Ca*a*', + self::ASN1_OBJECT, + $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), + $pbeWithMD5AndDES_CBC, + self::ASN1_SEQUENCE, + $this->_encodeLength(strlen($parameters)), + $parameters + ); + + $RSAPrivateKey = pack( + 'Ca*a*Ca*a*', + self::ASN1_SEQUENCE, + $this->_encodeLength(strlen($encryptionAlgorithm)), + $encryptionAlgorithm, + self::ASN1_OCTETSTRING, + $this->_encodeLength(strlen($RSAPrivateKey)), + $RSAPrivateKey + ); + + $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + + $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($RSAPrivateKey), 64) . + '-----END ENCRYPTED PRIVATE KEY-----'; + } else { + $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($RSAPrivateKey), 64) . + '-----END PRIVATE KEY-----'; + } + return $RSAPrivateKey; + } - /** - * Constructor - * - * PublicKey and PrivateKey objects can only be created from abstract RSA class - */ - protected function __construct() - { - parent::__construct(); + if (!empty($this->password) || is_string($this->password)) { + $iv = Random::string(8); + $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key + $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8); + $des = new TripleDES(); + $des->setKey($symkey); + $des->setIV($iv); + $iv = strtoupper(bin2hex($iv)); + $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . + "Proc-Type: 4,ENCRYPTED\r\n" . + "DEK-Info: DES-EDE3-CBC,$iv\r\n" . + "\r\n" . + chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) . + '-----END RSA PRIVATE KEY-----'; + } else { + $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($RSAPrivateKey), 64) . + '-----END RSA PRIVATE KEY-----'; + } - $this->hLen = $this->hash->getLengthInBytes(); - $this->mgfHash = new Hash('sha256'); - $this->mgfHLen = $this->mgfHash->getLengthInBytes(); + return $RSAPrivateKey; + } } /** - * Integer-to-Octet-String primitive - * - * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. + * Convert a public key to the appropriate format * * @access private - * @param bool|\phpseclib3\Math\BigInteger $x - * @param int $xLen - * @return bool|string + * @see self::setPublicKeyFormat() + * @param Math_BigInteger $n + * @param Math_BigInteger $e + * @return string|array */ - protected function i2osp($x, $xLen) + function _convertPublicKey($n, $e) { - if ($x === false) { - return false; - } - $x = $x->toBytes(); - if (strlen($x) > $xLen) { - throw new \OutOfRangeException('Resultant string length out of range'); + $signed = $this->publicKeyFormat != self::PUBLIC_FORMAT_XML; + + $modulus = $n->toBytes($signed); + $publicExponent = $e->toBytes($signed); + + switch ($this->publicKeyFormat) { + case self::PUBLIC_FORMAT_RAW: + return array('e' => $e->copy(), 'n' => $n->copy()); + case self::PUBLIC_FORMAT_XML: + return "\r\n" . + ' ' . base64_encode($modulus) . "\r\n" . + ' ' . base64_encode($publicExponent) . "\r\n" . + ''; + break; + case self::PUBLIC_FORMAT_OPENSSH: + // from : + // string "ssh-rsa" + // mpint e + // mpint n + $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus); + $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment; + + return $RSAPublicKey; + default: // eg. self::PUBLIC_FORMAT_PKCS1_RAW or self::PUBLIC_FORMAT_PKCS1 + // from : + // RSAPublicKey ::= SEQUENCE { + // modulus INTEGER, -- n + // publicExponent INTEGER -- e + // } + $components = array( + 'modulus' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus), + 'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent) + ); + + $RSAPublicKey = pack( + 'Ca*a*a*', + self::ASN1_SEQUENCE, + $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])), + $components['modulus'], + $components['publicExponent'] + ); + + if ($this->publicKeyFormat == self::PUBLIC_FORMAT_PKCS1_RAW) { + $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($RSAPublicKey), 64) . + '-----END RSA PUBLIC KEY-----'; + } else { + // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption. + $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $RSAPublicKey = chr(0) . $RSAPublicKey; + $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey; + + $RSAPublicKey = pack( + 'Ca*a*', + self::ASN1_SEQUENCE, + $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), + $rsaOID . $RSAPublicKey + ); + + $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($RSAPublicKey), 64) . + '-----END PUBLIC KEY-----'; + } + + return $RSAPublicKey; } - return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); } /** - * Octet-String-to-Integer primitive - * - * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. + * Break a public or private key down into its constituant components * * @access private - * @param string $x - * @return \phpseclib3\Math\BigInteger + * @see self::_convertPublicKey() + * @see self::_convertPrivateKey() + * @param string|array $key + * @param int $type + * @return array|bool */ - protected function os2ip($x) + function _parseKey($key, $type) { - return new BigInteger($x, 256); - } + if ($type != self::PUBLIC_FORMAT_RAW && !is_string($key)) { + return false; + } - /** - * EMSA-PKCS1-V1_5-ENCODE - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. - * - * @access private - * @param string $m - * @param int $emLen - * @throws \LengthException if the intended encoded message length is too short + switch ($type) { + case self::PUBLIC_FORMAT_RAW: + if (!is_array($key)) { + return false; + } + $components = array(); + switch (true) { + case isset($key['e']): + $components['publicExponent'] = $key['e']->copy(); + break; + case isset($key['exponent']): + $components['publicExponent'] = $key['exponent']->copy(); + break; + case isset($key['publicExponent']): + $components['publicExponent'] = $key['publicExponent']->copy(); + break; + case isset($key[0]): + $components['publicExponent'] = $key[0]->copy(); + } + switch (true) { + case isset($key['n']): + $components['modulus'] = $key['n']->copy(); + break; + case isset($key['modulo']): + $components['modulus'] = $key['modulo']->copy(); + break; + case isset($key['modulus']): + $components['modulus'] = $key['modulus']->copy(); + break; + case isset($key[1]): + $components['modulus'] = $key[1]->copy(); + } + return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false; + case self::PRIVATE_FORMAT_PKCS1: + case self::PRIVATE_FORMAT_PKCS8: + case self::PUBLIC_FORMAT_PKCS1: + /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is + "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to + protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding + two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: + + http://tools.ietf.org/html/rfc1421#section-4.6.1.1 + http://tools.ietf.org/html/rfc1421#section-4.6.1.3 + + DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. + DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation + function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's + own implementation. ie. the implementation *is* the standard and any bugs that may exist in that + implementation are part of the standard, as well. + + * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ + if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { + $iv = pack('H*', trim($matches[2])); + $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key + $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8))); + // remove the Proc-Type / DEK-Info sections as they're no longer needed + $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); + $ciphertext = $this->_extractBER($key); + if ($ciphertext === false) { + $ciphertext = $key; + } + switch ($matches[1]) { + case 'AES-256-CBC': + $crypto = new AES(); + break; + case 'AES-128-CBC': + $symkey = substr($symkey, 0, 16); + $crypto = new AES(); + break; + case 'DES-EDE3-CFB': + $crypto = new TripleDES(Base::MODE_CFB); + break; + case 'DES-EDE3-CBC': + $symkey = substr($symkey, 0, 24); + $crypto = new TripleDES(); + break; + case 'DES-CBC': + $crypto = new DES(); + break; + default: + return false; + } + $crypto->setKey($symkey); + $crypto->setIV($iv); + $decoded = $crypto->decrypt($ciphertext); + } else { + $decoded = $this->_extractBER($key); + } + + if ($decoded !== false) { + $key = $decoded; + } + + $components = array(); + + if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { + return false; + } + if ($this->_decodeLength($key) != strlen($key)) { + return false; + } + + $tag = ord($this->_string_shift($key)); + /* intended for keys for which OpenSSL's asn1parse returns the following: + + 0:d=0 hl=4 l= 631 cons: SEQUENCE + 4:d=1 hl=2 l= 1 prim: INTEGER :00 + 7:d=1 hl=2 l= 13 cons: SEQUENCE + 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption + 20:d=2 hl=2 l= 0 prim: NULL + 22:d=1 hl=4 l= 609 prim: OCTET STRING + + ie. PKCS8 keys*/ + + if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") { + $this->_string_shift($key, 3); + $tag = self::ASN1_SEQUENCE; + } + + if ($tag == self::ASN1_SEQUENCE) { + $temp = $this->_string_shift($key, $this->_decodeLength($key)); + if (ord($this->_string_shift($temp)) != self::ASN1_OBJECT) { + return false; + } + $length = $this->_decodeLength($temp); + switch ($this->_string_shift($temp, $length)) { + case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption + break; + case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC + /* + PBEParameter ::= SEQUENCE { + salt OCTET STRING (SIZE(8)), + iterationCount INTEGER } + */ + if (ord($this->_string_shift($temp)) != self::ASN1_SEQUENCE) { + return false; + } + if ($this->_decodeLength($temp) != strlen($temp)) { + return false; + } + $this->_string_shift($temp); // assume it's an octet string + $salt = $this->_string_shift($temp, $this->_decodeLength($temp)); + if (ord($this->_string_shift($temp)) != self::ASN1_INTEGER) { + return false; + } + $this->_decodeLength($temp); + list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT)); + $this->_string_shift($key); // assume it's an octet string + $length = $this->_decodeLength($key); + if (strlen($key) != $length) { + return false; + } + + $crypto = new DES(); + $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount); + $key = $crypto->decrypt($key); + if ($key === false) { + return false; + } + return $this->_parseKey($key, self::PRIVATE_FORMAT_PKCS1); + default: + return false; + } + /* intended for keys for which OpenSSL's asn1parse returns the following: + + 0:d=0 hl=4 l= 290 cons: SEQUENCE + 4:d=1 hl=2 l= 13 cons: SEQUENCE + 6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption + 17:d=2 hl=2 l= 0 prim: NULL + 19:d=1 hl=4 l= 271 prim: BIT STRING */ + $tag = ord($this->_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag + $this->_decodeLength($key); // skip over the BIT STRING / OCTET STRING length + // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of + // unused bits in the final subsequent octet. The number shall be in the range zero to seven." + // -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2) + if ($tag == self::ASN1_BITSTRING) { + $this->_string_shift($key); + } + if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { + return false; + } + if ($this->_decodeLength($key) != strlen($key)) { + return false; + } + $tag = ord($this->_string_shift($key)); + } + if ($tag != self::ASN1_INTEGER) { + return false; + } + + $length = $this->_decodeLength($key); + $temp = $this->_string_shift($key, $length); + if (strlen($temp) != 1 || ord($temp) > 2) { + $components['modulus'] = new BigInteger($temp, 256); + $this->_string_shift($key); // skip over self::ASN1_INTEGER + $length = $this->_decodeLength($key); + $components[$type == self::PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256); + + return $components; + } + if (ord($this->_string_shift($key)) != self::ASN1_INTEGER) { + return false; + } + $length = $this->_decodeLength($key); + $components['modulus'] = new BigInteger($this->_string_shift($key, $length), 256); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['publicExponent'] = new BigInteger($this->_string_shift($key, $length), 256); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['primes'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256)); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['exponents'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256)); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($key, $length), 256)); + + if (!empty($key)) { + if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { + return false; + } + $this->_decodeLength($key); + while (!empty($key)) { + if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { + return false; + } + $this->_decodeLength($key); + $key = substr($key, 1); + $length = $this->_decodeLength($key); + $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256); + $this->_string_shift($key); + $length = $this->_decodeLength($key); + $components['coefficients'][] = new BigInteger($this->_string_shift($key, $length), 256); + } + } + + return $components; + case self::PUBLIC_FORMAT_OPENSSH: + $parts = explode(' ', $key, 3); + + $key = isset($parts[1]) ? base64_decode($parts[1]) : false; + if ($key === false) { + return false; + } + + $comment = isset($parts[2]) ? $parts[2] : false; + + $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa"; + + if (strlen($key) <= 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($key, 4))); + $publicExponent = new BigInteger($this->_string_shift($key, $length), -256); + if (strlen($key) <= 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($key, 4))); + $modulus = new BigInteger($this->_string_shift($key, $length), -256); + + if ($cleanup && strlen($key)) { + if (strlen($key) <= 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($key, 4))); + $realModulus = new BigInteger($this->_string_shift($key, $length), -256); + return strlen($key) ? false : array( + 'modulus' => $realModulus, + 'publicExponent' => $modulus, + 'comment' => $comment + ); + } else { + return strlen($key) ? false : array( + 'modulus' => $modulus, + 'publicExponent' => $publicExponent, + 'comment' => $comment + ); + } + // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue + // http://en.wikipedia.org/wiki/XML_Signature + case self::PRIVATE_FORMAT_XML: + case self::PUBLIC_FORMAT_XML: + $this->components = array(); + + $xml = xml_parser_create('UTF-8'); + xml_set_object($xml, $this); + xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler'); + xml_set_character_data_handler($xml, '_data_handler'); + // add to account for "dangling" tags like ... that are sometimes added + if (!xml_parse($xml, '' . $key . '')) { + xml_parser_free($xml); + unset($xml); + return false; + } + + xml_parser_free($xml); + unset($xml); + + return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false; + // from PuTTY's SSHPUBK.C + case self::PRIVATE_FORMAT_PUTTY: + $components = array(); + $key = preg_split('#\r\n|\r|\n#', $key); + $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0])); + if ($type != 'ssh-rsa') { + return false; + } + $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); + $comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); + + $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); + $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); + $public = substr($public, 11); + extract(unpack('Nlength', $this->_string_shift($public, 4))); + $components['publicExponent'] = new BigInteger($this->_string_shift($public, $length), -256); + extract(unpack('Nlength', $this->_string_shift($public, 4))); + $components['modulus'] = new BigInteger($this->_string_shift($public, $length), -256); + + $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4])); + $private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength)))); + + switch ($encryption) { + case 'aes256-cbc': + $symkey = ''; + $sequence = 0; + while (strlen($symkey) < 32) { + $temp = pack('Na*', $sequence++, $this->password); + $symkey.= pack('H*', sha1($temp)); + } + $symkey = substr($symkey, 0, 32); + $crypto = new AES(); + } + + if ($encryption != 'none') { + $crypto->setKey($symkey); + $crypto->disablePadding(); + $private = $crypto->decrypt($private); + if ($private === false) { + return false; + } + } + + extract(unpack('Nlength', $this->_string_shift($private, 4))); + if (strlen($private) < $length) { + return false; + } + $components['privateExponent'] = new BigInteger($this->_string_shift($private, $length), -256); + extract(unpack('Nlength', $this->_string_shift($private, 4))); + if (strlen($private) < $length) { + return false; + } + $components['primes'] = array(1 => new BigInteger($this->_string_shift($private, $length), -256)); + extract(unpack('Nlength', $this->_string_shift($private, 4))); + if (strlen($private) < $length) { + return false; + } + $components['primes'][] = new BigInteger($this->_string_shift($private, $length), -256); + + $temp = $components['primes'][1]->subtract($this->one); + $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp)); + $temp = $components['primes'][2]->subtract($this->one); + $components['exponents'][] = $components['publicExponent']->modInverse($temp); + + extract(unpack('Nlength', $this->_string_shift($private, 4))); + if (strlen($private) < $length) { + return false; + } + $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($private, $length), -256)); + + return $components; + case self::PRIVATE_FORMAT_OPENSSH: + $components = array(); + $decoded = $this->_extractBER($key); + $magic = $this->_string_shift($decoded, 15); + if ($magic !== "openssh-key-v1\0") { + return false; + } + $options = $this->_string_shift($decoded, 24); + // \0\0\0\4none = ciphername + // \0\0\0\4none = kdfname + // \0\0\0\0 = kdfoptions + // \0\0\0\1 = numkeys + if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") { + return false; + } + extract(unpack('Nlength', $this->_string_shift($decoded, 4))); + if (strlen($decoded) < $length) { + return false; + } + $publicKey = $this->_string_shift($decoded, $length); + extract(unpack('Nlength', $this->_string_shift($decoded, 4))); + if (strlen($decoded) < $length) { + return false; + } + $paddedKey = $this->_string_shift($decoded, $length); + + if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") { + return false; + } + + $checkint1 = $this->_string_shift($paddedKey, 4); + $checkint2 = $this->_string_shift($paddedKey, 4); + if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) { + return false; + } + + if ($this->_string_shift($paddedKey, 11) !== "\0\0\0\7ssh-rsa") { + return false; + } + + $values = array( + &$components['modulus'], + &$components['publicExponent'], + &$components['privateExponent'], + &$components['coefficients'][2], + &$components['primes'][1], + &$components['primes'][2] + ); + + foreach ($values as &$value) { + extract(unpack('Nlength', $this->_string_shift($paddedKey, 4))); + if (strlen($paddedKey) < $length) { + return false; + } + $value = new BigInteger($this->_string_shift($paddedKey, $length), -256); + } + + extract(unpack('Nlength', $this->_string_shift($paddedKey, 4))); + if (strlen($paddedKey) < $length) { + return false; + } + $components['comment'] = $this->_string_shift($decoded, $length); + + $temp = $components['primes'][1]->subtract($this->one); + $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp)); + $temp = $components['primes'][2]->subtract($this->one); + $components['exponents'][] = $components['publicExponent']->modInverse($temp); + + return $components; + } + + return false; + } + + /** + * Returns the key size + * + * More specifically, this returns the size of the modulo in bits. + * + * @access public + * @return int + */ + function getSize() + { + return !isset($this->modulus) ? 0 : strlen($this->modulus->toBits()); + } + + /** + * Start Element Handler + * + * Called by xml_set_element_handler() + * + * @access private + * @param resource $parser + * @param string $name + * @param array $attribs + */ + function _start_element_handler($parser, $name, $attribs) + { + //$name = strtoupper($name); + switch ($name) { + case 'MODULUS': + $this->current = &$this->components['modulus']; + break; + case 'EXPONENT': + $this->current = &$this->components['publicExponent']; + break; + case 'P': + $this->current = &$this->components['primes'][1]; + break; + case 'Q': + $this->current = &$this->components['primes'][2]; + break; + case 'DP': + $this->current = &$this->components['exponents'][1]; + break; + case 'DQ': + $this->current = &$this->components['exponents'][2]; + break; + case 'INVERSEQ': + $this->current = &$this->components['coefficients'][2]; + break; + case 'D': + $this->current = &$this->components['privateExponent']; + } + $this->current = ''; + } + + /** + * Stop Element Handler + * + * Called by xml_set_element_handler() + * + * @access private + * @param resource $parser + * @param string $name + */ + function _stop_element_handler($parser, $name) + { + if (isset($this->current)) { + $this->current = new BigInteger(base64_decode($this->current), 256); + unset($this->current); + } + } + + /** + * Data Handler + * + * Called by xml_set_character_data_handler() + * + * @access private + * @param resource $parser + * @param string $data + */ + function _data_handler($parser, $data) + { + if (!isset($this->current) || is_object($this->current)) { + return; + } + $this->current.= trim($data); + } + + /** + * Loads a public or private key + * + * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed) + * + * @access public + * @param string|RSA|array $key + * @param bool|int $type optional + * @return bool + */ + function loadKey($key, $type = false) + { + if ($key instanceof RSA) { + $this->privateKeyFormat = $key->privateKeyFormat; + $this->publicKeyFormat = $key->publicKeyFormat; + $this->k = $key->k; + $this->hLen = $key->hLen; + $this->sLen = $key->sLen; + $this->mgfHLen = $key->mgfHLen; + $this->encryptionMode = $key->encryptionMode; + $this->signatureMode = $key->signatureMode; + $this->password = $key->password; + $this->configFile = $key->configFile; + $this->comment = $key->comment; + + if (is_object($key->hash)) { + $this->hash = new Hash($key->hash->getHash()); + } + if (is_object($key->mgfHash)) { + $this->mgfHash = new Hash($key->mgfHash->getHash()); + } + + if (is_object($key->modulus)) { + $this->modulus = $key->modulus->copy(); + } + if (is_object($key->exponent)) { + $this->exponent = $key->exponent->copy(); + } + if (is_object($key->publicExponent)) { + $this->publicExponent = $key->publicExponent->copy(); + } + + $this->primes = array(); + $this->exponents = array(); + $this->coefficients = array(); + + foreach ($this->primes as $prime) { + $this->primes[] = $prime->copy(); + } + foreach ($this->exponents as $exponent) { + $this->exponents[] = $exponent->copy(); + } + foreach ($this->coefficients as $coefficient) { + $this->coefficients[] = $coefficient->copy(); + } + + return true; + } + + if ($type === false) { + $types = array( + self::PUBLIC_FORMAT_RAW, + self::PRIVATE_FORMAT_PKCS1, + self::PRIVATE_FORMAT_XML, + self::PRIVATE_FORMAT_PUTTY, + self::PUBLIC_FORMAT_OPENSSH, + self::PRIVATE_FORMAT_OPENSSH + ); + foreach ($types as $type) { + $components = $this->_parseKey($key, $type); + if ($components !== false) { + break; + } + } + } else { + $components = $this->_parseKey($key, $type); + } + + if ($components === false) { + $this->comment = null; + $this->modulus = null; + $this->k = null; + $this->exponent = null; + $this->primes = null; + $this->exponents = null; + $this->coefficients = null; + $this->publicExponent = null; + + return false; + } + + if (isset($components['comment']) && $components['comment'] !== false) { + $this->comment = $components['comment']; + } + $this->modulus = $components['modulus']; + $this->k = strlen($this->modulus->toBytes()); + $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent']; + if (isset($components['primes'])) { + $this->primes = $components['primes']; + $this->exponents = $components['exponents']; + $this->coefficients = $components['coefficients']; + $this->publicExponent = $components['publicExponent']; + } else { + $this->primes = array(); + $this->exponents = array(); + $this->coefficients = array(); + $this->publicExponent = false; + } + + switch ($type) { + case self::PUBLIC_FORMAT_OPENSSH: + case self::PUBLIC_FORMAT_RAW: + $this->setPublicKey(); + break; + case self::PRIVATE_FORMAT_PKCS1: + switch (true) { + case strpos($key, '-BEGIN PUBLIC KEY-') !== false: + case strpos($key, '-BEGIN RSA PUBLIC KEY-') !== false: + $this->setPublicKey(); + } + } + + return true; + } + + /** + * Sets the password + * + * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. + * Or rather, pass in $password such that empty($password) && !is_string($password) is true. + * + * @see self::createKey() + * @see self::loadKey() + * @access public + * @param string $password + */ + function setPassword($password = false) + { + $this->password = $password; + } + + /** + * Defines the public key + * + * Some private key formats define the public exponent and some don't. Those that don't define it are problematic when + * used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a + * message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys + * and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public + * exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used + * is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being + * public. + * + * Do note that when a new key is loaded the index will be cleared. + * + * Returns true on success, false on failure + * + * @see self::getPublicKey() + * @access public + * @param string $key optional + * @param int $type optional + * @return bool + */ + function setPublicKey($key = false, $type = false) + { + // if a public key has already been loaded return false + if (!empty($this->publicExponent)) { + return false; + } + + if ($key === false && !empty($this->modulus)) { + $this->publicExponent = $this->exponent; + return true; + } + + if ($type === false) { + $types = array( + self::PUBLIC_FORMAT_RAW, + self::PUBLIC_FORMAT_PKCS1, + self::PUBLIC_FORMAT_XML, + self::PUBLIC_FORMAT_OPENSSH + ); + foreach ($types as $type) { + $components = $this->_parseKey($key, $type); + if ($components !== false) { + break; + } + } + } else { + $components = $this->_parseKey($key, $type); + } + + if ($components === false) { + return false; + } + + if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) { + $this->modulus = $components['modulus']; + $this->exponent = $this->publicExponent = $components['publicExponent']; + return true; + } + + $this->publicExponent = $components['publicExponent']; + + return true; + } + + /** + * Defines the private key + * + * If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force + * phpseclib to treat the key as a private key. This function will do that. + * + * Do note that when a new key is loaded the index will be cleared. + * + * Returns true on success, false on failure + * + * @see self::getPublicKey() + * @access public + * @param string $key optional + * @param int $type optional + * @return bool + */ + function setPrivateKey($key = false, $type = false) + { + if ($key === false && !empty($this->publicExponent)) { + $this->publicExponent = false; + return true; + } + + $rsa = new RSA(); + if (!$rsa->loadKey($key, $type)) { + return false; + } + $rsa->publicExponent = false; + + // don't overwrite the old key if the new key is invalid + $this->loadKey($rsa); + return true; + } + + /** + * Returns the public key + * + * The public key is only returned under two circumstances - if the private key had the public key embedded within it + * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this + * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. + * + * @see self::getPublicKey() + * @access public + * @param int $type optional + */ + function getPublicKey($type = self::PUBLIC_FORMAT_PKCS8) + { + if (empty($this->modulus) || empty($this->publicExponent)) { + return false; + } + + $oldFormat = $this->publicKeyFormat; + $this->publicKeyFormat = $type; + $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent); + $this->publicKeyFormat = $oldFormat; + return $temp; + } + + /** + * Returns the public key's fingerprint + * + * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is + * no public key currently loaded, false is returned. + * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) + * + * @access public + * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned + * for invalid values. + * @return mixed + */ + function getPublicKeyFingerprint($algorithm = 'md5') + { + if (empty($this->modulus) || empty($this->publicExponent)) { + return false; + } + + $modulus = $this->modulus->toBytes(true); + $publicExponent = $this->publicExponent->toBytes(true); + + $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus); + + switch ($algorithm) { + case 'sha256': + $hash = new Hash('sha256'); + $base = base64_encode($hash->hash($RSAPublicKey)); + return substr($base, 0, strlen($base) - 1); + case 'md5': + return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1); + default: + return false; + } + } + + /** + * Returns the private key + * + * The private key is only returned if the currently loaded key contains the constituent prime numbers. + * + * @see self::getPublicKey() + * @access public + * @param int $type optional + * @return mixed + */ + function getPrivateKey($type = self::PUBLIC_FORMAT_PKCS1) + { + if (empty($this->primes)) { + return false; + } + + $oldFormat = $this->privateKeyFormat; + $this->privateKeyFormat = $type; + $temp = $this->_convertPrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients); + $this->privateKeyFormat = $oldFormat; + return $temp; + } + + /** + * Returns a minimalistic private key + * + * Returns the private key without the prime number constituants. Structurally identical to a public key that + * hasn't been set as the public key + * + * @see self::getPrivateKey() + * @access private + * @param int $mode optional + */ + function _getPrivatePublicKey($mode = self::PUBLIC_FORMAT_PKCS8) + { + if (empty($this->modulus) || empty($this->exponent)) { + return false; + } + + $oldFormat = $this->publicKeyFormat; + $this->publicKeyFormat = $mode; + $temp = $this->_convertPublicKey($this->modulus, $this->exponent); + $this->publicKeyFormat = $oldFormat; + return $temp; + } + + /** + * __toString() magic method + * + * @access public + * @return string + */ + function __toString() + { + $key = $this->getPrivateKey($this->privateKeyFormat); + if ($key !== false) { + return $key; + } + $key = $this->_getPrivatePublicKey($this->publicKeyFormat); + return $key !== false ? $key : ''; + } + + /** + * __clone() magic method + * + * @access public + * @return Crypt_RSA + */ + function __clone() + { + $key = new RSA(); + $key->loadKey($this); + return $key; + } + + /** + * Generates the smallest and largest numbers requiring $bits bits + * + * @access private + * @param int $bits + * @return array + */ + function _generateMinMax($bits) + { + $bytes = $bits >> 3; + $min = str_repeat(chr(0), $bytes); + $max = str_repeat(chr(0xFF), $bytes); + $msb = $bits & 7; + if ($msb) { + $min = chr(1 << ($msb - 1)) . $min; + $max = chr((1 << $msb) - 1) . $max; + } else { + $min[0] = chr(0x80); + } + + return array( + 'min' => new BigInteger($min, 256), + 'max' => new BigInteger($max, 256) + ); + } + + /** + * DER-decode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @access private + * @param string $string + * @return int + */ + function _decodeLength(&$string) + { + $length = ord($this->_string_shift($string)); + if ($length & 0x80) { // definite length, long form + $length&= 0x7F; + $temp = $this->_string_shift($string, $length); + list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); + } + return $length; + } + + /** + * DER-encode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @access private + * @param int $length + * @return string + */ + function _encodeLength($length) + { + if ($length <= 0x7F) { + return chr($length); + } + + $temp = ltrim(pack('N', $length), chr(0)); + return pack('Ca*', 0x80 | strlen($temp), $temp); + } + + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + * @access private + */ + function _string_shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } + + /** + * Determines the private key format + * + * @see self::createKey() + * @access public + * @param int $format + */ + function setPrivateKeyFormat($format) + { + $this->privateKeyFormat = $format; + } + + /** + * Determines the public key format + * + * @see self::createKey() + * @access public + * @param int $format + */ + function setPublicKeyFormat($format) + { + $this->publicKeyFormat = $format; + } + + /** + * Determines which hashing function should be used + * + * Used with signature production / verification and (if the encryption mode is self::ENCRYPTION_OAEP) encryption and + * decryption. If $hash isn't supported, sha1 is used. + * + * @access public + * @param string $hash + */ + function setHash($hash) + { + // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch ($hash) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + $this->hash = new Hash($hash); + $this->hashName = $hash; + break; + default: + $this->hash = new Hash('sha1'); + $this->hashName = 'sha1'; + } + $this->hLen = $this->hash->getLength(); + } + + /** + * Determines which hashing function should be used for the mask generation function + * + * The mask generation function is used by self::ENCRYPTION_OAEP and self::SIGNATURE_PSS and although it's + * best if Hash and MGFHash are set to the same thing this is not a requirement. + * + * @access public + * @param string $hash + */ + function setMGFHash($hash) + { + // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch ($hash) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + $this->mgfHash = new Hash($hash); + break; + default: + $this->mgfHash = new Hash('sha1'); + } + $this->mgfHLen = $this->mgfHash->getLength(); + } + + /** + * Determines the salt length + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: + * + * Typical salt lengths in octets are hLen (the length of the output + * of the hash function Hash) and 0. + * + * @access public + * @param int $sLen + */ + function setSaltLength($sLen) + { + $this->sLen = $sLen; + } + + /** + * Integer-to-Octet-String primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. + * + * @access private + * @param \phpseclib\Math\BigInteger $x + * @param int $xLen + * @return string + */ + function _i2osp($x, $xLen) + { + $x = $x->toBytes(); + if (strlen($x) > $xLen) { + user_error('Integer too large'); + return false; + } + return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); + } + + /** + * Octet-String-to-Integer primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. + * + * @access private + * @param int|string|resource $x + * @return \phpseclib\Math\BigInteger + */ + function _os2ip($x) + { + return new BigInteger($x, 256); + } + + /** + * Exponentiate with or without Chinese Remainder Theorem + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}. + * + * @access private + * @param \phpseclib\Math\BigInteger $x + * @return \phpseclib\Math\BigInteger + */ + function _exponentiate($x) + { + switch (true) { + case empty($this->primes): + case $this->primes[1]->equals($this->zero): + case empty($this->coefficients): + case $this->coefficients[2]->equals($this->zero): + case empty($this->exponents): + case $this->exponents[1]->equals($this->zero): + return $x->modPow($this->exponent, $this->modulus); + } + + $num_primes = count($this->primes); + + if (defined('CRYPT_RSA_DISABLE_BLINDING')) { + $m_i = array( + 1 => $x->modPow($this->exponents[1], $this->primes[1]), + 2 => $x->modPow($this->exponents[2], $this->primes[2]) + ); + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } else { + $smallest = $this->primes[1]; + for ($i = 2; $i <= $num_primes; $i++) { + if ($smallest->compare($this->primes[$i]) > 0) { + $smallest = $this->primes[$i]; + } + } + + $one = new BigInteger(1); + + $r = $one->random($one, $smallest->subtract($one)); + + $m_i = array( + 1 => $this->_blind($x, $r, 1), + 2 => $this->_blind($x, $r, 2) + ); + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $this->_blind($x, $r, $i); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } + + return $m; + } + + /** + * Performs RSA Blinding + * + * Protects against timing attacks by employing RSA Blinding. + * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) + * + * @access private + * @param \phpseclib\Math\BigInteger $x + * @param \phpseclib\Math\BigInteger $r + * @param int $i + * @return \phpseclib\Math\BigInteger + */ + function _blind($x, $r, $i) + { + $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); + $x = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->modInverse($this->primes[$i]); + $x = $x->multiply($r); + list(, $x) = $x->divide($this->primes[$i]); + + return $x; + } + + /** + * Performs blinded RSA equality testing + * + * Protects against a particular type of timing attack described. + * + * See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)} + * + * Thanks for the heads up singpolyma! + * + * @access private + * @param string $x + * @param string $y + * @return bool + */ + function _equals($x, $y) + { + if (function_exists('hash_equals')) { + return hash_equals($x, $y); + } + + if (strlen($x) != strlen($y)) { + return false; + } + + $result = "\0"; + $x^= $y; + for ($i = 0; $i < strlen($x); $i++) { + $result|= $x[$i]; + } + + return $result === "\0"; + } + + /** + * RSAEP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. + * + * @access private + * @param \phpseclib\Math\BigInteger $m + * @return \phpseclib\Math\BigInteger + */ + function _rsaep($m) + { + if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { + user_error('Message representative out of range'); + return false; + } + return $this->_exponentiate($m); + } + + /** + * RSADP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. + * + * @access private + * @param \phpseclib\Math\BigInteger $c + * @return \phpseclib\Math\BigInteger + */ + function _rsadp($c) + { + if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) { + user_error('Ciphertext representative out of range'); + return false; + } + return $this->_exponentiate($c); + } + + /** + * RSASP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. + * + * @access private + * @param \phpseclib\Math\BigInteger $m + * @return \phpseclib\Math\BigInteger + */ + function _rsasp1($m) + { + if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { + user_error('Message representative out of range'); + return false; + } + return $this->_exponentiate($m); + } + + /** + * RSAVP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. + * + * @access private + * @param \phpseclib\Math\BigInteger $s + * @return \phpseclib\Math\BigInteger + */ + function _rsavp1($s) + { + if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) { + user_error('Signature representative out of range'); + return false; + } + return $this->_exponentiate($s); + } + + /** + * MGF1 + * + * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. + * + * @access private + * @param string $mgfSeed + * @param int $maskLen + * @return string + */ + function _mgf1($mgfSeed, $maskLen) + { + // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. + + $t = ''; + $count = ceil($maskLen / $this->mgfHLen); + for ($i = 0; $i < $count; $i++) { + $c = pack('N', $i); + $t.= $this->mgfHash->hash($mgfSeed . $c); + } + + return substr($t, 0, $maskLen); + } + + /** + * RSAES-OAEP-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and + * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. + * + * @access private + * @param string $m + * @param string $l + * @return string + */ + function _rsaes_oaep_encrypt($m, $l = '') + { + $mLen = strlen($m); + + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if ($mLen > $this->k - 2 * $this->hLen - 2) { + user_error('Message too long'); + return false; + } + + // EME-OAEP encoding + + $lHash = $this->hash->hash($l); + $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); + $db = $lHash . $ps . chr(1) . $m; + $seed = Random::string($this->hLen); + $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1); + $maskedDB = $db ^ $dbMask; + $seedMask = $this->_mgf1($maskedDB, $this->hLen); + $maskedSeed = $seed ^ $seedMask; + $em = chr(0) . $maskedSeed . $maskedDB; + + // RSA encryption + + $m = $this->_os2ip($em); + $c = $this->_rsaep($m); + $c = $this->_i2osp($c, $this->k); + + // Output the ciphertext C + + return $c; + } + + /** + * RSAES-OAEP-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error + * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: + * + * Note. Care must be taken to ensure that an opponent cannot + * distinguish the different error conditions in Step 3.g, whether by + * error message or timing, or, more generally, learn partial + * information about the encoded message EM. Otherwise an opponent may + * be able to obtain useful information about the decryption of the + * ciphertext C, leading to a chosen-ciphertext attack such as the one + * observed by Manger [36]. + * + * As for $l... to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: + * + * Both the encryption and the decryption operations of RSAES-OAEP take + * the value of a label L as input. In this version of PKCS #1, L is + * the empty string; other uses of the label are outside the scope of + * this document. + * + * @access private + * @param string $c + * @param string $l + * @return string + */ + function _rsaes_oaep_decrypt($c, $l = '') + { + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { + user_error('Decryption error'); + return false; + } + + // RSA decryption + + $c = $this->_os2ip($c); + $m = $this->_rsadp($c); + if ($m === false) { + user_error('Decryption error'); + return false; + } + $em = $this->_i2osp($m, $this->k); + + // EME-OAEP decoding + + $lHash = $this->hash->hash($l); + $y = ord($em[0]); + $maskedSeed = substr($em, 1, $this->hLen); + $maskedDB = substr($em, $this->hLen + 1); + $seedMask = $this->_mgf1($maskedDB, $this->hLen); + $seed = $maskedSeed ^ $seedMask; + $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $lHash2 = substr($db, 0, $this->hLen); + $m = substr($db, $this->hLen); + $hashesMatch = $this->_equals($lHash, $lHash2); + $leadingZeros = 1; + $patternMatch = 0; + $offset = 0; + for ($i = 0; $i < strlen($m); $i++) { + $patternMatch|= $leadingZeros & ($m[$i] === "\1"); + $leadingZeros&= $m[$i] === "\0"; + $offset+= $patternMatch ? 0 : 1; + } + + // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation + // to protect against timing attacks + if (!$hashesMatch & !$patternMatch) { + user_error('Decryption error'); + return false; + } + + // Output the message M + + return substr($m, $offset + 1); + } + + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @access private + * @param string $m + * @return string + */ + function _raw_encrypt($m) + { + $temp = $this->_os2ip($m); + $temp = $this->_rsaep($temp); + return $this->_i2osp($temp, $this->k); + } + + /** + * RSAES-PKCS1-V1_5-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. + * + * @access private + * @param string $m * @return string */ - protected function emsa_pkcs1_v1_5_encode($m, $emLen) + function _rsaes_pkcs1_v1_5_encrypt($m) { - $h = $this->hash->hash($m); + $mLen = strlen($m); - // see http://tools.ietf.org/html/rfc3447#page-43 - switch ($this->hash->getHash()) { - case 'md2': - $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10"; - break; - case 'md5': - $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"; - break; - case 'sha1': - $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"; - break; - case 'sha256': - $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; - break; - case 'sha384': - $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"; - break; - case 'sha512': - $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"; - break; - // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 - case 'sha224': - $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"; - break; - case 'sha512/224': - $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c"; - break; - case 'sha512/256': - $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20"; + // Length checking + + if ($mLen > $this->k - 11) { + user_error('Message too long'); + return false; } - $t.= $h; - $tLen = strlen($t); - if ($emLen < $tLen + 11) { - throw new \LengthException('Intended encoded message length too short'); + // EME-PKCS1-v1_5 encoding + + $psLen = $this->k - $mLen - 3; + $ps = ''; + while (strlen($ps) != $psLen) { + $temp = Random::string($psLen - strlen($ps)); + $temp = str_replace("\x00", '', $temp); + $ps.= $temp; + } + $type = 2; + // see the comments of _rsaes_pkcs1_v1_5_decrypt() to understand why this is being done + if (defined('CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) { + $type = 1; + // "The padding string PS shall consist of k-3-||D|| octets. ... for block type 01, they shall have value FF" + $ps = str_repeat("\xFF", $psLen); } + $em = chr(0) . chr($type) . $ps . chr(0) . $m; - $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + // RSA encryption + $m = $this->_os2ip($em); + $c = $this->_rsaep($m); + $c = $this->_i2osp($c, $this->k); - $em = "\0\1$ps\0$t"; + // Output the ciphertext C + + return $c; + } + + /** + * RSAES-PKCS1-V1_5-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. + * + * For compatibility purposes, this function departs slightly from the description given in RFC3447. + * The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the + * private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the + * public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed + * to be 2 regardless of which key is used. For compatibility purposes, we'll just check to make sure the + * second byte is 2 or less. If it is, we'll accept the decrypted string as valid. + * + * As a consequence of this, a private key encrypted ciphertext produced with \phpseclib\Crypt\RSA may not decrypt + * with a strictly PKCS#1 v1.5 compliant RSA implementation. Public key encrypted ciphertext's should but + * not private key encrypted ciphertext's. + * + * @access private + * @param string $c + * @return string + */ + function _rsaes_pkcs1_v1_5_decrypt($c) + { + // Length checking + + if (strlen($c) != $this->k) { // or if k < 11 + user_error('Decryption error'); + return false; + } + + // RSA decryption + + $c = $this->_os2ip($c); + $m = $this->_rsadp($c); + + if ($m === false) { + user_error('Decryption error'); + return false; + } + $em = $this->_i2osp($m, $this->k); + + // EME-PKCS1-v1_5 decoding + + if (ord($em[0]) != 0 || ord($em[1]) > 2) { + user_error('Decryption error'); + return false; + } + + $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); + $m = substr($em, strlen($ps) + 3); + + if (strlen($ps) < 8) { + user_error('Decryption error'); + return false; + } + + // Output M + + return $m; + } + + /** + * EMSA-PSS-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. + * + * @access private + * @param string $m + * @param int $emBits + */ + function _emsa_pss_encode($m, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + user_error('Encoding error'); + return false; + } + + $salt = Random::string($sLen); + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h = $this->hash->hash($m2); + $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); + $db = $ps . chr(1) . $salt; + $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1); + $maskedDB = $db ^ $dbMask; + $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; + $em = $maskedDB . $h . chr(0xBC); return $em; } /** - * MGF1 + * EMSA-PSS-VERIFY * - * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. * * @access private - * @param string $mgfSeed - * @param int $maskLen + * @param string $m + * @param string $em + * @param int $emBits * @return string */ - protected function mgf1($mgfSeed, $maskLen) + function _emsa_pss_verify($m, $em, $emBits) { - // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. - $t = ''; - $count = ceil($maskLen / $this->mgfHLen); - for ($i = 0; $i < $count; $i++) { - $c = pack('N', $i); - $t.= $this->mgfHash->hash($mgfSeed . $c); + $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + return false; } - return substr($t, 0, $maskLen); + if ($em[strlen($em) - 1] != chr(0xBC)) { + return false; + } + + $maskedDB = substr($em, 0, -$this->hLen - 1); + $h = substr($em, -$this->hLen - 1, $this->hLen); + $temp = chr(0xFF << ($emBits & 7)); + if ((~$maskedDB[0] & $temp) != $temp) { + return false; + } + $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; + $temp = $emLen - $this->hLen - $sLen - 2; + if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { + return false; + } + $salt = substr($db, $temp + 1); // should be $sLen long + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h2 = $this->hash->hash($m2); + return $this->_equals($h, $h2); } /** - * Returns the key size + * RSASSA-PSS-SIGN * - * More specifically, this returns the size of the modulo in bits. + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. * - * @access public - * @return int + * @access private + * @param string $m + * @return string */ - public function getLength() + function _rsassa_pss_sign($m) { - return !isset($this->modulus) ? 0 : $this->modulus->getLength(); + // EMSA-PSS encoding + + $em = $this->_emsa_pss_encode($m, 8 * $this->k - 1); + + // RSA signature + + $m = $this->_os2ip($em); + $s = $this->_rsasp1($m); + $s = $this->_i2osp($s, $this->k); + + // Output the signature S + + return $s; } /** - * Determines which hashing function should be used + * RSASSA-PSS-VERIFY * - * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and - * decryption. + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. * - * @access public - * @param string $hash + * @access private + * @param string $m + * @param string $s + * @return string */ - public function withHash($hash) + function _rsassa_pss_verify($m, $s) { - $new = clone $this; + // Length checking - // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. - switch (strtolower($hash)) { - case 'md2': - case 'md5': - case 'sha1': - case 'sha256': - case 'sha384': - case 'sha512': - case 'sha224': - case 'sha512/224': - case 'sha512/256': - $new->hash = new Hash($hash); - break; - default: - throw new UnsupportedAlgorithmException( - 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' - ); + if (strlen($s) != $this->k) { + user_error('Invalid signature'); + return false; + } + + // RSA verification + + $modBits = strlen($this->modulus->toBits()); + + $s2 = $this->_os2ip($s); + $m2 = $this->_rsavp1($s2); + if ($m2 === false) { + user_error('Invalid signature'); + return false; + } + $em = $this->_i2osp($m2, $this->k); + if ($em === false) { + user_error('Invalid signature'); + return false; } - $new->hLen = $new->hash->getLengthInBytes(); - return $new; + // EMSA-PSS verification + + return $this->_emsa_pss_verify($m, $em, $modBits - 1); } /** - * Determines which hashing function should be used for the mask generation function + * EMSA-PKCS1-V1_5-ENCODE * - * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's - * best if Hash and MGFHash are set to the same thing this is not a requirement. + * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. * - * @access public - * @param string $hash + * @access private + * @param string $m + * @param int $emLen + * @return string */ - public function withMGFHash($hash) + function _emsa_pkcs1_v1_5_encode($m, $emLen) { - $new = clone $this; + $h = $this->hash->hash($m); + if ($h === false) { + return false; + } - // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. - switch (strtolower($hash)) { + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hashName) { case 'md2': + $t = pack('H*', '3020300c06082a864886f70d020205000410'); + break; case 'md5': + $t = pack('H*', '3020300c06082a864886f70d020505000410'); + break; case 'sha1': + $t = pack('H*', '3021300906052b0e03021a05000414'); + break; case 'sha256': + $t = pack('H*', '3031300d060960864801650304020105000420'); + break; case 'sha384': - case 'sha512': - case 'sha224': - case 'sha512/224': - case 'sha512/256': - $new->mgfHash = new Hash($hash); + $t = pack('H*', '3041300d060960864801650304020205000430'); break; - default: - throw new UnsupportedAlgorithmException( - 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' - ); + case 'sha512': + $t = pack('H*', '3051300d060960864801650304020305000440'); + } + $t.= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + user_error('Intended encoded message length too short'); + return false; } - $new->mgfHLen = $new->mgfHash->getLengthInBytes(); - return $new; + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; } /** - * Returns the MGF hash algorithm currently being used + * RSASSA-PKCS1-V1_5-SIGN * - * @access public + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. + * + * @access private + * @param string $m + * @return string */ - public function getMGFHash() + function _rsassa_pkcs1_v1_5_sign($m) { - return clone $this->mgfHash; + // EMSA-PKCS1-v1_5 encoding + + $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); + if ($em === false) { + user_error('RSA modulus too short'); + return false; + } + + // RSA signature + + $m = $this->_os2ip($em); + $s = $this->_rsasp1($m); + $s = $this->_i2osp($s, $this->k); + + // Output the signature S + + return $s; } /** - * Determines the salt length + * RSASSA-PKCS1-V1_5-VERIFY * - * Used by RSA::PADDING_PSS + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. * - * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: + * @access private + * @param string $m + * @param string $s + * @return string + */ + function _rsassa_pkcs1_v1_5_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + user_error('Invalid signature'); + return false; + } + + // RSA verification + + $s = $this->_os2ip($s); + $m2 = $this->_rsavp1($s); + if ($m2 === false) { + user_error('Invalid signature'); + return false; + } + $em = $this->_i2osp($m2, $this->k); + if ($em === false) { + user_error('Invalid signature'); + return false; + } + + // EMSA-PKCS1-v1_5 encoding + + $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); + if ($em2 === false) { + user_error('RSA modulus too short'); + return false; + } + + // Compare + return $this->_equals($em, $em2); + } + + /** + * Set Encryption Mode * - * Typical salt lengths in octets are hLen (the length of the output - * of the hash function Hash) and 0. + * Valid values include self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1. * * @access public - * @param int $sLen + * @param int $mode */ - public function withSaltLength($sLen) + function setEncryptionMode($mode) { - $new = clone $this; - $new->sLen = $sLen; - return $new; + $this->encryptionMode = $mode; } /** - * Returns the salt length currently being used + * Set Signature Mode + * + * Valid values include self::SIGNATURE_PSS and self::SIGNATURE_PKCS1 * * @access public + * @param int $mode */ - public function getSaltLength() + function setSignatureMode($mode) { - return $this->sLen !== null ? $this->sLen : $this->hLen; + $this->signatureMode = $mode; } /** - * Determines the label - * - * Used by RSA::PADDING_OAEP - * - * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: - * - * Both the encryption and the decryption operations of RSAES-OAEP take - * the value of a label L as input. In this version of PKCS #1, L is - * the empty string; other uses of the label are outside the scope of - * this document. + * Set public key comment. * * @access public - * @param string $label + * @param string $comment */ - public function withLabel($label) + function setComment($comment) { - $new = clone $this; - $new->label = $label; - return $new; + $this->comment = $comment; } /** - * Returns the label currently being used + * Get public key comment. * * @access public + * @return string */ - public function getLabel() + function getComment() { - return $this->label; + return $this->comment; } /** - * Determines the padding modes + * Encryption * - * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1); + * Both self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1 both place limits on how long $plaintext can be. + * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will + * be concatenated together. * + * @see self::decrypt() * @access public - * @param int $padding - */ - public function withPadding($padding) - { - $masks = [ - self::ENCRYPTION_OAEP, - self::ENCRYPTION_PKCS1, - self::ENCRYPTION_NONE - ]; - $numSelected = 0; - $selected = 0; - foreach ($masks as $mask) { - if ($padding & $mask) { - $selected = $mask; - $numSelected++; - } - } - if ($numSelected > 1) { - throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); - } - $encryptionPadding = $selected; - - $masks = [ - self::SIGNATURE_PSS, - self::SIGNATURE_RELAXED_PKCS1, - self::SIGNATURE_PKCS1 - ]; - $numSelected = 0; - $selected = 0; - foreach ($masks as $mask) { - if ($padding & $mask) { - $selected = $mask; - $numSelected++; - } - } - if ($numSelected > 1) { - throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); - } - $signaturePadding = $selected; + * @param string $plaintext + * @return string + */ + function encrypt($plaintext) + { + switch ($this->encryptionMode) { + case self::ENCRYPTION_NONE: + $plaintext = str_split($plaintext, $this->k); + $ciphertext = ''; + foreach ($plaintext as $m) { + $ciphertext.= $this->_raw_encrypt($m); + } + return $ciphertext; + case self::ENCRYPTION_PKCS1: + $length = $this->k - 11; + if ($length <= 0) { + return false; + } + + $plaintext = str_split($plaintext, $length); + $ciphertext = ''; + foreach ($plaintext as $m) { + $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m); + } + return $ciphertext; + //case self::ENCRYPTION_OAEP: + default: + $length = $this->k - 2 * $this->hLen - 2; + if ($length <= 0) { + return false; + } - $new = clone $this; - $new->encryptionPadding = $encryptionPadding; - $new->signaturePadding = $signaturePadding; - return $new; + $plaintext = str_split($plaintext, $length); + $ciphertext = ''; + foreach ($plaintext as $m) { + $ciphertext.= $this->_rsaes_oaep_encrypt($m); + } + return $ciphertext; + } } /** - * Returns the padding currently being used + * Decryption * + * @see self::encrypt() * @access public + * @param string $ciphertext + * @return string */ - public function getPadding() + function decrypt($ciphertext) { - return $this->signaturePadding | $this->encryptionPadding; + if ($this->k <= 0) { + return false; + } + + $ciphertext = str_split($ciphertext, $this->k); + $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT); + + $plaintext = ''; + + switch ($this->encryptionMode) { + case self::ENCRYPTION_NONE: + $decrypt = '_raw_encrypt'; + break; + case self::ENCRYPTION_PKCS1: + $decrypt = '_rsaes_pkcs1_v1_5_decrypt'; + break; + //case self::ENCRYPTION_OAEP: + default: + $decrypt = '_rsaes_oaep_decrypt'; + } + + foreach ($ciphertext as $c) { + $temp = $this->$decrypt($c); + if ($temp === false) { + return false; + } + $plaintext.= $temp; + } + + return $plaintext; } /** - * Returns the current engine being used + * Create a signature * - * @see self::useInternalEngine() - * @see self::useBestEngine() + * @see self::verify() * @access public + * @param string $message * @return string */ - public function getEngine() + function sign($message) { - return 'PHP'; + if (empty($this->modulus) || empty($this->exponent)) { + return false; + } + + switch ($this->signatureMode) { + case self::SIGNATURE_PKCS1: + return $this->_rsassa_pkcs1_v1_5_sign($message); + //case self::SIGNATURE_PSS: + default: + return $this->_rsassa_pss_sign($message); + } } /** - * Enable RSA Blinding + * Verifies a signature * + * @see self::sign() * @access public + * @param string $message + * @param string $signature + * @return bool */ - public static function enableBlinding() + function verify($message, $signature) { - static::$enableBlinding = true; + if (empty($this->modulus) || empty($this->exponent)) { + return false; + } + + switch ($this->signatureMode) { + case self::SIGNATURE_PKCS1: + return $this->_rsassa_pkcs1_v1_5_verify($message, $signature); + //case self::SIGNATURE_PSS: + default: + return $this->_rsassa_pss_verify($message, $signature); + } } /** - * Disable RSA Blinding + * Extract raw BER from Base64 encoding * - * @access public + * @access private + * @param string $str + * @return string */ - public static function disableBlinding() + function _extractBER($str) { - static::$enableBlinding = false; + /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them + * above and beyond the ceritificate. + * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: + * + * Bag Attributes + * localKeyID: 01 00 00 00 + * subject=/O=organization/OU=org unit/CN=common name + * issuer=/O=organization/CN=common name + */ + $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); + // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff + $temp = preg_replace('#-+[^-]+-+#', '', $temp); + // remove new lines + $temp = str_replace(array("\r", "\n", ' '), '', $temp); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + return $temp != false ? $temp : $str; } -} \ No newline at end of file +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php deleted file mode 100644 index 74771204d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php +++ /dev/null @@ -1,242 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\UnsupportedFormatException; - -/** - * Microsoft BLOB Formatted RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class MSBLOB -{ - /** - * Public/Private Key Pair - * - * @access private - */ - const PRIVATEKEYBLOB = 0x7; - /** - * Public Key - * - * @access private - */ - const PUBLICKEYBLOB = 0x6; - /** - * Public Key - * - * @access private - */ - const PUBLICKEYBLOBEX = 0xA; - /** - * RSA public key exchange algorithm - * - * @access private - */ - const CALG_RSA_KEYX = 0x0000A400; - /** - * RSA public key exchange algorithm - * - * @access private - */ - const CALG_RSA_SIGN = 0x00002400; - /** - * Public Key - * - * @access private - */ - const RSA1 = 0x31415352; - /** - * Private Key - * - * @access private - */ - const RSA2 = 0x32415352; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $key = Base64::decode($key); - - if (!is_string($key)) { - throw new \UnexpectedValueException('Base64 decoding produced an error'); - } - if (strlen($key) < 20) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - // PUBLICKEYSTRUC publickeystruc - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx - extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8))); - /** - * @var string $type - * @var string $version - * @var integer $reserved - * @var integer $algo - */ - switch (ord($type)) { - case self::PUBLICKEYBLOB: - case self::PUBLICKEYBLOBEX: - $publickey = true; - break; - case self::PRIVATEKEYBLOB: - $publickey = false; - break; - default: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $components = ['isPublicKey' => $publickey]; - - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx - switch ($algo) { - case self::CALG_RSA_KEYX: - case self::CALG_RSA_SIGN: - break; - default: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - // RSAPUBKEY rsapubkey - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx - // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit - extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12))); - /** - * @var integer $magic - * @var integer $bitlen - * @var string $pubexp - */ - switch ($magic) { - case self::RSA2: - $components['isPublicKey'] = false; - case self::RSA1: - break; - default: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $baseLength = $bitlen / 16; - if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256); - // BYTE modulus[rsapubkey.bitlen/8] - $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); - - if ($publickey) { - return $components; - } - - $components['isPublicKey'] = false; - - // BYTE prime1[rsapubkey.bitlen/16] - $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; - // BYTE prime2[rsapubkey.bitlen/16] - $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); - // BYTE exponent1[rsapubkey.bitlen/16] - $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; - // BYTE exponent2[rsapubkey.bitlen/16] - $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); - // BYTE coefficient[rsapubkey.bitlen/16] - $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; - if (isset($components['privateExponent'])) { - $components['publicExponent'] = $components['privateExponent']; - } - // BYTE privateExponent[rsapubkey.bitlen/8] - $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') - { - if (count($primes) != 2) { - throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); - } - - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('MSBLOB private keys do not support encryption'); - } - - $n = strrev($n->toBytes()); - $e = str_pad(strrev($e->toBytes()), 4, "\0"); - $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); - $key.= pack('VVa*', self::RSA2, 8 * strlen($n), $e); - $key.= $n; - $key.= strrev($primes[1]->toBytes()); - $key.= strrev($primes[2]->toBytes()); - $key.= strrev($exponents[1]->toBytes()); - $key.= strrev($exponents[2]->toBytes()); - $key.= strrev($coefficients[2]->toBytes()); - $key.= strrev($d->toBytes()); - - return Base64::encode($key); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - $n = strrev($n->toBytes()); - $e = str_pad(strrev($e->toBytes()), 4, "\0"); - $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); - $key.= pack('VVa*', self::RSA1, 8 * strlen($n), $e); - $key.= $n; - - return Base64::encode($key); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php deleted file mode 100644 index 0f92c1003..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; - -/** - * OpenSSH Formatted RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class OpenSSH extends Progenitor -{ - /** - * Supported Key Types - * - * @var array - */ - protected static $types = ['ssh-rsa']; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - $parsed = parent::load($key, $password); - - if (isset($parsed['paddedKey'])) { - list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); - if ($type != $parsed['type']) { - throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); - } - - $primes = $coefficients = []; - - list( - $modulus, - $publicExponent, - $privateExponent, - $coefficients[2], - $primes[1], - $primes[2], - $comment, - ) = Strings::unpackSSH2('i6s', $parsed['paddedKey']); - - $temp = $primes[1]->subtract($one); - $exponents = [1 => $publicExponent->modInverse($temp)]; - $temp = $primes[2]->subtract($one); - $exponents[] = $publicExponent->modInverse($temp); - - $isPublicKey = false; - - return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); - } - - list($publicExponent, $modulus) = Strings::unpackSSH2('ii', $parsed['publicKey']); - - return [ - 'isPublicKey' => true, - 'modulus' => $modulus, - 'publicExponent' => $publicExponent, - 'comment' => $parsed['comment'] - ]; - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) - { - $RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $RSAPublicKey; - } - - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment; - - return $RSAPublicKey; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - $publicKey = self::savePublicKey($n, $e, ['binary' => true]); - $privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php deleted file mode 100644 index 5203e4631..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Common\Functions\Strings; - -/** - * PKCS#1 Formatted RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class PKCS1 extends Progenitor -{ - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (strpos($key, 'PUBLIC') !== false) { - $components = ['isPublicKey' => true]; - } elseif (strpos($key, 'PRIVATE') !== false) { - $components = ['isPublicKey' => false]; - } else { - $components = []; - } - - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP); - if (is_array($key)) { - $components+= [ - 'modulus' => $key['modulus'], - 'publicExponent' => $key['publicExponent'], - 'privateExponent' => $key['privateExponent'], - 'primes' => [1 => $key['prime1'], $key['prime2']], - 'exponents' => [1 => $key['exponent1'], $key['exponent2']], - 'coefficients' => [2 => $key['coefficient']] - ]; - if ($key['version'] == 'multi') { - foreach ($key['otherPrimeInfos'] as $primeInfo) { - $components['primes'][] = $primeInfo['prime']; - $components['exponents'][] = $primeInfo['exponent']; - $components['coefficients'][] = $primeInfo['coefficient']; - } - } - if (!isset($components['isPublicKey'])) { - $components['isPublicKey'] = false; - } - return $components; - } - - $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP); - - if (!is_array($key)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - if (!isset($components['isPublicKey'])) { - $components['isPublicKey'] = true; - } - - return $components + $key; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - $num_primes = count($primes); - $key = [ - 'version' => $num_primes == 2 ? 'two-prime' : 'multi', - 'modulus' => $n, - 'publicExponent' => $e, - 'privateExponent' => $d, - 'prime1' => $primes[1], - 'prime2' => $primes[2], - 'exponent1' => $exponents[1], - 'exponent2' => $exponents[2], - 'coefficient' => $coefficients[2] - ]; - for ($i = 3; $i <= $num_primes; $i++) { - $key['otherPrimeInfos'][] = [ - 'prime' => $primes[$i], - 'exponent' => $exponents[$i], - 'coefficient' => $coefficients[$i] - ]; - } - - $key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP); - - return self::wrapPrivateKey($key, 'RSA', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - $key = [ - 'modulus' => $n, - 'publicExponent' => $e - ]; - - $key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP); - - return self::wrapPublicKey($key, 'RSA'); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php deleted file mode 100644 index 8ead2c95b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\Common\Functions\Strings; - -/** - * PKCS#8 Formatted RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class PKCS8 extends Progenitor -{ - /** - * OID Name - * - * @var string - * @access private - */ - const OID_NAME = 'rsaEncryption'; - - /** - * OID Value - * - * @var string - * @access private - */ - const OID_VALUE = '1.2.840.113549.1.1.1'; - - /** - * Child OIDs loaded - * - * @var bool - * @access private - */ - protected static $childOIDsLoaded = false; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (strpos($key, 'PUBLIC') !== false) { - $components = ['isPublicKey' => true]; - } elseif (strpos($key, 'PRIVATE') !== false) { - $components = ['isPublicKey' => false]; - } else { - $components = []; - } - - $key = parent::load($key, $password); - - if (isset($key['privateKey'])) { - if (!isset($components['isPublicKey'])) { - $components['isPublicKey'] = false; - } - $type = 'private'; - } else { - if (!isset($components['isPublicKey'])) { - $components['isPublicKey'] = true; - } - $type = 'public'; - } - - $result = $components + PKCS1::load($key[$type . 'Key']); - - if (isset($key['meta'])) { - $result['meta'] = $key['meta']; - } - - return $result; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); - $key = ASN1::extractBER($key); - return self::wrapPrivateKey($key, [], null, $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) - { - $key = PKCS1::savePublicKey($n, $e); - $key = ASN1::extractBER($key); - return self::wrapPublicKey($key, null); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php deleted file mode 100644 index 813653aef..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php +++ /dev/null @@ -1,250 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Common\Functions\Strings; - -/** - * PKCS#8 Formatted RSA-PSS Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class PSS extends Progenitor -{ - /** - * OID Name - * - * @var string - * @access private - */ - const OID_NAME = 'id-RSASSA-PSS'; - - /** - * OID Value - * - * @var string - * @access private - */ - const OID_VALUE = '1.2.840.113549.1.1.10'; - - /** - * OIDs loaded - * - * @var bool - * @access private - */ - private static $oidsLoaded = false; - - /** - * Child OIDs loaded - * - * @var bool - * @access private - */ - protected static $childOIDsLoaded = false; - - /** - * Initialize static variables - */ - private static function initialize_static_variables() - { - if (!self::$oidsLoaded) { - ASN1::loadOIDs([ - 'md2' => '1.2.840.113549.2.2', - 'md4' => '1.2.840.113549.2.4', - 'md5' => '1.2.840.113549.2.5', - 'id-sha1' => '1.3.14.3.2.26', - 'id-sha256' => '2.16.840.1.101.3.4.2.1', - 'id-sha384' => '2.16.840.1.101.3.4.2.2', - 'id-sha512' => '2.16.840.1.101.3.4.2.3', - 'id-sha224' => '2.16.840.1.101.3.4.2.4', - 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', - 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', - - 'id-mgf1' => '1.2.840.113549.1.1.8' - ]); - self::$oidsLoaded = true; - } - } - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; - - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'private' : 'public'; - - $result = $components + PKCS1::load($key[$type . 'Key']); - - if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { - $decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); - if ($decoded === false) { - throw new \UnexpectedValueException('Unable to decode parameters'); - } - $params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP); - } else { - $params = []; - } - - if (isset($params['maskGenAlgorithm']['parameters'])) { - $decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); - if ($decoded === false) { - throw new \UnexpectedValueException('Unable to decode parameters'); - } - $params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP); - } else { - $params['maskGenAlgorithm'] = [ - 'algorithm' => 'id-mgf1', - 'parameters' => ['algorithm' => 'id-sha1'] - ]; - } - - if (!isset($params['hashAlgorithm']['algorithm'])) { - $params['hashAlgorithm']['algorithm'] = 'id-sha1'; - } - - $result['hash'] = str_replace('id-', '', $params['hashAlgorithm']['algorithm']); - $result['MGFHash'] = str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']); - if (isset($params['saltLength'])) { - $result['saltLength'] = (int) $params['saltLength']->toString(); - } - - if (isset($key['meta'])) { - $result['meta'] = $key['meta']; - } - - return $result; - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - self::initialize_static_variables(); - - $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); - $key = ASN1::extractBER($key); - $params = self::savePSSParams($options); - return self::wrapPrivateKey($key, [], $params, $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) - { - self::initialize_static_variables(); - - $key = PKCS1::savePublicKey($n, $e); - $key = ASN1::extractBER($key); - $params = self::savePSSParams($options); - return self::wrapPublicKey($key, $params); - } - - /** - * Encodes PSS parameters - * - * @access public - * @param array $options - * @return string - */ - public static function savePSSParams(array $options) - { - /* - The trailerField field is an integer. It provides - compatibility with IEEE Std 1363a-2004 [P1363A]. The value - MUST be 1, which represents the trailer field with hexadecimal - value 0xBC. Other trailer fields, including the trailer field - composed of HashID concatenated with 0xCC that is specified in - IEEE Std 1363a, are not supported. Implementations that - perform signature generation MUST omit the trailerField field, - indicating that the default trailer field value was used. - Implementations that perform signature validation MUST - recognize both a present trailerField field with value 1 and an - absent trailerField field. - - source: https://tools.ietf.org/html/rfc4055#page-9 - */ - $params = [ - 'trailerField' => new BigInteger(1) - ]; - if (isset($options['hash'])) { - $params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash']; - } - if (isset($options['MGFHash'])) { - $temp = ['algorithm' => 'id-' . $options['MGFHash']]; - $temp = ASN1::encodeDER($temp, Maps\HashAlgorithm::MAP); - $params['maskGenAlgorithm'] = [ - 'algorithm' => 'id-mgf1', - 'parameters' => new ASN1\Element($temp) - ]; - } - if (isset($options['saltLength'])) { - $params['saltLength'] = new BigInteger($options['saltLength']); - } - - return new ASN1\Element(ASN1::encodeDER($params, Maps\RSASSA_PSS_params::MAP)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php deleted file mode 100644 index 4c93b873d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; - -/** - * PuTTY Formatted RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class PuTTY extends Progenitor -{ - /** - * Public Handler - * - * @var string - * @access private - */ - const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH'; - - /** - * Algorithm Identifier - * - * @var array - * @access private - */ - protected static $types = ['ssh-rsa']; - - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - $components = parent::load($key, $password); - if (!isset($components['private'])) { - return $components; - } - extract($components); - unset($components['public'], $components['private']); - - $isPublicKey = false; - - $result = Strings::unpackSSH2('ii', $public); - if ($result === false) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - list($publicExponent, $modulus) = $result; - - $result = Strings::unpackSSH2('iiii', $private); - if ($result === false) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - $primes = $coefficients = []; - list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; - - $temp = $primes[1]->subtract($one); - $exponents = [1 => $publicExponent->modInverse($temp)]; - $temp = $primes[2]->subtract($one); - $exponents[] = $publicExponent->modInverse($temp); - - return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - if (count($primes) != 2) { - throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); - } - - $public = Strings::packSSH2('ii', $e, $n); - $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); - - return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa'); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php deleted file mode 100644 index 49d789285..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; - -/** - * Raw RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class Raw -{ - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!is_array($key)) { - throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); - } - if (isset($key['isPublicKey']) && isset($key['modulus'])) { - if (isset($key['privateExponent']) || isset($key['publicExponent'])) { - if (!isset($key['primes'])) { - return $key; - } - if (isset($key['exponents']) && isset($key['coefficients']) && isset($key['publicExponent']) && isset($key['privateExponent'])) { - return $key; - } - } - } - $components = ['isPublicKey' => true]; - switch (true) { - case isset($key['e']): - $components['publicExponent'] = $key['e']; - break; - case isset($key['exponent']): - $components['publicExponent'] = $key['exponent']; - break; - case isset($key['publicExponent']): - $components['publicExponent'] = $key['publicExponent']; - break; - case isset($key[0]): - $components['publicExponent'] = $key[0]; - } - switch (true) { - case isset($key['n']): - $components['modulus'] = $key['n']; - break; - case isset($key['modulo']): - $components['modulus'] = $key['modulo']; - break; - case isset($key['modulus']): - $components['modulus'] = $key['modulus']; - break; - case isset($key[1]): - $components['modulus'] = $key[1]; - } - if (isset($components['modulus']) && isset($components['publicExponent'])) { - return $components; - } - - throw new \UnexpectedValueException('Modulus / exponent not present'); - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return array - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - return ['e' => clone $e, 'n' => clone $n]; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php deleted file mode 100644 index 389f93a82..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use ParagonIE\ConstantTime\Base64; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\UnsupportedFormatException; - -/** - * XML Formatted RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -abstract class XML -{ - /** - * Break a public or private key down into its constituent components - * - * @access public - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $components = [ - 'isPublicKey' => false, - 'primes' => [], - 'exponents' => [], - 'coefficients' => [] - ]; - - $use_errors = libxml_use_internal_errors(true); - - $dom = new \DOMDocument(); - if (substr($key, 0, 5) != '' . $key . ''; - } - if (!$dom->loadXML($key)) { - throw new \UnexpectedValueException('Key does not appear to contain XML'); - } - $xpath = new \DOMXPath($dom); - $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; - foreach ($keys as $key) { - // $dom->getElementsByTagName($key) is case-sensitive - $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); - if (!$temp->length) { - continue; - } - $value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256); - switch ($key) { - case 'modulus': - $components['modulus'] = $value; - break; - case 'exponent': - $components['publicExponent'] = $value; - break; - case 'p': - $components['primes'][1] = $value; - break; - case 'q': - $components['primes'][2] = $value; - break; - case 'dp': - $components['exponents'][1] = $value; - break; - case 'dq': - $components['exponents'][2] = $value; - break; - case 'inverseq': - $components['coefficients'][2] = $value; - break; - case 'd': - $components['privateExponent'] = $value; - } - } - - libxml_use_internal_errors($use_errors); - - foreach ($components as $key => $value) { - if (is_array($value) && !count($value)) { - unset($components[$key]); - } - } - - if (isset($components['modulus']) && isset($components['publicExponent'])) { - if (count($components) == 3) { - $components['isPublicKey'] = true; - } - return $components; - } - - throw new \UnexpectedValueException('Modulus / exponent not present'); - } - - /** - * Convert a private key to the appropriate format. - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') - { - if (count($primes) != 2) { - throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); - } - - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('XML private keys do not support encryption'); - } - - return "\r\n" . - ' ' . Base64::encode($n->toBytes()) . "\r\n" . - ' ' . Base64::encode($e->toBytes()) . "\r\n" . - '

      ' . Base64::encode($primes[1]->toBytes()) . "

      \r\n" . - ' ' . Base64::encode($primes[2]->toBytes()) . "\r\n" . - ' ' . Base64::encode($exponents[1]->toBytes()) . "\r\n" . - ' ' . Base64::encode($exponents[2]->toBytes()) . "\r\n" . - ' ' . Base64::encode($coefficients[2]->toBytes()) . "\r\n" . - ' ' . Base64::encode($d->toBytes()) . "\r\n" . - '
      '; - } - - /** - * Convert a public key to the appropriate format - * - * @access public - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - return "\r\n" . - ' ' . Base64::encode($n->toBytes()) . "\r\n" . - ' ' . Base64::encode($e->toBytes()) . "\r\n" . - ''; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php deleted file mode 100644 index 5205ce63d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php +++ /dev/null @@ -1,556 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA; - -use phpseclib3\Crypt\RSA; -use phpseclib3\Math\BigInteger; -use phpseclib3\File\ASN1; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Hash; -use phpseclib3\Exceptions\NoKeyLoadedException; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; - -/** - * Raw RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -class PrivateKey extends RSA implements Common\PrivateKey -{ - use Common\Traits\PasswordProtected; - - /** - * Primes for Chinese Remainder Theorem (ie. p and q) - * - * @var array - * @access private - */ - protected $primes; - - /** - * Exponents for Chinese Remainder Theorem (ie. dP and dQ) - * - * @var array - * @access private - */ - protected $exponents; - - /** - * Coefficients for Chinese Remainder Theorem (ie. qInv) - * - * @var array - * @access private - */ - protected $coefficients; - - /** - * Public Exponent - * - * @var mixed - * @access private - */ - protected $publicExponent = false; - - /** - * RSADP - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. - * - * @access private - * @param \phpseclib3\Math\BigInteger $c - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsadp($c) - { - if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { - throw new \OutOfRangeException('Ciphertext representative out of range'); - } - return $this->exponentiate($c); - } - - /** - * RSASP1 - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. - * - * @access private - * @param \phpseclib3\Math\BigInteger $m - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsasp1($m) - { - if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { - throw new \OutOfRangeException('Signature representative out of range'); - } - return $this->exponentiate($m); - } - - /** - * Exponentiate - * - * @param \phpseclib3\Math\BigInteger $x - * @return \phpseclib3\Math\BigInteger - */ - protected function exponentiate(BigInteger $x) - { - switch (true) { - case empty($this->primes): - case $this->primes[1]->equals(self::$zero): - case empty($this->coefficients): - case $this->coefficients[2]->equals(self::$zero): - case empty($this->exponents): - case $this->exponents[1]->equals(self::$zero): - return $x->modPow($this->exponent, $this->modulus); - } - - $num_primes = count($this->primes); - - if (!static::$enableBlinding) { - $m_i = [ - 1 => $x->modPow($this->exponents[1], $this->primes[1]), - 2 => $x->modPow($this->exponents[2], $this->primes[2]) - ]; - $h = $m_i[1]->subtract($m_i[2]); - $h = $h->multiply($this->coefficients[2]); - list(, $h) = $h->divide($this->primes[1]); - $m = $m_i[2]->add($h->multiply($this->primes[2])); - - $r = $this->primes[1]; - for ($i = 3; $i <= $num_primes; $i++) { - $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); - - $r = $r->multiply($this->primes[$i - 1]); - - $h = $m_i->subtract($m); - $h = $h->multiply($this->coefficients[$i]); - list(, $h) = $h->divide($this->primes[$i]); - - $m = $m->add($r->multiply($h)); - } - } else { - $smallest = $this->primes[1]; - for ($i = 2; $i <= $num_primes; $i++) { - if ($smallest->compare($this->primes[$i]) > 0) { - $smallest = $this->primes[$i]; - } - } - - $r = BigInteger::randomRange(self::$one, $smallest->subtract(self::$one)); - - $m_i = [ - 1 => $this->blind($x, $r, 1), - 2 => $this->blind($x, $r, 2) - ]; - $h = $m_i[1]->subtract($m_i[2]); - $h = $h->multiply($this->coefficients[2]); - list(, $h) = $h->divide($this->primes[1]); - $m = $m_i[2]->add($h->multiply($this->primes[2])); - - $r = $this->primes[1]; - for ($i = 3; $i <= $num_primes; $i++) { - $m_i = $this->blind($x, $r, $i); - - $r = $r->multiply($this->primes[$i - 1]); - - $h = $m_i->subtract($m); - $h = $h->multiply($this->coefficients[$i]); - list(, $h) = $h->divide($this->primes[$i]); - - $m = $m->add($r->multiply($h)); - } - } - - return $m; - } - - /** - * Performs RSA Blinding - * - * Protects against timing attacks by employing RSA Blinding. - * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) - * - * @access private - * @param \phpseclib3\Math\BigInteger $x - * @param \phpseclib3\Math\BigInteger $r - * @param int $i - * @return \phpseclib3\Math\BigInteger - */ - private function blind($x, $r, $i) - { - $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); - $x = $x->modPow($this->exponents[$i], $this->primes[$i]); - - $r = $r->modInverse($this->primes[$i]); - $x = $x->multiply($r); - list(, $x) = $x->divide($this->primes[$i]); - - return $x; - } - - /** - * EMSA-PSS-ENCODE - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. - * - * @return string - * @access private - * @param string $m - * @throws \RuntimeException on encoding error - * @param int $emBits - */ - private function emsa_pss_encode($m, $emBits) - { - // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) - $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; - - $mHash = $this->hash->hash($m); - if ($emLen < $this->hLen + $sLen + 2) { - throw new \LengthException('RSA modulus too short'); - } - - $salt = Random::string($sLen); - $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; - $h = $this->hash->hash($m2); - $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); - $db = $ps . chr(1) . $salt; - $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); - $maskedDB = $db ^ $dbMask; - $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; - $em = $maskedDB . $h . chr(0xBC); - - return $em; - } - - /** - * RSASSA-PSS-SIGN - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. - * - * @access private - * @param string $m - * @return bool|string - */ - private function rsassa_pss_sign($m) - { - // EMSA-PSS encoding - - $em = $this->emsa_pss_encode($m, 8 * $this->k - 1); - - // RSA signature - - $m = $this->os2ip($em); - $s = $this->rsasp1($m); - $s = $this->i2osp($s, $this->k); - - // Output the signature S - - return $s; - } - - /** - * RSASSA-PKCS1-V1_5-SIGN - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. - * - * @access private - * @param string $m - * @throws \LengthException if the RSA modulus is too short - * @return bool|string - */ - private function rsassa_pkcs1_v1_5_sign($m) - { - // EMSA-PKCS1-v1_5 encoding - - // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus - // too short" and stop. - try { - $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); - } catch (\LengthException $e) { - throw new \LengthException('RSA modulus too short'); - } - - // RSA signature - - $m = $this->os2ip($em); - $s = $this->rsasp1($m); - $s = $this->i2osp($s, $this->k); - - // Output the signature S - - return $s; - } - - /** - * Create a signature - * - * @see self::verify() - * @access public - * @param string $message - * @return string - */ - public function sign($message) - { - switch ($this->signaturePadding) { - case self::SIGNATURE_PKCS1: - case self::SIGNATURE_RELAXED_PKCS1: - return $this->rsassa_pkcs1_v1_5_sign($message); - //case self::SIGNATURE_PSS: - default: - return $this->rsassa_pss_sign($message); - } - } - - /** - * RSAES-PKCS1-V1_5-DECRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. - * - * @access private - * @param string $c - * @return bool|string - */ - private function rsaes_pkcs1_v1_5_decrypt($c) - { - // Length checking - - if (strlen($c) != $this->k) { // or if k < 11 - throw new \LengthException('Ciphertext representative too long'); - } - - // RSA decryption - - $c = $this->os2ip($c); - $m = $this->rsadp($c); - $em = $this->i2osp($m, $this->k); - - // EME-PKCS1-v1_5 decoding - - if (ord($em[0]) != 0 || ord($em[1]) > 2) { - throw new \RuntimeException('Decryption error'); - } - - $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); - $m = substr($em, strlen($ps) + 3); - - if (strlen($ps) < 8) { - throw new \RuntimeException('Decryption error'); - } - - // Output M - - return $m; - } - - /** - * RSAES-OAEP-DECRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error - * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: - * - * Note. Care must be taken to ensure that an opponent cannot - * distinguish the different error conditions in Step 3.g, whether by - * error message or timing, or, more generally, learn partial - * information about the encoded message EM. Otherwise an opponent may - * be able to obtain useful information about the decryption of the - * ciphertext C, leading to a chosen-ciphertext attack such as the one - * observed by Manger [36]. - * - * @access private - * @param string $c - * @return bool|string - */ - private function rsaes_oaep_decrypt($c) - { - // Length checking - - // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { - throw new \LengthException('Ciphertext representative too long'); - } - - // RSA decryption - - $c = $this->os2ip($c); - $m = $this->rsadp($c); - $em = $this->i2osp($m, $this->k); - - // EME-OAEP decoding - - $lHash = $this->hash->hash($this->label); - $y = ord($em[0]); - $maskedSeed = substr($em, 1, $this->hLen); - $maskedDB = substr($em, $this->hLen + 1); - $seedMask = $this->mgf1($maskedDB, $this->hLen); - $seed = $maskedSeed ^ $seedMask; - $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); - $db = $maskedDB ^ $dbMask; - $lHash2 = substr($db, 0, $this->hLen); - $m = substr($db, $this->hLen); - $hashesMatch = hash_equals($lHash, $lHash2); - $leadingZeros = 1; - $patternMatch = 0; - $offset = 0; - for ($i = 0; $i < strlen($m); $i++) { - $patternMatch|= $leadingZeros & ($m[$i] === "\1"); - $leadingZeros&= $m[$i] === "\0"; - $offset+= $patternMatch ? 0 : 1; - } - - // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation - // to protect against timing attacks - if (!$hashesMatch & !$patternMatch) { - throw new \RuntimeException('Decryption error'); - } - - // Output the message M - - return substr($m, $offset + 1); - } - - /** - * Raw Encryption / Decryption - * - * Doesn't use padding and is not recommended. - * - * @access private - * @param string $m - * @return bool|string - * @throws \LengthException if strlen($m) > $this->k - */ - private function raw_encrypt($m) - { - if (strlen($m) > $this->k) { - throw new \LengthException('Ciphertext representative too long'); - } - - $temp = $this->os2ip($m); - $temp = $this->rsadp($temp); - return $this->i2osp($temp, $this->k); - } - - /** - * Decryption - * - * @see self::encrypt() - * @access public - * @param string $ciphertext - * @return bool|string - */ - public function decrypt($ciphertext) - { - switch ($this->encryptionPadding) { - case self::ENCRYPTION_NONE: - return $this->raw_encrypt($ciphertext); - case self::ENCRYPTION_PKCS1: - return $this->rsaes_pkcs1_v1_5_decrypt($ciphertext); - //case self::ENCRYPTION_OAEP: - default: - return $this->rsaes_oaep_decrypt($ciphertext); - } - } - - /** - * Returns the public key - * - * @access public - * @return mixed - */ - public function getPublicKey() - { - $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); - if (empty($this->modulus) || empty($this->publicExponent)) { - throw new \RuntimeException('Public key components not found'); - } - - $key = $type::savePublicKey($this->modulus, $this->publicExponent); - return RSA::loadFormat('PKCS8', $key) - ->withHash($this->hash->getHash()) - ->withMGFHash($this->mgfHash->getHash()) - ->withSaltLength($this->sLen) - ->withLabel($this->label) - ->withPadding($this->signaturePadding | $this->encryptionPadding); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin( - 'Keys', - $type, - empty($this->primes) ? 'savePublicKey' : 'savePrivateKey' - ); - - if ($type == PSS::class) { - if ($this->signaturePadding == self::SIGNATURE_PSS) { - $options+= [ - 'hash' => $this->hash->getHash(), - 'MGFHash' => $this->mgfHash->getHash(), - 'saltLength' => $this->getSaltLength() - ]; - } else { - throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); - } - } - - if (empty($this->primes)) { - return $type::savePublicKey($this->modulus, $this->exponent, $options); - } - - return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); - - /* - $key = $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); - if ($key !== false || count($this->primes) == 2) { - return $key; - } - - $nSize = $this->getSize() >> 1; - - $primes = [1 => clone self::$one, clone self::$one]; - $i = 1; - foreach ($this->primes as $prime) { - $primes[$i] = $primes[$i]->multiply($prime); - if ($primes[$i]->getLength() >= $nSize) { - $i++; - } - } - - $exponents = []; - $coefficients = [2 => $primes[2]->modInverse($primes[1])]; - - foreach ($primes as $i => $prime) { - $temp = $prime->subtract(self::$one); - $exponents[$i] = $this->modulus->modInverse($temp); - } - - return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $primes, $exponents, $coefficients, $this->password, $options); - */ - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php deleted file mode 100644 index 3475ad999..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php +++ /dev/null @@ -1,507 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA; - -use phpseclib3\Crypt\RSA; -use phpseclib3\Math\BigInteger; -use phpseclib3\File\ASN1; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Hash; -use phpseclib3\Exception\NoKeyLoadedException; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\Common; -use phpseclib3\File\ASN1\Maps\DigestInfo; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; - -/** - * Raw RSA Key Handler - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -class PublicKey extends RSA implements Common\PublicKey -{ - use Common\Traits\Fingerprint; - - /** - * Exponentiate - * - * @param \phpseclib3\Math\BigInteger $x - * @return \phpseclib3\Math\BigInteger - */ - private function exponentiate(BigInteger $x) - { - return $x->modPow($this->exponent, $this->modulus); - } - - /** - * RSAVP1 - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. - * - * @access private - * @param \phpseclib3\Math\BigInteger $s - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsavp1($s) - { - if ($s->compare(self::$zero) < 0 || $s->compare($this->modulus) > 0) { - return false; - } - return $this->exponentiate($s); - } - - /** - * RSASSA-PKCS1-V1_5-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. - * - * @access private - * @param string $m - * @param string $s - * @throws \LengthException if the RSA modulus is too short - * @return bool - */ - private function rsassa_pkcs1_v1_5_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - return false; - } - - // RSA verification - - $s = $this->os2ip($s); - $m2 = $this->rsavp1($s); - if ($m2 === false) { - return false; - } - $em = $this->i2osp($m2, $this->k); - if ($em === false) { - return false; - } - - // EMSA-PKCS1-v1_5 encoding - - // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus - // too short" and stop. - try { - $em2 = $this->emsa_pkcs1_v1_5_encode($m, $this->k); - } catch (\LengthException $e) { - throw new \LengthException('RSA modulus too short'); - } - - // Compare - return hash_equals($em, $em2); - } - - /** - * RSASSA-PKCS1-V1_5-VERIFY (relaxed matching) - * - * Per {@link http://tools.ietf.org/html/rfc3447#page-43 RFC3447#page-43} PKCS1 v1.5 - * specified the use BER encoding rather than DER encoding that PKCS1 v2.0 specified. - * This means that under rare conditions you can have a perfectly valid v1.5 signature - * that fails to validate with _rsassa_pkcs1_v1_5_verify(). PKCS1 v2.1 also recommends - * that if you're going to validate these types of signatures you "should indicate - * whether the underlying BER encoding is a DER encoding and hence whether the signature - * is valid with respect to the specification given in [PKCS1 v2.0+]". so if you do - * $rsa->getLastPadding() and get RSA::PADDING_RELAXED_PKCS1 back instead of - * RSA::PADDING_PKCS1... that means BER encoding was used. - * - * @access private - * @param string $m - * @param string $s - * @return bool - */ - private function rsassa_pkcs1_v1_5_relaxed_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - return false; - } - - // RSA verification - - $s = $this->os2ip($s); - $m2 = $this->rsavp1($s); - if ($m2 === false) { - return false; - } - $em = $this->i2osp($m2, $this->k); - if ($em === false) { - return false; - } - - if (Strings::shift($em, 2) != "\0\1") { - return false; - } - - $em = ltrim($em, "\xFF"); - if (Strings::shift($em) != "\0") { - return false; - } - - $decoded = ASN1::decodeBER($em); - if (!is_array($decoded) || empty($decoded[0]) || strlen($em) > $decoded[0]['length']) { - return false; - } - - static $oids; - if (!isset($oids)) { - $oids = [ - 'md2' => '1.2.840.113549.2.2', - 'md4' => '1.2.840.113549.2.4', // from PKCS1 v1.5 - 'md5' => '1.2.840.113549.2.5', - 'id-sha1' => '1.3.14.3.2.26', - 'id-sha256' => '2.16.840.1.101.3.4.2.1', - 'id-sha384' => '2.16.840.1.101.3.4.2.2', - 'id-sha512' => '2.16.840.1.101.3.4.2.3', - // from PKCS1 v2.2 - 'id-sha224' => '2.16.840.1.101.3.4.2.4', - 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', - 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', - ]; - ASN1::loadOIDs($oids); - } - - $decoded = ASN1::asn1map($decoded[0], DigestInfo::MAP); - if (!isset($decoded) || $decoded === false) { - return false; - } - - if (!isset($oids[$decoded['digestAlgorithm']['algorithm']])) { - return false; - } - - $hash = $decoded['digestAlgorithm']['algorithm']; - $hash = substr($hash, 0, 3) == 'id-' ? - substr($hash, 3) : - $hash; - $hash = new Hash($hash); - $em = $hash->hash($m); - $em2 = $decoded['digest']; - - return hash_equals($em, $em2); - } - - /** - * EMSA-PSS-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. - * - * @access private - * @param string $m - * @param string $em - * @param int $emBits - * @return string - */ - private function emsa_pss_verify($m, $em, $emBits) - { - // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); - $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; - - $mHash = $this->hash->hash($m); - if ($emLen < $this->hLen + $sLen + 2) { - return false; - } - - if ($em[strlen($em) - 1] != chr(0xBC)) { - return false; - } - - $maskedDB = substr($em, 0, -$this->hLen - 1); - $h = substr($em, -$this->hLen - 1, $this->hLen); - $temp = chr(0xFF << ($emBits & 7)); - if ((~$maskedDB[0] & $temp) != $temp) { - return false; - } - $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); - $db = $maskedDB ^ $dbMask; - $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; - $temp = $emLen - $this->hLen - $sLen - 2; - if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { - return false; - } - $salt = substr($db, $temp + 1); // should be $sLen long - $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; - $h2 = $this->hash->hash($m2); - return hash_equals($h, $h2); - } - - /** - * RSASSA-PSS-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. - * - * @access private - * @param string $m - * @param string $s - * @return bool|string - */ - private function rsassa_pss_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - return false; - } - - // RSA verification - - $modBits = strlen($this->modulus->toBits()); - - $s2 = $this->os2ip($s); - $m2 = $this->rsavp1($s2); - $em = $this->i2osp($m2, $this->k); - if ($em === false) { - return false; - } - - // EMSA-PSS verification - - return $this->emsa_pss_verify($m, $em, $modBits - 1); - } - - /** - * Verifies a signature - * - * @see self::sign() - * @param string $message - * @param string $signature - * @return bool - */ - public function verify($message, $signature) - { - switch ($this->signaturePadding) { - case self::SIGNATURE_RELAXED_PKCS1: - return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature); - case self::SIGNATURE_PKCS1: - return $this->rsassa_pkcs1_v1_5_verify($message, $signature); - //case self::SIGNATURE_PSS: - default: - return $this->rsassa_pss_verify($message, $signature); - } - } - - /** - * RSAES-PKCS1-V1_5-ENCRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. - * - * @access private - * @param string $m - * @param bool $pkcs15_compat optional - * @throws \LengthException if strlen($m) > $this->k - 11 - * @return bool|string - */ - private function rsaes_pkcs1_v1_5_encrypt($m, $pkcs15_compat = false) - { - $mLen = strlen($m); - - // Length checking - - if ($mLen > $this->k - 11) { - throw new \LengthException('Message too long'); - } - - // EME-PKCS1-v1_5 encoding - - $psLen = $this->k - $mLen - 3; - $ps = ''; - while (strlen($ps) != $psLen) { - $temp = Random::string($psLen - strlen($ps)); - $temp = str_replace("\x00", '', $temp); - $ps.= $temp; - } - $type = 2; - $em = chr(0) . chr($type) . $ps . chr(0) . $m; - - // RSA encryption - $m = $this->os2ip($em); - $c = $this->rsaep($m); - $c = $this->i2osp($c, $this->k); - - // Output the ciphertext C - - return $c; - } - - /** - * RSAES-OAEP-ENCRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and - * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. - * - * @access private - * @param string $m - * @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 - * @return string - */ - private function rsaes_oaep_encrypt($m) - { - $mLen = strlen($m); - - // Length checking - - // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - if ($mLen > $this->k - 2 * $this->hLen - 2) { - throw new \LengthException('Message too long'); - } - - // EME-OAEP encoding - - $lHash = $this->hash->hash($this->label); - $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); - $db = $lHash . $ps . chr(1) . $m; - $seed = Random::string($this->hLen); - $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); - $maskedDB = $db ^ $dbMask; - $seedMask = $this->mgf1($maskedDB, $this->hLen); - $maskedSeed = $seed ^ $seedMask; - $em = chr(0) . $maskedSeed . $maskedDB; - - // RSA encryption - - $m = $this->os2ip($em); - $c = $this->rsaep($m); - $c = $this->i2osp($c, $this->k); - - // Output the ciphertext C - - return $c; - } - - /** - * RSAEP - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. - * - * @access private - * @param \phpseclib3\Math\BigInteger $m - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsaep($m) - { - if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { - throw new \OutOfRangeException('Message representative out of range'); - } - return $this->exponentiate($m); - } - - /** - * Raw Encryption / Decryption - * - * Doesn't use padding and is not recommended. - * - * @access private - * @param string $m - * @return bool|string - * @throws \LengthException if strlen($m) > $this->k - */ - private function raw_encrypt($m) - { - if (strlen($m) > $this->k) { - throw new \LengthException('Message too long'); - } - - $temp = $this->os2ip($m); - $temp = $this->rsaep($temp); - return $this->i2osp($temp, $this->k); - } - - /** - * Encryption - * - * Both self::PADDING_OAEP and self::PADDING_PKCS1 both place limits on how long $plaintext can be. - * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will - * be concatenated together. - * - * @see self::decrypt() - * @access public - * @param string $plaintext - * @return bool|string - * @throws \LengthException if the RSA modulus is too short - */ - public function encrypt($plaintext) - { - switch ($this->encryptionPadding) { - case self::ENCRYPTION_NONE: - return $this->raw_encrypt($plaintext); - case self::ENCRYPTION_PKCS1: - return $this->rsaes_pkcs1_v1_5_encrypt($plaintext); - //case self::ENCRYPTION_OAEP: - default: - return $this->rsaes_oaep_encrypt($plaintext); - } - } - - /** - * Returns the public key - * - * The public key is only returned under two circumstances - if the private key had the public key embedded within it - * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this - * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. - * - * @param string $type - * @param array $options optional - * @return mixed - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - if ($type == PSS::class) { - if ($this->signaturePadding == self::SIGNATURE_PSS) { - $options+= [ - 'hash' => $this->hash->getHash(), - 'MGFHash' => $this->mgfHash->getHash(), - 'saltLength' => $this->getSaltLength() - ]; - } else { - throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); - } - } - - return $type::savePublicKey($this->modulus, $this->publicExponent, $options); - } - - /** - * Converts a public key to a private key - * - * @return RSA - */ - public function asPrivateKey() - { - $new = new PrivateKey; - $new->exponent = $this->exponent; - $new->modulus = $this->modulus; - $new->k = $this->k; - $new->format = $this->format; - return $new - ->withHash($this->hash->getHash()) - ->withMGFHash($this->mgfHash->getHash()) - ->withSaltLength($this->sLen) - ->withLabel($this->label) - ->withPadding($this->signaturePadding | $this->encryptionPadding); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php index b05f040eb..8f53eb319 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php @@ -10,7 +10,7 @@ * * * @@ -22,7 +22,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; +namespace phpseclib\Crypt; /** * Pure-PHP Random Number Generator @@ -31,7 +31,7 @@ namespace phpseclib3\Crypt; * @author Jim Wigginton * @access public */ -abstract class Random +class Random { /** * Generate a random string. @@ -41,26 +41,75 @@ abstract class Random * eg. for RSA key generation. * * @param int $length - * @throws \RuntimeException if a symmetric cipher is needed but not loaded * @return string */ - public static function string($length) + static function string($length) { if (!$length) { return ''; } - try { - return \random_bytes($length); - } catch (\Exception $e) { - // random_compat will throw an Exception, which in PHP 5 does not implement Throwable - } catch (\Throwable $e) { - // If a sufficient source of randomness is unavailable, random_bytes() will throw an - // object that implements the Throwable interface (Exception, TypeError, Error). - // We don't actually need to do anything here. The string() method should just continue - // as normal. Note, however, that if we don't have a sufficient source of randomness for - // random_bytes(), most of the other calls here will fail too, so we'll end up using - // the PHP implementation. + if (version_compare(PHP_VERSION, '7.0.0', '>=')) { + try { + return \random_bytes($length); + } catch (\Throwable $e) { + // If a sufficient source of randomness is unavailable, random_bytes() will throw an + // object that implements the Throwable interface (Exception, TypeError, Error). + // We don't actually need to do anything here. The string() method should just continue + // as normal. Note, however, that if we don't have a sufficient source of randomness for + // random_bytes(), most of the other calls here will fail too, so we'll end up using + // the PHP implementation. + } + } + + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { + // method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call. + // ie. class_alias is a function that was introduced in PHP 5.3 + if (extension_loaded('mcrypt') && function_exists('class_alias')) { + return @mcrypt_create_iv($length); + } + // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was, + // to quote , "possible blocking behavior". as of 5.3.4 + // openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both + // call php_win32_get_random_bytes(): + // + // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008 + // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392 + // + // php_win32_get_random_bytes() is defined thusly: + // + // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80 + // + // we're calling it, all the same, in the off chance that the mcrypt extension is not available + if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) { + return openssl_random_pseudo_bytes($length); + } + } else { + // method 1. the fastest + if (extension_loaded('openssl')) { + return openssl_random_pseudo_bytes($length); + } + // method 2 + static $fp = true; + if ($fp === true) { + // warning's will be output unles the error suppression operator is used. errors such as + // "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc. + $fp = @fopen('/dev/urandom', 'rb'); + } + if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource() + $temp = fread($fp, $length); + if (strlen($temp) == $length) { + return $temp; + } + } + // method 3. pretty much does the same thing as method 2 per the following url: + // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391 + // surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're + // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir + // restrictions or some such + if (extension_loaded('mcrypt')) { + return @mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); + } } // at this point we have no choice but to use a pure-PHP CSPRNG @@ -73,11 +122,11 @@ abstract class Random // PHP isn't low level to be able to use those as sources and on a web server there's not likely // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use // however, a ton of people visiting the website. obviously you don't want to base your seeding - // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled + // soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled // by the user and (2) this isn't just looking at the data sent by the current user - it's based // on the data sent by all users. one user requests the page and a hash of their info is saved. // another user visits the page and the serialization of their data is utilized along with the - // server environment stuff and a hash of the previous http request data (which itself utilizes + // server envirnment stuff and a hash of the previous http request data (which itself utilizes // a hash of the session data before that). certainly an attacker should be assumed to have // full control over his own http requests. he, however, is not going to have control over // everyone's http requests. @@ -97,14 +146,15 @@ abstract class Random session_cache_limiter(''); session_start(); - $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . - (isset($_POST) ? self::safe_serialize($_POST) : '') . - (isset($_GET) ? self::safe_serialize($_GET) : '') . - (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') . - self::safe_serialize($GLOBALS) . - self::safe_serialize($_SESSION) . - self::safe_serialize($_OLD_SESSION); - $v = $seed = $_SESSION['seed'] = sha1($v, true); + $v = $seed = $_SESSION['seed'] = pack('H*', sha1( + (isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') . + (isset($_POST) ? phpseclib_safe_serialize($_POST) : '') . + (isset($_GET) ? phpseclib_safe_serialize($_GET) : '') . + (isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') . + phpseclib_safe_serialize($GLOBALS) . + phpseclib_safe_serialize($_SESSION) . + phpseclib_safe_serialize($_OLD_SESSION) + )); if (!isset($_SESSION['count'])) { $_SESSION['count'] = 0; } @@ -135,37 +185,38 @@ abstract class Random // http://tools.ietf.org/html/rfc4253#section-7.2 // // see the is_string($crypto) part for an example of how to expand the keys - $key = sha1($seed . 'A', true); - $iv = sha1($seed . 'C', true); + $key = pack('H*', sha1($seed . 'A')); + $iv = pack('H*', sha1($seed . 'C')); // ciphers are used as per the nist.gov link below. also, see this link: // // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives switch (true) { - case class_exists('\phpseclib3\Crypt\AES'): - $crypto = new AES('ctr'); + case class_exists('\phpseclib\Crypt\AES'): + $crypto = new AES(Base::MODE_CTR); break; - case class_exists('\phpseclib3\Crypt\Twofish'): - $crypto = new Twofish('ctr'); + case class_exists('\phpseclib\Crypt\Twofish'): + $crypto = new Twofish(Base::MODE_CTR); break; - case class_exists('\phpseclib3\Crypt\Blowfish'): - $crypto = new Blowfish('ctr'); + case class_exists('\phpseclib\Crypt\Blowfish'): + $crypto = new Blowfish(Base::MODE_CTR); break; - case class_exists('\phpseclib3\Crypt\TripleDES'): - $crypto = new TripleDES('ctr'); + case class_exists('\phpseclib\Crypt\TripleDES'): + $crypto = new TripleDES(Base::MODE_CTR); break; - case class_exists('\phpseclib3\Crypt\DES'): - $crypto = new DES('ctr'); + case class_exists('\phpseclib\Crypt\DES'): + $crypto = new DES(Base::MODE_CTR); break; - case class_exists('\phpseclib3\Crypt\RC4'): + case class_exists('\phpseclib\Crypt\RC4'): $crypto = new RC4(); break; default: - throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); + user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded'); + return false; } - $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3)); - $crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3)); + $crypto->setKey($key); + $crypto->setIV($iv); $crypto->enableContinuousBuffer(); } @@ -186,18 +237,21 @@ abstract class Random $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20 $result.= $r; } - return substr($result, 0, $length); } +} +if (!function_exists('phpseclib_safe_serialize')) { /** * Safely serialize variables * - * If a class has a private __sleep() it'll emit a warning - * @return mixed + * If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier. + * PHP 5.3 will emit a warning. + * * @param mixed $arr + * @access public */ - private static function safe_serialize(&$arr) + function phpseclib_safe_serialize(&$arr) { if (is_object($arr)) { return ''; @@ -209,12 +263,12 @@ abstract class Random if (isset($arr['__phpseclib_marker'])) { return ''; } - $safearr = []; + $safearr = array(); $arr['__phpseclib_marker'] = true; foreach (array_keys($arr) as $key) { // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage if ($key !== '__phpseclib_marker') { - $safearr[$key] = self::safe_serialize($arr[$key]); + $safearr[$key] = phpseclib_safe_serialize($arr[$key]); } } unset($arr['__phpseclib_marker']); diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php index fb1edcf6e..3648a1972 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php @@ -30,7 +30,7 @@ * setKey('abcdefghijklmnop'); * @@ -52,14 +52,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\BadModeException; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\BadDecryptionException; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of Rijndael. @@ -68,69 +61,77 @@ use phpseclib3\Exception\BadDecryptionException; * @author Jim Wigginton * @access public */ -class Rijndael extends BlockCipher +class Rijndael extends Base { /** * The mcrypt specific name of the cipher * * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. - * \phpseclib3\Crypt\Rijndael determines automatically whether mcrypt is useable + * \phpseclib\Crypt\Rijndael determines automatically whether mcrypt is useable * or not for the current $block_size/$key_length. * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @see \phpseclib3\Crypt\Common\SymmetricKey::engine + * @see \phpseclib\Crypt\Base::cipher_name_mcrypt + * @see \phpseclib\Crypt\Base::engine * @see self::isValidEngine() * @var string * @access private */ - protected $cipher_name_mcrypt = 'rijndael-128'; + var $cipher_name_mcrypt = 'rijndael-128'; + + /** + * The default salt used by setPassword() + * + * @see \phpseclib\Crypt\Base::password_default_salt + * @see \phpseclib\Crypt\Base::setPassword() + * @var string + * @access private + */ + var $password_default_salt = 'phpseclib'; /** * The Key Schedule * - * @see self::setup() + * @see self::_setup() * @var array * @access private */ - private $w; + var $w; /** * The Inverse Key Schedule * - * @see self::setup() + * @see self::_setup() * @var array * @access private */ - private $dw; + var $dw; /** * The Block Length divided by 32 * - * {@internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size - * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could - * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once.} - * * @see self::setBlockLength() * @var int * @access private + * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size + * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could + * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once. */ - private $Nb = 4; + var $Nb = 4; /** * The Key Length (in bytes) * - * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk - * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could - * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once.} - * * @see self::setKeyLength() * @var int * @access private + * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once. */ - protected $key_length = 16; + var $key_length = 16; /** * The Key Length divided by 32 @@ -140,17 +141,16 @@ class Rijndael extends BlockCipher * @access private * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 */ - private $Nk = 4; + var $Nk = 4; /** * The Number of Rounds * - * {@internal The max value is 14, the min value is 10.} - * * @var int * @access private + * @internal The max value is 14, the min value is 10. */ - private $Nr; + var $Nr; /** * Shift offsets @@ -158,7 +158,7 @@ class Rijndael extends BlockCipher * @var array * @access private */ - private $c; + var $c; /** * Holds the last used key- and block_size information @@ -166,28 +166,13 @@ class Rijndael extends BlockCipher * @var array * @access private */ - private $kl; - - /** - * Default Constructor. - * - * @param string $mode - * @access public - * @throws \InvalidArgumentException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } + var $kl; /** * Sets the key length. * - * Valid key lengths are 128, 160, 192, 224, and 256. + * Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to + * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. * * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to @@ -201,114 +186,72 @@ class Rijndael extends BlockCipher * This results then in slower encryption. * * @access public - * @throws \LengthException if the key length is invalid * @param int $length */ - public function setKeyLength($length) + function setKeyLength($length) { - switch ($length) { - case 128: - case 160: - case 192: - case 224: - case 256: - $this->key_length = $length >> 3; + switch (true) { + case $length <= 128: + $this->key_length = 16; break; - default: - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); - } - - parent::setKeyLength($length); - } - - /** - * Sets the key. - * - * Rijndael supports five different key lengths - * - * @see setKeyLength() - * @access public - * @param string $key - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key) - { - switch (strlen($key)) { - case 16: - case 20: - case 24: - case 28: - case 32: + case $length <= 160: + $this->key_length = 20; + break; + case $length <= 192: + $this->key_length = 24; + break; + case $length <= 224: + $this->key_length = 28; break; default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); + $this->key_length = 32; } - parent::setKey($key); + parent::setKeyLength($length); } /** * Sets the block length * - * Valid block lengths are 128, 160, 192, 224, and 256. + * Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to + * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. * * @access public * @param int $length */ - public function setBlockLength($length) + function setBlockLength($length) { - switch ($length) { - case 128: - case 160: - case 192: - case 224: - case 256: - break; - default: - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); - } - - $this->Nb = $length >> 5; - $this->block_size = $length >> 3; - $this->changed = $this->nonIVChanged = true; - $this->setEngine(); + $length >>= 5; + if ($length > 8) { + $length = 8; + } elseif ($length < 4) { + $length = 4; + } + $this->Nb = $length; + $this->block_size = $length << 2; + $this->changed = true; + $this->_setEngine(); } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @see \phpseclib\Crypt\Base::__construct() * @param int $engine - * @access protected + * @access public * @return bool */ - protected function isValidEngineHelper($engine) + function isValidEngine($engine) { switch ($engine) { - case self::ENGINE_LIBSODIUM: - return function_exists('sodium_crypto_aead_aes256gcm_is_available') && - sodium_crypto_aead_aes256gcm_is_available() && - $this->mode == self::MODE_GCM && - $this->key_length == 32 && - $this->nonce && strlen($this->nonce) == 12 && - $this->block_size == 16; - case self::ENGINE_OPENSSL_GCM: - if (!extension_loaded('openssl')) { - return false; - } - $methods = openssl_get_cipher_methods(); - return $this->mode == self::MODE_GCM && - version_compare(PHP_VERSION, '7.1.0', '>=') && - in_array('aes-' . $this->getKeyLength() . '-gcm', $methods) && - $this->block_size == 16; case self::ENGINE_OPENSSL: if ($this->block_size != 16) { return false; } - self::$cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; - $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->openssl_translate_mode(); + $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; + $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode(); break; case self::ENGINE_MCRYPT: $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); @@ -318,7 +261,7 @@ class Rijndael extends BlockCipher } } - return parent::isValidEngineHelper($engine); + return parent::isValidEngine($engine); } /** @@ -328,11 +271,11 @@ class Rijndael extends BlockCipher * @param string $in * @return string */ - protected function encryptBlock($in) + function _encryptBlock($in) { static $tables; if (empty($tables)) { - $tables = &$this->getTables(); + $tables = &$this->_getTables(); } $t0 = $tables[0]; $t1 = $tables[1]; @@ -340,7 +283,7 @@ class Rijndael extends BlockCipher $t3 = $tables[3]; $sbox = $tables[4]; - $state = []; + $state = array(); $words = unpack('N*', $in); $c = $this->c; @@ -362,7 +305,7 @@ class Rijndael extends BlockCipher // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf - $temp = []; + $temp = array(); for ($round = 1; $round < $Nr; ++$round) { $i = 0; // $c[0] == 0 $j = $c[1]; @@ -408,7 +351,18 @@ class Rijndael extends BlockCipher $l = ($l + 1) % $Nb; } - return pack('N*', ...$temp); + switch ($Nb) { + case 8: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]); + case 7: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]); + case 6: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]); + case 5: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]); + default: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]); + } } /** @@ -418,11 +372,11 @@ class Rijndael extends BlockCipher * @param string $in * @return string */ - protected function decryptBlock($in) + function _decryptBlock($in) { static $invtables; if (empty($invtables)) { - $invtables = &$this->getInvTables(); + $invtables = &$this->_getInvTables(); } $dt0 = $invtables[0]; $dt1 = $invtables[1]; @@ -430,7 +384,7 @@ class Rijndael extends BlockCipher $dt3 = $invtables[3]; $isbox = $invtables[4]; - $state = []; + $state = array(); $words = unpack('N*', $in); $c = $this->c; @@ -444,7 +398,7 @@ class Rijndael extends BlockCipher $state[] = $word ^ $dw[++$wc]; } - $temp = []; + $temp = array(); for ($round = $Nr - 1; $round > 0; --$round) { $i = 0; // $c[0] == 0 $j = $Nb - $c[1]; @@ -487,33 +441,44 @@ class Rijndael extends BlockCipher $l = ($l + 1) % $Nb; } - return pack('N*', ...$temp); + switch ($Nb) { + case 8: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]); + case 7: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]); + case 6: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]); + case 5: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]); + default: + return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]); + } } /** * Setup the key (expansion) * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @see \phpseclib\Crypt\Base::_setupKey() * @access private */ - protected function setupKey() + function _setupKey() { // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse - static $rcon = [0, + static $rcon = array(0, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 - ]; + ); if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { // already expanded return; } - $this->kl = ['key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size]; + $this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size); $this->Nk = $this->key_length >> 2; // see Rijndael-ammended.pdf#page=44 @@ -527,13 +492,13 @@ class Rijndael extends BlockCipher case 4: case 5: case 6: - $this->c = [0, 1, 2, 3]; + $this->c = array(0, 1, 2, 3); break; case 7: - $this->c = [0, 1, 2, 4]; + $this->c = array(0, 1, 2, 4); break; case 8: - $this->c = [0, 1, 3, 4]; + $this->c = array(0, 1, 3, 4); } $w = array_values(unpack('N*words', $this->key)); @@ -547,9 +512,9 @@ class Rijndael extends BlockCipher // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord - $temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk]; + $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk]; } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { - $temp = $this->subWord($temp); + $temp = $this->_subWord($temp); } $w[$i] = $w[$i - $this->Nk] ^ $temp; } @@ -561,8 +526,8 @@ class Rijndael extends BlockCipher // 1. Apply the Key Expansion. // 2. Apply InvMixColumn to all Round Keys except the first and the last one." // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" - list($dt0, $dt1, $dt2, $dt3) = $this->getInvTables(); - $temp = $this->w = $this->dw = []; + list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables(); + $temp = $this->w = $this->dw = array(); for ($i = $row = $col = 0; $i < $length; $i++, $col++) { if ($col == $this->Nb) { if ($row == 0) { @@ -571,7 +536,7 @@ class Rijndael extends BlockCipher // subWord + invMixColumn + invSubWord = invMixColumn $j = 0; while ($j < $this->Nb) { - $dw = $this->subWord($this->w[$row][$j]); + $dw = $this->_subWord($this->w[$row][$j]); $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^ $dt1[$dw >> 16 & 0x000000FF] ^ $dt2[$dw >> 8 & 0x000000FF] ^ @@ -606,15 +571,14 @@ class Rijndael extends BlockCipher /** * Performs S-Box substitutions * - * @return array * @access private * @param int $word */ - private function subWord($word) + function _subWord($word) { static $sbox; if (empty($sbox)) { - list(, , , , $sbox) = self::getTables(); + list(, , , , $sbox) = $this->_getTables(); } return $sbox[$word & 0x000000FF] | @@ -626,20 +590,20 @@ class Rijndael extends BlockCipher /** * Provides the mixColumns and sboxes tables * - * @see self::encryptBlock() - * @see self::setupInlineCrypt() - * @see self::subWord() + * @see self::_encryptBlock() + * @see self::_setupInlineCrypt() + * @see self::_subWord() * @access private * @return array &$tables */ - protected function &getTables() + function &_getTables() { static $tables; if (empty($tables)) { // according to (section 5.2.1), // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so // those are the names we'll use. - $t3 = array_map('intval', [ + $t3 = array_map('intval', array( // with array_map('intval', ...) we ensure we have only int's and not // some slower floats converted by php automatically on high values 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, @@ -674,7 +638,7 @@ class Rijndael extends BlockCipher 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C - ]); + )); foreach ($t3 as $t3i) { $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF); @@ -682,14 +646,14 @@ class Rijndael extends BlockCipher $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF); } - $tables = [ + $tables = array( // The Precomputed mixColumns tables t0 - t3 $t0, $t1, $t2, $t3, // The SubByte S-Box - [ + array( 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, @@ -706,8 +670,8 @@ class Rijndael extends BlockCipher 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 - ] - ]; + ) + ); } return $tables; } @@ -715,17 +679,17 @@ class Rijndael extends BlockCipher /** * Provides the inverse mixColumns and inverse sboxes tables * - * @see self::decryptBlock() - * @see self::setupInlineCrypt() - * @see self::setupKey() + * @see self::_decryptBlock() + * @see self::_setupInlineCrypt() + * @see self::_setupKey() * @access private * @return array &$tables */ - protected function &getInvTables() + function &_getInvTables() { static $tables; if (empty($tables)) { - $dt3 = array_map('intval', [ + $dt3 = array_map('intval', array( 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, @@ -758,7 +722,7 @@ class Rijndael extends BlockCipher 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 - ]); + )); foreach ($dt3 as $dt3i) { $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF); @@ -766,14 +730,14 @@ class Rijndael extends BlockCipher $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF); }; - $tables = [ + $tables = array( // The Precomputed inverse mixColumns tables dt0 - dt3 $dt0, $dt1, $dt2, $dt3, // The inverse SubByte S-Box - [ + array( 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, @@ -790,8 +754,8 @@ class Rijndael extends BlockCipher 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D - ] - ]; + ) + ); } return $tables; } @@ -799,224 +763,174 @@ class Rijndael extends BlockCipher /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + * @see \phpseclib\Crypt\Base::_setupInlineCrypt() * @access private */ - protected function setupInlineCrypt() + function _setupInlineCrypt() { - $w = $this->w; - $dw = $this->dw; - $init_encrypt = ''; - $init_decrypt = ''; + // Note: _setupInlineCrypt() will be called only if $this->changed === true + // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt(). + // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible. + + $lambda_functions =& self::_getLambdaFunctions(); + + // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. + // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit) + // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. + $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); + + // Generation of a uniqe hash for our generated code + $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); + } + + if (!isset($lambda_functions[$code_hash])) { + switch (true) { + case $gen_hi_opt_code: + // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance. + $w = $this->w; + $dw = $this->dw; + $init_encrypt = ''; + $init_decrypt = ''; + break; + default: + for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) { + $w[] = '$w[' . $i . ']'; + $dw[] = '$dw[' . $i . ']'; + } + $init_encrypt = '$w = $self->w;'; + $init_decrypt = '$dw = $self->dw;'; + } - $Nr = $this->Nr; - $Nb = $this->Nb; - $c = $this->c; + $Nr = $this->Nr; + $Nb = $this->Nb; + $c = $this->c; - // Generating encrypt code: - $init_encrypt.= ' - static $tables; - if (empty($tables)) { - $tables = &$this->getTables(); + // Generating encrypt code: + $init_encrypt.= ' + static $tables; + if (empty($tables)) { + $tables = &$self->_getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + '; + + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $encrypt_block = '$in = unpack("N*", $in);'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n"; } - $t0 = $tables[0]; - $t1 = $tables[1]; - $t2 = $tables[2]; - $t3 = $tables[3]; - $sbox = $tables[4]; - '; - - $s = 'e'; - $e = 's'; - $wc = $Nb - 1; - // Preround: addRoundKey - $encrypt_block = '$in = unpack("N*", $in);'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n"; - } + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = array($e, $s); + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block.= + '$'.$e.$i.' = + $t0[($'.$s.$i .' >> 24) & 0xff] ^ + $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^ + $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^ + $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^ + '.$w[++$wc].";\n"; + } + } - // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey - for ($round = 1; $round < $Nr; ++$round) { - list($s, $e) = [$e, $s]; + // Finalround: subWord + shiftRows + addRoundKey for ($i = 0; $i < $Nb; ++$i) { $encrypt_block.= '$'.$e.$i.' = - $t0[($'.$s.$i .' >> 24) & 0xff] ^ - $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^ - $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^ - $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^ - '.$w[++$wc].";\n"; + $sbox[ $'.$e.$i.' & 0xff] | + ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) | + ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) | + ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; } - } - - // Finalround: subWord + shiftRows + addRoundKey - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block.= - '$'.$e.$i.' = - $sbox[ $'.$e.$i.' & 0xff] | - ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) | - ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) | - ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; - } - $encrypt_block .= '$in = pack("N*"'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block.= ', - ($'.$e.$i .' & '.((int)0xFF000000).') ^ - ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^ - ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^ - ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^ - '.$w[$i]."\n"; - } - $encrypt_block .= ');'; + $encrypt_block .= '$in = pack("N*"'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block.= ', + ($'.$e.$i .' & '.((int)0xFF000000).') ^ + ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^ + ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^ + ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^ + '.$w[$i]."\n"; + } + $encrypt_block .= ');'; - // Generating decrypt code: - $init_decrypt.= ' - static $invtables; - if (empty($invtables)) { - $invtables = &$this->getInvTables(); + // Generating decrypt code: + $init_decrypt.= ' + static $invtables; + if (empty($invtables)) { + $invtables = &$self->_getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + '; + + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $decrypt_block = '$in = unpack("N*", $in);'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n"; } - $dt0 = $invtables[0]; - $dt1 = $invtables[1]; - $dt2 = $invtables[2]; - $dt3 = $invtables[3]; - $isbox = $invtables[4]; - '; - - $s = 'e'; - $e = 's'; - $wc = $Nb - 1; - // Preround: addRoundKey - $decrypt_block = '$in = unpack("N*", $in);'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n"; - } + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = array($e, $s); + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block.= + '$'.$e.$i.' = + $dt0[($'.$s.$i .' >> 24) & 0xff] ^ + $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^ + $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^ + $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^ + '.$dw[++$wc].";\n"; + } + } - // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey - for ($round = 1; $round < $Nr; ++$round) { - list($s, $e) = [$e, $s]; + // Finalround: subWord + shiftRows + addRoundKey for ($i = 0; $i < $Nb; ++$i) { $decrypt_block.= '$'.$e.$i.' = - $dt0[($'.$s.$i .' >> 24) & 0xff] ^ - $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^ - $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^ - $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^ - '.$dw[++$wc].";\n"; + $isbox[ $'.$e.$i.' & 0xff] | + ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) | + ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) | + ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; } - } - - // Finalround: subWord + shiftRows + addRoundKey - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block.= - '$'.$e.$i.' = - $isbox[ $'.$e.$i.' & 0xff] | - ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) | - ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) | - ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; - } - $decrypt_block .= '$in = pack("N*"'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block.= ', - ($'.$e.$i. ' & '.((int)0xFF000000).') ^ - ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^ - ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^ - ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^ - '.$dw[$i]."\n"; - } - $decrypt_block .= ');'; - - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => '', - 'init_encrypt' => $init_encrypt, - 'init_decrypt' => $init_decrypt, - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); - } - - /** - * Encrypts a message. - * - * @see self::decrypt() - * @see parent::encrypt() - * @access public - * @param string $plaintext - * @return string - */ - public function encrypt($plaintext) - { - $this->setup(); - - switch ($this->engine) { - case self::ENGINE_LIBSODIUM: - $this->newtag = sodium_crypto_aead_aes256gcm_encrypt($plaintext, $this->aad, $this->nonce, $this->key); - return Strings::shift($this->newtag, strlen($plaintext)); - case self::ENGINE_OPENSSL_GCM: - return openssl_encrypt( - $plaintext, - 'aes-' . $this->getKeyLength() . '-gcm', - $this->key, - OPENSSL_RAW_DATA, - $this->nonce, - $this->newtag, - $this->aad - ); - } - - return parent::encrypt($plaintext); - } - - /** - * Decrypts a message. - * - * @see self::encrypt() - * @see parent::decrypt() - * @access public - * @param string $ciphertext - * @return string - */ - public function decrypt($ciphertext) - { - $this->setup(); - - switch ($this->engine) { - case self::ENGINE_LIBSODIUM: - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - if (strlen($this->oldtag) != 16) { - break; - } - $plaintext = sodium_crypto_aead_aes256gcm_decrypt($ciphertext . $this->oldtag, $this->aad, $this->nonce, $this->key); - if ($plaintext === false) { - $this->oldtag = false; - throw new BadDecryptionException('Error decrypting ciphertext with libsodium'); - } - return $plaintext; - case self::ENGINE_OPENSSL_GCM: - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - $plaintext = openssl_decrypt( - $ciphertext, - 'aes-' . $this->getKeyLength() . '-gcm', - $this->key, - OPENSSL_RAW_DATA, - $this->nonce, - $this->oldtag, - $this->aad - ); - if ($plaintext === false) { - $this->oldtag = false; - throw new BadDecryptionException('Error decrypting ciphertext with OpenSSL'); - } - return $plaintext; - } - - return parent::decrypt($ciphertext); + $decrypt_block .= '$in = pack("N*"'."\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block.= ', + ($'.$e.$i. ' & '.((int)0xFF000000).') ^ + ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^ + ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^ + ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^ + '.$dw[$i]."\n"; + } + $decrypt_block .= ');'; + + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( + array( + 'init_crypt' => '', + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ) + ); + } + $this->inline_crypt = $lambda_functions[$code_hash]; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php deleted file mode 100644 index d76af6af0..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php +++ /dev/null @@ -1,529 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\StreamCipher; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\BadDecryptionException; -use phpseclib3\Common\Functions\Strings; - -/** - * Pure-PHP implementation of Salsa20. - * - * @package Salsa20 - * @author Jim Wigginton - * @access public - */ -class Salsa20 extends StreamCipher -{ - /** - * Part 1 of the state - * - * @var string|false - */ - protected $p1 = false; - - /** - * Part 2 of the state - * - * @var string|false - */ - protected $p2 = false; - - /** - * Key Length (in bytes) - * - * @var int - */ - protected $key_length = 32; // = 256 bits - - /** - * @access private - * @see \phpseclib3\Crypt\Salsa20::crypt() - */ - const ENCRYPT = 0; - - /** - * @access private - * @see \phpseclib3\Crypt\Salsa20::crypt() - */ - const DECRYPT = 1; - - /** - * Encryption buffer for continuous mode - * - * @var array - */ - protected $enbuffer; - - /** - * Decryption buffer for continuous mode - * - * @var array - */ - protected $debuffer; - - /** - * Counter - * - * @var int - */ - protected $counter = 0; - - /** - * Using Generated Poly1305 Key - * - * @var boolean - */ - protected $usingGeneratedPoly1305Key = false; - - /** - * Salsa20 uses a nonce - * - * @return bool - */ - public function usesNonce() - { - return true; - } - - /** - * Sets the key. - * - * @param string $key - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key) - { - switch (strlen($key)) { - case 16: - case 32: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported'); - } - - parent::setKey($key); - } - - /** - * Sets the nonce. - * - * @param string $nonce - */ - public function setNonce($nonce) - { - if (strlen($nonce) != 8) { - throw new \LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported'); - } - - $this->nonce = $nonce; - $this->changed = true; - $this->setEngine(); - } - - /** - * Sets the counter. - * - * @param int $counter - */ - public function setCounter($counter) - { - $this->counter = $counter; - $this->setEngine(); - } - - /** - * Creates a Poly1305 key using the method discussed in RFC8439 - * - * See https://tools.ietf.org/html/rfc8439#section-2.6.1 - */ - protected function createPoly1305Key() - { - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - $c = clone $this; - $c->setCounter(0); - $c->usePoly1305 = false; - $block = $c->encrypt(str_repeat("\0", 256)); - $this->setPoly1305Key(substr($block, 0, 32)); - - if ($this->counter == 0) { - $this->counter++; - } - } - - /** - * Setup the self::ENGINE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setNonce() - * - * - First run of encrypt() / decrypt() with no init-settings - * - * @see self::setKey() - * @see self::setNonce() - * @see self::disableContinuousBuffer() - */ - protected function setup() - { - if (!$this->changed) { - return; - } - - $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; - - $this->changed = $this->nonIVChanged = false; - - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - if ($this->usePoly1305 && !isset($this->poly1305Key)) { - $this->usingGeneratedPoly1305Key = true; - $this->createPoly1305Key(); - } - - $key = $this->key; - if (strlen($key) == 16) { - $constant = 'expand 16-byte k'; - $key.= $key; - } else { - $constant = 'expand 32-byte k'; - } - - $this->p1 = substr($constant, 0, 4) . - substr($key, 0, 16) . - substr($constant, 4, 4) . - $this->nonce . - "\0\0\0\0"; - $this->p2 = substr($constant, 8, 4) . - substr($key, 16, 16) . - substr($constant, 12, 4); - } - - /** - * Setup the key (expansion) - */ - protected function setupKey() - { - // Salsa20 does not utilize this method - } - - /** - * Encrypts a message. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @see self::crypt() - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - $ciphertext = $this->crypt($plaintext, self::ENCRYPT); - if (isset($this->poly1305Key)) { - $this->newtag = $this->poly1305($ciphertext); - } - return $ciphertext; - } - - /** - * Decrypts a message. - * - * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). - * At least if the continuous buffer is disabled. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see self::crypt() - * @param string $ciphertext - * @return string $plaintext - */ - public function decrypt($ciphertext) - { - if (isset($this->poly1305Key)) { - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - $newtag = $this->poly1305($ciphertext); - if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { - $this->oldtag = false; - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - $this->oldtag = false; - } - - return $this->crypt($ciphertext, self::DECRYPT); - } - - /** - * Encrypts a block - * - * @param string $in - */ - protected function encryptBlock($in) - { - // Salsa20 does not utilize this method - } - - /** - * Decrypts a block - * - * @param string $in - */ - protected function decryptBlock($in) - { - // Salsa20 does not utilize this method - } - - /** - * Encrypts or decrypts a message. - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $text - * @param int $mode - * @return string $text - */ - private function crypt($text, $mode) - { - $this->setup(); - if (!$this->continuousBuffer) { - if ($this->engine == self::ENGINE_OPENSSL) { - $iv = pack('V', $this->counter) . $this->p2; - return openssl_encrypt( - $text, - $this->cipher_name_openssl, - $this->key, - OPENSSL_RAW_DATA, - $iv - ); - } - $i = $this->counter; - $blocks = str_split($text, 64); - foreach ($blocks as &$block) { - $block^= static::salsa20($this->p1 . pack('V', $i++) . $this->p2); - } - - return implode('', $blocks); - } - - if ($mode == self::ENCRYPT) { - $buffer = &$this->enbuffer; - } else { - $buffer = &$this->debuffer; - } - if (strlen($buffer['ciphertext'])) { - $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text)); - $text = substr($text, strlen($ciphertext)); - if (!strlen($text)) { - return $ciphertext; - } - } - - $overflow = strlen($text) % 64; // & 0x3F - if ($overflow) { - $text2 = Strings::pop($text, $overflow); - if ($this->engine == self::ENGINE_OPENSSL) { - $iv = pack('V', $buffer['counter']) . $this->p2; - // at this point $text should be a multiple of 64 - $buffer['counter']+= (strlen($text) >> 6) + 1; // ie. divide by 64 - $encrypted = openssl_encrypt( - $text . str_repeat("\0", 64), - $this->cipher_name_openssl, - $this->key, - OPENSSL_RAW_DATA, - $iv - ); - $temp = Strings::pop($encrypted, 64); - } else { - $blocks = str_split($text, 64); - if (strlen($text)) { - foreach ($blocks as &$block) { - $block^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); - } - } - $encrypted = implode('', $blocks); - $temp = static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); - } - $ciphertext.= $encrypted . ($text2 ^ $temp); - $buffer['ciphertext'] = substr($temp, $overflow); - } elseif (!strlen($buffer['ciphertext'])) { - if ($this->engine == self::ENGINE_OPENSSL) { - $iv = pack('V', $buffer['counter']) . $this->p2; - $buffer['counter']+= (strlen($text) >> 6); - $ciphertext.= openssl_encrypt( - $text, - $this->cipher_name_openssl, - $this->key, - OPENSSL_RAW_DATA, - $iv - ); - } else { - $blocks = str_split($text, 64); - foreach ($blocks as &$block) { - $block^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); - } - $ciphertext.= implode('', $blocks); - } - } - - return $ciphertext; - } - - /** - * Left Rotate - * - * @param int $x - * @param int $n - * @return int - */ - protected static function leftRotate($x, $n) - { - $r1 = $x << $n; - if (PHP_INT_SIZE == 8) { - $r1&= 0xFFFFFFFF; - $r2 = ($x & 0xFFFFFFFF) >> (32 - $n); - } else { - $r2 = $x >> (32 - $n); - $r2&= (1 << $n) - 1; - } - return $r1 | $r2; - } - - /** - * The quarterround function - * - * @param int $a - * @param int $b - * @param int $c - * @param int $d - */ - protected static function quarterRound(&$a, &$b, &$c, &$d) - { - $b^= self::leftRotate($a + $d, 7); - $c^= self::leftRotate($b + $a, 9); - $d^= self::leftRotate($c + $b, 13); - $a^= self::leftRotate($d + $c, 18); - } - - /** - * The doubleround function - * - * @param int $x0 (by reference) - * @param int $x1 (by reference) - * @param int $x2 (by reference) - * @param int $x3 (by reference) - * @param int $x4 (by reference) - * @param int $x5 (by reference) - * @param int $x6 (by reference) - * @param int $x7 (by reference) - * @param int $x8 (by reference) - * @param int $x9 (by reference) - * @param int $x10 (by reference) - * @param int $x11 (by reference) - * @param int $x12 (by reference) - * @param int $x13 (by reference) - * @param int $x14 (by reference) - * @param int $x15 (by reference) - */ - protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) - { - // columnRound - static::quarterRound( $x0, $x4, $x8, $x12); - static::quarterRound( $x5, $x9, $x13, $x1); - static::quarterRound($x10, $x14, $x2, $x6); - static::quarterRound($x15, $x3, $x7, $x11); - // rowRound - static::quarterRound( $x0, $x1, $x2, $x3); - static::quarterRound( $x5, $x6, $x7, $x4); - static::quarterRound($x10, $x11, $x8, $x9); - static::quarterRound($x15, $x12, $x13, $x14); - } - - /** - * The Salsa20 hash function function - * - * @param string $x - */ - protected static function salsa20($x) - { - $z = $x = unpack('V*', $x); - for ($i = 0; $i < 10; $i++) { - static::doubleRound(...$z); - } - - for ($i = 1; $i <= 16; $i++) { - $x[$i]+= $z[$i]; - } - - return pack('V*', ...$x); - } - - /** - * Calculates Poly1305 MAC - * - * @see self::decrypt() - * @see self::encrypt() - * @access private - * @param string $ciphertext - * @return string - */ - protected function poly1305($ciphertext) - { - if (!$this->usingGeneratedPoly1305Key) { - return parent::poly1305($this->aad . $ciphertext); - } else { - /* - sodium_crypto_aead_chacha20poly1305_encrypt does not calculate the poly1305 tag - the same way sodium_crypto_aead_chacha20poly1305_ietf_encrypt does. you can see - how the latter encrypts it in Salsa20::encrypt(). here's how the former encrypts - it: - - $this->newtag = $this->poly1305( - $this->aad . - pack('V', strlen($this->aad)) . "\0\0\0\0" . - $ciphertext . - pack('V', strlen($ciphertext)) . "\0\0\0\0" - ); - - phpseclib opts to use the IETF construction, even when the nonce is 64-bits - instead of 96-bits - */ - return parent::poly1305( - self::nullPad128($this->aad) . - self::nullPad128($ciphertext) . - pack('V', strlen($this->aad)) . "\0\0\0\0" . - pack('V', strlen($ciphertext)) . "\0\0\0\0" - ); - } - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php index 2c98d6392..a2c41668a 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php @@ -12,7 +12,7 @@ * setKey('abcdefghijklmnopqrstuvwx'); * @@ -34,7 +34,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of Triple DES. @@ -55,47 +55,57 @@ class TripleDES extends DES /** * Encrypt / decrypt using outer chaining * - * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib3\Crypt\Common\BlockCipher::MODE_CBC. + * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC. */ - const MODE_CBC3 = self::MODE_CBC; + const MODE_CBC3 = Base::MODE_CBC; /** * Key Length (in bytes) * - * @see \phpseclib3\Crypt\TripleDES::setKeyLength() + * @see \phpseclib\Crypt\TripleDES::setKeyLength() * @var int * @access private */ - protected $key_length = 24; + var $key_length = 24; + + /** + * The default salt used by setPassword() + * + * @see \phpseclib\Crypt\Base::password_default_salt + * @see \phpseclib\Crypt\Base::setPassword() + * @var string + * @access private + */ + var $password_default_salt = 'phpseclib'; /** * The mcrypt specific name of the cipher * - * @see \phpseclib3\Crypt\DES::cipher_name_mcrypt - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib\Crypt\DES::cipher_name_mcrypt + * @see \phpseclib\Crypt\Base::cipher_name_mcrypt * @var string * @access private */ - protected $cipher_name_mcrypt = 'tripledes'; + var $cipher_name_mcrypt = 'tripledes'; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @see \phpseclib\Crypt\Base::cfb_init_len * @var int * @access private */ - protected $cfb_init_len = 750; + var $cfb_init_len = 750; /** * max possible size of $key * * @see self::setKey() - * @see \phpseclib3\Crypt\DES::setKey() + * @see \phpseclib\Crypt\DES::setKey() * @var string * @access private */ - protected $key_length_max = 24; + var $key_length_max = 24; /** * Internal flag whether using self::MODE_3CBC or not @@ -103,108 +113,103 @@ class TripleDES extends DES * @var bool * @access private */ - private $mode_3cbc; + var $mode_3cbc; /** - * The \phpseclib3\Crypt\DES objects + * The \phpseclib\Crypt\DES objects * * Used only if $mode_3cbc === true * * @var array * @access private */ - private $des; + var $des; /** * Default Constructor. * - * Determines whether or not the mcrypt or OpenSSL extensions should be used. + * Determines whether or not the mcrypt extension should be used. * * $mode could be: * - * - ecb + * - \phpseclib\Crypt\Base::MODE_ECB * - * - cbc + * - \phpseclib\Crypt\Base::MODE_CBC * - * - ctr + * - \phpseclib\Crypt\Base::MODE_CTR * - * - cfb + * - \phpseclib\Crypt\Base::MODE_CFB * - * - ofb + * - \phpseclib\Crypt\Base::MODE_OFB * - * - 3cbc + * - \phpseclib\Crypt\TripleDES::MODE_3CBC * - * - cbc3 (same as cbc) + * If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used. * - * @see \phpseclib3\Crypt\DES::__construct() - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param string $mode + * @see \phpseclib\Crypt\DES::__construct() + * @see \phpseclib\Crypt\Base::__construct() + * @param int $mode * @access public */ - public function __construct($mode) + function __construct($mode = Base::MODE_CBC) { - switch (strtolower($mode)) { + switch ($mode) { // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC // and additional flag us internally as 3CBC - case '3cbc': - parent::__construct('cbc'); + case self::MODE_3CBC: + parent::__construct(Base::MODE_CBC); $this->mode_3cbc = true; // This three $des'es will do the 3CBC work (if $key > 64bits) - $this->des = [ - new DES('cbc'), - new DES('cbc'), - new DES('cbc'), - ]; + $this->des = array( + new DES(Base::MODE_CBC), + new DES(Base::MODE_CBC), + new DES(Base::MODE_CBC), + ); - // we're going to be doing the padding, ourselves, so disable it in the \phpseclib3\Crypt\DES objects + // we're going to be doing the padding, ourselves, so disable it in the \phpseclib\Crypt\DES objects $this->des[0]->disablePadding(); $this->des[1]->disablePadding(); $this->des[2]->disablePadding(); break; - case 'cbc3': - $mode = 'cbc'; // If not 3CBC, we init as usual default: parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } } } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @see \phpseclib\Crypt\Base::__construct() * @param int $engine - * @access protected + * @access public * @return bool */ - protected function isValidEngineHelper($engine) + function isValidEngine($engine) { if ($engine == self::ENGINE_OPENSSL) { - self::$cipher_name_openssl_ecb = 'des-ede3'; - $mode = $this->openssl_translate_mode(); + $this->cipher_name_openssl_ecb = 'des-ede3'; + $mode = $this->_openssl_translate_mode(); $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; } - return parent::isValidEngineHelper($engine); + return parent::isValidEngine($engine); } /** - * Sets the initialization vector. + * Sets the initialization vector. (optional) * - * SetIV is not required when \phpseclib3\Crypt\Common\SymmetricKey::MODE_ECB is being used. + * SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used. If not explicitly set, it'll be assumed + * to be all zero's. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setIV() + * @see \phpseclib\Crypt\Base::setIV() * @access public * @param string $iv */ - public function setIV($iv) + function setIV($iv) { parent::setIV($iv); if ($this->mode_3cbc) { @@ -217,23 +222,24 @@ class TripleDES extends DES /** * Sets the key length. * - * Valid key lengths are 128 and 192 bits. - * - * If you want to use a 64-bit key use DES.php + * Valid key lengths are 64, 128 and 192 * - * @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength() + * @see \phpseclib\Crypt\Base:setKeyLength() * @access public - * @throws \LengthException if the key length is invalid * @param int $length */ - public function setKeyLength($length) + function setKeyLength($length) { - switch ($length) { - case 128: - case 192: + $length >>= 3; + switch (true) { + case $length <= 8: + $this->key_length = 8; + break; + case $length <= 16: + $this->key_length = 16; break; default: - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported'); + $this->key_length = 24; } parent::setKeyLength($length); @@ -242,39 +248,36 @@ class TripleDES extends DES /** * Sets the key. * - * Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys. + * Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or + * 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate. * * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. * + * If the key is not explicitly set, it'll be assumed to be all null bytes. + * * @access public - * @see \phpseclib3\Crypt\DES::setKey() - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() - * @throws \LengthException if the key length is invalid + * @see \phpseclib\Crypt\DES::setKey() + * @see \phpseclib\Crypt\Base::setKey() * @param string $key */ - public function setKey($key) + function setKey($key) { - if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { - throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); - } - - switch (strlen($key)) { - case 16: - $key.= substr($key, 0, 8); - break; - case 24: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported'); + $length = $this->explicit_key_length ? $this->key_length : strlen($key); + if ($length > 8) { + $key = str_pad(substr($key, 0, 24), 24, chr(0)); + // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this: + // http://php.net/function.mcrypt-encrypt#47973 + $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24); + } else { + $key = str_pad($key, 8, chr(0)); } + parent::setKey($key); - // copied from self::setKey() - $this->key = $key; - $this->key_length = strlen($key); - $this->changed = $this->nonIVChanged = true; - $this->setEngine(); - - if ($this->mode_3cbc) { + // And in case of self::MODE_3CBC: + // if key <= 64bits we not need the 3 $des to work, + // because we will then act as regular DES-CBC with just a <= 64bit key. + // So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des. + if ($this->mode_3cbc && $length > 8) { $this->des[0]->setKey(substr($key, 0, 8)); $this->des[1]->setKey(substr($key, 8, 8)); $this->des[2]->setKey(substr($key, 16, 8)); @@ -284,12 +287,12 @@ class TripleDES extends DES /** * Encrypts a message. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib\Crypt\Base::encrypt() * @access public * @param string $plaintext * @return string $cipertext */ - public function encrypt($plaintext) + function encrypt($plaintext) { // parent::en/decrypt() is able to do all the work for all modes and keylengths, // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits @@ -299,7 +302,7 @@ class TripleDES extends DES return $this->des[2]->encrypt( $this->des[1]->decrypt( $this->des[0]->encrypt( - $this->pad($plaintext) + $this->_pad($plaintext) ) ) ); @@ -311,15 +314,15 @@ class TripleDES extends DES /** * Decrypts a message. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see \phpseclib\Crypt\Base::decrypt() * @access public * @param string $ciphertext * @return string $plaintext */ - public function decrypt($ciphertext) + function decrypt($ciphertext) { if ($this->mode_3cbc && strlen($this->key) > 8) { - return $this->unpad( + return $this->_unpad( $this->des[0]->decrypt( $this->des[1]->encrypt( $this->des[2]->decrypt( @@ -362,16 +365,16 @@ class TripleDES extends DES * outputs. The reason is due to the fact that the initialization vector's change after every encryption / * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. * - * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\DES() object changes after each + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\DES() object changes after each * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), * however, they are also less intuitive and more likely to cause you problems. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::enableContinuousBuffer() + * @see \phpseclib\Crypt\Base::enableContinuousBuffer() * @see self::disableContinuousBuffer() * @access public */ - public function enableContinuousBuffer() + function enableContinuousBuffer() { parent::enableContinuousBuffer(); if ($this->mode_3cbc) { @@ -386,11 +389,11 @@ class TripleDES extends DES * * The default behavior. * - * @see \phpseclib3\Crypt\Common\SymmetricKey::disableContinuousBuffer() + * @see \phpseclib\Crypt\Base::disableContinuousBuffer() * @see self::enableContinuousBuffer() * @access public */ - public function disableContinuousBuffer() + function disableContinuousBuffer() { parent::disableContinuousBuffer(); if ($this->mode_3cbc) { @@ -403,11 +406,11 @@ class TripleDES extends DES /** * Creates the key schedule * - * @see \phpseclib3\Crypt\DES::setupKey() - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + * @see \phpseclib\Crypt\DES::_setupKey() + * @see \phpseclib\Crypt\Base::_setupKey() * @access private */ - protected function setupKey() + function _setupKey() { switch (true) { // if $key <= 64bits we configure our internal pure-php cipher engine @@ -422,28 +425,29 @@ class TripleDES extends DES // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. if ($this->mode_3cbc) { - $this->des[0]->setupKey(); - $this->des[1]->setupKey(); - $this->des[2]->setupKey(); + $this->des[0]->_setupKey(); + $this->des[1]->_setupKey(); + $this->des[2]->_setupKey(); // because $des[0-2] will, now, do all the work we can return here - // not need unnecessary stress parent::setupKey() with our, now unused, $key. + // not need unnecessary stress parent::_setupKey() with our, now unused, $key. return; } } // setup our key - parent::setupKey(); + parent::_setupKey(); } /** * Sets the internal crypt engine * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @see \phpseclib3\Crypt\Common\SymmetricKey::setPreferredEngine() + * @see \phpseclib\Crypt\Base::__construct() + * @see \phpseclib\Crypt\Base::setPreferredEngine() * @param int $engine * @access public + * @return int */ - public function setPreferredEngine($engine) + function setPreferredEngine($engine) { if ($this->mode_3cbc) { $this->des[0]->setPreferredEngine($engine); @@ -451,6 +455,6 @@ class TripleDES extends DES $this->des[2]->setPreferredEngine($engine); } - parent::setPreferredEngine($engine); + return parent::setPreferredEngine($engine); } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php index c9cc5b46c..70980a2ff 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php @@ -16,7 +16,7 @@ * setKey('12345678901234567890123456789012'); * @@ -35,10 +35,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; -use phpseclib3\Exception\BadModeException; +namespace phpseclib\Crypt; /** * Pure-PHP implementation of Twofish. @@ -48,25 +45,25 @@ use phpseclib3\Exception\BadModeException; * @author Hans-Juergen Petrich * @access public */ -class Twofish extends BlockCipher +class Twofish extends Base { /** * The mcrypt specific name of the cipher * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib\Crypt\Base::cipher_name_mcrypt * @var string * @access private */ - protected $cipher_name_mcrypt = 'twofish'; + var $cipher_name_mcrypt = 'twofish'; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @see \phpseclib\Crypt\Base::cfb_init_len * @var int * @access private */ - protected $cfb_init_len = 800; + var $cfb_init_len = 800; /** * Q-Table @@ -74,7 +71,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private static $q0 = [ + var $q0 = array( 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, @@ -107,7 +104,7 @@ class Twofish extends BlockCipher 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 - ]; + ); /** * Q-Table @@ -115,7 +112,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private static $q1 = [ + var $q1 = array( 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, @@ -148,7 +145,7 @@ class Twofish extends BlockCipher 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 - ]; + ); /** * M-Table @@ -156,7 +153,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private static $m0 = [ + var $m0 = array( 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, @@ -189,7 +186,7 @@ class Twofish extends BlockCipher 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 - ]; + ); /** * M-Table @@ -197,7 +194,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private static $m1 = [ + var $m1 = array( 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, @@ -230,7 +227,7 @@ class Twofish extends BlockCipher 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 - ]; + ); /** * M-Table @@ -238,7 +235,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private static $m2 = [ + var $m2 = array( 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, @@ -271,7 +268,7 @@ class Twofish extends BlockCipher 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF - ]; + ); /** * M-Table @@ -279,7 +276,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private static $m3 = [ + var $m3 = array( 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, @@ -312,7 +309,7 @@ class Twofish extends BlockCipher 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8 - ]; + ); /** * The Key Schedule Array @@ -320,7 +317,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private $K = []; + var $K = array(); /** * The Key depended S-Table 0 @@ -328,7 +325,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private $S0 = []; + var $S0 = array(); /** * The Key depended S-Table 1 @@ -336,7 +333,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private $S1 = []; + var $S1 = array(); /** * The Key depended S-Table 2 @@ -344,7 +341,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private $S2 = []; + var $S2 = array(); /** * The Key depended S-Table 3 @@ -352,7 +349,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private $S3 = []; + var $S3 = array(); /** * Holds the last used key @@ -360,7 +357,7 @@ class Twofish extends BlockCipher * @var array * @access private */ - private $kl; + var $kl; /** * The Key Length (in bytes) @@ -369,23 +366,7 @@ class Twofish extends BlockCipher * @var int * @access private */ - protected $key_length = 16; - - /** - * Default Constructor. - * - * @param string $mode - * @access public - * @throws BadModeException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } + var $key_length = 16; /** * Sets the key length. @@ -395,74 +376,52 @@ class Twofish extends BlockCipher * @access public * @param int $length */ - public function setKeyLength($length) + function setKeyLength($length) { - switch ($length) { - case 128: - case 192: - case 256: + switch (true) { + case $length <= 128: + $this->key_length = 16; break; - default: - throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); - } - - parent::setKeyLength($length); - } - - /** - * Sets the key. - * - * Rijndael supports five different key lengths - * - * @see setKeyLength() - * @access public - * @param string $key - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key) - { - switch (strlen($key)) { - case 16: - case 24: - case 32: + case $length <= 192: + $this->key_length = 24; break; default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + $this->key_length = 32; } - parent::setKey($key); + parent::setKeyLength($length); } /** * Setup the key (expansion) * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + * @see \phpseclib\Crypt\Base::_setupKey() * @access private */ - protected function setupKey() + function _setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key']) { // already expanded return; } - $this->kl = ['key' => $this->key]; + $this->kl = array('key' => $this->key); /* Key expanding and generating the key-depended s-boxes */ $le_longs = unpack('V*', $this->key); $key = unpack('C*', $this->key); - $m0 = self::$m0; - $m1 = self::$m1; - $m2 = self::$m2; - $m3 = self::$m3; - $q0 = self::$q0; - $q1 = self::$q1; + $m0 = $this->m0; + $m1 = $this->m1; + $m2 = $this->m2; + $m3 = $this->m3; + $q0 = $this->q0; + $q1 = $this->q1; - $K = $S0 = $S1 = $S2 = $S3 = []; + $K = $S0 = $S1 = $S2 = $S3 = array(); switch (strlen($this->key)) { case 16: - list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[1], $le_longs[2]); - list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[3], $le_longs[4]); + list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]); + list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]); for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^ @@ -473,9 +432,9 @@ class Twofish extends BlockCipher $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); - $A = self::safe_intval($A + $B); + $A = $this->safe_intval($A + $B); $K[] = $A; - $A = self::safe_intval($A + $B); + $A = $this->safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { @@ -486,9 +445,9 @@ class Twofish extends BlockCipher } break; case 24: - list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[1], $le_longs[2]); - list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[3], $le_longs[4]); - list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[5], $le_longs[6]); + list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]); + list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]); + list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]); for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ @@ -499,9 +458,9 @@ class Twofish extends BlockCipher $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); - $A = self::safe_intval($A + $B); + $A = $this->safe_intval($A + $B); $K[] = $A; - $A = self::safe_intval($A + $B); + $A = $this->safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { @@ -512,10 +471,10 @@ class Twofish extends BlockCipher } break; default: // 32 - list($sf, $se, $sd, $sc) = $this->mdsrem($le_longs[1], $le_longs[2]); - list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[3], $le_longs[4]); - list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[5], $le_longs[6]); - list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[7], $le_longs[8]); + list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]); + list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]); + list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]); + list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]); for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ @@ -526,9 +485,9 @@ class Twofish extends BlockCipher $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); - $A = self::safe_intval($A + $B); + $A = $this->safe_intval($A + $B); $K[] = $A; - $A = self::safe_intval($A + $B); + $A = $this->safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { @@ -554,7 +513,7 @@ class Twofish extends BlockCipher * @param string $B * @return array */ - private function mdsrem($A, $B) + function _mdsrem($A, $B) { // No gain by unrolling this loop. for ($i = 0; $i < 8; ++$i) { @@ -587,11 +546,11 @@ class Twofish extends BlockCipher $B^= ($u << 24) | ($u << 8); } - return [ + return array( 0xff & $B >> 24, 0xff & $B >> 16, 0xff & $B >> 8, - 0xff & $B]; + 0xff & $B); } /** @@ -601,7 +560,7 @@ class Twofish extends BlockCipher * @param string $in * @return string */ - protected function encryptBlock($in) + function _encryptBlock($in) { $S0 = $this->S0; $S1 = $this->S1; @@ -625,9 +584,9 @@ class Twofish extends BlockCipher $S1[ $R1 & 0xff] ^ $S2[($R1 >> 8) & 0xff] ^ $S3[($R1 >> 16) & 0xff]; - $R2^= self::safe_intval($t0 + $t1 + $K[++$ki]); + $R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]); $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); - $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]); $t0 = $S0[ $R2 & 0xff] ^ $S1[($R2 >> 8) & 0xff] ^ @@ -637,9 +596,9 @@ class Twofish extends BlockCipher $S1[ $R3 & 0xff] ^ $S2[($R3 >> 8) & 0xff] ^ $S3[($R3 >> 16) & 0xff]; - $R0^= self::safe_intval($t0 + $t1 + $K[++$ki]); + $R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]); $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); - $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]); } // @codingStandardsIgnoreStart @@ -657,7 +616,7 @@ class Twofish extends BlockCipher * @param string $in * @return string */ - protected function decryptBlock($in) + function _decryptBlock($in) { $S0 = $this->S0; $S1 = $this->S1; @@ -681,9 +640,9 @@ class Twofish extends BlockCipher $S1[$R1 & 0xff] ^ $S2[$R1 >> 8 & 0xff] ^ $S3[$R1 >> 16 & 0xff]; - $R3^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]); $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; - $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]); $t0 = $S0[$R2 & 0xff] ^ $S1[$R2 >> 8 & 0xff] ^ @@ -693,9 +652,9 @@ class Twofish extends BlockCipher $S1[$R3 & 0xff] ^ $S2[$R3 >> 8 & 0xff] ^ $S3[$R3 >> 16 & 0xff]; - $R1^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]); $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; - $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]); } // @codingStandardsIgnoreStart @@ -709,118 +668,149 @@ class Twofish extends BlockCipher /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() + * @see \phpseclib\Crypt\Base::_setupInlineCrypt() * @access private */ - protected function setupInlineCrypt() + function _setupInlineCrypt() { - $K = $this->K; - $init_crypt = ' - static $S0, $S1, $S2, $S3; - if (!$S0) { - for ($i = 0; $i < 256; ++$i) { - $S0[] = (int)$this->S0[$i]; - $S1[] = (int)$this->S1[$i]; - $S2[] = (int)$this->S2[$i]; - $S3[] = (int)$this->S3[$i]; - } + $lambda_functions =& self::_getLambdaFunctions(); + + // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one. + // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit) + $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); + + // Generation of a unique hash for our generated code + $code_hash = "Crypt_Twofish, {$this->mode}"; + if ($gen_hi_opt_code) { + $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); + } + + $safeint = $this->safe_intval_inline(); + + if (!isset($lambda_functions[$code_hash])) { + switch (true) { + case $gen_hi_opt_code: + $K = $this->K; + $init_crypt = ' + static $S0, $S1, $S2, $S3; + if (!$S0) { + for ($i = 0; $i < 256; ++$i) { + $S0[] = (int)$self->S0[$i]; + $S1[] = (int)$self->S1[$i]; + $S2[] = (int)$self->S2[$i]; + $S3[] = (int)$self->S3[$i]; + } + } + '; + break; + default: + $K = array(); + for ($i = 0; $i < 40; ++$i) { + $K[] = '$K_' . $i; + } + $init_crypt = ' + $S0 = $self->S0; + $S1 = $self->S1; + $S2 = $self->S2; + $S3 = $self->S3; + list(' . implode(',', $K) . ') = $self->K; + '; } - '; - - $safeint = self::safe_intval_inline(); - - // Generating encrypt code: - $encrypt_block = ' - $in = unpack("V4", $in); - $R0 = '.$K[0].' ^ $in[1]; - $R1 = '.$K[1].' ^ $in[2]; - $R2 = '.$K[2].' ^ $in[3]; - $R3 = '.$K[3].' ^ $in[4]; - '; - for ($ki = 7, $i = 0; $i < 8; ++$i) { - $encrypt_block.= ' - $t0 = $S0[ $R0 & 0xff] ^ - $S1[($R0 >> 8) & 0xff] ^ - $S2[($R0 >> 16) & 0xff] ^ - $S3[($R0 >> 24) & 0xff]; - $t1 = $S0[($R1 >> 24) & 0xff] ^ - $S1[ $R1 & 0xff] ^ - $S2[($R1 >> 8) & 0xff] ^ - $S3[($R1 >> 16) & 0xff]; + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("V4", $in); + $R0 = '.$K[0].' ^ $in[1]; + $R1 = '.$K[1].' ^ $in[2]; + $R2 = '.$K[2].' ^ $in[3]; + $R3 = '.$K[3].' ^ $in[4]; + '; + for ($ki = 7, $i = 0; $i < 8; ++$i) { + $encrypt_block.= ' + $t0 = $S0[ $R0 & 0xff] ^ + $S1[($R0 >> 8) & 0xff] ^ + $S2[($R0 >> 16) & 0xff] ^ + $S3[($R0 >> 24) & 0xff]; + $t1 = $S0[($R1 >> 24) & 0xff] ^ + $S1[ $R1 & 0xff] ^ + $S2[($R1 >> 8) & 0xff] ^ + $S3[($R1 >> 16) & 0xff]; $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . '; - $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); - $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; - - $t0 = $S0[ $R2 & 0xff] ^ - $S1[($R2 >> 8) & 0xff] ^ - $S2[($R2 >> 16) & 0xff] ^ - $S3[($R2 >> 24) & 0xff]; - $t1 = $S0[($R3 >> 24) & 0xff] ^ - $S1[ $R3 & 0xff] ^ - $S2[($R3 >> 8) & 0xff] ^ - $S3[($R3 >> 16) & 0xff]; - $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; - $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); - $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + + $t0 = $S0[ $R2 & 0xff] ^ + $S1[($R2 >> 8) & 0xff] ^ + $S2[($R2 >> 16) & 0xff] ^ + $S3[($R2 >> 24) & 0xff]; + $t1 = $S0[($R3 >> 24) & 0xff] ^ + $S1[ $R3 & 0xff] ^ + $S2[($R3 >> 8) & 0xff] ^ + $S3[($R3 >> 16) & 0xff]; + $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; + $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + '; + } + $encrypt_block.= ' + $in = pack("V4", ' . $K[4] . ' ^ $R2, + ' . $K[5] . ' ^ $R3, + ' . $K[6] . ' ^ $R0, + ' . $K[7] . ' ^ $R1); '; - } - $encrypt_block.= ' - $in = pack("V4", '.$K[4].' ^ $R2, - '.$K[5].' ^ $R3, - '.$K[6].' ^ $R0, - '.$K[7].' ^ $R1); - '; - - // Generating decrypt code: - $decrypt_block = ' - $in = unpack("V4", $in); - $R0 = '.$K[4].' ^ $in[1]; - $R1 = '.$K[5].' ^ $in[2]; - $R2 = '.$K[6].' ^ $in[3]; - $R3 = '.$K[7].' ^ $in[4]; - '; - for ($ki = 40, $i = 0; $i < 8; ++$i) { + + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("V4", $in); + $R0 = '.$K[4].' ^ $in[1]; + $R1 = '.$K[5].' ^ $in[2]; + $R2 = '.$K[6].' ^ $in[3]; + $R3 = '.$K[7].' ^ $in[4]; + '; + for ($ki = 40, $i = 0; $i < 8; ++$i) { + $decrypt_block.= ' + $t0 = $S0[$R0 & 0xff] ^ + $S1[$R0 >> 8 & 0xff] ^ + $S2[$R0 >> 16 & 0xff] ^ + $S3[$R0 >> 24 & 0xff]; + $t1 = $S0[$R1 >> 24 & 0xff] ^ + $S1[$R1 & 0xff] ^ + $S2[$R1 >> 8 & 0xff] ^ + $S3[$R1 >> 16 & 0xff]; + $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; + + $t0 = $S0[$R2 & 0xff] ^ + $S1[$R2 >> 8 & 0xff] ^ + $S2[$R2 >> 16 & 0xff] ^ + $S3[$R2 >> 24 & 0xff]; + $t1 = $S0[$R3 >> 24 & 0xff] ^ + $S1[$R3 & 0xff] ^ + $S2[$R3 >> 8 & 0xff] ^ + $S3[$R3 >> 16 & 0xff]; + $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; + '; + } $decrypt_block.= ' - $t0 = $S0[$R0 & 0xff] ^ - $S1[$R0 >> 8 & 0xff] ^ - $S2[$R0 >> 16 & 0xff] ^ - $S3[$R0 >> 24 & 0xff]; - $t1 = $S0[$R1 >> 24 & 0xff] ^ - $S1[$R1 & 0xff] ^ - $S2[$R1 >> 8 & 0xff] ^ - $S3[$R1 >> 16 & 0xff]; - $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; - $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; - $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; - - $t0 = $S0[$R2 & 0xff] ^ - $S1[$R2 >> 8 & 0xff] ^ - $S2[$R2 >> 16 & 0xff] ^ - $S3[$R2 >> 24 & 0xff]; - $t1 = $S0[$R3 >> 24 & 0xff] ^ - $S1[$R3 & 0xff] ^ - $S2[$R3 >> 8 & 0xff] ^ - $S3[$R3 >> 16 & 0xff]; - $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; - $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; - $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; + $in = pack("V4", ' . $K[0] . ' ^ $R2, + ' . $K[1] . ' ^ $R3, + ' . $K[2] . ' ^ $R0, + ' . $K[3] . ' ^ $R1); '; + + $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( + array( + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ) + ); } - $decrypt_block.= ' - $in = pack("V4", '.$K[0].' ^ $R2, - '.$K[1].' ^ $R3, - '.$K[2].' ^ $R0, - '.$K[3].' ^ $R1); - '; - - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'init_encrypt' => '', - 'init_decrypt' => '', - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); + $this->inline_crypt = $lambda_functions[$code_hash]; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php deleted file mode 100644 index fa5a818ac..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * BadConfigurationException - * - * @package BadConfigurationException - * @author Jim Wigginton - */ -class BadConfigurationException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php deleted file mode 100644 index c1171b159..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * BadDecryptionException - * - * @package BadDecryptionException - * @author Jim Wigginton - */ -class BadDecryptionException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php deleted file mode 100644 index ace9f578d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * BadModeException - * - * @package BadModeException - * @author Jim Wigginton - */ -class BadModeException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php deleted file mode 100644 index d6300d5c6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * ConnectionClosedException - * - * @package ConnectionClosedException - * @author Jim Wigginton - */ -class ConnectionClosedException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php deleted file mode 100644 index bc1b91898..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * FileNotFoundException - * - * @package FileNotFoundException - * @author Jim Wigginton - */ -class FileNotFoundException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php deleted file mode 100644 index 77db4a0e2..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * InconsistentSetupException - * - * @package InconsistentSetupException - * @author Jim Wigginton - */ -class InconsistentSetupException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php deleted file mode 100644 index 27f49f2f8..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * InsufficientSetupException - * - * @package InsufficientSetupException - * @author Jim Wigginton - */ -class InsufficientSetupException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php deleted file mode 100644 index 95152eb46..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * NoKeyLoadedException - * - * @package NoKeyLoadedException - * @author Jim Wigginton - */ -class NoKeyLoadedException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php deleted file mode 100644 index 7a7471dca..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * NoSupportedAlgorithmsException - * - * @package NoSupportedAlgorithmsException - * @author Jim Wigginton - */ -class NoSupportedAlgorithmsException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php deleted file mode 100644 index 909ef67fa..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnableToConnectException - * - * @package UnableToConnectException - * @author Jim Wigginton - */ -class UnableToConnectException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php deleted file mode 100644 index e0c07a436..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedAlgorithmException - * - * @package UnsupportedAlgorithmException - * @author Jim Wigginton - */ -class UnsupportedAlgorithmException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php deleted file mode 100644 index 6d746ab1b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedCurveException - * - * @package UnsupportedCurveException - * @author Jim Wigginton - */ -class UnsupportedCurveException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php deleted file mode 100644 index f58f812d3..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedFormatException - * - * @package UnsupportedFormatException - * @author Jim Wigginton - */ -class UnsupportedFormatException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php b/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php deleted file mode 100644 index 7872a1a82..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedOperationException - * - * @package UnsupportedOperationException - * @author Jim Wigginton - */ -class UnsupportedOperationException extends \RuntimeException -{ -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php index f0dc19618..b6874d357 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php @@ -5,10 +5,10 @@ * * PHP version 5 * - * If you call read() in \phpseclib3\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back. + * If you call read() in \phpseclib\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back. * They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a * {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what - * color to display them in, etc. \phpseclib3\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator. + * color to display them in, etc. \phpseclib\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator. * * @category File * @package ANSI @@ -18,7 +18,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\File; +namespace phpseclib\File; /** * Pure-PHP ANSI Decoder @@ -35,7 +35,7 @@ class ANSI * @var int * @access private */ - private $max_x; + var $max_x; /** * Max Height @@ -43,7 +43,7 @@ class ANSI * @var int * @access private */ - private $max_y; + var $max_y; /** * Max History @@ -51,7 +51,7 @@ class ANSI * @var int * @access private */ - private $max_history; + var $max_history; /** * History @@ -59,7 +59,7 @@ class ANSI * @var array * @access private */ - private $history; + var $history; /** * History Attributes @@ -67,7 +67,7 @@ class ANSI * @var array * @access private */ - private $history_attrs; + var $history_attrs; /** * Current Column @@ -75,7 +75,7 @@ class ANSI * @var int * @access private */ - private $x; + var $x; /** * Current Row @@ -83,7 +83,7 @@ class ANSI * @var int * @access private */ - private $y; + var $y; /** * Old Column @@ -91,7 +91,7 @@ class ANSI * @var int * @access private */ - private $old_x; + var $old_x; /** * Old Row @@ -99,7 +99,7 @@ class ANSI * @var int * @access private */ - private $old_y; + var $old_y; /** * An empty attribute cell @@ -107,7 +107,7 @@ class ANSI * @var object * @access private */ - private $base_attr_cell; + var $base_attr_cell; /** * The current attribute cell @@ -115,7 +115,7 @@ class ANSI * @var object * @access private */ - private $attr_cell; + var $attr_cell; /** * An empty attribute row @@ -123,7 +123,7 @@ class ANSI * @var array * @access private */ - private $attr_row; + var $attr_row; /** * The current screen text @@ -131,7 +131,7 @@ class ANSI * @var array * @access private */ - private $screen; + var $screen; /** * The current screen attributes @@ -139,7 +139,7 @@ class ANSI * @var array * @access private */ - private $attrs; + var $attrs; /** * Current ANSI code @@ -147,7 +147,7 @@ class ANSI * @var string * @access private */ - private $ansi; + var $ansi; /** * Tokenization @@ -155,15 +155,15 @@ class ANSI * @var array * @access private */ - private $tokenization; + var $tokenization; /** * Default Constructor. * - * @return \phpseclib3\File\ANSI + * @return \phpseclib\File\ANSI * @access public */ - public function __construct() + function __construct() { $attr_cell = new \stdClass(); $attr_cell->bold = false; @@ -188,12 +188,12 @@ class ANSI * @param int $y * @access public */ - public function setDimensions($x, $y) + function setDimensions($x, $y) { $this->max_x = $x - 1; $this->max_y = $y - 1; $this->x = $this->y = 0; - $this->history = $this->history_attrs = []; + $this->history = $this->history_attrs = array(); $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell); $this->screen = array_fill(0, $this->max_y + 1, ''); $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row); @@ -206,7 +206,7 @@ class ANSI * @param int $history * @access public */ - public function setHistory($history) + function setHistory($history) { $this->max_history = $history; } @@ -217,7 +217,7 @@ class ANSI * @param string $source * @access public */ - public function loadString($source) + function loadString($source) { $this->setDimensions($this->max_x + 1, $this->max_y + 1); $this->appendString($source); @@ -229,9 +229,9 @@ class ANSI * @param string $source * @access public */ - public function appendString($source) + function appendString($source) { - $this->tokenization = ['']; + $this->tokenization = array(''); for ($i = 0; $i < strlen($source); $i++) { if (strlen($this->ansi)) { $this->ansi.= $source[$i]; @@ -282,7 +282,7 @@ class ANSI case "\x1B(B": // set united states g0 character set break; case "\x1BE": // Move to next line - $this->newLine(); + $this->_newLine(); $this->x = 0; break; default: @@ -382,7 +382,7 @@ class ANSI $this->x = 0; break; case "\n": - $this->newLine(); + $this->_newLine(); break; case "\x08": // backspace if ($this->x) { @@ -419,7 +419,7 @@ class ANSI if ($this->x > $this->max_x) { $this->x = 0; - $this->newLine(); + $this->_newLine(); } else { $this->x++; } @@ -434,17 +434,17 @@ class ANSI * * @access private */ - private function newLine() + function _newLine() { //if ($this->y < $this->max_y) { // $this->y++; //} while ($this->y >= $this->max_y) { - $this->history = array_merge($this->history, [array_shift($this->screen)]); + $this->history = array_merge($this->history, array(array_shift($this->screen))); $this->screen[] = ''; - $this->history_attrs = array_merge($this->history_attrs, [array_shift($this->attrs)]); + $this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs))); $this->attrs[] = $this->attr_row; if (count($this->history) >= $this->max_history) { @@ -461,12 +461,9 @@ class ANSI * Returns the current coordinate without preformating * * @access private - * @param \stdClass $last_attr - * @param \stdClass $cur_attr - * @param string $char * @return string */ - private function processCoordinate($last_attr, $cur_attr, $char) + function _processCoordinate($last_attr, $cur_attr, $char) { $output = ''; @@ -523,21 +520,21 @@ class ANSI * @access private * @return string */ - private function getScreenHelper() + function _getScreen() { $output = ''; $last_attr = $this->base_attr_cell; for ($i = 0; $i <= $this->max_y; $i++) { for ($j = 0; $j <= $this->max_x; $j++) { $cur_attr = $this->attrs[$i][$j]; - $output.= $this->processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); + $output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); $last_attr = $this->attrs[$i][$j]; } $output.= "\r\n"; } $output = substr($output, 0, -2); // close any remaining open tags - $output.= $this->processCoordinate($last_attr, $this->base_attr_cell, ''); + $output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, ''); return rtrim($output); } @@ -547,9 +544,9 @@ class ANSI * @access public * @return string */ - public function getScreen() + function getScreen() { - return '
      ' . $this->getScreenHelper() . '
      '; + return '
      ' . $this->_getScreen() . '
      '; } /** @@ -558,21 +555,21 @@ class ANSI * @access public * @return string */ - public function getHistory() + function getHistory() { $scrollback = ''; $last_attr = $this->base_attr_cell; for ($i = 0; $i < count($this->history); $i++) { for ($j = 0; $j <= $this->max_x + 1; $j++) { $cur_attr = $this->history_attrs[$i][$j]; - $scrollback.= $this->processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); + $scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); $last_attr = $this->history_attrs[$i][$j]; } $scrollback.= "\r\n"; } $base_attr_cell = $this->base_attr_cell; $this->base_attr_cell = $last_attr; - $scrollback.= $this->getScreen(); + $scrollback.= $this->_getScreen(); $this->base_attr_cell = $base_attr_cell; return '
      ' . $scrollback . '
      '; diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php index cdc5b697d..807ca88ce 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php @@ -9,7 +9,7 @@ * utilized scheme is DER or the "Distinguished Encoding Rules". PEM's are base64 encoded * DER blobs. * - * \phpseclib3\File\ASN1 decodes and encodes DER formatted messages and places them in a semantic context. + * \phpseclib\File\ASN1 decodes and encodes DER formatted messages and places them in a semantic context. * * Uses the 1988 ASN.1 syntax. * @@ -21,12 +21,10 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\File; +namespace phpseclib\File; -use ParagonIE\ConstantTime\Base64; -use phpseclib3\File\ASN1\Element; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; +use phpseclib\File\ASN1\Element; +use phpseclib\Math\BigInteger; use DateTime; use DateTimeZone; @@ -37,17 +35,26 @@ use DateTimeZone; * @author Jim Wigginton * @access public */ -abstract class ASN1 +class ASN1 { - // Tag Classes - // http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 + /**#@+ + * Tag Classes + * + * @access private + * @link http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 + */ const CLASS_UNIVERSAL = 0; const CLASS_APPLICATION = 1; const CLASS_CONTEXT_SPECIFIC = 2; const CLASS_PRIVATE = 3; + /**#@-*/ - // Tag Classes - // http://www.obj-sys.com/asn1tutorial/node124.html + /**#@+ + * Tag Classes + * + * @access private + * @link http://www.obj-sys.com/asn1tutorial/node124.html + */ const TYPE_BOOLEAN = 1; const TYPE_INTEGER = 2; const TYPE_BIT_STRING = 3; @@ -63,9 +70,13 @@ abstract class ASN1 //const TYPE_RELATIVE_OID = 13; const TYPE_SEQUENCE = 16; // SEQUENCE OF const TYPE_SET = 17; // SET OF - - // More Tag Classes - // http://www.obj-sys.com/asn1tutorial/node10.html + /**#@-*/ + /**#@+ + * More Tag Classes + * + * @access private + * @link http://www.obj-sys.com/asn1tutorial/node10.html + */ const TYPE_NUMERIC_STRING = 18; const TYPE_PRINTABLE_STRING = 19; const TYPE_TELETEX_STRING = 20; // T61String @@ -79,28 +90,27 @@ abstract class ASN1 const TYPE_UNIVERSAL_STRING = 28; //const TYPE_CHARACTER_STRING = 29; const TYPE_BMP_STRING = 30; + /**#@-*/ - // Tag Aliases - // These tags are kinda place holders for other tags. + /**#@+ + * Tag Aliases + * + * These tags are kinda place holders for other tags. + * + * @access private + */ const TYPE_CHOICE = -1; const TYPE_ANY = -2; + /**#@-*/ /** - * ASN.1 object identifiers + * ASN.1 object identifier * * @var array * @access private * @link http://en.wikipedia.org/wiki/Object_identifier */ - private static $oids = []; - - /** - * ASN.1 object identifier reverse mapping - * - * @var array - * @access private - */ - private static $reverseOIDs = []; + var $oids = array(); /** * Default date format @@ -109,52 +119,41 @@ abstract class ASN1 * @access private * @link http://php.net/class.datetime */ - private static $format = 'D, d M Y H:i:s O'; + var $format = 'D, d M Y H:i:s O'; /** - * Filters - * - * If the mapping type is self::TYPE_ANY what do we actually encode it as? + * Default date format * * @var array * @access private - * @see self::encode_der() + * @see self::setTimeFormat() + * @see self::asn1map() + * @link http://php.net/class.datetime */ - private static $filters; + var $encoded; /** - * Current Location of most recent ASN.1 encode process + * Filters * - * Useful for debug purposes + * If the mapping type is self::TYPE_ANY what do we actually encode it as? * * @var array * @access private - * @see self::encode_der() + * @see self::_encode_der() */ - private static $location; - - /** - * DER Encoded String - * - * In case we need to create ASN1\Element object's.. - * - * @var string - * @access private - * @see self::decodeDER() - */ - private static $encoded; + var $filters; /** * Type mapping table for the ANY type. * - * Structured or unknown types are mapped to a \phpseclib3\File\ASN1\Element. + * Structured or unknown types are mapped to a \phpseclib\File\ASN1\Element. * Unambiguous types get the direct mapping (int/real/bool). * Others are mapped as a choice, with an extra indexing level. * * @var array * @access public */ - const ANY_MAP = [ + var $ANYmap = array( self::TYPE_BOOLEAN => true, self::TYPE_INTEGER => true, self::TYPE_BIT_STRING => 'bitString', @@ -177,7 +176,7 @@ abstract class ASN1 self::TYPE_UNIVERSAL_STRING => 'universalString', //self::TYPE_CHARACTER_STRING => 'characterString', self::TYPE_BMP_STRING => 'bmpString' - ]; + ); /** * String type to character size mapping table. @@ -188,7 +187,7 @@ abstract class ASN1 * @var array * @access public */ - const STRING_TYPE_SIZE = [ + var $stringTypeSize = array( self::TYPE_UTF8_STRING => 0, self::TYPE_BMP_STRING => 2, self::TYPE_UNIVERSAL_STRING => 4, @@ -196,7 +195,7 @@ abstract class ASN1 self::TYPE_TELETEX_STRING => 1, self::TYPE_IA5_STRING => 1, self::TYPE_VISIBLE_STRING => 1, - ]; + ); /** * Parse BER-encoding @@ -207,18 +206,15 @@ abstract class ASN1 * @return array * @access public */ - public static function decodeBER($encoded) + function decodeBER($encoded) { if ($encoded instanceof Element) { $encoded = $encoded->element; } - self::$encoded = $encoded; - - $decoded = [self::decode_ber($encoded)]; - + $this->encoded = $encoded; // encapsulate in an array for BC with the old decodeBER - return $decoded; + return array($this->_decode_ber($encoded)); } /** @@ -231,12 +227,12 @@ abstract class ASN1 * @param string $encoded * @param int $start * @param int $encoded_pos - * @return array|bool + * @return array * @access private */ - private static function decode_ber($encoded, $start = 0, $encoded_pos = 0) + function _decode_ber($encoded, $start = 0, $encoded_pos = 0) { - $current = ['start' => $start]; + $current = array('start' => $start); $type = ord($encoded[$encoded_pos++]); $start++; @@ -270,12 +266,11 @@ abstract class ASN1 $temp = substr($encoded, $encoded_pos, $length); $encoded_pos += $length; // tags of indefinte length don't really have a header length; this length includes the tag - $current+= ['headerlength' => $length + 2]; + $current+= array('headerlength' => $length + 2); $start+= $length; extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); - /** @var integer $length */ } else { - $current+= ['headerlength' => 2]; + $current+= array('headerlength' => 2); } if ($length > (strlen($encoded) - $encoded_pos)) { @@ -302,18 +297,18 @@ abstract class ASN1 case self::CLASS_PRIVATE: case self::CLASS_CONTEXT_SPECIFIC: if (!$constructed) { - return [ + return array( 'type' => $class, 'constant' => $tag, 'content' => $content, 'length' => $length + $start - $current['start'] - ] + $current; + ); } - $newcontent = []; + $newcontent = array(); $remainingLength = $length; while ($remainingLength > 0) { - $temp = self::decode_ber($content, $start, $content_pos); + $temp = $this->_decode_ber($content, $start, $content_pos); if ($temp === false) { break; } @@ -331,7 +326,7 @@ abstract class ASN1 $content_pos += $length; } - return [ + return array( 'type' => $class, 'constant' => $tag, // the array encapsulation is for BC with the old format @@ -340,10 +335,10 @@ abstract class ASN1 // the absence of $content['headerlength'] is how we know if something is indefinite or not. // technically, it could be defined to be 2 and then another indicator could be used but whatever. 'length' => $start - $current['start'] - ] + $current; + ) + $current; } - $current+= ['type' => $tag]; + $current+= array('type' => $tag); // decode UNIVERSAL tags switch ($tag) { @@ -367,7 +362,7 @@ abstract class ASN1 if (!$constructed) { $current['content'] = substr($content, $content_pos); } else { - $temp = self::decode_ber($content, $start, $content_pos); + $temp = $this->_decode_ber($content, $start, $content_pos); if ($temp === false) { return false; } @@ -394,7 +389,7 @@ abstract class ASN1 $current['content'] = ''; $length = 0; while (substr($content, $content_pos, 2) != "\0\0") { - $temp = self::decode_ber($content, $length + $start, $content_pos); + $temp = $this->_decode_ber($content, $length + $start, $content_pos); if ($temp === false) { return false; } @@ -420,7 +415,7 @@ abstract class ASN1 case self::TYPE_SEQUENCE: case self::TYPE_SET: $offset = 0; - $current['content'] = []; + $current['content'] = array(); $content_len = strlen($content); while ($content_pos < $content_len) { // if indefinite length construction was used and we have an end-of-content string next @@ -429,7 +424,7 @@ abstract class ASN1 $length = $offset + 2; // +2 for the EOC break 2; } - $temp = self::decode_ber($content, $start + $offset, $content_pos); + $temp = $this->_decode_ber($content, $start + $offset, $content_pos); if ($temp === false) { return false; } @@ -439,7 +434,7 @@ abstract class ASN1 } break; case self::TYPE_OBJECT_IDENTIFIER: - $current['content'] = self::decodeOID(substr($content, $content_pos)); + $current['content'] = $this->_decodeOID(substr($content, $content_pos)); break; /* Each character string type shall be encoded as if it had been declared: [UNIVERSAL x] IMPLICIT OCTET STRING @@ -473,14 +468,14 @@ abstract class ASN1 break; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: - $current['content'] = self::decodeTime(substr($content, $content_pos), $tag); + $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag); default: } $start+= $length; // ie. length is the length of the full TLV encoding - it's not just the length of the value - return $current + ['length' => $start - $current['start']]; + return $current + array('length' => $start - $current['start']); } /** @@ -493,10 +488,10 @@ abstract class ASN1 * @param array $decoded * @param array $mapping * @param array $special - * @return array|bool|Element + * @return array * @access public */ - public static function asn1map($decoded, $mapping, $special = []) + function asn1map($decoded, $mapping, $special = array()) { if (!is_array($decoded)) { return false; @@ -509,13 +504,12 @@ abstract class ASN1 switch (true) { case $mapping['type'] == self::TYPE_ANY: $intype = $decoded['type']; - // !isset(self::ANY_MAP[$intype]) produces a fatal error on PHP 5.6 - if (isset($decoded['constant']) || !array_key_exists($intype, self::ANY_MAP) || (ord(self::$encoded[$decoded['start']]) & 0x20)) { - return new Element(substr(self::$encoded, $decoded['start'], $decoded['length'])); + if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || (ord($this->encoded[$decoded['start']]) & 0x20)) { + return new Element(substr($this->encoded, $decoded['start'], $decoded['length'])); } - $inmap = self::ANY_MAP[$intype]; + $inmap = $this->ANYmap[$intype]; if (is_string($inmap)) { - return [$inmap => self::asn1map($decoded, ['type' => $intype] + $mapping, $special)]; + return array($inmap => $this->asn1map($decoded, array('type' => $intype) + $mapping, $special)); } break; case $mapping['type'] == self::TYPE_CHOICE: @@ -523,19 +517,19 @@ abstract class ASN1 switch (true) { case isset($option['constant']) && $option['constant'] == $decoded['constant']: case !isset($option['constant']) && $option['type'] == $decoded['type']: - $value = self::asn1map($decoded, $option, $special); + $value = $this->asn1map($decoded, $option, $special); break; case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE: - $v = self::asn1map($decoded, $option, $special); + $v = $this->asn1map($decoded, $option, $special); if (isset($v)) { $value = $v; } } if (isset($value)) { if (isset($special[$key])) { - $value = $special[$key]($value); + $value = call_user_func($special[$key], $value); } - return [$key => $value]; + return array($key => $value); } } return null; @@ -561,13 +555,13 @@ abstract class ASN1 switch ($decoded['type']) { case self::TYPE_SEQUENCE: - $map = []; + $map = array(); // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { $child = $mapping['children']; foreach ($decoded['content'] as $content) { - if (($map[] = self::asn1map($content, $child, $special)) === null) { + if (($map[] = $this->asn1map($content, $child, $special)) === null) { return null; } } @@ -603,37 +597,26 @@ abstract class ASN1 $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; } else { // Can only match if no constant expected and type matches or is generic. - $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; + $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false; } } } if ($maymatch) { // Attempt submapping. - $candidate = self::asn1map($temp, $child, $special); + $candidate = $this->asn1map($temp, $child, $special); $maymatch = $candidate !== null; } if ($maymatch) { // Got the match: use it. if (isset($special[$key])) { - $candidate = $special[$key]($candidate); + $candidate = call_user_func($special[$key], $candidate); } $map[$key] = $candidate; $i++; } elseif (isset($child['default'])) { - switch ($child['type']) { - case ASN1::TYPE_INTEGER: - $map[$key] = new BigInteger($child['default']); - break; - //case self::TYPE_OBJECT_IDENTIFIER: - // if (!isset(self::$reverseOIDs[$name])) { - // return null; - // } - //case ASN1::TYPE_BOOLEAN: - default: - $map[$key] = $child['default']; - } + $map[$key] = $child['default']; // Use default. } elseif (!isset($child['optional'])) { return null; // Syntax error. } @@ -644,13 +627,13 @@ abstract class ASN1 // the main diff between sets and sequences is the encapsulation of the foreach in another for loop case self::TYPE_SET: - $map = []; + $map = array(); // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { $child = $mapping['children']; foreach ($decoded['content'] as $content) { - if (($map[] = self::asn1map($content, $child, $special)) === null) { + if (($map[] = $this->asn1map($content, $child, $special)) === null) { return null; } } @@ -686,13 +669,13 @@ abstract class ASN1 $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; } else { // Can only match if no constant expected and type matches or is generic. - $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; + $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false; } } if ($maymatch) { // Attempt submapping. - $candidate = self::asn1map($temp, $child, $special); + $candidate = $this->asn1map($temp, $child, $special); $maymatch = $candidate !== null; } @@ -702,7 +685,7 @@ abstract class ASN1 // Got the match: use it. if (isset($special[$key])) { - $candidate = $special[$key]($candidate); + $candidate = call_user_func($special[$key], $candidate); } $map[$key] = $candidate; break; @@ -720,7 +703,7 @@ abstract class ASN1 } return $map; case self::TYPE_OBJECT_IDENTIFIER: - return isset(self::$oids[$decoded['content']]) ? self::$oids[$decoded['content']] : $decoded['content']; + return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content']; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: // for explicitly tagged optional stuff @@ -731,9 +714,9 @@ abstract class ASN1 // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist // in the wild that OpenSSL decodes without issue so we'll support them as well if (!is_object($decoded['content'])) { - $decoded['content'] = self::decodeTime($decoded['content'], $decoded['type']); + $decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']); } - return $decoded['content'] ? $decoded['content']->format(self::$format) : false; + return $decoded['content'] ? $decoded['content']->format($this->format) : false; case self::TYPE_BIT_STRING: if (isset($mapping['mapping'])) { $offset = ord($decoded['content'][0]); @@ -746,7 +729,7 @@ abstract class ASN1 therefore ensure that different semantics are not associated with such values which differ only in the number of trailing 0 bits." */ - $bits = count($mapping['mapping']) == $size ? [] : array_fill(0, count($mapping['mapping']) - $size, false); + $bits = count($mapping['mapping']) == $size ? array() : array_fill(0, count($mapping['mapping']) - $size, false); for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) { $current = ord($decoded['content'][$i]); for ($j = $offset; $j < 8; $j++) { @@ -754,7 +737,7 @@ abstract class ASN1 } $offset = 0; } - $values = []; + $values = array(); $map = array_reverse($mapping['mapping']); foreach ($map as $i => $value) { if ($bits[$i]) { @@ -764,7 +747,7 @@ abstract class ASN1 return $values; } case self::TYPE_OCTET_STRING: - return $decoded['content']; + return base64_encode($decoded['content']); case self::TYPE_NULL: return ''; case self::TYPE_BOOLEAN: @@ -797,27 +780,6 @@ abstract class ASN1 } } - /** - * DER-decode the length - * - * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See - * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. - * - * @access public - * @param string $string - * @return int - */ - public static function decodeLength(&$string) - { - $length = ord(Strings::shift($string)); - if ($length & 0x80) { // definite length, long form - $length&= 0x7F; - $temp = Strings::shift($string, $length); - list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); - } - return $length; - } - /** * ASN.1 Encode * @@ -826,29 +788,29 @@ abstract class ASN1 * * "Special" mappings can be applied via $special. * - * @param Element|string|array $source - * @param array $mapping + * @param string $source + * @param string $mapping * @param array $special * @return string * @access public */ - public static function encodeDER($source, $mapping, $special = []) + function encodeDER($source, $mapping, $special = array()) { - self::$location = []; - return self::encode_der($source, $mapping, null, $special); + $this->location = array(); + return $this->_encode_der($source, $mapping, null, $special); } /** * ASN.1 Encode (Helper function) * - * @param Element|string|array $source - * @param array $mapping + * @param string $source + * @param string $mapping * @param int $idx * @param array $special * @return string * @access private */ - private static function encode_der($source, $mapping, $idx = null, $special = []) + function _encode_der($source, $mapping, $idx = null, $special = array()) { if ($source instanceof Element) { return $source->element; @@ -861,9 +823,9 @@ abstract class ASN1 if (isset($idx)) { if (isset($special[$idx])) { - $source = $special[$idx]($source); + $source = call_user_func($special[$idx], $source); } - self::$location[] = $idx; + $this->location[] = $idx; } $tag = $mapping['type']; @@ -875,11 +837,11 @@ abstract class ASN1 // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { - $value = []; + $value = array(); $child = $mapping['children']; foreach ($source as $content) { - $temp = self::encode_der($content, $child, null, $special); + $temp = $this->_encode_der($content, $child, null, $special); if ($temp === false) { return false; } @@ -906,7 +868,7 @@ abstract class ASN1 continue; } - $temp = self::encode_der($source[$key], $child, $key, $special); + $temp = $this->_encode_der($source[$key], $child, $key, $special); if ($temp === false) { return false; } @@ -930,7 +892,7 @@ abstract class ASN1 */ if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); - $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; + $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp; } else { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); $temp = $subtag . substr($temp, 1); @@ -947,7 +909,7 @@ abstract class ASN1 continue; } - $temp = self::encode_der($source[$key], $child, $key, $special); + $temp = $this->_encode_der($source[$key], $child, $key, $special); if ($temp === false) { return false; } @@ -964,7 +926,7 @@ abstract class ASN1 if (isset($child['constant'])) { if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); - $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; + $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp; } else { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); $temp = $subtag . substr($temp, 1); @@ -973,7 +935,7 @@ abstract class ASN1 } if (isset($idx)) { - array_pop(self::$location); + array_pop($this->location); } if ($temp && isset($mapping['cast'])) { @@ -1044,36 +1006,36 @@ abstract class ASN1 the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven. -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */ - $value = $source; + $value = base64_decode($source); break; case self::TYPE_OBJECT_IDENTIFIER: - $value = self::encodeOID($source); + $value = $this->_encodeOID($source); break; case self::TYPE_ANY: - $loc = self::$location; + $loc = $this->location; if (isset($idx)) { - array_pop(self::$location); + array_pop($this->location); } switch (true) { case !isset($source): - return self::encode_der(null, ['type' => self::TYPE_NULL] + $mapping, null, $special); + return $this->_encode_der(null, array('type' => self::TYPE_NULL) + $mapping, null, $special); case is_int($source): case $source instanceof BigInteger: - return self::encode_der($source, ['type' => self::TYPE_INTEGER] + $mapping, null, $special); + return $this->_encode_der($source, array('type' => self::TYPE_INTEGER) + $mapping, null, $special); case is_float($source): - return self::encode_der($source, ['type' => self::TYPE_REAL] + $mapping, null, $special); + return $this->_encode_der($source, array('type' => self::TYPE_REAL) + $mapping, null, $special); case is_bool($source): - return self::encode_der($source, ['type' => self::TYPE_BOOLEAN] + $mapping, null, $special); + return $this->_encode_der($source, array('type' => self::TYPE_BOOLEAN) + $mapping, null, $special); case is_array($source) && count($source) == 1: $typename = implode('', array_keys($source)); - $outtype = array_search($typename, self::ANY_MAP, true); + $outtype = array_search($typename, $this->ANYmap, true); if ($outtype !== false) { - return self::encode_der($source[$typename], ['type' => $outtype] + $mapping, null, $special); + return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping, null, $special); } } - $filters = self::$filters; + $filters = $this->filters; foreach ($loc as $part) { if (!isset($filters[$part])) { $filters = false; @@ -1082,9 +1044,10 @@ abstract class ASN1 $filters = $filters[$part]; } if ($filters === false) { - throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); + user_error('No filters defined for ' . implode('/', $loc)); + return false; } - return self::encode_der($source, $filters + $mapping, null, $special); + return $this->_encode_der($source, $filters + $mapping, null, $special); case self::TYPE_NULL: $value = ''; break; @@ -1105,23 +1068,44 @@ abstract class ASN1 $value = $source ? "\xFF" : "\x00"; break; default: - throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location)); + user_error('Mapping provides no type definition for ' . implode('/', $this->location)); + return false; } if (isset($idx)) { - array_pop(self::$location); + array_pop($this->location); } if (isset($mapping['cast'])) { if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) { - $value = chr($tag) . self::encodeLength(strlen($value)) . $value; + $value = chr($tag) . $this->_encodeLength(strlen($value)) . $value; $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast']; } else { $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast']; } } - return chr($tag) . self::encodeLength(strlen($value)) . $value; + return chr($tag) . $this->_encodeLength(strlen($value)) . $value; + } + + /** + * DER-encode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @access private + * @param int $length + * @return string + */ + function _encodeLength($length) + { + if ($length <= 0x7F) { + return chr($length); + } + + $temp = ltrim(pack('N', $length), chr(0)); + return pack('Ca*', 0x80 | strlen($temp), $temp); } /** @@ -1129,11 +1113,11 @@ abstract class ASN1 * * Called by _decode_ber() * - * @access public + * @access private * @param string $content * @return string */ - public static function decodeOID($content) + function _decodeOID($content) { static $eighty; if (!$eighty) { @@ -1177,11 +1161,11 @@ abstract class ASN1 * * Called by _encode_der() * - * @access public + * @access private * @param string $source * @return string */ - public static function encodeOID($source) + function _encodeOID($source) { static $mask, $zero, $forty; if (!$mask) { @@ -1190,15 +1174,11 @@ abstract class ASN1 $forty = new BigInteger(40); } - if (!preg_match('#(?:\d+\.)+#', $source)) { - $oid = isset(self::$reverseOIDs[$source]) ? self::$reverseOIDs[$source] : false; - } else { - $oid = $source; - } + $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids); if ($oid === false) { - throw new \RuntimeException('Invalid OID'); + user_error('Invalid OID'); + return false; } - $parts = explode('.', $oid); $part1 = array_shift($parts); $part2 = array_shift($parts); @@ -1240,7 +1220,7 @@ abstract class ASN1 * @param int $tag * @return string */ - private static function decodeTime($content, $tag) + function _decodeTime($content, $tag) { /* UTCTime: http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 @@ -1286,38 +1266,52 @@ abstract class ASN1 * @access public * @param string $format */ - public static function setTimeFormat($format) + function setTimeFormat($format) { - self::$format = $format; + $this->format = $format; } /** * Load OIDs * * Load the relevant OIDs for a particular ASN.1 semantic mapping. - * Previously loaded OIDs are retained. * * @access public * @param array $oids */ - public static function loadOIDs($oids) + function loadOIDs($oids) { - self::$reverseOIDs+= $oids; - self::$oids = array_flip(self::$reverseOIDs); + $this->oids = $oids; } /** - * Set filters + * Load filters * - * See \phpseclib3\File\X509, etc, for an example. - * Previously loaded filters are not retained. + * See \phpseclib\File\X509, etc, for an example. * * @access public * @param array $filters */ - public static function setFilters($filters) + function loadFilters($filters) { - self::$filters = $filters; + $this->filters = $filters; + } + + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + * @access private + */ + function _string_shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; } /** @@ -1332,14 +1326,13 @@ abstract class ASN1 * @return string * @access public */ - public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) + function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) { - // isset(self::STRING_TYPE_SIZE[$from] returns a fatal error on PHP 5.6 - if (!array_key_exists($from, self::STRING_TYPE_SIZE) || !array_key_exists($to, self::STRING_TYPE_SIZE)) { + if (!isset($this->stringTypeSize[$from]) || !isset($this->stringTypeSize[$to])) { return false; } - $insize = self::STRING_TYPE_SIZE[$from]; - $outsize = self::STRING_TYPE_SIZE[$to]; + $insize = $this->stringTypeSize[$from]; + $outsize = $this->stringTypeSize[$to]; $inlength = strlen($in); $out = ''; @@ -1419,80 +1412,4 @@ abstract class ASN1 } return $out; } - - /** - * Extract raw BER from Base64 encoding - * - * @access private - * @param string $str - * @return string - */ - public static function extractBER($str) - { - /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them - * above and beyond the ceritificate. - * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: - * - * Bag Attributes - * localKeyID: 01 00 00 00 - * subject=/O=organization/OU=org unit/CN=common name - * issuer=/O=organization/CN=common name - */ - if (strlen($str) > ini_get('pcre.backtrack_limit')) { - $temp = $str; - } else { - $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); - $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $str, 1); - } - // remove new lines - $temp = str_replace(["\r", "\n", ' '], '', $temp); - // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff - $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false; - return $temp != false ? $temp : $str; - } - - /** - * DER-encode the length - * - * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See - * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. - * - * @access public - * @param int $length - * @return string - */ - public static function encodeLength($length) - { - if ($length <= 0x7F) { - return chr($length); - } - - $temp = ltrim(pack('N', $length), chr(0)); - return pack('Ca*', 0x80 | strlen($temp), $temp); - } - - /** - * Returns the OID corresponding to a name - * - * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if - * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version - * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able - * to work from version to version. - * - * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that - * what's being passed to it already is an OID and return that instead. A few examples. - * - * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' - * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' - * getOID('zzz') == 'zzz' - * - * @access public - * @param string $name - * @return string - */ - public static function getOID($name) - { - return isset(self::$reverseOIDs[$name]) ? self::$reverseOIDs[$name] : $name; - } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php index ade26ae51..68246e2b5 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php +++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php @@ -1,7 +1,6 @@ @@ -33,16 +31,16 @@ class Element * @var string * @access private */ - public $element; + var $element; /** * Constructor * * @param string $encoded - * @return \phpseclib3\File\ASN1\Element + * @return \phpseclib\File\ASN1\Element * @access public */ - public function __construct($encoded) + function __construct($encoded) { $this->element = $encoded; } diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php deleted file mode 100644 index 969de8c44..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AccessDescription - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AccessDescription -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'accessMethod' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'accessLocation' => GeneralName::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php deleted file mode 100644 index 1b607e7cd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AdministrationDomainName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AdministrationDomainName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or - // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC - 'class' => ASN1::CLASS_APPLICATION, - 'cast' => 2, - 'children' => [ - 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], - 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php deleted file mode 100644 index f9f25334a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AlgorithmIdentifier - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AlgorithmIdentifier -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'algorithm' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'parameters' => [ - 'type' => ASN1::TYPE_ANY, - 'optional' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php deleted file mode 100644 index 3fe2ba0bd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AnotherName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AnotherName -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type-id' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'value' => [ - 'type' => ASN1::TYPE_ANY, - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php deleted file mode 100644 index a80dad31c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Attribute - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Attribute -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type' => AttributeType::MAP, - 'value'=> [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => AttributeValue::MAP - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php deleted file mode 100644 index 891b80825..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AttributeType - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AttributeType -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php deleted file mode 100644 index ff4faa078..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AttributeTypeAndValue - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AttributeTypeAndValue -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type' => AttributeType::MAP, - 'value'=> AttributeValue::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php deleted file mode 100644 index eca03273c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AttributeValue - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AttributeValue -{ - const MAP = ['type' => ASN1::TYPE_ANY]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php deleted file mode 100644 index 563a69001..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Attributes - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Attributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => Attribute::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php deleted file mode 100644 index 38c714d5a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AuthorityInfoAccessSyntax - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AuthorityInfoAccessSyntax -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => AccessDescription::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php deleted file mode 100644 index b6b08ae01..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AuthorityKeyIdentifier - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class AuthorityKeyIdentifier -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'keyIdentifier' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + KeyIdentifier::MAP, - 'authorityCertIssuer' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + GeneralNames::MAP, - 'authorityCertSerialNumber' => [ - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ] + CertificateSerialNumber::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php deleted file mode 100644 index 8453e49d9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BaseDistance - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class BaseDistance -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php deleted file mode 100644 index 490bc9201..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BasicConstraints - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class BasicConstraints -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'cA' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'optional' => true, - 'default' => false - ], - 'pathLenConstraint' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php deleted file mode 100644 index 19f31c24a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BuiltInDomainDefinedAttribute - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class BuiltInDomainDefinedAttribute -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type' => ['type' => ASN1::TYPE_PRINTABLE_STRING], - 'value' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php deleted file mode 100644 index dc412118c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BuiltInDomainDefinedAttributes - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class BuiltInDomainDefinedAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 4, // ub-domain-defined-attributes - 'children' => BuiltInDomainDefinedAttribute::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php deleted file mode 100644 index 4cbe0b09f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BuiltInStandardAttributes - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class BuiltInStandardAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'country-name' => ['optional' => true] + CountryName::MAP, - 'administration-domain-name' => ['optional' => true] + AdministrationDomainName::MAP, - 'network-address' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + NetworkAddress::MAP, - 'terminal-identifier' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + TerminalIdentifier::MAP, - 'private-domain-name' => [ - 'constant' => 2, - 'optional' => true, - 'explicit' => true - ] + PrivateDomainName::MAP, - 'organization-name' => [ - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] + OrganizationName::MAP, - 'numeric-user-identifier' => [ - 'constant' => 4, - 'optional' => true, - 'implicit' => true - ] + NumericUserIdentifier::MAP, - 'personal-name' => [ - 'constant' => 5, - 'optional' => true, - 'implicit' => true - ] + PersonalName::MAP, - 'organizational-unit-names' => [ - 'constant' => 6, - 'optional' => true, - 'implicit' => true - ] + OrganizationalUnitNames::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php deleted file mode 100644 index 78733df9a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CPSuri - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CPSuri -{ - const MAP = ['type' => ASN1::TYPE_IA5_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php deleted file mode 100644 index 21ab66236..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CRLDistributionPoints - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CRLDistributionPoints -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => DistributionPoint::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php deleted file mode 100644 index 921fdd529..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CRLNumber - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CRLNumber -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php deleted file mode 100644 index e43e4dd75..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CRLReason - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CRLReason -{ - const MAP = [ - 'type' => ASN1::TYPE_ENUMERATED, - 'mapping' => [ - 'unspecified', - 'keyCompromise', - 'cACompromise', - 'affiliationChanged', - 'superseded', - 'cessationOfOperation', - 'certificateHold', - // Value 7 is not used. - 8 => 'removeFromCRL', - 'privilegeWithdrawn', - 'aACompromise' - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php deleted file mode 100644 index a4620e7d0..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertPolicyId - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CertPolicyId -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php deleted file mode 100644 index f8ff4130f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Certificate - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Certificate -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'tbsCertificate' => TBSCertificate::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php deleted file mode 100644 index ba4504afc..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificateIssuer - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CertificateIssuer -{ - const MAP = GeneralNames::MAP; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php deleted file mode 100644 index 79a1f3242..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificateList - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CertificateList -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'tbsCertList' => TBSCertList::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php deleted file mode 100644 index e9f9354af..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificatePolicies - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CertificatePolicies -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => PolicyInformation::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php deleted file mode 100644 index 83f26d311..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificateSerialNumber - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CertificateSerialNumber -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php deleted file mode 100644 index 23587f087..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificationRequest - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CertificationRequest -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'certificationRequestInfo' => CertificationRequestInfo::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php deleted file mode 100644 index 1ebff5ff6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificationRequestInfo - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CertificationRequestInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1'] - ], - 'subject' => Name::MAP, - 'subjectPKInfo' => SubjectPublicKeyInfo::MAP, - 'attributes' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + Attributes::MAP, - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php deleted file mode 100644 index b73e0ba2d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Characteristic_two - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Characteristic_two -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'm' => ['type' => ASN1::TYPE_INTEGER], // field size 2**m - 'basis' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'parameters' => [ - 'type' => ASN1::TYPE_ANY, - 'optional' => true - ] - ] - ]; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php deleted file mode 100644 index 83b3a2c3f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CountryName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class CountryName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or - // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC - 'class' => ASN1::CLASS_APPLICATION, - 'cast' => 1, - 'children' => [ - 'x121-dcc-code' => ['type' => ASN1::TYPE_NUMERIC_STRING], - 'iso-3166-alpha2-code' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php deleted file mode 100644 index 1a574583b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Curve - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Curve -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'a' => FieldElement::MAP, - 'b' => FieldElement::MAP, - 'seed' => [ - 'type' => ASN1::TYPE_BIT_STRING, - 'optional' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php deleted file mode 100644 index 8edd9d06b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DHParameter - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DHParameter -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'prime' => ['type' => ASN1::TYPE_INTEGER], - 'base' => ['type' => ASN1::TYPE_INTEGER], - 'privateValueLength' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php deleted file mode 100644 index c89fd84b4..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DSAParams - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DSAParams -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'p' => ['type' => ASN1::TYPE_INTEGER], - 'q' => ['type' => ASN1::TYPE_INTEGER], - 'g' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php deleted file mode 100644 index eaec347da..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DSAPrivateKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DSAPrivateKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => ['type' => ASN1::TYPE_INTEGER], - 'p' => ['type' => ASN1::TYPE_INTEGER], - 'q' => ['type' => ASN1::TYPE_INTEGER], - 'g' => ['type' => ASN1::TYPE_INTEGER], - 'y' => ['type' => ASN1::TYPE_INTEGER], - 'x' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php deleted file mode 100644 index 867d80b7d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DSAPublicKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DSAPublicKey -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php deleted file mode 100644 index 828c27989..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DigestInfo - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DigestInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'digestAlgorithm' => AlgorithmIdentifier::MAP, - 'digest' => ['type' => ASN1::TYPE_OCTET_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php deleted file mode 100644 index 458acab19..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DirectoryString - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DirectoryString -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'teletexString' => ['type' => ASN1::TYPE_TELETEX_STRING], - 'printableString' => ['type' => ASN1::TYPE_PRINTABLE_STRING], - 'universalString' => ['type' => ASN1::TYPE_UNIVERSAL_STRING], - 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING], - 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php deleted file mode 100644 index 6c88b41cb..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DisplayText - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DisplayText -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], - 'visibleString' => ['type' => ASN1::TYPE_VISIBLE_STRING], - 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING], - 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php deleted file mode 100644 index 91b3feef5..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DistributionPoint - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DistributionPoint -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'distributionPoint' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + DistributionPointName::MAP, - 'reasons' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + ReasonFlags::MAP, - 'cRLIssuer' => [ - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ] + GeneralNames::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php deleted file mode 100644 index fc157bcae..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DistributionPointName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DistributionPointName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'fullName' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + GeneralNames::MAP, - 'nameRelativeToCRLIssuer' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + RelativeDistinguishedName::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php deleted file mode 100644 index 1bffe9253..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DssSigValue - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class DssSigValue -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'r' => ['type' => ASN1::TYPE_INTEGER], - 's' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php deleted file mode 100644 index c27d16f9e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ECParameters - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * -- implicitCurve NULL - * -- specifiedCurve SpecifiedECDomain - * } - * -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. - * -- Details for SpecifiedECDomain can be found in [X9.62]. - * -- Any future additions to this CHOICE should be coordinated - * -- with ANSI X9. - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ECParameters -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'namedCurve' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'implicitCurve' => ['type' => ASN1::TYPE_NULL], - 'specifiedCurve' => SpecifiedECDomain::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php deleted file mode 100644 index 1a9429a44..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ECPoint - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ECPoint -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php deleted file mode 100644 index a0d7a066c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ECPrivateKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ECPrivateKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => [1 => 'ecPrivkeyVer1'] - ], - 'privateKey' => ['type' => ASN1::TYPE_OCTET_STRING], - 'parameters' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + ECParameters::MAP, - 'publicKey' => [ - 'type' => ASN1::TYPE_BIT_STRING, - 'constant' => 1, - 'optional' => true, - 'explicit' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php deleted file mode 100644 index 0c2327b8e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EDIPartyName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class EDIPartyName -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'nameAssigner' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + DirectoryString::MAP, - // partyName is technically required but \phpseclib3\File\ASN1 doesn't currently support non-optional constants and - // setting it to optional gets the job done in any event. - 'partyName' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + DirectoryString::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php deleted file mode 100644 index 98dd965aa..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EcdsaSigValue - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class EcdsaSigValue -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'r' => ['type' => ASN1::TYPE_INTEGER], - 's' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php deleted file mode 100644 index 7873579fd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EncryptedData - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class EncryptedData -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php deleted file mode 100644 index 5d409eb1a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EncryptedPrivateKeyInfo - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class EncryptedPrivateKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'encryptionAlgorithm' => AlgorithmIdentifier::MAP, - 'encryptedData' => EncryptedData::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php deleted file mode 100644 index c61116df4..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ExtKeyUsageSyntax - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ExtKeyUsageSyntax -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => KeyPurposeId::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php deleted file mode 100644 index 392007938..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Extension - * - * A certificate using system MUST reject the certificate if it encounters - * a critical extension it does not recognize; however, a non-critical - * extension may be ignored if it is not recognized. - * - * http://tools.ietf.org/html/rfc5280#section-4.2 - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Extension -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'extnId' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'critical' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'optional' => true, - 'default' => false - ], - 'extnValue' => ['type' => ASN1::TYPE_OCTET_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php deleted file mode 100644 index 6455e1898..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ExtensionAttribute - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ExtensionAttribute -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'extension-attribute-type' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ], - 'extension-attribute-value' => [ - 'type' => ASN1::TYPE_ANY, - 'constant' => 1, - 'optional' => true, - 'explicit' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php deleted file mode 100644 index 047bb29a4..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ExtensionAttributes - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ExtensionAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => 256, // ub-extension-attributes - 'children' => ExtensionAttribute::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php deleted file mode 100644 index e3d528d45..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Extensions - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Extensions -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - // technically, it's MAX, but we'll assume anything < 0 is MAX - 'max' => -1, - // if 'children' isn't an array then 'min' and 'max' must be defined - 'children' => Extension::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php deleted file mode 100644 index 6666e2ade..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * FieldElement - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class FieldElement -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php deleted file mode 100644 index 13c6ac490..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * FieldID - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class FieldID -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'fieldType' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'parameters' => [ - 'type' => ASN1::TYPE_ANY, - 'optional' => true - ] - ] - ]; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php deleted file mode 100644 index ba0b9e484..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class GeneralName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'otherName' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + AnotherName::MAP, - 'rfc822Name' => [ - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ], - 'dNSName' => [ - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ], - 'x400Address' => [ - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] + ORAddress::MAP, - 'directoryName' => [ - 'constant' => 4, - 'optional' => true, - 'explicit' => true - ] + Name::MAP, - 'ediPartyName' => [ - 'constant' => 5, - 'optional' => true, - 'implicit' => true - ] + EDIPartyName::MAP, - 'uniformResourceIdentifier' => [ - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 6, - 'optional' => true, - 'implicit' => true - ], - 'iPAddress' => [ - 'type' => ASN1::TYPE_OCTET_STRING, - 'constant' => 7, - 'optional' => true, - 'implicit' => true - ], - 'registeredID' => [ - 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, - 'constant' => 8, - 'optional' => true, - 'implicit' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php deleted file mode 100644 index c8a3c89bd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralNames - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class GeneralNames -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => GeneralName::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php deleted file mode 100644 index 15d954304..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralSubtree - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class GeneralSubtree -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'base' => GeneralName::MAP, - 'minimum' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true, - 'default' => '0' - ] + BaseDistance::MAP, - 'maximum' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true, - ] + BaseDistance::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php deleted file mode 100644 index 3b10265cd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralSubtrees - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class GeneralSubtrees -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => GeneralSubtree::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php deleted file mode 100644 index 02f587d13..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * HashAglorithm - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class HashAlgorithm -{ - const MAP = AlgorithmIdentifier::MAP; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php deleted file mode 100644 index 7d4959614..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * HoldInstructionCode - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class HoldInstructionCode -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php deleted file mode 100644 index 0ae964ce9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * InvalidityDate - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class InvalidityDate -{ - const MAP = ['type' => ASN1::TYPE_GENERALIZED_TIME]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php deleted file mode 100644 index 5f71db8f7..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * IssuerAltName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class IssuerAltName -{ - const MAP = GeneralNames::MAP; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php deleted file mode 100644 index f4b35b380..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * IssuingDistributionPoint - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class IssuingDistributionPoint -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'distributionPoint' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + DistributionPointName::MAP, - 'onlyContainsUserCerts' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 1, - 'optional' => true, - 'default' => false, - 'implicit' => true - ], - 'onlyContainsCACerts' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 2, - 'optional' => true, - 'default' => false, - 'implicit' => true - ], - 'onlySomeReasons' => [ - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] + ReasonFlags::MAP, - 'indirectCRL' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 4, - 'optional' => true, - 'default' => false, - 'implicit' => true - ], - 'onlyContainsAttributeCerts' =>[ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 5, - 'optional' => true, - 'default' => false, - 'implicit' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php deleted file mode 100644 index eb2939b85..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * KeyIdentifier - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class KeyIdentifier -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php deleted file mode 100644 index 7aee54ada..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * KeyPurposeId - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class KeyPurposeId -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php deleted file mode 100644 index abf599ed1..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * KeyUsage - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class KeyUsage -{ - const MAP = [ - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => [ - 'digitalSignature', - 'nonRepudiation', - 'keyEncipherment', - 'dataEncipherment', - 'keyAgreement', - 'keyCertSign', - 'cRLSign', - 'encipherOnly', - 'decipherOnly' - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php deleted file mode 100644 index 5e0e26f07..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * MaskGenAglorithm - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class MaskGenAlgorithm -{ - const MAP = AlgorithmIdentifier::MAP; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php deleted file mode 100644 index a4ba82a0e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Name - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Name -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'rdnSequence' => RDNSequence::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php deleted file mode 100644 index 518e68f6b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NameConstraints - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class NameConstraints -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'permittedSubtrees' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + GeneralSubtrees::MAP, - 'excludedSubtrees' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + GeneralSubtrees::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php deleted file mode 100644 index a67c0276c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NetworkAddress - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class NetworkAddress -{ - const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php deleted file mode 100644 index cea267733..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NoticeReference - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class NoticeReference -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'organization' => DisplayText::MAP, - 'noticeNumbers' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 200, - 'children' => ['type' => ASN1::TYPE_INTEGER] - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php deleted file mode 100644 index 04998393c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NumericUserIdentifier - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class NumericUserIdentifier -{ - const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php deleted file mode 100644 index cde7b3d6c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ORAddress - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ORAddress -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'built-in-standard-attributes' => BuiltInStandardAttributes::MAP, - 'built-in-domain-defined-attributes' => ['optional' => true] + BuiltInDomainDefinedAttributes::MAP, - 'extension-attributes' => ['optional' => true] + ExtensionAttributes::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php deleted file mode 100644 index 9a5c16873..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OneAsymmetricKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class OneAsymmetricKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1', 'v2'] - ], - 'privateKeyAlgorithm'=> AlgorithmIdentifier::MAP, - 'privateKey' => PrivateKey::MAP, - 'attributes' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + Attributes::MAP, - 'publicKey' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + PublicKey::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php deleted file mode 100644 index 250c92774..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OrganizationName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class OrganizationName -{ - const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php deleted file mode 100644 index eb2ac677a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OrganizationalUnitNames - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class OrganizationalUnitNames -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 4, // ub-organizational-units - 'children' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php deleted file mode 100644 index d75fa3f7c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OtherPrimeInfo - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class OtherPrimeInfo -{ - // version must be multi if otherPrimeInfos present - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'prime' => ['type' => ASN1::TYPE_INTEGER], // ri - 'exponent' => ['type' => ASN1::TYPE_INTEGER], // di - 'coefficient' => ['type' => ASN1::TYPE_INTEGER] // ti - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php deleted file mode 100644 index bb833171d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OtherPrimeInfos - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class OtherPrimeInfos -{ - // version must be multi if otherPrimeInfos present - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => OtherPrimeInfo::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php deleted file mode 100644 index bd17291fd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBEParameter - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PBEParameter -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], - 'iterationCount' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php deleted file mode 100644 index 1d807db70..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBES2params - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PBES2params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'keyDerivationFunc'=> AlgorithmIdentifier::MAP, - 'encryptionScheme' => AlgorithmIdentifier::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php deleted file mode 100644 index 16d37a95b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBKDF2params - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PBKDF2params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - // technically, this is a CHOICE in RFC2898 but the other "choice" is, currently, more of a placeholder - // in the RFC - 'salt'=> ['type' => ASN1::TYPE_OCTET_STRING], - 'iterationCount'=> ['type' => ASN1::TYPE_INTEGER], - 'keyLength' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ], - 'prf' => AlgorithmIdentifier::MAP + ['optional' => true] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php deleted file mode 100644 index f375aa16b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBMAC1params - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PBMAC1params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'keyDerivationFunc'=> AlgorithmIdentifier::MAP, - 'messageAuthScheme'=> AlgorithmIdentifier::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php deleted file mode 100644 index 11c638bdf..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PKCS9String - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PKCS9String -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], - 'directoryString' => DirectoryString::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php deleted file mode 100644 index 493cd2992..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Pentanomial - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Pentanomial -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'k1' => ['type' => ASN1::TYPE_INTEGER], // k1 > 0 - 'k2' => ['type' => ASN1::TYPE_INTEGER], // k2 > k1 - 'k3' => ['type' => ASN1::TYPE_INTEGER], // k3 > h2 - ] - ]; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php deleted file mode 100644 index c9492c9ef..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PersonalName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PersonalName -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'children' => [ - 'surname' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ], - 'given-name' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ], - 'initials' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ], - 'generation-qualifier' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php deleted file mode 100644 index cfda3990c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyInformation - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PolicyInformation -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'policyIdentifier' => CertPolicyId::MAP, - 'policyQualifiers' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 0, - 'max' => -1, - 'optional' => true, - 'children' => PolicyQualifierInfo::MAP - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php deleted file mode 100644 index c1086477a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyMappings - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PolicyMappings -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'issuerDomainPolicy' => CertPolicyId::MAP, - 'subjectDomainPolicy' => CertPolicyId::MAP - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php deleted file mode 100644 index 454a9d1a9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyQualifierId - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PolicyQualifierId -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php deleted file mode 100644 index a1d7e1727..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyQualifierInfo - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PolicyQualifierInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'policyQualifierId' => PolicyQualifierId::MAP, - 'qualifier' => ['type' => ASN1::TYPE_ANY] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php deleted file mode 100644 index ec8354fa0..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PostalAddress - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PostalAddress -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'optional' => true, - 'min' => 1, - 'max' => -1, - 'children' => DirectoryString::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php deleted file mode 100644 index 09c8006be..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Prime_p - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Prime_p -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php deleted file mode 100644 index b26c0cbaa..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateDomainName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PrivateDomainName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], - 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php deleted file mode 100644 index 7670f4add..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PrivateKey -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php deleted file mode 100644 index 170f6f276..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateKeyInfo - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PrivateKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1'] - ], - 'privateKeyAlgorithm'=> AlgorithmIdentifier::MAP, - 'privateKey' => PrivateKey::MAP, - 'attributes' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + Attributes::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php deleted file mode 100644 index 8c396a000..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateKeyUsagePeriod - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PrivateKeyUsagePeriod -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'notBefore' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true, - 'type' => ASN1::TYPE_GENERALIZED_TIME], - 'notAfter' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true, - 'type' => ASN1::TYPE_GENERALIZED_TIME] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php deleted file mode 100644 index b8239aa6a..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PublicKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PublicKey -{ - const MAP = ['type' => ASN1::TYPE_BIT_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php deleted file mode 100644 index ef212812d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PublicKeyAndChallenge - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PublicKeyAndChallenge -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'spki' => SubjectPublicKeyInfo::MAP, - 'challenge' => ['type' => ASN1::TYPE_IA5_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php deleted file mode 100644 index 587230bc3..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PublicKeyInfo - * - * this format is not formally defined anywhere but is none-the-less the form you - * get when you do "openssl rsa -in private.pem -outform PEM -pubout" - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class PublicKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'publicKeyAlgorithm'=> AlgorithmIdentifier::MAP, - 'publicKey' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php deleted file mode 100644 index 3697f103b..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RC2CBCParameter - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class RC2CBCParameter -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'rc2ParametersVersion'=> [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ], - 'iv'=> ['type' => ASN1::TYPE_OCTET_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php deleted file mode 100644 index 848e2c938..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RDNSequence - * - * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, - * but they can be useful at times when either there is no unique attribute in the entry or you - * want to ensure that the entry's DN contains some useful identifying information. - * - * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class RDNSequence -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - // RDNSequence does not define a min or a max, which means it doesn't have one - 'min' => 0, - 'max' => -1, - 'children' => RelativeDistinguishedName::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php deleted file mode 100644 index fbbb0f7cf..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RSAPrivateKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class RSAPrivateKey -{ - // version must be multi if otherPrimeInfos present - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['two-prime', 'multi'] - ], - 'modulus' => ['type' => ASN1::TYPE_INTEGER], // n - 'publicExponent' => ['type' => ASN1::TYPE_INTEGER], // e - 'privateExponent' => ['type' => ASN1::TYPE_INTEGER], // d - 'prime1' => ['type' => ASN1::TYPE_INTEGER], // p - 'prime2' => ['type' => ASN1::TYPE_INTEGER], // q - 'exponent1' => ['type' => ASN1::TYPE_INTEGER], // d mod (p-1) - 'exponent2' => ['type' => ASN1::TYPE_INTEGER], // d mod (q-1) - 'coefficient' => ['type' => ASN1::TYPE_INTEGER], // (inverse of q) mod p - 'otherPrimeInfos' => OtherPrimeInfos::MAP + ['optional' => true] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php deleted file mode 100644 index 1ea441d03..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RSAPublicKey - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class RSAPublicKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'modulus' => ['type' => ASN1::TYPE_INTEGER], - 'publicExponent' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php deleted file mode 100644 index b9ad46b01..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RSASSA_PSS_params - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class RSASSA_PSS_params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'hashAlgorithm' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true, - //'default' => 'sha1Identifier' - ] + HashAlgorithm::MAP, - 'maskGenAlgorithm' => [ - 'constant' => 1, - 'optional' => true, - 'explicit' => true, - //'default' => 'mgf1SHA1Identifier' - ] + MaskGenAlgorithm::MAP, - 'saltLength' => [ - 'type' => ASN1::TYPE_INTEGER, - 'constant' => 2, - 'optional' => true, - 'explicit' => true, - 'default' => 20 - ], - 'trailerField' => [ - 'type' => ASN1::TYPE_INTEGER, - 'constant' => 3, - 'optional' => true, - 'explicit' => true, - 'default' => 1 - ] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php deleted file mode 100644 index 3cb32c480..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ReasonFlags - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class ReasonFlags -{ - const MAP = [ - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => [ - 'unused', - 'keyCompromise', - 'cACompromise', - 'affiliationChanged', - 'superseded', - 'cessationOfOperation', - 'certificateHold', - 'privilegeWithdrawn', - 'aACompromise' - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php deleted file mode 100644 index de9dfaf60..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RelativeDistinguishedName - * - * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, - * but they can be useful at times when either there is no unique attribute in the entry or you - * want to ensure that the entry's DN contains some useful identifying information. - * - * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class RelativeDistinguishedName -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => AttributeTypeAndValue::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php deleted file mode 100644 index b012d9dff..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RevokedCertificate - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class RevokedCertificate -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'userCertificate' => CertificateSerialNumber::MAP, - 'revocationDate' => Time::MAP, - 'crlEntryExtensions' => [ - 'optional' => true - ] + Extensions::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php deleted file mode 100644 index c3591e2ff..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SignedPublicKeyAndChallenge - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class SignedPublicKeyAndChallenge -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'publicKeyAndChallenge' => PublicKeyAndChallenge::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php deleted file mode 100644 index fb437eab4..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SpecifiedECDomain - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class SpecifiedECDomain -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => [1 => 'ecdpVer1', 'ecdpVer2', 'ecdpVer3'] - ], - 'fieldID' => FieldID::MAP, - 'curve' => Curve::MAP, - 'base' => ECPoint::MAP, - 'order' => ['type' => ASN1::TYPE_INTEGER], - 'cofactor' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ], - 'hash' => ['optional' => true] + HashAlgorithm::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php deleted file mode 100644 index 02d2d6d49..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SubjectAltName - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class SubjectAltName -{ - const MAP = GeneralNames::MAP; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php deleted file mode 100644 index 1eff925a2..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SubjectDirectoryAttributes - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class SubjectDirectoryAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => Attribute::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php deleted file mode 100644 index 98ab3ddd6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SubjectInfoAccessSyntax - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class SubjectInfoAccessSyntax -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => AccessDescription::MAP - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php deleted file mode 100644 index c367608cd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SubjectPublicKeyInfo - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class SubjectPublicKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'algorithm' => AlgorithmIdentifier::MAP, - 'subjectPublicKey' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php deleted file mode 100644 index 49be58eb9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * TBSCertList - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class TBSCertList -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1', 'v2', 'v3'], - 'optional' => true, - 'default' => 'v2' - ], - 'signature' => AlgorithmIdentifier::MAP, - 'issuer' => Name::MAP, - 'thisUpdate' => Time::MAP, - 'nextUpdate' => [ - 'optional' => true - ] + Time::MAP, - 'revokedCertificates' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'optional' => true, - 'min' => 0, - 'max' => -1, - 'children' => RevokedCertificate::MAP - ], - 'crlExtensions' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + Extensions::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php deleted file mode 100644 index dc5fe2aa3..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * TBSCertificate - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class TBSCertificate -{ - // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - // technically, default implies optional, but we'll define it as being optional, none-the-less, just to - // reenforce that fact - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'constant' => 0, - 'optional' => true, - 'explicit' => true, - 'mapping' => ['v1', 'v2', 'v3'], - 'default' => 'v1' - ], - 'serialNumber' => CertificateSerialNumber::MAP, - 'signature' => AlgorithmIdentifier::MAP, - 'issuer' => Name::MAP, - 'validity' => Validity::MAP, - 'subject' => Name::MAP, - 'subjectPublicKeyInfo' => SubjectPublicKeyInfo::MAP, - // implicit means that the T in the TLV structure is to be rewritten, regardless of the type - 'issuerUniqueID' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + UniqueIdentifier::MAP, - 'subjectUniqueID' => [ - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ] + UniqueIdentifier::MAP, - // doesn't use the EXPLICIT keyword but if - // it's not IMPLICIT, it's EXPLICIT - 'extensions' => [ - 'constant' => 3, - 'optional' => true, - 'explicit' => true - ] + Extensions::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php deleted file mode 100644 index 5c6fdddb6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * TerminalIdentifier - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class TerminalIdentifier -{ - const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php deleted file mode 100644 index a673c3afc..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Time - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Time -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'utcTime' => ['type' => ASN1::TYPE_UTC_TIME], - 'generalTime' => ['type' => ASN1::TYPE_GENERALIZED_TIME] - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php deleted file mode 100644 index 7cd4ba27c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Trinomial - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Trinomial -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php deleted file mode 100644 index 64645773d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * UniqueIdentifier - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class UniqueIdentifier -{ - const MAP = ['type' => ASN1::TYPE_BIT_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php deleted file mode 100644 index 2a0c86542..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * UserNotice - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class UserNotice -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'noticeRef' => [ - 'optional' => true, - 'implicit' => true - ] + NoticeReference::MAP, - 'explicitText' => [ - 'optional' => true, - 'implicit' => true - ] + DisplayText::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php deleted file mode 100644 index 040aa7f59..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Validity - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class Validity -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'notBefore' => Time::MAP, - 'notAfter' => Time::MAP - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php deleted file mode 100644 index 1da389a72..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * netscape_ca_policy_url - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class netscape_ca_policy_url -{ - const MAP = ['type' => ASN1::TYPE_IA5_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php deleted file mode 100644 index c5845b594..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * netscape_cert_type - * - * mapping is from - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class netscape_cert_type -{ - const MAP = [ - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => [ - 'SSLClient', - 'SSLServer', - 'Email', - 'ObjectSigning', - 'Reserved', - 'SSLCA', - 'EmailCA', - 'ObjectSigningCA' - ] - ]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php deleted file mode 100644 index 8ff14dacc..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * netscape_comment - * - * @package ASN1 - * @author Jim Wigginton - * @access public - */ -abstract class netscape_comment -{ - const MAP = ['type' => ASN1::TYPE_IA5_STRING]; -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php index eb122b6bb..3520efdc1 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php +++ b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php @@ -24,26 +24,15 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\File; - -use DateTimeImmutable; -use DateTimeInterface; +namespace phpseclib\File; + +use phpseclib\Crypt\Hash; +use phpseclib\Crypt\Random; +use phpseclib\Crypt\RSA; +use phpseclib\File\ASN1\Element; +use phpseclib\Math\BigInteger; +use DateTime; use DateTimeZone; -use ParagonIE\ConstantTime\Base64; -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Crypt\Common\PublicKey; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\File\ASN1\Element; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; -use phpseclib3\Crypt\PublicKeyLoader; /** * Pure-PHP X.509 Parser @@ -63,77 +52,55 @@ class X509 */ const VALIDATE_SIGNATURE_BY_CA = 1; + /**#@+ + * @access public + * @see \phpseclib\File\X509::getDN() + */ /** * Return internal array representation - * - * @access public - * @see \phpseclib3\File\X509::getDN() */ const DN_ARRAY = 0; /** * Return string - * - * @access public - * @see \phpseclib3\File\X509::getDN() */ const DN_STRING = 1; /** * Return ASN.1 name string - * - * @access public - * @see \phpseclib3\File\X509::getDN() */ const DN_ASN1 = 2; /** * Return OpenSSL compatible array - * - * @access public - * @see \phpseclib3\File\X509::getDN() */ const DN_OPENSSL = 3; /** * Return canonical ASN.1 RDNs string - * - * @access public - * @see \phpseclib3\File\X509::getDN() */ const DN_CANON = 4; /** * Return name hash for file indexing - * - * @access public - * @see \phpseclib3\File\X509::getDN() */ const DN_HASH = 5; + /**#@-*/ + /**#@+ + * @access public + * @see \phpseclib\File\X509::saveX509() + * @see \phpseclib\File\X509::saveCSR() + * @see \phpseclib\File\X509::saveCRL() + */ /** * Save as PEM * * ie. a base64-encoded PEM with a header and a footer - * - * @access public - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_PEM = 0; /** * Save as DER - * - * @access public - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_DER = 1; /** * Save as a SPKAC * - * @access public - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() - * * Only works on CSRs. Not currently supported. */ const FORMAT_SPKAC = 2; @@ -141,13 +108,9 @@ class X509 * Auto-detect the format * * Used only by the load*() functions - * - * @access public - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_AUTO_DETECT = 3; + /**#@-*/ /** * Attribute value disposition. @@ -157,13 +120,87 @@ class X509 const ATTR_APPEND = -2; // Add a value. const ATTR_REPLACE = -3; // Clear first, then add a value. + /** + * ASN.1 syntax for X.509 certificates + * + * @var array + * @access private + */ + var $Certificate; + + /**#@+ + * ASN.1 syntax for various extensions + * + * @access private + */ + var $DirectoryString; + var $PKCS9String; + var $AttributeValue; + var $Extensions; + var $KeyUsage; + var $ExtKeyUsageSyntax; + var $BasicConstraints; + var $KeyIdentifier; + var $CRLDistributionPoints; + var $AuthorityKeyIdentifier; + var $CertificatePolicies; + var $AuthorityInfoAccessSyntax; + var $SubjectAltName; + var $SubjectDirectoryAttributes; + var $PrivateKeyUsagePeriod; + var $IssuerAltName; + var $PolicyMappings; + var $NameConstraints; + + var $CPSuri; + var $UserNotice; + + var $netscape_cert_type; + var $netscape_comment; + var $netscape_ca_policy_url; + + var $Name; + var $RelativeDistinguishedName; + var $CRLNumber; + var $CRLReason; + var $IssuingDistributionPoint; + var $InvalidityDate; + var $CertificateIssuer; + var $HoldInstructionCode; + var $SignedPublicKeyAndChallenge; + /**#@-*/ + + /**#@+ + * ASN.1 syntax for various DN attributes + * + * @access private + */ + var $PostalAddress; + /**#@-*/ + + /** + * ASN.1 syntax for Certificate Signing Requests (RFC2986) + * + * @var array + * @access private + */ + var $CertificationRequest; + + /** + * ASN.1 syntax for Certificate Revocation Lists (RFC5280) + * + * @var array + * @access private + */ + var $CertificateList; + /** * Distinguished Name * * @var array * @access private */ - private $dn; + var $dn; /** * Public key @@ -171,7 +208,7 @@ class X509 * @var string * @access private */ - private $publicKey; + var $publicKey; /** * Private key @@ -179,7 +216,7 @@ class X509 * @var string * @access private */ - private $privateKey; + var $privateKey; /** * Object identifiers for X.509 certificates @@ -188,7 +225,7 @@ class X509 * @access private * @link http://en.wikipedia.org/wiki/Object_identifier */ - private $oids; + var $oids; /** * The certificate authorities @@ -196,7 +233,7 @@ class X509 * @var array * @access private */ - private $CAs; + var $CAs; /** * The currently loaded certificate @@ -204,18 +241,18 @@ class X509 * @var array * @access private */ - private $currentCert; + var $currentCert; /** * The signature subject * - * There's no guarantee \phpseclib3\File\X509 is going to re-encode an X.509 cert in the same way it was originally + * There's no guarantee \phpseclib\File\X509 is going to re-encode an X.509 cert in the same way it was originally * encoded so we take save the portion of the original cert that the signature would have made for. * * @var string * @access private */ - private $signatureSubject; + var $signatureSubject; /** * Certificate Start Date @@ -223,7 +260,7 @@ class X509 * @var string * @access private */ - private $startDate; + var $startDate; /** * Certificate End Date @@ -231,7 +268,7 @@ class X509 * @var string * @access private */ - private $endDate; + var $endDate; /** * Serial Number @@ -239,7 +276,7 @@ class X509 * @var string * @access private */ - private $serialNumber; + var $serialNumber; /** * Key Identifier @@ -250,7 +287,7 @@ class X509 * @var string * @access private */ - private $currentKeyIdentifier; + var $currentKeyIdentifier; /** * CA Flag @@ -258,7 +295,7 @@ class X509 * @var bool * @access private */ - private $caFlag = false; + var $caFlag = false; /** * SPKAC Challenge @@ -266,21 +303,7 @@ class X509 * @var string * @access private */ - private $challenge; - - /** - * @var array - * @access private - */ - private $extensionValues = []; - - /** - * OIDs loaded - * - * @var bool - * @access private - */ - private static $oidsLoaded = false; + var $challenge; /** * Recursion Limit @@ -288,7 +311,7 @@ class X509 * @var int * @access private */ - private static $recur_limit = 5; + static $recur_limit = 5; /** * URL fetch flag @@ -296,172 +319,1137 @@ class X509 * @var bool * @access private */ - private static $disable_url_fetch = false; - - /** - * @var array - * @access private - */ - private static $extensions = []; - - /** - * @var ?array - * @access private - */ - private $ipAddresses = null; - - /** - * @var ?array - * @access private - */ - private $domains = null; + static $disable_url_fetch = false; /** * Default Constructor. * - * @return \phpseclib3\File\X509 + * @return \phpseclib\File\X509 * @access public */ - public function __construct() + function __construct() { // Explicitly Tagged Module, 1988 Syntax // http://tools.ietf.org/html/rfc5280#appendix-A.1 - if (!self::$oidsLoaded) { - // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 - ASN1::loadOIDs([ - //'id-pkix' => '1.3.6.1.5.5.7', - //'id-pe' => '1.3.6.1.5.5.7.1', - //'id-qt' => '1.3.6.1.5.5.7.2', - //'id-kp' => '1.3.6.1.5.5.7.3', - //'id-ad' => '1.3.6.1.5.5.7.48', - 'id-qt-cps' => '1.3.6.1.5.5.7.2.1', - 'id-qt-unotice' => '1.3.6.1.5.5.7.2.2', - 'id-ad-ocsp' =>'1.3.6.1.5.5.7.48.1', - 'id-ad-caIssuers' => '1.3.6.1.5.5.7.48.2', - 'id-ad-timeStamping' => '1.3.6.1.5.5.7.48.3', - 'id-ad-caRepository' => '1.3.6.1.5.5.7.48.5', - //'id-at' => '2.5.4', - 'id-at-name' => '2.5.4.41', - 'id-at-surname' => '2.5.4.4', - 'id-at-givenName' => '2.5.4.42', - 'id-at-initials' => '2.5.4.43', - 'id-at-generationQualifier' => '2.5.4.44', - 'id-at-commonName' => '2.5.4.3', - 'id-at-localityName' => '2.5.4.7', - 'id-at-stateOrProvinceName' => '2.5.4.8', - 'id-at-organizationName' => '2.5.4.10', - 'id-at-organizationalUnitName' => '2.5.4.11', - 'id-at-title' => '2.5.4.12', - 'id-at-description' => '2.5.4.13', - 'id-at-dnQualifier' => '2.5.4.46', - 'id-at-countryName' => '2.5.4.6', - 'id-at-serialNumber' => '2.5.4.5', - 'id-at-pseudonym' => '2.5.4.65', - 'id-at-postalCode' => '2.5.4.17', - 'id-at-streetAddress' => '2.5.4.9', - 'id-at-uniqueIdentifier' => '2.5.4.45', - 'id-at-role' => '2.5.4.72', - 'id-at-postalAddress' => '2.5.4.16', - - //'id-domainComponent' => '0.9.2342.19200300.100.1.25', - //'pkcs-9' => '1.2.840.113549.1.9', - 'pkcs-9-at-emailAddress' => '1.2.840.113549.1.9.1', - //'id-ce' => '2.5.29', - 'id-ce-authorityKeyIdentifier' => '2.5.29.35', - 'id-ce-subjectKeyIdentifier' => '2.5.29.14', - 'id-ce-keyUsage' => '2.5.29.15', - 'id-ce-privateKeyUsagePeriod' => '2.5.29.16', - 'id-ce-certificatePolicies' => '2.5.29.32', - //'anyPolicy' => '2.5.29.32.0', - - 'id-ce-policyMappings' => '2.5.29.33', - - 'id-ce-subjectAltName' => '2.5.29.17', - 'id-ce-issuerAltName' => '2.5.29.18', - 'id-ce-subjectDirectoryAttributes' => '2.5.29.9', - 'id-ce-basicConstraints' => '2.5.29.19', - 'id-ce-nameConstraints' => '2.5.29.30', - 'id-ce-policyConstraints' => '2.5.29.36', - 'id-ce-cRLDistributionPoints' => '2.5.29.31', - 'id-ce-extKeyUsage' => '2.5.29.37', - //'anyExtendedKeyUsage' => '2.5.29.37.0', - 'id-kp-serverAuth' => '1.3.6.1.5.5.7.3.1', - 'id-kp-clientAuth' => '1.3.6.1.5.5.7.3.2', - 'id-kp-codeSigning' => '1.3.6.1.5.5.7.3.3', - 'id-kp-emailProtection' => '1.3.6.1.5.5.7.3.4', - 'id-kp-timeStamping' => '1.3.6.1.5.5.7.3.8', - 'id-kp-OCSPSigning' => '1.3.6.1.5.5.7.3.9', - 'id-ce-inhibitAnyPolicy' => '2.5.29.54', - 'id-ce-freshestCRL' => '2.5.29.46', - 'id-pe-authorityInfoAccess' => '1.3.6.1.5.5.7.1.1', - 'id-pe-subjectInfoAccess' => '1.3.6.1.5.5.7.1.11', - 'id-ce-cRLNumber' => '2.5.29.20', - 'id-ce-issuingDistributionPoint' => '2.5.29.28', - 'id-ce-deltaCRLIndicator' => '2.5.29.27', - 'id-ce-cRLReasons' => '2.5.29.21', - 'id-ce-certificateIssuer' => '2.5.29.29', - 'id-ce-holdInstructionCode' => '2.5.29.23', - //'holdInstruction' => '1.2.840.10040.2', - 'id-holdinstruction-none' => '1.2.840.10040.2.1', - 'id-holdinstruction-callissuer' => '1.2.840.10040.2.2', - 'id-holdinstruction-reject' => '1.2.840.10040.2.3', - 'id-ce-invalidityDate' => '2.5.29.24', - - 'rsaEncryption' => '1.2.840.113549.1.1.1', - 'md2WithRSAEncryption' => '1.2.840.113549.1.1.2', - 'md5WithRSAEncryption' => '1.2.840.113549.1.1.4', - 'sha1WithRSAEncryption' => '1.2.840.113549.1.1.5', - 'sha224WithRSAEncryption' => '1.2.840.113549.1.1.14', - 'sha256WithRSAEncryption' => '1.2.840.113549.1.1.11', - 'sha384WithRSAEncryption' => '1.2.840.113549.1.1.12', - 'sha512WithRSAEncryption' => '1.2.840.113549.1.1.13', - - 'id-ecPublicKey' => '1.2.840.10045.2.1', - 'ecdsa-with-SHA1' => '1.2.840.10045.4.1', - // from https://tools.ietf.org/html/rfc5758#section-3.2 - 'ecdsa-with-SHA224' => '1.2.840.10045.4.3.1', - 'ecdsa-with-SHA256' => '1.2.840.10045.4.3.2', - 'ecdsa-with-SHA384' => '1.2.840.10045.4.3.3', - 'ecdsa-with-SHA512' => '1.2.840.10045.4.3.4', - - 'id-dsa' => '1.2.840.10040.4.1', - 'id-dsa-with-sha1' => '1.2.840.10040.4.3', - // from https://tools.ietf.org/html/rfc5758#section-3.1 - 'id-dsa-with-sha224' => '2.16.840.1.101.3.4.3.1', - 'id-dsa-with-sha256' => '2.16.840.1.101.3.4.3.2', - - // from https://tools.ietf.org/html/rfc8410: - 'id-Ed25519' => '1.3.101.112', - 'id-Ed448' => '1.3.101.113', - - 'id-RSASSA-PSS' => '1.2.840.113549.1.1.10', - - //'id-sha224' => '2.16.840.1.101.3.4.2.4', - //'id-sha256' => '2.16.840.1.101.3.4.2.1', - //'id-sha384' => '2.16.840.1.101.3.4.2.2', - //'id-sha512' => '2.16.840.1.101.3.4.2.3', - //'id-GostR3411-94-with-GostR3410-94' => '1.2.643.2.2.4', - //'id-GostR3411-94-with-GostR3410-2001' => '1.2.643.2.2.3', - //'id-GostR3410-2001' => '1.2.643.2.2.20', - //'id-GostR3410-94' => '1.2.643.2.2.19', - // Netscape Object Identifiers from "Netscape Certificate Extensions" - 'netscape' => '2.16.840.1.113730', - 'netscape-cert-extension' => '2.16.840.1.113730.1', - 'netscape-cert-type' => '2.16.840.1.113730.1.1', - 'netscape-comment' => '2.16.840.1.113730.1.13', - 'netscape-ca-policy-url' => '2.16.840.1.113730.1.8', - // the following are X.509 extensions not supported by phpseclib - 'id-pe-logotype' => '1.3.6.1.5.5.7.1.12', - 'entrustVersInfo' => '1.2.840.113533.7.65.0', - 'verisignPrivate' => '2.16.840.1.113733.1.6.9', - // for Certificate Signing Requests - // see http://tools.ietf.org/html/rfc2985 - 'pkcs-9-at-unstructuredName' => '1.2.840.113549.1.9.2', // PKCS #9 unstructured name - 'pkcs-9-at-challengePassword' => '1.2.840.113549.1.9.7', // Challenge password for certificate revocations - 'pkcs-9-at-extensionRequest' => '1.2.840.113549.1.9.14' // Certificate extension request - ]); - } + $this->DirectoryString = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'teletexString' => array('type' => ASN1::TYPE_TELETEX_STRING), + 'printableString' => array('type' => ASN1::TYPE_PRINTABLE_STRING), + 'universalString' => array('type' => ASN1::TYPE_UNIVERSAL_STRING), + 'utf8String' => array('type' => ASN1::TYPE_UTF8_STRING), + 'bmpString' => array('type' => ASN1::TYPE_BMP_STRING) + ) + ); + + $this->PKCS9String = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'ia5String' => array('type' => ASN1::TYPE_IA5_STRING), + 'directoryString' => $this->DirectoryString + ) + ); + + $this->AttributeValue = array('type' => ASN1::TYPE_ANY); + + $AttributeType = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); + + $AttributeTypeAndValue = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'type' => $AttributeType, + 'value'=> $this->AttributeValue + ) + ); + + /* + In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, + but they can be useful at times when either there is no unique attribute in the entry or you + want to ensure that the entry's DN contains some useful identifying information. + + - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName + */ + $this->RelativeDistinguishedName = array( + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => $AttributeTypeAndValue + ); + + // http://tools.ietf.org/html/rfc5280#section-4.1.2.4 + $RDNSequence = array( + 'type' => ASN1::TYPE_SEQUENCE, + // RDNSequence does not define a min or a max, which means it doesn't have one + 'min' => 0, + 'max' => -1, + 'children' => $this->RelativeDistinguishedName + ); + + $this->Name = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'rdnSequence' => $RDNSequence + ) + ); + + // http://tools.ietf.org/html/rfc5280#section-4.1.1.2 + $AlgorithmIdentifier = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'algorithm' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), + 'parameters' => array( + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ) + ) + ); + + /* + A certificate using system MUST reject the certificate if it encounters + a critical extension it does not recognize; however, a non-critical + extension may be ignored if it is not recognized. + + http://tools.ietf.org/html/rfc5280#section-4.2 + */ + $Extension = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'extnId' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), + 'critical' => array( + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ), + 'extnValue' => array('type' => ASN1::TYPE_OCTET_STRING) + ) + ); + + $this->Extensions = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + // technically, it's MAX, but we'll assume anything < 0 is MAX + 'max' => -1, + // if 'children' isn't an array then 'min' and 'max' must be defined + 'children' => $Extension + ); + + $SubjectPublicKeyInfo = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'algorithm' => $AlgorithmIdentifier, + 'subjectPublicKey' => array('type' => ASN1::TYPE_BIT_STRING) + ) + ); + + $UniqueIdentifier = array('type' => ASN1::TYPE_BIT_STRING); + + $Time = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'utcTime' => array('type' => ASN1::TYPE_UTC_TIME), + 'generalTime' => array('type' => ASN1::TYPE_GENERALIZED_TIME) + ) + ); + + // http://tools.ietf.org/html/rfc5280#section-4.1.2.5 + $Validity = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'notBefore' => $Time, + 'notAfter' => $Time + ) + ); + + $CertificateSerialNumber = array('type' => ASN1::TYPE_INTEGER); + + $Version = array( + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => array('v1', 'v2', 'v3') + ); + + // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) + $TBSCertificate = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + // technically, default implies optional, but we'll define it as being optional, none-the-less, just to + // reenforce that fact + 'version' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'default' => 'v1' + ) + $Version, + 'serialNumber' => $CertificateSerialNumber, + 'signature' => $AlgorithmIdentifier, + 'issuer' => $this->Name, + 'validity' => $Validity, + 'subject' => $this->Name, + 'subjectPublicKeyInfo' => $SubjectPublicKeyInfo, + // implicit means that the T in the TLV structure is to be rewritten, regardless of the type + 'issuerUniqueID' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ) + $UniqueIdentifier, + 'subjectUniqueID' => array( + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ) + $UniqueIdentifier, + // doesn't use the EXPLICIT keyword but if + // it's not IMPLICIT, it's EXPLICIT + 'extensions' => array( + 'constant' => 3, + 'optional' => true, + 'explicit' => true + ) + $this->Extensions + ) + ); + + $this->Certificate = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'tbsCertificate' => $TBSCertificate, + 'signatureAlgorithm' => $AlgorithmIdentifier, + 'signature' => array('type' => ASN1::TYPE_BIT_STRING) + ) + ); + + $this->KeyUsage = array( + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => array( + 'digitalSignature', + 'nonRepudiation', + 'keyEncipherment', + 'dataEncipherment', + 'keyAgreement', + 'keyCertSign', + 'cRLSign', + 'encipherOnly', + 'decipherOnly' + ) + ); + + $this->BasicConstraints = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'cA' => array( + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ), + 'pathLenConstraint' => array( + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ) + ) + ); + + $this->KeyIdentifier = array('type' => ASN1::TYPE_OCTET_STRING); + + $OrganizationalUnitNames = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-organizational-units + 'children' => array('type' => ASN1::TYPE_PRINTABLE_STRING) + ); + + $PersonalName = array( + 'type' => ASN1::TYPE_SET, + 'children' => array( + 'surname' => array( + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ), + 'given-name' => array( + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ), + 'initials' => array( + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ), + 'generation-qualifier' => array( + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ) + ) + ); + + $NumericUserIdentifier = array('type' => ASN1::TYPE_NUMERIC_STRING); + + $OrganizationName = array('type' => ASN1::TYPE_PRINTABLE_STRING); + + $PrivateDomainName = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'numeric' => array('type' => ASN1::TYPE_NUMERIC_STRING), + 'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING) + ) + ); + + $TerminalIdentifier = array('type' => ASN1::TYPE_PRINTABLE_STRING); + + $NetworkAddress = array('type' => ASN1::TYPE_NUMERIC_STRING); + + $AdministrationDomainName = array( + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 2, + 'children' => array( + 'numeric' => array('type' => ASN1::TYPE_NUMERIC_STRING), + 'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING) + ) + ); + + $CountryName = array( + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 1, + 'children' => array( + 'x121-dcc-code' => array('type' => ASN1::TYPE_NUMERIC_STRING), + 'iso-3166-alpha2-code' => array('type' => ASN1::TYPE_PRINTABLE_STRING) + ) + ); + + $AnotherName = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'type-id' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), + 'value' => array( + 'type' => ASN1::TYPE_ANY, + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ) + ) + ); + + $ExtensionAttribute = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'extension-attribute-type' => array( + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ), + 'extension-attribute-value' => array( + 'type' => ASN1::TYPE_ANY, + 'constant' => 1, + 'optional' => true, + 'explicit' => true + ) + ) + ); + + $ExtensionAttributes = array( + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => 256, // ub-extension-attributes + 'children' => $ExtensionAttribute + ); + + $BuiltInDomainDefinedAttribute = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'type' => array('type' => ASN1::TYPE_PRINTABLE_STRING), + 'value' => array('type' => ASN1::TYPE_PRINTABLE_STRING) + ) + ); + + $BuiltInDomainDefinedAttributes = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-domain-defined-attributes + 'children' => $BuiltInDomainDefinedAttribute + ); + + $BuiltInStandardAttributes = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'country-name' => array('optional' => true) + $CountryName, + 'administration-domain-name' => array('optional' => true) + $AdministrationDomainName, + 'network-address' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ) + $NetworkAddress, + 'terminal-identifier' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ) + $TerminalIdentifier, + 'private-domain-name' => array( + 'constant' => 2, + 'optional' => true, + 'explicit' => true + ) + $PrivateDomainName, + 'organization-name' => array( + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ) + $OrganizationName, + 'numeric-user-identifier' => array( + 'constant' => 4, + 'optional' => true, + 'implicit' => true + ) + $NumericUserIdentifier, + 'personal-name' => array( + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ) + $PersonalName, + 'organizational-unit-names' => array( + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ) + $OrganizationalUnitNames + ) + ); + + $ORAddress = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'built-in-standard-attributes' => $BuiltInStandardAttributes, + 'built-in-domain-defined-attributes' => array('optional' => true) + $BuiltInDomainDefinedAttributes, + 'extension-attributes' => array('optional' => true) + $ExtensionAttributes + ) + ); + + $EDIPartyName = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'nameAssigner' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ) + $this->DirectoryString, + // partyName is technically required but \phpseclib\File\ASN1 doesn't currently support non-optional constants and + // setting it to optional gets the job done in any event. + 'partyName' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ) + $this->DirectoryString + ) + ); + + $GeneralName = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'otherName' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ) + $AnotherName, + 'rfc822Name' => array( + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ), + 'dNSName' => array( + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ), + 'x400Address' => array( + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ) + $ORAddress, + 'directoryName' => array( + 'constant' => 4, + 'optional' => true, + 'explicit' => true + ) + $this->Name, + 'ediPartyName' => array( + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ) + $EDIPartyName, + 'uniformResourceIdentifier' => array( + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ), + 'iPAddress' => array( + 'type' => ASN1::TYPE_OCTET_STRING, + 'constant' => 7, + 'optional' => true, + 'implicit' => true + ), + 'registeredID' => array( + 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, + 'constant' => 8, + 'optional' => true, + 'implicit' => true + ) + ) + ); + + $GeneralNames = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $GeneralName + ); + + $this->IssuerAltName = $GeneralNames; + + $ReasonFlags = array( + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => array( + 'unused', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + 'privilegeWithdrawn', + 'aACompromise' + ) + ); + + $DistributionPointName = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'fullName' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ) + $GeneralNames, + 'nameRelativeToCRLIssuer' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ) + $this->RelativeDistinguishedName + ) + ); + + $DistributionPoint = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'distributionPoint' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ) + $DistributionPointName, + 'reasons' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ) + $ReasonFlags, + 'cRLIssuer' => array( + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ) + $GeneralNames + ) + ); + + $this->CRLDistributionPoints = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $DistributionPoint + ); + + $this->AuthorityKeyIdentifier = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'keyIdentifier' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ) + $this->KeyIdentifier, + 'authorityCertIssuer' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ) + $GeneralNames, + 'authorityCertSerialNumber' => array( + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ) + $CertificateSerialNumber + ) + ); + + $PolicyQualifierId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); + + $PolicyQualifierInfo = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'policyQualifierId' => $PolicyQualifierId, + 'qualifier' => array('type' => ASN1::TYPE_ANY) + ) + ); + + $CertPolicyId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); + + $PolicyInformation = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'policyIdentifier' => $CertPolicyId, + 'policyQualifiers' => array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 0, + 'max' => -1, + 'optional' => true, + 'children' => $PolicyQualifierInfo + ) + ) + ); + + $this->CertificatePolicies = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $PolicyInformation + ); + + $this->PolicyMappings = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'issuerDomainPolicy' => $CertPolicyId, + 'subjectDomainPolicy' => $CertPolicyId + ) + ) + ); + + $KeyPurposeId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); + + $this->ExtKeyUsageSyntax = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $KeyPurposeId + ); + + $AccessDescription = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'accessMethod' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), + 'accessLocation' => $GeneralName + ) + ); + + $this->AuthorityInfoAccessSyntax = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $AccessDescription + ); + + $this->SubjectInfoAccessSyntax = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $AccessDescription + ); + + $this->SubjectAltName = $GeneralNames; + + $this->PrivateKeyUsagePeriod = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'notBefore' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME), + 'notAfter' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME) + ) + ); + + $BaseDistance = array('type' => ASN1::TYPE_INTEGER); + + $GeneralSubtree = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'base' => $GeneralName, + 'minimum' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'default' => new BigInteger(0) + ) + $BaseDistance, + 'maximum' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + ) + $BaseDistance + ) + ); + + $GeneralSubtrees = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $GeneralSubtree + ); + + $this->NameConstraints = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'permittedSubtrees' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ) + $GeneralSubtrees, + 'excludedSubtrees' => array( + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ) + $GeneralSubtrees + ) + ); + + $this->CPSuri = array('type' => ASN1::TYPE_IA5_STRING); + + $DisplayText = array( + 'type' => ASN1::TYPE_CHOICE, + 'children' => array( + 'ia5String' => array('type' => ASN1::TYPE_IA5_STRING), + 'visibleString' => array('type' => ASN1::TYPE_VISIBLE_STRING), + 'bmpString' => array('type' => ASN1::TYPE_BMP_STRING), + 'utf8String' => array('type' => ASN1::TYPE_UTF8_STRING) + ) + ); + + $NoticeReference = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'organization' => $DisplayText, + 'noticeNumbers' => array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 200, + 'children' => array('type' => ASN1::TYPE_INTEGER) + ) + ) + ); + + $this->UserNotice = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'noticeRef' => array( + 'optional' => true, + 'implicit' => true + ) + $NoticeReference, + 'explicitText' => array( + 'optional' => true, + 'implicit' => true + ) + $DisplayText + ) + ); + + // mapping is from + $this->netscape_cert_type = array( + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => array( + 'SSLClient', + 'SSLServer', + 'Email', + 'ObjectSigning', + 'Reserved', + 'SSLCA', + 'EmailCA', + 'ObjectSigningCA' + ) + ); + + $this->netscape_comment = array('type' => ASN1::TYPE_IA5_STRING); + $this->netscape_ca_policy_url = array('type' => ASN1::TYPE_IA5_STRING); + + // attribute is used in RFC2986 but we're using the RFC5280 definition + + $Attribute = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'type' => $AttributeType, + 'value'=> array( + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => $this->AttributeValue + ) + ) + ); + + $this->SubjectDirectoryAttributes = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $Attribute + ); + + // adapted from + + $Attributes = array( + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => $Attribute + ); + + $CertificationRequestInfo = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'version' => array( + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => array('v1') + ), + 'subject' => $this->Name, + 'subjectPKInfo' => $SubjectPublicKeyInfo, + 'attributes' => array( + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ) + $Attributes, + ) + ); + + $this->CertificationRequest = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'certificationRequestInfo' => $CertificationRequestInfo, + 'signatureAlgorithm' => $AlgorithmIdentifier, + 'signature' => array('type' => ASN1::TYPE_BIT_STRING) + ) + ); + + $RevokedCertificate = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'userCertificate' => $CertificateSerialNumber, + 'revocationDate' => $Time, + 'crlEntryExtensions' => array( + 'optional' => true + ) + $this->Extensions + ) + ); + + $TBSCertList = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'version' => array( + 'optional' => true, + 'default' => 'v1' + ) + $Version, + 'signature' => $AlgorithmIdentifier, + 'issuer' => $this->Name, + 'thisUpdate' => $Time, + 'nextUpdate' => array( + 'optional' => true + ) + $Time, + 'revokedCertificates' => array( + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 0, + 'max' => -1, + 'children' => $RevokedCertificate + ), + 'crlExtensions' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ) + $this->Extensions + ) + ); + + $this->CertificateList = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'tbsCertList' => $TBSCertList, + 'signatureAlgorithm' => $AlgorithmIdentifier, + 'signature' => array('type' => ASN1::TYPE_BIT_STRING) + ) + ); + + $this->CRLNumber = array('type' => ASN1::TYPE_INTEGER); + + $this->CRLReason = array('type' => ASN1::TYPE_ENUMERATED, + 'mapping' => array( + 'unspecified', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + // Value 7 is not used. + 8 => 'removeFromCRL', + 'privilegeWithdrawn', + 'aACompromise' + ) + ); + + $this->IssuingDistributionPoint = array('type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'distributionPoint' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ) + $DistributionPointName, + 'onlyContainsUserCerts' => array( + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 1, + 'optional' => true, + 'default' => false, + 'implicit' => true + ), + 'onlyContainsCACerts' => array( + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 2, + 'optional' => true, + 'default' => false, + 'implicit' => true + ), + 'onlySomeReasons' => array( + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ) + $ReasonFlags, + 'indirectCRL' => array( + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 4, + 'optional' => true, + 'default' => false, + 'implicit' => true + ), + 'onlyContainsAttributeCerts' => array( + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 5, + 'optional' => true, + 'default' => false, + 'implicit' => true + ) + ) + ); + + $this->InvalidityDate = array('type' => ASN1::TYPE_GENERALIZED_TIME); + + $this->CertificateIssuer = $GeneralNames; + + $this->HoldInstructionCode = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); + + $PublicKeyAndChallenge = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'spki' => $SubjectPublicKeyInfo, + 'challenge' => array('type' => ASN1::TYPE_IA5_STRING) + ) + ); + + $this->SignedPublicKeyAndChallenge = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => array( + 'publicKeyAndChallenge' => $PublicKeyAndChallenge, + 'signatureAlgorithm' => $AlgorithmIdentifier, + 'signature' => array('type' => ASN1::TYPE_BIT_STRING) + ) + ); + + $this->PostalAddress = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 1, + 'max' => -1, + 'children' => $this->DirectoryString + ); + + // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 + $this->oids = array( + '1.3.6.1.5.5.7' => 'id-pkix', + '1.3.6.1.5.5.7.1' => 'id-pe', + '1.3.6.1.5.5.7.2' => 'id-qt', + '1.3.6.1.5.5.7.3' => 'id-kp', + '1.3.6.1.5.5.7.48' => 'id-ad', + '1.3.6.1.5.5.7.2.1' => 'id-qt-cps', + '1.3.6.1.5.5.7.2.2' => 'id-qt-unotice', + '1.3.6.1.5.5.7.48.1' =>'id-ad-ocsp', + '1.3.6.1.5.5.7.48.2' => 'id-ad-caIssuers', + '1.3.6.1.5.5.7.48.3' => 'id-ad-timeStamping', + '1.3.6.1.5.5.7.48.5' => 'id-ad-caRepository', + '2.5.4' => 'id-at', + '2.5.4.41' => 'id-at-name', + '2.5.4.4' => 'id-at-surname', + '2.5.4.42' => 'id-at-givenName', + '2.5.4.43' => 'id-at-initials', + '2.5.4.44' => 'id-at-generationQualifier', + '2.5.4.3' => 'id-at-commonName', + '2.5.4.7' => 'id-at-localityName', + '2.5.4.8' => 'id-at-stateOrProvinceName', + '2.5.4.10' => 'id-at-organizationName', + '2.5.4.11' => 'id-at-organizationalUnitName', + '2.5.4.12' => 'id-at-title', + '2.5.4.13' => 'id-at-description', + '2.5.4.46' => 'id-at-dnQualifier', + '2.5.4.6' => 'id-at-countryName', + '2.5.4.5' => 'id-at-serialNumber', + '2.5.4.65' => 'id-at-pseudonym', + '2.5.4.17' => 'id-at-postalCode', + '2.5.4.9' => 'id-at-streetAddress', + '2.5.4.45' => 'id-at-uniqueIdentifier', + '2.5.4.72' => 'id-at-role', + '2.5.4.16' => 'id-at-postalAddress', + + '0.9.2342.19200300.100.1.25' => 'id-domainComponent', + '1.2.840.113549.1.9' => 'pkcs-9', + '1.2.840.113549.1.9.1' => 'pkcs-9-at-emailAddress', + '2.5.29' => 'id-ce', + '2.5.29.35' => 'id-ce-authorityKeyIdentifier', + '2.5.29.14' => 'id-ce-subjectKeyIdentifier', + '2.5.29.15' => 'id-ce-keyUsage', + '2.5.29.16' => 'id-ce-privateKeyUsagePeriod', + '2.5.29.32' => 'id-ce-certificatePolicies', + '2.5.29.32.0' => 'anyPolicy', + + '2.5.29.33' => 'id-ce-policyMappings', + '2.5.29.17' => 'id-ce-subjectAltName', + '2.5.29.18' => 'id-ce-issuerAltName', + '2.5.29.9' => 'id-ce-subjectDirectoryAttributes', + '2.5.29.19' => 'id-ce-basicConstraints', + '2.5.29.30' => 'id-ce-nameConstraints', + '2.5.29.36' => 'id-ce-policyConstraints', + '2.5.29.31' => 'id-ce-cRLDistributionPoints', + '2.5.29.37' => 'id-ce-extKeyUsage', + '2.5.29.37.0' => 'anyExtendedKeyUsage', + '1.3.6.1.5.5.7.3.1' => 'id-kp-serverAuth', + '1.3.6.1.5.5.7.3.2' => 'id-kp-clientAuth', + '1.3.6.1.5.5.7.3.3' => 'id-kp-codeSigning', + '1.3.6.1.5.5.7.3.4' => 'id-kp-emailProtection', + '1.3.6.1.5.5.7.3.8' => 'id-kp-timeStamping', + '1.3.6.1.5.5.7.3.9' => 'id-kp-OCSPSigning', + '2.5.29.54' => 'id-ce-inhibitAnyPolicy', + '2.5.29.46' => 'id-ce-freshestCRL', + '1.3.6.1.5.5.7.1.1' => 'id-pe-authorityInfoAccess', + '1.3.6.1.5.5.7.1.11' => 'id-pe-subjectInfoAccess', + '2.5.29.20' => 'id-ce-cRLNumber', + '2.5.29.28' => 'id-ce-issuingDistributionPoint', + '2.5.29.27' => 'id-ce-deltaCRLIndicator', + '2.5.29.21' => 'id-ce-cRLReasons', + '2.5.29.29' => 'id-ce-certificateIssuer', + '2.5.29.23' => 'id-ce-holdInstructionCode', + '1.2.840.10040.2' => 'holdInstruction', + '1.2.840.10040.2.1' => 'id-holdinstruction-none', + '1.2.840.10040.2.2' => 'id-holdinstruction-callissuer', + '1.2.840.10040.2.3' => 'id-holdinstruction-reject', + '2.5.29.24' => 'id-ce-invalidityDate', + + '1.2.840.113549.2.2' => 'md2', + '1.2.840.113549.2.5' => 'md5', + '1.3.14.3.2.26' => 'id-sha1', + '1.2.840.10040.4.1' => 'id-dsa', + '1.2.840.10040.4.3' => 'id-dsa-with-sha1', + '1.2.840.113549.1.1' => 'pkcs-1', + '1.2.840.113549.1.1.1' => 'rsaEncryption', + '1.2.840.113549.1.1.2' => 'md2WithRSAEncryption', + '1.2.840.113549.1.1.4' => 'md5WithRSAEncryption', + '1.2.840.113549.1.1.5' => 'sha1WithRSAEncryption', + '1.2.840.10046.2.1' => 'dhpublicnumber', + '2.16.840.1.101.2.1.1.22' => 'id-keyExchangeAlgorithm', + '1.2.840.10045' => 'ansi-X9-62', + '1.2.840.10045.4' => 'id-ecSigType', + '1.2.840.10045.4.1' => 'ecdsa-with-SHA1', + '1.2.840.10045.1' => 'id-fieldType', + '1.2.840.10045.1.1' => 'prime-field', + '1.2.840.10045.1.2' => 'characteristic-two-field', + '1.2.840.10045.1.2.3' => 'id-characteristic-two-basis', + '1.2.840.10045.1.2.3.1' => 'gnBasis', + '1.2.840.10045.1.2.3.2' => 'tpBasis', + '1.2.840.10045.1.2.3.3' => 'ppBasis', + '1.2.840.10045.2' => 'id-publicKeyType', + '1.2.840.10045.2.1' => 'id-ecPublicKey', + '1.2.840.10045.3' => 'ellipticCurve', + '1.2.840.10045.3.0' => 'c-TwoCurve', + '1.2.840.10045.3.0.1' => 'c2pnb163v1', + '1.2.840.10045.3.0.2' => 'c2pnb163v2', + '1.2.840.10045.3.0.3' => 'c2pnb163v3', + '1.2.840.10045.3.0.4' => 'c2pnb176w1', + '1.2.840.10045.3.0.5' => 'c2pnb191v1', + '1.2.840.10045.3.0.6' => 'c2pnb191v2', + '1.2.840.10045.3.0.7' => 'c2pnb191v3', + '1.2.840.10045.3.0.8' => 'c2pnb191v4', + '1.2.840.10045.3.0.9' => 'c2pnb191v5', + '1.2.840.10045.3.0.10' => 'c2pnb208w1', + '1.2.840.10045.3.0.11' => 'c2pnb239v1', + '1.2.840.10045.3.0.12' => 'c2pnb239v2', + '1.2.840.10045.3.0.13' => 'c2pnb239v3', + '1.2.840.10045.3.0.14' => 'c2pnb239v4', + '1.2.840.10045.3.0.15' => 'c2pnb239v5', + '1.2.840.10045.3.0.16' => 'c2pnb272w1', + '1.2.840.10045.3.0.17' => 'c2pnb304w1', + '1.2.840.10045.3.0.18' => 'c2pnb359v1', + '1.2.840.10045.3.0.19' => 'c2pnb368w1', + '1.2.840.10045.3.0.20' => 'c2pnb431r1', + '1.2.840.10045.3.1' => 'primeCurve', + '1.2.840.10045.3.1.1' => 'prime192v1', + '1.2.840.10045.3.1.2' => 'prime192v2', + '1.2.840.10045.3.1.3' => 'prime192v3', + '1.2.840.10045.3.1.4' => 'prime239v1', + '1.2.840.10045.3.1.5' => 'prime239v2', + '1.2.840.10045.3.1.6' => 'prime239v3', + '1.2.840.10045.3.1.7' => 'prime256v1', + '1.2.840.113549.1.1.7' => 'id-RSAES-OAEP', + '1.2.840.113549.1.1.9' => 'id-pSpecified', + '1.2.840.113549.1.1.10' => 'id-RSASSA-PSS', + '1.2.840.113549.1.1.8' => 'id-mgf1', + '1.2.840.113549.1.1.14' => 'sha224WithRSAEncryption', + '1.2.840.113549.1.1.11' => 'sha256WithRSAEncryption', + '1.2.840.113549.1.1.12' => 'sha384WithRSAEncryption', + '1.2.840.113549.1.1.13' => 'sha512WithRSAEncryption', + '2.16.840.1.101.3.4.2.4' => 'id-sha224', + '2.16.840.1.101.3.4.2.1' => 'id-sha256', + '2.16.840.1.101.3.4.2.2' => 'id-sha384', + '2.16.840.1.101.3.4.2.3' => 'id-sha512', + '1.2.643.2.2.4' => 'id-GostR3411-94-with-GostR3410-94', + '1.2.643.2.2.3' => 'id-GostR3411-94-with-GostR3410-2001', + '1.2.643.2.2.20' => 'id-GostR3410-2001', + '1.2.643.2.2.19' => 'id-GostR3410-94', + // Netscape Object Identifiers from "Netscape Certificate Extensions" + '2.16.840.1.113730' => 'netscape', + '2.16.840.1.113730.1' => 'netscape-cert-extension', + '2.16.840.1.113730.1.1' => 'netscape-cert-type', + '2.16.840.1.113730.1.13' => 'netscape-comment', + '2.16.840.1.113730.1.8' => 'netscape-ca-policy-url', + // the following are X.509 extensions not supported by phpseclib + '1.3.6.1.5.5.7.1.12' => 'id-pe-logotype', + '1.2.840.113533.7.65.0' => 'entrustVersInfo', + '2.16.840.1.113733.1.6.9' => 'verisignPrivate', + // for Certificate Signing Requests + // see http://tools.ietf.org/html/rfc2985 + '1.2.840.113549.1.9.2' => 'pkcs-9-at-unstructuredName', // PKCS #9 unstructured name + '1.2.840.113549.1.9.7' => 'pkcs-9-at-challengePassword', // Challenge password for certificate revocations + '1.2.840.113549.1.9.14' => 'pkcs-9-at-extensionRequest' // Certificate extension request + ); } /** @@ -474,7 +1462,7 @@ class X509 * @access public * @return mixed */ - public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) + function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($cert) && isset($cert['tbsCertificate'])) { unset($this->currentCert); @@ -493,8 +1481,10 @@ class X509 return $cert; } + $asn1 = new ASN1(); + if ($mode != self::FORMAT_DER) { - $newcert = ASN1::extractBER($cert); + $newcert = $this->_extractBER($cert); if ($mode == self::FORMAT_PEM && $cert == $newcert) { return false; } @@ -506,10 +1496,11 @@ class X509 return false; } - $decoded = ASN1::decodeBER($cert); + $asn1->loadOIDs($this->oids); + $decoded = $asn1->decodeBER($cert); if (!empty($decoded)) { - $x509 = ASN1::asn1map($decoded[0], Maps\Certificate::MAP); + $x509 = $asn1->asn1map($decoded[0], $this->Certificate); } if (!isset($x509) || $x509 === false) { $this->currentCert = false; @@ -518,18 +1509,14 @@ class X509 $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - if ($this->isSubArrayValid($x509, 'tbsCertificate/extensions')) { - $this->mapInExtensions($x509, 'tbsCertificate/extensions'); + if ($this->_isSubArrayValid($x509, 'tbsCertificate/extensions')) { + $this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1); } - $this->mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence'); - $this->mapInDNs($x509, 'tbsCertificate/subject/rdnSequence'); + $this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1); + $this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1); - $key = $x509['tbsCertificate']['subjectPublicKeyInfo']; - $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); - $x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = - "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($key), 64) . - "-----END PUBLIC KEY-----"; + $key = &$x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']; + $key = $this->_reformatKey($x509['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $key); $this->currentCert = $x509; $this->dn = $x509['tbsCertificate']['subject']; @@ -548,7 +1535,7 @@ class X509 * @access public * @return string */ - public function saveX509($cert, $format = self::FORMAT_PEM) + function saveX509($cert, $format = self::FORMAT_PEM) { if (!is_array($cert) || !isset($cert['tbsCertificate'])) { return false; @@ -556,22 +1543,32 @@ class X509 switch (true) { // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()" - case !($algorithm = $this->subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): + case !($algorithm = $this->_subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): break; default: - $cert['tbsCertificate']['subjectPublicKeyInfo'] = new Element( - base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])) - ); + switch ($algorithm) { + case 'rsaEncryption': + $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] + = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); + /* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier." + -- https://tools.ietf.org/html/rfc3279#section-2.3.1 + + given that and the fact that RSA keys appear ot be the only key type for which the parameters field can be blank, + it seems like perhaps the ASN.1 description ought not say the parameters field is OPTIONAL, but whatever. + */ + $cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = null; + // https://tools.ietf.org/html/rfc3279#section-2.2.1 + $cert['signatureAlgorithm']['parameters'] = null; + $cert['tbsCertificate']['signature']['parameters'] = null; + } } - if ($algorithm == 'rsaEncryption') { - $cert['signatureAlgorithm']['parameters'] = null; - $cert['tbsCertificate']['signature']['parameters'] = null; - } + $asn1 = new ASN1(); + $asn1->loadOIDs($this->oids); - $filters = []; - $type_utf8_string = ['type' => ASN1::TYPE_UTF8_STRING]; + $filters = array(); + $type_utf8_string = array('type' => ASN1::TYPE_UTF8_STRING); $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string; $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string; $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string; @@ -583,31 +1580,27 @@ class X509 $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string; $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string; - foreach (self::$extensions as $extension) { - $filters['tbsCertificate']['extensions'][] = $extension; - } - - /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib3\File\ASN1::TYPE_IA5_STRING. - \phpseclib3\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random + /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib\File\ASN1::TYPE_IA5_STRING. + \phpseclib\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random characters. */ $filters['policyQualifiers']['qualifier'] - = ['type' => ASN1::TYPE_IA5_STRING]; + = array('type' => ASN1::TYPE_IA5_STRING); - ASN1::setFilters($filters); + $asn1->loadFilters($filters); - $this->mapOutExtensions($cert, 'tbsCertificate/extensions'); - $this->mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence'); - $this->mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence'); + $this->_mapOutExtensions($cert, 'tbsCertificate/extensions', $asn1); + $this->_mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence', $asn1); + $this->_mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence', $asn1); - $cert = ASN1::encodeDER($cert, Maps\Certificate::MAP); + $cert = $asn1->encodeDER($cert, $this->Certificate); switch ($format) { case self::FORMAT_DER: return $cert; // case self::FORMAT_PEM: default: - return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Base64::encode($cert), 64) . '-----END CERTIFICATE-----'; + return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert), 64) . '-----END CERTIFICATE-----'; } } @@ -617,25 +1610,27 @@ class X509 * * @param array $root (by reference) * @param string $path + * @param object $asn1 * @access private */ - private function mapInExtensions(&$root, $path) + function _mapInExtensions(&$root, $path, $asn1) { - $extensions = &$this->subArrayUnchecked($root, $path); + $extensions = &$this->_subArrayUnchecked($root, $path); if ($extensions) { for ($i = 0; $i < count($extensions); $i++) { $id = $extensions[$i]['extnId']; $value = &$extensions[$i]['extnValue']; - $decoded = ASN1::decodeBER($value); + $value = base64_decode($value); + $decoded = $asn1->decodeBER($value); /* [extnValue] contains the DER encoding of an ASN.1 value corresponding to the extension type identified by extnID */ - $map = $this->getMapping($id); + $map = $this->_getMapping($id); if (!is_bool($map)) { $decoder = $id == 'id-ce-nameConstraints' ? - [static::class, 'decodeNameConstraintIP'] : - [static::class, 'decodeIP']; - $mapped = ASN1::asn1map($decoded[0], $map, ['iPAddress' => $decoder]); + array($this, '_decodeNameConstraintIP') : + array($this, '_decodeIP'); + $mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => $decoder)); $value = $mapped === false ? $decoded[0] : $mapped; if ($id == 'id-ce-certificatePolicies') { @@ -645,16 +1640,18 @@ class X509 } for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; - $map = $this->getMapping($subid); + $map = $this->_getMapping($subid); $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; if ($map !== false) { - $decoded = ASN1::decodeBER($subvalue); - $mapped = ASN1::asn1map($decoded[0], $map); + $decoded = $asn1->decodeBER($subvalue); + $mapped = $asn1->asn1map($decoded[0], $map); $subvalue = $mapped === false ? $decoded[0] : $mapped; } } } } + } else { + $value = base64_encode($value); } } } @@ -666,18 +1663,12 @@ class X509 * * @param array $root (by reference) * @param string $path + * @param object $asn1 * @access private */ - private function mapOutExtensions(&$root, $path) + function _mapOutExtensions(&$root, $path, $asn1) { - foreach ($this->extensionValues as $id => $value) { - $root['tbsCertificate']['extensions'][] = [ - 'extnId' => $id, - 'extnValue' => $value, - ]; - } - - $extensions = &$this->subArray($root, $path); + $extensions = &$this->_subArray($root, $path); if (is_array($extensions)) { $size = count($extensions); @@ -697,12 +1688,12 @@ class X509 } for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; - $map = $this->getMapping($subid); + $map = $this->_getMapping($subid); $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; if ($map !== false) { - // by default \phpseclib3\File\ASN1 will try to render qualifier as a \phpseclib3\File\ASN1::TYPE_IA5_STRING since it's - // actual type is \phpseclib3\File\ASN1::TYPE_ANY - $subvalue = new Element(ASN1::encodeDER($subvalue, $map)); + // by default \phpseclib\File\ASN1 will try to render qualifier as a \phpseclib\File\ASN1::TYPE_IA5_STRING since it's + // actual type is \phpseclib\File\ASN1::TYPE_ANY + $subvalue = new Element($asn1->encodeDER($subvalue, $map)); } } } @@ -718,14 +1709,15 @@ class X509 /* [extnValue] contains the DER encoding of an ASN.1 value corresponding to the extension type identified by extnID */ - $map = $this->getMapping($id); + $map = $this->_getMapping($id); if (is_bool($map)) { if (!$map) { - //user_error($id . ' is not a currently supported extension'); + user_error($id . ' is not a currently supported extension'); unset($extensions[$i]); } } else { - $value = ASN1::encodeDER($value, $map, ['iPAddress' => [static::class, 'encodeIP']]); + $temp = $asn1->encodeDER($value, $map, array('iPAddress' => array($this, '_encodeIP'))); + $value = base64_encode($temp); } } } @@ -737,33 +1729,34 @@ class X509 * * @param array $root (by reference) * @param string $path + * @param object $asn1 * @access private */ - private function mapInAttributes(&$root, $path) + function _mapInAttributes(&$root, $path, $asn1) { - $attributes = &$this->subArray($root, $path); + $attributes = &$this->_subArray($root, $path); if (is_array($attributes)) { for ($i = 0; $i < count($attributes); $i++) { $id = $attributes[$i]['type']; /* $value contains the DER encoding of an ASN.1 value corresponding to the attribute type identified by type */ - $map = $this->getMapping($id); + $map = $this->_getMapping($id); if (is_array($attributes[$i]['value'])) { $values = &$attributes[$i]['value']; for ($j = 0; $j < count($values); $j++) { - $value = ASN1::encodeDER($values[$j], Maps\AttributeValue::MAP); - $decoded = ASN1::decodeBER($value); + $value = $asn1->encodeDER($values[$j], $this->AttributeValue); + $decoded = $asn1->decodeBER($value); if (!is_bool($map)) { - $mapped = ASN1::asn1map($decoded[0], $map); + $mapped = $asn1->asn1map($decoded[0], $map); if ($mapped !== false) { $values[$j] = $mapped; } - if ($id == 'pkcs-9-at-extensionRequest' && $this->isSubArrayValid($values, $j)) { - $this->mapInExtensions($values, $j); + if ($id == 'pkcs-9-at-extensionRequest' && $this->_isSubArrayValid($values, $j)) { + $this->_mapInExtensions($values, $j, $asn1); } } elseif ($map) { - $values[$j] = $value; + $values[$j] = base64_encode($value); } } } @@ -777,11 +1770,12 @@ class X509 * * @param array $root (by reference) * @param string $path + * @param object $asn1 * @access private */ - private function mapOutAttributes(&$root, $path) + function _mapOutAttributes(&$root, $path, $asn1) { - $attributes = &$this->subArray($root, $path); + $attributes = &$this->_subArray($root, $path); if (is_array($attributes)) { $size = count($attributes); @@ -789,23 +1783,23 @@ class X509 /* [value] contains the DER encoding of an ASN.1 value corresponding to the attribute type identified by type */ $id = $attributes[$i]['type']; - $map = $this->getMapping($id); + $map = $this->_getMapping($id); if ($map === false) { - //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); + user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); unset($attributes[$i]); } elseif (is_array($attributes[$i]['value'])) { $values = &$attributes[$i]['value']; for ($j = 0; $j < count($values); $j++) { switch ($id) { case 'pkcs-9-at-extensionRequest': - $this->mapOutExtensions($values, $j); + $this->_mapOutExtensions($values, $j, $asn1); break; } if (!is_bool($map)) { - $temp = ASN1::encodeDER($values[$j], $map); - $decoded = ASN1::decodeBER($temp); - $values[$j] = ASN1::asn1map($decoded[0], Maps\AttributeValue::MAP); + $temp = $asn1->encodeDER($values[$j], $map); + $decoded = $asn1->decodeBER($temp); + $values[$j] = $asn1->asn1map($decoded[0], $this->AttributeValue); } } } @@ -819,11 +1813,12 @@ class X509 * * @param array $root (by reference) * @param string $path + * @param object $asn1 * @access private */ - private function mapInDNs(&$root, $path) + function _mapInDNs(&$root, $path, $asn1) { - $dns = &$this->subArray($root, $path); + $dns = &$this->_subArray($root, $path); if (is_array($dns)) { for ($i = 0; $i < count($dns); $i++) { @@ -831,10 +1826,10 @@ class X509 $type = $dns[$i][$j]['type']; $value = &$dns[$i][$j]['value']; if (is_object($value) && $value instanceof Element) { - $map = $this->getMapping($type); + $map = $this->_getMapping($type); if (!is_bool($map)) { - $decoded = ASN1::decodeBER($value); - $value = ASN1::asn1map($decoded[0], $map); + $decoded = $asn1->decodeBER($value); + $value = $asn1->asn1map($decoded[0], $map); } } } @@ -848,11 +1843,12 @@ class X509 * * @param array $root (by reference) * @param string $path + * @param object $asn1 * @access private */ - private function mapOutDNs(&$root, $path) + function _mapOutDNs(&$root, $path, $asn1) { - $dns = &$this->subArray($root, $path); + $dns = &$this->_subArray($root, $path); if (is_array($dns)) { $size = count($dns); @@ -864,9 +1860,9 @@ class X509 continue; } - $map = $this->getMapping($type); + $map = $this->_getMapping($type); if (!is_bool($map)) { - $value = new Element(ASN1::encodeDER($value, $map)); + $value = new Element($asn1->encodeDER($value, $map)); } } } @@ -880,59 +1876,57 @@ class X509 * @access private * @return mixed */ - private function getMapping($extnId) + function _getMapping($extnId) { - if (!is_string($extnId)) { // eg. if it's a \phpseclib3\File\ASN1\Element object + if (!is_string($extnId)) { // eg. if it's a \phpseclib\File\ASN1\Element object return true; } - if (isset(self::$extensions[$extnId])) { - return self::$extensions[$extnId]; - } - switch ($extnId) { case 'id-ce-keyUsage': - return Maps\KeyUsage::MAP; + return $this->KeyUsage; case 'id-ce-basicConstraints': - return Maps\BasicConstraints::MAP; + return $this->BasicConstraints; case 'id-ce-subjectKeyIdentifier': - return Maps\KeyIdentifier::MAP; + return $this->KeyIdentifier; case 'id-ce-cRLDistributionPoints': - return Maps\CRLDistributionPoints::MAP; + return $this->CRLDistributionPoints; case 'id-ce-authorityKeyIdentifier': - return Maps\AuthorityKeyIdentifier::MAP; + return $this->AuthorityKeyIdentifier; case 'id-ce-certificatePolicies': - return Maps\CertificatePolicies::MAP; + return $this->CertificatePolicies; case 'id-ce-extKeyUsage': - return Maps\ExtKeyUsageSyntax::MAP; + return $this->ExtKeyUsageSyntax; case 'id-pe-authorityInfoAccess': - return Maps\AuthorityInfoAccessSyntax::MAP; + return $this->AuthorityInfoAccessSyntax; + case 'id-pe-subjectInfoAccess': + return $this->SubjectInfoAccessSyntax; case 'id-ce-subjectAltName': - return Maps\SubjectAltName::MAP; + return $this->SubjectAltName; case 'id-ce-subjectDirectoryAttributes': - return Maps\SubjectDirectoryAttributes::MAP; + return $this->SubjectDirectoryAttributes; case 'id-ce-privateKeyUsagePeriod': - return Maps\PrivateKeyUsagePeriod::MAP; + return $this->PrivateKeyUsagePeriod; case 'id-ce-issuerAltName': - return Maps\IssuerAltName::MAP; + return $this->IssuerAltName; case 'id-ce-policyMappings': - return Maps\PolicyMappings::MAP; + return $this->PolicyMappings; case 'id-ce-nameConstraints': - return Maps\NameConstraints::MAP; + return $this->NameConstraints; case 'netscape-cert-type': - return Maps\netscape_cert_type::MAP; + return $this->netscape_cert_type; case 'netscape-comment': - return Maps\netscape_comment::MAP; + return $this->netscape_comment; case 'netscape-ca-policy-url': - return Maps\netscape_ca_policy_url::MAP; + return $this->netscape_ca_policy_url; // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets // back around to asn1map() and we don't want it decoded again. //case 'id-qt-cps': - // return Maps\CPSuri::MAP; + // return $this->CPSuri; case 'id-qt-unotice': - return Maps\UserNotice::MAP; + return $this->UserNotice; // the following OIDs are unsupported but we don't want them to give notices when calling saveX509(). case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt @@ -953,31 +1947,31 @@ class X509 // CSR attributes case 'pkcs-9-at-unstructuredName': - return Maps\PKCS9String::MAP; + return $this->PKCS9String; case 'pkcs-9-at-challengePassword': - return Maps\DirectoryString::MAP; + return $this->DirectoryString; case 'pkcs-9-at-extensionRequest': - return Maps\Extensions::MAP; + return $this->Extensions; // CRL extensions. case 'id-ce-cRLNumber': - return Maps\CRLNumber::MAP; + return $this->CRLNumber; case 'id-ce-deltaCRLIndicator': - return Maps\CRLNumber::MAP; + return $this->CRLNumber; case 'id-ce-issuingDistributionPoint': - return Maps\IssuingDistributionPoint::MAP; + return $this->IssuingDistributionPoint; case 'id-ce-freshestCRL': - return Maps\CRLDistributionPoints::MAP; + return $this->CRLDistributionPoints; case 'id-ce-cRLReasons': - return Maps\CRLReason::MAP; + return $this->CRLReason; case 'id-ce-invalidityDate': - return Maps\InvalidityDate::MAP; + return $this->InvalidityDate; case 'id-ce-certificateIssuer': - return Maps\CertificateIssuer::MAP; + return $this->CertificateIssuer; case 'id-ce-holdInstructionCode': - return Maps\HoldInstructionCode::MAP; + return $this->HoldInstructionCode; case 'id-at-postalAddress': - return Maps\PostalAddress::MAP; + return $this->PostalAddress; } return false; @@ -990,7 +1984,7 @@ class X509 * @access public * @return bool */ - public function loadCA($cert) + function loadCA($cert) { $olddn = $this->dn; $oldcert = $this->currentCert; @@ -1057,7 +2051,7 @@ class X509 * @access public * @return bool */ - public function validateURL($url) + function validateURL($url) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; @@ -1071,7 +2065,7 @@ class X509 if ($names = $this->getExtension('id-ce-subjectAltName')) { foreach ($names as $name) { foreach ($name as $key => $value) { - $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value); + $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value); switch ($key) { case 'dNSName': /* From RFC2818 "HTTP over TLS": @@ -1101,7 +2095,7 @@ class X509 } if ($value = $this->getDNProp('id-at-commonName')) { - $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value[0]); + $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value[0]); return preg_match('#^' . $value . '$#', $components['host']); } @@ -1113,18 +2107,17 @@ class X509 * * If $date isn't defined it is assumed to be the current date. * - * @param DateTimeInterface|string $date optional + * @param \DateTime|string $date optional * @access public - * @return boolean */ - public function validateDate($date = null) + function validateDate($date = null) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; } if (!isset($date)) { - $date = new DateTimeImmutable(null, new DateTimeZone(@date_default_timezone_get())); + $date = new DateTime(null, new DateTimeZone(@date_default_timezone_get())); } $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore']; @@ -1134,13 +2127,19 @@ class X509 $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime']; if (is_string($date)) { - $date = new DateTimeImmutable($date, new DateTimeZone(@date_default_timezone_get())); + $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get())); } - $notBefore = new DateTimeImmutable($notBefore, new DateTimeZone(@date_default_timezone_get())); - $notAfter = new DateTimeImmutable($notAfter, new DateTimeZone(@date_default_timezone_get())); + $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get())); + $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get())); - return $date >= $notBefore && $date<= $notAfter; + switch (true) { + case $date < $notBefore: + case $date > $notAfter: + return false; + } + + return true; } /** @@ -1150,7 +2149,7 @@ class X509 * @access private * @return bool|string */ - private static function fetchURL($url) + static function _fetchURL($url) { if (self::$disable_url_fetch) { return false; @@ -1206,7 +2205,7 @@ class X509 * @access private * @return bool */ - private function testForIntermediate($caonly, $count) + function _testForIntermediate($caonly, $count) { $opts = $this->getExtension('id-pe-authorityInfoAccess'); if (!is_array($opts)) { @@ -1228,7 +2227,7 @@ class X509 return false; } - $cert = static::fetchURL($url); + $cert = static::_fetchURL($url); if (!is_string($cert)) { return false; } @@ -1248,7 +2247,7 @@ class X509 return false; } - if (!$parent->validateSignatureCountable($caonly, ++$count)) { + if (!$parent->_validateSignatureCountable($caonly, ++$count)) { return false; } @@ -1273,9 +2272,9 @@ class X509 * @access public * @return mixed */ - public function validateSignature($caonly = true) + function validateSignature($caonly = true) { - return $this->validateSignatureCountable($caonly, 0); + return $this->_validateSignatureCountable($caonly, 0); } /** @@ -1288,7 +2287,7 @@ class X509 * @access private * @return mixed */ - private function validateSignatureCountable($caonly, $count) + function _validateSignatureCountable($caonly, $count) { if (!is_array($this->currentCert) || !isset($this->signatureSubject)) { return null; @@ -1343,32 +2342,32 @@ class X509 } } if (count($this->CAs) == $i && $caonly) { - return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly); } } elseif (!isset($signingCert) || $caonly) { - return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly); } - return $this->validateSignatureHelper( + return $this->_validateSignature( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), + substr(base64_decode($this->currentCert['signature']), 1), $this->signatureSubject ); case isset($this->currentCert['certificationRequestInfo']): - return $this->validateSignatureHelper( + return $this->_validateSignature( $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'], $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), + substr(base64_decode($this->currentCert['signature']), 1), $this->signatureSubject ); case isset($this->currentCert['publicKeyAndChallenge']): - return $this->validateSignatureHelper( + return $this->_validateSignature( $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'], $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), + substr(base64_decode($this->currentCert['signature']), 1), $this->signatureSubject ); case isset($this->currentCert['tbsCertList']): @@ -1396,11 +2395,11 @@ class X509 if (!isset($signingCert)) { return false; } - return $this->validateSignatureHelper( + return $this->_validateSignature( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), + substr(base64_decode($this->currentCert['signature']), 1), $this->signatureSubject ); default: @@ -1411,8 +2410,7 @@ class X509 /** * Validates a signature * - * Returns true if the signature is verified and false if it is not correct. - * If the algorithms are unsupposed an exception is thrown. + * Returns true if the signature is verified, false if it is not correct or null on error * * @param string $publicKeyAlgorithm * @param string $publicKey @@ -1420,17 +2418,15 @@ class X509 * @param string $signature * @param string $signatureSubject * @access private - * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported - * @return bool + * @return int */ - private function validateSignatureHelper($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) + function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) { switch ($publicKeyAlgorithm) { - case 'id-RSASSA-PSS': - $key = RSA::loadFormat('PSS', $publicKey); - break; case 'rsaEncryption': - $key = RSA::loadFormat('PKCS8', $publicKey); + $rsa = new RSA(); + $rsa->loadKey($publicKey); + switch ($signatureAlgorithm) { case 'md2WithRSAEncryption': case 'md5WithRSAEncryption': @@ -1439,51 +2435,21 @@ class X509 case 'sha256WithRSAEncryption': case 'sha384WithRSAEncryption': case 'sha512WithRSAEncryption': - $key = $key - ->withHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)) - ->withPadding(RSA::SIGNATURE_PKCS1); - break; - default: - throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); - } - break; - case 'id-Ed25519': - case 'id-Ed448': - $key = EC::loadFormat('PKCS8', $publicKey); - break; - case 'id-ecPublicKey': - $key = EC::loadFormat('PKCS8', $publicKey); - switch ($signatureAlgorithm) { - case 'ecdsa-with-SHA1': - case 'ecdsa-with-SHA224': - case 'ecdsa-with-SHA256': - case 'ecdsa-with-SHA384': - case 'ecdsa-with-SHA512': - $key = $key - ->withHash(preg_replace('#^ecdsa-with-#', '', strtolower($signatureAlgorithm))); - break; - default: - throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); - } - break; - case 'id-dsa': - $key = DSA::loadFormat('PKCS8', $publicKey); - switch ($signatureAlgorithm) { - case 'id-dsa-with-sha1': - case 'id-dsa-with-sha224': - case 'id-dsa-with-sha256': - $key = $key - ->withHash(preg_replace('#^id-dsa-with-#', '', strtolower($signatureAlgorithm))); + $rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)); + $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); + if (!@$rsa->verify($signatureSubject, $signature)) { + return false; + } break; default: - throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + return null; } break; default: - throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); + return null; } - return $key->verify($signatureSubject, $signature); + return true; } /** @@ -1496,7 +2462,7 @@ class X509 * @param int $count * @access public */ - public static function setRecurLimit($count) + static function setRecurLimit($count) { self::$recur_limit = $count; } @@ -1506,7 +2472,7 @@ class X509 * * @access public */ - public static function disableURLFetch() + static function disableURLFetch() { self::$disable_url_fetch = true; } @@ -1516,11 +2482,37 @@ class X509 * * @access public */ - public static function enableURLFetch() + static function enableURLFetch() { self::$disable_url_fetch = false; } + /** + * Reformat public keys + * + * Reformats a public key to a format supported by phpseclib (if applicable) + * + * @param string $algorithm + * @param string $key + * @access private + * @return string + */ + function _reformatKey($algorithm, $key) + { + switch ($algorithm) { + case 'rsaEncryption': + return + "-----BEGIN RSA PUBLIC KEY-----\r\n" . + // subjectPublicKey is stored as a bit string in X.509 certs. the first byte of a bit string represents how many bits + // in the last byte should be ignored. the following only supports non-zero stuff but as none of the X.509 certs Firefox + // uses as a cert authority actually use a non-zero bit I think it's safe to assume that none do. + chunk_split(base64_encode(substr(base64_decode($key), 1)), 64) . + '-----END RSA PUBLIC KEY-----'; + default: + return $key; + } + } + /** * Decodes an IP address * @@ -1530,9 +2522,9 @@ class X509 * @access private * @return string */ - public static function decodeIP($ip) + function _decodeIP($ip) { - return inet_ntop($ip); + return inet_ntop(base64_decode($ip)); } /** @@ -1544,12 +2536,13 @@ class X509 * @access private * @return array */ - public static function decodeNameConstraintIP($ip) + function _decodeNameConstraintIP($ip) { + $ip = base64_decode($ip); $size = strlen($ip) >> 1; $mask = substr($ip, $size); $ip = substr($ip, 0, $size); - return [inet_ntop($ip), inet_ntop($mask)]; + return array(inet_ntop($ip), inet_ntop($mask)); } /** @@ -1561,11 +2554,11 @@ class X509 * @access private * @return string */ - public static function encodeIP($ip) + function _encodeIP($ip) { return is_string($ip) ? - inet_pton($ip) : - inet_pton($ip[0]) . inet_pton($ip[1]); + base64_encode(inet_pton($ip)) : + base64_encode(inet_pton($ip[0]) . inet_pton($ip[1])); } /** @@ -1575,7 +2568,7 @@ class X509 * @access private * @return mixed */ - private function translateDNProp($propName) + function _translateDNProp($propName) { switch (strtolower($propName)) { case 'id-at-countryname': @@ -1669,26 +2662,26 @@ class X509 * @access public * @return bool */ - public function setDNProp($propName, $propValue, $type = 'utf8String') + function setDNProp($propName, $propValue, $type = 'utf8String') { if (empty($this->dn)) { - $this->dn = ['rdnSequence' => []]; + $this->dn = array('rdnSequence' => array()); } - if (($propName = $this->translateDNProp($propName)) === false) { + if (($propName = $this->_translateDNProp($propName)) === false) { return false; } foreach ((array) $propValue as $v) { if (!is_array($v) && isset($type)) { - $v = [$type => $v]; + $v = array($type => $v); } - $this->dn['rdnSequence'][] = [ - [ + $this->dn['rdnSequence'][] = array( + array( 'type' => $propName, 'value'=> $v - ] - ]; + ) + ); } return true; @@ -1700,13 +2693,13 @@ class X509 * @param string $propName * @access public */ - public function removeDNProp($propName) + function removeDNProp($propName) { if (empty($this->dn)) { return; } - if (($propName = $this->translateDNProp($propName)) === false) { + if (($propName = $this->_translateDNProp($propName)) === false) { return; } @@ -1734,7 +2727,7 @@ class X509 * @return mixed * @access public */ - public function getDNProp($propName, $dn = null, $withType = false) + function getDNProp($propName, $dn = null, $withType = false) { if (!isset($dn)) { $dn = $this->dn; @@ -1744,25 +2737,27 @@ class X509 return false; } - if (($propName = $this->translateDNProp($propName)) === false) { + if (($propName = $this->_translateDNProp($propName)) === false) { return false; } - $filters = []; - $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); - $this->mapOutDNs($dn, 'rdnSequence'); + $asn1 = new ASN1(); + $asn1->loadOIDs($this->oids); + $filters = array(); + $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING); + $asn1->loadFilters($filters); + $this->_mapOutDNs($dn, 'rdnSequence', $asn1); $dn = $dn['rdnSequence']; - $result = []; + $result = array(); for ($i = 0; $i < count($dn); $i++) { if ($dn[$i][0]['type'] == $propName) { $v = $dn[$i][0]['value']; if (!$withType) { if (is_array($v)) { foreach ($v as $type => $s) { - $type = array_search($type, ASN1::ANY_MAP); - if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { - $s = ASN1::convert($s, $type); + $type = array_search($type, $asn1->ANYmap, true); + if ($type !== false && isset($asn1->stringTypeSize[$type])) { + $s = $asn1->convert($s, $type); if ($s !== false) { $v = $s; break; @@ -1773,10 +2768,10 @@ class X509 $v = array_pop($v); // Always strip data type. } } elseif (is_object($v) && $v instanceof Element) { - $map = $this->getMapping($propName); + $map = $this->_getMapping($propName); if (!is_bool($map)) { - $decoded = ASN1::decodeBER($v); - $v = ASN1::asn1map($decoded[0], $map); + $decoded = $asn1->decodeBER($v); + $v = $asn1->asn1map($decoded[0], $map); } } } @@ -1796,7 +2791,7 @@ class X509 * @access public * @return bool */ - public function setDN($dn, $merge = false, $type = 'utf8String') + function setDN($dn, $merge = false, $type = 'utf8String') { if (!$merge) { $this->dn = null; @@ -1836,9 +2831,9 @@ class X509 * @param mixed $format optional * @param array $dn optional * @access public - * @return array|bool + * @return bool */ - public function getDN($format = self::DN_ARRAY, $dn = null) + function getDN($format = self::DN_ARRAY, $dn = null) { if (!isset($dn)) { $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; @@ -1848,28 +2843,32 @@ class X509 case self::DN_ARRAY: return $dn; case self::DN_ASN1: - $filters = []; - $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); - $this->mapOutDNs($dn, 'rdnSequence'); - return ASN1::encodeDER($dn, Maps\Name::MAP); + $asn1 = new ASN1(); + $asn1->loadOIDs($this->oids); + $filters = array(); + $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING); + $asn1->loadFilters($filters); + $this->_mapOutDNs($dn, 'rdnSequence', $asn1); + return $asn1->encodeDER($dn, $this->Name); case self::DN_CANON: // No SEQUENCE around RDNs and all string values normalized as // trimmed lowercase UTF-8 with all spacing as one blank. // constructed RDNs will not be canonicalized - $filters = []; - $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); + $asn1 = new ASN1(); + $asn1->loadOIDs($this->oids); + $filters = array(); + $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING); + $asn1->loadFilters($filters); $result = ''; - $this->mapOutDNs($dn, 'rdnSequence'); + $this->_mapOutDNs($dn, 'rdnSequence', $asn1); foreach ($dn['rdnSequence'] as $rdn) { foreach ($rdn as $i => $attr) { $attr = &$rdn[$i]; if (is_array($attr['value'])) { foreach ($attr['value'] as $type => $v) { - $type = array_search($type, ASN1::ANY_MAP, true); - if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { - $v = ASN1::convert($v, $type); + $type = array_search($type, $asn1->ANYmap, true); + if ($type !== false && isset($asn1->stringTypeSize[$type])) { + $v = $asn1->convert($v, $type); if ($v !== false) { $v = preg_replace('/\s+/', ' ', $v); $attr['value'] = strtolower(trim($v)); @@ -1879,7 +2878,7 @@ class X509 } } } - $result .= ASN1::encodeDER($rdn, Maps\RelativeDistinguishedName::MAP); + $result .= $asn1->encodeDER($rdn, $this->RelativeDistinguishedName); } return $result; case self::DN_HASH: @@ -1887,18 +2886,20 @@ class X509 $hash = new Hash('sha1'); $hash = $hash->hash($dn); extract(unpack('Vhash', $hash)); - return strtolower(Hex::encode(pack('N', $hash))); + return strtolower(bin2hex(pack('N', $hash))); } // Default is to return a string. $start = true; $output = ''; - $result = []; - $filters = []; - $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); - $this->mapOutDNs($dn, 'rdnSequence'); + $result = array(); + $asn1 = new ASN1(); + $asn1->loadOIDs($this->oids); + $filters = array(); + $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING); + $asn1->loadFilters($filters); + $this->_mapOutDNs($dn, 'rdnSequence', $asn1); foreach ($dn['rdnSequence'] as $field) { $prop = $field[0]['type']; @@ -1945,9 +2946,9 @@ class X509 } if (is_array($value)) { foreach ($value as $type => $v) { - $type = array_search($type, ASN1::ANY_MAP, true); - if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { - $v = ASN1::convert($v, $type); + $type = array_search($type, $asn1->ANYmap, true); + if ($type !== false && isset($asn1->stringTypeSize[$type])) { + $v = $asn1->convert($v, $type); if ($v !== false) { $value = $v; break; @@ -1958,12 +2959,14 @@ class X509 $value = array_pop($value); // Always strip data type. } } elseif (is_object($value) && $value instanceof Element) { - $callback = function($x) { return '\x' . bin2hex($x[0]); }; + $callback = function ($x) { + return "\x" . bin2hex($x[0]); + }; $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element)); } $output.= $desc . '=' . $value; $result[$desc] = isset($result[$desc]) ? - array_merge((array) $result[$desc], [$value]) : + array_merge((array) $result[$desc], array($value)) : $value; $start = false; } @@ -1978,7 +2981,7 @@ class X509 * @access public * @return mixed */ - public function getIssuerDN($format = self::DN_ARRAY) + function getIssuerDN($format = self::DN_ARRAY) { switch (true) { case !isset($this->currentCert) || !is_array($this->currentCert): @@ -2000,7 +3003,7 @@ class X509 * @access public * @return mixed */ - public function getSubjectDN($format = self::DN_ARRAY) + function getSubjectDN($format = self::DN_ARRAY) { switch (true) { case !empty($this->dn): @@ -2024,7 +3027,7 @@ class X509 * @access public * @return mixed */ - public function getIssuerDNProp($propName, $withType = false) + function getIssuerDNProp($propName, $withType = false) { switch (true) { case !isset($this->currentCert) || !is_array($this->currentCert): @@ -2046,7 +3049,7 @@ class X509 * @access public * @return mixed */ - public function getSubjectDNProp($propName, $withType = false) + function getSubjectDNProp($propName, $withType = false) { switch (true) { case !empty($this->dn): @@ -2068,9 +3071,9 @@ class X509 * @access public * @return mixed */ - public function getChain() + function getChain() { - $chain = [$this->currentCert]; + $chain = array($this->currentCert); if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; @@ -2110,26 +3113,27 @@ class X509 /** * Set public key * - * Key needs to be a \phpseclib3\Crypt\RSA object + * Key needs to be a \phpseclib\Crypt\RSA object * - * @param PublicKey $key + * @param object $key * @access public * @return bool */ - public function setPublicKey(PublicKey $key) + function setPublicKey($key) { + $key->setPublicKey(); $this->publicKey = $key; } /** * Set private key * - * Key needs to be a \phpseclib3\Crypt\RSA object + * Key needs to be a \phpseclib\Crypt\RSA object * - * @param PrivateKey $key + * @param object $key * @access public */ - public function setPrivateKey(PrivateKey $key) + function setPrivateKey($key) { $this->privateKey = $key; } @@ -2142,7 +3146,7 @@ class X509 * @param string $challenge * @access public */ - public function setChallenge($challenge) + function setChallenge($challenge) { $this->challenge = $challenge; } @@ -2150,25 +3154,20 @@ class X509 /** * Gets the public key * - * Returns a \phpseclib3\Crypt\RSA object or a false. + * Returns a \phpseclib\Crypt\RSA object or a false. * * @access public * @return mixed */ - public function getPublicKey() + function getPublicKey() { if (isset($this->publicKey)) { return $this->publicKey; } if (isset($this->currentCert) && is_array($this->currentCert)) { - $paths = [ - 'tbsCertificate/subjectPublicKeyInfo', - 'certificationRequestInfo/subjectPKInfo', - 'publicKeyAndChallenge/spki' - ]; - foreach ($paths as $path) { - $keyinfo = $this->subArray($this->currentCert, $path); + foreach (array('tbsCertificate/subjectPublicKeyInfo', 'certificationRequestInfo/subjectPKInfo') as $path) { + $keyinfo = $this->_subArray($this->currentCert, $path); if (!empty($keyinfo)) { break; } @@ -2182,27 +3181,26 @@ class X509 switch ($keyinfo['algorithm']['algorithm']) { case 'rsaEncryption': - return RSA::loadFormat('PKCS8', $key); - case 'id-ecPublicKey': - case 'id-Ed25519': - case 'id-Ed448': - return EC::loadFormat('PKCS8', $key); - case 'id-dsa': - return DSA::loadFormat('PKCS8', $key); + $publicKey = new RSA(); + $publicKey->loadKey($key); + $publicKey->setPublicKey(); + break; + default: + return false; } - return false; + return $publicKey; } /** * Load a Certificate Signing Request * - * @param string $csr + * @param string|array $csr * @param int $mode - * @return mixed * @access public + * @return mixed */ - public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) + function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($csr) && isset($csr['certificationRequestInfo'])) { unset($this->currentCert); @@ -2219,8 +3217,10 @@ class X509 // see http://tools.ietf.org/html/rfc2986 + $asn1 = new ASN1(); + if ($mode != self::FORMAT_DER) { - $newcsr = ASN1::extractBER($csr); + $newcsr = $this->_extractBER($csr); if ($mode == self::FORMAT_PEM && $csr == $newcsr) { return false; } @@ -2233,39 +3233,44 @@ class X509 return false; } - $decoded = ASN1::decodeBER($csr); + $asn1->loadOIDs($this->oids); + $decoded = $asn1->decodeBER($csr); if (empty($decoded)) { $this->currentCert = false; return false; } - $csr = ASN1::asn1map($decoded[0], Maps\CertificationRequest::MAP); + $csr = $asn1->asn1map($decoded[0], $this->CertificationRequest); if (!isset($csr) || $csr === false) { $this->currentCert = false; return false; } - $this->mapInAttributes($csr, 'certificationRequestInfo/attributes'); - $this->mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); + $this->_mapInAttributes($csr, 'certificationRequestInfo/attributes', $asn1); + $this->_mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1); $this->dn = $csr['certificationRequestInfo']['subject']; $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - $key = $csr['certificationRequestInfo']['subjectPKInfo']; - $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); - $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = - "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($key), 64) . - "-----END PUBLIC KEY-----"; + $algorithm = &$csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm']; + $key = &$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']; + $key = $this->_reformatKey($algorithm, $key); + + switch ($algorithm) { + case 'rsaEncryption': + $this->publicKey = new RSA(); + $this->publicKey->loadKey($key); + $this->publicKey->setPublicKey(); + break; + default: + $this->publicKey = null; + } $this->currentKeyIdentifier = null; $this->currentCert = $csr; - $this->publicKey = null; - $this->publicKey = $this->getPublicKey(); - return $csr; } @@ -2277,38 +3282,47 @@ class X509 * @access public * @return string */ - public function saveCSR($csr, $format = self::FORMAT_PEM) + function saveCSR($csr, $format = self::FORMAT_PEM) { if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) { return false; } switch (true) { - case !($algorithm = $this->subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): + case !($algorithm = $this->_subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): break; default: - $csr['certificationRequestInfo']['subjectPKInfo'] = new Element( - base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])) - ); + switch ($algorithm) { + case 'rsaEncryption': + $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] + = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']))); + $csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['parameters'] = null; + $csr['signatureAlgorithm']['parameters'] = null; + $csr['certificationRequestInfo']['signature']['parameters'] = null; + } } - $filters = []; + $asn1 = new ASN1(); + + $asn1->loadOIDs($this->oids); + + $filters = array(); $filters['certificationRequestInfo']['subject']['rdnSequence']['value'] - = ['type' => ASN1::TYPE_UTF8_STRING]; + = array('type' => ASN1::TYPE_UTF8_STRING); - ASN1::setFilters($filters); + $asn1->loadFilters($filters); - $this->mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); - $this->mapOutAttributes($csr, 'certificationRequestInfo/attributes'); - $csr = ASN1::encodeDER($csr, Maps\CertificationRequest::MAP); + $this->_mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1); + $this->_mapOutAttributes($csr, 'certificationRequestInfo/attributes', $asn1); + $csr = $asn1->encodeDER($csr, $this->CertificationRequest); switch ($format) { case self::FORMAT_DER: return $csr; // case self::FORMAT_PEM: default: - return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Base64::encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; + return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; } } @@ -2319,11 +3333,11 @@ class X509 * * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen * - * @param string $spkac + * @param string|array $spkac * @access public * @return mixed */ - public function loadSPKAC($spkac) + function loadSPKAC($spkac) { if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) { unset($this->currentCert); @@ -2335,9 +3349,11 @@ class X509 // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge + $asn1 = new ASN1(); + // OpenSSL produces SPKAC's that are preceded by the string SPKAC= $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false; + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; if ($temp != false) { $spkac = $temp; } @@ -2348,14 +3364,15 @@ class X509 return false; } - $decoded = ASN1::decodeBER($spkac); + $asn1->loadOIDs($this->oids); + $decoded = $asn1->decodeBER($spkac); if (empty($decoded)) { $this->currentCert = false; return false; } - $spkac = ASN1::asn1map($decoded[0], Maps\SignedPublicKeyAndChallenge::MAP); + $spkac = $asn1->asn1map($decoded[0], $this->SignedPublicKeyAndChallenge); if (!isset($spkac) || $spkac === false) { $this->currentCert = false; @@ -2364,48 +3381,57 @@ class X509 $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - $key = $spkac['publicKeyAndChallenge']['spki']; - $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); - $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] = - "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($key), 64) . - "-----END PUBLIC KEY-----"; + $algorithm = &$spkac['publicKeyAndChallenge']['spki']['algorithm']['algorithm']; + $key = &$spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']; + $key = $this->_reformatKey($algorithm, $key); + + switch ($algorithm) { + case 'rsaEncryption': + $this->publicKey = new RSA(); + $this->publicKey->loadKey($key); + $this->publicKey->setPublicKey(); + break; + default: + $this->publicKey = null; + } $this->currentKeyIdentifier = null; $this->currentCert = $spkac; - $this->publicKey = null; - $this->publicKey = $this->getPublicKey(); - return $spkac; } /** * Save a SPKAC CSR request * - * @param array $spkac + * @param string|array $spkac * @param int $format optional * @access public * @return string */ - public function saveSPKAC($spkac, $format = self::FORMAT_PEM) + function saveSPKAC($spkac, $format = self::FORMAT_PEM) { if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) { return false; } - $algorithm = $this->subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); + $algorithm = $this->_subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); switch (true) { case !$algorithm: case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']): break; default: - $spkac['publicKeyAndChallenge']['spki'] = new Element( - base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])) - ); + switch ($algorithm) { + case 'rsaEncryption': + $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] + = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']))); + } } - $spkac = ASN1::encodeDER($spkac, Maps\SignedPublicKeyAndChallenge::MAP); + $asn1 = new ASN1(); + + $asn1->loadOIDs($this->oids); + $spkac = $asn1->encodeDER($spkac, $this->SignedPublicKeyAndChallenge); switch ($format) { case self::FORMAT_DER: @@ -2414,7 +3440,7 @@ class X509 default: // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much // no other SPKAC decoders phpseclib will use that same format - return 'SPKAC=' . Base64::encode($spkac); + return 'SPKAC=' . base64_encode($spkac); } } @@ -2423,10 +3449,10 @@ class X509 * * @param string $crl * @param int $mode - * @return mixed * @access public + * @return mixed */ - public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) + function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($crl) && isset($crl['tbsCertList'])) { $this->currentCert = $crl; @@ -2434,8 +3460,10 @@ class X509 return $crl; } + $asn1 = new ASN1(); + if ($mode != self::FORMAT_DER) { - $newcrl = ASN1::extractBER($crl); + $newcrl = $this->_extractBER($crl); if ($mode == self::FORMAT_PEM && $crl == $newcrl) { return false; } @@ -2448,14 +3476,15 @@ class X509 return false; } - $decoded = ASN1::decodeBER($crl); + $asn1->loadOIDs($this->oids); + $decoded = $asn1->decodeBER($crl); if (empty($decoded)) { $this->currentCert = false; return false; } - $crl = ASN1::asn1map($decoded[0], Maps\CertificateList::MAP); + $crl = $asn1->asn1map($decoded[0], $this->CertificateList); if (!isset($crl) || $crl === false) { $this->currentCert = false; return false; @@ -2463,17 +3492,17 @@ class X509 $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - $this->mapInDNs($crl, 'tbsCertList/issuer/rdnSequence'); - if ($this->isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { - $this->mapInExtensions($crl, 'tbsCertList/crlExtensions'); + $this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1); + if ($this->_isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { + $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1); } - if ($this->isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { - $rclist_ref = &$this->subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); + if ($this->_isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { + $rclist_ref = &$this->_subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); if ($rclist_ref) { $rclist = $crl['tbsCertList']['revokedCertificates']; foreach ($rclist as $i => $extension) { - if ($this->isSubArrayValid($rclist, "$i/crlEntryExtensions")) { - $this->mapInExtensions($rclist_ref, "$i/crlEntryExtensions"); + if ($this->_isSubArrayValid($rclist, "$i/crlEntryExtensions", $asn1)) { + $this->_mapInExtensions($rclist_ref, "$i/crlEntryExtensions", $asn1); } } } @@ -2493,49 +3522,53 @@ class X509 * @access public * @return string */ - public function saveCRL($crl, $format = self::FORMAT_PEM) + function saveCRL($crl, $format = self::FORMAT_PEM) { if (!is_array($crl) || !isset($crl['tbsCertList'])) { return false; } - $filters = []; + $asn1 = new ASN1(); + + $asn1->loadOIDs($this->oids); + + $filters = array(); $filters['tbsCertList']['issuer']['rdnSequence']['value'] - = ['type' => ASN1::TYPE_UTF8_STRING]; + = array('type' => ASN1::TYPE_UTF8_STRING); $filters['tbsCertList']['signature']['parameters'] - = ['type' => ASN1::TYPE_UTF8_STRING]; + = array('type' => ASN1::TYPE_UTF8_STRING); $filters['signatureAlgorithm']['parameters'] - = ['type' => ASN1::TYPE_UTF8_STRING]; + = array('type' => ASN1::TYPE_UTF8_STRING); if (empty($crl['tbsCertList']['signature']['parameters'])) { $filters['tbsCertList']['signature']['parameters'] - = ['type' => ASN1::TYPE_NULL]; + = array('type' => ASN1::TYPE_NULL); } if (empty($crl['signatureAlgorithm']['parameters'])) { $filters['signatureAlgorithm']['parameters'] - = ['type' => ASN1::TYPE_NULL]; + = array('type' => ASN1::TYPE_NULL); } - ASN1::setFilters($filters); + $asn1->loadFilters($filters); - $this->mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence'); - $this->mapOutExtensions($crl, 'tbsCertList/crlExtensions'); - $rclist = &$this->subArray($crl, 'tbsCertList/revokedCertificates'); + $this->_mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1); + $this->_mapOutExtensions($crl, 'tbsCertList/crlExtensions', $asn1); + $rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates'); if (is_array($rclist)) { foreach ($rclist as $i => $extension) { - $this->mapOutExtensions($rclist, "$i/crlEntryExtensions"); + $this->_mapOutExtensions($rclist, "$i/crlEntryExtensions", $asn1); } } - $crl = ASN1::encodeDER($crl, Maps\CertificateList::MAP); + $crl = $asn1->encodeDER($crl, $this->CertificateList); switch ($format) { case self::FORMAT_DER: return $crl; // case self::FORMAT_PEM: default: - return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Base64::encode($crl), 64) . '-----END X509 CRL-----'; + return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl), 64) . '-----END X509 CRL-----'; } } @@ -2549,19 +3582,19 @@ class X509 * * @param string $date in format date('D, d M Y H:i:s O') * @access private - * @return array|Element + * @return array */ - private function timeField($date) + function _timeField($date) { if ($date instanceof Element) { return $date; } - $dateObj = new DateTimeImmutable($date, new DateTimeZone('GMT')); + $dateObj = new DateTime($date, new DateTimeZone('GMT')); $year = $dateObj->format('Y'); // the same way ASN1.php parses this if ($year < 2050) { - return ['utcTime' => $date]; + return array('utcTime' => $date); } else { - return ['generalTime' => $date]; + return array('generalTime' => $date); } } @@ -2572,45 +3605,35 @@ class X509 * $subject can be either an existing X.509 cert (if you want to resign it), * a CSR or something with the DN and public key explicitly set. * - * @param \phpseclib3\File\X509 $issuer - * @param \phpseclib3\File\X509 $subject + * @param \phpseclib\File\X509 $issuer + * @param \phpseclib\File\X509 $subject + * @param string $signatureAlgorithm optional * @access public * @return mixed */ - public function sign($issuer, $subject) + function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption') { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { return false; } - if (isset($subject->publicKey) && !($subjectPublicKey = $subject->formatSubjectPublicKey())) { + if (isset($subject->publicKey) && !($subjectPublicKey = $subject->_formatSubjectPublicKey())) { return false; } $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); - if ($signatureAlgorithm != 'id-RSASSA-PSS') { - $signatureAlgorithm = ['algorithm' => $signatureAlgorithm]; - } else { - $r = PSS::load($issuer->privateKey->toString('PSS')); - $signatureAlgorithm = [ - 'algorithm' => 'id-RSASSA-PSS', - 'parameters' => PSS::savePSSParams($r) - ]; - } + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null; if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) { $this->currentCert = $subject->currentCert; - $this->currentCert['tbsCertificate']['signature'] = $signatureAlgorithm; - $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; - + $this->currentCert['tbsCertificate']['signature']['algorithm'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; if (!empty($this->startDate)) { - $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->timeField($this->startDate); + $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->_timeField($this->startDate); } if (!empty($this->endDate)) { - $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->timeField($this->endDate); + $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->_timeField($this->endDate); } if (!empty($this->serialNumber)) { $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber; @@ -2632,10 +3655,10 @@ class X509 return false; } - $startDate = new DateTimeImmutable('now', new DateTimeZone(@date_default_timezone_get())); + $startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get())); $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O'); - $endDate = new DateTimeImmutable('+1 year', new DateTimeZone(@date_default_timezone_get())); + $endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get())); $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O'); /* "The serial number MUST be a positive integer" @@ -2649,23 +3672,23 @@ class X509 $this->serialNumber : new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256); - $this->currentCert = [ + $this->currentCert = array( 'tbsCertificate' => - [ + array( 'version' => 'v3', 'serialNumber' => $serialNumber, // $this->setSerialNumber() - 'signature' => $signatureAlgorithm, + 'signature' => array('algorithm' => $signatureAlgorithm), 'issuer' => false, // this is going to be overwritten later - 'validity' => [ - 'notBefore' => $this->timeField($startDate), // $this->setStartDate() - 'notAfter' => $this->timeField($endDate) // $this->setEndDate() - ], + 'validity' => array( + 'notBefore' => $this->_timeField($startDate), // $this->setStartDate() + 'notAfter' => $this->_timeField($endDate) // $this->setEndDate() + ), 'subject' => $subject->dn, 'subjectPublicKeyInfo' => $subjectPublicKey - ], - 'signatureAlgorithm' => $signatureAlgorithm, + ), + 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), 'signature' => false // this is going to be overwritten later - ]; + ); // Copy extensions from CSR. $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0); @@ -2678,14 +3701,14 @@ class X509 $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn; if (isset($issuer->currentKeyIdentifier)) { - $this->setExtension('id-ce-authorityKeyIdentifier', [ + $this->setExtension('id-ce-authorityKeyIdentifier', array( //'authorityCertIssuer' => array( // array( // 'directoryName' => $issuer->dn // ) //), 'keyIdentifier' => $issuer->currentKeyIdentifier - ]); + )); //$extensions = &$this->currentCert['tbsCertificate']['extensions']; //if (isset($issuer->serialNumber)) { // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; @@ -2697,18 +3720,18 @@ class X509 $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier); } - $altName = []; + $altName = array(); if (isset($subject->domains) && count($subject->domains)) { - $altName = array_map(['\phpseclib3\File\X509', 'dnsName'], $subject->domains); + $altName = array_map(array('\phpseclib\File\X509', '_dnsName'), $subject->domains); } if (isset($subject->ipAddresses) && count($subject->ipAddresses)) { // should an IP address appear as the CN if no domain name is specified? idk //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1); - $ipAddresses = []; + $ipAddresses = array(); foreach ($subject->ipAddresses as $ipAddress) { - $encoded = $subject->ipAddress($ipAddress); + $encoded = $subject->_ipAddress($ipAddress); if ($encoded !== false) { $ipAddresses[] = $encoded; } @@ -2725,37 +3748,36 @@ class X509 if ($this->caFlag) { $keyUsage = $this->getExtension('id-ce-keyUsage'); if (!$keyUsage) { - $keyUsage = []; + $keyUsage = array(); } $this->setExtension( 'id-ce-keyUsage', - array_values(array_unique(array_merge($keyUsage, ['cRLSign', 'keyCertSign']))) + array_values(array_unique(array_merge($keyUsage, array('cRLSign', 'keyCertSign')))) ); $basicConstraints = $this->getExtension('id-ce-basicConstraints'); if (!$basicConstraints) { - $basicConstraints = []; + $basicConstraints = array(); } $this->setExtension( 'id-ce-basicConstraints', - array_unique(array_merge(['cA' => true], $basicConstraints)), + array_unique(array_merge(array('cA' => true), $basicConstraints)), true ); if (!isset($subject->currentKeyIdentifier)) { - $this->setExtension('id-ce-subjectKeyIdentifier', $this->computeKeyIdentifier($this->currentCert), false, false); + $this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false); } } // resync $this->signatureSubject - // save $tbsCertificate in case there are any \phpseclib3\File\ASN1\Element objects in it + // save $tbsCertificate in case there are any \phpseclib\File\ASN1\Element objects in it $tbsCertificate = $this->currentCert['tbsCertificate']; $this->loadX509($this->saveX509($this->currentCert)); - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); + $result = $this->_sign($issuer->privateKey, $signatureAlgorithm); $result['tbsCertificate'] = $tbsCertificate; $this->currentCert = $currentCert; @@ -2770,20 +3792,24 @@ class X509 * @access public * @return mixed */ - public function signCSR() + function signCSR($signatureAlgorithm = 'sha1WithRSAEncryption') { if (!is_object($this->privateKey) || empty($this->dn)) { return false; } $origPublicKey = $this->publicKey; - $this->publicKey = $this->privateKey->getPublicKey(); - $publicKey = $this->formatSubjectPublicKey(); + $class = get_class($this->privateKey); + $this->publicKey = new $class(); + $this->publicKey->loadKey($this->privateKey->getPublicKey()); + $this->publicKey->setPublicKey(); + if (!($publicKey = $this->_formatSubjectPublicKey())) { + return false; + } $this->publicKey = $origPublicKey; $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null; if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) { $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; @@ -2792,25 +3818,24 @@ class X509 } $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey; } else { - $this->currentCert = [ + $this->currentCert = array( 'certificationRequestInfo' => - [ + array( 'version' => 'v1', 'subject' => $this->dn, 'subjectPKInfo' => $publicKey - ], - 'signatureAlgorithm' => ['algorithm' => $signatureAlgorithm], + ), + 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), 'signature' => false // this is going to be overwritten later - ]; + ); } // resync $this->signatureSubject - // save $certificationRequestInfo in case there are any \phpseclib3\File\ASN1\Element objects in it + // save $certificationRequestInfo in case there are any \phpseclib\File\ASN1\Element objects in it $certificationRequestInfo = $this->currentCert['certificationRequestInfo']; $this->loadCSR($this->saveCSR($this->currentCert)); - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); + $result = $this->_sign($this->privateKey, $signatureAlgorithm); $result['certificationRequestInfo'] = $certificationRequestInfo; $this->currentCert = $currentCert; @@ -2825,20 +3850,25 @@ class X509 * @access public * @return mixed */ - public function signSPKAC() + function signSPKAC($signatureAlgorithm = 'sha1WithRSAEncryption') { if (!is_object($this->privateKey)) { return false; } $origPublicKey = $this->publicKey; - $this->publicKey = $this->privateKey->getPublicKey(); - $publicKey = $this->formatSubjectPublicKey(); + $class = get_class($this->privateKey); + $this->publicKey = new $class(); + $this->publicKey->loadKey($this->privateKey->getPublicKey()); + $this->publicKey->setPublicKey(); + $publicKey = $this->_formatSubjectPublicKey(); + if (!$publicKey) { + return false; + } $this->publicKey = $origPublicKey; $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null; // re-signing a SPKAC seems silly but since everything else supports re-signing why not? if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) { @@ -2849,9 +3879,9 @@ class X509 $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge)); } } else { - $this->currentCert = [ + $this->currentCert = array( 'publicKeyAndChallenge' => - [ + array( 'spki' => $publicKey, // quoting , // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified." @@ -2859,19 +3889,18 @@ class X509 // we could alternatively do this instead if we ignored the specs: // Random::string(8) & str_repeat("\x7F", 8) 'challenge' => !empty($this->challenge) ? $this->challenge : '' - ], - 'signatureAlgorithm' => ['algorithm' => $signatureAlgorithm], + ), + 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), 'signature' => false // this is going to be overwritten later - ]; + ); } // resync $this->signatureSubject - // save $publicKeyAndChallenge in case there are any \phpseclib3\File\ASN1\Element objects in it + // save $publicKeyAndChallenge in case there are any \phpseclib\File\ASN1\Element objects in it $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge']; $this->loadSPKAC($this->saveSPKAC($this->currentCert)); - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); + $result = $this->_sign($this->privateKey, $signatureAlgorithm); $result['publicKeyAndChallenge'] = $publicKeyAndChallenge; $this->currentCert = $currentCert; @@ -2885,12 +3914,13 @@ class X509 * * $issuer's private key needs to be loaded. * - * @param \phpseclib3\File\X509 $issuer - * @param \phpseclib3\File\X509 $crl + * @param \phpseclib\File\X509 $issuer + * @param \phpseclib\File\X509 $crl + * @param string $signatureAlgorithm optional * @access public * @return mixed */ - public function signCRL($issuer, $crl) + function signCRL($issuer, $crl, $signatureAlgorithm = 'sha1WithRSAEncryption') { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { return false; @@ -2898,9 +3928,8 @@ class X509 $currentCert = isset($this->currentCert) ? $this->currentCert : null; $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); - $thisUpdate = new DateTimeImmutable('now', new DateTimeZone(@date_default_timezone_get())); + $thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get())); $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O'); if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) { @@ -2908,25 +3937,25 @@ class X509 $this->currentCert['tbsCertList']['signature']['algorithm'] = $signatureAlgorithm; $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; } else { - $this->currentCert = [ + $this->currentCert = array( 'tbsCertList' => - [ + array( 'version' => 'v2', - 'signature' => ['algorithm' => $signatureAlgorithm], + 'signature' => array('algorithm' => $signatureAlgorithm), 'issuer' => false, // this is going to be overwritten later - 'thisUpdate' => $this->timeField($thisUpdate) // $this->setStartDate() - ], - 'signatureAlgorithm' => ['algorithm' => $signatureAlgorithm], + 'thisUpdate' => $this->_timeField($thisUpdate) // $this->setStartDate() + ), + 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), 'signature' => false // this is going to be overwritten later - ]; + ); } $tbsCertList = &$this->currentCert['tbsCertList']; $tbsCertList['issuer'] = $issuer->dn; - $tbsCertList['thisUpdate'] = $this->timeField($thisUpdate); + $tbsCertList['thisUpdate'] = $this->_timeField($thisUpdate); if (!empty($this->endDate)) { - $tbsCertList['nextUpdate'] = $this->timeField($this->endDate); // $this->setEndDate() + $tbsCertList['nextUpdate'] = $this->_timeField($this->endDate); // $this->setEndDate() } else { unset($tbsCertList['nextUpdate']); } @@ -2971,14 +4000,14 @@ class X509 } if (isset($issuer->currentKeyIdentifier)) { - $this->setExtension('id-ce-authorityKeyIdentifier', [ + $this->setExtension('id-ce-authorityKeyIdentifier', array( //'authorityCertIssuer' => array( - // ] + // array( // 'directoryName' => $issuer->dn - // ] + // ) //), 'keyIdentifier' => $issuer->currentKeyIdentifier - ]); + )); //$extensions = &$tbsCertList['crlExtensions']; //if (isset($issuer->serialNumber)) { // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; @@ -3000,12 +4029,11 @@ class X509 unset($tbsCertList); // resync $this->signatureSubject - // save $tbsCertList in case there are any \phpseclib3\File\ASN1\Element objects in it + // save $tbsCertList in case there are any \phpseclib\File\ASN1\Element objects in it $tbsCertList = $this->currentCert['tbsCertList']; $this->loadCRL($this->saveCRL($this->currentCert)); - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); + $result = $this->_sign($issuer->privateKey, $signatureAlgorithm); $result['tbsCertList'] = $tbsCertList; $this->currentCert = $currentCert; @@ -3015,72 +4043,45 @@ class X509 } /** - * Identify signature algorithm from key settings + * X.509 certificate signing helper function. * - * @param PrivateKey $key - * @access private - * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported - * @return string + * @param \phpseclib\File\X509 $key + * @param string $signatureAlgorithm + * @access public + * @return mixed */ - private static function identifySignatureAlgorithm(PrivateKey $key) + function _sign($key, $signatureAlgorithm) { if ($key instanceof RSA) { - if ($key->getPadding() & RSA::SIGNATURE_PSS) { - return 'id-RSASSA-PSS'; + switch ($signatureAlgorithm) { + case 'md2WithRSAEncryption': + case 'md5WithRSAEncryption': + case 'sha1WithRSAEncryption': + case 'sha224WithRSAEncryption': + case 'sha256WithRSAEncryption': + case 'sha384WithRSAEncryption': + case 'sha512WithRSAEncryption': + $key->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)); + $key->setSignatureMode(RSA::SIGNATURE_PKCS1); + + $this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject)); + return $this->currentCert; } - switch ($key->getHash()) { - case 'md2': - case 'md5': - case 'sha1': - case 'sha224': - case 'sha256': - case 'sha384': - case 'sha512': - return $key->getHash() . 'WithRSAEncryption'; - } - throw new UnsupportedAlgorithmException('The only supported hash algorithms for RSA are: md2, md5, sha1, sha224, sha256, sha384, sha512'); - } - - if ($key instanceof DSA) { - switch ($key->getHash()) { - case 'sha1': - case 'sha224': - case 'sha256': - return 'id-dsa-with-' . $key->getHash(); - } - throw new UnsupportedAlgorithmException('The only supported hash algorithms for DSA are: sha1, sha224, sha256'); - } - - if ($key instanceof EC) { - switch ($key->getCurve()) { - case 'Ed25519': - case 'Ed448': - return 'id-' . $key->getCurve(); - } - switch ($key->getHash()) { - case 'sha1': - case 'sha224': - case 'sha256': - case 'sha384': - case 'sha512': - return 'ecdsa-with-' . strtoupper($key->getHash()); - } - throw new UnsupportedAlgorithmException('The only supported hash algorithms for EC are: sha1, sha224, sha256, sha384, sha512'); } - throw new UnsupportedAlgorithmException('The only supported public key classes are: RSA, DSA, EC'); + return false; } /** * Set certificate start date * - * @param DateTimeInterface|string $date + * @param string $date * @access public */ - public function setStartDate($date) + function setStartDate($date) { - if (!is_object($date) || !($date instanceof DateTimeInterface)) { - $date = new DateTimeImmutable($date, new DateTimeZone(@date_default_timezone_get())); + if (!is_object($date) || !is_a($date, 'DateTime')) { + $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get())); } $this->startDate = $date->format('D, d M Y H:i:s O'); @@ -3089,10 +4090,10 @@ class X509 /** * Set certificate end date * - * @param DateTimeInterface|string $date + * @param string $date * @access public */ - public function setEndDate($date) + function setEndDate($date) { /* To indicate that a certificate has no well-defined expiration date, @@ -3101,13 +4102,14 @@ class X509 -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5 */ - if (is_string($date) && strtolower($date) === 'lifetime') { + if (strtolower($date) == 'lifetime') { $temp = '99991231235959Z'; - $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . ASN1::encodeLength(strlen($temp)) . $temp; + $asn1 = new ASN1(); + $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp; $this->endDate = new Element($temp); } else { - if (!is_object($date) || !($date instanceof DateTimeInterface)) { - $date = new DateTimeImmutable($date, new DateTimeZone(@date_default_timezone_get())); + if (!is_object($date) || !is_a($date, 'DateTime')) { + $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get())); } $this->endDate = $date->format('D, d M Y H:i:s O'); @@ -3121,7 +4123,7 @@ class X509 * @param int $base optional * @access public */ - public function setSerialNumber($serial, $base = -256) + function setSerialNumber($serial, $base = -256) { $this->serialNumber = new BigInteger($serial, $base); } @@ -3131,7 +4133,7 @@ class X509 * * @access public */ - public function makeCA() + function makeCA() { $this->caFlag = true; } @@ -3148,7 +4150,7 @@ class X509 * @return boolean * @access private */ - private function isSubArrayValid($root, $path) + function _isSubArrayValid($root, $path) { if (!is_array($root)) { return false; @@ -3185,7 +4187,7 @@ class X509 * @access private * @return array|false */ - private function &subArrayUnchecked(&$root, $path, $create = false) + function &_subArrayUnchecked(&$root, $path, $create = false) { $false = false; @@ -3195,7 +4197,7 @@ class X509 return $false; } - $root[$i] = []; + $root[$i] = array(); } $root = &$root[$i]; @@ -3213,7 +4215,7 @@ class X509 * @access private * @return array|false */ - private function &subArray(&$root, $path, $create = false) + function &_subArray(&$root, $path, $create = false) { $false = false; @@ -3231,7 +4233,7 @@ class X509 return $false; } - $root[$i] = []; + $root[$i] = array(); } $root = &$root[$i]; @@ -3249,7 +4251,7 @@ class X509 * @access private * @return array|false */ - private function &extensions(&$root, $path = null, $create = false) + function &_extensions(&$root, $path = null, $create = false) { if (!isset($root)) { $root = $this->currentCert; @@ -3267,7 +4269,7 @@ class X509 break; case isset($root['certificationRequestInfo']): $pth = 'certificationRequestInfo/attributes'; - $attributes = &$this->subArray($root, $pth, $create); + $attributes = &$this->_subArray($root, $pth, $create); if (is_array($attributes)) { foreach ($attributes as $key => $value) { @@ -3278,14 +4280,14 @@ class X509 } if ($create) { $key = count($attributes); - $attributes[] = ['type' => 'pkcs-9-at-extensionRequest', 'value' => []]; + $attributes[] = array('type' => 'pkcs-9-at-extensionRequest', 'value' => array()); $path = "$pth/$key/value/0"; } } break; } - $extensions = &$this->subArray($root, $path, $create); + $extensions = &$this->_subArray($root, $path, $create); if (!is_array($extensions)) { $false = false; @@ -3303,9 +4305,9 @@ class X509 * @access private * @return bool */ - private function removeExtensionHelper($id, $path = null) + function _removeExtension($id, $path = null) { - $extensions = &$this->extensions($this->currentCert, $path); + $extensions = &$this->_extensions($this->currentCert, $path); if (!is_array($extensions)) { return false; @@ -3338,9 +4340,9 @@ class X509 * @access private * @return mixed */ - private function getExtensionHelper($id, $cert = null, $path = null) + function _getExtension($id, $cert = null, $path = null) { - $extensions = $this->extensions($cert, $path); + $extensions = $this->_extensions($cert, $path); if (!is_array($extensions)) { return false; @@ -3363,10 +4365,10 @@ class X509 * @access private * @return array */ - private function getExtensionsHelper($cert = null, $path = null) + function _getExtensions($cert = null, $path = null) { - $exts = $this->extensions($cert, $path); - $extensions = []; + $exts = $this->_extensions($cert, $path); + $extensions = array(); if (is_array($exts)) { foreach ($exts as $extension) { @@ -3388,15 +4390,15 @@ class X509 * @access private * @return bool */ - private function setExtensionHelper($id, $value, $critical = false, $replace = true, $path = null) + function _setExtension($id, $value, $critical = false, $replace = true, $path = null) { - $extensions = &$this->extensions($this->currentCert, $path, true); + $extensions = &$this->_extensions($this->currentCert, $path, true); if (!is_array($extensions)) { return false; } - $newext = ['extnId' => $id, 'critical' => $critical, 'extnValue' => $value]; + $newext = array('extnId' => $id, 'critical' => $critical, 'extnValue' => $value); foreach ($extensions as $key => $value) { if ($value['extnId'] == $id) { @@ -3420,9 +4422,9 @@ class X509 * @access public * @return bool */ - public function removeExtension($id) + function removeExtension($id) { - return $this->removeExtensionHelper($id); + return $this->_removeExtension($id); } /** @@ -3432,26 +4434,24 @@ class X509 * * @param string $id * @param array $cert optional - * @param string $path * @access public * @return mixed */ - public function getExtension($id, $cert = null, $path=null) + function getExtension($id, $cert = null) { - return $this->getExtensionHelper($id, $cert, $path); + return $this->_getExtension($id, $cert); } /** * Returns a list of all extensions in use in certificate, CSR or CRL * * @param array $cert optional - * @param string $path optional * @access public * @return array */ - public function getExtensions($cert = null, $path = null) + function getExtensions($cert = null) { - return $this->getExtensionsHelper($cert, $path); + return $this->_getExtensions($cert); } /** @@ -3464,9 +4464,9 @@ class X509 * @access public * @return bool */ - public function setExtension($id, $value, $critical = false, $replace = true) + function setExtension($id, $value, $critical = false, $replace = true) { - return $this->setExtensionHelper($id, $value, $critical, $replace); + return $this->_setExtension($id, $value, $critical, $replace); } /** @@ -3477,9 +4477,9 @@ class X509 * @access public * @return bool */ - public function removeAttribute($id, $disposition = self::ATTR_ALL) + function removeAttribute($id, $disposition = self::ATTR_ALL) { - $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes'); + $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { return false; @@ -3528,13 +4528,13 @@ class X509 * @access public * @return mixed */ - public function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null) + function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null) { if (empty($csr)) { $csr = $this->currentCert; } - $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); + $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { return false; @@ -3568,14 +4568,14 @@ class X509 * @access public * @return array */ - public function getAttributes($csr = null) + function getAttributes($csr = null) { if (empty($csr)) { $csr = $this->currentCert; } - $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); - $attrs = []; + $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes'); + $attrs = array(); if (is_array($attributes)) { foreach ($attributes as $attribute) { @@ -3591,13 +4591,13 @@ class X509 * * @param string $id * @param mixed $value - * @param int $disposition optional + * @param bool $disposition optional * @access public * @return bool */ - public function setAttribute($id, $value, $disposition = self::ATTR_ALL) + function setAttribute($id, $value, $disposition = self::ATTR_ALL) { - $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes', true); + $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes', true); if (!is_array($attributes)) { return false; @@ -3635,7 +4635,7 @@ class X509 $attributes[$last]['value'][] = $value; break; default: - $attributes[] = ['type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value: [$value]]; + $attributes[] = array('type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value: array($value)); break; } @@ -3650,12 +4650,12 @@ class X509 * @param string $value * @access public */ - public function setKeyIdentifier($value) + function setKeyIdentifier($value) { if (empty($value)) { unset($this->currentKeyIdentifier); } else { - $this->currentKeyIdentifier = $value; + $this->currentKeyIdentifier = base64_encode($value); } } @@ -3667,9 +4667,9 @@ class X509 * recommended methods (4.2.1.2 RFC 3280). * Highly polymorphic: try to accept all possible forms of key: * - Key object - * - \phpseclib3\File\X509 object with public or private key defined + * - \phpseclib\File\X509 object with public or private key defined * - Certificate or CSR array - * - \phpseclib3\File\ASN1\Element object + * - \phpseclib\File\ASN1\Element object * - PEM or DER string * * @param mixed $key optional @@ -3677,7 +4677,7 @@ class X509 * @access public * @return string binary key identifier */ - public function computeKeyIdentifier($key = null, $method = 1) + function computeKeyIdentifier($key = null, $method = 1) { if (is_null($key)) { $key = $this; @@ -3694,20 +4694,25 @@ class X509 return false; case $key instanceof Element: // Assume the element is a bitstring-packed key. - $decoded = ASN1::decodeBER($key->element); + $asn1 = new ASN1(); + $decoded = $asn1->decodeBER($key->element); if (empty($decoded)) { return false; } - $raw = ASN1::asn1map($decoded[0], ['type' => ASN1::TYPE_BIT_STRING]); + $raw = $asn1->asn1map($decoded[0], array('type' => ASN1::TYPE_BIT_STRING)); if (empty($raw)) { return false; } + $raw = base64_decode($raw); // If the key is private, compute identifier from its corresponding public key. - $key = PublicKeyLoader::load($raw); - if ($key instanceof PrivateKey) { // If private. + $key = new RSA(); + if (!$key->loadKey($raw)) { + return false; // Not an unencrypted RSA key. + } + if ($key->getPrivateKey() !== false) { // If private. return $this->computeKeyIdentifier($key, $method); } - $key = $raw; // Is a public key. + $key = $raw; // Is a public key. break; case $key instanceof X509: if (isset($key->publicKey)) { @@ -3720,13 +4725,13 @@ class X509 return $this->computeKeyIdentifier($key->currentCert, $method); } return false; - default: // Should be a key object (i.e.: \phpseclib3\Crypt\RSA). - $key = $key->getPublicKey(); + default: // Should be a key object (i.e.: \phpseclib\Crypt\RSA). + $key = $key->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); break; } // If in PEM format, convert to binary. - $key = ASN1::extractBER($key); + $key = $this->_extractBER($key); // Now we have the key string: compute its sha-1 sum. $hash = new Hash('sha1'); @@ -3744,34 +4749,32 @@ class X509 * Format a public key as appropriate * * @access private - * @return array|bool + * @return array */ - private function formatSubjectPublicKey() + function _formatSubjectPublicKey() { - $format = $this->publicKey instanceof RSA && ($this->publicKey->getPadding() & RSA::SIGNATURE_PSS) ? - 'PSS' : - 'PKCS8'; - - $publicKey = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->toString($format))); - - $decoded = ASN1::decodeBER($publicKey); - $mapped = ASN1::asn1map($decoded[0], Maps\SubjectPublicKeyInfo::MAP); - - $mapped['subjectPublicKey'] = $this->publicKey->toString($format); + if ($this->publicKey instanceof RSA) { + // the following two return statements do the same thing. i dunno.. i just prefer the later for some reason. + // the former is a good example of how to do fuzzing on the public key + //return new Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey()))); + return array( + 'algorithm' => array('algorithm' => 'rsaEncryption'), + 'subjectPublicKey' => $this->publicKey->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1) + ); + } - return $mapped; + return false; } /** * Set the domain name's which the cert is to be valid for * - * @param mixed[] ...$domains * @access public * @return array */ - public function setDomain(...$domains) + function setDomain() { - $this->domains = $domains; + $this->domains = func_get_args(); $this->removeDNProp('id-at-commonName'); $this->setDNProp('id-at-commonName', $this->domains[0]); } @@ -3780,11 +4783,10 @@ class X509 * Set the IP Addresses's which the cert is to be valid for * * @access public - * @param mixed[] ...$ipAddresses */ - public function setIPAddress(...$ipAddresses) + function setIPAddress() { - $this->ipAddresses = $ipAddresses; + $this->ipAddresses = func_get_args(); /* if (!isset($this->domains)) { $this->removeDNProp('id-at-commonName'); @@ -3800,9 +4802,9 @@ class X509 * @param string $domain * @return array */ - private function dnsName($domain) + function _dnsName($domain) { - return ['dNSName' => $domain]; + return array('dNSName' => $domain); } /** @@ -3814,9 +4816,9 @@ class X509 * @param string $address * @return array */ - private function iPAddress($address) + function _iPAddress($address) { - return ['iPAddress' => $address]; + return array('iPAddress' => $address); } /** @@ -3828,7 +4830,7 @@ class X509 * @access private * @return int|false */ - private function revokedCertificate(&$rclist, $serial, $create = false) + function _revokedCertificate(&$rclist, $serial, $create = false) { $serial = new BigInteger($serial); @@ -3843,9 +4845,9 @@ class X509 } $i = count($rclist); - $revocationDate = new DateTimeImmutable('now', new DateTimeZone(@date_default_timezone_get())); - $rclist[] = ['userCertificate' => $serial, - 'revocationDate' => $this->timeField($revocationDate->format('D, d M Y H:i:s O'))]; + $revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get())); + $rclist[] = array('userCertificate' => $serial, + 'revocationDate' => $this->_timeField($revocationDate->format('D, d M Y H:i:s O'))); return $i; } @@ -3857,14 +4859,14 @@ class X509 * @access public * @return bool */ - public function revoke($serial, $date = null) + function revoke($serial, $date = null) { if (isset($this->currentCert['tbsCertList'])) { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { - if ($this->revokedCertificate($rclist, $serial) === false) { // If not yet revoked - if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { + if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if ($this->_revokedCertificate($rclist, $serial) === false) { // If not yet revoked + if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) { if (!empty($date)) { - $rclist[$i]['revocationDate'] = $this->timeField($date); + $rclist[$i]['revocationDate'] = $this->_timeField($date); } return true; @@ -3883,10 +4885,10 @@ class X509 * @access public * @return bool */ - public function unrevoke($serial) + function unrevoke($serial) { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { unset($rclist[$i]); $rclist = array_values($rclist); return true; @@ -3903,10 +4905,10 @@ class X509 * @access public * @return mixed */ - public function getRevoked($serial) + function getRevoked($serial) { - if (is_array($rclist = $this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + if (is_array($rclist = $this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { return $rclist[$i]; } } @@ -3919,9 +4921,9 @@ class X509 * * @param array $crl optional * @access public - * @return array|bool + * @return array */ - public function listRevoked($crl = null) + function listRevoked($crl = null) { if (!isset($crl)) { $crl = $this->currentCert; @@ -3931,9 +4933,9 @@ class X509 return false; } - $result = []; + $result = array(); - if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { foreach ($rclist as $rc) { $result[] = $rc['userCertificate']->toString(); } @@ -3950,11 +4952,11 @@ class X509 * @access public * @return bool */ - public function removeRevokedCertificateExtension($serial, $id) + function removeRevokedCertificateExtension($serial, $id) { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - return $this->removeExtensionHelper($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { + return $this->_removeExtension($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } @@ -3972,15 +4974,15 @@ class X509 * @access public * @return mixed */ - public function getRevokedCertificateExtension($serial, $id, $crl = null) + function getRevokedCertificateExtension($serial, $id, $crl = null) { if (!isset($crl)) { $crl = $this->currentCert; } - if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - return $this->getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { + return $this->_getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } @@ -3993,17 +4995,17 @@ class X509 * @param string $serial * @param array $crl optional * @access public - * @return array|bool + * @return array */ - public function getRevokedCertificateExtensions($serial, $crl = null) + function getRevokedCertificateExtensions($serial, $crl = null) { if (!isset($crl)) { $crl = $this->currentCert; } - if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - return $this->getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { + return $this->_getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } @@ -4021,12 +5023,12 @@ class X509 * @access public * @return bool */ - public function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) + function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) { if (isset($this->currentCert['tbsCertList'])) { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { - if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { - return $this->setExtensionHelper($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) { + return $this->_setExtension($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } } @@ -4035,42 +5037,58 @@ class X509 } /** - * Register the mapping for a custom/unsupported extension. + * Extract raw BER from Base64 encoding * - * @param string $id - * @param array $mapping + * @access private + * @param string $str + * @return string */ - public static function registerExtension($id, array $mapping) + function _extractBER($str) { - if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) { - throw new \RuntimeException( - 'Extension ' . $id . ' has already been defined with a different mapping.' - ); - } - - self::$extensions[$id] = $mapping; + /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them + * above and beyond the ceritificate. + * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: + * + * Bag Attributes + * localKeyID: 01 00 00 00 + * subject=/O=organization/OU=org unit/CN=common name + * issuer=/O=organization/CN=common name + */ + $temp = strlen($str) <= ini_get('pcre.backtrack_limit') ? + preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1) : + $str; + // remove new lines + $temp = str_replace(array("\r", "\n", ' '), '', $temp); + // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff + $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + return $temp != false ? $temp : $str; } /** - * Register the mapping for a custom/unsupported extension. + * Returns the OID corresponding to a name * - * @param string $id + * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if + * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version + * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able + * to work from version to version. * - * @return array|null - */ - public static function getRegisteredExtension($id) - { - return isset(self::$extensions[$id]) ? self::$extensions[$id] : null; - } - - /** - * Register the mapping for a custom/unsupported extension. + * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that + * what's being passed to it already is an OID and return that instead. A few examples. * - * @param string $id - * @param mixed $value + * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' + * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' + * getOID('zzz') == 'zzz' + * + * @access public + * @return string */ - public function setExtensionValue($id, $value) + function getOID($name) { - $this->extensionValues[$id] = $value; + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_flip($this->oids); + } + return isset($reverseMap[$name]) ? $reverseMap[$name] : $name; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php index f6ff12ed5..9df0bf0f2 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -6,13 +6,33 @@ * Supports base-2, base-10, base-16, and base-256 numbers. Uses the GMP or BCMath extensions, if available, * and an internal implementation, otherwise. * - * PHP version 5 and 7 + * PHP version 5 + * + * {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the + * {@link self::MODE_INTERNAL self::MODE_INTERNAL} mode) + * + * BigInteger uses base-2**26 to perform operations such as multiplication and division and + * base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction. Because the largest possible + * value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating + * point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are + * used. As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %, + * which only supports integers. Although this fact will slow this library down, the fact that such a high + * base is being used should more than compensate. + * + * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format. ie. + * (new \phpseclib\Math\BigInteger(pow(2, 26)))->value = array(0, 1) + * + * Useful resources are as follows: + * + * - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)} + * - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)} + * - Java's BigInteger classes. See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip * * Here's an example of how to use this library: * * add($b); * @@ -23,13 +43,13 @@ * @category Math * @package BigInteger * @author Jim Wigginton - * @copyright 2017 Jim Wigginton + * @copyright 2006 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ -namespace phpseclib3\Math; +namespace phpseclib\Math; -use phpseclib3\Exception\BadConfigurationException; +use phpseclib\Crypt\Random; /** * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 @@ -39,113 +59,174 @@ use phpseclib3\Exception\BadConfigurationException; * @author Jim Wigginton * @access public */ -class BigInteger implements \Serializable +class BigInteger { - /** - * Main Engine + /**#@+ + * Reduction constants * - * @var string + * @access private + * @see BigInteger::_reduce() + */ + /** + * @see BigInteger::_montgomery() + * @see BigInteger::_prepMontgomery() + */ + const MONTGOMERY = 0; + /** + * @see BigInteger::_barrett() + */ + const BARRETT = 1; + /** + * @see BigInteger::_mod2() + */ + const POWEROF2 = 2; + /** + * @see BigInteger::_remainder() + */ + const CLASSIC = 3; + /** + * @see BigInteger::__clone() */ - private static $mainEngine; + const NONE = 4; + /**#@-*/ + /**#@+ + * Array constants + * + * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and + * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. + * + * @access private + */ + /** + * $result[self::VALUE] contains the value. + */ + const VALUE = 0; + /** + * $result[self::SIGN] contains the sign. + */ + const SIGN = 1; + /**#@-*/ + + /**#@+ + * @access private + * @see BigInteger::_montgomery() + * @see BigInteger::_barrett() + */ /** - * Modular Exponentiation Engine + * Cache constants * - * @var string + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. */ - private static $modexpEngine; + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + */ + const DATA = 1; + /**#@-*/ + /**#@+ + * Mode constants. + * + * @access private + * @see BigInteger::__construct() + */ + /** + * To use the pure-PHP implementation + */ + const MODE_INTERNAL = 1; /** - * Selected Engines + * To use the BCMath library * - * @var array + * (if enabled; otherwise, the internal implementation will be used) */ - private static $engines; - + const MODE_BCMATH = 2; /** - * The actual BigInteger object + * To use the GMP library * - * @var object + * (if present; otherwise, either the BCMath or the internal implementation will be used) */ - private $value; + const MODE_GMP = 3; + /**#@-*/ /** - * Sets engine type. + * Karatsuba Cutoff * - * Throws an exception if the type is invalid + * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? * - * @param string $main - * @param array $modexps optional + * @access private */ - public static function setEngine($main, $modexps = ['DefaultEngine']) - { - self::$engines = []; + const KARATSUBA_CUTOFF = 25; - $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main; - if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) { - throw new \InvalidArgumentException("$main is not a valid engine"); - } - if (!$fqmain::isValidEngine()) { - throw new BadConfigurationException("$main is not setup correctly on this system"); - } - self::$mainEngine = $fqmain; - - if (!in_array('Default', $modexps)) { - $modexps[] = 'DefaultEngine'; - } + /**#@+ + * Static properties used by the pure-PHP implementation. + * + * @see __construct() + */ + protected static $base; + protected static $baseFull; + protected static $maxDigit; + protected static $msb; - $found = false; - foreach ($modexps as $modexp) { - try { - $fqmain::setModExpEngine($modexp); - $found = true; - break; - } catch (\Exception $e) { - } - } + /** + * $max10 in greatest $max10Len satisfying + * $max10 = 10**$max10Len <= 2**$base. + */ + protected static $max10; - if (!$found) { - throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); - } + /** + * $max10Len in greatest $max10Len satisfying + * $max10 = 10**$max10Len <= 2**$base. + */ + protected static $max10Len; + protected static $maxDigit2; + /**#@-*/ - self::$modexpEngine = $modexp; + /** + * Holds the BigInteger's value. + * + * @var array + * @access private + */ + var $value; - self::$engines = [$main, $modexp]; - } + /** + * Holds the BigInteger's magnitude. + * + * @var bool + * @access private + */ + var $is_negative = false; /** - * Returns the engine type + * Precision * - * @return string[] + * @see self::setPrecision() + * @access private */ - public static function getEngine() - { - self::initialize_static_variables(); + var $precision = -1; - return self::$engines; - } + /** + * Precision Bitmask + * + * @see self::setPrecision() + * @access private + */ + var $bitmask = false; /** - * Initialize static variables + * Mode independent value used for serialization. + * + * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for + * a variable that'll be serializable regardless of whether or not extensions are being used. Unlike $this->value, + * however, $this->hex is only calculated when $this->__sleep() is called. + * + * @see self::__sleep() + * @see self::__wakeup() + * @var string + * @access private */ - private static function initialize_static_variables() - { - if (!isset(self::$mainEngine)) { - $engines = [ - ['GMP'], - ['PHP64', ['OpenSSL']], - ['BCMath', ['OpenSSL']], - ['PHP32', ['OpenSSL']] - ]; - foreach ($engines as $engine) { - try { - self::setEngine($engine[0], isset($engine[1]) ? $engine[1] : []); - break; - } catch (\Exception $e) { - } - } - } - } + var $hex; /** * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. @@ -153,72 +234,404 @@ class BigInteger implements \Serializable * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. * - * @param int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set. + * Here's an example: + * + * toString(); // outputs 50 + * ?> + * + * + * @param int|string|resource $x base-10 number or base-$base number if $base set. * @param int $base - * @return BigInteger + * @return \phpseclib\Math\BigInteger + * @access public */ - public function __construct($x = 0, $base = 10) + function __construct($x = 0, $base = 10) { - self::initialize_static_variables(); + if (!defined('MATH_BIGINTEGER_MODE')) { + switch (true) { + case extension_loaded('gmp'): + define('MATH_BIGINTEGER_MODE', self::MODE_GMP); + break; + case extension_loaded('bcmath'): + define('MATH_BIGINTEGER_MODE', self::MODE_BCMATH); + break; + default: + define('MATH_BIGINTEGER_MODE', self::MODE_INTERNAL); + } + } - if ($x instanceof self::$mainEngine) { - $this->value = clone $x; - } elseif ($x instanceof BigInteger\Engines\Engine) { - $this->value = new static("$x"); - $this->value->setPrecision($x->getPrecision()); - } else { - $this->value = new self::$mainEngine($x, $base); + if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) { + // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work + $versions = array(); + + // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems) + if (strpos(ini_get('disable_functions'), 'phpinfo') === false) { + ob_start(); + @phpinfo(); + $content = ob_get_contents(); + ob_end_clean(); + + preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches); + + if (!empty($matches[1])) { + for ($i = 0; $i < count($matches[1]); $i++) { + $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i]))); + + // Remove letter part in OpenSSL version + if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) { + $versions[$matches[1][$i]] = $fullVersion; + } else { + $versions[$matches[1][$i]] = $m[0]; + } + } + } + } + + // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+ + switch (true) { + case !isset($versions['Header']): + case !isset($versions['Library']): + case $versions['Header'] == $versions['Library']: + case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0: + define('MATH_BIGINTEGER_OPENSSL_ENABLED', true); + break; + default: + define('MATH_BIGINTEGER_OPENSSL_DISABLE', true); + } } - } - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - return $this->value->toString(); - } + if (!defined('PHP_INT_SIZE')) { + define('PHP_INT_SIZE', 4); + } - /** - * __toString() magic method - */ - public function __toString() - { - return (string) $this->value; - } + if (empty(self::$base) && MATH_BIGINTEGER_MODE == self::MODE_INTERNAL) { + switch (PHP_INT_SIZE) { + case 8: // use 64-bit integers if int size is 8 bytes + self::$base = 31; + self::$baseFull = 0x80000000; + self::$maxDigit = 0x7FFFFFFF; + self::$msb = 0x40000000; + self::$max10 = 1000000000; + self::$max10Len = 9; + self::$maxDigit2 = pow(2, 62); + break; + //case 4: // use 64-bit floats if int size is 4 bytes + default: + self::$base = 26; + self::$baseFull = 0x4000000; + self::$maxDigit = 0x3FFFFFF; + self::$msb = 0x2000000; + self::$max10 = 10000000; + self::$max10Len = 7; + self::$maxDigit2 = pow(2, 52); // pow() prevents truncation + } + } - /** - * __debugInfo() magic method - * - * Will be called, automatically, when print_r() or var_dump() are called - */ - public function __debugInfo() - { - return $this->value->__debugInfo(); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + switch (true) { + case is_resource($x) && get_resource_type($x) == 'GMP integer': + // PHP 5.6 switched GMP from using resources to objects + case $x instanceof \GMP: + $this->value = $x; + return; + } + $this->value = gmp_init(0); + break; + case self::MODE_BCMATH: + $this->value = '0'; + break; + default: + $this->value = array(); + } + + // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 + // '0' is the only value like this per http://php.net/empty + if (empty($x) && (abs($base) != 256 || $x !== '0')) { + return; + } + + switch ($base) { + case -256: + if (ord($x[0]) & 0x80) { + $x = ~$x; + $this->is_negative = true; + } + case 256: + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $this->value = function_exists('gmp_import') ? + gmp_import($x) : + gmp_init('0x' . bin2hex($x)); + if ($this->is_negative) { + $this->value = gmp_neg($this->value); + } + break; + case self::MODE_BCMATH: + // round $len to the nearest 4 (thanks, DavidMJ!) + $len = (strlen($x) + 3) & 0xFFFFFFFC; + + $x = str_pad($x, $len, chr(0), STR_PAD_LEFT); + + for ($i = 0; $i < $len; $i+= 4) { + $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 + $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0); + } + + if ($this->is_negative) { + $this->value = '-' . $this->value; + } + + break; + // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb) + default: + while (strlen($x)) { + $this->value[] = $this->_bytes2int($this->_base256_rshift($x, self::$base)); + } + } + + if ($this->is_negative) { + if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) { + $this->is_negative = false; + } + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case 16: + case -16: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x); + + $is_negative = false; + if ($base < 0 && hexdec($x[0]) >= 8) { + $this->is_negative = $is_negative = true; + $x = bin2hex(~pack('H*', $x)); + } + + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = $this->is_negative ? '-0x' . $x : '0x' . $x; + $this->value = gmp_init($temp); + $this->is_negative = false; + break; + case self::MODE_BCMATH: + $x = (strlen($x) & 1) ? '0' . $x : $x; + $temp = new static(pack('H*', $x), 256); + $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; + $this->is_negative = false; + break; + default: + $x = (strlen($x) & 1) ? '0' . $x : $x; + $temp = new static(pack('H*', $x), 256); + $this->value = $temp->value; + } + + if ($is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case 10: + case -10: + // (?value = gmp_init($x); + break; + case self::MODE_BCMATH: + // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different + // results then doing it on '-1' does (modInverse does $x[0]) + $this->value = $x === '-' ? '0' : (string) $x; + break; + default: + $temp = new static(); + + $multiplier = new static(); + $multiplier->value = array(self::$max10); + + if ($x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = str_pad($x, strlen($x) + ((self::$max10Len - 1) * strlen($x)) % self::$max10Len, 0, STR_PAD_LEFT); + while (strlen($x)) { + $temp = $temp->multiply($multiplier); + $temp = $temp->add(new static($this->_int2bytes(substr($x, 0, self::$max10Len)), 256)); + $x = substr($x, self::$max10Len); + } + + $this->value = $temp->value; + } + break; + case 2: // base-2 support originally implemented by Lluis Pamies - thanks! + case -2: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^([01]*).*#', '$1', $x); + $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT); + + $str = '0x'; + while (strlen($x)) { + $part = substr($x, 0, 4); + $str.= dechex(bindec($part)); + $x = substr($x, 4); + } + + if ($this->is_negative) { + $str = '-' . $str; + } + + $temp = new static($str, 8 * $base); // ie. either -16 or +16 + $this->value = $temp->value; + $this->is_negative = $temp->is_negative; + + break; + default: + // base not supported, so we'll let $this == 0 + } } /** * Converts a BigInteger to a byte string (eg. base-256). * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * Here's an example: + * + * toBytes(); // outputs chr(65) + * ?> + * + * * @param bool $twos_compliment * @return string + * @access public + * @internal Converts a base-2**26 number to base-2**8 */ - public function toBytes($twos_compliment = false) + function toBytes($twos_compliment = false) { - return $this->value->toBytes($twos_compliment); + if ($twos_compliment) { + $comparison = $this->compare(new static()); + if ($comparison == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy(); + $bytes = $temp->toBytes(); + + if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 + $bytes = chr(0); + } + + if ($this->precision <= 0 && (ord($bytes[0]) & 0x80)) { + $bytes = chr(0) . $bytes; + } + + return $comparison < 0 ? ~$bytes : $bytes; + } + + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + if (gmp_cmp($this->value, gmp_init(0)) == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + if (function_exists('gmp_export')) { + $temp = gmp_export($this->value); + } else { + $temp = gmp_strval(gmp_abs($this->value), 16); + $temp = (strlen($temp) & 1) ? '0' . $temp : $temp; + $temp = pack('H*', $temp); + } + + return $this->precision > 0 ? + substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($temp, chr(0)); + case self::MODE_BCMATH: + if ($this->value === '0') { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $value = ''; + $current = $this->value; + + if ($current[0] == '-') { + $current = substr($current, 1); + } + + while (bccomp($current, '0', 0) > 0) { + $temp = bcmod($current, '16777216'); + $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value; + $current = bcdiv($current, '16777216', 0); + } + + return $this->precision > 0 ? + substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($value, chr(0)); + } + + if (!count($this->value)) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + $result = $this->_int2bytes($this->value[count($this->value) - 1]); + + $temp = $this->copy(); + + for ($i = count($temp->value) - 2; $i >= 0; --$i) { + $temp->_base256_lshift($result, self::$base); + $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT); + } + + return $this->precision > 0 ? + str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) : + $result; } /** - * Converts a BigInteger to a hex string (eg. base-16). + * Converts a BigInteger to a hex string (eg. base-16)). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * Here's an example: + * + * toHex(); // outputs '41' + * ?> + * * * @param bool $twos_compliment * @return string + * @access public + * @internal Converts a base-2**26 number to base-2**8 */ - public function toHex($twos_compliment = false) + function toHex($twos_compliment = false) { - return $this->value->toHex($twos_compliment); + return bin2hex($this->toBytes($twos_compliment)); } /** @@ -227,227 +640,2039 @@ class BigInteger implements \Serializable * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're * saved as two's compliment. * + * Here's an example: + * + * toBits(); // outputs '1000001' + * ?> + * + * * @param bool $twos_compliment * @return string + * @access public + * @internal Converts a base-2**26 number to base-2**2 */ function toBits($twos_compliment = false) { - return $this->value->toBits($twos_compliment); + $hex = $this->toHex($twos_compliment); + $bits = ''; + for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) { + $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits; + } + if ($start) { // hexdec('') == 0 + $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits; + } + $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); + + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $result; + } + + return $result; } /** - * Adds two BigIntegers. + * Converts a BigInteger to a base-10 number. * - * @param BigInteger $y - * @return BigInteger + * Here's an example: + * + * toString(); // outputs 50 + * ?> + * + * + * @return string + * @access public + * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10) */ - public function add(BigInteger $y) + function toString() { - return new static($this->value->add($y->value)); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + return gmp_strval($this->value); + case self::MODE_BCMATH: + if ($this->value === '0') { + return '0'; + } + + return ltrim($this->value, '0'); + } + + if (!count($this->value)) { + return '0'; + } + + $temp = $this->copy(); + $temp->bitmask = false; + $temp->is_negative = false; + + $divisor = new static(); + $divisor->value = array(self::$max10); + $result = ''; + while (count($temp->value)) { + list($temp, $mod) = $temp->divide($divisor); + $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', self::$max10Len, '0', STR_PAD_LEFT) . $result; + } + $result = ltrim($result, '0'); + if (empty($result)) { + $result = '0'; + } + + if ($this->is_negative) { + $result = '-' . $result; + } + + return $result; } /** - * Subtracts two BigIntegers. + * Copy an object + * + * PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee + * that all objects are passed by value, when appropriate. More information can be found here: + * + * {@link http://php.net/language.oop5.basic#51624} * - * @param BigInteger $y - * @return BigInteger + * @access public + * @see self::__clone() + * @return \phpseclib\Math\BigInteger */ - function subtract(BigInteger $y) + function copy() { - return new static($this->value->subtract($y->value)); + $temp = new static(); + $temp->value = $this->value; + $temp->is_negative = $this->is_negative; + $temp->precision = $this->precision; + $temp->bitmask = $this->bitmask; + return $temp; } /** - * Multiplies two BigIntegers + * __toString() magic method + * + * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call + * toString(). * - * @param BigInteger $x - * @return BigInteger + * @access public + * @internal Implemented per a suggestion by Techie-Michael - thanks! */ - public function multiply(BigInteger $x) + function __toString() { - return new static($this->value->multiply($x->value)); + return $this->toString(); } /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * Here's an example: - * - * divide($b); + * __clone() magic method * - * echo $quotient->toString(); // outputs 0 - * echo "\r\n"; - * echo $remainder->toString(); // outputs 10 - * ?> - * + * Although you can call BigInteger::__toString() directly in PHP5, you cannot call BigInteger::__clone() directly + * in PHP5. You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5 + * only syntax of $y = clone $x. As such, if you're trying to write an application that works on both PHP4 and + * PHP5, call BigInteger::copy(), instead. * - * @param BigInteger $y - * @return BigInteger[] + * @access public + * @see self::copy() + * @return \phpseclib\Math\BigInteger */ - public function divide(BigInteger $y) + function __clone() { - list($q, $r) = $this->value->divide($y->value); - return [ - new static($q), - new static($r) - ]; + return $this->copy(); } /** - * Calculates modular inverses. + * __sleep() magic method * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @return BigInteger - * @param BigInteger $n + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * @see self::__wakeup() + * @access public + */ + function __sleep() + { + $this->hex = $this->toHex(true); + $vars = array('hex'); + if ($this->precision > 0) { + $vars[] = 'precision'; + } + return $vars; + } + + /** + * __wakeup() magic method + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + * + * @see self::__sleep() + * @access public + */ + function __wakeup() + { + $temp = new static($this->hex, -16); + $this->value = $temp->value; + $this->is_negative = $temp->is_negative; + if ($this->precision > 0) { + // recalculate $this->bitmask + $this->setPrecision($this->precision); + } + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + * + * @access public + */ + function __debugInfo() + { + $opts = array(); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $engine = 'gmp'; + break; + case self::MODE_BCMATH: + $engine = 'bcmath'; + break; + case self::MODE_INTERNAL: + $engine = 'internal'; + $opts[] = PHP_INT_SIZE == 8 ? '64-bit' : '32-bit'; + } + if (MATH_BIGINTEGER_MODE != self::MODE_GMP && defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) { + $opts[] = 'OpenSSL'; + } + if (!empty($opts)) { + $engine.= ' (' . implode('.', $opts) . ')'; + } + return array( + 'value' => '0x' . $this->toHex(true), + 'engine' => $engine + ); + } + + /** + * Adds two BigIntegers. + * + * Here's an example: + * + * add($b); + * + * echo $c->toString(); // outputs 30 + * ?> + * + * + * @param \phpseclib\Math\BigInteger $y + * @return \phpseclib\Math\BigInteger + * @access public + * @internal Performs base-2**52 addition + */ + function add($y) + { + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = new static(); + $temp->value = gmp_add($this->value, $y->value); + + return $this->_normalize($temp); + case self::MODE_BCMATH: + $temp = new static(); + $temp->value = bcadd($this->value, $y->value, 0); + + return $this->_normalize($temp); + } + + $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative); + + $result = new static(); + $result->value = $temp[self::VALUE]; + $result->is_negative = $temp[self::SIGN]; + + return $this->_normalize($result); + } + + /** + * Performs addition. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + * @access private + */ + function _add($x_value, $x_negative, $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return array( + self::VALUE => $y_value, + self::SIGN => $y_negative + ); + } elseif ($y_size == 0) { + return array( + self::VALUE => $x_value, + self::SIGN => $x_negative + ); + } + + // subtract, if appropriate + if ($x_negative != $y_negative) { + if ($x_value == $y_value) { + return array( + self::VALUE => array(), + self::SIGN => false + ); + } + + $temp = $this->_subtract($x_value, false, $y_value, false); + $temp[self::SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ? + $x_negative : $y_negative; + + return $temp; + } + + if ($x_size < $y_size) { + $size = $x_size; + $value = $y_value; + } else { + $size = $y_size; + $value = $x_value; + } + + $value[count($value)] = 0; // just in case the carry adds an extra digit + + $carry = 0; + for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) { + $sum = $x_value[$j] * self::$baseFull + $x_value[$i] + $y_value[$j] * self::$baseFull + $y_value[$i] + $carry; + $carry = $sum >= self::$maxDigit2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum - self::$maxDigit2 : $sum; + + $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $value[$i] = (int) ($sum - self::$baseFull * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) + $value[$j] = $temp; + } + + if ($j == $size) { // ie. if $y_size is odd + $sum = $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= self::$baseFull; + $value[$i] = $carry ? $sum - self::$baseFull : $sum; + ++$i; // ie. let $i = $j since we've just done $value[$i] + } + + if ($carry) { + for (; $value[$i] == self::$maxDigit; ++$i) { + $value[$i] = 0; + } + ++$value[$i]; + } + + return array( + self::VALUE => $this->_trim($value), + self::SIGN => $x_negative + ); + } + + /** + * Subtracts two BigIntegers. + * + * Here's an example: + * + * subtract($b); + * + * echo $c->toString(); // outputs -10 + * ?> + * + * + * @param \phpseclib\Math\BigInteger $y + * @return \phpseclib\Math\BigInteger + * @access public + * @internal Performs base-2**52 subtraction + */ + function subtract($y) + { + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = new static(); + $temp->value = gmp_sub($this->value, $y->value); + + return $this->_normalize($temp); + case self::MODE_BCMATH: + $temp = new static(); + $temp->value = bcsub($this->value, $y->value, 0); + + return $this->_normalize($temp); + } + + $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative); + + $result = new static(); + $result->value = $temp[self::VALUE]; + $result->is_negative = $temp[self::SIGN]; + + return $this->_normalize($result); + } + + /** + * Performs subtraction. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + * @access private + */ + function _subtract($x_value, $x_negative, $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return array( + self::VALUE => $y_value, + self::SIGN => !$y_negative + ); + } elseif ($y_size == 0) { + return array( + self::VALUE => $x_value, + self::SIGN => $x_negative + ); + } + + // add, if appropriate (ie. -$x - +$y or +$x - -$y) + if ($x_negative != $y_negative) { + $temp = $this->_add($x_value, false, $y_value, false); + $temp[self::SIGN] = $x_negative; + + return $temp; + } + + $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative); + + if (!$diff) { + return array( + self::VALUE => array(), + self::SIGN => false + ); + } + + // switch $x and $y around, if appropriate. + if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_negative = !$x_negative; + + $x_size = count($x_value); + $y_size = count($y_value); + } + + // at this point, $x_value should be at least as big as - if not bigger than - $y_value + + $carry = 0; + for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) { + $sum = $x_value[$j] * self::$baseFull + $x_value[$i] - $y_value[$j] * self::$baseFull - $y_value[$i] - $carry; + $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum + self::$maxDigit2 : $sum; + + $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $x_value[$i] = (int) ($sum - self::$baseFull * $temp); + $x_value[$j] = $temp; + } + + if ($j == $y_size) { // ie. if $y_size is odd + $sum = $x_value[$i] - $y_value[$i] - $carry; + $carry = $sum < 0; + $x_value[$i] = $carry ? $sum + self::$baseFull : $sum; + ++$i; + } + + if ($carry) { + for (; !$x_value[$i]; ++$i) { + $x_value[$i] = self::$maxDigit; + } + --$x_value[$i]; + } + + return array( + self::VALUE => $this->_trim($x_value), + self::SIGN => $x_negative + ); + } + + /** + * Multiplies two BigIntegers + * + * Here's an example: + * + * multiply($b); + * + * echo $c->toString(); // outputs 200 + * ?> + * + * + * @param \phpseclib\Math\BigInteger $x + * @return \phpseclib\Math\BigInteger + * @access public + */ + function multiply($x) + { + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = new static(); + $temp->value = gmp_mul($this->value, $x->value); + + return $this->_normalize($temp); + case self::MODE_BCMATH: + $temp = new static(); + $temp->value = bcmul($this->value, $x->value, 0); + + return $this->_normalize($temp); + } + + $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative); + + $product = new static(); + $product->value = $temp[self::VALUE]; + $product->is_negative = $temp[self::SIGN]; + + return $this->_normalize($product); + } + + /** + * Performs multiplication. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + * @access private + */ + function _multiply($x_value, $x_negative, $y_value, $y_negative) + { + //if ( $x_value == $y_value ) { + // return array( + // self::VALUE => $this->_square($x_value), + // self::SIGN => $x_sign != $y_value + // ); + //} + + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return array( + self::VALUE => array(), + self::SIGN => false + ); + } + + return array( + self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? + $this->_trim($this->_regularMultiply($x_value, $y_value)) : + $this->_trim($this->_karatsuba($x_value, $y_value)), + self::SIGN => $x_negative != $y_negative + ); + } + + /** + * Performs long multiplication on two BigIntegers + * + * Modeled after 'multiply' in MutableBigInteger.java. + * + * @param array $x_value + * @param array $y_value + * @return array + * @access private + */ + function _regularMultiply($x_value, $y_value) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return array(); + } + + if ($x_length < $y_length) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_length = count($x_value); + $y_length = count($y_value); + } + + $product_value = $this->_array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int) ($temp - self::$baseFull * $carry); + } + + $product_value[$j] = $carry; + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int) ($temp - self::$baseFull * $carry); + } + + $product_value[$k] = $carry; + } + + return $product_value; + } + + /** + * Performs Karatsuba multiplication on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. + * + * @param array $x_value + * @param array $y_value + * @return array + * @access private + */ + function _karatsuba($x_value, $y_value) + { + $m = min(count($x_value) >> 1, count($y_value) >> 1); + + if ($m < self::KARATSUBA_CUTOFF) { + return $this->_regularMultiply($x_value, $y_value); + } + + $x1 = array_slice($x_value, $m); + $x0 = array_slice($x_value, 0, $m); + $y1 = array_slice($y_value, $m); + $y0 = array_slice($y_value, 0, $m); + + $z2 = $this->_karatsuba($x1, $y1); + $z0 = $this->_karatsuba($x0, $y0); + + $z1 = $this->_add($x1, false, $x0, false); + $temp = $this->_add($y1, false, $y0, false); + $z1 = $this->_karatsuba($z1[self::VALUE], $temp[self::VALUE]); + $temp = $this->_add($z2, false, $z0, false); + $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xy = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xy = $this->_add($xy[self::VALUE], $xy[self::SIGN], $z0, false); + + return $xy[self::VALUE]; + } + + /** + * Performs squaring + * + * @param array $x + * @return array + * @access private + */ + function _square($x = false) + { + return count($x) < 2 * self::KARATSUBA_CUTOFF ? + $this->_trim($this->_baseSquare($x)) : + $this->_trim($this->_karatsubaSquare($x)); + } + + /** + * Performs traditional squaring on two BigIntegers + * + * Squaring can be done faster than multiplying a number by itself can be. See + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. + * + * @param array $value + * @return array + * @access private + */ + function _baseSquare($value) + { + if (empty($value)) { + return array(); + } + $square_value = $this->_array_repeat(0, 2 * count($value)); + + for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { + $i2 = $i << 1; + + $temp = $square_value[$i2] + $value[$i] * $value[$i]; + $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$i2] = (int) ($temp - self::$baseFull * $carry); + + // note how we start from $i+1 instead of 0 as we do in multiplication. + for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { + $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; + $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$k] = (int) ($temp - self::$baseFull * $carry); + } + + // the following line can yield values larger 2**15. at this point, PHP should switch + // over to floats. + $square_value[$i + $max_index + 1] = $carry; + } + + return $square_value; + } + + /** + * Performs Karatsuba "squaring" on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. + * + * @param array $value + * @return array + * @access private + */ + function _karatsubaSquare($value) + { + $m = count($value) >> 1; + + if ($m < self::KARATSUBA_CUTOFF) { + return $this->_baseSquare($value); + } + + $x1 = array_slice($value, $m); + $x0 = array_slice($value, 0, $m); + + $z2 = $this->_karatsubaSquare($x1); + $z0 = $this->_karatsubaSquare($x0); + + $z1 = $this->_add($x1, false, $x0, false); + $z1 = $this->_karatsubaSquare($z1[self::VALUE]); + $temp = $this->_add($z2, false, $z0, false); + $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xx = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xx = $this->_add($xx[self::VALUE], $xx[self::SIGN], $z0, false); + + return $xx[self::VALUE]; + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * Here's an example: + * + * divide($b); + * + * echo $quotient->toString(); // outputs 0 + * echo "\r\n"; + * echo $remainder->toString(); // outputs 10 + * ?> + * + * + * @param \phpseclib\Math\BigInteger $y + * @return array + * @access public + * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. + */ + function divide($y) + { + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $quotient = new static(); + $remainder = new static(); + + list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); + + if (gmp_sign($remainder->value) < 0) { + $remainder->value = gmp_add($remainder->value, gmp_abs($y->value)); + } + + return array($this->_normalize($quotient), $this->_normalize($remainder)); + case self::MODE_BCMATH: + $quotient = new static(); + $remainder = new static(); + + $quotient->value = bcdiv($this->value, $y->value, 0); + $remainder->value = bcmod($this->value, $y->value); + + if ($remainder->value[0] == '-') { + $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); + } + + return array($this->_normalize($quotient), $this->_normalize($remainder)); + } + + if (count($y->value) == 1) { + list($q, $r) = $this->_divide_digit($this->value, $y->value[0]); + $quotient = new static(); + $remainder = new static(); + $quotient->value = $q; + $remainder->value = array($r); + $quotient->is_negative = $this->is_negative != $y->is_negative; + return array($this->_normalize($quotient), $this->_normalize($remainder)); + } + + static $zero; + if (!isset($zero)) { + $zero = new static(); + } + + $x = $this->copy(); + $y = $y->copy(); + + $x_sign = $x->is_negative; + $y_sign = $y->is_negative; + + $x->is_negative = $y->is_negative = false; + + $diff = $x->compare($y); + + if (!$diff) { + $temp = new static(); + $temp->value = array(1); + $temp->is_negative = $x_sign != $y_sign; + return array($this->_normalize($temp), $this->_normalize(new static())); + } + + if ($diff < 0) { + // if $x is negative, "add" $y. + if ($x_sign) { + $x = $y->subtract($x); + } + return array($this->_normalize(new static()), $this->_normalize($x)); + } + + // normalize $x and $y as described in HAC 14.23 / 14.24 + $msb = $y->value[count($y->value) - 1]; + for ($shift = 0; !($msb & self::$msb); ++$shift) { + $msb <<= 1; + } + $x->_lshift($shift); + $y->_lshift($shift); + $y_value = &$y->value; + + $x_max = count($x->value) - 1; + $y_max = count($y->value) - 1; + + $quotient = new static(); + $quotient_value = &$quotient->value; + $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1); + + static $temp, $lhs, $rhs; + if (!isset($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + $temp_value = &$temp->value; + $rhs_value = &$rhs->value; + + // $temp = $y << ($x_max - $y_max-1) in base 2**26 + $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value); + + while ($x->compare($temp) >= 0) { + // calculate the "common residue" + ++$quotient_value[$x_max - $y_max]; + $x = $x->subtract($temp); + $x_max = count($x->value) - 1; + } + + for ($i = $x_max; $i >= $y_max + 1; --$i) { + $x_value = &$x->value; + $x_window = array( + isset($x_value[$i]) ? $x_value[$i] : 0, + isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, + isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 + ); + $y_window = array( + $y_value[$y_max], + ($y_max > 0) ? $y_value[$y_max - 1] : 0 + ); + + $q_index = $i - $y_max - 1; + if ($x_window[0] == $y_window[0]) { + $quotient_value[$q_index] = self::$maxDigit; + } else { + $quotient_value[$q_index] = $this->_safe_divide( + $x_window[0] * self::$baseFull + $x_window[1], + $y_window[0] + ); + } + + $temp_value = array($y_window[1], $y_window[0]); + + $lhs->value = array($quotient_value[$q_index]); + $lhs = $lhs->multiply($temp); + + $rhs_value = array($x_window[2], $x_window[1], $x_window[0]); + + while ($lhs->compare($rhs) > 0) { + --$quotient_value[$q_index]; + + $lhs->value = array($quotient_value[$q_index]); + $lhs = $lhs->multiply($temp); + } + + $adjust = $this->_array_repeat(0, $q_index); + $temp_value = array($quotient_value[$q_index]); + $temp = $temp->multiply($y); + $temp_value = &$temp->value; + if (count($temp_value)) { + $temp_value = array_merge($adjust, $temp_value); + } + + $x = $x->subtract($temp); + + if ($x->compare($zero) < 0) { + $temp_value = array_merge($adjust, $y_value); + $x = $x->add($temp); + + --$quotient_value[$q_index]; + } + + $x_max = count($x_value) - 1; + } + + // unnormalize the remainder + $x->_rshift($shift); + + $quotient->is_negative = $x_sign != $y_sign; + + // calculate the "common residue", if appropriate + if ($x_sign) { + $y->_rshift($shift); + $x = $y->subtract($x); + } + + return array($this->_normalize($quotient), $this->_normalize($x)); + } + + /** + * Divides a BigInteger by a regular integer + * + * abc / x = a00 / x + b0 / x + c / x + * + * @param array $dividend + * @param array $divisor + * @return array + * @access private + */ + function _divide_digit($dividend, $divisor) + { + $carry = 0; + $result = array(); + + for ($i = count($dividend) - 1; $i >= 0; --$i) { + $temp = self::$baseFull * $carry + $dividend[$i]; + $result[$i] = $this->_safe_divide($temp, $divisor); + $carry = (int) ($temp - $divisor * $result[$i]); + } + + return array($result, $carry); + } + + /** + * Performs modular exponentiation. + * + * Here's an example: + * + * modPow($b, $c); + * + * echo $c->toString(); // outputs 10 + * ?> + * + * + * @param \phpseclib\Math\BigInteger $e + * @param \phpseclib\Math\BigInteger $n + * @return \phpseclib\Math\BigInteger + * @access public + * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and + * and although the approach involving repeated squaring does vastly better, it, too, is impractical + * for our purposes. The reason being that division - by far the most complicated and time-consuming + * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. + * + * Modular reductions resolve this issue. Although an individual modular reduction takes more time + * then an individual division, when performed in succession (with the same modulo), they're a lot faster. + * + * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, + * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the + * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because + * the product of two odd numbers is odd), but what about when RSA isn't used? + * + * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a + * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the + * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, + * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and + * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. + * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. + */ + function modPow($e, $n) + { + $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); + + if ($e->compare(new static()) < 0) { + $e = $e->abs(); + + $temp = $this->modInverse($n); + if ($temp === false) { + return false; + } + + return $this->_normalize($temp->modPow($e, $n)); + } + + if (MATH_BIGINTEGER_MODE == self::MODE_GMP) { + $temp = new static(); + $temp->value = gmp_powm($this->value, $e->value, $n->value); + + return $this->_normalize($temp); + } + + if ($this->compare(new static()) < 0 || $this->compare($n) > 0) { + list(, $temp) = $this->divide($n); + return $temp->modPow($e, $n); + } + + if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) { + $components = array( + 'modulus' => $n->toBytes(true), + 'publicExponent' => $e->toBytes(true) + ); + + $components = array( + 'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']), + 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent']) + ); + + $RSAPublicKey = pack( + 'Ca*a*a*', + 48, + $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])), + $components['modulus'], + $components['publicExponent'] + ); + + $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $RSAPublicKey = chr(0) . $RSAPublicKey; + $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey; + + $encapsulated = pack( + 'Ca*a*', + 48, + $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), + $rsaOID . $RSAPublicKey + ); + + $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($encapsulated)) . + '-----END PUBLIC KEY-----'; + + $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT); + + if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) { + return new static($result, 256); + } + } + + if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) { + $temp = new static(); + $temp->value = bcpowmod($this->value, $e->value, $n->value, 0); + + return $this->_normalize($temp); + } + + if (empty($e->value)) { + $temp = new static(); + $temp->value = array(1); + return $this->_normalize($temp); + } + + if ($e->value == array(1)) { + list(, $temp) = $this->divide($n); + return $this->_normalize($temp); + } + + if ($e->value == array(2)) { + $temp = new static(); + $temp->value = $this->_square($this->value); + list(, $temp) = $temp->divide($n); + return $this->_normalize($temp); + } + + return $this->_normalize($this->_slidingWindow($e, $n, self::BARRETT)); + + // the following code, although not callable, can be run independently of the above code + // although the above code performed better in my benchmarks the following could might + // perform better under different circumstances. in lieu of deleting it it's just been + // made uncallable + + // is the modulo odd? + if ($n->value[0] & 1) { + return $this->_normalize($this->_slidingWindow($e, $n, self::MONTGOMERY)); + } + // if it's not, it's even + + // find the lowest set bit (eg. the max pow of 2 that divides $n) + for ($i = 0; $i < count($n->value); ++$i) { + if ($n->value[$i]) { + $temp = decbin($n->value[$i]); + $j = strlen($temp) - strrpos($temp, '1') - 1; + $j+= 26 * $i; + break; + } + } + // at this point, 2^$j * $n/(2^$j) == $n + + $mod1 = $n->copy(); + $mod1->_rshift($j); + $mod2 = new static(); + $mod2->value = array(1); + $mod2->_lshift($j); + + $part1 = ($mod1->value != array(1)) ? $this->_slidingWindow($e, $mod1, self::MONTGOMERY) : new static(); + $part2 = $this->_slidingWindow($e, $mod2, self::POWEROF2); + + $y1 = $mod2->modInverse($mod1); + $y2 = $mod1->modInverse($mod2); + + $result = $part1->multiply($mod2); + $result = $result->multiply($y1); + + $temp = $part2->multiply($mod1); + $temp = $temp->multiply($y2); + + $result = $result->add($temp); + list(, $result) = $result->divide($n); + + return $this->_normalize($result); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param \phpseclib\Math\BigInteger $e + * @param \phpseclib\Math\BigInteger $n + * @return \phpseclib\Math\BigInteger + * @access public + */ + function powMod($e, $n) + { + return $this->modPow($e, $n); + } + + /** + * Sliding Window k-ary Modular Exponentiation + * + * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, + * however, this function performs a modular reduction after every multiplication and squaring operation. + * As such, this function has the same preconditions that the reductions being used do. + * + * @param \phpseclib\Math\BigInteger $e + * @param \phpseclib\Math\BigInteger $n + * @param int $mode + * @return \phpseclib\Math\BigInteger + * @access private + */ + function _slidingWindow($e, $n, $mode) + { + static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function + //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1 + + $e_value = $e->value; + $e_length = count($e_value) - 1; + $e_bits = decbin($e_value[$e_length]); + for ($i = $e_length - 1; $i >= 0; --$i) { + $e_bits.= str_pad(decbin($e_value[$i]), self::$base, '0', STR_PAD_LEFT); + } + + $e_length = strlen($e_bits); + + // calculate the appropriate window size. + // $window_size == 3 if $window_ranges is between 25 and 81, for example. + for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { + } + + $n_value = $n->value; + + // precompute $this^0 through $this^$window_size + $powers = array(); + $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode); + $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode); + + // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end + // in a 1. ie. it's supposed to be odd. + $temp = 1 << ($window_size - 1); + for ($i = 1; $i < $temp; ++$i) { + $i2 = $i << 1; + $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode); + } + + $result = array(1); + $result = $this->_prepareReduce($result, $n_value, $mode); + + for ($i = 0; $i < $e_length;) { + if (!$e_bits[$i]) { + $result = $this->_squareReduce($result, $n_value, $mode); + ++$i; + } else { + for ($j = $window_size - 1; $j > 0; --$j) { + if (!empty($e_bits[$i + $j])) { + break; + } + } + + // eg. the length of substr($e_bits, $i, $j + 1) + for ($k = 0; $k <= $j; ++$k) { + $result = $this->_squareReduce($result, $n_value, $mode); + } + + $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode); + + $i += $j + 1; + } + } + + $temp = new static(); + $temp->value = $this->_reduce($result, $n_value, $mode); + + return $temp; + } + + /** + * Modular reduction + * + * For most $modes this will return the remainder. + * + * @see self::_slidingWindow() + * @access private + * @param array $x + * @param array $n + * @param int $mode + * @return array */ - public function modInverse(BigInteger $n) + function _reduce($x, $n, $mode) { - return new static($this->value->modInverse($n->value)); + switch ($mode) { + case self::MONTGOMERY: + return $this->_montgomery($x, $n); + case self::BARRETT: + return $this->_barrett($x, $n); + case self::POWEROF2: + $lhs = new static(); + $lhs->value = $x; + $rhs = new static(); + $rhs->value = $n; + return $x->_mod2($n); + case self::CLASSIC: + $lhs = new static(); + $lhs->value = $x; + $rhs = new static(); + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + case self::NONE: + return $x; + default: + // an invalid $mode was provided + } } /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @return BigInteger[] - * @param BigInteger $n + * Modular reduction preperation + * + * @see self::_slidingWindow() + * @access private + * @param array $x + * @param array $n + * @param int $mode + * @return array */ - public function extendedGCD(BigInteger $n) + function _prepareReduce($x, $n, $mode) { - extract($this->value->extendedGCD($n->value)); - /** - * @var BigInteger $gcd - * @var BigInteger $x - * @var BigInteger $y - */ - return [ - 'gcd' => new static($gcd), - 'x' => new static($x), - 'y' => new static($y) - ]; + if ($mode == self::MONTGOMERY) { + return $this->_prepMontgomery($x, $n); + } + return $this->_reduce($x, $n, $mode); } /** - * Calculates the greatest common divisor + * Modular multiply + * + * @see self::_slidingWindow() + * @access private + * @param array $x + * @param array $y + * @param array $n + * @param int $mode + * @return array + */ + function _multiplyReduce($x, $y, $n, $mode) + { + if ($mode == self::MONTGOMERY) { + return $this->_montgomeryMultiply($x, $y, $n); + } + $temp = $this->_multiply($x, false, $y, false); + return $this->_reduce($temp[self::VALUE], $n, $mode); + } + + /** + * Modular square + * + * @see self::_slidingWindow() + * @access private + * @param array $x + * @param array $n + * @param int $mode + * @return array + */ + function _squareReduce($x, $n, $mode) + { + if ($mode == self::MONTGOMERY) { + return $this->_montgomeryMultiply($x, $x, $n); + } + return $this->_reduce($this->_square($x), $n, $mode); + } + + /** + * Modulos for Powers of Two * - * Say you have 693 and 609. The GCD is 21. + * Calculates $x%$n, where $n = 2**$e, for some $e. Since this is basically the same as doing $x & ($n-1), + * we'll just use this function as a wrapper for doing that. * - * @param BigInteger $n - * @return BigInteger + * @see self::_slidingWindow() + * @access private + * @param \phpseclib\Math\BigInteger $n + * @return \phpseclib\Math\BigInteger */ - public function gcd(BigInteger $n) + function _mod2($n) { - return new static($this->value->gcd($n->value)); + $temp = new static(); + $temp->value = array(1); + return $this->bitwise_and($n->subtract($temp)); } /** - * Absolute value. - * - * @return BigInteger - * @access public + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @see self::_slidingWindow() + * @access private + * @param array $n + * @param array $m + * @return array */ - public function abs() + function _barrett($n, $m) { - return new static($this->value->abs()); + static $cache = array( + self::VARIABLE => array(), + self::DATA => array() + ); + + $m_length = count($m); + + // if ($this->_compare($n, $this->_square($m)) >= 0) { + if (count($n) > 2 * $m_length) { + $lhs = new static(); + $rhs = new static(); + $lhs->value = $n; + $rhs->value = $m; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return $this->_regularBarrett($n, $m); + } + + // n = 2 * m.length + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + + $lhs = new static(); + $lhs_value = &$lhs->value; + $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new static(); + $rhs->value = $m; + + list($u, $m1) = $lhs->divide($rhs); + $u = $u->value; + $m1 = $m1->value; + + $cache[self::DATA][] = array( + 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1'=> $m1 // m.length + ); + } else { + extract($cache[self::DATA][$key]); + } + + $cutoff = $m_length + ($m_length >> 1); + $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) + $msd = array_slice($n, $cutoff); // m.length >> 1 + $lsd = $this->_trim($lsd); + $temp = $this->_multiply($msd, false, $m1, false); + $n = $this->_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 + + if ($m_length & 1) { + return $this->_regularBarrett($n[self::VALUE], $m); + } + + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = array_slice($n[self::VALUE], $m_length - 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = $this->_multiply($temp, false, $u, false); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = $this->_multiply($temp, false, $m, false); + + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + + $result = $this->_subtract($n[self::VALUE], false, $temp[self::VALUE], false); + + while ($this->_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { + $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $m, false); + } + + return $result[self::VALUE]; } /** - * Set Precision + * (Regular) Barrett Modular Reduction * - * Some bitwise operations give different results depending on the precision being used. Examples include left - * shift, not, and rotates. + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. * - * @param int $bits + * @see self::_slidingWindow() + * @access private + * @param array $x + * @param array $n + * @return array + */ + function _regularBarrett($x, $n) + { + static $cache = array( + self::VARIABLE => array(), + self::DATA => array() + ); + + $n_length = count($n); + + if (count($x) > 2 * $n_length) { + $lhs = new static(); + $rhs = new static(); + $lhs->value = $x; + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = new static(); + $lhs_value = &$lhs->value; + $lhs_value = $this->_array_repeat(0, 2 * $n_length); + $lhs_value[] = 1; + $rhs = new static(); + $rhs->value = $n; + list($temp, ) = $lhs->divide($rhs); // m.length + $cache[self::DATA][] = $temp->value; + } + + // 2 * m.length - (m.length - 1) = m.length + 1 + $temp = array_slice($x, $n_length - 1); + // (m.length + 1) + m.length = 2 * m.length + 1 + $temp = $this->_multiply($temp, false, $cache[self::DATA][$key], false); + // (2 * m.length + 1) - (m.length - 1) = m.length + 2 + $temp = array_slice($temp[self::VALUE], $n_length + 1); + + // m.length + 1 + $result = array_slice($x, 0, $n_length + 1); + // m.length + 1 + $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1); + // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1) + + if ($this->_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { + $corrector_value = $this->_array_repeat(0, $n_length + 1); + $corrector_value[count($corrector_value)] = 1; + $result = $this->_add($result, false, $corrector_value, false); + $result = $result[self::VALUE]; + } + + // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits + $result = $this->_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]); + while ($this->_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { + $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Performs long multiplication up to $stop digits + * + * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. + * + * @see self::_regularBarrett() + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @param int $stop + * @return array + * @access private + */ + function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return array( + self::VALUE => array(), + self::SIGN => false + ); + } + + if ($x_length < $y_length) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_length = count($x_value); + $y_length = count($y_value); + } + + $product_value = $this->_array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int) ($temp - self::$baseFull * $carry); + } + + if ($j < $stop) { + $product_value[$j] = $carry; + } + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int) ($temp - self::$baseFull * $carry); + } + + if ($k < $stop) { + $product_value[$k] = $carry; + } + } + + return array( + self::VALUE => $this->_trim($product_value), + self::SIGN => $x_negative != $y_negative + ); + } + + /** + * Montgomery Modular Reduction + * + * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n. + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be + * improved upon (basically, by using the comba method). gcd($n, 2) must be equal to one for this function + * to work correctly. + * + * @see self::_prepMontgomery() + * @see self::_slidingWindow() + * @access private + * @param array $x + * @param array $n + * @return array + */ + function _montgomery($x, $n) + { + static $cache = array( + self::VARIABLE => array(), + self::DATA => array() + ); + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $x; + $cache[self::DATA][] = $this->_modInverse67108864($n); + } + + $k = count($n); + + $result = array(self::VALUE => $x); + + for ($i = 0; $i < $k; ++$i) { + $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; + $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $this->_regularMultiply(array($temp), $n); + $temp = array_merge($this->_array_repeat(0, $i), $temp); + $result = $this->_add($result[self::VALUE], false, $temp, false); + } + + $result[self::VALUE] = array_slice($result[self::VALUE], $k); + + if ($this->_compare($result, false, $n, false) >= 0) { + $result = $this->_subtract($result[self::VALUE], false, $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @see self::_prepMontgomery() + * @see self::_montgomery() + * @access private + * @param array $x + * @param array $y + * @param array $m + * @return array + */ + function _montgomeryMultiply($x, $y, $m) + { + $temp = $this->_multiply($x, false, $y, false); + return $this->_montgomery($temp[self::VALUE], $m); + + // the following code, although not callable, can be run independently of the above code + // although the above code performed better in my benchmarks the following could might + // perform better under different circumstances. in lieu of deleting it it's just been + // made uncallable + + static $cache = array( + self::VARIABLE => array(), + self::DATA => array() + ); + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + $cache[self::DATA][] = $this->_modInverse67108864($m); + } + + $n = max(count($x), count($y), count($m)); + $x = array_pad($x, $n, 0); + $y = array_pad($y, $n, 0); + $m = array_pad($m, $n, 0); + $a = array(self::VALUE => $this->_array_repeat(0, $n + 1)); + for ($i = 0; $i < $n; ++$i) { + $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; + $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $temp * $cache[self::DATA][$key]; + $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false); + $a = $this->_add($a[self::VALUE], false, $temp[self::VALUE], false); + $a[self::VALUE] = array_slice($a[self::VALUE], 1); + } + if ($this->_compare($a[self::VALUE], false, $m, false) >= 0) { + $a = $this->_subtract($a[self::VALUE], false, $m, false); + } + return $a[self::VALUE]; + } + + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @see self::_montgomery() + * @see self::_slidingWindow() + * @access private + * @param array $x + * @param array $n + * @return array */ - public function setPrecision($bits) + function _prepMontgomery($x, $n) { - $this->value->setPrecision($bits); + $lhs = new static(); + $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x); + $rhs = new static(); + $rhs->value = $n; + + list(, $temp) = $lhs->divide($rhs); + return $temp->value; } /** - * Get Precision + * Modular Inverse of a number mod 2**26 (eg. 67108864) + * + * Based off of the bnpInvDigit function implemented and justified in the following URL: * - * Returns the precision if it exists, false if it doesn't + * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} * - * @return int|bool + * The following URL provides more info: + * + * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} + * + * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For + * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields + * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't + * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that + * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the + * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to + * 40 bits, which only 64-bit floating points will support. + * + * Thanks to Pedro Gimeno Fortea for input! + * + * @see self::_montgomery() + * @access private + * @param array $x + * @return int */ - public function getPrecision() + function _modInverse67108864($x) // 2**26 == 67,108,864 { - return $this->value->getPrecision(); + $x = -$x[0]; + $result = $x & 0x3; // x**-1 mod 2**2 + $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 + $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 + $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 + $result = fmod($result * (2 - fmod($x * $result, self::$baseFull)), self::$baseFull); // x**-1 mod 2**26 + return $result & self::$maxDigit; } /** - * Serialize + * Calculates modular inverses. * - * Will be called, automatically, when serialize() is called on a BigInteger object. + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * - * phpseclib 1.0 serialized strings look like this: - * O:15:"Math_BigInteger":1:{s:3:"hex";s:18:"00ab54a98ceb1f0ad2";} + * Here's an example: + * + * modInverse($b); + * echo $c->toString(); // outputs 4 * - * @return string + * echo "\r\n"; + * + * $d = $a->multiply($c); + * list(, $d) = $d->divide($b); + * echo $d; // outputs 1 (as per the definition of modular inverse) + * ?> + * + * + * @param \phpseclib\Math\BigInteger $n + * @return \phpseclib\Math\BigInteger|false + * @access public + * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information. */ - public function serialize() + function modInverse($n) { - $val = ['hex' => $this->toHex(true)]; - $precision = $this->value->getPrecision(); - if ($precision > 0) { - $val['precision'] = $precision; + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = new static(); + $temp->value = gmp_invert($this->value, $n->value); + + return ($temp->value === false) ? false : $this->_normalize($temp); + } + + static $zero, $one; + if (!isset($zero)) { + $zero = new static(); + $one = new static(1); + } + + // $x mod -$n == $x mod $n. + $n = $n->abs(); + + if ($this->compare($zero) < 0) { + $temp = $this->abs(); + $temp = $temp->modInverse($n); + return $this->_normalize($n->subtract($temp)); } - return serialize($val); + + extract($this->extendedGCD($n)); + + if (!$gcd->equals($one)) { + return false; + } + + $x = $x->compare($zero) < 0 ? $x->add($n) : $x; + + return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x); } /** - * Serialize + * Calculates the greatest common divisor and Bezout's identity. * - * Will be called, automatically, when unserialize() is called on a BigInteger object. + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * Here's an example: + * + * extendedGCD($b)); + * + * echo $gcd->toString() . "\r\n"; // outputs 21 + * echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21 + * ?> + * * - * @param string $serialized + * @param \phpseclib\Math\BigInteger $n + * @return \phpseclib\Math\BigInteger + * @access public + * @internal Calculates the GCD using the binary xGCD algorithim described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes, + * the more traditional algorithim requires "relatively costly multiple-precision divisions". */ - public function unserialize($serialized) + function extendedGCD($n) { - $r = unserialize($serialized); - $temp = new static($r['hex'], -16); - $this->value = $temp->value; - if (isset($r['precision'])) { - // recalculate $this->bitmask - $this->setPrecision($r['precision']); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + extract(gmp_gcdext($this->value, $n->value)); + + return array( + 'gcd' => $this->_normalize(new static($g)), + 'x' => $this->_normalize(new static($s)), + 'y' => $this->_normalize(new static($t)) + ); + case self::MODE_BCMATH: + // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works + // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, + // the basic extended euclidean algorithim is what we're using. + + $u = $this->value; + $v = $n->value; + + $a = '1'; + $b = '0'; + $c = '0'; + $d = '1'; + + while (bccomp($v, '0', 0) != 0) { + $q = bcdiv($u, $v, 0); + + $temp = $u; + $u = $v; + $v = bcsub($temp, bcmul($v, $q, 0), 0); + + $temp = $a; + $a = $c; + $c = bcsub($temp, bcmul($a, $q, 0), 0); + + $temp = $b; + $b = $d; + $d = bcsub($temp, bcmul($b, $q, 0), 0); + } + + return array( + 'gcd' => $this->_normalize(new static($u)), + 'x' => $this->_normalize(new static($a)), + 'y' => $this->_normalize(new static($b)) + ); + } + + $y = $n->copy(); + $x = $this->copy(); + $g = new static(); + $g->value = array(1); + + while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) { + $x->_rshift(1); + $y->_rshift(1); + $g->_lshift(1); + } + + $u = $x->copy(); + $v = $y->copy(); + + $a = new static(); + $b = new static(); + $c = new static(); + $d = new static(); + + $a->value = $d->value = $g->value = array(1); + $b->value = $c->value = array(); + + while (!empty($u->value)) { + while (!($u->value[0] & 1)) { + $u->_rshift(1); + if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) { + $a = $a->add($y); + $b = $b->subtract($x); + } + $a->_rshift(1); + $b->_rshift(1); + } + + while (!($v->value[0] & 1)) { + $v->_rshift(1); + if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) { + $c = $c->add($y); + $d = $d->subtract($x); + } + $c->_rshift(1); + $d->_rshift(1); + } + + if ($u->compare($v) >= 0) { + $u = $u->subtract($v); + $a = $a->subtract($c); + $b = $b->subtract($d); + } else { + $v = $v->subtract($u); + $c = $c->subtract($a); + $d = $d->subtract($b); + } } + + return array( + 'gcd' => $this->_normalize($g->multiply($v)), + 'x' => $this->_normalize($c), + 'y' => $this->_normalize($d) + ); } /** - * Performs modular exponentiation. + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * Here's an example: + * + * extendedGCD($b); * - * @param BigInteger $e - * @param BigInteger $n - * @return BigInteger + * echo $gcd->toString() . "\r\n"; // outputs 21 + * ?> + * + * + * @param \phpseclib\Math\BigInteger $n + * @return \phpseclib\Math\BigInteger + * @access public */ - public function powMod(BigInteger $e, BigInteger $n) + function gcd($n) { - return new static($this->value->powMod($e->value, $n->value)); + extract($this->extendedGCD($n)); + return $gcd; } /** - * Performs modular exponentiation. + * Absolute value. * - * @param BigInteger $e - * @param BigInteger $n - * @return BigInteger + * @return \phpseclib\Math\BigInteger + * @access public */ - public function modPow(BigInteger $e, BigInteger $n) + function abs() { - return new static($this->value->modPow($e->value, $n->value)); + $temp = new static(); + + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp->value = gmp_abs($this->value); + break; + case self::MODE_BCMATH: + $temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value; + break; + default: + $temp->value = $this->value; + } + + return $temp; } /** @@ -462,16 +2687,65 @@ class BigInteger implements \Serializable * * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param BigInteger $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @param \phpseclib\Math\BigInteger $y + * @return int that is < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. * @access public * @see self::equals() + * @internal Could return $this->subtract($x), but that's not as fast as what we do do. + */ + function compare($y) + { + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $r = gmp_cmp($this->value, $y->value); + if ($r < -1) { + $r = -1; + } + if ($r > 1) { + $r = 1; + } + return $r; + case self::MODE_BCMATH: + return bccomp($this->value, $y->value, 0); + } + + return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative); + } + + /** + * Compares two numbers. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return int + * @see self::compare() + * @access private */ - public function compare(BigInteger $y) + function _compare($x_value, $x_negative, $y_value, $y_negative) { - return $this->value->compare($y->value); + if ($x_negative != $y_negative) { + return (!$x_negative && $y_negative) ? 1 : -1; + } + + $result = $x_negative ? -1 : 1; + + if (count($x_value) != count($y_value)) { + return (count($x_value) > count($y_value)) ? $result : -$result; + } + $size = max(count($x_value), count($y_value)); + + $x_value = array_pad($x_value, $size, 0); + $y_value = array_pad($y_value, $size, 0); + + for ($i = count($x_value) - 1; $i >= 0; --$i) { + if ($x_value[$i] != $y_value[$i]) { + return ($x_value[$i] > $y_value[$i]) ? $result : -$result; + } + } + + return 0; } /** @@ -479,55 +2753,201 @@ class BigInteger implements \Serializable * * If you need to see if one number is greater than or less than another number, use BigInteger::compare() * - * @param BigInteger $x + * @param \phpseclib\Math\BigInteger $x * @return bool + * @access public + * @see self::compare() */ - public function equals(BigInteger $x) + function equals($x) { - return $this->value->equals($x->value); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + return gmp_cmp($this->value, $x->value) == 0; + default: + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } } /** - * Logical Not + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. * - * @return BigInteger + * @param int $bits + * @access public */ - public function bitwise_not() + function setPrecision($bits) { - return new static($this->value->bitwise_not()); + $this->precision = $bits; + if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) { + $this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); + } else { + $this->bitmask = new static(bcpow('2', $bits, 0)); + } + + $temp = $this->_normalize($this); + $this->value = $temp->value; } /** * Logical And * - * @param BigInteger $x - * @return BigInteger + * @param \phpseclib\Math\BigInteger $x + * @access public + * @internal Implemented per a request by Lluis Pamies i Juarez + * @return \phpseclib\Math\BigInteger + */ + function bitwise_and($x) + { + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = new static(); + $temp->value = gmp_and($this->value, $x->value); + + return $this->_normalize($temp); + case self::MODE_BCMATH: + $left = $this->toBytes(); + $right = $x->toBytes(); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->_normalize(new static($left & $right, 256)); + } + + $result = $this->copy(); + + $length = min(count($x->value), count($this->value)); + + $result->value = array_slice($result->value, 0, $length); + + for ($i = 0; $i < $length; ++$i) { + $result->value[$i]&= $x->value[$i]; + } + + return $this->_normalize($result); + } + + /** + * Logical Or + * + * @param \phpseclib\Math\BigInteger $x + * @access public + * @internal Implemented per a request by Lluis Pamies i Juarez + * @return \phpseclib\Math\BigInteger */ - public function bitwise_and(BigInteger $x) + function bitwise_or($x) { - return new static($this->value->bitwise_and($x->value)); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = new static(); + $temp->value = gmp_or($this->value, $x->value); + + return $this->_normalize($temp); + case self::MODE_BCMATH: + $left = $this->toBytes(); + $right = $x->toBytes(); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->_normalize(new static($left | $right, 256)); + } + + $length = max(count($this->value), count($x->value)); + $result = $this->copy(); + $result->value = array_pad($result->value, $length, 0); + $x->value = array_pad($x->value, $length, 0); + + for ($i = 0; $i < $length; ++$i) { + $result->value[$i]|= $x->value[$i]; + } + + return $this->_normalize($result); } /** - * Logical Or + * Logical Exclusive-Or * - * @param BigInteger $x - * @return BigInteger + * @param \phpseclib\Math\BigInteger $x + * @access public + * @internal Implemented per a request by Lluis Pamies i Juarez + * @return \phpseclib\Math\BigInteger */ - public function bitwise_or(BigInteger $x) + function bitwise_xor($x) { - return new static($this->value->bitwise_or($x->value)); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + $temp = new static(); + $temp->value = gmp_xor(gmp_abs($this->value), gmp_abs($x->value)); + return $this->_normalize($temp); + case self::MODE_BCMATH: + $left = $this->toBytes(); + $right = $x->toBytes(); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->_normalize(new static($left ^ $right, 256)); + } + + $length = max(count($this->value), count($x->value)); + $result = $this->copy(); + $result->is_negative = false; + $result->value = array_pad($result->value, $length, 0); + $x->value = array_pad($x->value, $length, 0); + + for ($i = 0; $i < $length; ++$i) { + $result->value[$i]^= $x->value[$i]; + } + + return $this->_normalize($result); } /** - * Logical Exclusive Or + * Logical Not * - * @param BigInteger $x - * @return BigInteger + * @access public + * @internal Implemented per a request by Lluis Pamies i Juarez + * @return \phpseclib\Math\BigInteger */ - public function bitwise_xor(BigInteger $x) + function bitwise_not() { - return new static($this->value->bitwise_xor($x->value)); + // calculuate "not" without regard to $this->precision + // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) + $temp = $this->toBytes(); + if ($temp == '') { + return $this->_normalize(new static()); + } + $pre_msb = decbin(ord($temp[0])); + $temp = ~$temp; + $msb = decbin(ord($temp[0])); + if (strlen($msb) == 8) { + $msb = substr($msb, strpos($msb, '0')); + } + $temp[0] = chr(bindec($msb)); + + // see if we need to add extra leading 1's + $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; + $new_bits = $this->precision - $current_bits; + if ($new_bits <= 0) { + return $this->_normalize(new static($temp, 256)); + } + + // generate as many leading 1's as we need to. + $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); + $this->_base256_lshift($leading_ones, $current_bits); + + $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); + + return $this->_normalize(new static($leading_ones | $temp, 256)); } /** @@ -536,11 +2956,36 @@ class BigInteger implements \Serializable * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. * * @param int $shift - * @return BigInteger + * @return \phpseclib\Math\BigInteger + * @access public + * @internal The only version that yields any speed increases is the internal version. */ - public function bitwise_rightShift($shift) + function bitwise_rightShift($shift) { - return new static($this->value->bitwise_rightShift($shift)); + $temp = new static(); + + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + static $two; + + if (!isset($two)) { + $two = gmp_init('2'); + } + + $temp->value = gmp_div_q($this->value, gmp_pow($two, $shift)); + + break; + case self::MODE_BCMATH: + $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); + + break; + default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->_rshift($shift); + } + + return $this->_normalize($temp); } /** @@ -549,11 +2994,36 @@ class BigInteger implements \Serializable * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. * * @param int $shift - * @return BigInteger + * @return \phpseclib\Math\BigInteger + * @access public + * @internal The only version that yields any speed increases is the internal version. */ - public function bitwise_leftShift($shift) + function bitwise_leftShift($shift) { - return new static($this->value->bitwise_leftShift($shift)); + $temp = new static(); + + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + static $two; + + if (!isset($two)) { + $two = gmp_init('2'); + } + + $temp->value = gmp_mul($this->value, gmp_pow($two, $shift)); + + break; + case self::MODE_BCMATH: + $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); + + break; + default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->_lshift($shift); + } + + return $this->_normalize($temp); } /** @@ -562,11 +3032,43 @@ class BigInteger implements \Serializable * Instead of the top x bits being dropped they're appended to the shifted bit string. * * @param int $shift - * @return BigInteger + * @return \phpseclib\Math\BigInteger + * @access public */ - public function bitwise_leftRotate($shift) + function bitwise_leftRotate($shift) { - return new static($this->value->bitwise_leftRotate($shift)); + $bits = $this->toBytes(); + + if ($this->precision > 0) { + $precision = $this->precision; + if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) { + $mask = $this->bitmask->subtract(new static(1)); + $mask = $mask->toBytes(); + } else { + $mask = $this->bitmask->toBytes(); + } + } else { + $temp = ord($bits[0]); + for ($i = 0; $temp >> $i; ++$i) { + } + $precision = 8 * strlen($bits) - 8 + $i; + $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); + } + + if ($shift < 0) { + $shift+= $precision; + } + $shift%= $precision; + + if (!$shift) { + return $this->copy(); + } + + $left = $this->bitwise_leftShift($shift); + $left = $left->bitwise_and(new static($mask, 256)); + $right = $this->bitwise_rightShift($precision - $shift); + $result = MATH_BIGINTEGER_MODE != self::MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right); + return $this->_normalize($result); } /** @@ -575,118 +3077,255 @@ class BigInteger implements \Serializable * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. * * @param int $shift - * @return BigInteger + * @return \phpseclib\Math\BigInteger + * @access public */ - public function bitwise_rightRotate($shift) + function bitwise_rightRotate($shift) { - return new static($this->value->bitwise_rightRotate($shift)); + return $this->bitwise_leftRotate(-$shift); } /** - * Returns the smallest and largest n-bit number + * Generates a random BigInteger * - * @param int $bits - * @return BigInteger[] + * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not. + * + * @param int $size + * @return \phpseclib\Math\BigInteger + * @access private */ - public static function minMaxBits($bits) + function _random_number_helper($size) { - self::initialize_static_variables(); + if (class_exists('\phpseclib\Crypt\Random')) { + $random = Random::string($size); + } else { + $random = ''; - $class = self::$mainEngine; - extract($class::minMaxBits($bits)); - /** @var BigInteger $min - * @var BigInteger $max - */ - return [ - 'min' => new static($min), - 'max' => new static($max) - ]; - } + if ($size & 1) { + $random.= chr(mt_rand(0, 255)); + } - /** - * Return the size of a BigInteger in bits - * - * @return int - */ - public function getLength() - { - return $this->value->getLength(); - } + $blocks = $size >> 1; + for ($i = 0; $i < $blocks; ++$i) { + // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems + $random.= pack('n', mt_rand(0, 0xFFFF)); + } + } - /** - * Return the size of a BigInteger in bytes - * - * @return int - */ - public function getLengthInBytes() - { - return $this->value->getLengthInBytes(); + return new static($random, 256); } /** - * Generates a random number of a certain size + * Generate a random number + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: * - * Bit length is equal to $size + * $min->random($max) + * $max->random($min) * - * @param int $size - * @return BigInteger + * @param \phpseclib\Math\BigInteger $arg1 + * @param \phpseclib\Math\BigInteger $arg2 + * @return \phpseclib\Math\BigInteger + * @access public + * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object. + * That method is still supported for BC purposes. */ - public static function random($size) + function random($arg1, $arg2 = false) { - self::initialize_static_variables(); + if ($arg1 === false) { + return false; + } - $class = self::$mainEngine; - return new static($class::random($size)); - } + if ($arg2 === false) { + $max = $arg1; + $min = $this; + } else { + $min = $arg1; + $max = $arg2; + } - /** - * Generates a random prime number of a certain size - * - * Bit length is equal to $size - * - * @param int $size - * @return BigInteger - */ - public static function randomPrime($size) - { - self::initialize_static_variables(); + $compare = $max->compare($min); + + if (!$compare) { + return $this->_normalize($min); + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } - $class = self::$mainEngine; - return new static($class::randomPrime($size)); + static $one; + if (!isset($one)) { + $one = new static(1); + } + + $max = $max->subtract($min->subtract($one)); + $size = strlen(ltrim($max->toBytes(), chr(0))); + + /* + doing $random % $max doesn't work because some numbers will be more likely to occur than others. + eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 + would produce 5 whereas the only value of random that could produce 139 would be 139. ie. + not all numbers would be equally likely. some would be more likely than others. + + creating a whole new random number until you find one that is within the range doesn't work + because, for sufficiently small ranges, the likelihood that you'd get a number within that range + would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability + would be pretty high that $random would be greater than $max. + + phpseclib works around this using the technique described here: + + http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string + */ + $random_max = new static(chr(1) . str_repeat("\0", $size), 256); + $random = $this->_random_number_helper($size); + + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + + while ($random->compare($max_multiple) >= 0) { + $random = $random->subtract($max_multiple); + $random_max = $random_max->subtract($max_multiple); + $random = $random->bitwise_leftShift(8); + $random = $random->add($this->_random_number_helper(1)); + $random_max = $random_max->bitwise_leftShift(8); + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + } + list(, $random) = $random->divide($max); + + return $this->_normalize($random->add($min)); } /** - * Generate a random prime number between a range + * Generate a random prime number. * * If there's not a prime within the given range, false will be returned. + * If more than $timeout seconds have elapsed, give up and return false. * - * @param BigInteger $min - * @param BigInteger $max - * @return false|BigInteger + * @param \phpseclib\Math\BigInteger $arg1 + * @param \phpseclib\Math\BigInteger $arg2 + * @param int $timeout + * @return Math_BigInteger|false + * @access public + * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}. */ - public static function randomRangePrime(BigInteger $min, BigInteger $max) + function randomPrime($arg1, $arg2 = false, $timeout = false) { - $class = self::$mainEngine; - return new static($class::randomRangePrime($min->value, $max->value)); + if ($arg1 === false) { + return false; + } + + if ($arg2 === false) { + $max = $arg1; + $min = $this; + } else { + $min = $arg1; + $max = $arg2; + } + + $compare = $max->compare($min); + + if (!$compare) { + return $min->isPrime() ? $min : false; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + + static $one, $two; + if (!isset($one)) { + $one = new static(1); + $two = new static(2); + } + + $start = time(); + + $x = $this->random($min, $max); + + // gmp_nextprime() requires PHP 5 >= 5.2.0 per . + if (MATH_BIGINTEGER_MODE == self::MODE_GMP && extension_loaded('gmp')) { + $p = new static(); + $p->value = gmp_nextprime($x->value); + + if ($p->compare($max) <= 0) { + return $p; + } + + if (!$min->equals($x)) { + $x = $x->subtract($one); + } + + return $x->randomPrime($min, $x); + } + + if ($x->equals($two)) { + return $x; + } + + $x->_make_odd(); + if ($x->compare($max) > 0) { + // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range + if ($min->equals($max)) { + return false; + } + $x = $min->copy(); + $x->_make_odd(); + } + + $initial_x = $x->copy(); + + while (true) { + if ($timeout !== false && time() - $start > $timeout) { + return false; + } + + if ($x->isPrime()) { + return $x; + } + + $x = $x->add($two); + + if ($x->compare($max) > 0) { + $x = $min->copy(); + if ($x->equals($two)) { + return $x; + } + $x->_make_odd(); + } + + if ($x->equals($initial_x)) { + return false; + } + } } /** - * Generate a random number between a range + * Make the current number odd * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param BigInteger $min - * @param BigInteger $max - * @return BigInteger + * @see self::randomPrime() + * @access private */ - public static function randomRange(BigInteger $min, BigInteger $max) + function _make_odd() { - $class = self::$mainEngine; - return new static($class::randomRange($min->value, $max->value)); + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + gmp_setbit($this->value, 0); + break; + case self::MODE_BCMATH: + if ($this->value[strlen($this->value) - 1] % 2 == 0) { + $this->value = bcadd($this->value, '1'); + } + break; + default: + $this->value[0] |= 1; + } } /** @@ -696,169 +3335,453 @@ class BigInteger implements \Serializable * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads * on a website instead of just one. * - * @param int|bool $t + * @param \phpseclib\Math\BigInteger $t * @return bool + * @access public + * @internal Uses the + * {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. See + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}. */ - public function isPrime($t = false) + function isPrime($t = false) { - return $this->value->isPrime($t); + $length = strlen($this->toBytes()); + + if (!$t) { + // see HAC 4.49 "Note (controlling the error probability)" + // @codingStandardsIgnoreStart + if ($length >= 163) { $t = 2; } // floor(1300 / 8) + else if ($length >= 106) { $t = 3; } // floor( 850 / 8) + else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) + else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) + else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) + else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) + else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) + else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) + else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) + else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) + else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) + else { $t = 27; } + // @codingStandardsIgnoreEnd + } + + // ie. gmp_testbit($this, 0) + // ie. isEven() or !isOdd() + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + return gmp_prob_prime($this->value, $t) != 0; + case self::MODE_BCMATH: + if ($this->value === '2') { + return true; + } + if ($this->value[strlen($this->value) - 1] % 2 == 0) { + return false; + } + break; + default: + if ($this->value == array(2)) { + return true; + } + if (~$this->value[0] & 1) { + return false; + } + } + + static $primes, $zero, $one, $two; + + if (!isset($primes)) { + $primes = array( + 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 + ); + + if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) { + for ($i = 0; $i < count($primes); ++$i) { + $primes[$i] = new static($primes[$i]); + } + } + + $zero = new static(); + $one = new static(1); + $two = new static(2); + } + + if ($this->equals($one)) { + return false; + } + + // see HAC 4.4.1 "Random search for probable primes" + if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) { + foreach ($primes as $prime) { + list(, $r) = $this->divide($prime); + if ($r->equals($zero)) { + return $this->equals($prime); + } + } + } else { + $value = $this->value; + foreach ($primes as $prime) { + list(, $r) = $this->_divide_digit($value, $prime); + if (!$r) { + return count($value) == 1 && $value[0] == $prime; + } + } + } + + $n = $this->copy(); + $n_1 = $n->subtract($one); + $n_2 = $n->subtract($two); + + $r = $n_1->copy(); + $r_value = $r->value; + // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) { + $s = 0; + // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier + while ($r->value[strlen($r->value) - 1] % 2 == 0) { + $r->value = bcdiv($r->value, '2', 0); + ++$s; + } + } else { + for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { + $temp = ~$r_value[$i] & 0xFFFFFF; + for ($j = 1; ($temp >> $j) & 1; ++$j) { + } + if ($j != 25) { + break; + } + } + $s = 26 * $i + $j; + $r->_rshift($s); + } + + for ($i = 0; $i < $t; ++$i) { + $a = $this->random($two, $n_2); + $y = $a->modPow($r, $n); + + if (!$y->equals($one) && !$y->equals($n_1)) { + for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { + $y = $y->modPow($two, $n); + if ($y->equals($one)) { + return false; + } + } + + if (!$y->equals($n_1)) { + return false; + } + } + } + return true; } /** - * Calculates the nth root of a biginteger. + * Logical Left Shift * - * Returns the nth root of a positive biginteger, where n defaults to 2 + * Shifts BigInteger's by $shift bits. * - * @param int $n optional - * @return BigInteger + * @param int $shift + * @access private */ - public function root($n = 2) + function _lshift($shift) { - return new static($this->value->root($n)); - } + if ($shift == 0) { + return; + } - /** - * Performs exponentiation. - * - * @param BigInteger $n - * @return BigInteger - */ - public function pow(BigInteger $n) - { - return new static($this->value->pow($n->value)); + $num_digits = (int) ($shift / self::$base); + $shift %= self::$base; + $shift = 1 << $shift; + + $carry = 0; + + for ($i = 0; $i < count($this->value); ++$i) { + $temp = $this->value[$i] * $shift + $carry; + $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $this->value[$i] = (int) ($temp - $carry * self::$baseFull); + } + + if ($carry) { + $this->value[count($this->value)] = $carry; + } + + while ($num_digits--) { + array_unshift($this->value, 0); + } } /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits. * - * @param BigInteger ...$nums - * @return BigInteger + * @param int $shift + * @access private */ - public static function min(BigInteger ...$nums) + function _rshift($shift) { - $class = self::$mainEngine; - $nums = array_map(function($num) { return $num->value; }, $nums); - return new static($class::min(...$nums)); + if ($shift == 0) { + return; + } + + $num_digits = (int) ($shift / self::$base); + $shift %= self::$base; + $carry_shift = self::$base - $shift; + $carry_mask = (1 << $shift) - 1; + + if ($num_digits) { + $this->value = array_slice($this->value, $num_digits); + } + + $carry = 0; + + for ($i = count($this->value) - 1; $i >= 0; --$i) { + $temp = $this->value[$i] >> $shift | $carry; + $carry = ($this->value[$i] & $carry_mask) << $carry_shift; + $this->value[$i] = $temp; + } + + $this->value = $this->_trim($this->value); } /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision * - * @param BigInteger ...$nums - * @return BigInteger + * @param \phpseclib\Math\BigInteger $result + * @return \phpseclib\Math\BigInteger + * @see self::_trim() + * @access private */ - public static function max(BigInteger ...$nums) + function _normalize($result) { - $class = self::$mainEngine; - $nums = array_map(function($num) { return $num->value; }, $nums); - return new static($class::max(...$nums)); + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + switch (MATH_BIGINTEGER_MODE) { + case self::MODE_GMP: + if ($this->bitmask !== false) { + $flip = gmp_cmp($result->value, gmp_init(0)) < 0; + if ($flip) { + $result->value = gmp_neg($result->value); + } + $result->value = gmp_and($result->value, $result->bitmask->value); + if ($flip) { + $result->value = gmp_neg($result->value); + } + } + + return $result; + case self::MODE_BCMATH: + if (!empty($result->bitmask->value)) { + $result->value = bcmod($result->value, $result->bitmask->value); + } + + return $result; + } + + $value = &$result->value; + + if (!count($value)) { + $result->is_negative = false; + return $result; + } + + $value = $this->_trim($value); + + if (!empty($result->bitmask->value)) { + $length = min(count($value), count($this->bitmask->value)); + $value = array_slice($value, 0, $length); + + for ($i = 0; $i < $length; ++$i) { + $value[$i] = $value[$i] & $this->bitmask->value[$i]; + } + } + + return $result; } /** - * Tests BigInteger to see if it is between two integers, inclusive + * Trim * - * @param BigInteger $min - * @param BigInteger $max - * @return bool + * Removes leading zeros + * + * @param array $value + * @return \phpseclib\Math\BigInteger + * @access private */ - public function between(BigInteger $min, BigInteger $max) + function _trim($value) { - return $this->value->between($min->value, $max->value); - } + for ($i = count($value) - 1; $i >= 0; --$i) { + if ($value[$i]) { + break; + } + unset($value[$i]); + } - /** - * Clone - */ - public function __clone() - { - $this->value = clone $this->value; + return $value; } /** - * Is Odd? + * Array Repeat * - * @return boolean + * @param array $input + * @param mixed $multiplier + * @return array + * @access private */ - public function isOdd() + function _array_repeat($input, $multiplier) { - return $this->value->isOdd(); + return ($multiplier) ? array_fill(0, $multiplier, $input) : array(); } /** - * Tests if a bit is set + * Logical Left Shift * - * @param int $x - * @return boolean + * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. + * + * @param string $x (by reference) + * @param int $shift + * @return string + * @access private */ - public function testBit($x) + function _base256_lshift(&$x, $shift) { - return $this->value->testBit($x); + if ($shift == 0) { + return; + } + + $num_bytes = $shift >> 3; // eg. floor($shift/8) + $shift &= 7; // eg. $shift % 8 + + $carry = 0; + for ($i = strlen($x) - 1; $i >= 0; --$i) { + $temp = ord($x[$i]) << $shift | $carry; + $x[$i] = chr($temp); + $carry = $temp >> 8; + } + $carry = ($carry != 0) ? chr($carry) : ''; + $x = $carry . $x . str_repeat(chr(0), $num_bytes); } /** - * Is Negative? + * Logical Right Shift + * + * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder. * - * @return boolean + * @param string $x (by referenc) + * @param int $shift + * @return string + * @access private */ - public function isNegative() + function _base256_rshift(&$x, $shift) { - return $this->value->isNegative(); + if ($shift == 0) { + $x = ltrim($x, chr(0)); + return ''; + } + + $num_bytes = $shift >> 3; // eg. floor($shift/8) + $shift &= 7; // eg. $shift % 8 + + $remainder = ''; + if ($num_bytes) { + $start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes; + $remainder = substr($x, $start); + $x = substr($x, 0, -$num_bytes); + } + + $carry = 0; + $carry_shift = 8 - $shift; + for ($i = 0; $i < strlen($x); ++$i) { + $temp = (ord($x[$i]) >> $shift) | $carry; + $carry = (ord($x[$i]) << $carry_shift) & 0xFF; + $x[$i] = chr($temp); + } + $x = ltrim($x, chr(0)); + + $remainder = chr($carry >> $carry_shift) . $remainder; + + return ltrim($remainder, chr(0)); } + // one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long + // at 32-bits, while java's longs are 64-bits. + /** - * Negate - * - * Given $k, returns -$k + * Converts 32-bit integers to bytes. * - * @return BigInteger + * @param int $x + * @return string + * @access private */ - public function negate() + function _int2bytes($x) { - return new static($this->value->negate()); + return ltrim(pack('N', $x), chr(0)); } /** - * Scan for 1 and right shift by that amount + * Converts bytes to 32-bit integers * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @param BigInteger $r + * @param string $x * @return int + * @access private */ - public static function scan1divide(BigInteger $r) + function _bytes2int($x) { - $class = self::$mainEngine; - return $class::scan1divide($r->value); + $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT)); + return $temp['int']; } /** - * Create Recurring Modulo Function + * DER-encode an integer * - * Sometimes it may be desirable to do repeated modulos with the same number outside of - * modular exponentiation + * The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL * - * @return callable + * @see self::modPow() + * @access private + * @param int $length + * @return string */ - public function createRecurringModuloFunction() + function _encodeASN1Length($length) { - $func = $this->value->createRecurringModuloFunction(); - return function(BigInteger $x) use ($func) { - return new static($func($x->value)); - }; + if ($length <= 0x7F) { + return chr($length); + } + + $temp = ltrim(pack('N', $length), chr(0)); + return pack('Ca*', 0x80 | strlen($temp), $temp); } /** - * Bitwise Split + * Single digit division * - * Splits BigInteger's into chunks of $split bits + * Even if int64 is being used the division operator will return a float64 value + * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't + * have the precision of int64 this is a problem so, when int64 is being used, + * we'll guarantee that the dividend is divisible by first subtracting the remainder. * - * @param int $split - * @return \phpseclib3\Math\BigInteger[] + * @access private + * @param int $x + * @param int $y + * @return int */ - public function bitwise_split($split) + function _safe_divide($x, $y) { - return array_map(function($val) { - return new static($val); - }, $this->value->bitwise_split($split)); + if (self::$base === 26) { + return (int) ($x / $y); + } + + // self::$base === 31 + return ($x - ($x % $y)) / $y; } -} \ No newline at end of file +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php deleted file mode 100644 index b97392432..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php +++ /dev/null @@ -1,742 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Exception\BadConfigurationException; - -/** - * BCMath Engine. - * - * @package BCMath - * @author Jim Wigginton - * @access public - */ -class BCMath extends Engine -{ - /** - * Can Bitwise operations be done fast? - * - * @see parent::bitwise_leftRotate() - * @see parent::bitwise_rightRotate() - * @access protected - */ - const FAST_BITWISE = false; - - /** - * Engine Directory - * - * @see parent::setModExpEngine - * @access protected - */ - const ENGINE_DIR = 'BCMath'; - - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\BCMath - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\BCMath - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\BCMath - */ - protected static $two; - - /** - * Primes > 2 and < 1000 - * - * @var array - */ - protected static $primes; - - /** - * Test for engine validity - * - * @see parent::__construct() - * @return bool - */ - public static function isValidEngine() - { - return extension_loaded('bcmath'); - } - - /** - * Default constructor - * - * @param mixed $x integer Base-10 number or base-$base number if $base set. - * @param int $base - * @see parent::__construct() - * @return \phpseclib3\Math\BigInteger\Engines\BCMath - */ - public function __construct($x = 0, $base = 10) - { - if (!isset(self::$isValidEngine)) { - self::$isValidEngine = self::isValidEngine(); - } - if (!self::$isValidEngine) { - throw new BadConfigurationException('BCMath is not setup correctly on this system'); - } - - $this->value = '0'; - - parent::__construct($x, $base); - } - - /** - * Initialize a BCMath BigInteger Engine instance - * - * @param int $base - * @see parent::__construct() - */ - protected function initialize($base) - { - switch (abs($base)) { - case 256: - // round $len to the nearest 4 - $len = (strlen($this->value) + 3) & 0xFFFFFFFC; - - $x = str_pad($this->value, $len, chr(0), STR_PAD_LEFT); - - $this->value = '0'; - for ($i = 0; $i < $len; $i+= 4) { - $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 - $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0); - } - - if ($this->is_negative) { - $this->value = '-' . $this->value; - } - break; - case 16: - $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; - $temp = new self(Hex::decode($x), 256); - $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; - $this->is_negative = false; - break; - case 10: - // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different - // results then doing it on '-1' does (modInverse does $x[0]) - $this->value = $this->value === '-' ? '0' : (string) $this->value; - } - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - if ($this->value === '0') { - return '0'; - } - - return ltrim($this->value, '0'); - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * @param bool $twos_compliment - * @return string - */ - function toBytes($twos_compliment = false) - { - if ($twos_compliment) { - return $this->toBytesHelper(); - } - - $value = ''; - $current = $this->value; - - if ($current[0] == '-') { - $current = substr($current, 1); - } - - while (bccomp($current, '0', 0) > 0) { - $temp = bcmod($current, '16777216'); - $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value; - $current = bcdiv($current, '16777216', 0); - } - - return $this->precision > 0 ? - substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : - ltrim($value, chr(0)); - } - - /** - * Adds two BigIntegers. - * - * @param BCMath $y - * @return BCMath - */ - public function add(BCMath $y) - { - $temp = new self(); - $temp->value = bcadd($this->value, $y->value); - - return $this->normalize($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param BCMath $y - * @return BCMath - */ - public function subtract(BCMath $y) - { - $temp = new self(); - $temp->value = bcsub($this->value, $y->value); - - return $this->normalize($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param BCMath $x - * @return BCMath - */ - public function multiply(BCMath $x) - { - $temp = new self(); - $temp->value = bcmul($this->value, $x->value); - - return $this->normalize($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param BCMath $y - * @return BCMath - */ - public function divide(BCMath $y) - { - $quotient = new self(); - $remainder = new self(); - - $quotient->value = bcdiv($this->value, $y->value, 0); - $remainder->value = bcmod($this->value, $y->value); - - if ($remainder->value[0] == '-') { - $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); - } - - return [$this->normalize($quotient), $this->normalize($remainder)]; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * @return false|BCMath - * @param \phpseclib3\Math\BigInteger\Engines\BCMath $n - */ - public function modInverse(BCMath $n) - { - return $this->modInverseHelper($n); - } - - /** - * Calculates the greatest common divisor and Bezout's identity. - * - * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that - * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which - * combination is returned is dependent upon which mode is in use. See - * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. - * - * @param BCMath $n - * @return BCMath - */ - public function extendedGCD(BCMath $n) - { - // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works - // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, - // the basic extended euclidean algorithim is what we're using. - - $u = $this->value; - $v = $n->value; - - $a = '1'; - $b = '0'; - $c = '0'; - $d = '1'; - - while (bccomp($v, '0', 0) != 0) { - $q = bcdiv($u, $v, 0); - - $temp = $u; - $u = $v; - $v = bcsub($temp, bcmul($v, $q, 0), 0); - - $temp = $a; - $a = $c; - $c = bcsub($temp, bcmul($a, $q, 0), 0); - - $temp = $b; - $b = $d; - $d = bcsub($temp, bcmul($b, $q, 0), 0); - } - - return [ - 'gcd' => $this->normalize(new static($u)), - 'x' => $this->normalize(new static($a)), - 'y' => $this->normalize(new static($b)) - ]; - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param BCMath $n - * @return BCMath - */ - public function gcd(BCMath $n) - { - extract($this->extendedGCD($n)); - /** @var BCMath $gcd */ - return $gcd; - } - - /** - * Absolute value. - * - * @return \phpseclib3\Math\BigInteger\Engines\BCMath - */ - public function abs() - { - $temp = new static(); - $temp->value = strlen($this->value) && $this->value[0] == '-' ? - substr($this->value, 1) : - $this->value; - - return $temp; - } - - /** - * Logical And - * - * @param BCMath $x - * @return BCMath - */ - public function bitwise_and(BCMath $x) - { - return $this->bitwiseAndHelper($x); - } - - /** - * Logical Or - * - * @param BCMath $x - * @return BCMath - */ - public function bitwise_or(BCMath $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Logical Exclusive Or - * - * @param BCMath $x - * @return BCMath - */ - public function bitwise_xor(BCMath $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\BCMath - */ - public function bitwise_rightShift($shift) - { - $temp = new static(); - $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); - - return $this->normalize($temp); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\BCMath - */ - public function bitwise_leftShift($shift) - { - $temp = new static(); - $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); - - return $this->normalize($temp); - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is - * demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param BCMath $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @see self::equals() - */ - public function compare(BCMath $y) - { - return bccomp($this->value, $y->value, 0); - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param BCMath $x - * @return bool - */ - public function equals(BCMath $x) - { - return $this->value == $x->value; - } - - /** - * Performs modular exponentiation. - * - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - public function modPow(BCMath $e, BCMath $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - public function powMod(BCMath $e, BCMath $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - protected function powModInner(BCMath $e, BCMath $n) - { - try { - $class = self::$modexpEngine; - return $class::powModHelper($this, $e, $n, static::class); - } catch (\Exception $err) { - return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); - } - } - - /** - * Normalize - * - * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision - * - * @param BCMath $result - * @return BCMath - */ - protected function normalize(BCMath $result) - { - unset($result->reduce); - - $result->precision = $this->precision; - $result->bitmask = $this->bitmask; - - if ($result->bitmask !== false) { - $result->value = bcmod($result->value, $result->bitmask->value); - } - - return $result; - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param BCMath $min - * @param BCMath $max - * @return false|BCMath - */ - public static function randomRangePrime(BCMath $min, BCMath $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param BCMath $min - * @param BCMath $max - * @return BCMath - */ - public static function randomRange(BCMath $min, BCMath $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Make the current number odd - * - * If the current number is odd it'll be unchanged. If it's even, one will be added to it. - * - * @see self::randomPrime() - */ - protected function make_odd() - { - if (!$this->isOdd()) { - $this->value = bcadd($this->value, '1'); - } - } - - /** - * Test the number against small primes. - * - * @see self::isPrime() - */ - protected function testSmallPrimes() - { - if ($this->value === '1') { - return false; - } - if ($this->value === '2') { - return true; - } - if ($this->value[strlen($this->value) - 1] % 2 == 0) { - return false; - } - - $value = $this->value; - - foreach (self::$primes as $prime) { - $r = bcmod($this->value, $prime); - if ($r == '0') { - return $this->value == $prime; - } - } - - return true; - } - - /** - * Scan for 1 and right shift by that amount - * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @see self::isPrime() - * @param BCMath $r - * @return int - */ - public static function scan1divide(BCMath $r) - { - $r_value = &$r->value; - $s = 0; - // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one) check earlier - while ($r_value[strlen($r_value) - 1] % 2 == 0) { - $r_value = bcdiv($r_value, '2', 0); - ++$s; - } - - return $s; - } - - /** - * Performs exponentiation. - * - * @param BCMath $n - * @return BCMath - */ - public function pow(BCMath $n) - { - $temp = new self(); - $temp->value = bcpow($this->value, $n->value); - - return $this->normalize($temp); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param BCMath ...$nums - * @return BCMath - */ - public static function min(BCMath ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param BCMath ...$nums - * @return BCMath - */ - public static function max(BCMath ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param BCMath $min - * @param BCMath $max - * @return bool - */ - public function between(BCMath $min, BCMath $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } - - /** - * Set Bitmask - * - * @return Engine - * @param int $bits - * @see self::setPrecision() - */ - protected static function setBitmask($bits) - { - $temp = parent::setBitmask($bits); - return $temp->add(static::$one); - } - - /** - * Is Odd? - * - * @return boolean - */ - public function isOdd() - { - return $this->value[strlen($this->value) - 1] % 2 == 1; - } - - /** - * Tests if a bit is set - * - * @return boolean - */ - public function testBit($x) - { - return bccomp( - bcmod($this->value, bcpow('2', $x + 1, 0), 0), - bcpow('2', $x, 0), - 0 - ) >= 0; - } - - /** - * Is Negative? - * - * @return boolean - */ - public function isNegative() - { - return strlen($this->value) && $this->value[0] == '-'; - } - - /** - * Negate - * - * Given $k, returns -$k - * - * @return BCMath - */ - public function negate() - { - $temp = clone $this; - - if (!strlen($temp->value)) { - return $temp; - } - - $temp->value = $temp->value[0] == '-' ? - substr($this->value, 1) : - '-' . $this->value; - - return $temp; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php deleted file mode 100644 index 0e189b707..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\BCMath; - -/** - * Sliding Window Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class Base extends BCMath -{ - /** - * Cache constants - * - * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. - * - * @access private - */ - const VARIABLE = 0; - /** - * $cache[self::DATA] contains the cached data. - * - * @access private - */ - const DATA = 1; - - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * @param \phpseclib3\Math\BigInteger\Engines\BCMath $x - * @param \phpseclib3\Math\BigInteger\Engines\BCMath $e - * @param \phpseclib3\Math\BigInteger\Engines\BCMath $n - * @param string $class - * @return \phpseclib3\Math\BigInteger\Engines\BCMath - */ - protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n, $class) - { - if (empty($e->value)) { - $temp = new $class(); - $temp->value = '1'; - return $x->normalize($temp); - } - - return $x->normalize(static::slidingWindow($x, $e, $n, $class)); - } - - /** - * Modular reduction preparation - * - * @param string $x - * @param string $n - * @param string $class - * @see self::slidingWindow() - * @return string - */ - protected static function prepareReduce($x, $n, $class) - { - return static::reduce($x, $n); - } - - /** - * Modular multiply - * - * @param string $x - * @param string $y - * @param string $n - * @param string $class - * @see self::slidingWindow() - * @return string - */ - protected static function multiplyReduce($x, $y, $n, $class) - { - return static::reduce(bcmul($x, $y), $n); - } - - /** - * Modular square - * - * @param string $x - * @param string $n - * @param string $class - * @see self::slidingWindow() - * @return string - */ - protected static function squareReduce($x, $n, $class) - { - return static::reduce(bcmul($x, $x), $n); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php deleted file mode 100644 index f312be15e..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\BCMath; - -/** - * Built-In BCMath Modular Exponentiation Engine - * - * @package BCMath - * @author Jim Wigginton - * @access public - */ -abstract class BuiltIn extends BCMath -{ - /** - * Performs modular exponentiation. - * - * @param BCMath $x - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n) - { - $temp = new BCMath(); - $temp->value = bcpowmod($x->value, $e->value, $n->value); - - return $x->normalize($temp); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php deleted file mode 100644 index a6d175f5c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett; - -/** - * PHP Default Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class DefaultEngine extends Barrett -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php deleted file mode 100644 index df7c965d6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; - -/** - * OpenSSL Modular Exponentiation Engine - * - * @package BCMath - * @author Jim Wigginton - * @access public - */ -abstract class OpenSSL extends Progenitor -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php deleted file mode 100644 index 32b16dca6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php +++ /dev/null @@ -1,193 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; - -use phpseclib3\Math\BigInteger\Engines\BCMath\Base; - -/** - * PHP Barrett Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class Barrett extends Base -{ - /** - * Cache constants - * - * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. - * - * @access private - */ - const VARIABLE = 0; - /** - * $cache[self::DATA] contains the cached data. - * - * @access private - */ - const DATA = 1; - - /** - * Barrett Modular Reduction - * - * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, - * so as not to require negative numbers (initially, this script didn't support negative numbers). - * - * Employs "folding", as described at - * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from - * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." - * - * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that - * usable on account of (1) its not using reasonable radix points as discussed in - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable - * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that - * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line - * comments for details. - * - * @param string $n - * @param string $m - * @return array|string - */ - protected static function reduce($n, $m) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $m_length = strlen($m); - - if (strlen($n) > 2 * $m_length) { - return bcmod($n, $m); - } - - // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced - if ($m_length < 5) { - return self::regularBarrett($n, $m); - } - // n = 2 * m.length - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - - $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); - $u = bcdiv($lhs, $m, 0); - $m1 = bcsub($lhs, bcmul($u, $m)); - - $cache[self::DATA][] = [ - 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) - 'm1'=> $m1 // m.length - ]; - } else { - extract($cache[self::DATA][$key]); - } - - $cutoff = $m_length + ($m_length >> 1); - - $lsd = substr($n, -$cutoff); - $msd = substr($n, 0, -$cutoff); - - $temp = bcmul($msd, $m1); // m.length + (m.length >> 1) - $n = bcadd($lsd, $temp); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) - //if ($m_length & 1) { - // return self::regularBarrett($n, $m); - //} - - // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 - $temp = substr($n, 0, -$m_length + 1); - // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 - // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 - $temp = bcmul($temp, $u); - // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 - // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) - $temp = substr($temp, 0, -($m_length >> 1) - 1); - // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 - // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) - $temp = bcmul($temp, $m); - - // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit - // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop - // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). - - $result = bcsub($n, $temp); - - //if (bccomp($result, '0') < 0) { - if ($result[0] == '-') { - $temp = '1' . str_repeat('0', $m_length + 1); - $result = bcadd($result, $temp); - } - - while (bccomp($result, $m) >= 0) { - $result = bcsub($result, $m); - } - - return $result; - } - - /** - * (Regular) Barrett Modular Reduction - * - * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this - * is that this function does not fold the denominator into a smaller form. - * - * @param string $x - * @param string $n - * @return string - */ - private static function regularBarrett($x, $n) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $n_length = strlen($n); - - if (strlen($x) > 2 * $n_length) { - return bcmod($x, $n); - } - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $n; - $lhs = '1' . str_repeat('0', 2 * $n_length); - $cache[self::DATA][] = bcdiv($lhs, $n, 0); - } - - $temp = substr($x, 0, -$n_length + 1); - $temp = bcmul($temp, $cache[self::DATA][$key]); - $temp = substr($temp, 0, -$n_length - 1); - - $r1 = substr($x, -$n_length - 1); - $r2 = substr(bcmul($temp, $n), -$n_length - 1); - $result = bcsub($r1, $r2); - - //if (bccomp($result, '0') < 0) { - if ($result[0] == '-') { - $q = '1' . str_repeat('0', $n_length + 1); - $result = bcadd($result, $q); - } - - while (bccomp($result, $n) >= 0) { - $result = bcsub($result, $n); - } - - return $result; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php deleted file mode 100644 index 27530ec7d..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; - -use phpseclib3\Math\BigInteger\Engines\BCMath\Base; -use phpseclib3\Math\BigInteger\Engines\BCMath; - -/** - * PHP Barrett Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class EvalBarrett extends Base -{ - /** - * Custom Reduction Function - * - * @see self::generateCustomReduction - */ - private static $custom_reduction; - - /** - * Barrett Modular Reduction - * - * This calls a dynamically generated loop unrolled function that's specific to a given modulo. - * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. - * - * @param string $n - * @param string $m - * @return string - */ - protected static function reduce($n, $m) - { - $inline = self::$custom_reduction; - return $inline($n); - } - - /** - * Generate Custom Reduction - * - * @param BCMath $m - * @param string $class - * @return callable|void - */ - protected static function generateCustomReduction(BCMath $m, $class) - { - if (isset($n->reduce)) { - self::$custom_reduction = $n->reduce; - return $n->reduce; - } - - $m_length = strlen($m); - - if ($m_length < 5) { - $code = 'return bcmod($x, $n);'; - eval('$func = function ($n) { ' . $code . '};'); - self::$custom_reduction = $func; - return; - } - - $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); - $u = bcdiv($lhs, $m, 0); - $m1 = bcsub($lhs, bcmul($u, $m)); - - $cutoff = $m_length + ($m_length >> 1); - - $m = "'$m'"; - $u = "'$u'"; - $m1= "'$m1'"; - - $code.= ' - $lsd = substr($n, -' . $cutoff . '); - $msd = substr($n, 0, -' . $cutoff . '); - - $temp = bcmul($msd, ' . $m1 . '); - $n = bcadd($lsd, $temp); - - $temp = substr($n, 0, ' . (-$m_length + 1) . '); - $temp = bcmul($temp, ' . $u . '); - $temp = substr($temp, 0, ' . (-($m_length >> 1) - 1) . '); - $temp = bcmul($temp, ' . $m . '); - - $result = bcsub($n, $temp); - - if ($result[0] == \'-\') { - $temp = \'1' . str_repeat('0', $m_length + 1) . '\'; - $result = bcadd($result, $temp); - } - - while (bccomp($result, ' . $m . ') >= 0) { - $result = bcsub($result, ' . $m . '); - } - - return $result;'; - - eval('$func = function ($n) { ' . $code . '};'); - - self::$custom_reduction = $func; - - return $func; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php deleted file mode 100644 index 10dd994bd..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php +++ /dev/null @@ -1,1219 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\Crypt\Random; -use phpseclib3\Math\BigInteger; -use phpseclib3\Common\Functions\Strings; - -/** - * Base Engine. - * - * @package Engine - * @author Jim Wigginton - * @access public - */ -abstract class Engine implements \Serializable -{ - /** - * Holds the BigInteger's value - * - * @var mixed - */ - protected $value; - - /** - * Holds the BigInteger's sign - * - * @var bool - */ - protected $is_negative; - - /** - * Precision - * - * @see static::setPrecision() - */ - protected $precision = -1; - - /** - * Precision Bitmask - * - * @see static::setPrecision() - */ - protected $bitmask = false; - - /** - * Recurring Modulo Function - * - * @var callable - */ - protected $reduce; - - /** - * Default constructor - * - * @param mixed $x integer Base-10 number or base-$base number if $base set. - * @param int $base - */ - public function __construct($x, $base) - { - if (!isset(static::$primes)) { - static::$primes = [ - 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 - ]; - static::$zero = new static(0); - static::$one = new static(1); - static::$two = new static(2); - } - - // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 - // '0' is the only value like this per http://php.net/empty - if (empty($x) && (abs($base) != 256 || $x !== '0')) { - return; - } - - switch ($base) { - case -256: - case 256: - if ($base == -256 && (ord($x[0]) & 0x80)) { - $this->value = ~$x; - $this->is_negative = true; - } else { - $this->value = $x; - $this->is_negative = false; - } - - static::initialize($base); - - if ($this->is_negative) { - $temp = $this->add(new static('-1')); - $this->value = $temp->value; - } - break; - case -16: - case 16: - if ($base > 0 && $x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x); - - $is_negative = false; - if ($base < 0 && hexdec($x[0]) >= 8) { - $this->is_negative = $is_negative = true; - $x = Hex::encode(~Hex::decode($x)); - } - - $this->value = $x; - static::initialize($base); - - if ($is_negative) { - $temp = $this->add(new static('-1')); - $this->value = $temp->value; - } - break; - case -10: - case 10: - // (?value = preg_replace('#(?value) || $this->value == '-') { - $this->value = '0'; - } - static::initialize($base); - break; - case -2: - case 2: - if ($base > 0 && $x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = preg_replace('#^([01]*).*#', '$1', $x); - - $temp = new static(Strings::bits2bin($x), 128 * $base); // ie. either -16 or +16 - $this->value = $temp->value; - if ($temp->is_negative) { - $this->is_negative = true; - } - - break; - default: - // base not supported, so we'll let $this == 0 - } - } - - /** - * Sets engine type. - * - * Throws an exception if the type is invalid - * - * @param string $engine - */ - public static function setModExpEngine($engine) - { - $fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; - if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) { - throw new \InvalidArgumentException("$engine is not a valid engine"); - } - if (!$fqengine::isValidEngine()) { - throw new BadConfigurationException("$engine is not setup correctly on this system"); - } - static::$modexpEngine = $fqengine; - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * @return string - */ - protected function toBytesHelper() - { - $comparison = $this->compare(new static()); - if ($comparison == 0) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $temp = $comparison < 0 ? $this->add(new static(1)) : $this; - $bytes = $temp->toBytes(); - - if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 - $bytes = chr(0); - } - - if (ord($bytes[0]) & 0x80) { - $bytes = chr(0) . $bytes; - } - - return $comparison < 0 ? ~$bytes : $bytes; - } - - /** - * Converts a BigInteger to a hex string (eg. base-16). - * - * @param bool $twos_compliment - * @return string - */ - public function toHex($twos_compliment = false) - { - return Hex::encode($this->toBytes($twos_compliment)); - } - - /** - * Converts a BigInteger to a bit string (eg. base-2). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * @param bool $twos_compliment - * @return string - */ - public function toBits($twos_compliment = false) - { - $hex = $this->toBytes($twos_compliment); - $bits = Strings::bin2bits($hex); - - $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); - - if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { - return '0' . $result; - } - - return $result; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} - * - * @param \phpseclib3\Math\BigInteger\Engines\Engine $n - * @return \phpseclib3\Math\BigInteger\Engines\Engine|false - */ - protected function modInverseHelper(Engine $n) - { - // $x mod -$n == $x mod $n. - $n = $n->abs(); - - if ($this->compare(static::$zero) < 0) { - $temp = $this->abs(); - $temp = $temp->modInverse($n); - return $this->normalize($n->subtract($temp)); - } - - extract($this->extendedGCD($n)); - /** - * @var BigInteger $gcd - * @var BigInteger $x - */ - - if (!$gcd->equals(static::$one)) { - return false; - } - - $x = $x->compare(static::$zero) < 0 ? $x->add($n) : $x; - - return $this->compare(static::$zero) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); - } - - /** - * Serialize - * - * Will be called, automatically, when serialize() is called on a BigInteger object. - * - * @return string - */ - public function serialize() - { - $val = ['hex' => $this->toHex(true)]; - if ($this->precision > 0) { - $val['precision'] = $this->precision; - } - return serialize($val); - } - - /** - * Serialize - * - * Will be called, automatically, when unserialize() is called on a BigInteger object. - * - * @param string $serialized - */ - public function unserialize($serialized) - { - $r = unserialize($serialized); - $temp = new static($r['hex'], -16); - $this->value = $temp->value; - $this->is_negative = $temp->is_negative; - if (isset($r['precision'])) { - // recalculate $this->bitmask - $this->setPrecision($r['precision']); - } - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * __debugInfo() magic method - * - * Will be called, automatically, when print_r() or var_dump() are called - */ - public function __debugInfo() - { - return [ - 'value' => '0x' . $this->toHex(true), - 'engine' => basename(static::class) - ]; - } - - /** - * Set Precision - * - * Some bitwise operations give different results depending on the precision being used. Examples include left - * shift, not, and rotates. - * - * @param int $bits - */ - public function setPrecision($bits) - { - if ($bits < 1) { - $this->precision = -1; - $this->bitmask = false; - - return; - } - $this->precision = $bits; - $this->bitmask = static::setBitmask($bits); - - $temp = $this->normalize($this); - $this->value = $temp->value; - } - - /** - * Get Precision - * - * Returns the precision if it exists, -1 if it doesn't - * - * @return int - */ - public function getPrecision() - { - return $this->precision; - } - - /** - * Set Bitmask - * @return Engine - * @param int $bits - * @see self::setPrecision() - */ - protected static function setBitmask($bits) - { - return new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); - } - - /** - * Logical Not - * - * @return Engine|string - */ - public function bitwise_not() - { - // calculuate "not" without regard to $this->precision - // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) - $temp = $this->toBytes(); - if ($temp == '') { - return $this->normalize(static::$zero); - } - $pre_msb = decbin(ord($temp[0])); - $temp = ~$temp; - $msb = decbin(ord($temp[0])); - if (strlen($msb) == 8) { - $msb = substr($msb, strpos($msb, '0')); - } - $temp[0] = chr(bindec($msb)); - - // see if we need to add extra leading 1's - $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; - $new_bits = $this->precision - $current_bits; - if ($new_bits <= 0) { - return $this->normalize(new static($temp, 256)); - } - - // generate as many leading 1's as we need to. - $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); - - self::base256_lshift($leading_ones, $current_bits); - - $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); - - return $this->normalize(new static($leading_ones | $temp, 256)); - } - - /** - * Logical Left Shift - * - * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. - * - * @param string $x - * @param int $shift - * @return string - */ - protected static function base256_lshift(&$x, $shift) - { - if ($shift == 0) { - return; - } - - $num_bytes = $shift >> 3; // eg. floor($shift/8) - $shift &= 7; // eg. $shift % 8 - - $carry = 0; - for ($i = strlen($x) - 1; $i >= 0; --$i) { - $temp = ord($x[$i]) << $shift | $carry; - $x[$i] = chr($temp); - $carry = $temp >> 8; - } - $carry = ($carry != 0) ? chr($carry) : ''; - $x = $carry . $x . str_repeat(chr(0), $num_bytes); - } - - /** - * Logical Left Rotate - * - * Instead of the top x bits being dropped they're appended to the shifted bit string. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - public function bitwise_leftRotate($shift) - { - $bits = $this->toBytes(); - - if ($this->precision > 0) { - $precision = $this->precision; - if (static::FAST_BITWISE) { - $mask = $this->bitmask->toBytes(); - } else { - $mask = $this->bitmask->subtract(new static(1)); - $mask = $mask->toBytes(); - } - } else { - $temp = ord($bits[0]); - for ($i = 0; $temp >> $i; ++$i) { - } - $precision = 8 * strlen($bits) - 8 + $i; - $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); - } - - if ($shift < 0) { - $shift+= $precision; - } - $shift%= $precision; - - if (!$shift) { - return clone $this; - } - - $left = $this->bitwise_leftShift($shift); - $left = $left->bitwise_and(new static($mask, 256)); - $right = $this->bitwise_rightShift($precision - $shift); - $result = static::FAST_BITWISE ? $left->bitwise_or($right) : $left->add($right); - return $this->normalize($result); - } - - /** - * Logical Right Rotate - * - * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - public function bitwise_rightRotate($shift) - { - return $this->bitwise_leftRotate(-$shift); - } - - /** - * Returns the smallest and largest n-bit number - * - * @param int $bits - * @return \phpseclib3\Math\BigInteger\Engines\Engine[] - */ - public static function minMaxBits($bits) - { - $bytes = $bits >> 3; - $min = str_repeat(chr(0), $bytes); - $max = str_repeat(chr(0xFF), $bytes); - $msb = $bits & 7; - if ($msb) { - $min = chr(1 << ($msb - 1)) . $min; - $max = chr((1 << $msb) - 1) . $max; - } else { - $min[0] = chr(0x80); - } - return [ - 'min' => new static($min, 256), - 'max' => new static($max, 256) - ]; - } - - /** - * Return the size of a BigInteger in bits - * - * @return int - */ - public function getLength() - { - return strlen($this->toBits()); - } - - /** - * Return the size of a BigInteger in bytes - * - * @return int - */ - public function getLengthInBytes() - { - return strlen($this->toBytes()); - } - - /** - * Performs some pre-processing for powMod - * - * @param Engine $e - * @param Engine $n - * @return bool|Engine - */ - protected function powModOuter(Engine $e, Engine $n) - { - $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); - - if ($e->compare(new static()) < 0) { - $e = $e->abs(); - - $temp = $this->modInverse($n); - if ($temp === false) { - return false; - } - - return $this->normalize($temp->powModInner($e, $n)); - } - - return $this->powModInner($e, $n); - } - - /** - * Sliding Window k-ary Modular Exponentiation - * - * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, - * however, this function performs a modular reduction after every multiplication and squaring operation. - * As such, this function has the same preconditions that the reductions being used do. - * - * @param \phpseclib3\Math\BigInteger\Engines\Engine $x - * @param \phpseclib3\Math\BigInteger\Engines\Engine $e - * @param \phpseclib3\Math\BigInteger\Engines\Engine $n - * @param string $class - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) - { - static $window_ranges = [7, 25, 81, 241, 673, 1793]; // from BigInteger.java's oddModPow function - //static $window_ranges = [0, 7, 36, 140, 450, 1303, 3529]; // from MPM 7.3.1 - - $e_bits = $e->toBits(); - $e_length = strlen($e_bits); - - // calculate the appropriate window size. - // $window_size == 3 if $window_ranges is between 25 and 81, for example. - for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { - } - - $n_value = $n->value; - - if (method_exists(static::class, 'generateCustomReduction')) { - static::generateCustomReduction($n, $class); - } - - // precompute $this^0 through $this^$window_size - $powers = []; - $powers[1] = static::prepareReduce($x->value, $n_value, $class); - $powers[2] = static::squareReduce($powers[1], $n_value, $class); - - // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end - // in a 1. ie. it's supposed to be odd. - $temp = 1 << ($window_size - 1); - for ($i = 1; $i < $temp; ++$i) { - $i2 = $i << 1; - $powers[$i2 + 1] = static::multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $class); - } - - $result = new $class(1); - $result = static::prepareReduce($result->value, $n_value, $class); - - for ($i = 0; $i < $e_length;) { - if (!$e_bits[$i]) { - $result = static::squareReduce($result, $n_value, $class); - ++$i; - } else { - for ($j = $window_size - 1; $j > 0; --$j) { - if (!empty($e_bits[$i + $j])) { - break; - } - } - - // eg. the length of substr($e_bits, $i, $j + 1) - for ($k = 0; $k <= $j; ++$k) { - $result = static::squareReduce($result, $n_value, $class); - } - - $result = static::multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $class); - - $i += $j + 1; - } - } - - $temp = new $class(); - $temp->value = static::reduce($result, $n_value, $class); - - return $temp; - } - - /** - * Generates a random number of a certain size - * - * Bit length is equal to $size - * - * @param int $size - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - public static function random($size) - { - extract(static::minMaxBits($size)); - /** - * @var BigInteger $min - * @var BigInteger $max - */ - return static::randomRange($min, $max); - } - - /** - * Generates a random prime number of a certain size - * - * Bit length is equal to $size - * - * @param int $size - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - public static function randomPrime($size) - { - extract(static::minMaxBits($size)); - /** - * @var BigInteger $min - * @var BigInteger $max - */ - return static::randomRangePrime($min, $max); - } - - /** - * Performs some pre-processing for randomRangePrime - * - * @param Engine $min - * @param Engine $max - * @return bool|Engine - */ - protected static function randomRangePrimeOuter(Engine $min, Engine $max) - { - $compare = $max->compare($min); - - if (!$compare) { - return $min->isPrime() ? $min : false; - } elseif ($compare < 0) { - // if $min is bigger then $max, swap $min and $max - $temp = $max; - $max = $min; - $min = $temp; - } - - $x = static::randomRange($min, $max); - - return static::randomRangePrimeInner($x, $min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param Engine $min - * @param Engine $max - * @return Engine - */ - protected static function randomRangeHelper(Engine $min, Engine $max) - { - $compare = $max->compare($min); - - if (!$compare) { - return $min; - } elseif ($compare < 0) { - // if $min is bigger then $max, swap $min and $max - $temp = $max; - $max = $min; - $min = $temp; - } - - if (!isset(static::$one)) { - static::$one = new static(1); - } - - $max = $max->subtract($min->subtract(static::$one)); - - $size = strlen(ltrim($max->toBytes(), chr(0))); - - /* - doing $random % $max doesn't work because some numbers will be more likely to occur than others. - eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 - would produce 5 whereas the only value of random that could produce 139 would be 139. ie. - not all numbers would be equally likely. some would be more likely than others. - - creating a whole new random number until you find one that is within the range doesn't work - because, for sufficiently small ranges, the likelihood that you'd get a number within that range - would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability - would be pretty high that $random would be greater than $max. - - phpseclib works around this using the technique described here: - - http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string - */ - $random_max = new static(chr(1) . str_repeat("\0", $size), 256); - $random = new static(Random::string($size), 256); - - list($max_multiple) = $random_max->divide($max); - $max_multiple = $max_multiple->multiply($max); - - while ($random->compare($max_multiple) >= 0) { - $random = $random->subtract($max_multiple); - $random_max = $random_max->subtract($max_multiple); - $random = $random->bitwise_leftShift(8); - $random = $random->add(new static(Random::string(1), 256)); - $random_max = $random_max->bitwise_leftShift(8); - list($max_multiple) = $random_max->divide($max); - $max_multiple = $max_multiple->multiply($max); - } - list(, $random) = $random->divide($max); - - return $random->add($min); - } - - /** - * Performs some post-processing for randomRangePrime - * - * @param Engine $x - * @param Engine $min - * @param Engine $max - * @return bool|Engine - */ - protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) - { - if (!isset(static::$two)) { - static::$two = new static('2'); - } - - $x->make_odd(); - if ($x->compare($max) > 0) { - // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range - if ($min->equals($max)) { - return false; - } - $x = clone $min; - $x->make_odd(); - } - - $initial_x = clone $x; - - while (true) { - if ($x->isPrime()) { - return $x; - } - - $x = $x->add(static::$two); - - if ($x->compare($max) > 0) { - $x = clone $min; - if ($x->equals(static::$two)) { - return $x; - } - $x->make_odd(); - } - - if ($x->equals($initial_x)) { - return false; - } - } - } - - /** - * Sets the $t parameter for primality testing - * - * @return int - */ - protected function setupIsPrime() - { - $length = $this->getLengthInBytes(); - - // see HAC 4.49 "Note (controlling the error probability)" - // @codingStandardsIgnoreStart - if ($length >= 163) { $t = 2; } // floor(1300 / 8) - else if ($length >= 106) { $t = 3; } // floor( 850 / 8) - else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) - else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) - else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) - else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) - else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) - else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) - else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) - else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) - else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) - else { $t = 27; } - // @codingStandardsIgnoreEnd - - return $t; - } - - /** - * Tests Primality - * - * Uses the {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. - * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24} for more info. - * - * @param int $t - * @return bool - */ - protected function testPrimality($t) - { - if (!$this->testSmallPrimes()) { - return false; - } - - $n = clone $this; - $n_1 = $n->subtract(static::$one); - $n_2 = $n->subtract(static::$two); - - $r = clone $n_1; - $s = static::scan1divide($r); - - for ($i = 0; $i < $t; ++$i) { - $a = static::randomRange(static::$two, $n_2); - $y = $a->modPow($r, $n); - - if (!$y->equals(static::$one) && !$y->equals($n_1)) { - for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { - $y = $y->modPow(static::$two, $n); - if ($y->equals(static::$one)) { - return false; - } - } - - if (!$y->equals($n_1)) { - return false; - } - } - } - - return true; - } - - /** - * Checks a numer to see if it's prime - * - * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the - * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads - * on a website instead of just one. - * - * @param int|bool $t - * @return bool - */ - public function isPrime($t = false) - { - if (!$t) { - $t = $this->setupIsPrime(); - } - return $this->testPrimality($t); - } - - /** - * Performs a few preliminary checks on root - * - * @param int $n - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - protected function rootHelper($n) - { - if ($n < 1) { - return clone static::$zero; - } // we want positive exponents - if ($this->compare(static::$one) < 0) { - return clone static::$zero; - } // we want positive numbers - if ($this->compare(static::$two) < 0) { - return clone static::$one; - } // n-th root of 1 or 2 is 1 - - return $this->rootInner($n); - } - - /** - * Calculates the nth root of a biginteger. - * - * Returns the nth root of a positive biginteger, where n defaults to 2 - * - * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} - * - * @param int $n - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - protected function rootInner($n) - { - $n = new static($n); - - // g is our guess number - $g = static::$two; - // while (g^n < num) g=g*2 - while ($g->pow($n)->compare($this) < 0) { - $g = $g->multiply(static::$two); - } - // if (g^n==num) num is a power of 2, we're lucky, end of job - // == 0 bccomp(bcpow($g, $n), $n->value)==0 - if ($g->pow($n)->equals($this) > 0) { - $root = $g; - return $this->normalize($root); - } - - // if we're here num wasn't a power of 2 :( - $og = $g; // og means original guess and here is our upper bound - $g = $g->divide(static::$two)[0]; // g is set to be our lower bound - $step = $og->subtract($g)->divide(static::$two)[0]; // step is the half of upper bound - lower bound - $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval - - // while step>1 - - while ($step->compare(static::$one) == 1) { - $guess = $g->pow($n); - $step = $step->divide(static::$two)[0]; - $comp = $guess->compare($this); // compare our guess with real number - switch ($comp) { - case -1: // if guess is lower we add the new step - $g = $g->add($step); - break; - case 1: // if guess is higher we sub the new step - $g = $g->subtract($step); - break; - case 0: // if guess is exactly the num we're done, we return the value - $root = $g; - break 2; - } - } - - if ($comp == 1) { - $g = $g->subtract($step); - } - - // whatever happened, g is the closest guess we can make so return it - $root = $g; - - return $this->normalize($root); - } - - /** - * Calculates the nth root of a biginteger. - * - * @param int $n - * @return Engine - */ - public function root($n = 2) - { - return $this->rootHelper($n); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param array $nums - * @return Engine - */ - protected static function minHelper(array $nums) - { - if (count($nums) == 1) { - return $nums[0]; - } - $min = $nums[0]; - for ($i = 1; $i < count($nums); $i++) { - $min = $min->compare($nums[$i]) > 0 ? $nums[$i] : $min; - } - return $min; - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param array $nums - * @return Engine - */ - protected static function maxHelper(array $nums) - { - if (count($nums) == 1) { - return $nums[0]; - } - $max = $nums[0]; - for ($i = 1; $i < count($nums); $i++) { - $max = $max->compare($nums[$i]) < 0 ? $nums[$i] : $max; - } - return $max; - } - - /** - * Create Recurring Modulo Function - * - * Sometimes it may be desirable to do repeated modulos with the same number outside of - * modular exponentiation - * - * @return callable - */ - public function createRecurringModuloFunction() - { - $class = static::class; - - $fqengine = !method_exists(static::$modexpEngine, 'reduce') ? - '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : - static::$modexpEngine; - if (method_exists($fqengine, 'generateCustomReduction')) { - $func = $fqengine::generateCustomReduction($this, static::class); - $this->reduce = eval('return function(' . static::class . ' $x) use ($func, $class) { - $r = new $class(); - $r->value = $func($x->value); - return $r; - };'); - return clone $this->reduce; - } - $n = $this->value; - $this->reduce = eval('return function(' . static::class . ' $x) use ($n, $fqengine, $class) { - $r = new $class(); - $r->value = $fqengine::reduce($x->value, $n, $class); - return $r; - };'); - return clone $this->reduce; - } - - /** - * Calculates the greatest common divisor and Bezout's identity. - * - * @param Engine $n - * @param Engine $stop (optional) - * @return Engine - */ - protected function extendedGCDHelper(Engine $n, Engine $stop = null) - { - $u = clone $this; - $v = clone $n; - - $one = new static(1); - $zero = new static(); - - $a = clone $one; - $b = clone $zero; - $c = clone $zero; - $d = clone $one; - - while (!$v->equals($zero)) { - list($q) = $u->divide($v); - - $temp = $u; - $u = $v; - $v = $temp->subtract($v->multiply($q)); - - $temp = $a; - $a = $c; - $c = $temp->subtract($a->multiply($q)); - - $temp = $b; - $b = $d; - $d = $temp->subtract($b->multiply($q)); - } - - return [ - 'gcd'=> $u, - 'x' => $a, - 'y' => $b - ]; - } - - /** - * Bitwise Split - * - * Splits BigInteger's into chunks of $split bits - * - * @param int $split - * @return \phpseclib3\Math\BigInteger\Engines\Engine[] - */ - public function bitwise_split($split) - { - if ($split < 1) { - throw new \RuntimeException('Offset must be greater than 1'); - } - - $mask = static::$one->bitwise_leftShift($split)->subtract(static::$one); - - $num = clone $this; - - $vals = []; - while (!$num->equals(static::$zero)) { - $vals[] = $num->bitwise_and($mask); - $num = $num->bitwise_rightShift($split); - } - - return array_reverse($vals); - } - - /** - * Logical And - * - * @param Engine $x - * @return Engine - */ - protected function bitwiseAndHelper(Engine $x) - { - $left = $this->toBytes(true); - $right = $x->toBytes(true); - - $length = max(strlen($left), strlen($right)); - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - - return $this->normalize(new static($left & $right, -256)); - } - - /** - * Logical Or - * - * @param Engine $x - * @return Engine - */ - protected function bitwiseOrHelper(Engine $x) - { - $left = $this->toBytes(true); - $right = $x->toBytes(true); - - $length = max(strlen($left), strlen($right)); - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - - return $this->normalize(new static($left | $right, -256)); - } - - /** - * Logical Exclusive Or - * - * @param Engine $x - * @return Engine - */ - protected function bitwiseXorHelper(Engine $x) - { - $left = $this->toBytes(true); - $right = $x->toBytes(true); - - $length = max(strlen($left), strlen($right)); - - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - return $this->normalize(new static($left ^ $right, -256)); - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php deleted file mode 100644 index 2cbc9cbed..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php +++ /dev/null @@ -1,751 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Exception\BadConfigurationException; - -/** - * GMP Engine. - * - * @package GMP - * @author Jim Wigginton - * @access public - */ -class GMP extends Engine -{ - /** - * Can Bitwise operations be done fast? - * - * @see parent::bitwise_leftRotate() - * @see parent::bitwise_rightRotate() - * @access protected - */ - const FAST_BITWISE = true; - - /** - * Engine Directory - * - * @see parent::setModExpEngine - * @access protected - */ - const ENGINE_DIR = 'GMP'; - - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\GMP - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\GMP - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\GMP - */ - protected static $two; - - /** - * Primes > 2 and < 1000 - * - * Unused for GMP Engine - * - * @var mixed - */ - protected static $primes; - - /** - * Test for engine validity - * - * @see parent::__construct() - * @return bool - */ - public static function isValidEngine() - { - return extension_loaded('gmp'); - } - - /** - * Default constructor - * - * @param mixed $x integer Base-10 number or base-$base number if $base set. - * @param int $base - * @see parent::__construct() - * @return \phpseclib3\Math\BigInteger\Engines\GMP - */ - public function __construct($x = 0, $base = 10) - { - if (!isset(self::$isValidEngine)) { - self::$isValidEngine = self::isValidEngine(); - } - if (!self::$isValidEngine) { - throw new BadConfigurationException('GMP is not setup correctly on this system'); - } - - if ($x instanceof \GMP) { - $this->value = $x; - return; - } - - $this->value = gmp_init(0); - - parent::__construct($x, $base); - } - - /** - * Initialize a GMP BigInteger Engine instance - * - * @param int $base - * @see parent::__construct() - */ - protected function initialize($base) - { - switch (abs($base)) { - case 256: - $this->value = gmp_import($this->value); - if ($this->is_negative) { - $this->value = -$this->value; - } - break; - case 16: - $temp = $this->is_negative ? '-0x' . $this->value : '0x' . $this->value; - $this->value = gmp_init($temp); - break; - case 10: - $this->value = gmp_init(isset($this->value) ? $this->value : '0'); - } - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - return (string) $this->value; - } - - /** - * Converts a BigInteger to a bit string (eg. base-2). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * @param bool $twos_compliment - * @return string - */ - public function toBits($twos_compliment = false) - { - $hex = $this->toHex($twos_compliment); - - $bits = gmp_strval(gmp_init($hex, 16), 2); - - if ($this->precision > 0) { - $bits = substr($bits, -$this->precision); - } - - if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { - return '0' . $bits; - } - - return $bits; - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * @param bool $twos_compliment - * @return string - */ - function toBytes($twos_compliment = false) - { - if ($twos_compliment) { - return $this->toBytesHelper(); - } - - if (gmp_cmp($this->value, gmp_init(0)) == 0) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $temp = gmp_export($this->value); - - return $this->precision > 0 ? - substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : - ltrim($temp, chr(0)); - } - - /** - * Adds two BigIntegers. - * - * @param GMP $y - * @return GMP - */ - public function add(GMP $y) - { - $temp = new self(); - $temp->value = $this->value + $y->value; - - return $this->normalize($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param GMP $y - * @return GMP - */ - public function subtract(GMP $y) - { - $temp = new self(); - $temp->value = $this->value - $y->value; - - return $this->normalize($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param GMP $x - * @return GMP - */ - public function multiply(GMP $x) - { - $temp = new self(); - $temp->value = $this->value * $x->value; - - return $this->normalize($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param GMP $y - * @return GMP - */ - public function divide(GMP $y) - { - $quotient = new self(); - $remainder = new self(); - - list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); - - if (gmp_sign($remainder->value) < 0) { - $remainder->value = $remainder->value + gmp_abs($y->value); - } - - return [$this->normalize($quotient), $this->normalize($remainder)]; - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is - * demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param GMP $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @access public - * @see self::equals() - */ - public function compare(GMP $y) - { - $r = gmp_cmp($this->value, $y->value); - if ($r < -1) { - $r = -1; - } - if ($r > 1) { - $r = 1; - } - return $r; - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param GMP $x - * @return bool - */ - public function equals(GMP $x) - { - return $this->value == $x->value; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * @param GMP $n - * @return false|GMP - */ - public function modInverse(GMP $n) - { - $temp = new self(); - $temp->value = gmp_invert($this->value, $n->value); - - return $temp->value === false ? false : $this->normalize($temp); - } - - /** - * Calculates the greatest common divisor and Bezout's identity. - * - * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that - * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which - * combination is returned is dependent upon which mode is in use. See - * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. - * - * @param \phpseclib3\Math\BigInteger\Engines\GMP $n - * @return \phpseclib3\Math\BigInteger\Engines\GMP[] - */ - public function extendedGCD(GMP $n) - { - extract(gmp_gcdext($this->value, $n->value)); - - return [ - 'gcd' => $this->normalize(new self($g)), - 'x' => $this->normalize(new self($s)), - 'y' => $this->normalize(new self($t)) - ]; - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param GMP $n - * @return GMP - */ - public function gcd(GMP $n) - { - $r = gmp_gcd($this->value, $n->value); - return $this->normalize(new self($r)); - } - - /** - * Absolute value. - * - * @return \phpseclib3\Math\BigInteger\Engines\GMP - * @access public - */ - public function abs() - { - $temp = new self(); - $temp->value = gmp_abs($this->value); - - return $temp; - } - - /** - * Logical And - * - * @param GMP $x - * @return GMP - */ - public function bitwise_and(GMP $x) - { - $temp = new self(); - $temp->value = $this->value & $x->value; - - return $this->normalize($temp); - } - - /** - * Logical Or - * - * @param GMP $x - * @return GMP - */ - public function bitwise_or(GMP $x) - { - $temp = new self(); - $temp->value = $this->value | $x->value; - - return $this->normalize($temp); - } - - /** - * Logical Exclusive Or - * - * @param GMP $x - * @return GMP - */ - public function bitwise_xor(GMP $x) - { - $temp = new self(); - $temp->value = $this->value ^ $x->value; - - return $this->normalize($temp); - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\GMP - */ - public function bitwise_rightShift($shift) - { - // 0xFFFFFFFF >> 2 == -1 (on 32-bit systems) - // gmp_init('0xFFFFFFFF') >> 2 == gmp_init('0x3FFFFFFF') - - $temp = new self(); - $temp->value = $this->value >> $shift; - - return $this->normalize($temp); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\GMP - */ - public function bitwise_leftShift($shift) - { - $temp = new self(); - $temp->value = $this->value << $shift; - - return $this->normalize($temp); - } - - /** - * Performs modular exponentiation. - * - * @param GMP $e - * @param GMP $n - * @return GMP - */ - public function modPow(GMP $e, GMP $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param GMP $e - * @param GMP $n - * @return GMP - */ - public function powMod(GMP $e, GMP $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * @param GMP $e - * @param GMP $n - * @return GMP - */ - protected function powModInner(GMP $e, GMP $n) - { - $class = self::$modexpEngine; - return $class::powModHelper($this, $e, $n); - } - - /** - * Normalize - * - * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision - * - * @param GMP $result - * @return GMP - */ - protected function normalize(GMP $result) - { - unset($result->reduce); - - $result->precision = $this->precision; - $result->bitmask = $this->bitmask; - - if ($result->bitmask !== false) { - $flip = $result->value < 0; - if ($flip) { - $result->value = -$result->value; - } - $result->value = $result->value & $result->bitmask->value; - if ($flip) { - $result->value = -$result->value; - } - } - - return $result; - } - - /** - * Performs some post-processing for randomRangePrime - * - * @param Engine $x - * @param Engine $min - * @param Engine $max - * @return GMP - */ - protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) - { - $p = gmp_nextprime($x->value); - - if ($p <= $max->value) { - return new self($p); - } - - if ($min->value != $x->value) { - $x = new self($x->value - 1); - } - - return self::randomRangePrime($min, $x); - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param GMP $min - * @param GMP $max - * @return false|GMP - */ - public static function randomRangePrime(GMP $min, GMP $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param GMP $min - * @param GMP $max - * @return GMP - */ - public static function randomRange(GMP $min, GMP $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Make the current number odd - * - * If the current number is odd it'll be unchanged. If it's even, one will be added to it. - * - * @see self::randomPrime() - */ - protected function make_odd() - { - gmp_setbit($this->value, 0); - } - - /** - * Tests Primality - * - * @param int $t - * @return bool - */ - protected function testPrimality($t) - { - return gmp_prob_prime($this->value, $t) != 0; - } - - /** - * Calculates the nth root of a biginteger. - * - * Returns the nth root of a positive biginteger, where n defaults to 2 - * - * @param int $n - * @return GMP - */ - protected function rootInner($n) - { - $root = new self(); - $root->value = gmp_root($this->value, $n); - return $this->normalize($root); - } - - /** - * Performs exponentiation. - * - * @param GMP $n - * @return GMP - */ - public function pow(GMP $n) - { - $temp = new self(); - $temp->value = $this->value ** $n->value; - - return $this->normalize($temp); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param GMP ...$nums - * @return GMP - */ - public static function min(GMP ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param GMP ...$nums - * @return GMP - */ - public static function max(GMP ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param GMP $min - * @param GMP $max - * @return bool - */ - public function between(GMP $min, GMP $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } - - /** - * Create Recurring Modulo Function - * - * Sometimes it may be desirable to do repeated modulos with the same number outside of - * modular exponentiation - * - * @return callable - */ - public function createRecurringModuloFunction() - { - $temp = $this->value; - $this->reduce = function(GMP $x) use ($temp) { - return new GMP($x->value % $temp); - }; - return $this->reduce; - } - - /** - * Scan for 1 and right shift by that amount - * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @param GMP $r - * @return int - */ - public static function scan1divide(GMP $r) - { - $s = gmp_scan1($r->value, 0); - $r->value >>= $s; - return $s; - } - - /** - * Is Odd? - * - * @return boolean - */ - public function isOdd() - { - return gmp_testbit($this->value, 0); - } - - /** - * Tests if a bit is set - * - * @return boolean - */ - public function testBit($x) - { - return gmp_testbit($this->value, $x); - } - - /** - * Is Negative? - * - * @return boolean - */ - public function isNegative() - { - return gmp_sign($this->value) == -1; - } - - /** - * Negate - * - * Given $k, returns -$k - * - * @return GMP - */ - public function negate() - { - $temp = clone $this; - $temp->value = -$this->value; - - return $temp; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php deleted file mode 100644 index 9889271ec..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\GMP; - -use phpseclib3\Math\BigInteger\Engines\GMP; - -/** - * GMP Modular Exponentiation Engine - * - * @package GMP - * @author Jim Wigginton - * @access public - */ -abstract class DefaultEngine extends GMP -{ - /** - * Performs modular exponentiation. - * - * @param GMP $x - * @param GMP $e - * @param GMP $n - * @return GMP - */ - protected static function powModHelper(GMP $x, GMP $e, GMP $n) - { - $temp = new GMP(); - $temp->value = gmp_powm($x->value, $e->value, $n->value); - - return $x->normalize($temp); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php deleted file mode 100644 index ce4d18a3f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; -use phpseclib3\Math\BigInteger; - -/** - * OpenSSL Modular Exponentiation Engine - * - * @package Engines - * @author Jim Wigginton - * @access public - */ -abstract class OpenSSL -{ - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return extension_loaded('openssl') && static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * @param Engine $x - * @param Engine $e - * @param Engine $n - * @return Engine - */ - public static function powModHelper(Engine $x, Engine $e, Engine $n) - { - if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { - throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); - } - - $key = PKCS8::savePublicKey( - new BigInteger($n), - new BigInteger($e) - ); - $rsa = RSA::load($key); - //$rsa->setPublicKeyFormat('PKCS1'); - - $plaintext = str_pad($x->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT); - - // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it - // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line" - // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what - // about odd numbers divisible by 3, by 5, etc? - if (!openssl_public_encrypt($plaintext, $result, "$rsa", OPENSSL_NO_PADDING)) { - throw new \UnexpectedValueException(openssl_error_string()); - } - - $class = get_class($x); - return new $class($result, 256); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php deleted file mode 100644 index 5f94e68ba..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php +++ /dev/null @@ -1,1316 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Exception\BadConfigurationException; - -/** - * Pure-PHP Engine. - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class PHP extends Engine -{ - /**#@+ - * Array constants - * - * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and - * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. - * - * @access protected - */ - /** - * $result[self::VALUE] contains the value. - */ - const VALUE = 0; - /** - * $result[self::SIGN] contains the sign. - */ - const SIGN = 1; - /**#@-*/ - - /** - * Karatsuba Cutoff - * - * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? - * - * @access private - */ - const KARATSUBA_CUTOFF = 25; - - /** - * Can Bitwise operations be done fast? - * - * @see parent::bitwise_leftRotate() - * @see parent::bitwise_rightRotate() - * @access protected - */ - const FAST_BITWISE = true; - - /** - * Engine Directory - * - * @see parent::setModExpEngine - * @access protected - */ - const ENGINE_DIR = 'PHP'; - - /** - * Default constructor - * - * @param mixed $x integer Base-10 number or base-$base number if $base set. - * @param int $base - * @see parent::__construct() - * @return \phpseclib3\Math\BigInteger\Engines\PHP - */ - public function __construct($x = 0, $base = 10) - { - if (!isset(static::$isValidEngine)) { - static::$isValidEngine = static::isValidEngine(); - } - if (!static::$isValidEngine) { - throw new BadConfigurationException(static::class . ' is not setup correctly on this system'); - } - - $this->value = []; - parent::__construct($x, $base); - } - - /** - * Initialize a PHP BigInteger Engine instance - * - * @param int $base - * @see parent::__construct() - */ - protected function initialize($base) - { - switch (abs($base)) { - case 16: - $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; - $temp = new static(Hex::decode($x), 256); - $this->value = $temp->value; - break; - case 10: - $temp = new static(); - - $multiplier = new static(); - $multiplier->value = [static::MAX10]; - - $x = $this->value; - - if ($x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = str_pad($x, strlen($x) + ((static::MAX10LEN - 1) * strlen($x)) % static::MAX10LEN, 0, STR_PAD_LEFT); - while (strlen($x)) { - $temp = $temp->multiply($multiplier); - $temp = $temp->add(new static($this->int2bytes(substr($x, 0, static::MAX10LEN)), 256)); - $x = substr($x, static::MAX10LEN); - } - - $this->value = $temp->value; - } - } - - /** - * Pads strings so that unpack may be used on them - * - * @param string $str - * @return string - */ - protected function pad($str) - { - $length = strlen($str); - - $pad = 4 - (strlen($str) % 4); - - return str_pad($str, $length + $pad, "\0", STR_PAD_LEFT); - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - if (!count($this->value)) { - return '0'; - } - - $temp = clone $this; - $temp->bitmask = false; - $temp->is_negative = false; - - $divisor = new static(); - $divisor->value = [static::MAX10]; - $result = ''; - while (count($temp->value)) { - list($temp, $mod) = $temp->divide($divisor); - $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', static::MAX10LEN, '0', STR_PAD_LEFT) . $result; - } - $result = ltrim($result, '0'); - if (empty($result)) { - $result = '0'; - } - - if ($this->is_negative) { - $result = '-' . $result; - } - - return $result; - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * @param bool $twos_compliment - * @return string - */ - public function toBytes($twos_compliment = false) - { - if ($twos_compliment) { - return $this->toBytesHelper(); - } - - if (!count($this->value)) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $result = $this->bitwise_small_split(8); - $result = implode('', array_map('chr', $result)); - - return $this->precision > 0 ? - str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) : - $result; - } - - /** - * Performs addition. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - */ - protected static function addHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - $x_size = count($x_value); - $y_size = count($y_value); - - if ($x_size == 0) { - return [ - self::VALUE => $y_value, - self::SIGN => $y_negative - ]; - } elseif ($y_size == 0) { - return [ - self::VALUE => $x_value, - self::SIGN => $x_negative - ]; - } - - // subtract, if appropriate - if ($x_negative != $y_negative) { - if ($x_value == $y_value) { - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - $temp = self::subtractHelper($x_value, false, $y_value, false); - $temp[self::SIGN] = self::compareHelper($x_value, false, $y_value, false) > 0 ? - $x_negative : $y_negative; - - return $temp; - } - - if ($x_size < $y_size) { - $size = $x_size; - $value = $y_value; - } else { - $size = $y_size; - $value = $x_value; - } - - $value[count($value)] = 0; // just in case the carry adds an extra digit - - $carry = 0; - for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) { - //$sum = $x_value[$j] * static::BASE_FULL + $x_value[$i] + $y_value[$j] * static::BASE_FULL + $y_value[$i] + $carry; - $sum = ($x_value[$j] + $y_value[$j]) * static::BASE_FULL + $x_value[$i] + $y_value[$i] + $carry; - $carry = $sum >= static::MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 - $sum = $carry ? $sum - static::MAX_DIGIT2 : $sum; - - $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); - - $value[$i] = (int) ($sum - static::BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) - $value[$j] = $temp; - } - - if ($j == $size) { // ie. if $y_size is odd - $sum = $x_value[$i] + $y_value[$i] + $carry; - $carry = $sum >= static::BASE_FULL; - $value[$i] = $carry ? $sum - static::BASE_FULL : $sum; - ++$i; // ie. let $i = $j since we've just done $value[$i] - } - - if ($carry) { - for (; $value[$i] == static::MAX_DIGIT; ++$i) { - $value[$i] = 0; - } - ++$value[$i]; - } - - return [ - self::VALUE => self::trim($value), - self::SIGN => $x_negative - ]; - } - - /** - * Performs subtraction. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - */ - static function subtractHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - $x_size = count($x_value); - $y_size = count($y_value); - - if ($x_size == 0) { - return [ - self::VALUE => $y_value, - self::SIGN => !$y_negative - ]; - } elseif ($y_size == 0) { - return [ - self::VALUE => $x_value, - self::SIGN => $x_negative - ]; - } - - // add, if appropriate (ie. -$x - +$y or +$x - -$y) - if ($x_negative != $y_negative) { - $temp = self::addHelper($x_value, false, $y_value, false); - $temp[self::SIGN] = $x_negative; - - return $temp; - } - - $diff = self::compareHelper($x_value, $x_negative, $y_value, $y_negative); - - if (!$diff) { - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - // switch $x and $y around, if appropriate. - if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { - $temp = $x_value; - $x_value = $y_value; - $y_value = $temp; - - $x_negative = !$x_negative; - - $x_size = count($x_value); - $y_size = count($y_value); - } - - // at this point, $x_value should be at least as big as - if not bigger than - $y_value - - $carry = 0; - for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) { - $sum = ($x_value[$j] - $y_value[$j]) * static::BASE_FULL + $x_value[$i] - $y_value[$i] - $carry; - - $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 - $sum = $carry ? $sum + static::MAX_DIGIT2 : $sum; - - $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); - - $x_value[$i] = (int) ($sum - static::BASE_FULL * $temp); - $x_value[$j] = $temp; - } - - if ($j == $y_size) { // ie. if $y_size is odd - $sum = $x_value[$i] - $y_value[$i] - $carry; - $carry = $sum < 0; - $x_value[$i] = $carry ? $sum + static::BASE_FULL : $sum; - ++$i; - } - - if ($carry) { - for (; !$x_value[$i]; ++$i) { - $x_value[$i] = static::MAX_DIGIT; - } - --$x_value[$i]; - } - - return [ - self::VALUE => self::trim($x_value), - self::SIGN => $x_negative - ]; - } - - /** - * Performs multiplication. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - */ - protected static function multiplyHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - //if ( $x_value == $y_value ) { - // return [ - // self::VALUE => self::square($x_value), - // self::SIGN => $x_sign != $y_value - // ]; - //} - - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - return [ - self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? - self::trim(self::regularMultiply($x_value, $y_value)) : - self::trim(self::karatsuba($x_value, $y_value)), - self::SIGN => $x_negative != $y_negative - ]; - } - - /** - * Performs Karatsuba multiplication on two BigIntegers - * - * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. - * - * @param array $x_value - * @param array $y_value - * @return array - */ - private static function karatsuba(array $x_value, array $y_value) - { - $m = min(count($x_value) >> 1, count($y_value) >> 1); - - if ($m < self::KARATSUBA_CUTOFF) { - return self::regularMultiply($x_value, $y_value); - } - - $x1 = array_slice($x_value, $m); - $x0 = array_slice($x_value, 0, $m); - $y1 = array_slice($y_value, $m); - $y0 = array_slice($y_value, 0, $m); - - $z2 = self::karatsuba($x1, $y1); - $z0 = self::karatsuba($x0, $y0); - - $z1 = self::addHelper($x1, false, $x0, false); - $temp = self::addHelper($y1, false, $y0, false); - $z1 = self::karatsuba($z1[self::VALUE], $temp[self::VALUE]); - $temp = self::addHelper($z2, false, $z0, false); - $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); - - $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); - $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - - $xy = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xy = self::addHelper($xy[self::VALUE], $xy[self::SIGN], $z0, false); - - return $xy[self::VALUE]; - } - - /** - * Performs long multiplication on two BigIntegers - * - * Modeled after 'multiply' in MutableBigInteger.java. - * - * @param array $x_value - * @param array $y_value - * @return array - */ - protected static function regularMultiply(array $x_value, array $y_value) - { - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return []; - } - - $product_value = self::array_repeat(0, $x_length + $y_length); - - // the following for loop could be removed if the for loop following it - // (the one with nested for loops) initially set $i to 0, but - // doing so would also make the result in one set of unnecessary adds, - // since on the outermost loops first pass, $product->value[$k] is going - // to always be 0 - - $carry = 0; - for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 - $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$j] = (int) ($temp - static::BASE_FULL * $carry); - } - - $product_value[$j] = $carry; - - // the above for loop is what the previous comment was talking about. the - // following for loop is the "one with nested for loops" - for ($i = 1; $i < $y_length; ++$i) { - $carry = 0; - - for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { - $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$k] = (int) ($temp - static::BASE_FULL * $carry); - } - - $product_value[$k] = $carry; - } - - return $product_value; - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param \phpseclib3\Math\BigInteger\engines\PHP $y - * @return array - * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. - */ - protected function divideHelper(PHP $y) - { - if (count($y->value) == 1) { - list($q, $r) = $this->divide_digit($this->value, $y->value[0]); - $quotient = new static(); - $remainder = new static(); - $quotient->value = $q; - $remainder->value = [$r]; - $quotient->is_negative = $this->is_negative != $y->is_negative; - return [$this->normalize($quotient), $this->normalize($remainder)]; - } - - $x = clone $this; - $y = clone $y; - - $x_sign = $x->is_negative; - $y_sign = $y->is_negative; - - $x->is_negative = $y->is_negative = false; - - $diff = $x->compare($y); - - if (!$diff) { - $temp = new static(); - $temp->value = [1]; - $temp->is_negative = $x_sign != $y_sign; - return [$this->normalize($temp), $this->normalize(static::$zero)]; - } - - if ($diff < 0) { - // if $x is negative, "add" $y. - if ($x_sign) { - $x = $y->subtract($x); - } - return [$this->normalize(static::$zero), $this->normalize($x)]; - } - - // normalize $x and $y as described in HAC 14.23 / 14.24 - $msb = $y->value[count($y->value) - 1]; - for ($shift = 0; !($msb & static::MSB); ++$shift) { - $msb <<= 1; - } - $x->lshift($shift); - $y->lshift($shift); - $y_value = &$y->value; - - $x_max = count($x->value) - 1; - $y_max = count($y->value) - 1; - - $quotient = new static(); - $quotient_value = &$quotient->value; - $quotient_value = self::array_repeat(0, $x_max - $y_max + 1); - - static $temp, $lhs, $rhs; - if (!isset($temp)) { - $temp = new static(); - $lhs = new static(); - $rhs = new static(); - } - $temp_value = &$temp->value; - $rhs_value = &$rhs->value; - - // $temp = $y << ($x_max - $y_max-1) in base 2**26 - $temp_value = array_merge(self::array_repeat(0, $x_max - $y_max), $y_value); - - while ($x->compare($temp) >= 0) { - // calculate the "common residue" - ++$quotient_value[$x_max - $y_max]; - $x = $x->subtract($temp); - $x_max = count($x->value) - 1; - } - - for ($i = $x_max; $i >= $y_max + 1; --$i) { - $x_value = &$x->value; - $x_window = [ - isset($x_value[$i]) ? $x_value[$i] : 0, - isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, - isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 - ]; - $y_window = [ - $y_value[$y_max], - ($y_max > 0) ? $y_value[$y_max - 1] : 0 - ]; - - $q_index = $i - $y_max - 1; - if ($x_window[0] == $y_window[0]) { - $quotient_value[$q_index] = static::MAX_DIGIT; - } else { - $quotient_value[$q_index] = self::safe_divide( - $x_window[0] * static::BASE_FULL + $x_window[1], - $y_window[0] - ); - } - - $temp_value = [$y_window[1], $y_window[0]]; - - $lhs->value = [$quotient_value[$q_index]]; - $lhs = $lhs->multiply($temp); - - $rhs_value = [$x_window[2], $x_window[1], $x_window[0]]; - - while ($lhs->compare($rhs) > 0) { - --$quotient_value[$q_index]; - - $lhs->value = [$quotient_value[$q_index]]; - $lhs = $lhs->multiply($temp); - } - - $adjust = self::array_repeat(0, $q_index); - $temp_value = [$quotient_value[$q_index]]; - $temp = $temp->multiply($y); - $temp_value = &$temp->value; - if (count($temp_value)) { - $temp_value = array_merge($adjust, $temp_value); - } - - $x = $x->subtract($temp); - - if ($x->compare(static::$zero) < 0) { - $temp_value = array_merge($adjust, $y_value); - $x = $x->add($temp); - - --$quotient_value[$q_index]; - } - - $x_max = count($x_value) - 1; - } - - // unnormalize the remainder - $x->rshift($shift); - - $quotient->is_negative = $x_sign != $y_sign; - - // calculate the "common residue", if appropriate - if ($x_sign) { - $y->rshift($shift); - $x = $y->subtract($x); - } - - return [$this->normalize($quotient), $this->normalize($x)]; - } - - /** - * Divides a BigInteger by a regular integer - * - * abc / x = a00 / x + b0 / x + c / x - * - * @param array $dividend - * @param int $divisor - * @return array - */ - private static function divide_digit(array $dividend, $divisor) - { - $carry = 0; - $result = []; - - for ($i = count($dividend) - 1; $i >= 0; --$i) { - $temp = static::BASE_FULL * $carry + $dividend[$i]; - $result[$i] = self::safe_divide($temp, $divisor); - $carry = (int) ($temp - $divisor * $result[$i]); - } - - return [$result, $carry]; - } - - /** - * Single digit division - * - * Even if int64 is being used the division operator will return a float64 value - * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't - * have the precision of int64 this is a problem so, when int64 is being used, - * we'll guarantee that the dividend is divisible by first subtracting the remainder. - * - * @param int $x - * @param int $y - * @return int - */ - private static function safe_divide($x, $y) - { - if (static::BASE === 26) { - return (int) ($x / $y); - } - - // static::BASE === 31 - return ($x - ($x % $y)) / $y; - } - - /* - * Convert an array / boolean to a PHP BigInteger object - * - * @param array $arr - * @return \phpseclib3\Math\BigInteger\Engines\PHP - */ - protected function convertToObj(array $arr) - { - $result = new static(); - $result->value = $arr[self::VALUE]; - $result->is_negative = $arr[self::SIGN]; - - return $this->normalize($result); - } - - /** - * Normalize - * - * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision - * - * @param PHP $result - * @return PHP - */ - protected function normalize(PHP $result) - { - unset($result->reduce); - - $result->precision = $this->precision; - $result->bitmask = $this->bitmask; - - $value = &$result->value; - - if (!count($value)) { - $result->is_negative = false; - return $result; - } - - $value = static::trim($value); - - if (!empty($result->bitmask->value)) { - $length = min(count($value), count($result->bitmask->value)); - $value = array_slice($value, 0, $length); - - for ($i = 0; $i < $length; ++$i) { - $value[$i] = $value[$i] & $result->bitmask->value[$i]; - } - } - - return $result; - } - - /* - * Compares two numbers. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return int - * @see static::compare() - */ - protected static function compareHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - if ($x_negative != $y_negative) { - return (!$x_negative && $y_negative) ? 1 : -1; - } - - $result = $x_negative ? -1 : 1; - - if (count($x_value) != count($y_value)) { - return (count($x_value) > count($y_value)) ? $result : -$result; - } - $size = max(count($x_value), count($y_value)); - - $x_value = array_pad($x_value, $size, 0); - $y_value = array_pad($y_value, $size, 0); - - for ($i = count($x_value) - 1; $i >= 0; --$i) { - if ($x_value[$i] != $y_value[$i]) { - return ($x_value[$i] > $y_value[$i]) ? $result : -$result; - } - } - - return 0; - } - - /** - * Absolute value. - * - * @return \phpseclib3\Math\BigInteger\Engines\PHP - */ - public function abs() - { - $temp = new static(); - $temp->value = $this->value; - - return $temp; - } - - /** - * Trim - * - * Removes leading zeros - * - * @param array $value - * @return PHP - */ - protected static function trim(array $value) - { - for ($i = count($value) - 1; $i >= 0; --$i) { - if ($value[$i]) { - break; - } - unset($value[$i]); - } - - return $value; - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\PHP - */ - public function bitwise_rightShift($shift) - { - $temp = new static(); - - // could just replace lshift with this, but then all lshift() calls would need to be rewritten - // and I don't want to do that... - $temp->value = $this->value; - $temp->rshift($shift); - - return $this->normalize($temp); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\PHP - */ - public function bitwise_leftShift($shift) - { - $temp = new static(); - // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten - // and I don't want to do that... - $temp->value = $this->value; - $temp->lshift($shift); - - return $this->normalize($temp); - } - - /** - * Converts 32-bit integers to bytes. - * - * @param int $x - * @return string - */ - private static function int2bytes($x) - { - return ltrim(pack('N', $x), chr(0)); - } - - /** - * Array Repeat - * - * @param int $input - * @param int $multiplier - * @return array - */ - protected static function array_repeat($input, $multiplier) - { - return $multiplier ? array_fill(0, $multiplier, $input) : []; - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits. - * - * @param int $shift - */ - protected function lshift($shift) - { - if ($shift == 0) { - return; - } - - $num_digits = (int) ($shift / static::BASE); - $shift %= static::BASE; - $shift = 1 << $shift; - - $carry = 0; - - for ($i = 0; $i < count($this->value); ++$i) { - $temp = $this->value[$i] * $shift + $carry; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $this->value[$i] = (int) ($temp - $carry * static::BASE_FULL); - } - - if ($carry) { - $this->value[count($this->value)] = $carry; - } - - while ($num_digits--) { - array_unshift($this->value, 0); - } - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits. - * - * @param int $shift - */ - protected function rshift($shift) - { - if ($shift == 0) { - return; - } - - $num_digits = (int) ($shift / static::BASE); - $shift %= static::BASE; - $carry_shift = static::BASE - $shift; - $carry_mask = (1 << $shift) - 1; - - if ($num_digits) { - $this->value = array_slice($this->value, $num_digits); - } - - $carry = 0; - - for ($i = count($this->value) - 1; $i >= 0; --$i) { - $temp = $this->value[$i] >> $shift | $carry; - $carry = ($this->value[$i] & $carry_mask) << $carry_shift; - $this->value[$i] = $temp; - } - - $this->value = static::trim($this->value); - } - - /** - * Performs modular exponentiation. - * - * @param PHP $e - * @param PHP $n - * @return PHP - */ - protected function powModInner(PHP $e, PHP $n) - { - try { - $class = static::$modexpEngine; - return $class::powModHelper($this, $e, $n, static::class); - } catch (\Exception $err) { - return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); - } - } - - /** - * Performs squaring - * - * @param array $x - * @return array - */ - protected static function square(array $x) - { - return count($x) < 2 * self::KARATSUBA_CUTOFF ? - self::trim(self::baseSquare($x)) : - self::trim(self::karatsubaSquare($x)); - } - - /** - * Performs traditional squaring on two BigIntegers - * - * Squaring can be done faster than multiplying a number by itself can be. See - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. - * - * @param array $value - * @return array - */ - protected static function baseSquare(array $value) - { - if (empty($value)) { - return []; - } - $square_value = self::array_repeat(0, 2 * count($value)); - - for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { - $i2 = $i << 1; - - $temp = $square_value[$i2] + $value[$i] * $value[$i]; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $square_value[$i2] = (int) ($temp - static::BASE_FULL * $carry); - - // note how we start from $i+1 instead of 0 as we do in multiplication. - for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { - $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $square_value[$k] = (int) ($temp - static::BASE_FULL * $carry); - } - - // the following line can yield values larger 2**15. at this point, PHP should switch - // over to floats. - $square_value[$i + $max_index + 1] = $carry; - } - - return $square_value; - } - - /** - * Performs Karatsuba "squaring" on two BigIntegers - * - * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. - * - * @param array $value - * @return array - */ - protected static function karatsubaSquare(array $value) - { - $m = count($value) >> 1; - - if ($m < self::KARATSUBA_CUTOFF) { - return self::baseSquare($value); - } - - $x1 = array_slice($value, $m); - $x0 = array_slice($value, 0, $m); - - $z2 = self::karatsubaSquare($x1); - $z0 = self::karatsubaSquare($x0); - - $z1 = self::addHelper($x1, false, $x0, false); - $z1 = self::karatsubaSquare($z1[self::VALUE]); - $temp = self::addHelper($z2, false, $z0, false); - $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); - - $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); - $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - - $xx = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xx = self::addHelper($xx[self::VALUE], $xx[self::SIGN], $z0, false); - - return $xx[self::VALUE]; - } - - /** - * Make the current number odd - * - * If the current number is odd it'll be unchanged. If it's even, one will be added to it. - * - * @see self::randomPrime() - */ - protected function make_odd() - { - $this->value[0] |= 1; - } - - /** - * Test the number against small primes. - * - * @see self::isPrime() - */ - protected function testSmallPrimes() - { - if ($this->value == [1]) { - return false; - } - if ($this->value == [2]) { - return true; - } - if (~$this->value[0] & 1) { - return false; - } - - $value = $this->value; - foreach (static::$primes as $prime) { - list(, $r) = self::divide_digit($value, $prime); - if (!$r) { - return count($value) == 1 && $value[0] == $prime; - } - } - - return true; - } - - /** - * Scan for 1 and right shift by that amount - * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @see self::isPrime() - * @param PHP $r - * @return int - */ - public static function scan1divide(PHP $r) - { - $r_value = &$r->value; - for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { - $temp = ~$r_value[$i] & static::MAX_DIGIT; - for ($j = 1; ($temp >> $j) & 1; ++$j) { - } - if ($j <= static::BASE) { - break; - } - } - $s = static::BASE * $i + $j; - $r->rshift($s); - return $s; - } - - /** - * Performs exponentiation. - * - * @param PHP $n - * @return PHP - */ - protected function powHelper(PHP $n) - { - if ($n->compare(static::$zero) == 0) { - return new static(1); - } // n^0 = 1 - - $temp = clone $this; - while (!$n->equals(static::$one)) { - $temp = $temp->multiply($this); - $n = $n->subtract(static::$one); - } - - return $temp; - } - - /** - * Is Odd? - * - * @return boolean - */ - public function isOdd() - { - return (bool) ($this->value[0] & 1); - } - - /** - * Tests if a bit is set - * - * @return boolean - */ - public function testBit($x) - { - $digit = floor($x / static::BASE); - $bit = $x % static::BASE; - - if (!isset($this->value[$digit])) { - return false; - } - - return (bool) ($this->value[$digit] & (1 << $bit)); - } - - /** - * Is Negative? - * - * @return boolean - */ - public function isNegative() - { - return $this->is_negative; - } - - /** - * Negate - * - * Given $k, returns -$k - * - * @return BigInteger - */ - public function negate() - { - $temp = clone $this; - $temp->is_negative = !$temp->is_negative; - - return $temp; - } - - /** - * Bitwise Split - * - * Splits BigInteger's into chunks of $split bits - * - * @param int $split - * @return \phpseclib3\Math\BigInteger\Engines\PHP[] - */ - public function bitwise_split($split) - { - if ($split < 1) { - throw new \RuntimeException('Offset must be greater than 1'); - } - - $width = (int) ($split / static::BASE); - if (!$width) { - $arr = $this->bitwise_small_split($split); - return array_map(function ($digit) { - $temp = new static(); - $temp->value = $digit != 0 ? [$digit] : []; - return $temp; - }, $arr); - } - - $vals = []; - $val = $this->value; - - $i = $overflow = 0; - $len = count($val); - while ($i < $len) { - $digit = []; - if (!$overflow) { - $digit = array_slice($val, $i, $width); - $i+= $width; - $overflow = $split % static::BASE; - if ($overflow) { - $mask = (1 << $overflow) - 1; - $temp = isset($val[$i]) ? $val[$i] : 0; - $digit[] = $temp & $mask; - } - } else { - $remaining = static::BASE - $overflow; - $tempsplit = $split - $remaining; - $tempwidth = (int) ($tempsplit / static::BASE + 1); - $digit = array_slice($val, $i, $tempwidth); - $i+= $tempwidth; - $tempoverflow = $tempsplit % static::BASE; - if ($tempoverflow) { - $tempmask = (1 << $tempoverflow) - 1; - $temp = isset($val[$i]) ? $val[$i] : 0; - $digit[] = $temp & $tempmask; - } - $newbits = 0; - for ($j = count($digit) - 1; $j >= 0; $j--) { - $temp = $digit[$j] & $mask; - $digit[$j] = ($digit[$j] >> $overflow) | ($newbits << $remaining); - $newbits = $temp; - } - $overflow = $tempoverflow; - $mask = $tempmask; - } - $temp = new static(); - $temp->value = static::trim($digit); - $vals[] = $temp; - } - - return array_reverse($vals); - } - - /** - * Bitwise Split where $split < static::BASE - * - * @param int $split - * @return \phpseclib3\Math\BigInteger\Engines\PHP[] - */ - private function bitwise_small_split($split) - { - $vals = []; - $val = $this->value; - - $mask = (1 << $split) - 1; - - $i = $overflow = 0; - $len = count($val); - $val[] = 0; - $remaining = static::BASE; - while ($i != $len) { - $digit = $val[$i] & $mask; - $val[$i]>>= $split; - if (!$overflow) { - $remaining-= $split; - $overflow = $split <= $remaining ? 0 : $split - $remaining; - - if (!$remaining) { - $i++; - $remaining = static::BASE; - $overflow = 0; - } - } else if (++$i != $len) { - $tempmask = (1 << $overflow) - 1; - $digit|= ($val[$i] & $tempmask) << $remaining; - $val[$i]>>= $overflow; - $remaining = static::BASE - $overflow; - $overflow = $split <= $remaining ? 0 : $split - $remaining; - } - - $vals[] = $digit; - } - - while ($vals[count($vals) - 1] == 0) { - unset($vals[count($vals) - 1]); - } - - return array_reverse($vals); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php deleted file mode 100644 index fb781c945..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\PHP; - -/** - * PHP Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class Base extends PHP -{ - /** - * Cache constants - * - * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. - * - * @access private - */ - const VARIABLE = 0; - /** - * $cache[self::DATA] contains the cached data. - * - * @access private - */ - const DATA = 1; - - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * The most naive approach to modular exponentiation has very unreasonable requirements, and - * and although the approach involving repeated squaring does vastly better, it, too, is impractical - * for our purposes. The reason being that division - by far the most complicated and time-consuming - * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. - * - * Modular reductions resolve this issue. Although an individual modular reduction takes more time - * then an individual division, when performed in succession (with the same modulo), they're a lot faster. - * - * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, - * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the - * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because - * the product of two odd numbers is odd), but what about when RSA isn't used? - * - * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a - * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the - * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, - * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and - * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. - * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. - * - * @param \phpseclib3\Math\BigInteger\Engines\PHP $x - * @param \phpseclib3\Math\BigInteger\Engines\PHP $e - * @param \phpseclib3\Math\BigInteger\Engines\PHP $n - * @param string $class - * @return \phpseclib3\Math\BigInteger\Engines\PHP - */ - protected static function powModHelper(PHP $x, PHP $e, PHP $n, $class) - { - if (empty($e->value)) { - $temp = new $class(); - $temp->value = [1]; - return $x->normalize($temp); - } - - if ($e->value == [1]) { - list(, $temp) = $x->divide($n); - return $x->normalize($temp); - } - - if ($e->value == [2]) { - $temp = new $class; - $temp->value = $class::square($x->value); - list(, $temp) = $temp->divide($n); - return $x->normalize($temp); - } - - return $x->normalize(static::slidingWindow($x, $e, $n, $class)); - } - - /** - * Modular reduction preparation - * - * @param array $x - * @param array $n - * @param string $class - * @see self::slidingWindow() - * @return array - */ - protected static function prepareReduce(array $x, array $n, $class) - { - return static::reduce($x, $n, $class); - } - - /** - * Modular multiply - * - * @param array $x - * @param array $y - * @param array $n - * @param string $class - * @see self::slidingWindow() - * @return array - */ - protected static function multiplyReduce(array $x, array $y, array $n, $class) - { - $temp = $class::multiplyHelper($x, false, $y, false); - return static::reduce($temp[self::VALUE], $n, $class); - } - - /** - * Modular square - * - * @param array $x - * @param array $n - * @param string $class - * @see self::slidingWindow() - * @return array - */ - protected static function squareReduce(array $x, array $n, $class) - { - return static::reduce($class::square($x), $n, $class); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php deleted file mode 100644 index 138deb1f6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett; - -/** - * PHP Default Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class DefaultEngine extends EvalBarrett -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php deleted file mode 100644 index 0ebbd71a8..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo; -use phpseclib3\Math\BigInteger\Engines\PHP; -use phpseclib3\Math\BigInteger\Engines\PHP\Base; -use phpseclib3\Math\BigInteger\Engines\Engine; - -/** - * PHP Montgomery Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class Montgomery extends Base -{ - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * @param \phpseclib3\Math\BigInteger\Engines\Engine $x - * @param \phpseclib3\Math\BigInteger\Engines\Engine $e - * @param \phpseclib3\Math\BigInteger\Engines\Engine $n - * @param string $class - * @return \phpseclib3\Math\BigInteger\Engines\Engine - */ - protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) - { - // is the modulo odd? - if ($n->value[0] & 1) { - return parent::slidingWindow($x, $e, $n, $class); - } - // if it's not, it's even - - // find the lowest set bit (eg. the max pow of 2 that divides $n) - for ($i = 0; $i < count($n->value); ++$i) { - if ($n->value[$i]) { - $temp = decbin($n->value[$i]); - $j = strlen($temp) - strrpos($temp, '1') - 1; - $j+= $class::BASE * $i; - break; - } - } - // at this point, 2^$j * $n/(2^$j) == $n - - $mod1 = clone $n; - $mod1->rshift($j); - $mod2 = new $class(); - $mod2->value = [1]; - $mod2->lshift($j); - - $part1 = $mod1->value != [1] ? parent::slidingWindow($x, $e, $mod1, $class) : new $class(); - $part2 = PowerOfTwo::slidingWindow($x, $e, $mod2, $class); - - $y1 = $mod2->modInverse($mod1); - $y2 = $mod1->modInverse($mod2); - - $result = $part1->multiply($mod2); - $result = $result->multiply($y1); - - $temp = $part2->multiply($mod1); - $temp = $temp->multiply($y2); - - $result = $result->add($temp); - list(, $result) = $result->divide($n); - - return $result; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php deleted file mode 100644 index 1b7b5b401..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; - -/** - * OpenSSL Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class OpenSSL extends Progenitor -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php deleted file mode 100644 index 03e0f8aaa..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php +++ /dev/null @@ -1,284 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Barrett Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class Barrett extends Base -{ - /** - * Barrett Modular Reduction - * - * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, - * so as not to require negative numbers (initially, this script didn't support negative numbers). - * - * Employs "folding", as described at - * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from - * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." - * - * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that - * usable on account of (1) its not using reasonable radix points as discussed in - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable - * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that - * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line - * comments for details. - * - * @param array $n - * @param array $m - * @param string $class - * @return array - */ - protected static function reduce(array $n, array $m, $class) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $m_length = count($m); - - // if (self::compareHelper($n, $static::square($m)) >= 0) { - if (count($n) > 2 * $m_length) { - $lhs = new $class(); - $rhs = new $class(); - $lhs->value = $n; - $rhs->value = $m; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced - if ($m_length < 5) { - return self::regularBarrett($n, $m, $class); - } - // n = 2 * m.length - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - - $lhs = new $class(); - $lhs_value = &$lhs->value; - $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); - $lhs_value[] = 1; - $rhs = new $class(); - $rhs->value = $m; - - list($u, $m1) = $lhs->divide($rhs); - $u = $u->value; - $m1 = $m1->value; - - $cache[self::DATA][] = [ - 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) - 'm1'=> $m1 // m.length - ]; - } else { - extract($cache[self::DATA][$key]); - } - - $cutoff = $m_length + ($m_length >> 1); - $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) - $msd = array_slice($n, $cutoff); // m.length >> 1 - - $lsd = self::trim($lsd); - $temp = $class::multiplyHelper($msd, false, $m1, false); // m.length + (m.length >> 1) - $n = $class::addHelper($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) - //if ($m_length & 1) { - // return self::regularBarrett($n[self::VALUE], $m, $class); - //} - - // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 - $temp = array_slice($n[self::VALUE], $m_length - 1); - // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 - // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 - $temp = $class::multiplyHelper($temp, false, $u, false); - // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 - // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) - $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); - // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 - // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) - $temp = $class::multiplyHelper($temp, false, $m, false); - - // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit - // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop - // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). - - $result = $class::subtractHelper($n[self::VALUE], false, $temp[self::VALUE], false); - - while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { - $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $m, false); - } - - return $result[self::VALUE]; - } - - /** - * (Regular) Barrett Modular Reduction - * - * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this - * is that this function does not fold the denominator into a smaller form. - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - private static function regularBarrett(array $x, array $n, $class) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $n_length = count($n); - - if (count($x) > 2 * $n_length) { - $lhs = new $class(); - $rhs = new $class(); - $lhs->value = $x; - $rhs->value = $n; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $n; - $lhs = new $class(); - $lhs_value = &$lhs->value; - $lhs_value = self::array_repeat(0, 2 * $n_length); - $lhs_value[] = 1; - $rhs = new $class(); - $rhs->value = $n; - list($temp, ) = $lhs->divide($rhs); // m.length - $cache[self::DATA][] = $temp->value; - } - - // 2 * m.length - (m.length - 1) = m.length + 1 - $temp = array_slice($x, $n_length - 1); - // (m.length + 1) + m.length = 2 * m.length + 1 - $temp = $class::multiplyHelper($temp, false, $cache[self::DATA][$key], false); - // (2 * m.length + 1) - (m.length - 1) = m.length + 2 - $temp = array_slice($temp[self::VALUE], $n_length + 1); - - // m.length + 1 - $result = array_slice($x, 0, $n_length + 1); - // m.length + 1 - $temp = self::multiplyLower($temp, false, $n, false, $n_length + 1, $class); - // $temp == array_slice($class::regularMultiply($temp, false, $n, false)->value, 0, $n_length + 1) - - if (self::compareHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { - $corrector_value = self::array_repeat(0, $n_length + 1); - $corrector_value[count($corrector_value)] = 1; - $result = $class::addHelper($result, false, $corrector_value, false); - $result = $result[self::VALUE]; - } - - // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits - $result = $class::subtractHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]); - while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { - $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $n, false); - } - - return $result[self::VALUE]; - } - - /** - * Performs long multiplication up to $stop digits - * - * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. - * - * @see self::regularBarrett() - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @param int $stop - * @param string $class - * @return array - */ - private static function multiplyLower(array $x_value, $x_negative, array $y_value, $y_negative, $stop, $class) - { - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - if ($x_length < $y_length) { - $temp = $x_value; - $x_value = $y_value; - $y_value = $temp; - - $x_length = count($x_value); - $y_length = count($y_value); - } - - $product_value = self::array_repeat(0, $x_length + $y_length); - - // the following for loop could be removed if the for loop following it - // (the one with nested for loops) initially set $i to 0, but - // doing so would also make the result in one set of unnecessary adds, - // since on the outermost loops first pass, $product->value[$k] is going - // to always be 0 - - $carry = 0; - - for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i - $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$j] = (int) ($temp - $class::BASE_FULL * $carry); - } - - if ($j < $stop) { - $product_value[$j] = $carry; - } - - // the above for loop is what the previous comment was talking about. the - // following for loop is the "one with nested for loops" - - for ($i = 1; $i < $y_length; ++$i) { - $carry = 0; - - for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { - $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$k] = (int) ($temp - $class::BASE_FULL * $carry); - } - - if ($k < $stop) { - $product_value[$k] = $carry; - } - } - - return [ - self::VALUE => self::trim($product_value), - self::SIGN => $x_negative != $y_negative - ]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php deleted file mode 100644 index aef167de9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Classic Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class Classic extends Base -{ - /** - * Regular Division - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function reduce(array $x, array $n, $class) - { - $lhs = new $class(); - $lhs->value = $x; - $rhs = new $class(); - $rhs->value = $n; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php deleted file mode 100644 index 7c81071da..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php +++ /dev/null @@ -1,492 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Base; -use phpseclib3\Math\BigInteger\Engines\PHP; - -/** - * PHP Dynamic Barrett Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class EvalBarrett extends Base -{ - /** - * Custom Reduction Function - * - * @see self::generateCustomReduction - */ - private static $custom_reduction; - - /** - * Barrett Modular Reduction - * - * This calls a dynamically generated loop unrolled function that's specific to a given modulo. - * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. - * - * @param array $n - * @param array $m - * @param string $class - * @return array - */ - protected static function reduce(array $n, array $m, $class) - { - $inline = self::$custom_reduction; - return $inline($n); - } - - /** - * Generate Custom Reduction - * - * @param PHP $m - * @param string $class - * @return callable - */ - protected static function generateCustomReduction(PHP $m, $class) - { - if (isset($n->reduce)) { - self::$custom_reduction = $n->reduce; - return $n->reduce; - } - - $m_length = count($m->value); - - if ($m_length < 5) { - $code = ' - $lhs = new ' . $class . '(); - $lhs->value = $x; - $rhs = new ' . $class . '(); - $rhs->value = [' . - implode(',', array_map('self::float2string', $m->value)) . ']; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - '; - eval('$func = function ($x) { ' . $code . '};'); - self::$custom_reduction = $func; - //self::$custom_reduction = \Closure::bind($func, $m, $class); - return $func; - } - - $lhs = new $class(); - $lhs_value = &$lhs->value; - - $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); - $lhs_value[] = 1; - $rhs = new $class(); - - list($u, $m1) = $lhs->divide($m); - - if ($class::BASE != 26) { - $u = $u->value; - } else { - $lhs_value = self::array_repeat(0, 2 * $m_length); - $lhs_value[] = 1; - $rhs = new $class(); - - list($u) = $lhs->divide($m); - $u = $u->value; - } - - $m = $m->value; - $m1 = $m1->value; - - $cutoff = count($m) + (count($m) >> 1); - - $code = ' - if (count($n) > ' . (2 * count($m)) . ') { - $lhs = new ' . $class . '(); - $rhs = new ' . $class . '(); - $lhs->value = $n; - $rhs->value = [' . - implode(',', array_map('self::float2string', $m)) . ']; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - $lsd = array_slice($n, 0, ' . $cutoff . '); - $msd = array_slice($n, ' . $cutoff . ');'; - - $code.= self::generateInlineTrim('msd'); - $code.= self::generateInlineMultiply('msd', $m1, 'temp', $class); - $code.= self::generateInlineAdd('lsd', 'temp', 'n', $class); - - $code.= '$temp = array_slice($n, ' . (count($m) - 1) . ');'; - $code.= self::generateInlineMultiply('temp', $u, 'temp2', $class); - $code.= self::generateInlineTrim('temp2'); - - $code.= $class::BASE == 26 ? - '$temp = array_slice($temp2, ' . (count($m) + 1) . ');' : - '$temp = array_slice($temp2, ' . ((count($m) >> 1) + 1) . ');'; - $code.= self::generateInlineMultiply('temp', $m, 'temp2', $class); - $code.= self::generateInlineTrim('temp2'); - - /* - if ($class::BASE == 26) { - $code.= '$n = array_slice($n, 0, ' . (count($m) + 1) . '); - $temp2 = array_slice($temp2, 0, ' . (count($m) + 1) . ');'; - } - */ - - $code.= self::generateInlineSubtract2('n', 'temp2', 'temp', $class); - - $subcode = self::generateInlineSubtract1('temp', $m, 'temp2', $class); - $subcode.= '$temp = $temp2;'; - - $code.= self::generateInlineCompare($m, 'temp', $subcode); - - $code.= 'return $temp;'; - - eval('$func = function ($n) { ' . $code . '};'); - - self::$custom_reduction = $func; - - return $func; - - //self::$custom_reduction = \Closure::bind($func, $m, $class); - } - - /** - * Inline Trim - * - * Removes leading zeros - * - * @param string $name - * @return string - */ - private static function generateInlineTrim($name) - { - return ' - for ($i = count($' . $name . ') - 1; $i >= 0; --$i) { - if ($' . $name . '[$i]) { - break; - } - unset($' . $name . '[$i]); - }'; - } - - /** - * Inline Multiply (unknown, known) - * - * @param string $input - * @param array $arr - * @param string $output - * @param string $class - * @return string - */ - private static function generateInlineMultiply($input, array $arr, $output, $class) - { - if (!count($arr)) { - return 'return [];'; - } - - $regular = ' - $length = count($' . $input . '); - if (!$length) { - $' . $output . ' = []; - }else{ - $' . $output . ' = array_fill(0, $length + ' . count($arr) . ', 0); - $carry = 0;'; - - for ($i = 0; $i < count($arr); $i++) { - $regular.= ' - $subtemp = $' . $input . '[0] * ' . $arr[$i]; - $regular.= $i ? ' + $carry;' : ';'; - - $regular.= '$carry = '; - $regular.= $class::BASE === 26 ? - 'intval($subtemp / 0x4000000);' : - '$subtemp >> 31;'; - $regular.= - '$' . $output . '[' . $i . '] = '; - if ($class::BASE === 26) { - $regular.= '(int) ('; - } - $regular.= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; - $regular.= $class::BASE === 26 ? ');' : ';'; - } - - $regular.= '$' . $output . '[' . count($arr) . '] = $carry;'; - - $regular.= ' - for ($i = 1; $i < $length; ++$i) {'; - - for ($j = 0; $j < count($arr); $j++) { - $regular.= $j ? '$k++;' : '$k = $i;'; - $regular.= ' - $subtemp = $' . $output . '[$k] + $' . $input . '[$i] * ' . $arr[$j]; - $regular.= $j ? ' + $carry;' : ';'; - - $regular.= '$carry = '; - $regular.= $class::BASE === 26 ? - 'intval($subtemp / 0x4000000);' : - '$subtemp >> 31;'; - $regular.= - '$' . $output . '[$k] = '; - if ($class::BASE === 26) { - $regular.= '(int) ('; - } - $regular.= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; - $regular.= $class::BASE === 26 ? ');' : ';'; - } - - $regular.= '$' . $output. '[++$k] = $carry; $carry = 0;'; - - $regular.= '}}'; - - //if (count($arr) < 2 * self::KARATSUBA_CUTOFF) { - //} - - return $regular; - } - - /** - * Inline Addition - * - * @param string $x - * @param string $y - * @param string $result - * @param string $class - * @return string - */ - private static function generateInlineAdd($x, $y, $result, $class) - { - $code = ' - $length = max(count($' . $x . '), count($' . $y . ')); - $' . $result . ' = array_pad($' . $x . ', $length + 1, 0); - $_' . $y . ' = array_pad($' . $y . ', $length, 0); - $carry = 0; - for ($i = 0, $j = 1; $j < $length; $i+=2, $j+=2) { - $sum = ($' . $result . '[$j] + $_' . $y . '[$j]) * ' . $class::BASE_FULL . ' - + $' . $result . '[$i] + $_' . $y . '[$i] + - $carry; - $carry = $sum >= ' . self::float2string($class::MAX_DIGIT2) . '; - $sum = $carry ? $sum - ' . self::float2string($class::MAX_DIGIT2) . ' : $sum;'; - - $code.= $class::BASE === 26 ? - '$upper = intval($sum / 0x4000000); $' . $result . '[$i] = (int) ($sum - ' . $class::BASE_FULL . ' * $upper);' : - '$upper = $sum >> 31; $' . $result . '[$i] = $sum - ' . $class::BASE_FULL . ' * $upper;'; - $code.= ' - $' . $result . '[$j] = $upper; - } - if ($j == $length) { - $sum = $' . $result . '[$i] + $_' . $y . '[$i] + $carry; - $carry = $sum >= ' . self::float2string($class::BASE_FULL) . '; - $' . $result . '[$i] = $carry ? $sum - ' . self::float2string($class::BASE_FULL) . ' : $sum; - } - if ($carry) { - for (; $' . $result . '[$i] == ' . $class::MAX_DIGIT . '; ++$i) { - $' . $result . '[$i] = 0; - } - ++$' . $result . '[$i]; - }'; - $code.= self::generateInlineTrim($result); - - return $code; - } - - /** - * Inline Subtraction 2 - * - * For when $known is more digits than $unknown. This is the harder use case to optimize for. - * - * @param string $known - * @param string $unknown - * @param string $result - * @param string $class - * @return string - */ - private static function generateInlineSubtract2($known, $unknown, $result, $class) - { - $code = ' - $' . $result .' = $' . $known . '; - $carry = 0; - $size = count($' . $unknown . '); - for ($i = 0, $j = 1; $j < $size; $i+= 2, $j+= 2) { - $sum = ($' . $known . '[$j] - $' . $unknown . '[$j]) * ' . $class::BASE_FULL . ' + $' . $known . '[$i] - - $' . $unknown . '[$i] - - $carry; - $carry = $sum < 0; - if ($carry) { - $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; - } - $subtemp = '; - $code.= $class::BASE === 26 ? - 'intval($sum / 0x4000000);' : - '$sum >> 31;'; - $code.= '$' . $result . '[$i] = '; - if ($class::BASE === 26) { - $code.= '(int) ('; - } - $code.= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; - if ($class::BASE === 26) { - $code.= ')'; - } - $code.= '; - $' . $result . '[$j] = $subtemp; - } - if ($j == $size) { - $sum = $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; - $carry = $sum < 0; - $' . $result . '[$i] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; - ++$i; - } - - if ($carry) { - for (; !$' . $result . '[$i]; ++$i) { - $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; - } - --$' . $result . '[$i]; - }'; - - $code.= self::generateInlineTrim($result); - - return $code; - } - - /** - * Inline Subtraction 1 - * - * For when $unknown is more digits than $known. This is the easier use case to optimize for. - * - * @param string $unknown - * @param array $known - * @param string $result - * @param string $class - * @return string - */ - private static function generateInlineSubtract1($unknown, array $known, $result, $class) - { - $code = '$' . $result . ' = $' . $unknown . ';'; - for ($i = 0, $j = 1; $j < count($known); $i+=2, $j+=2) { - $code.= '$sum = $' . $unknown . '[' . $j . '] * ' . $class::BASE_FULL . ' + $' . $unknown . '[' . $i . '] - '; - $code.= self::float2string($known[$j] * $class::BASE_FULL + $known[$i]); - if ($i != 0) { - $code.= ' - $carry'; - } - - $code.= '; - if ($carry = $sum < 0) { - $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; - } - $subtemp = '; - $code.= $class::BASE === 26 ? - 'intval($sum / 0x4000000);' : - '$sum >> 31;'; - $code.= ' - $' . $result . '[' . $i . '] = '; - if ($class::BASE === 26) { - $code.= ' (int) ('; - } - $code.= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; - if ($class::BASE === 26) { - $code.= ')'; - } - $code.= '; - $' . $result . '[' . $j . '] = $subtemp;'; - } - - $code.= '$i = ' . $i . ';'; - - if ($j == count($known)) { - $code.= ' - $sum = $' . $unknown . '[' . $i . '] - ' . $known[$i] . ' - $carry; - $carry = $sum < 0; - $' . $result . '[' . $i . '] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; - ++$i;'; - } - - $code.= ' - if ($carry) { - for (; !$' . $result . '[$i]; ++$i) { - $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; - } - --$' . $result . '[$i]; - }'; - $code.= self::generateInlineTrim($result); - - return $code; - } - - /** - * Inline Comparison - * - * If $unknown >= $known then loop - * - * @param array $known - * @param string $unknown - * @param string $subcode - * @return string - */ - private static function generateInlineCompare(array $known, $unknown, $subcode) - { - $uniqid = uniqid(); - $code = 'loop_' . $uniqid . ': - $clength = count($' . $unknown . '); - switch (true) { - case $clength < ' . count($known) . ': - goto end_' . $uniqid . '; - case $clength > ' . count($known) . ':'; - for ($i = count($known) - 1; $i >= 0; $i--) { - $code.= ' - case $' . $unknown . '[' . $i . '] > ' . $known[$i] . ': - goto subcode_' . $uniqid . '; - case $' . $unknown . '[' . $i . '] < ' . $known[$i] . ': - goto end_' . $uniqid . ';'; - } - $code.= ' - default: - // do subcode - } - - subcode_' . $uniqid . ':' . $subcode . ' - goto loop_' . $uniqid . '; - - end_' . $uniqid . ':'; - - return $code; - } - - /** - * Convert a float to a string - * - * If you do echo floatval(pow(2, 52)) you'll get 4.6116860184274E+18. It /can/ be displayed without a loss of - * precision but displayed in this way there will be precision loss, hence the need for this method. - * - * @param int|float $num - * @return string - */ - private static function float2string($num) - { - if (!is_float($num)) { - return $num; - } - - if ($num < 0) { - return '-' . self::float2string(abs($num)); - } - - $temp = ''; - while ($num) { - $temp = fmod($num, 10) . $temp; - $num = floor($num / 10); - } - - return $temp; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php deleted file mode 100644 index 79db314d6..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Montgomery as Progenitor; - -/** - * PHP Montgomery Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class Montgomery extends Progenitor -{ - /** - * Prepare a number for use in Montgomery Modular Reductions - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function prepareReduce(array $x, array $n, $class) - { - $lhs = new $class(); - $lhs->value = array_merge(self::array_repeat(0, count($n)), $x); - $rhs = new $class(); - $rhs->value = $n; - - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - /** - * Montgomery Multiply - * - * Interleaves the montgomery reduction and long multiplication algorithms together as described in - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function reduce(array $x, array $n, $class) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $x; - $cache[self::DATA][] = self::modInverse67108864($n, $class); - } - - $k = count($n); - - $result = [self::VALUE => $x]; - - for ($i = 0; $i < $k; ++$i) { - $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; - $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $class::regularMultiply([$temp], $n); - $temp = array_merge(self::array_repeat(0, $i), $temp); - $result = $class::addHelper($result[self::VALUE], false, $temp, false); - } - - $result[self::VALUE] = array_slice($result[self::VALUE], $k); - - if (self::compareHelper($result, false, $n, false) >= 0) { - $result = $class::subtractHelper($result[self::VALUE], false, $n, false); - } - - return $result[self::VALUE]; - } - - /** - * Modular Inverse of a number mod 2**26 (eg. 67108864) - * - * Based off of the bnpInvDigit function implemented and justified in the following URL: - * - * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} - * - * The following URL provides more info: - * - * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} - * - * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For - * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields - * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't - * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that - * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the - * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to - * 40 bits, which only 64-bit floating points will support. - * - * Thanks to Pedro Gimeno Fortea for input! - * - * @param array $x - * @param string $class - * @return int - */ - protected static function modInverse67108864(array $x, $class) // 2**26 == 67,108,864 - { - $x = -$x[0]; - $result = $x & 0x3; // x**-1 mod 2**2 - $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 - $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 - $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 - $result = $class::BASE == 26 ? - fmod($result * (2 - fmod($x * $result, $class::BASE_FULL)), $class::BASE_FULL) : // x**-1 mod 2**26 - ($result * (2 - ($x * $result) % $class::BASE_FULL)) % $class::BASE_FULL; - return $result & $class::MAX_DIGIT; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php deleted file mode 100644 index 31e8af211..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class MontgomeryMult extends Montgomery -{ - /** - * Montgomery Multiply - * - * Interleaves the montgomery reduction and long multiplication algorithms together as described in - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} - * - * @see self::_prepMontgomery() - * @see self::_montgomery() - * @access private - * @param array $x - * @param array $y - * @param array $m - * @param string $class - * @return array - */ - public static function multiplyReduce(array $x, array $y, array $m, $class) - { - // the following code, although not callable, can be run independently of the above code - // although the above code performed better in my benchmarks the following could might - // perform better under different circumstances. in lieu of deleting it it's just been - // made uncallable - - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - $cache[self::DATA][] = self::modInverse67108864($m, $class); - } - - $n = max(count($x), count($y), count($m)); - $x = array_pad($x, $n, 0); - $y = array_pad($y, $n, 0); - $m = array_pad($m, $n, 0); - $a = [self::VALUE => self::array_repeat(0, $n + 1)]; - for ($i = 0; $i < $n; ++$i) { - $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; - $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $temp * $cache[self::DATA][$key]; - $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $class::addHelper($class::regularMultiply([$x[$i]], $y), false, $class::regularMultiply([$temp], $m), false); - $a = $class::addHelper($a[self::VALUE], false, $temp[self::VALUE], false); - $a[self::VALUE] = array_slice($a[self::VALUE], 1); - } - if (self::compareHelper($a[self::VALUE], false, $m, false) >= 0) { - $a = $class::subtractHelper($a[self::VALUE], false, $m, false); - } - return $a[self::VALUE]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php deleted file mode 100644 index 73f133d06..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Power Of Two Modular Exponentiation Engine - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -abstract class PowerOfTwo extends Base -{ - /** - * Prepare a number for use in Montgomery Modular Reductions - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function prepareReduce(array $x, array $n, $class) - { - return self::reduce($x, $n, $class); - } - - /** - * Power Of Two Reduction - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function reduce(array $x, array $n, $class) - { - $lhs = new $class(); - $lhs->value = $x; - $rhs = new $class(); - $rhs->value = $n; - - $temp = new $class(); - $temp->value = [1]; - - $result = $lhs->bitwise_and($rhs->subtract($temp)); - return $result->value; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php deleted file mode 100644 index a1b4a7a50..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php +++ /dev/null @@ -1,418 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use ParagonIE\ConstantTime\Hex; - -/** - * Pure-PHP 32-bit Engine. - * - * Uses 64-bit floats if int size is 4 bits - * - * @package PHP32 - * @author Jim Wigginton - * @access public - */ -class PHP32 extends PHP -{ - // Constants used by PHP.php - const BASE = 26; - const BASE_FULL = 0x4000000; - const MAX_DIGIT = 0x3FFFFFF; - const MSB = 0x2000000; - - /** - * MAX10 in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10 = 10000000; - - /** - * MAX10LEN in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10LEN = 7; - const MAX_DIGIT2 = 4503599627370496; - /**#@-*/ - - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * Primes > 2 and < 1000 - * - * @var array - */ - protected static $primes; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP32 - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP32 - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP32 - */ - protected static $two; - - /** - * Initialize a PHP32 BigInteger Engine instance - * - * @param int $base - * @see parent::initialize() - */ - protected function initialize($base) - { - if ($base != 256 && $base != -256) { - return parent::initialize($base); - } - - $val = $this->value; - $this->value = []; - $vals = &$this->value; - $i = strlen($val); - if (!$i) { - return; - } - - while (true) { - $i-= 4; - if ($i < 0) { - if ($i == -4) { - break; - } - $val = substr($val, 0, 4 + $i); - $val = str_pad($val, 4, "\0", STR_PAD_LEFT); - if ($val == "\0\0\0\0") { - break; - } - $i = 0; - } - list(, $digit) = unpack('N', substr($val, $i, 4)); - $step = count($vals) & 3; - if ($step) { - $digit>>= 2 * $step; - } - if ($step != 3) { - $digit&= static::MAX_DIGIT; - $i++; - } - $vals[] = $digit; - } - while (end($vals) === 0) { - array_pop($vals); - } - reset($vals); - } - - /** - * Test for engine validity - * - * @see parent::__construct() - * @return bool - */ - public static function isValidEngine() - { - return PHP_INT_SIZE >= 4; - } - - /** - * Adds two BigIntegers. - * - * @param PHP32 $y - * @return PHP32 - */ - public function add(PHP32 $y) - { - $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param PHP32 $y - * @return PHP32 - */ - public function subtract(PHP32 $y) - { - $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param PHP32 $y - * @return PHP32 - */ - public function multiply(PHP32 $y) - { - $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param PHP32 $y - * @return PHP32 - */ - public function divide(PHP32 $y) - { - return $this->divideHelper($y); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP32 $n - * @return false|PHP32 - */ - public function modInverse(PHP32 $n) - { - return $this->modInverseHelper($n); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP32 $n - * @return PHP32[] - */ - public function extendedGCD(PHP32 $n) - { - return $this->extendedGCDHelper($n); - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param PHP32 $n - * @return PHP32 - */ - public function gcd(PHP32 $n) - { - return $this->extendedGCD($n)['gcd']; - } - - /** - * Logical And - * - * @param PHP32 $x - * @return PHP32 - */ - public function bitwise_and(PHP32 $x) - { - return $this->bitwiseAndHelper($x); - } - - /** - * Logical Or - * - * @param PHP32 $x - * @return PHP32 - */ - public function bitwise_or(PHP32 $x) - { - return $this->bitwiseOrHelper($x); - } - - /** - * Logical Exclusive Or - * - * @param PHP32 $x - * @return PHP32 - */ - public function bitwise_xor(PHP32 $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is - * demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param PHP32 $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @access public - * @see self::equals() - */ - public function compare(PHP32 $y) - { - return $this->compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param PHP32 $x - * @return bool - */ - public function equals(PHP32 $x) - { - return $this->value === $x->value && $this->is_negative == $x->is_negative; - } - - /** - * Performs modular exponentiation. - * - * @param PHP32 $e - * @param PHP32 $n - * @return PHP32 - */ - public function modPow(PHP32 $e, PHP32 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param PHP32 $e - * @param PHP32 $n - * @return PHP32 - */ - public function powMod(PHP32 $e, PHP32 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param PHP32 $min - * @param PHP32 $max - * @return false|PHP32 - */ - public static function randomRangePrime(PHP32 $min, PHP32 $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param PHP32 $min - * @param PHP32 $max - * @return PHP32 - */ - public static function randomRange(PHP32 $min, PHP32 $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Performs exponentiation. - * - * @param PHP32 $n - * @return PHP32 - */ - public function pow(PHP32 $n) - { - return $this->powHelper($n); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP32 ...$nums - * @return PHP32 - */ - public static function min(PHP32 ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP32 ...$nums - * @return PHP32 - */ - public static function max(PHP32 ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param PHP32 $min - * @param PHP32 $max - * @return bool - */ - public function between(PHP32 $min, PHP32 $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php deleted file mode 100644 index 42d1982d9..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php +++ /dev/null @@ -1,422 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use ParagonIE\ConstantTime\Hex; - -/** - * Pure-PHP 64-bit Engine. - * - * Uses 64-bit integers if int size is 8 bits - * - * @package PHP - * @author Jim Wigginton - * @access public - */ -class PHP64 extends PHP -{ - // Constants used by PHP.php - const BASE = 31; - const BASE_FULL = 0x80000000; - const MAX_DIGIT = 0x7FFFFFFF; - const MSB = 0x40000000; - - /** - * MAX10 in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10 = 1000000000; - - /** - * MAX10LEN in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10LEN = 9; - const MAX_DIGIT2 = 4611686018427387904; - /**#@-*/ - - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * Primes > 2 and < 1000 - * - * @var array - */ - protected static $primes; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP64 - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP64 - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP64 - */ - protected static $two; - - /** - * Initialize a PHP64 BigInteger Engine instance - * - * @param int $base - * @see parent::initialize() - */ - protected function initialize($base) - { - if ($base != 256 && $base != -256) { - return parent::initialize($base); - } - - $val = $this->value; - $this->value = []; - $vals = &$this->value; - $i = strlen($val); - if (!$i) { - return; - } - - while (true) { - $i-= 4; - if ($i < 0) { - if ($i == -4) { - break; - } - $val = substr($val, 0, 4 + $i); - $val = str_pad($val, 4, "\0", STR_PAD_LEFT); - if ($val == "\0\0\0\0") { - break; - } - $i = 0; - } - list(, $digit) = unpack('N', substr($val, $i, 4)); - $step = count($vals) & 7; - if (!$step) { - $digit&= static::MAX_DIGIT; - $i++; - } else { - $shift = 8 - $step; - $digit>>= $shift; - $shift = 32 - $shift; - $digit&= (1 << $shift) - 1; - $temp = $i > 0 ? ord($val[$i - 1]) : 0; - $digit|= ($temp << $shift) & 0x7F000000; - } - $vals[] = $digit; - } - while (end($vals) === 0) { - array_pop($vals); - } - reset($vals); - } - - /** - * Test for engine validity - * - * @see parent::__construct() - * @return bool - */ - public static function isValidEngine() - { - return PHP_INT_SIZE >= 8; - } - - /** - * Adds two BigIntegers. - * - * @param PHP64 $y - * @return PHP64 - */ - public function add(PHP64 $y) - { - $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param PHP64 $y - * @return PHP64 - */ - public function subtract(PHP64 $y) - { - $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param PHP64 $y - * @return PHP64 - */ - public function multiply(PHP64 $y) - { - $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param PHP64 $y - * @return PHP64 - */ - public function divide(PHP64 $y) - { - return $this->divideHelper($y); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP64 $n - * @return false|PHP64 - */ - public function modInverse(PHP64 $n) - { - return $this->modInverseHelper($n); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP64 $n - * @return PHP64[] - */ - public function extendedGCD(PHP64 $n) - { - return $this->extendedGCDHelper($n); - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param PHP64 $n - * @return PHP64 - */ - public function gcd(PHP64 $n) - { - return $this->extendedGCD($n)['gcd']; - } - - /** - * Logical And - * - * @param PHP64 $x - * @return PHP64 - */ - public function bitwise_and(PHP64 $x) - { - return $this->bitwiseAndHelper($x); - } - - /** - * Logical Or - * - * @param PHP64 $x - * @return PHP64 - */ - public function bitwise_or(PHP64 $x) - { - return $this->bitwiseOrHelper($x); - } - - /** - * Logical Exclusive Or - * - * @param PHP64 $x - * @return PHP64 - */ - public function bitwise_xor(PHP64 $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is - * demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param PHP64 $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @access public - * @see self::equals() - */ - public function compare(PHP64 $y) - { - return parent::compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param PHP64 $x - * @return bool - */ - public function equals(PHP64 $x) - { - return $this->value === $x->value && $this->is_negative == $x->is_negative; - } - - /** - * Performs modular exponentiation. - * - * @param PHP64 $e - * @param PHP64 $n - * @return PHP64 - */ - public function modPow(PHP64 $e, PHP64 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param PHP64 $e - * @param PHP64 $n - * @return PHP64 - */ - public function powMod(PHP64 $e, PHP64 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param PHP64 $min - * @param PHP64 $max - * @return false|PHP64 - */ - public static function randomRangePrime(PHP64 $min, PHP64 $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param PHP64 $min - * @param PHP64 $max - * @return PHP64 - */ - public static function randomRange(PHP64 $min, PHP64 $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Performs exponentiation. - * - * @param PHP64 $n - * @return PHP64 - */ - public function pow(PHP64 $n) - { - return $this->powHelper($n); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP64 ...$nums - * @return PHP64 - */ - public static function min(PHP64 ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP64 ...$nums - * @return PHP64 - */ - public static function max(PHP64 ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param PHP64 $min - * @param PHP64 $max - * @return bool - */ - public function between(PHP64 $min, PHP64 $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php deleted file mode 100644 index 7457b720f..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php +++ /dev/null @@ -1,196 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math; - -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Math\Common\FiniteField; -use phpseclib3\Math\BinaryField\Integer; -use phpseclib3\Common\Functions\Strings; - -/** - * Binary Finite Fields - * - * @package Math - * @author Jim Wigginton - * @access public - */ -class BinaryField extends FiniteField -{ - /** - * Instance Counter - * - * @var int - */ - private static $instanceCounter = 0; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** - * Default constructor - */ - public function __construct(...$indices) - { - $m = array_shift($indices); - $val = str_repeat('0', $m) . '1'; - foreach ($indices as $index) { - $val[$index] = '1'; - } - $modulo = static::base2ToBase256(strrev($val)); - - $mStart = 2 * $m - 2; - $t = ceil($m / 8); - $finalMask = chr((1 << ($m % 8)) - 1); - if ($finalMask == "\0") { - $finalMask = "\xFF"; - } - $bitLen = $mStart + 1; - $pad = ceil($bitLen / 8); - $h = $bitLen & 7; - $h = $h ? 8 - $h : 0; - - $r = rtrim(substr($val, 0, -1), '0'); - $u = [static::base2ToBase256(strrev($r))]; - for ($i = 1; $i < 8; $i++) { - $u[] = static::base2ToBase256(strrev(str_repeat('0', $i) . $r)); - } - - // implements algorithm 2.40 (in section 2.3.5) in "Guide to Elliptic Curve Cryptography" - // with W = 8 - $reduce = function($c) use ($u, $mStart, $m, $t, $finalMask, $pad, $h) { - $c = str_pad($c, $pad, "\0", STR_PAD_LEFT); - for ($i = $mStart; $i >= $m;) { - $g = $h >> 3; - $mask = $h & 7; - $mask = $mask ? 1 << (7 - $mask) : 0x80; - for (; $mask > 0; $mask >>= 1, $i--, $h++) { - if (ord($c[$g]) & $mask) { - $temp = $i - $m; - $j = $temp >> 3; - $k = $temp & 7; - $t1 = $j ? substr($c, 0, -$j) : $c; - $length = strlen($t1); - if ($length) { - $t2 = str_pad($u[$k], $length, "\0", STR_PAD_LEFT); - $temp = $t1 ^ $t2; - $c = $j ? substr_replace($c, $temp, 0, $length) : $temp; - } - } - } - } - $c = substr($c, -$t); - if (strlen($c) == $t) { - $c[0] = $c[0] & $finalMask; - } - return ltrim($c, "\0"); - }; - - $this->instanceID = self::$instanceCounter++; - Integer::setModulo($this->instanceID, $modulo); - Integer::setRecurringModuloFunction($this->instanceID, $reduce); - - $this->randomMax = new BigInteger($modulo, 2); - } - - /** - * Returns an instance of a dynamically generated PrimeFieldInteger class - * - * @param string $num - * @return object - */ - public function newInteger($num) - { - return new Integer($this->instanceID, $num instanceof BigInteger ? $num->toBytes() : $num); - } - - /** - * Returns an integer on the finite field between one and the prime modulo - * - * @return object - */ - public function randomInteger() - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - return new Integer($this->instanceID, BigInteger::randomRange($one, $this->randomMax)->toBytes()); - } - - /** - * Returns the length of the modulo in bytes - * - * @return integer - */ - public function getLengthInBytes() - { - return strlen(Integer::getModulo($this->instanceID)); - } - - /** - * Returns the length of the modulo in bits - * - * @return integer - */ - public function getLength() - { - return strlen(Integer::getModulo($this->instanceID)) << 3; - } - - /** - * Converts a base-2 string to a base-256 string - * - * @param string $x - * @param integer $size - * @return string - */ - public static function base2ToBase256($x, $size = null) - { - $str = Strings::bits2bin($x); - - $pad = strlen($x) >> 3; - if (strlen($x) & 3) { - $pad++; - } - $str = str_pad($str, $pad, "\0", STR_PAD_LEFT); - if (isset($size)) { - $str = str_pad($str, $size, "\0", STR_PAD_LEFT); - } - - return $str; - } - - /** - * Converts a base-256 string to a base-2 string - * - * @param string $x - * @return string - */ - public static function base256ToBase2($x) - { - if (function_exists('gmp_import')) { - return gmp_strval(gmp_import($x), 2); - } - - return Strings::bin2bits($x); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php deleted file mode 100644 index fc7a11ad2..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php +++ /dev/null @@ -1,520 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\BinaryField; - -use phpseclib3\Math\Common\FiniteField\Integer as Base; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\BinaryField; -use ParagonIE\ConstantTime\Hex; - -/** - * Binary Finite Fields - * - * @package Math - * @author Jim Wigginton - * @access public - */ -class Integer extends Base -{ - /** - * Holds the BinaryField's value - * - * @var string - */ - protected $value; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** - * Holds the PrimeField's modulo - * - * @var string[] - */ - protected static $modulo; - - /** - * Holds a pre-generated function to perform modulo reductions - * - * @var callable[] - */ - protected static $reduce; - - /** - * Default constructor - */ - public function __construct($instanceID, $num = '') - { - $this->instanceID = $instanceID; - if (!strlen($num)) { - $this->value = ''; - } else { - $reduce = static::$reduce[$instanceID]; - $this->value = $reduce($num); - } - } - - /** - * Set the modulo for a given instance - */ - public static function setModulo($instanceID, $modulo) - { - static::$modulo[$instanceID] = $modulo; - } - - /** - * Set the modulo for a given instance - */ - public static function setRecurringModuloFunction($instanceID, callable $function) - { - static::$reduce[$instanceID] = $function; - } - - /** - * Tests a parameter to see if it's of the right instance - * - * Throws an exception if the incorrect class is being utilized - */ - private static function checkInstance(self $x, self $y) - { - if ($x->instanceID != $y->instanceID) { - throw new \UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match'); - } - } - - /** - * Tests the equality of two numbers. - * - * @return bool - */ - public function equals(self $x) - { - static::checkInstance($this, $x); - - return $this->value == $x->value; - } - - /** - * Compares two numbers. - * - * @return int - */ - public function compare(self $x) - { - static::checkInstance($this, $x); - - $a = $this->value; - $b = $x->value; - - $length = max(strlen($a), strlen($b)); - - $a = str_pad($a, $length, "\0", STR_PAD_LEFT); - $b = str_pad($b, $length, "\0", STR_PAD_LEFT); - - return strcmp($a, $b); - } - - /** - * Returns the degree of the polynomial - * - * @param string $x - * @return int - */ - private static function deg($x) - { - $x = ltrim($x, "\0"); - $xbit = decbin(ord($x[0])); - $xlen = $xbit == '0' ? 0 : strlen($xbit); - $len = strlen($x); - if (!$len) { - return -1; - } - return 8 * strlen($x) - 9 + $xlen; - } - - /** - * Perform polynomial division - * - * @return string[] - * @link https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclidean_division - */ - private static function polynomialDivide($x, $y) - { - // in wikipedia's description of the algorithm, lc() is the leading coefficient. over a binary field that's - // always going to be 1. - - $q = chr(0); - $d = static::deg($y); - $r = $x; - while (($degr = static::deg($r)) >= $d) { - $s = '1' . str_repeat('0', $degr - $d); - $s = BinaryField::base2ToBase256($s); - $length = max(strlen($s), strlen($q)); - $q = !isset($q) ? $s : - str_pad($q, $length, "\0", STR_PAD_LEFT) ^ - str_pad($s, $length, "\0", STR_PAD_LEFT); - $s = static::polynomialMultiply($s, $y); - $length = max(strlen($r), strlen($s)); - $r = str_pad($r, $length, "\0", STR_PAD_LEFT) ^ - str_pad($s, $length, "\0", STR_PAD_LEFT); - } - - return [ltrim($q, "\0"), ltrim($r, "\0")]; - } - - /** - * Perform polynomial multiplation in the traditional way - * - * @return string - * @link https://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplication - */ - private static function regularPolynomialMultiply($x, $y) - { - $precomputed = [ltrim($x, "\0")]; - $x = strrev(BinaryField::base256ToBase2($x)); - $y = strrev(BinaryField::base256ToBase2($y)); - if (strlen($x) == strlen($y)) { - $length = strlen($x); - } else { - $length = max(strlen($x), strlen($y)); - $x = str_pad($x, $length, '0'); - $y = str_pad($y, $length, '0'); - } - $result = str_repeat('0', 2 * $length - 1); - $result = BinaryField::base2ToBase256($result); - $size = strlen($result); - $x = strrev($x); - - // precompute left shift 1 through 7 - for ($i = 1; $i < 8; $i++) { - $precomputed[$i] = BinaryField::base2ToBase256($x . str_repeat('0', $i)); - } - for ($i = 0; $i < strlen($y); $i++) { - if ($y[$i] == '1') { - $temp = $precomputed[$i & 7] . str_repeat("\0", $i >> 3); - $result^= str_pad($temp, $size, "\0", STR_PAD_LEFT); - } - } - - return $result; - } - - /** - * Perform polynomial multiplation - * - * Uses karatsuba multiplication to reduce x-bit multiplications to a series of 32-bit multiplications - * - * @return string - * @link https://en.wikipedia.org/wiki/Karatsuba_algorithm - */ - private static function polynomialMultiply($x, $y) - { - if (strlen($x) == strlen($y)) { - $length = strlen($x); - } else { - $length = max(strlen($x), strlen($y)); - $x = str_pad($x, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y, $length, "\0", STR_PAD_LEFT); - } - - switch (true) { - case PHP_INT_SIZE == 8 && $length <= 4: - return $length != 4 ? - self::subMultiply(str_pad($x, 4, "\0", STR_PAD_LEFT), str_pad($y, 4, "\0", STR_PAD_LEFT)) : - self::subMultiply($x, $y); - case PHP_INT_SIZE == 4 || $length > 32: - return self::regularPolynomialMultiply($x, $y); - } - - $m = $length >> 1; - - $x1 = substr($x, 0, -$m); - $x0 = substr($x, -$m); - $y1 = substr($y, 0, -$m); - $y0 = substr($y, -$m); - - $z2 = self::polynomialMultiply($x1, $y1); - $z0 = self::polynomialMultiply($x0, $y0); - $z1 = self::polynomialMultiply( - self::subAdd2($x1, $x0), - self::subAdd2($y1, $y0) - ); - - $z1 = self::subAdd3($z1, $z2, $z0); - - $xy = self::subAdd3( - $z2 . str_repeat("\0", 2 * $m), - $z1 . str_repeat("\0", $m), - $z0 - ); - - return ltrim($xy, "\0"); - } - - /** - * Perform polynomial multiplication on 2x 32-bit numbers, returning - * a 64-bit number - * - * @param string $x - * @param string $y - * @return string - * @link https://www.bearssl.org/constanttime.html#ghash-for-gcm - */ - private static function subMultiply($x, $y) - { - $x = unpack('N', $x)[1]; - $y = unpack('N', $y)[1]; - - $x0 = $x & 0x11111111; - $x1 = $x & 0x22222222; - $x2 = $x & 0x44444444; - $x3 = $x & 0x88888888; - - $y0 = $y & 0x11111111; - $y1 = $y & 0x22222222; - $y2 = $y & 0x44444444; - $y3 = $y & 0x88888888; - - $z0 = ($x0 * $y0) ^ ($x1 * $y3) ^ ($x2 * $y2) ^ ($x3 * $y1); - $z1 = ($x0 * $y1) ^ ($x1 * $y0) ^ ($x2 * $y3) ^ ($x3 * $y2); - $z2 = ($x0 * $y2) ^ ($x1 * $y1) ^ ($x2 * $y0) ^ ($x3 * $y3); - $z3 = ($x0 * $y3) ^ ($x1 * $y2) ^ ($x2 * $y1) ^ ($x3 * $y0); - - $z0&= 0x1111111111111111; - $z1&= 0x2222222222222222; - $z2&= 0x4444444444444444; - $z3&= -8608480567731124088; // 0x8888888888888888 gets interpreted as a float - - $z = $z0 | $z1 | $z2 | $z3; - - return pack('J', $z); - } - - /** - * Adds two numbers - * - * @param string $x - * @param string $y - * @return string - */ - private static function subAdd2($x, $y) - { - $length = max(strlen($x), strlen($y)); - $x = str_pad($x, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y, $length, "\0", STR_PAD_LEFT); - return $x ^ $y; - } - - /** - * Adds three numbers - * - * @param string $x - * @param string $y - * @return string - */ - private static function subAdd3($x, $y, $z) - { - $length = max(strlen($x), strlen($y), strlen($z)); - $x = str_pad($x, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y, $length, "\0", STR_PAD_LEFT); - $z = str_pad($z, $length, "\0", STR_PAD_LEFT); - return $x ^ $y ^ $z; - } - - /** - * Adds two BinaryFieldIntegers. - * - * @return static - */ - public function add(self $y) - { - static::checkInstance($this, $y); - - $length = strlen(static::$modulo[$this->instanceID]); - - $x = str_pad($this->value, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y->value, $length, "\0", STR_PAD_LEFT); - - return new static($this->instanceID, $x ^ $y); - } - - /** - * Subtracts two BinaryFieldIntegers. - * - * @return static - */ - public function subtract(self $x) - { - return $this->add($x); - } - - /** - * Multiplies two BinaryFieldIntegers. - * - * @return static - */ - public function multiply(self $y) - { - static::checkInstance($this, $y); - - return new static($this->instanceID, static::polynomialMultiply($this->value, $y->value)); - } - - /** - * Returns the modular inverse of a BinaryFieldInteger - * - * @return static - */ - public function modInverse() - { - $remainder0 = static::$modulo[$this->instanceID]; - $remainder1 = $this->value; - - if ($remainder1 == '') { - return new static($this->instanceID); - } - - $aux0 = "\0"; - $aux1 = "\1"; - while ($remainder1 != "\1") { - list($q, $r) = static::polynomialDivide($remainder0, $remainder1); - $remainder0 = $remainder1; - $remainder1 = $r; - // the auxiliary in row n is given by the sum of the auxiliary in - // row n-2 and the product of the quotient and the auxiliary in row - // n-1 - $temp = static::polynomialMultiply($aux1, $q); - $aux = str_pad($aux0, strlen($temp), "\0", STR_PAD_LEFT) ^ - str_pad($temp, strlen($aux0), "\0", STR_PAD_LEFT); - $aux0 = $aux1; - $aux1 = $aux; - } - - $temp = new static($this->instanceID); - $temp->value = ltrim($aux1, "\0"); - return $temp; - } - - /** - * Divides two PrimeFieldIntegers. - * - * @return static - */ - public function divide(self $x) - { - static::checkInstance($this, $x); - - $x = $x->modInverse(); - return $this->multiply($x); - } - - /** - * Negate - * - * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo - * so 0-12 is the same thing as modulo-12 - * - * @return object - */ - public function negate() - { - $x = str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); - - return new static($this->instanceID, $x ^ static::$modulo[$this->instanceID]); - } - - /** - * Returns the modulo - * - * @return integer - */ - public static function getModulo($instanceID) - { - return static::$modulo[$instanceID]; - } - - /** - * Converts an Integer to a byte string (eg. base-256). - * - * @return string - */ - public function toBytes() - { - return str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); - } - - /** - * Converts an Integer to a hex string (eg. base-16). - * - * @return string - */ - public function toHex() - { - return Hex::encode($this->toBytes()); - } - - /** - * Converts an Integer to a bit string (eg. base-2). - * - * @return string - */ - public function toBits() - { - //return str_pad(BinaryField::base256ToBase2($this->value), strlen(static::$modulo[$this->instanceID]), '0', STR_PAD_LEFT); - return BinaryField::base256ToBase2($this->value); - } - - /** - * Converts an Integer to a BigInteger - * - * @return string - */ - public function toBigInteger() - { - return new BigInteger($this->value, 256); - } - - /** - * __toString() magic method - * - * @access public - */ - public function __toString() - { - return (string) $this->toBigInteger(); - } - - /** - * __debugInfo() magic method - * - * @access public - */ - public function __debugInfo() - { - return ['value' => $this->toHex()]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php b/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php deleted file mode 100644 index c2294a04c..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\Common; - -/** - * Finite Fields - * - * @package Math - * @author Jim Wigginton - * @access public - */ -abstract class FiniteField -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php b/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php deleted file mode 100644 index d163f5523..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\Common\FiniteField; - -/** - * Finite Field Integer - * - * @package Math - * @author Jim Wigginton - * @access public - */ -abstract class Integer -{ -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php b/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php deleted file mode 100644 index 6b85c7247..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math; - -use phpseclib3\Math\Common\FiniteField; -use phpseclib3\Math\PrimeField\Integer; - -/** - * Prime Finite Fields - * - * @package Math - * @author Jim Wigginton - * @access public - */ -class PrimeField extends FiniteField -{ - /** - * Instance Counter - * - * @var int - */ - private static $instanceCounter = 0; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** - * Default constructor - */ - public function __construct(BigInteger $modulo) - { - //if (!$modulo->isPrime()) { - // throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); - //} - - $this->modulo = $modulo; - - $this->instanceID = self::$instanceCounter++; - Integer::setModulo($this->instanceID, $modulo); - Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); - } - - /** - * Use a custom defined modular reduction function - */ - public function setReduction(callable $func) - { - $this->reduce = $func->bindTo($this, $this); - } - - /** - * Returns an instance of a dynamically generated PrimeFieldInteger class - * - * @return object - */ - public function newInteger(BigInteger $num) - { - return new Integer($this->instanceID, $num); - } - - /** - * Returns an integer on the finite field between one and the prime modulo - * - * @return object - */ - public function randomInteger() - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - return new Integer($this->instanceID, BigInteger::randomRange($one, Integer::getModulo($this->instanceID))); - } - - /** - * Returns the length of the modulo in bytes - * - * @return integer - */ - public function getLengthInBytes() - { - return Integer::getModulo($this->instanceID)->getLengthInBytes(); - } - - /** - * Returns the length of the modulo in bits - * - * @return integer - */ - public function getLength() - { - return Integer::getModulo($this->instanceID)->getLength(); - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php deleted file mode 100644 index c274ff641..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php +++ /dev/null @@ -1,399 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\PrimeField; - -use phpseclib3\Math\Common\FiniteField\Integer as Base; -use phpseclib3\Math\BigInteger; -use ParagonIE\ConstantTime\Hex; - -/** - * Prime Finite Fields - * - * @package Math - * @author Jim Wigginton - * @access public - */ -class Integer extends Base -{ - /** - * Holds the PrimeField's value - * - * @var \phpseclib3\Math\BigInteger - */ - protected $value; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** - * Holds the PrimeField's modulo - * - * @var \phpseclib3\Math\BigInteger - */ - protected static $modulo; - - /** - * Holds a pre-generated function to perform modulo reductions - * - * @var Callable - */ - protected static $reduce; - - /** - * Zero - * - * @var \phpseclib3\Math\BigInteger - */ - protected static $zero; - - /** - * Default constructor - */ - public function __construct($instanceID, BigInteger $num = null) - { - $this->instanceID = $instanceID; - if (!isset($num)) { - $this->value = clone static::$zero; - } else { - $reduce = static::$reduce[$instanceID]; - $this->value = $reduce($num); - } - } - - /** - * Set the modulo for a given instance - */ - public static function setModulo($instanceID, BigInteger $modulo) - { - static::$modulo[$instanceID] = $modulo; - } - - /** - * Set the modulo for a given instance - */ - public static function setRecurringModuloFunction($instanceID, callable $function) - { - static::$reduce[$instanceID] = $function; - if (!isset(static::$zero)) { - static::$zero = new BigInteger(); - } - } - - /** - * Returns the modulo - * - * @return integer - */ - public static function getModulo($instanceID) - { - return static::$modulo[$instanceID]; - } - - /** - * Tests a parameter to see if it's of the right instance - * - * Throws an exception if the incorrect class is being utilized - */ - public static function checkInstance(self $x, self $y) - { - if ($x->instanceID != $y->instanceID) { - throw new \UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match'); - } - } - - /** - * Tests the equality of two numbers. - * - * @return bool - */ - public function equals(self $x) - { - static::checkInstance($this, $x); - - return $this->value->equals($x->value); - } - - /** - * Compares two numbers. - * - * @return int - */ - public function compare(self $x) - { - static::checkInstance($this, $x); - - return $this->value->compare($x->value); - } - - /** - * Adds two PrimeFieldIntegers. - * - * @return static - */ - public function add(self $x) - { - static::checkInstance($this, $x); - - $temp = new static($this->instanceID); - $temp->value = $this->value->add($x->value); - if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) { - $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]); - } - - return $temp; - } - - /** - * Subtracts two PrimeFieldIntegers. - * - * @return static - */ - public function subtract(self $x) - { - static::checkInstance($this, $x); - - $temp = new static($this->instanceID); - $temp->value = $this->value->subtract($x->value); - if ($temp->value->isNegative()) { - $temp->value = $temp->value->add(static::$modulo[$this->instanceID]); - } - - return $temp; - } - - /** - * Multiplies two PrimeFieldIntegers. - * - * @return static - */ - public function multiply(self $x) - { - static::checkInstance($this, $x); - - return new static($this->instanceID, $this->value->multiply($x->value)); - } - - /** - * Divides two PrimeFieldIntegers. - * - * @return static - */ - public function divide(self $x) - { - static::checkInstance($this, $x); - - $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]); - return new static($this->instanceID, $this->value->multiply($denominator)); - } - - /** - * Performs power operation on a PrimeFieldInteger. - * - * @return static - */ - public function pow(BigInteger $x) - { - $temp = new static($this->instanceID); - $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]); - - return $temp; - } - - /** - * Calculates the square root - * - * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm - * @return static|false - */ - public function squareRoot() - { - static $one, $two; - if (!isset($one)) { - $one = new BigInteger(1); - $two = new BigInteger(2); - } - $reduce = static::$reduce[$this->instanceID]; - $p_1 = static::$modulo[$this->instanceID]->subtract($one); - $q = clone $p_1; - $s = BigInteger::scan1divide($q); - list($pow) = $p_1->divide($two); - for ($z = $one; !$z->equals(static::$modulo[$this->instanceID]); $z = $z->add($one)) { - $temp = $z->powMod($pow, static::$modulo[$this->instanceID]); - if ($temp->equals($p_1)) { - break; - } - } - - $m = new BigInteger($s); - $c = $z->powMod($q, static::$modulo[$this->instanceID]); - $t = $this->value->powMod($q, static::$modulo[$this->instanceID]); - list($temp) = $q->add($one)->divide($two); - $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]); - - while (!$t->equals($one)) { - $i = clone $one; - - while (!$t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) { - $i = $i->add($one); - } - - if ($i->compare($m) >= 0) { - return false; - } - $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), static::$modulo[$this->instanceID]); - $m = $i; - $c = $reduce($b->multiply($b)); - $t = $reduce($t->multiply($c)); - $r = $reduce($r->multiply($b)); - } - - return new static($this->instanceID, $r); - } - - /** - * Is Odd? - * - * @return boolean - */ - public function isOdd() - { - return $this->value->isOdd(); - } - - /** - * Negate - * - * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo - * so 0-12 is the same thing as modulo-12 - * - * @return object - */ - public function negate() - { - return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value)); - } - - /** - * Converts an Integer to a byte string (eg. base-256). - * - * @return string - */ - public function toBytes() - { - $length = static::$modulo[$this->instanceID]->getLengthInBytes(); - return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); - } - - /** - * Converts an Integer to a hex string (eg. base-16). - * - * @return string - */ - public function toHex() - { - return Hex::encode($this->toBytes()); - } - - /** - * Converts an Integer to a bit string (eg. base-2). - * - * @return string - */ - public function toBits() - { - // return $this->value->toBits(); - static $length; - if (!isset($length)) { - $length = static::$modulo[$this->instanceID]->getLength(); - } - - return str_pad($this->value->toBits(), $length, '0', STR_PAD_LEFT); - } - - /** - * Returns the w-ary non-adjacent form (wNAF) - * - * @param int $w optional - * @return int[] - */ - public function getNAF($w = 1) - { - $w++; - - $mask = new BigInteger((1 << $w) - 1); - $sub = new BigInteger(1 << $w); - //$sub = new BigInteger(1 << ($w - 1)); - $d = $this->toBigInteger(); - $d_i = []; - - $i = 0; - while ($d->compare(static::$zero) > 0) { - if ($d->isOdd()) { - // start mods - $d_i[$i] = $d->testBit($w - 1) ? - $d->bitwise_and($mask)->subtract($sub) : - //$sub->subtract($d->bitwise_and($mask)) : - $d->bitwise_and($mask); - // end mods - $d = $d->subtract($d_i[$i]); - $d_i[$i] = (int) $d_i[$i]->toString(); - } else { - $d_i[$i] = 0; - } - $shift = !$d->equals(static::$zero) && $d->bitwise_and($mask)->equals(static::$zero) ? $w : 1; // $w or $w + 1? - $d = $d->bitwise_rightShift($shift); - while (--$shift > 0) { - $d_i[++$i] = 0; - } - $i++; - } - - return $d_i; - } - - /** - * Converts an Integer to a BigInteger - * - * @return string - */ - public function toBigInteger() - { - return clone $this->value; - } - - /** - * __toString() magic method - * - * @access public - */ - public function __toString() - { - return (string) $this->value; - } - - /** - * __debugInfo() magic method - * - * @access public - */ - public function __debugInfo() - { - return ['value' => $this->toHex()]; - } -} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php index c04fe7e68..8ae43fa04 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php @@ -16,7 +16,7 @@ * login('username', 'password')) { * exit('Login Failed'); * } @@ -35,11 +35,7 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Net; - -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Exception\FileNotFoundException; -use phpseclib3\Common\Functions\Strings; +namespace phpseclib\Net; /** * Pure-PHP implementations of SFTP. @@ -53,51 +49,41 @@ class SFTP extends SSH2 /** * SFTP channel constant * - * \phpseclib3\Net\SSH2::exec() uses 0 and \phpseclib3\Net\SSH2::read() / \phpseclib3\Net\SSH2::write() use 1. + * \phpseclib\Net\SSH2::exec() uses 0 and \phpseclib\Net\SSH2::read() / \phpseclib\Net\SSH2::write() use 1. * - * @see \phpseclib3\Net\SSH2::send_channel_packet() - * @see \phpseclib3\Net\SSH2::get_channel_packet() + * @see \phpseclib\Net\SSH2::_send_channel_packet() + * @see \phpseclib\Net\SSH2::_get_channel_packet() * @access private */ const CHANNEL = 0x100; + /**#@+ + * @access public + * @see \phpseclib\Net\SFTP::put() + */ /** * Reads data from a local file. - * - * @access public - * @see \phpseclib3\Net\SFTP::put() */ const SOURCE_LOCAL_FILE = 1; /** * Reads data from a string. - * - * @access public - * @see \phpseclib3\Net\SFTP::put() */ // this value isn't really used anymore but i'm keeping it reserved for historical reasons const SOURCE_STRING = 2; /** * Reads data from callback: * function callback($length) returns string to proceed, null for EOF - * - * @access public - * @see \phpseclib3\Net\SFTP::put() */ const SOURCE_CALLBACK = 16; /** * Resumes an upload - * - * @access public - * @see \phpseclib3\Net\SFTP::put() */ const RESUME = 4; /** * Append a local file to an already existing remote file - * - * @access public - * @see \phpseclib3\Net\SFTP::put() */ const RESUME_START = 8; + /**#@-*/ /** * Packet Types @@ -106,7 +92,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $packet_types = []; + var $packet_types = array(); /** * Status Codes @@ -115,7 +101,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $status_codes = []; + var $status_codes = array(); /** * The Request ID @@ -127,7 +113,7 @@ class SFTP extends SSH2 * @see self::_send_sftp_packet() * @access private */ - private $use_request_id = false; + var $use_request_id = false; /** * The Packet Type @@ -139,7 +125,7 @@ class SFTP extends SSH2 * @see self::_get_sftp_packet() * @access private */ - private $packet_type = -1; + var $packet_type = -1; /** * Packet Buffer @@ -148,7 +134,7 @@ class SFTP extends SSH2 * @see self::_get_sftp_packet() * @access private */ - private $packet_buffer = ''; + var $packet_buffer = ''; /** * Extensions supported by the server @@ -157,7 +143,7 @@ class SFTP extends SSH2 * @see self::_initChannel() * @access private */ - private $extensions = []; + var $extensions = array(); /** * Server SFTP version @@ -166,7 +152,7 @@ class SFTP extends SSH2 * @see self::_initChannel() * @access private */ - private $version; + var $version; /** * Current working directory @@ -176,7 +162,7 @@ class SFTP extends SSH2 * @see self::chdir() * @access private */ - private $pwd = false; + var $pwd = false; /** * Packet Type Log @@ -185,7 +171,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $packet_type_log = []; + var $packet_type_log = array(); /** * Packet Log @@ -194,7 +180,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $packet_log = []; + var $packet_log = array(); /** * Error information @@ -204,7 +190,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $sftp_errors = []; + var $sftp_errors = array(); /** * Stat Cache @@ -218,7 +204,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $stat_cache = []; + var $stat_cache = array(); /** * Max SFTP Packet Size @@ -228,7 +214,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $max_sftp_packet; + var $max_sftp_packet; /** * Stat Cache Flag @@ -238,7 +224,7 @@ class SFTP extends SSH2 * @var bool * @access private */ - private $use_stat_cache = true; + var $use_stat_cache = true; /** * Sort Options @@ -248,7 +234,7 @@ class SFTP extends SSH2 * @var array * @access private */ - protected $sortOptions = []; + var $sortOptions = array(); /** * Canonicalization Flag @@ -262,7 +248,7 @@ class SFTP extends SSH2 * @var bool * @access private */ - private $canonicalize_paths = true; + var $canonicalize_paths = true; /** * Request Buffers @@ -291,16 +277,16 @@ class SFTP extends SSH2 * @param string $host * @param int $port * @param int $timeout - * @return \phpseclib3\Net\SFTP + * @return \phpseclib\Net\SFTP * @access public */ - public function __construct($host, $port = 22, $timeout = 10) + function __construct($host, $port = 22, $timeout = 10) { parent::__construct($host, $port, $timeout); $this->max_sftp_packet = 1 << 15; - $this->packet_types = [ + $this->packet_types = array( 1 => 'NET_SFTP_INIT', 2 => 'NET_SFTP_VERSION', /* the format of SSH_FXP_OPEN changed between SFTPv4 and SFTPv5+: @@ -336,8 +322,8 @@ class SFTP extends SSH2 105=> 'NET_SFTP_ATTRS', 200=> 'NET_SFTP_EXTENDED' - ]; - $this->status_codes = [ + ); + $this->status_codes = array( 0 => 'NET_SFTP_STATUS_OK', 1 => 'NET_SFTP_STATUS_EOF', 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', @@ -370,10 +356,10 @@ class SFTP extends SSH2 29 => 'NET_SFTP_STATUS_OWNER_INVALID', 30 => 'NET_SFTP_STATUS_GROUP_INVALID', 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' - ]; + ); // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 - // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why - $this->attributes = [ + // the order, in this case, matters quite a lot - see \phpseclib\Net\SFTP::_parseAttributes() to understand why + $this->attributes = array( 0x00000001 => 'NET_SFTP_ATTR_SIZE', 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', @@ -383,34 +369,34 @@ class SFTP extends SSH2 // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. (-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED' - ]; + ); // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name // the array for that $this->open5_flags and similarly alter the constant names. - $this->open_flags = [ + $this->open_flags = array( 0x00000001 => 'NET_SFTP_OPEN_READ', 0x00000002 => 'NET_SFTP_OPEN_WRITE', 0x00000004 => 'NET_SFTP_OPEN_APPEND', 0x00000008 => 'NET_SFTP_OPEN_CREATE', 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', 0x00000020 => 'NET_SFTP_OPEN_EXCL' - ]; + ); // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 - // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation - $this->file_types = [ + // see \phpseclib\Net\SFTP::_parseLongname() for an explanation + $this->file_types = array( 1 => 'NET_SFTP_TYPE_REGULAR', 2 => 'NET_SFTP_TYPE_DIRECTORY', 3 => 'NET_SFTP_TYPE_SYMLINK', 4 => 'NET_SFTP_TYPE_SPECIAL', 5 => 'NET_SFTP_TYPE_UNKNOWN', - // the following types were first defined for use in SFTPv5+ + // the followin types were first defined for use in SFTPv5+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 6 => 'NET_SFTP_TYPE_SOCKET', 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', 9 => 'NET_SFTP_TYPE_FIFO' - ]; - $this->define_array( + ); + $this->_define_array( $this->packet_types, $this->status_codes, $this->attributes, @@ -430,50 +416,55 @@ class SFTP extends SSH2 * Login * * @param string $username - * @param string[] ...$args - * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool * @access public */ - public function login($username, ...$args) + function login($username) { - if (!parent::login(...func_get_args())) { + if (!call_user_func_array('parent::login', func_get_args())) { return false; } $this->window_size_server_to_client[self::CHANNEL] = $this->window_size; - $packet = Strings::packSSH2( - 'CsN3', + $packet = pack( + 'CNa*N3', NET_SSH2_MSG_CHANNEL_OPEN, + strlen('session'), 'session', self::CHANNEL, $this->window_size, 0x4000 ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN; - $response = $this->get_channel_packet(self::CHANNEL, true); + $response = $this->_get_channel_packet(self::CHANNEL, true); if ($response === false) { return false; } - $packet = Strings::packSSH2( - 'CNsbs', + $packet = pack( + 'CNNa*CNa*', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], + strlen('subsystem'), 'subsystem', - true, + 1, + strlen('sftp'), 'sftp' ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; - $response = $this->get_channel_packet(self::CHANNEL, true); + $response = $this->_get_channel_packet(self::CHANNEL, true); if ($response === false) { // from PuTTY's psftp.exe $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" . @@ -481,19 +472,23 @@ class SFTP extends SSH2 "exec sftp-server"; // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does // is redundant - $packet = Strings::packSSH2( - 'CNsCs', + $packet = pack( + 'CNNa*CNa*', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], + strlen('exec'), 'exec', 1, + strlen($command), $command ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; - $response = $this->get_channel_packet(self::CHANNEL, true); + $response = $this->_get_channel_packet(self::CHANNEL, true); if ($response === false) { return false; } @@ -501,19 +496,32 @@ class SFTP extends SSH2 $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA; - if (!$this->send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) { + if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_VERSION) { - throw new \UnexpectedValueException('Expected NET_SFTP_VERSION. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_VERSION'); + return false; } - list($this->version) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nversion', $this->_string_shift($response, 4))); + $this->version = $version; while (!empty($response)) { - list($key, $value) = Strings::unpackSSH2('ss', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $key = $this->_string_shift($response, $length); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $value = $this->_string_shift($response, $length); $this->extensions[$key] = $value; } @@ -553,7 +561,7 @@ class SFTP extends SSH2 So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed - in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib3\Net\SFTP would do is close the + in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib\Net\SFTP would do is close the channel and reopen it with a new and updated SSH_FXP_INIT packet. */ switch ($this->version) { @@ -564,9 +572,9 @@ class SFTP extends SSH2 return false; } - $this->pwd = $this->realpath('.'); + $this->pwd = $this->_realpath('.'); - $this->update_stat_cache($this->pwd, []); + $this->_update_stat_cache($this->pwd, array()); return true; } @@ -586,7 +594,7 @@ class SFTP extends SSH2 * * @access public */ - public function enableStatCache() + function enableStatCache() { $this->use_stat_cache = true; } @@ -596,9 +604,9 @@ class SFTP extends SSH2 * * @access public */ - public function clearStatCache() + function clearStatCache() { - $this->stat_cache = []; + $this->stat_cache = array(); } /** @@ -606,7 +614,7 @@ class SFTP extends SSH2 * * @access public */ - public function enablePathCanonicalization() + function enablePathCanonicalization() { $this->canonicalize_paths = true; } @@ -616,7 +624,7 @@ class SFTP extends SSH2 * * @access public */ - public function disablePathCanonicalization() + function disablePathCanonicalization() { $this->canonicalize_paths = false; } @@ -627,7 +635,7 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function pwd() + function pwd() { return $this->pwd; } @@ -637,24 +645,42 @@ class SFTP extends SSH2 * * @param string $response * @param int $status - * @access private + * @access public */ - private function logError($response, $status = -1) + function _logError($response, $status = -1) { if ($status == -1) { - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); } - list($error) = $this->status_codes[$status]; + $error = $this->status_codes[$status]; - if ($this->version > 2) { - list($message) = Strings::unpackSSH2('s', $response); - $this->sftp_errors[] = "$error: $message"; + if ($this->version > 2 || strlen($response) < 4) { + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length); } else { $this->sftp_errors[] = $error; } } + /** + * Returns canonicalized absolute pathname + * + * realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input + * path and returns the canonicalized absolute pathname. + * + * @param string $path + * @return mixed + * @access public + */ + function realpath($path) + { + return $this->_realpath($path); + } + /** * Canonicalize the Server-Side Path Name * @@ -666,11 +692,10 @@ class SFTP extends SSH2 * @see self::chdir() * @see self::disablePathCanonicalization() * @param string $path - * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed - * @access public + * @access private */ - public function realpath($path) + function _realpath($path) { if (!$this->canonicalize_paths) { return $path; @@ -678,24 +703,28 @@ class SFTP extends SSH2 if ($this->pwd === false) { // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9 - if (!$this->send_sftp_packet(NET_SFTP_REALPATH, Strings::packSSH2('s', $path))) { + if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks // at is the first part and that part is defined the same in SFTP versions 3 through 6. - list(, $filename) = Strings::unpackSSH2('Ns', $response); - return $filename; + $this->_string_shift($response, 4); // skip over the count - it should be 1, anyway + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + return $this->_string_shift($response, $length); case NET_SFTP_STATUS: - $this->logError($response); + $this->_logError($response); return false; default: - throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); + return false; } } @@ -704,7 +733,7 @@ class SFTP extends SSH2 } $path = explode('/', $path); - $new = []; + $new = array(); foreach ($path as $dir) { if (!strlen($dir)) { continue; @@ -726,11 +755,10 @@ class SFTP extends SSH2 * Changes the current directory * * @param string $dir - * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool * @access public */ - public function chdir($dir) + function chdir($dir) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; @@ -744,10 +772,10 @@ class SFTP extends SSH2 $dir.= '/'; } - $dir = $this->realpath($dir); + $dir = $this->_realpath($dir); // confirm that $dir is, in fact, a valid directory - if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) { + if ($this->use_stat_cache && is_array($this->_query_stat_cache($dir))) { $this->pwd = $dir; return true; } @@ -757,29 +785,29 @@ class SFTP extends SSH2 // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy // way to get those with SFTP - if (!$this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir))) { + if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) { return false; } - // see \phpseclib3\Net\SFTP::nlist() for a more thorough explanation of the following - $response = $this->get_sftp_packet(); + // see \phpseclib\Net\SFTP::nlist() for a more thorough explanation of the following + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: - $this->logError($response); + $this->_logError($response); return false; default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS' . - 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); + return false; } - if (!$this->close_handle($handle)) { + if (!$this->_close_handle($handle)) { return false; } - $this->update_stat_cache($dir, []); + $this->_update_stat_cache($dir, array()); $this->pwd = $dir; return true; @@ -793,9 +821,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function nlist($dir = '.', $recursive = false) + function nlist($dir = '.', $recursive = false) { - return $this->nlist_helper($dir, $recursive, ''); + return $this->_nlist_helper($dir, $recursive, ''); } /** @@ -807,23 +835,25 @@ class SFTP extends SSH2 * @return mixed * @access private */ - private function nlist_helper($dir, $recursive, $relativeDir) + function _nlist_helper($dir, $recursive, $relativeDir) { - $files = $this->readlist($dir, false); + $files = $this->_list($dir, false); if (!$recursive || $files === false) { return $files; } - $result = []; + $result = array(); foreach ($files as $value) { if ($value == '.' || $value == '..') { - $result[] = $relativeDir . $value; + if ($relativeDir == '') { + $result[] = $value; + } continue; } - if (is_array($this->query_stat_cache($this->realpath($dir . '/' . $value)))) { - $temp = $this->nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); - $temp = is_array($temp) ? $temp : []; + if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) { + $temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); + $temp = is_array($temp) ? $temp : array(); $result = array_merge($result, $temp); } else { $result[] = $relativeDir . $value; @@ -841,9 +871,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function rawlist($dir = '.', $recursive = false) + function rawlist($dir = '.', $recursive = false) { - $files = $this->readlist($dir, true); + $files = $this->_list($dir, true); if (!$recursive || $files === false) { return $files; } @@ -858,7 +888,7 @@ class SFTP extends SSH2 $is_directory = false; if ($key != '.' && $key != '..') { if ($this->use_stat_cache) { - $is_directory = is_array($this->query_stat_cache($this->realpath($dir . '/' . $key))); + $is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key))); } else { $stat = $this->lstat($dir . '/' . $key); $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY; @@ -883,26 +913,25 @@ class SFTP extends SSH2 * @param string $dir * @param bool $raw * @return mixed - * @throws \UnexpectedValueException on receipt of unexpected packets * @access private */ - private function readlist($dir, $raw = true) + function _list($dir, $raw = true) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $dir = $this->realpath($dir . '/'); + $dir = $this->_realpath($dir . '/'); if ($dir === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2 - if (!$this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir))) { + if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2 @@ -912,72 +941,87 @@ class SFTP extends SSH2 break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - $this->logError($response); + $this->_logError($response); return false; default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); + return false; } - $this->update_stat_cache($dir, []); + $this->_update_stat_cache($dir, array()); - $contents = []; + $contents = array(); while (true) { // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2 // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many // SSH_MSG_CHANNEL_DATA messages is not known to me. - if (!$this->send_sftp_packet(NET_SFTP_READDIR, Strings::packSSH2('s', $handle))) { + if (!$this->_send_sftp_packet(NET_SFTP_READDIR, pack('Na*', strlen($handle), $handle))) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: - list($count) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Ncount', $this->_string_shift($response, 4))); for ($i = 0; $i < $count; $i++) { - list($shortname, $longname) = Strings::unpackSSH2('ss', $response); - $attributes = $this->parseAttributes($response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $shortname = $this->_string_shift($response, $length); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $longname = $this->_string_shift($response, $length); + $attributes = $this->_parseAttributes($response); if (!isset($attributes['type'])) { - $fileType = $this->parseLongname($longname); + $fileType = $this->_parseLongname($longname); if ($fileType) { $attributes['type'] = $fileType; } } - $contents[$shortname] = $attributes + ['filename' => $shortname]; + $contents[$shortname] = $attributes + array('filename' => $shortname); if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) { - $this->update_stat_cache($dir . '/' . $shortname, []); + $this->_update_stat_cache($dir . '/' . $shortname, array()); } else { if ($shortname == '..') { - $temp = $this->realpath($dir . '/..') . '/.'; + $temp = $this->_realpath($dir . '/..') . '/.'; } else { $temp = $dir . '/' . $shortname; } - $this->update_stat_cache($temp, (object) ['lstat' => $attributes]); + $this->_update_stat_cache($temp, (object) array('lstat' => $attributes)); } // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the // final SSH_FXP_STATUS packet should tell us that, already. } break; case NET_SFTP_STATUS: - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_EOF) { - $this->logError($response, $status); + $this->_logError($response, $status); return false; } break 2; default: - throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); + return false; } } - if (!$this->close_handle($handle)) { + if (!$this->_close_handle($handle)) { return false; } if (count($this->sortOptions)) { - uasort($contents, [&$this, 'comparator']); + uasort($contents, array(&$this, '_comparator')); } return $raw ? $contents : array_keys($contents); @@ -993,7 +1037,7 @@ class SFTP extends SSH2 * @return int * @access private */ - private function comparator($a, $b) + function _comparator($a, $b) { switch (true) { case $a['filename'] === '.' || $b['filename'] === '.': @@ -1034,6 +1078,7 @@ class SFTP extends SSH2 return $order === SORT_DESC ? -$result : $result; } break; + case 'permissions': case 'mode': $a[$sort]&= 07777; $b[$sort]&= 07777; @@ -1064,12 +1109,12 @@ class SFTP extends SSH2 * $sftp->setListOrder(); * Don't do any sort of sorting * - * @param string[] ...$args * @access public */ - public function setListOrder(...$args) + function setListOrder() { - $this->sortOptions = []; + $this->sortOptions = array(); + $args = func_get_args(); if (empty($args)) { return; } @@ -1078,10 +1123,32 @@ class SFTP extends SSH2 $this->sortOptions[$args[$i]] = $args[$i + 1]; } if (!count($this->sortOptions)) { - $this->sortOptions = ['bogus' => true]; + $this->sortOptions = array('bogus' => true); } } + /** + * Returns the file size, in bytes, or false, on failure + * + * Files larger than 4GB will show up as being exactly 4GB. + * + * @param string $filename + * @return mixed + * @access public + */ + function size($filename) + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + $result = $this->stat($filename); + if ($result === false) { + return false; + } + return isset($result['size']) ? $result['size'] : -1; + } + /** * Save files / directories to cache * @@ -1089,7 +1156,7 @@ class SFTP extends SSH2 * @param mixed $value * @access private */ - private function update_stat_cache($path, $value) + function _update_stat_cache($path, $value) { if ($this->use_stat_cache === false) { return; @@ -1105,10 +1172,10 @@ class SFTP extends SSH2 // 1. a file was deleted and changed to a directory behind phpseclib's back // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to if (is_object($temp)) { - $temp = []; + $temp = array(); } if (!isset($temp[$dir])) { - $temp[$dir] = []; + $temp[$dir] = array(); } if ($i === $max) { if (is_object($temp[$dir]) && is_object($value)) { @@ -1133,7 +1200,7 @@ class SFTP extends SSH2 * @return bool * @access private */ - private function remove_from_stat_cache($path) + function _remove_from_stat_cache($path) { $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); @@ -1163,7 +1230,7 @@ class SFTP extends SSH2 * @return mixed * @access private */ - private function query_stat_cache($path) + function _query_stat_cache($path) { $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); @@ -1189,19 +1256,19 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function stat($filename) + function stat($filename) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $filename = $this->realpath($filename); + $filename = $this->_realpath($filename); if ($filename === false) { return false; } if ($this->use_stat_cache) { - $result = $this->query_stat_cache($filename); + $result = $this->_query_stat_cache($filename); if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) { return $result['.']->stat; } @@ -1210,16 +1277,16 @@ class SFTP extends SSH2 } } - $stat = $this->stat_helper($filename, NET_SFTP_STAT); + $stat = $this->_stat($filename, NET_SFTP_STAT); if ($stat === false) { - $this->remove_from_stat_cache($filename); + $this->_remove_from_stat_cache($filename); return false; } if (isset($stat['type'])) { if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename.= '/.'; } - $this->update_stat_cache($filename, (object) ['stat' => $stat]); + $this->_update_stat_cache($filename, (object) array('stat' => $stat)); return $stat; } @@ -1232,7 +1299,7 @@ class SFTP extends SSH2 if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename.= '/.'; } - $this->update_stat_cache($filename, (object) ['stat' => $stat]); + $this->_update_stat_cache($filename, (object) array('stat' => $stat)); return $stat; } @@ -1246,19 +1313,19 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function lstat($filename) + function lstat($filename) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $filename = $this->realpath($filename); + $filename = $this->_realpath($filename); if ($filename === false) { return false; } if ($this->use_stat_cache) { - $result = $this->query_stat_cache($filename); + $result = $this->_query_stat_cache($filename); if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) { return $result['.']->lstat; } @@ -1267,24 +1334,24 @@ class SFTP extends SSH2 } } - $lstat = $this->stat_helper($filename, NET_SFTP_LSTAT); + $lstat = $this->_stat($filename, NET_SFTP_LSTAT); if ($lstat === false) { - $this->remove_from_stat_cache($filename); + $this->_remove_from_stat_cache($filename); return false; } if (isset($lstat['type'])) { if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename.= '/.'; } - $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + $this->_update_stat_cache($filename, (object) array('lstat' => $lstat)); return $lstat; } - $stat = $this->stat_helper($filename, NET_SFTP_STAT); + $stat = $this->_stat($filename, NET_SFTP_STAT); if ($lstat != $stat) { - $lstat = array_merge($lstat, ['type' => NET_SFTP_TYPE_SYMLINK]); - $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + $lstat = array_merge($lstat, array('type' => NET_SFTP_TYPE_SYMLINK)); + $this->_update_stat_cache($filename, (object) array('lstat' => $lstat)); return $stat; } @@ -1297,7 +1364,7 @@ class SFTP extends SSH2 if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename.= '/.'; } - $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + $this->_update_stat_cache($filename, (object) array('lstat' => $lstat)); return $lstat; } @@ -1305,34 +1372,33 @@ class SFTP extends SSH2 /** * Returns general information about a file or symbolic link * - * Determines information without calling \phpseclib3\Net\SFTP::realpath(). + * Determines information without calling \phpseclib\Net\SFTP::realpath(). * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT. * * @param string $filename * @param int $type - * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed * @access private */ - private function stat_helper($filename, $type) + function _stat($filename, $type) { // SFTPv4+ adds an additional 32-bit integer field - flags - to the following: - $packet = Strings::packSSH2('s', $filename); - if (!$this->send_sftp_packet($type, $packet)) { + $packet = pack('Na*', strlen($filename), $filename); + if (!$this->_send_sftp_packet($type, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_ATTRS: - return $this->parseAttributes($response); + return $this->_parseAttributes($response); case NET_SFTP_STATUS: - $this->logError($response); + $this->_logError($response); return false; } - throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); + return false; } /** @@ -1343,11 +1409,11 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function truncate($filename, $new_size) + function truncate($filename, $new_size) { $attr = pack('N3', NET_SFTP_ATTR_SIZE, $new_size / 4294967296, $new_size); // 4294967296 == 0x100000000 == 1<<32 - return $this->setstat($filename, $attr, false); + return $this->_setstat($filename, $attr, false); } /** @@ -1358,17 +1424,16 @@ class SFTP extends SSH2 * @param string $filename * @param int $time * @param int $atime - * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool * @access public */ - public function touch($filename, $time = null, $atime = null) + function touch($filename, $time = null, $atime = null) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $filename = $this->realpath($filename); + $filename = $this->_realpath($filename); if ($filename === false) { return false; } @@ -1382,24 +1447,24 @@ class SFTP extends SSH2 $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL; $attr = pack('N3', NET_SFTP_ATTR_ACCESSTIME, $time, $atime); - $packet = Strings::packSSH2('sN', $filename, $flags) . $attr; - if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + $packet = pack('Na*Na*', strlen($filename), $filename, $flags, $attr); + if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: - return $this->close_handle(substr($response, 4)); + return $this->_close_handle(substr($response, 4)); case NET_SFTP_STATUS: - $this->logError($response); + $this->_logError($response); break; default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); + return false; } - return $this->setstat($filename, $attr, false); + return $this->_setstat($filename, $attr, false); } /** @@ -1413,13 +1478,13 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function chown($filename, $uid, $recursive = false) + function chown($filename, $uid, $recursive = false) { // quoting from , // "if the owner or group is specified as -1, then that ID is not changed" $attr = pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1); - return $this->setstat($filename, $attr, $recursive); + return $this->_setstat($filename, $attr, $recursive); } /** @@ -1433,11 +1498,11 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function chgrp($filename, $gid, $recursive = false) + function chgrp($filename, $gid, $recursive = false) { $attr = pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid); - return $this->setstat($filename, $attr, $recursive); + return $this->_setstat($filename, $attr, $recursive); } /** @@ -1449,11 +1514,10 @@ class SFTP extends SSH2 * @param int $mode * @param string $filename * @param bool $recursive - * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed * @access public */ - public function chmod($mode, $filename, $recursive = false) + function chmod($mode, $filename, $recursive = false) { if (is_string($mode) && is_int($filename)) { $temp = $mode; @@ -1462,7 +1526,7 @@ class SFTP extends SSH2 } $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777); - if (!$this->setstat($filename, $attr, $recursive)) { + if (!$this->_setstat($filename, $attr, $recursive)) { return false; } if ($recursive) { @@ -1474,22 +1538,22 @@ class SFTP extends SSH2 // tell us if the file actually exists. // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following: $packet = pack('Na*', strlen($filename), $filename); - if (!$this->send_sftp_packet(NET_SFTP_STAT, $packet)) { + if (!$this->_send_sftp_packet(NET_SFTP_STAT, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_ATTRS: - $attrs = $this->parseAttributes($response); - return $attrs['mode']; + $attrs = $this->_parseAttributes($response); + return $attrs['permissions']; case NET_SFTP_STATUS: - $this->logError($response); + $this->_logError($response); return false; } - throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); + return false; } /** @@ -1498,33 +1562,32 @@ class SFTP extends SSH2 * @param string $filename * @param string $attr * @param bool $recursive - * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool * @access private */ - private function setstat($filename, $attr, $recursive) + function _setstat($filename, $attr, $recursive) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $filename = $this->realpath($filename); + $filename = $this->_realpath($filename); if ($filename === false) { return false; } - $this->remove_from_stat_cache($filename); + $this->_remove_from_stat_cache($filename); if ($recursive) { $i = 0; - $result = $this->setstat_recursive($filename, $attr, $i); - $this->read_put_responses($i); + $result = $this->_setstat_recursive($filename, $attr, $i); + $this->_read_put_responses($i); return $result; } // SFTPv4+ has an additional byte field - type - that would need to be sent, as well. setting it to // SSH_FILEXFER_TYPE_UNKNOWN might work. if not, we'd have to do an SSH_FXP_STAT before doing an SSH_FXP_SETSTAT. - if (!$this->send_sftp_packet(NET_SFTP_SETSTAT, Strings::packSSH2('s', $filename) . $attr)) { + if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($filename), $filename, $attr))) { return false; } @@ -1535,15 +1598,18 @@ class SFTP extends SSH2 -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6 */ - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); + $this->_logError($response, $status); return false; } @@ -1561,16 +1627,16 @@ class SFTP extends SSH2 * @return bool * @access private */ - private function setstat_recursive($path, $attr, &$i) + function _setstat_recursive($path, $attr, &$i) { - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { return false; } $i = 0; - $entries = $this->readlist($path, true); + $entries = $this->_list($path, true); if ($entries === false) { - return $this->setstat($path, $attr, false); + return $this->_setstat($path, $attr, false); } // normally $entries would have at least . and .. but it might not if the directories @@ -1587,18 +1653,18 @@ class SFTP extends SSH2 $temp = $path . '/' . $filename; if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { - if (!$this->setstat_recursive($temp, $attr, $i)) { + if (!$this->_setstat_recursive($temp, $attr, $i)) { return false; } } else { - if (!$this->send_sftp_packet(NET_SFTP_SETSTAT, Strings::packSSH2('s', $temp) . $attr)) { + if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($temp), $temp, $attr))) { return false; } $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { return false; } $i = 0; @@ -1606,14 +1672,14 @@ class SFTP extends SSH2 } } - if (!$this->send_sftp_packet(NET_SFTP_SETSTAT, Strings::packSSH2('s', $path) . $attr)) { + if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($path), $path, $attr))) { return false; } $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { return false; } $i = 0; @@ -1626,43 +1692,47 @@ class SFTP extends SSH2 * Return the target of a symbolic link * * @param string $link - * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed * @access public */ - public function readlink($link) + function readlink($link) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $link = $this->realpath($link); + $link = $this->_realpath($link); - if (!$this->send_sftp_packet(NET_SFTP_READLINK, Strings::packSSH2('s', $link))) { + if (!$this->_send_sftp_packet(NET_SFTP_READLINK, pack('Na*', strlen($link), $link))) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: break; case NET_SFTP_STATUS: - $this->logError($response); + $this->_logError($response); return false; default: - throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); + return false; } - list($count) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Ncount', $this->_string_shift($response, 4))); // the file isn't a symlink if (!$count) { return false; } - list($filename) = Strings::unpackSSH2('s', $response); - - return $filename; + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + return $this->_string_shift($response, $length); } /** @@ -1672,33 +1742,35 @@ class SFTP extends SSH2 * * @param string $target * @param string $link - * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool * @access public */ - public function symlink($target, $link) + function symlink($target, $link) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - //$target = $this->realpath($target); - $link = $this->realpath($link); + //$target = $this->_realpath($target); + $link = $this->_realpath($link); - $packet = Strings::packSSH2('ss', $target, $link); - if (!$this->send_sftp_packet(NET_SFTP_SYMLINK, $packet)) { + $packet = pack('Na*Na*', strlen($target), $target, strlen($link), $link); + if (!$this->_send_sftp_packet(NET_SFTP_SYMLINK, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); + $this->_logError($response, $status); return false; } @@ -1714,13 +1786,13 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function mkdir($dir, $mode = -1, $recursive = false) + function mkdir($dir, $mode = -1, $recursive = false) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $dir = $this->realpath($dir); + $dir = $this->_realpath($dir); if ($recursive) { $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir)); @@ -1731,12 +1803,12 @@ class SFTP extends SSH2 for ($i = 0; $i < count($dirs); $i++) { $temp = array_slice($dirs, 0, $i + 1); $temp = implode('/', $temp); - $result = $this->mkdir_helper($temp, $mode); + $result = $this->_mkdir_helper($temp, $mode); } return $result; } - return $this->mkdir_helper($dir, $mode); + return $this->_mkdir_helper($dir, $mode); } /** @@ -1747,22 +1819,25 @@ class SFTP extends SSH2 * @return bool * @access private */ - private function mkdir_helper($dir, $mode) + function _mkdir_helper($dir, $mode) { // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing) - if (!$this->send_sftp_packet(NET_SFTP_MKDIR, Strings::packSSH2('s', $dir) . "\0\0\0\0")) { + if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, "\0\0\0\0"))) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); + $this->_logError($response, $status); return false; } @@ -1777,43 +1852,45 @@ class SFTP extends SSH2 * Removes a directory. * * @param string $dir - * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool * @access public */ - public function rmdir($dir) + function rmdir($dir) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $dir = $this->realpath($dir); + $dir = $this->_realpath($dir); if ($dir === false) { return false; } - if (!$this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $dir))) { + if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($dir), $dir))) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED? - $this->logError($response, $status); + $this->_logError($response, $status); return false; } - $this->remove_from_stat_cache($dir); + $this->_remove_from_stat_cache($dir); // the following will do a soft delete, which would be useful if you deleted a file // and then tried to do a stat on the deleted file. the above, in contrast, does // a hard delete - //$this->update_stat_cache($dir, false); + //$this->_update_stat_cache($dir, false); return true; } @@ -1821,8 +1898,8 @@ class SFTP extends SSH2 /** * Uploads a file to the SFTP server. * - * By default, \phpseclib3\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. - * So, for example, if you set $data to 'filename.ext' and then do \phpseclib3\Net\SFTP::get(), you will get a file, twelve bytes + * By default, \phpseclib\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. + * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SFTP::get(), you will get a file, twelve bytes * long, containing 'filename.ext' as its contents. * * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will @@ -1853,31 +1930,29 @@ class SFTP extends SSH2 * * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE. * - * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().} - * * @param string $remote_file * @param string|resource $data * @param int $mode * @param int $start * @param int $local_start * @param callable|null $progressCallback - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid - * @throws \phpseclib3\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist * @return bool * @access public + * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode(). */ - public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) + function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $remote_file = $this->realpath($remote_file); + $remote_file = $this->_realpath($remote_file); if ($remote_file === false) { return false; } + $this->_remove_from_stat_cache($remote_file); + $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file." // in practice, it doesn't seem to do that. @@ -1887,31 +1962,29 @@ class SFTP extends SSH2 $offset = $start; } elseif ($mode & self::RESUME) { // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called - $size = $this->stat($remote_file)['size']; + $size = $this->size($remote_file); $offset = $size !== false ? $size : 0; } else { $offset = 0; $flags|= NET_SFTP_OPEN_TRUNCATE; } - $this->remove_from_stat_cache($remote_file); - - $packet = Strings::packSSH2('sNN', $remote_file, $flags, 0); - if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + $packet = pack('Na*N2', strlen($remote_file), $remote_file, $flags, 0); + if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: - $this->logError($response); + $this->_logError($response); return false; default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); + return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 @@ -1919,7 +1992,7 @@ class SFTP extends SSH2 switch (true) { case $mode & self::SOURCE_CALLBACK: if (!is_callable($data)) { - throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); + user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); } $dataCallback = $data; // do nothing @@ -1937,7 +2010,8 @@ class SFTP extends SSH2 break; case $mode & self::SOURCE_LOCAL_FILE: if (!is_file($data)) { - throw new FileNotFoundException("$data is not a valid file"); + user_error("$data is not a valid file"); + return false; } $fp = @fopen($data, 'rb'); if (!$fp) { @@ -1968,7 +2042,7 @@ class SFTP extends SSH2 $i = $j = 0; while ($dataCallback || ($size === 0 || $sent < $size)) { if ($dataCallback) { - $temp = $dataCallback($sftp_packet_size); + $temp = call_user_func($dataCallback, $sftp_packet_size); if (is_null($temp)) { break; } @@ -1981,7 +2055,7 @@ class SFTP extends SSH2 $subtemp = $offset + $sent; $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp); - if (!$this->send_sftp_packet(NET_SFTP_WRITE, $packet, $j)) { + if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet, $j)) { if ($mode & self::SOURCE_LOCAL_FILE) { fclose($fp); } @@ -1989,13 +2063,14 @@ class SFTP extends SSH2 } $sent+= strlen($temp); if (is_callable($progressCallback)) { - $progressCallback($sent); + call_user_func($progressCallback, $sent); } $i++; $j++; + if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { $i = 0; break; } @@ -2003,11 +2078,11 @@ class SFTP extends SSH2 } } - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { if ($mode & self::SOURCE_LOCAL_FILE) { fclose($fp); } - $this->close_handle($handle); + $this->_close_handle($handle); return false; } @@ -2022,7 +2097,7 @@ class SFTP extends SSH2 } } - return $this->close_handle($handle); + return $this->_close_handle($handle); } /** @@ -2033,21 +2108,23 @@ class SFTP extends SSH2 * * @param int $i * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets * @access private */ - private function read_put_responses($i) + function _read_put_responses($i) { while ($i--) { - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); + $this->_logError($response, $status); break; } } @@ -2060,26 +2137,28 @@ class SFTP extends SSH2 * * @param string $handle * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets * @access private */ - private function close_handle($handle) + function _close_handle($handle) { - if (!$this->send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) { + if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) { return false; } // "The client MUST release all resources associated with the handle regardless of the status." // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); + $this->_logError($response, $status); return false; } @@ -2096,41 +2175,40 @@ class SFTP extends SSH2 * $offset and $length can be used to download files in chunks. * * @param string $remote_file - * @param string|bool|resource $local_file + * @param string $local_file * @param int $offset * @param int $length * @param callable|null $progressCallback - * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed * @access public */ - public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) + function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $remote_file = $this->realpath($remote_file); + $remote_file = $this->_realpath($remote_file); if ($remote_file === false) { return false; } $packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_READ, 0); - if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - $this->logError($response); + $this->_logError($response); return false; default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); + return false; } if (is_resource($local_file)) { @@ -2161,8 +2239,8 @@ class SFTP extends SSH2 $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet; - $packet = Strings::packSSH2('sN3', $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); - if (!$this->send_sftp_packet(NET_SFTP_READ, $packet, $i)) { + $packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); + if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet, $i)) { if ($fclose_check) { fclose($fp); } @@ -2184,10 +2262,10 @@ class SFTP extends SSH2 $i--; if ($clear_responses) { - $this->get_sftp_packet($packets_sent - $i); + $this->_get_sftp_packet($packets_sent - $i); continue; } else { - $response = $this->get_sftp_packet($packets_sent - $i); + $response = $this->_get_sftp_packet($packets_sent - $i); } switch ($this->packet_type) { @@ -2208,15 +2286,14 @@ class SFTP extends SSH2 break; case NET_SFTP_STATUS: // could, in theory, return false if !strlen($content) but we'll hold off for the time being - $this->logError($response); + $this->_logError($response); $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses break; default: if ($fclose_check) { fclose($fp); } - throw new \UnexpectedValueException('Expected NET_SFTP_DATA or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS'); } $response = null; } @@ -2243,7 +2320,7 @@ class SFTP extends SSH2 } } - if (!$this->close_handle($handle)) { + if (!$this->_close_handle($handle)) { return false; } @@ -2257,10 +2334,9 @@ class SFTP extends SSH2 * @param string $path * @param bool $recursive * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets * @access public */ - public function delete($path, $recursive = true) + function delete($path, $recursive = true) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; @@ -2275,37 +2351,39 @@ class SFTP extends SSH2 return false; } - $path = $this->realpath($path); + $path = $this->_realpath($path); if ($path === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 - if (!$this->send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) { + if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); + $this->_logError($response, $status); if (!$recursive) { return false; } - $i = 0; - $result = $this->delete_recursive($path, $i); - $this->read_put_responses($i); + $result = $this->_delete_recursive($path, $i); + $this->_read_put_responses($i); return $result; } - $this->remove_from_stat_cache($path); + $this->_remove_from_stat_cache($path); return true; } @@ -2320,13 +2398,13 @@ class SFTP extends SSH2 * @return bool * @access private */ - private function delete_recursive($path, &$i) + function _delete_recursive($path, &$i) { - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { return false; } $i = 0; - $entries = $this->readlist($path, true); + $entries = $this->_list($path, true); // normally $entries would have at least . and .. but it might not if the directories // permissions didn't allow reading @@ -2342,19 +2420,19 @@ class SFTP extends SSH2 $temp = $path . '/' . $filename; if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { - if (!$this->delete_recursive($temp, $i)) { + if (!$this->_delete_recursive($temp, $i)) { return false; } } else { - if (!$this->send_sftp_packet(NET_SFTP_REMOVE, Strings::packSSH2('s', $temp))) { + if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($temp), $temp))) { return false; } - $this->remove_from_stat_cache($temp); + $this->_remove_from_stat_cache($temp); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { return false; } $i = 0; @@ -2362,15 +2440,15 @@ class SFTP extends SSH2 } } - if (!$this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $path))) { + if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($path), $path))) { return false; } - $this->remove_from_stat_cache($path); + $this->_remove_from_stat_cache($path); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { + if (!$this->_read_put_responses($i)) { return false; } $i = 0; @@ -2386,12 +2464,12 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function file_exists($path) + function file_exists($path) { if ($this->use_stat_cache) { - $path = $this->realpath($path); + $path = $this->_realpath($path); - $result = $this->query_stat_cache($path); + $result = $this->_query_stat_cache($path); if (isset($result)) { // return true if $result is an array or if it's an stdClass object @@ -2409,9 +2487,9 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function is_dir($path) + function is_dir($path) { - $result = $this->get_stat_cache_prop($path, 'type'); + $result = $this->_get_stat_cache_prop($path, 'type'); if ($result === false) { return false; } @@ -2425,9 +2503,9 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function is_file($path) + function is_file($path) { - $result = $this->get_stat_cache_prop($path, 'type'); + $result = $this->_get_stat_cache_prop($path, 'type'); if ($result === false) { return false; } @@ -2441,9 +2519,9 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function is_link($path) + function is_link($path) { - $result = $this->get_lstat_cache_prop($path, 'type'); + $result = $this->_get_lstat_cache_prop($path, 'type'); if ($result === false) { return false; } @@ -2457,22 +2535,24 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function is_readable($path) + function is_readable($path) { - $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_READ, 0); - if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + $path = $this->_realpath($path); + + $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_READ, 0); + if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: return true; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED return false; default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); + return false; } } @@ -2483,22 +2563,24 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function is_writable($path) + function is_writable($path) { - $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_WRITE, 0); - if (!$this->send_sftp_packet(NET_SFTP_OPEN, $packet)) { + $path = $this->_realpath($path); + + $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_WRITE, 0); + if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: return true; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED return false; default: - throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); + return false; } } @@ -2511,7 +2593,7 @@ class SFTP extends SSH2 * @return bool * @access public */ - public function is_writeable($path) + function is_writeable($path) { return $this->is_writable($path); } @@ -2523,9 +2605,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function fileatime($path) + function fileatime($path) { - return $this->get_stat_cache_prop($path, 'atime'); + return $this->_get_stat_cache_prop($path, 'atime'); } /** @@ -2535,9 +2617,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function filemtime($path) + function filemtime($path) { - return $this->get_stat_cache_prop($path, 'mtime'); + return $this->_get_stat_cache_prop($path, 'mtime'); } /** @@ -2547,9 +2629,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function fileperms($path) + function fileperms($path) { - return $this->get_stat_cache_prop($path, 'mode'); + return $this->_get_stat_cache_prop($path, 'permissions'); } /** @@ -2559,9 +2641,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function fileowner($path) + function fileowner($path) { - return $this->get_stat_cache_prop($path, 'uid'); + return $this->_get_stat_cache_prop($path, 'uid'); } /** @@ -2571,9 +2653,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function filegroup($path) + function filegroup($path) { - return $this->get_stat_cache_prop($path, 'gid'); + return $this->_get_stat_cache_prop($path, 'gid'); } /** @@ -2583,9 +2665,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function filesize($path) + function filesize($path) { - return $this->get_stat_cache_prop($path, 'size'); + return $this->_get_stat_cache_prop($path, 'size'); } /** @@ -2595,9 +2677,9 @@ class SFTP extends SSH2 * @return mixed * @access public */ - public function filetype($path) + function filetype($path) { - $type = $this->get_stat_cache_prop($path, 'type'); + $type = $this->_get_stat_cache_prop($path, 'type'); if ($type === false) { return false; } @@ -2630,9 +2712,9 @@ class SFTP extends SSH2 * @return mixed * @access private */ - private function get_stat_cache_prop($path, $prop) + function _get_stat_cache_prop($path, $prop) { - return $this->get_xstat_cache_prop($path, $prop, 'stat'); + return $this->_get_xstat_cache_prop($path, $prop, 'stat'); } /** @@ -2645,9 +2727,9 @@ class SFTP extends SSH2 * @return mixed * @access private */ - private function get_lstat_cache_prop($path, $prop) + function _get_lstat_cache_prop($path, $prop) { - return $this->get_xstat_cache_prop($path, $prop, 'lstat'); + return $this->_get_xstat_cache_prop($path, $prop, 'lstat'); } /** @@ -2657,16 +2739,16 @@ class SFTP extends SSH2 * * @param string $path * @param string $prop - * @param string $type + * @param mixed $type * @return mixed * @access private */ - private function get_xstat_cache_prop($path, $prop, $type) + function _get_xstat_cache_prop($path, $prop, $type) { if ($this->use_stat_cache) { - $path = $this->realpath($path); + $path = $this->_realpath($path); - $result = $this->query_stat_cache($path); + $result = $this->_query_stat_cache($path); if (is_object($result) && isset($result->$type)) { return $result->{$type}[$prop]; @@ -2688,45 +2770,47 @@ class SFTP extends SSH2 * @param string $oldname * @param string $newname * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets * @access public */ - public function rename($oldname, $newname) + function rename($oldname, $newname) { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } - $oldname = $this->realpath($oldname); - $newname = $this->realpath($newname); + $oldname = $this->_realpath($oldname); + $newname = $this->_realpath($newname); if ($oldname === false || $newname === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 - $packet = Strings::packSSH2('ss', $oldname, $newname); - if (!$this->send_sftp_packet(NET_SFTP_RENAME, $packet)) { + $packet = pack('Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname); + if (!$this->_send_sftp_packet(NET_SFTP_RENAME, $packet)) { return false; } - $response = $this->get_sftp_packet(); + $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); + user_error('Expected SSH_FXP_STATUS'); + return false; } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - list($status) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); + $this->_logError($response, $status); return false; } // don't move the stat cache entry over since this operation could very well change the // atime and mtime attributes - //$this->update_stat_cache($newname, $this->query_stat_cache($oldname)); - $this->remove_from_stat_cache($oldname); - $this->remove_from_stat_cache($newname); + //$this->_update_stat_cache($newname, $this->_query_stat_cache($oldname)); + $this->_remove_from_stat_cache($oldname); + $this->_remove_from_stat_cache($newname); return true; } @@ -2740,11 +2824,14 @@ class SFTP extends SSH2 * @return array * @access private */ - protected function parseAttributes(&$response) + function _parseAttributes(&$response) { - $attr = []; - list($flags) = Strings::unpackSSH2('N', $response); - + $attr = array(); + if (strlen($response) < 4) { + user_error('Malformed file attributes'); + return array(); + } + extract(unpack('Nflags', $this->_string_shift($response, 4))); // SFTPv4+ have a type field (a byte) that follows the above flag field foreach ($this->attributes as $key => $value) { switch ($flags & $key) { @@ -2755,28 +2842,55 @@ class SFTP extends SSH2 // IEEE 754 binary64 "double precision" on such platforms and // as such can represent integers of at least 2^50 without loss // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB. - list($upper, $size) = Strings::unpackSSH2('NN', $response); - $attr['size'] = $upper ? 4294967296 * $upper : 0; - $attr['size']+= $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; + $attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8))); break; case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) - list($attr['uid'], $attr['gid']) = Strings::unpackSSH2('NN', $response); + if (strlen($response) < 8) { + user_error('Malformed file attributes'); + return $attr; + } + $attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8)); break; case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 - list($attr['mode']) = Strings::unpackSSH2('N', $response); - $fileType = $this->parseMode($attr['mode']); + if (strlen($response) < 4) { + user_error('Malformed file attributes'); + return $attr; + } + $attr+= unpack('Npermissions', $this->_string_shift($response, 4)); + // mode == permissions; permissions was the original array key and is retained for bc purposes. + // mode was added because that's the more industry standard terminology + $attr+= array('mode' => $attr['permissions']); + $fileType = $this->_parseMode($attr['permissions']); if ($fileType !== false) { - $attr+= ['type' => $fileType]; + $attr+= array('type' => $fileType); } break; case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 - list($attr['atime'], $attr['mtime']) = Strings::unpackSSH2('NN', $response); + if (strlen($response) < 8) { + user_error('Malformed file attributes'); + return $attr; + } + $attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8)); break; case NET_SFTP_ATTR_EXTENDED: // 0x80000000 - list($count) = Strings::unpackSSH2('N', $response); + if (strlen($response) < 4) { + user_error('Malformed file attributes'); + return $attr; + } + extract(unpack('Ncount', $this->_string_shift($response, 4))); for ($i = 0; $i < $count; $i++) { - list($key, $value) = Strings::unpackSSH2('ss', $response); - $attr[$key] = $value; + if (strlen($response) < 4) { + user_error('Malformed file attributes'); + return $attr; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $key = $this->_string_shift($response, $length); + if (strlen($response) < 4) { + user_error('Malformed file attributes'); + return $attr; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $attr[$key] = $this->_string_shift($response, $length); } } } @@ -2792,7 +2906,7 @@ class SFTP extends SSH2 * @return int * @access private */ - private function parseMode($mode) + function _parseMode($mode) { // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12 // see, also, http://linux.die.net/man/2/stat @@ -2839,7 +2953,7 @@ class SFTP extends SSH2 * @return mixed * @access private */ - private function parseLongname($longname) + function _parseLongname($longname) { // http://en.wikipedia.org/wiki/Unix_file_types // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions @@ -2868,11 +2982,11 @@ class SFTP extends SSH2 * @param string $data * @param int $request_id * @see self::_get_sftp_packet() - * @see self::send_channel_packet() + * @see self::_send_channel_packet() * @return bool * @access private */ - private function send_sftp_packet($type, $data, $request_id = 1) + function _send_sftp_packet($type, $data, $request_id = 1) { // in SSH2.php the timeout is cumulative per function call. eg. exec() will // timeout after 10s. but for SFTP.php it's cumulative per packet @@ -2882,25 +2996,17 @@ class SFTP extends SSH2 pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : pack('NCa*', strlen($data) + 1, $type, $data); - $start = microtime(true); - $result = $this->send_channel_packet(self::CHANNEL, $packet); - $stop = microtime(true); + $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + $result = $this->_send_channel_packet(self::CHANNEL, $packet); + $stop = strtok(microtime(), ' ') + strtok(''); if (defined('NET_SFTP_LOGGING')) { $packet_type = '-> ' . $this->packet_types[$type] . ' (' . round($stop - $start, 4) . 's)'; if (NET_SFTP_LOGGING == self::LOG_REALTIME) { - switch (PHP_SAPI) { - case 'cli': - $start = $stop = "\r\n"; - break; - default: - $start = '
      ';
      -                        $stop = '
      '; - } - echo $start . $this->format_log([$data], [$packet_type]) . $stop; - @flush(); - @ob_flush(); + echo "
      \r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n
      \r\n"; + flush(); + ob_flush(); } else { $this->packet_type_log[] = $packet_type; if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { @@ -2918,12 +3024,12 @@ class SFTP extends SSH2 * @param int $reason * @access private */ - protected function reset_connection($reason) + function _reset_connection($reason) { - parent::reset_connection($reason); + parent::_reset_connection($reason); $this->use_request_id = false; $this->pwd = false; - $this->requestBuffer = []; + $this->requestBuffer = array(); } /** @@ -2939,7 +3045,7 @@ class SFTP extends SSH2 * @return string * @access private */ - private function get_sftp_packet($request_id = null) + function _get_sftp_packet($request_id = null) { if (isset($request_id) && isset($this->requestBuffer[$request_id])) { $this->packet_type = $this->requestBuffer[$request_id]['packet_type']; @@ -2952,11 +3058,11 @@ class SFTP extends SSH2 // timeout after 10s. but for SFTP.php it's cumulative per packet $this->curTimeout = $this->timeout; - $start = microtime(true); + $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 // SFTP packet length while (strlen($this->packet_buffer) < 4) { - $temp = $this->get_channel_packet(self::CHANNEL, true); + $temp = $this->_get_channel_packet(self::CHANNEL, true); if (is_bool($temp)) { $this->packet_type = false; $this->packet_buffer = ''; @@ -2967,21 +3073,20 @@ class SFTP extends SSH2 if (strlen($this->packet_buffer) < 4) { return false; } - extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4))); - /** @var integer $length */ - + extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4))); $tempLength = $length; $tempLength-= strlen($this->packet_buffer); // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h if ($tempLength > 256 * 1024) { - throw new \RuntimeException('Invalid Size'); + user_error('Invalid SFTP packet size'); + return false; } // SFTP packet type and data payload while ($tempLength > 0) { - $temp = $this->get_channel_packet(self::CHANNEL, true); + $temp = $this->_get_channel_packet(self::CHANNEL, true); if (is_bool($temp)) { $this->packet_type = false; $this->packet_buffer = ''; @@ -2991,34 +3096,26 @@ class SFTP extends SSH2 $tempLength-= strlen($temp); } - $stop = microtime(true); + $stop = strtok(microtime(), ' ') + strtok(''); - $this->packet_type = ord(Strings::shift($this->packet_buffer)); + $this->packet_type = ord($this->_string_shift($this->packet_buffer)); if ($this->use_request_id) { - extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))); // remove the request id + extract(unpack('Npacket_id', $this->_string_shift($this->packet_buffer, 4))); // remove the request id $length-= 5; // account for the request id and the packet type } else { $length-= 1; // account for the packet type } - $packet = Strings::shift($this->packet_buffer, $length); + $packet = $this->_string_shift($this->packet_buffer, $length); if (defined('NET_SFTP_LOGGING')) { $packet_type = '<- ' . $this->packet_types[$this->packet_type] . ' (' . round($stop - $start, 4) . 's)'; if (NET_SFTP_LOGGING == self::LOG_REALTIME) { - switch (PHP_SAPI) { - case 'cli': - $start = $stop = "\r\n"; - break; - default: - $start = '
      ';
      -                        $stop = '
      '; - } - echo $start . $this->format_log([$packet], [$packet_type]) . $stop; - @flush(); - @ob_flush(); + echo "
      \r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n
      \r\n"; + flush(); + ob_flush(); } else { $this->packet_type_log[] = $packet_type; if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { @@ -3032,7 +3129,7 @@ class SFTP extends SSH2 'packet_type' => $this->packet_type, 'packet' => $packet ); - return $this->get_sftp_packet($request_id); + return $this->_get_sftp_packet($request_id); } return $packet; @@ -3041,12 +3138,12 @@ class SFTP extends SSH2 /** * Returns a log of the packets that have been sent and received. * - * Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') + * Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') * * @access public - * @return array|string + * @return string or Array */ - public function getSFTPLog() + function getSFTPLog() { if (!defined('NET_SFTP_LOGGING')) { return false; @@ -3054,7 +3151,7 @@ class SFTP extends SSH2 switch (NET_SFTP_LOGGING) { case self::LOG_COMPLEX: - return $this->format_log($this->packet_log, $this->packet_type_log); + return $this->_format_log($this->packet_log, $this->packet_type_log); break; //case self::LOG_SIMPLE: default: @@ -3068,7 +3165,7 @@ class SFTP extends SSH2 * @return array * @access public */ - public function getSFTPErrors() + function getSFTPErrors() { return $this->sftp_errors; } @@ -3079,7 +3176,7 @@ class SFTP extends SSH2 * @return string * @access public */ - public function getLastSFTPError() + function getLastSFTPError() { return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : ''; } @@ -3090,9 +3187,9 @@ class SFTP extends SSH2 * @return array * @access public */ - public function getSupportedVersions() + function getSupportedVersions() { - $temp = ['version' => $this->version]; + $temp = array('version' => $this->version); if (isset($this->extensions['versions'])) { $temp['extensions'] = $this->extensions['versions']; } @@ -3104,12 +3201,12 @@ class SFTP extends SSH2 * * @param int $reason * @return bool - * @access protected + * @access private */ - protected function disconnect_helper($reason) + function _disconnect($reason) { $this->pwd = false; - parent::disconnect_helper($reason); + parent::_disconnect($reason); } /** diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php index 89a0e59b2..1a44b10a0 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php @@ -15,11 +15,10 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Net\SFTP; +namespace phpseclib\Net\SFTP; -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Net\SFTP; -use phpseclib3\Net\SSH2; +use phpseclib\Crypt\RSA; +use phpseclib\Net\SFTP; /** * SFTP Stream Wrapper @@ -28,7 +27,7 @@ use phpseclib3\Net\SSH2; * @author Jim Wigginton * @access public */ -class Stream extends SFTP +class Stream { /** * SFTP instances @@ -45,7 +44,7 @@ class Stream extends SFTP * @var object * @access private */ - private $sftp; + var $sftp; /** * Path @@ -53,7 +52,7 @@ class Stream extends SFTP * @var string * @access private */ - private $path; + var $path; /** * Mode @@ -61,7 +60,7 @@ class Stream extends SFTP * @var string * @access private */ - private $mode; + var $mode; /** * Position @@ -69,7 +68,7 @@ class Stream extends SFTP * @var int * @access private */ - private $pos; + var $pos; /** * Size @@ -77,7 +76,7 @@ class Stream extends SFTP * @var int * @access private */ - private $size; + var $size; /** * Directory entries @@ -85,7 +84,7 @@ class Stream extends SFTP * @var array * @access private */ - private $entries; + var $entries; /** * EOF flag @@ -93,17 +92,17 @@ class Stream extends SFTP * @var bool * @access private */ - private $eof; + var $eof; /** * Context resource * - * Technically this needs to be publicly accessible so PHP can set it directly + * Technically this needs to be publically accessible so PHP can set it directly * * @var resource * @access public */ - public $context; + var $context; /** * Notification callback function @@ -111,7 +110,7 @@ class Stream extends SFTP * @var callable * @access public */ - private $notification; + var $notification; /** * Registers this class as a URL wrapper. @@ -120,7 +119,7 @@ class Stream extends SFTP * @return bool True on success, false otherwise. * @access public */ - public static function register($protocol = 'sftp') + static function register($protocol = 'sftp') { if (in_array($protocol, stream_get_wrappers(), true)) { return false; @@ -133,7 +132,7 @@ class Stream extends SFTP * * @access public */ - public function __construct() + function __construct() { if (defined('NET_SFTP_STREAM_LOGGING')) { echo "__construct()\r\n"; @@ -152,10 +151,10 @@ class Stream extends SFTP * @return string * @access private */ - protected function parse_path($path) + function _parse_path($path) { $orig = $path; - extract(parse_url($path) + ['port' => 22]); + extract(parse_url($path) + array('port' => 22)); if (isset($query)) { $path.= '?' . $query; } elseif (preg_match('/(\?|\?#)$/', $orig)) { @@ -178,12 +177,13 @@ class Stream extends SFTP } } - if (preg_match('/^{[a-z0-9]+}$/i', $host)) { - $host = SSH2::getConnectionByResourceId($host); - if ($host === false) { + if ($host[0] == '$') { + $host = substr($host, 1); + global ${$host}; + if (($$host instanceof SFTP) === false) { return false; } - $this->sftp = $host; + $this->sftp = $$host; } else { if (isset($this->context)) { $context = stream_context_get_options($this->context); @@ -204,7 +204,7 @@ class Stream extends SFTP if (isset($context[$scheme]['password'])) { $pass = $context[$scheme]['password']; } - if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof PrivateKey) { + if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof RSA) { $pass = $context[$scheme]['privkey']; } @@ -212,7 +212,7 @@ class Stream extends SFTP return false; } - // casting $pass to a string is necessary in the event that it's a \phpseclib3\Crypt\RSA object + // casting $pass to a string is necessary in the event that it's a \phpseclib\Crypt\RSA object if (isset(self::$instances[$host][$port][$user][(string) $pass])) { $this->sftp = self::$instances[$host][$port][$user][(string) $pass]; } else { @@ -257,16 +257,16 @@ class Stream extends SFTP * @return bool * @access public */ - private function _stream_open($path, $mode, $options, &$opened_path) + function _stream_open($path, $mode, $options, &$opened_path) { - $path = $this->parse_path($path); + $path = $this->_parse_path($path); if ($path === false) { return false; } $this->path = $path; - $this->size = $this->sftp->filesize($path); + $this->size = $this->sftp->size($path); $this->mode = preg_replace('#[bt]$#', '', $mode); $this->eof = false; @@ -299,7 +299,7 @@ class Stream extends SFTP * @return mixed * @access public */ - private function _stream_read($count) + function _stream_read($count) { switch ($this->mode) { case 'w': @@ -341,7 +341,7 @@ class Stream extends SFTP * @return mixed * @access public */ - private function _stream_write($data) + function _stream_write($data) { switch ($this->mode) { case 'r': @@ -375,7 +375,7 @@ class Stream extends SFTP * @return int * @access public */ - private function _stream_tell() + function _stream_tell() { return $this->pos; } @@ -393,7 +393,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _stream_eof() + function _stream_eof() { return $this->eof; } @@ -406,7 +406,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _stream_seek($offset, $whence) + function _stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: @@ -435,9 +435,9 @@ class Stream extends SFTP * @return bool * @access public */ - private function _stream_metadata($path, $option, $var) + function _stream_metadata($path, $option, $var) { - $path = $this->parse_path($path); + $path = $this->_parse_path($path); if ($path === false) { return false; } @@ -467,7 +467,7 @@ class Stream extends SFTP * @return resource * @access public */ - private function _stream_cast($cast_as) + function _stream_cast($cast_as) { return $this->sftp->fsock; } @@ -479,7 +479,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _stream_lock($operation) + function _stream_lock($operation) { return false; } @@ -488,7 +488,7 @@ class Stream extends SFTP * Renames a file or directory * * Attempts to rename oldname to newname, moving it between directories if necessary. - * If newname exists, it will be overwritten. This is a departure from what \phpseclib3\Net\SFTP + * If newname exists, it will be overwritten. This is a departure from what \phpseclib\Net\SFTP * does. * * @param string $path_from @@ -496,7 +496,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _rename($path_from, $path_to) + function _rename($path_from, $path_to) { $path1 = parse_url($path_from); $path2 = parse_url($path_to); @@ -505,7 +505,7 @@ class Stream extends SFTP return false; } - $path_from = $this->parse_path($path_from); + $path_from = $this->_parse_path($path_from); $path_to = parse_url($path_to); if ($path_from === false) { return false; @@ -548,9 +548,9 @@ class Stream extends SFTP * @return bool * @access public */ - private function _dir_opendir($path, $options) + function _dir_opendir($path, $options) { - $path = $this->parse_path($path); + $path = $this->_parse_path($path); if ($path === false) { return false; } @@ -565,7 +565,7 @@ class Stream extends SFTP * @return mixed * @access public */ - private function _dir_readdir() + function _dir_readdir() { if (isset($this->entries[$this->pos])) { return $this->entries[$this->pos++]; @@ -579,7 +579,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _dir_rewinddir() + function _dir_rewinddir() { $this->pos = 0; return true; @@ -591,7 +591,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _dir_closedir() + function _dir_closedir() { return true; } @@ -607,9 +607,9 @@ class Stream extends SFTP * @return bool * @access public */ - private function _mkdir($path, $mode, $options) + function _mkdir($path, $mode, $options) { - $path = $this->parse_path($path); + $path = $this->_parse_path($path); if ($path === false) { return false; } @@ -630,9 +630,9 @@ class Stream extends SFTP * @return bool * @access public */ - private function _rmdir($path, $options) + function _rmdir($path, $options) { - $path = $this->parse_path($path); + $path = $this->_parse_path($path); if ($path === false) { return false; } @@ -643,12 +643,12 @@ class Stream extends SFTP /** * Flushes the output * - * See . Always returns true because \phpseclib3\Net\SFTP doesn't cache stuff before writing + * See . Always returns true because \phpseclib\Net\SFTP doesn't cache stuff before writing * * @return bool * @access public */ - private function _stream_flush() + function _stream_flush() { return true; } @@ -659,7 +659,7 @@ class Stream extends SFTP * @return mixed * @access public */ - private function _stream_stat() + function _stream_stat() { $results = $this->sftp->stat($this->path); if ($results === false) { @@ -675,9 +675,9 @@ class Stream extends SFTP * @return bool * @access public */ - private function _unlink($path) + function _unlink($path) { - $path = $this->parse_path($path); + $path = $this->_parse_path($path); if ($path === false) { return false; } @@ -688,7 +688,7 @@ class Stream extends SFTP /** * Retrieve information about a file * - * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib3\Net\SFTP\Stream is quiet by default + * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib\Net\SFTP\Stream is quiet by default * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll * cross that bridge when and if it's reached * @@ -697,9 +697,9 @@ class Stream extends SFTP * @return mixed * @access public */ - private function _url_stat($path, $flags) + function _url_stat($path, $flags) { - $path = $this->parse_path($path); + $path = $this->_parse_path($path); if ($path === false) { return false; } @@ -719,7 +719,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _stream_truncate($new_size) + function _stream_truncate($new_size) { if (!$this->sftp->truncate($this->path, $new_size)) { return false; @@ -735,7 +735,7 @@ class Stream extends SFTP * Change stream options * * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't. - * The other two aren't supported because of limitations in \phpseclib3\Net\SFTP. + * The other two aren't supported because of limitations in \phpseclib\Net\SFTP. * * @param int $option * @param int $arg1 @@ -743,7 +743,7 @@ class Stream extends SFTP * @return bool * @access public */ - private function _stream_set_option($option, $arg1, $arg2) + function _stream_set_option($option, $arg1, $arg2) { return false; } @@ -753,7 +753,7 @@ class Stream extends SFTP * * @access public */ - private function _stream_close() + function _stream_close() { } @@ -772,7 +772,7 @@ class Stream extends SFTP * @return mixed * @access public */ - public function __call($name, $arguments) + function __call($name, $arguments) { if (defined('NET_SFTP_STREAM_LOGGING')) { echo $name . '('; @@ -789,6 +789,6 @@ class Stream extends SFTP if (!method_exists($this, $name)) { return false; } - return $this->$name(...$arguments); + return call_user_func_array(array($this, $name), $arguments); } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php index 8ad3dcc36..e2571190b 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php @@ -10,7 +10,7 @@ * login('username', 'password')) { * exit('Login Failed'); * } @@ -24,9 +24,11 @@ * setPassword('whatever'); + * $key->loadKey(file_get_contents('privatekey')); * - * $ssh = new \phpseclib3\Net\SSH2('www.domain.tld'); + * $ssh = new \phpseclib\Net\SSH2('www.domain.tld'); * if (!$ssh->login('username', $key)) { * exit('Login Failed'); * } @@ -45,31 +47,19 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib3\Net; - -use phpseclib3\Crypt\Blowfish; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\RC4; -use phpseclib3\Crypt\Rijndael; -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\DH; -use phpseclib3\Crypt\TripleDES; -use phpseclib3\Crypt\Twofish; -use phpseclib3\Crypt\ChaCha20; -use phpseclib3\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. -use phpseclib3\System\SSH\Agent; -use phpseclib3\System\SSH\Agent\Identity as AgentIdentity; -use phpseclib3\Exception\NoSupportedAlgorithmsException; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Exception\ConnectionClosedException; -use phpseclib3\Exception\UnableToConnectException; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Common\Functions\Strings; +namespace phpseclib\Net; + +use phpseclib\Crypt\Base; +use phpseclib\Crypt\Blowfish; +use phpseclib\Crypt\Hash; +use phpseclib\Crypt\Random; +use phpseclib\Crypt\RC4; +use phpseclib\Crypt\Rijndael; +use phpseclib\Crypt\RSA; +use phpseclib\Crypt\TripleDES; +use phpseclib\Crypt\Twofish; +use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. +use phpseclib\System\SSH\Agent; /** * Pure-PHP implementation of SSHv2. @@ -80,84 +70,79 @@ use phpseclib3\Common\Functions\Strings; */ class SSH2 { - // Execution Bitmap Masks + /**#@+ + * Execution Bitmap Masks + * + * @see \phpseclib\Net\SSH2::bitmap + * @access private + */ const MASK_CONSTRUCTOR = 0x00000001; const MASK_CONNECTED = 0x00000002; const MASK_LOGIN_REQ = 0x00000004; const MASK_LOGIN = 0x00000008; const MASK_SHELL = 0x00000010; const MASK_WINDOW_ADJUST = 0x00000020; + /**#@-*/ - /* + /**#@+ * Channel constants * * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a - * recipient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel - * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snippet: + * recepient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel + * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snipet: * The 'recipient channel' is the channel number given in the original * open request, and 'sender channel' is the channel number allocated by * the other side. * - * @see \phpseclib3\Net\SSH2::send_channel_packet() - * @see \phpseclib3\Net\SSH2::get_channel_packet() + * @see \phpseclib\Net\SSH2::_send_channel_packet() + * @see \phpseclib\Net\SSH2::_get_channel_packet() * @access private - */ + */ const CHANNEL_EXEC = 1; // PuTTy uses 0x100 const CHANNEL_SHELL = 2; const CHANNEL_SUBSYSTEM = 3; const CHANNEL_AGENT_FORWARD = 4; const CHANNEL_KEEP_ALIVE = 5; + /**#@-*/ + /**#@+ + * @access public + * @see \phpseclib\Net\SSH2::getLog() + */ /** * Returns the message numbers - * - * @access public - * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_SIMPLE = 1; /** * Returns the message content - * - * @access public - * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_COMPLEX = 2; /** * Outputs the content real-time - * - * @access public - * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_REALTIME = 3; /** * Dumps the content real-time to a file - * - * @access public - * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_REALTIME_FILE = 4; /** * Make sure that the log never gets larger than this - * - * @access public - * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_MAX_SIZE = 1048576; // 1024 * 1024 + /**#@-*/ + /**#@+ + * @access public + * @see \phpseclib\Net\SSH2::read() + */ /** * Returns when a string matching $expect exactly is found - * - * @access public - * @see \phpseclib3\Net\SSH2::read() */ const READ_SIMPLE = 1; /** * Returns when a string matching the regular expression $expect is found - * - * @access public - * @see \phpseclib3\Net\SSH2::read() */ const READ_REGEX = 2; /** @@ -165,11 +150,9 @@ class SSH2 * * Some data packets may only contain a single character so it may be necessary * to call read() multiple times when using this option - * - * @access public - * @see \phpseclib3\Net\SSH2::read() */ const READ_NEXT = 3; + /**#@-*/ /** * The SSH identifier @@ -177,7 +160,7 @@ class SSH2 * @var string * @access private */ - private $identifier; + var $identifier; /** * The Socket Object @@ -185,7 +168,7 @@ class SSH2 * @var object * @access private */ - protected $fsock; + var $fsock; /** * Execution Bitmap @@ -196,17 +179,17 @@ class SSH2 * @var int * @access private */ - protected $bitmap = 0; + var $bitmap = 0; /** * Error information * * @see self::getErrors() * @see self::getLastError() - * @var array + * @var string * @access private */ - private $errors = []; + var $errors = array(); /** * Server Identifier @@ -215,7 +198,7 @@ class SSH2 * @var array|false * @access private */ - private $server_identifier = false; + var $server_identifier = false; /** * Key Exchange Algorithms @@ -224,7 +207,7 @@ class SSH2 * @var array|false * @access private */ - private $kex_algorithms = false; + var $kex_algorithms = false; /** * Key Exchange Algorithm @@ -233,7 +216,7 @@ class SSH2 * @var string|false * @access private */ - private $kex_algorithm = false; + var $kex_algorithm = false; /** * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods @@ -242,7 +225,7 @@ class SSH2 * @var int * @access private */ - private $kex_dh_group_size_min = 1536; + var $kex_dh_group_size_min = 1536; /** * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods @@ -251,7 +234,7 @@ class SSH2 * @var int * @access private */ - private $kex_dh_group_size_preferred = 2048; + var $kex_dh_group_size_preferred = 2048; /** * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods @@ -260,7 +243,7 @@ class SSH2 * @var int * @access private */ - private $kex_dh_group_size_max = 4096; + var $kex_dh_group_size_max = 4096; /** * Server Host Key Algorithms @@ -269,7 +252,7 @@ class SSH2 * @var array|false * @access private */ - private $server_host_key_algorithms = false; + var $server_host_key_algorithms = false; /** * Encryption Algorithms: Client to Server @@ -278,7 +261,7 @@ class SSH2 * @var array|false * @access private */ - private $encryption_algorithms_client_to_server = false; + var $encryption_algorithms_client_to_server = false; /** * Encryption Algorithms: Server to Client @@ -287,7 +270,7 @@ class SSH2 * @var array|false * @access private */ - private $encryption_algorithms_server_to_client = false; + var $encryption_algorithms_server_to_client = false; /** * MAC Algorithms: Client to Server @@ -296,7 +279,7 @@ class SSH2 * @var array|false * @access private */ - private $mac_algorithms_client_to_server = false; + var $mac_algorithms_client_to_server = false; /** * MAC Algorithms: Server to Client @@ -305,7 +288,7 @@ class SSH2 * @var array|false * @access private */ - private $mac_algorithms_server_to_client = false; + var $mac_algorithms_server_to_client = false; /** * Compression Algorithms: Client to Server @@ -314,7 +297,7 @@ class SSH2 * @var array|false * @access private */ - private $compression_algorithms_client_to_server = false; + var $compression_algorithms_client_to_server = false; /** * Compression Algorithms: Server to Client @@ -323,7 +306,7 @@ class SSH2 * @var array|false * @access private */ - private $compression_algorithms_server_to_client = false; + var $compression_algorithms_server_to_client = false; /** * Languages: Server to Client @@ -332,7 +315,7 @@ class SSH2 * @var array|false * @access private */ - private $languages_server_to_client = false; + var $languages_server_to_client = false; /** * Languages: Client to Server @@ -341,7 +324,7 @@ class SSH2 * @var array|false * @access private */ - private $languages_client_to_server = false; + var $languages_client_to_server = false; /** * Preferred Algorithms @@ -350,7 +333,7 @@ class SSH2 * @var array * @access private */ - private $preferred = []; + var $preferred = array(); /** * Block Size for Server to Client Encryption @@ -367,7 +350,7 @@ class SSH2 * @var int * @access private */ - private $encrypt_block_size = 8; + var $encrypt_block_size = 8; /** * Block Size for Client to Server Encryption @@ -377,7 +360,7 @@ class SSH2 * @var int * @access private */ - private $decrypt_block_size = 8; + var $decrypt_block_size = 8; /** * Server to Client Encryption Object @@ -386,16 +369,7 @@ class SSH2 * @var object * @access private */ - private $decrypt = false; - - /** - * Server to Client Length Encryption Object - * - * @see self::_get_binary_packet() - * @var object - * @access private - */ - private $lengthDecrypt = false; + var $decrypt = false; /** * Client to Server Encryption Object @@ -404,16 +378,7 @@ class SSH2 * @var object * @access private */ - private $encrypt = false; - - /** - * Client to Server Length Encryption Object - * - * @see self::_send_binary_packet() - * @var object - * @access private - */ - private $lengthEncrypt = false; + var $encrypt = false; /** * Client to Server HMAC Object @@ -422,7 +387,7 @@ class SSH2 * @var object * @access private */ - private $hmac_create = false; + var $hmac_create = false; /** * Server to Client HMAC Object @@ -431,7 +396,7 @@ class SSH2 * @var object * @access private */ - private $hmac_check = false; + var $hmac_check = false; /** * Size of server to client HMAC @@ -444,7 +409,7 @@ class SSH2 * @var int * @access private */ - private $hmac_size = false; + var $hmac_size = false; /** * Server Public Host Key @@ -453,7 +418,7 @@ class SSH2 * @var string * @access private */ - private $server_public_host_key; + var $server_public_host_key; /** * Session identifier @@ -468,7 +433,7 @@ class SSH2 * @var string * @access private */ - private $session_id = false; + var $session_id = false; /** * Exchange hash @@ -479,7 +444,7 @@ class SSH2 * @var string * @access private */ - private $exchange_hash = false; + var $exchange_hash = false; /** * Message Numbers @@ -488,7 +453,7 @@ class SSH2 * @var array * @access private */ - private $message_numbers = []; + var $message_numbers = array(); /** * Disconnection Message 'reason codes' defined in RFC4253 @@ -497,7 +462,7 @@ class SSH2 * @var array * @access private */ - private $disconnect_reasons = []; + var $disconnect_reasons = array(); /** * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 @@ -506,7 +471,7 @@ class SSH2 * @var array * @access private */ - private $channel_open_failure_reasons = []; + var $channel_open_failure_reasons = array(); /** * Terminal Modes @@ -516,7 +481,7 @@ class SSH2 * @var array * @access private */ - private $terminal_modes = []; + var $terminal_modes = array(); /** * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes @@ -526,7 +491,7 @@ class SSH2 * @var array * @access private */ - private $channel_extended_data_type_codes = []; + var $channel_extended_data_type_codes = array(); /** * Send Sequence Number @@ -537,7 +502,7 @@ class SSH2 * @var int * @access private */ - private $send_seq_no = 0; + var $send_seq_no = 0; /** * Get Sequence Number @@ -548,19 +513,19 @@ class SSH2 * @var int * @access private */ - private $get_seq_no = 0; + var $get_seq_no = 0; /** * Server Channels * * Maps client channels to server channels * - * @see self::get_channel_packet() + * @see self::_get_channel_packet() * @see self::exec() * @var array * @access private */ - protected $server_channels = []; + var $server_channels = array(); /** * Channel Buffers @@ -568,34 +533,34 @@ class SSH2 * If a client requests a packet from one channel but receives two packets from another those packets should * be placed in a buffer * - * @see self::get_channel_packet() + * @see self::_get_channel_packet() * @see self::exec() * @var array * @access private */ - private $channel_buffers = []; + var $channel_buffers = array(); /** * Channel Status * * Contains the type of the last sent message * - * @see self::get_channel_packet() + * @see self::_get_channel_packet() * @var array * @access private */ - protected $channel_status = []; + var $channel_status = array(); /** * Packet Size * * Maximum packet size indexed by channel * - * @see self::send_channel_packet() + * @see self::_send_channel_packet() * @var array * @access private */ - private $packet_size_client_to_server = []; + var $packet_size_client_to_server = array(); /** * Message Number Log @@ -604,7 +569,7 @@ class SSH2 * @var array * @access private */ - private $message_number_log = []; + var $message_number_log = array(); /** * Message Log @@ -613,7 +578,7 @@ class SSH2 * @var array * @access private */ - private $message_log = []; + var $message_log = array(); /** * The Window Size @@ -621,11 +586,11 @@ class SSH2 * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB) * * @var int - * @see self::send_channel_packet() + * @see self::_send_channel_packet() * @see self::exec() * @access private */ - protected $window_size = 0x7FFFFFFF; + var $window_size = 0x7FFFFFFF; /** * What we resize the window to @@ -646,22 +611,22 @@ class SSH2 * * Window size indexed by channel * - * @see self::send_channel_packet() + * @see self::_send_channel_packet() * @var array * @access private */ - protected $window_size_server_to_client = []; + var $window_size_server_to_client = array(); /** * Window size, client to server * * Window size indexed by channel * - * @see self::get_channel_packet() + * @see self::_get_channel_packet() * @var array * @access private */ - private $window_size_client_to_server = []; + var $window_size_client_to_server = array(); /** * Server signature @@ -672,7 +637,7 @@ class SSH2 * @var string * @access private */ - private $signature = ''; + var $signature = ''; /** * Server signature format @@ -683,7 +648,7 @@ class SSH2 * @var string * @access private */ - private $signature_format = ''; + var $signature_format = ''; /** * Interactive Buffer @@ -692,7 +657,7 @@ class SSH2 * @var array * @access private */ - private $interactiveBuffer = ''; + var $interactiveBuffer = ''; /** * Current log size @@ -704,7 +669,7 @@ class SSH2 * @var int * @access private */ - private $log_size; + var $log_size; /** * Timeout @@ -712,15 +677,15 @@ class SSH2 * @see self::setTimeout() * @access private */ - protected $timeout; + var $timeout; /** * Current Timeout * - * @see self::get_channel_packet() + * @see self::_get_channel_packet() * @access private */ - protected $curTimeout; + var $curTimeout; /** * Keep Alive Interval @@ -737,7 +702,7 @@ class SSH2 * @var resource * @access private */ - private $realtime_log_file; + var $realtime_log_file; /** * Real-time log file size @@ -746,7 +711,7 @@ class SSH2 * @var int * @access private */ - private $realtime_log_size; + var $realtime_log_size; /** * Has the signature been validated? @@ -755,7 +720,7 @@ class SSH2 * @var bool * @access private */ - private $signature_validated = false; + var $signature_validated = false; /** * Real-time log file wrap boolean @@ -763,7 +728,7 @@ class SSH2 * @see self::_append_log() * @access private */ - private $realtime_log_wrap; + var $realtime_log_wrap; /** * Flag to suppress stderr from output @@ -771,7 +736,7 @@ class SSH2 * @see self::enableQuietMode() * @access private */ - private $quiet_mode = false; + var $quiet_mode = false; /** * Time of first network activity @@ -779,7 +744,7 @@ class SSH2 * @var int * @access private */ - private $last_packet; + var $last_packet; /** * Exit status returned from ssh if any @@ -787,7 +752,7 @@ class SSH2 * @var int * @access private */ - private $exit_status; + var $exit_status; /** * Flag to request a PTY when using exec() @@ -796,7 +761,7 @@ class SSH2 * @see self::enablePTY() * @access private */ - private $request_pty = false; + var $request_pty = false; /** * Flag set while exec() is running when using enablePTY() @@ -804,7 +769,7 @@ class SSH2 * @var bool * @access private */ - private $in_request_pty_exec = false; + var $in_request_pty_exec = false; /** * Flag set after startSubsystem() is called @@ -812,7 +777,7 @@ class SSH2 * @var bool * @access private */ - private $in_subsystem; + var $in_subsystem; /** * Contents of stdError @@ -820,7 +785,7 @@ class SSH2 * @var string * @access private */ - private $stdErrorLog; + var $stdErrorLog; /** * The Last Interactive Response @@ -829,7 +794,7 @@ class SSH2 * @var string * @access private */ - private $last_interactive_response = ''; + var $last_interactive_response = ''; /** * Keyboard Interactive Request / Responses @@ -838,7 +803,7 @@ class SSH2 * @var array * @access private */ - private $keyboard_requests_responses = []; + var $keyboard_requests_responses = array(); /** * Banner Message @@ -851,7 +816,7 @@ class SSH2 * @var string * @access private */ - private $banner_message = ''; + var $banner_message = ''; /** * Did read() timeout or return normally? @@ -860,7 +825,7 @@ class SSH2 * @var bool * @access private */ - private $is_timeout = false; + var $is_timeout = false; /** * Log Boundary @@ -869,7 +834,7 @@ class SSH2 * @var string * @access private */ - private $log_boundary = ':'; + var $log_boundary = ':'; /** * Log Long Width @@ -878,7 +843,7 @@ class SSH2 * @var int * @access private */ - private $log_long_width = 65; + var $log_long_width = 65; /** * Log Short Width @@ -887,7 +852,7 @@ class SSH2 * @var int * @access private */ - private $log_short_width = 16; + var $log_short_width = 16; /** * Hostname @@ -897,7 +862,7 @@ class SSH2 * @var string * @access private */ - private $host; + var $host; /** * Port Number @@ -907,7 +872,7 @@ class SSH2 * @var int * @access private */ - private $port; + var $port; /** * Number of columns for terminal window size @@ -918,7 +883,7 @@ class SSH2 * @var int * @access private */ - private $windowColumns = 80; + var $windowColumns = 80; /** * Number of columns for terminal window size @@ -929,7 +894,7 @@ class SSH2 * @var int * @access private */ - private $windowRows = 24; + var $windowRows = 24; /** * Crypto Engine @@ -939,23 +904,15 @@ class SSH2 * @var int * @access private */ - private static $crypto_engine = false; + var $crypto_engine = false; /** * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario * - * @var \phpseclib3\System\Ssh\Agent + * @var System_SSH_Agent * @access private */ - private $agent; - - /** - * Connection storage to replicates ssh2 extension functionality: - * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples} - * - * @var SSH2[] - */ - private static $connections; + var $agent; /** * Send the identification string first? @@ -963,7 +920,7 @@ class SSH2 * @var bool * @access private */ - private $send_id_string_first = true; + var $send_id_string_first = true; /** * Send the key exchange initiation packet first? @@ -971,7 +928,7 @@ class SSH2 * @var bool * @access private */ - private $send_kex_first = true; + var $send_kex_first = true; /** * Some versions of OpenSSH incorrectly calculate the key size @@ -979,7 +936,7 @@ class SSH2 * @var bool * @access private */ - private $bad_key_size_fix = false; + var $bad_key_size_fix = false; /** * Should we try to re-connect to re-establish keys? @@ -987,7 +944,7 @@ class SSH2 * @var bool * @access private */ - private $retry_connect = false; + var $retry_connect = false; /** * Binary Packet Buffer @@ -995,7 +952,7 @@ class SSH2 * @var string|false * @access private */ - private $binary_packet_buffer = false; + var $binary_packet_buffer = false; /** * Preferred Signature Format @@ -1003,7 +960,7 @@ class SSH2 * @var string|false * @access private */ - protected $preferred_signature_format = false; + var $preferred_signature_format = false; /** * Authentication Credentials @@ -1011,7 +968,7 @@ class SSH2 * @var array * @access private */ - protected $auth = []; + var $auth = array(); /** * Default Constructor. @@ -1022,12 +979,12 @@ class SSH2 * @param int $port * @param int $timeout * @see self::login() - * @return SSH2|void + * @return \phpseclib\Net\SSH2 * @access public */ - public function __construct($host, $port = 22, $timeout = 10) + function __construct($host, $port = 22, $timeout = 10) { - $this->message_numbers = [ + $this->message_numbers = array( 1 => 'NET_SSH2_MSG_DISCONNECT', 2 => 'NET_SSH2_MSG_IGNORE', 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', @@ -1057,8 +1014,8 @@ class SSH2 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' - ]; - $this->disconnect_reasons = [ + ); + $this->disconnect_reasons = array( 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', @@ -1074,40 +1031,38 @@ class SSH2 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' - ]; - $this->channel_open_failure_reasons = [ + ); + $this->channel_open_failure_reasons = array( 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' - ]; - $this->terminal_modes = [ + ); + $this->terminal_modes = array( 0 => 'NET_SSH2_TTY_OP_END' - ]; - $this->channel_extended_data_type_codes = [ + ); + $this->channel_extended_data_type_codes = array( 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' - ]; + ); - $this->define_array( + $this->_define_array( $this->message_numbers, $this->disconnect_reasons, $this->channel_open_failure_reasons, $this->terminal_modes, $this->channel_extended_data_type_codes, - [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], - [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], - [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', - 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], + array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'), + array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'), + array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', + 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'), // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} - [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', + array(30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', - 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], + 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'), // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) - [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', - 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] + array(30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', + 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY') ); - self::$connections[$this->getResourceId()] = $this; - if (is_resource($host)) { $this->fsock = $host; return; @@ -1124,14 +1079,14 @@ class SSH2 * Set Crypto Engine Mode * * Possible $engine values: - * OpenSSL, mcrypt, Eval, PHP + * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT * * @param int $engine * @access public */ - public static function setCryptoEngine($engine) + function setCryptoEngine($engine) { - self::$crypto_engine = $engine; + $this->crypto_engine = $engine; } /** @@ -1143,7 +1098,7 @@ class SSH2 * * @access public */ - public function sendIdentificationStringFirst() + function sendIdentificationStringFirst() { $this->send_id_string_first = true; } @@ -1157,7 +1112,7 @@ class SSH2 * * @access public */ - public function sendIdentificationStringLast() + function sendIdentificationStringLast() { $this->send_id_string_first = false; } @@ -1171,7 +1126,7 @@ class SSH2 * * @access public */ - public function sendKEXINITFirst() + function sendKEXINITFirst() { $this->send_kex_first = true; } @@ -1185,7 +1140,7 @@ class SSH2 * * @access public */ - public function sendKEXINITLast() + function sendKEXINITLast() { $this->send_kex_first = false; } @@ -1194,11 +1149,9 @@ class SSH2 * Connect to an SSHv2 server * * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors * @access private */ - private function connect() + function _connect() { if ($this->bitmap & self::MASK_CONSTRUCTOR) { return false; @@ -1218,7 +1171,8 @@ class SSH2 $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout); if (!$this->fsock) { $host = $this->host . ':' . $this->port; - throw new UnableToConnectException(rtrim("Cannot connect to $host. Error $errno. $errstr")); + user_error(rtrim("Cannot connect to $host. Error $errno. $errstr")); + return false; } $elapsed = microtime(true) - $start; @@ -1231,7 +1185,7 @@ class SSH2 } } - $this->identifier = $this->generate_identifier(); + $this->identifier = $this->_generate_identifier(); if ($this->send_id_string_first) { fputs($this->fsock, $this->identifier . "\r\n"); @@ -1253,12 +1207,14 @@ class SSH2 $this->is_timeout = true; return false; } - $read = [$this->fsock]; + $read = array($this->fsock); $write = $except = null; $start = microtime(true); $sec = floor($this->curTimeout); $usec = 1000000 * ($this->curTimeout - $sec); - if (@stream_select($read, $write, $except, $sec, $usec) === false) { + // on windows this returns a "Warning: Invalid CRT parameters detected" error + // the !count() is done as a workaround for + if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { $this->is_timeout = true; return false; } @@ -1294,14 +1250,15 @@ class SSH2 if (feof($this->fsock)) { $this->bitmap = 0; - throw new ConnectionClosedException('Connection closed by server'); + user_error('Connection closed by server'); + return false; } $extra = $matches[1]; if (defined('NET_SSH2_LOGGING')) { - $this->append_log('<-', $matches[0]); - $this->append_log('->', $this->identifier . "\r\n"); + $this->_append_log('<-', $matches[0]); + $this->_append_log('->', $this->identifier . "\r\n"); } $this->server_identifier = trim($temp, "\r\n"); @@ -1310,8 +1267,8 @@ class SSH2 } if (version_compare($matches[3], '1.99', '<')) { - $this->bitmap = 0; - throw new UnableToConnectException("Cannot connect to SSH $matches[3] servers"); + user_error("Cannot connect to SSH $matches[3] servers"); + return false; } if (!$this->send_id_string_first) { @@ -1319,23 +1276,24 @@ class SSH2 } if (!$this->send_kex_first) { - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { $this->bitmap = 0; - throw new ConnectionClosedException('Connection closed by server'); + user_error('Connection closed by server'); + return false; } if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) { - $this->bitmap = 0; - throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + user_error('Expected SSH_MSG_KEXINIT'); + return false; } - if (!$this->key_exchange($response)) { + if (!$this->_key_exchange($response)) { return false; } } - if ($this->send_kex_first && !$this->key_exchange()) { + if ($this->send_kex_first && !$this->_key_exchange()) { return false; } @@ -1352,12 +1310,12 @@ class SSH2 * @access protected * @return string */ - private function generate_identifier() + function _generate_identifier() { - $identifier = 'SSH-2.0-phpseclib_3.0'; + $identifier = 'SSH-2.0-phpseclib_2.0'; - $ext = []; - if (extension_loaded('sodium')) { + $ext = array(); + if (function_exists('sodium_crypto_box_publickey_from_secretkey')) { $ext[] = 'libsodium'; } @@ -1383,41 +1341,37 @@ class SSH2 /** * Key Exchange * - * @return bool - * @param string|bool $kexinit_payload_server optional - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors - * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible + * @param string $kexinit_payload_server optional * @access private */ - private function key_exchange($kexinit_payload_server = false) + function _key_exchange($kexinit_payload_server = false) { $preferred = $this->preferred; $kex_algorithms = isset($preferred['kex']) ? $preferred['kex'] : - SSH2::getSupportedKEXAlgorithms(); + $this->getSupportedKEXAlgorithms(); $server_host_key_algorithms = isset($preferred['hostkey']) ? $preferred['hostkey'] : - SSH2::getSupportedHostKeyAlgorithms(); + $this->getSupportedHostKeyAlgorithms(); $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ? $preferred['server_to_client']['crypt'] : - SSH2::getSupportedEncryptionAlgorithms(); + $this->getSupportedEncryptionAlgorithms(); $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ? $preferred['client_to_server']['crypt'] : - SSH2::getSupportedEncryptionAlgorithms(); + $this->getSupportedEncryptionAlgorithms(); $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ? $preferred['server_to_client']['mac'] : - SSH2::getSupportedMACAlgorithms(); + $this->getSupportedMACAlgorithms(); $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ? $preferred['client_to_server']['mac'] : - SSH2::getSupportedMACAlgorithms(); + $this->getSupportedMACAlgorithms(); $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ? $preferred['server_to_client']['comp'] : - SSH2::getSupportedCompressionAlgorithms(); + $this->getSupportedCompressionAlgorithms(); $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ? $preferred['client_to_server']['comp'] : - SSH2::getSupportedCompressionAlgorithms(); + $this->getSupportedCompressionAlgorithms(); // some SSH servers have buggy implementations of some of the above algorithms switch (true) { @@ -1426,166 +1380,209 @@ class SSH2 if (!isset($preferred['server_to_client']['mac'])) { $s2c_mac_algorithms = array_values(array_diff( $s2c_mac_algorithms, - ['hmac-sha1-96', 'hmac-md5-96'] + array('hmac-sha1-96', 'hmac-md5-96') )); } if (!isset($preferred['client_to_server']['mac'])) { $c2s_mac_algorithms = array_values(array_diff( $c2s_mac_algorithms, - ['hmac-sha1-96', 'hmac-md5-96'] + array('hmac-sha1-96', 'hmac-md5-96') )); } } + $str_kex_algorithms = implode(',', $kex_algorithms); + $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms); + $encryption_algorithms_server_to_client = implode(',', $s2c_encryption_algorithms); + $encryption_algorithms_client_to_server = implode(',', $c2s_encryption_algorithms); + $mac_algorithms_server_to_client = implode(',', $s2c_mac_algorithms); + $mac_algorithms_client_to_server = implode(',', $c2s_mac_algorithms); + $compression_algorithms_server_to_client = implode(',', $s2c_compression_algorithms); + $compression_algorithms_client_to_server = implode(',', $c2s_compression_algorithms); + $client_cookie = Random::string(16); - $kexinit_payload_client = pack('Ca*', NET_SSH2_MSG_KEXINIT, $client_cookie); - $kexinit_payload_client.= Strings::packSSH2( - 'L10bN', - $kex_algorithms, - $server_host_key_algorithms, - $c2s_encryption_algorithms, - $s2c_encryption_algorithms, - $c2s_mac_algorithms, - $s2c_mac_algorithms, - $c2s_compression_algorithms, - $s2c_compression_algorithms, - [], // language, client to server - [], // language, server to client - false, // first_kex_packet_follows - 0 // reserved for future extension + $kexinit_payload_client = pack( + 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN', + NET_SSH2_MSG_KEXINIT, + $client_cookie, + strlen($str_kex_algorithms), + $str_kex_algorithms, + strlen($str_server_host_key_algorithms), + $str_server_host_key_algorithms, + strlen($encryption_algorithms_client_to_server), + $encryption_algorithms_client_to_server, + strlen($encryption_algorithms_server_to_client), + $encryption_algorithms_server_to_client, + strlen($mac_algorithms_client_to_server), + $mac_algorithms_client_to_server, + strlen($mac_algorithms_server_to_client), + $mac_algorithms_server_to_client, + strlen($compression_algorithms_client_to_server), + $compression_algorithms_client_to_server, + strlen($compression_algorithms_server_to_client), + $compression_algorithms_server_to_client, + 0, + '', + 0, + '', + 0, + 0 ); if ($this->send_kex_first) { - $this->send_binary_packet($kexinit_payload_client); + if (!$this->_send_binary_packet($kexinit_payload_client)) { + return false; + } - $kexinit_payload_server = $this->get_binary_packet(); + $kexinit_payload_server = $this->_get_binary_packet(); if ($kexinit_payload_server === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + user_error('Expected SSH_MSG_KEXINIT'); + return false; } } $response = $kexinit_payload_server; - Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) - $server_cookie = Strings::shift($response, 16); - - list( - $this->kex_algorithms, - $this->server_host_key_algorithms, - $this->encryption_algorithms_client_to_server, - $this->encryption_algorithms_server_to_client, - $this->mac_algorithms_client_to_server, - $this->mac_algorithms_server_to_client, - $this->compression_algorithms_client_to_server, - $this->compression_algorithms_server_to_client, - $this->languages_client_to_server, - $this->languages_server_to_client, - $first_kex_packet_follows - ) = Strings::unpackSSH2('L10C', $response); + $this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) + $server_cookie = $this->_string_shift($response, 16); - if (!$this->send_kex_first) { - $this->send_binary_packet($kexinit_payload_client); + if (strlen($response) < 4) { + return false; } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length'])); - // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); + + if (!strlen($response)) { + return false; + } + extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1))); + $first_kex_packet_follows = $first_kex_packet_follows != 0; + + if (!$this->send_kex_first && !$this->_send_binary_packet($kexinit_payload_client)) { + return false; + } + // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the // diffie-hellman key exchange as fast as possible - $decrypt = self::array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); - $decryptKeyLength = $this->encryption_algorithm_to_key_size($decrypt); + $decrypt = $this->_array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); + $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt); if ($decryptKeyLength === null) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found'); + user_error('No compatible server to client encryption algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } - $encrypt = self::array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); - $encryptKeyLength = $this->encryption_algorithm_to_key_size($encrypt); + $encrypt = $this->_array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); + $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt); if ($encryptKeyLength === null) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found'); + user_error('No compatible client to server encryption algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } // through diffie-hellman key exchange a symmetric key is obtained - $this->kex_algorithm = self::array_intersect_first($kex_algorithms, $this->kex_algorithms); - if ($this->kex_algorithm === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found'); + $this->kex_algorithm = $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms); + if ($kex_algorithm === false) { + user_error('No compatible key exchange algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } - $server_host_key_algorithm = self::array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); + $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); if ($server_host_key_algorithm === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); - } - - $mac_algorithm_out = self::array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); - if ($mac_algorithm_out === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found'); + user_error('No compatible server host key algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } - $mac_algorithm_in = self::array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); + $mac_algorithm_in = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); if ($mac_algorithm_in === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found'); + user_error('No compatible server to client message authentication algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } - $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client); - if ($compression_algorithm_in === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found'); + $compression_algorithm_out = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_out === false) { + user_error('No compatible client to server compression algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } - $this->decompress = $compression_algorithm_in == 'zlib'; + //$this->decompress = $compression_algorithm_out == 'zlib'; - $compression_algorithm_out = self::array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); - if ($compression_algorithm_out === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found'); - } - $this->compress = $compression_algorithm_out == 'zlib'; - - switch ($this->kex_algorithm) { - case 'diffie-hellman-group15-sha512': - case 'diffie-hellman-group16-sha512': - case 'diffie-hellman-group17-sha512': - case 'diffie-hellman-group18-sha512': - case 'ecdh-sha2-nistp521': - $kexHash = new Hash('sha512'); - break; - case 'ecdh-sha2-nistp384': - $kexHash = new Hash('sha384'); - break; - case 'diffie-hellman-group-exchange-sha256': - case 'diffie-hellman-group14-sha256': - case 'ecdh-sha2-nistp256': - case 'curve25519-sha256@libssh.org': - case 'curve25519-sha256': - $kexHash = new Hash('sha256'); - break; - default: - $kexHash = new Hash('sha1'); + $compression_algorithm_in = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_in === false) { + user_error('No compatible server to client compression algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } + //$this->compress = $compression_algorithm_in == 'zlib'; // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. - $exchange_hash_rfc4419 = ''; - if (strpos($this->kex_algorithm, 'curve25519-sha256') === 0 || strpos($this->kex_algorithm, 'ecdh-sha2-nistp') === 0) { - $curve = strpos($this->kex_algorithm, 'curve25519-sha256') === 0 ? - 'Curve25519' : - substr($this->kex_algorithm, 10); - $ourPrivate = EC::createKey($curve); - $ourPublicBytes = $ourPrivate->getPublicKey()->getEncodedCoordinates(); + if ($kex_algorithm === 'curve25519-sha256@libssh.org') { + $x = Random::string(32); + $eBytes = sodium_crypto_box_publickey_from_secretkey($x); $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT'; $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY'; + $kexHash = new Hash('sha256'); } else { - if (strpos($this->kex_algorithm, 'diffie-hellman-group-exchange') === 0) { + if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) { $dh_group_sizes_packed = pack( 'NNN', $this->kex_dh_group_size_min, @@ -1597,112 +1594,210 @@ class SSH2 NET_SSH2_MSG_KEXDH_GEX_REQUEST, $dh_group_sizes_packed ); - $this->send_binary_packet($packet); - $this->updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); + if (!$this->_send_binary_packet($packet)) { + return false; + } + $this->_updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } - - list($type, $primeBytes, $gBytes) = Strings::unpackSSH2('Css', $response); + extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP'); + user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP'); + return false; + } + $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); + + if (strlen($response) < 4) { + return false; } - $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); + extract(unpack('NprimeLength', $this->_string_shift($response, 4))); + $primeBytes = $this->_string_shift($response, $primeLength); $prime = new BigInteger($primeBytes, -256); + + if (strlen($response) < 4) { + return false; + } + extract(unpack('NgLength', $this->_string_shift($response, 4))); + $gBytes = $this->_string_shift($response, $gLength); $g = new BigInteger($gBytes, -256); - $exchange_hash_rfc4419 = $dh_group_sizes_packed . Strings::packSSH2( - 'ss', + $exchange_hash_rfc4419 = pack( + 'a*Na*Na*', + $dh_group_sizes_packed, + $primeLength, $primeBytes, + $gLength, $gBytes ); - $params = DH::createParameters($prime, $g); $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT'; $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY'; } else { - $params = DH::createParameters($this->kex_algorithm); + switch ($kex_algorithm) { + // see http://tools.ietf.org/html/rfc2409#section-6.2 and + // http://tools.ietf.org/html/rfc2412, appendex E + case 'diffie-hellman-group1-sha1': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; + break; + // see http://tools.ietf.org/html/rfc3526#section-3 + case 'diffie-hellman-group14-sha1': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; + break; + } + // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1 + // the generator field element is 2 (decimal) and the hash function is sha1. + $g = new BigInteger(2); + $prime = new BigInteger($prime, 16); $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT'; $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY'; } - $keyLength = min($kexHash->getLengthInBytes(), max($encryptKeyLength, $decryptKeyLength)); + switch ($kex_algorithm) { + case 'diffie-hellman-group-exchange-sha256': + $kexHash = new Hash('sha256'); + break; + default: + $kexHash = new Hash('sha1'); + } - $ourPrivate = DH::createKey($params, 16 * $keyLength); // 2 * 8 * $keyLength - $ourPublic = $ourPrivate->getPublicKey()->toBigInteger(); - $ourPublicBytes = $ourPublic->toBytes(true); - } + /* To increase the speed of the key exchange, both client and server may + reduce the size of their private exponents. It should be at least + twice as long as the key material that is generated from the shared + secret. For more details, see the paper by van Oorschot and Wiener + [VAN-OORSCHOT]. - $data = pack('CNa*', constant($clientKexInitMessage), strlen($ourPublicBytes), $ourPublicBytes); + -- http://tools.ietf.org/html/rfc4419#section-6.2 */ + $one = new BigInteger(1); + $keyLength = min($kexHash->getLength(), max($encryptKeyLength, $decryptKeyLength)); + $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength + $max = $max->subtract($one); - $this->send_binary_packet($data); + $x = $one->random($one, $max); + $e = $g->modPow($x, $prime); + $eBytes = $e->toBytes(true); + } + $data = pack('CNa*', constant($clientKexInitMessage), strlen($eBytes), $eBytes); + + if (!$this->_send_binary_packet($data)) { + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; + } switch ($clientKexInitMessage) { case 'NET_SSH2_MSG_KEX_ECDH_INIT': - $this->updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); + $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); break; case 'NET_SSH2_MSG_KEXDH_GEX_INIT': - $this->updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); + $this->_updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } if (!strlen($response)) { return false; } - - list( - $type, - $server_public_host_key, - $theirPublicBytes, - $this->signature - ) = Strings::unpackSSH2('Csss', $response); + extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != constant($serverKexReplyMessage)) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException("Expected $serverKexReplyMessage"); + user_error("Expected $serverKexReplyMessage"); + return false; } switch ($serverKexReplyMessage) { case 'NET_SSH2_MSG_KEX_ECDH_REPLY': - $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); + $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); break; case 'NET_SSH2_MSG_KEXDH_GEX_REPLY': - $this->updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); + $this->_updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); + } + + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']); + + if (strlen($server_public_host_key) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); + $public_key_format = $this->_string_shift($server_public_host_key, $temp['length']); + + if (strlen($response) < 4) { + return false; } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $fBytes = $this->_string_shift($response, $temp['length']); - $this->server_public_host_key = $server_public_host_key; - list($public_key_format) = Strings::unpackSSH2('s', $server_public_host_key); + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($response, 4)); + $this->signature = $this->_string_shift($response, $temp['length']); if (strlen($this->signature) < 4) { return false; } - $temp = unpack('Nlength', substr($this->signature, 0, 4)); - $this->signature_format = substr($this->signature, 4, $temp['length']); - $keyBytes = DH::computeSecret($ourPrivate, $theirPublicBytes); - if (($keyBytes & "\xFF\x80") === "\x00\x00") { - $keyBytes = substr($keyBytes, 1); - } elseif (($keyBytes[0] & "\x80") === "\x80") { - $keyBytes = "\0$keyBytes"; + $temp = unpack('Nlength', $this->_string_shift($this->signature, 4)); + $this->signature_format = $this->_string_shift($this->signature, $temp['length']); + + if ($kex_algorithm === 'curve25519-sha256@libssh.org') { + if (strlen($fBytes) !== 32) { + user_error('Received curve25519 public key of invalid length.'); + return false; + } + $key = new BigInteger(sodium_crypto_scalarmult($x, $fBytes), 256); + // sodium_compat doesn't emulate sodium_memzero + // also, with v1 of libsodium API the extension identifies itself as + // libsodium whereas v2 of the libsodium API (what PHP 7.2+ includes) + // identifies itself as sodium. sodium_compat uses the v1 API to + // emulate the v2 API if it's the v1 API that's available + if (extension_loaded('sodium') || extension_loaded('libsodium')) { + sodium_memzero($x); + } + } else { + $f = new BigInteger($fBytes, -256); + $key = $f->modPow($x, $prime); } + $keyBytes = $key->toBytes(true); - $this->exchange_hash = Strings::packSSH2('s5', + $this->exchange_hash = pack( + 'Na*Na*Na*Na*Na*a*Na*Na*Na*', + strlen($this->identifier), $this->identifier, + strlen($this->server_identifier), $this->server_identifier, + strlen($kexinit_payload_client), $kexinit_payload_client, + strlen($kexinit_payload_server), $kexinit_payload_server, - $this->server_public_host_key - ); - $this->exchange_hash.= $exchange_hash_rfc4419; - $this->exchange_hash.= Strings::packSSH2('s3', - $ourPublicBytes, - $theirPublicBytes, + strlen($this->server_public_host_key), + $this->server_public_host_key, + $exchange_hash_rfc4419, + strlen($eBytes), + $eBytes, + strlen($fBytes), + $fBytes, + strlen($keyBytes), $keyBytes ); @@ -1713,128 +1808,112 @@ class SSH2 } switch ($server_host_key_algorithm) { - case 'rsa-sha2-256': - case 'rsa-sha2-512': - //case 'ssh-rsa': - $expected_key_format = 'ssh-rsa'; + case 'ssh-dss': + $expected_key_format = 'ssh-dss'; break; + //case 'rsa-sha2-256': + //case 'rsa-sha2-512': + //case 'ssh-rsa': default: - $expected_key_format = $server_host_key_algorithm; + $expected_key_format = 'ssh-rsa'; } + if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { switch (true) { case $this->signature_format == $server_host_key_algorithm: case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': case $this->signature_format != 'ssh-rsa': - $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - throw new \RuntimeException('Server Host Key Algorithm Mismatch'); + user_error('Server Host Key Algorithm Mismatch'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } } - $packet = pack('C', NET_SSH2_MSG_NEWKEYS); - $this->send_binary_packet($packet); + $packet = pack( + 'C', + NET_SSH2_MSG_NEWKEYS + ); + + if (!$this->_send_binary_packet($packet)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } - list($type) = Strings::unpackSSH2('C', $response); + if (!strlen($response)) { + return false; + } + extract(unpack('Ctype', $this->_string_shift($response, 1))); + if ($type != NET_SSH2_MSG_NEWKEYS) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); + user_error('Expected SSH_MSG_NEWKEYS'); + return false; } $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); - $this->encrypt = self::encryption_algorithm_to_crypt_instance($encrypt); + $this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt); if ($this->encrypt) { - if (self::$crypto_engine) { - $this->encrypt->setPreferredEngine(self::$crypto_engine); + if ($this->crypto_engine) { + $this->encrypt->setPreferredEngine($this->crypto_engine); } - if ($this->encrypt->getBlockLengthInBytes()) { - $this->encrypt_block_size = $this->encrypt->getBlockLengthInBytes(); + if ($this->encrypt->block_size) { + $this->encrypt_block_size = $this->encrypt->block_size; } + $this->encrypt->enableContinuousBuffer(); $this->encrypt->disablePadding(); - if ($this->encrypt->usesIV()) { - $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); - while ($this->encrypt_block_size > strlen($iv)) { - $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); - } - $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); + if ($this->encrypt->getBlockLength()) { + $this->encrypt_block_size = $this->encrypt->getBlockLength() >> 3; } - switch ($encrypt) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); - $this->encrypt->fixed = substr($nonce, 0, 4); - $this->encrypt->invocation_counter = substr($nonce, 4, 8); - case 'chacha20-poly1305@openssh.com': - break; - default: - $this->encrypt->enableContinuousBuffer(); + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); + while ($this->encrypt_block_size > strlen($iv)) { + $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); } + $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); while ($encryptKeyLength > strlen($key)) { $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } - switch ($encrypt) { - case 'chacha20-poly1305@openssh.com': - $encryptKeyLength = 32; - $this->lengthEncrypt = self::encryption_algorithm_to_crypt_instance($encrypt); - $this->lengthEncrypt->setKey(substr($key, 32, 32)); - } $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); - $this->encrypt->name = $encrypt; + + $this->encrypt->name = $decrypt; } - $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt); + $this->decrypt = $this->_encryption_algorithm_to_crypt_instance($decrypt); if ($this->decrypt) { - if (self::$crypto_engine) { - $this->decrypt->setPreferredEngine(self::$crypto_engine); + if ($this->crypto_engine) { + $this->decrypt->setPreferredEngine($this->crypto_engine); } - if ($this->decrypt->getBlockLengthInBytes()) { - $this->decrypt_block_size = $this->decrypt->getBlockLengthInBytes(); + if ($this->decrypt->block_size) { + $this->decrypt_block_size = $this->decrypt->block_size; } + $this->decrypt->enableContinuousBuffer(); $this->decrypt->disablePadding(); - if ($this->decrypt->usesIV()) { - $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); - while ($this->decrypt_block_size > strlen($iv)) { - $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); - } - $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); + if ($this->decrypt->getBlockLength()) { + $this->decrypt_block_size = $this->decrypt->getBlockLength() >> 3; } - switch ($decrypt) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - // see https://tools.ietf.org/html/rfc5647#section-7.1 - $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); - $this->decrypt->fixed = substr($nonce, 0, 4); - $this->decrypt->invocation_counter = substr($nonce, 4, 8); - case 'chacha20-poly1305@openssh.com': - break; - default: - $this->decrypt->enableContinuousBuffer(); + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); + while ($this->decrypt_block_size > strlen($iv)) { + $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); } + $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); while ($decryptKeyLength > strlen($key)) { $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } - switch ($decrypt) { - case 'chacha20-poly1305@openssh.com': - $decryptKeyLength = 32; - $this->lengthDecrypt = self::encryption_algorithm_to_crypt_instance($decrypt); - $this->lengthDecrypt->setKey(substr($key, 32, 32)); - } $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); + $this->decrypt->name = $decrypt; } @@ -1852,45 +1931,77 @@ class SSH2 $this->decrypt->decrypt(str_repeat("\0", 1536)); } - if (!$this->encrypt->usesNonce()) { - list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out); - } else { - $this->hmac_create = new \stdClass; - $this->hmac_create->name = $mac_algorithm_out; - //$mac_algorithm_out = 'none'; - $createKeyLength = 0; + $mac_algorithm_out = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); + if ($mac_algorithm_out === false) { + user_error('No compatible client to server message authentication algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } - if ($this->hmac_create instanceof Hash) { - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); - while ($createKeyLength > strlen($key)) { - $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); - $this->hmac_create->name = $mac_algorithm_out; - $this->hmac_create->etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out); + $createKeyLength = 0; // ie. $mac_algorithm == 'none' + switch ($mac_algorithm_out) { + case 'hmac-sha2-256': + $this->hmac_create = new Hash('sha256'); + $createKeyLength = 32; + break; + case 'hmac-sha1': + $this->hmac_create = new Hash('sha1'); + $createKeyLength = 20; + break; + case 'hmac-sha1-96': + $this->hmac_create = new Hash('sha1-96'); + $createKeyLength = 20; + break; + case 'hmac-md5': + $this->hmac_create = new Hash('md5'); + $createKeyLength = 16; + break; + case 'hmac-md5-96': + $this->hmac_create = new Hash('md5-96'); + $createKeyLength = 16; } + $this->hmac_create->name = $mac_algorithm_out; - if (!$this->decrypt->usesNonce()) { - list($this->hmac_check, $checkKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_in); - $this->hmac_size = $this->hmac_check->getLengthInBytes(); - } else { - $this->hmac_check = new \stdClass; - $this->hmac_check->name = $mac_algorithm_in; - //$mac_algorithm_in = 'none'; - $checkKeyLength = 0; - $this->hmac_size = 0; + $checkKeyLength = 0; + $this->hmac_size = 0; + switch ($mac_algorithm_in) { + case 'hmac-sha2-256': + $this->hmac_check = new Hash('sha256'); + $checkKeyLength = 32; + $this->hmac_size = 32; + break; + case 'hmac-sha1': + $this->hmac_check = new Hash('sha1'); + $checkKeyLength = 20; + $this->hmac_size = 20; + break; + case 'hmac-sha1-96': + $this->hmac_check = new Hash('sha1-96'); + $checkKeyLength = 20; + $this->hmac_size = 12; + break; + case 'hmac-md5': + $this->hmac_check = new Hash('md5'); + $checkKeyLength = 16; + $this->hmac_size = 16; + break; + case 'hmac-md5-96': + $this->hmac_check = new Hash('md5-96'); + $checkKeyLength = 16; + $this->hmac_size = 12; } + $this->hmac_check->name = $mac_algorithm_in; - if ($this->hmac_check instanceof Hash) { - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); - while ($checkKeyLength > strlen($key)) { - $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); - $this->hmac_check->name = $mac_algorithm_in; - $this->hmac_check->etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in); + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); + while ($createKeyLength > strlen($key)) { + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } + $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); + + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); + while ($checkKeyLength > strlen($key)) { + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); return true; } @@ -1902,16 +2013,15 @@ class SSH2 * @return int|null Number of bytes as an integer or null for unknown * @access private */ - private function encryption_algorithm_to_key_size($algorithm) + function _encryption_algorithm_to_key_size($algorithm) { - if ($this->bad_key_size_fix && self::bad_algorithm_candidate($algorithm)) { + if ($this->bad_key_size_fix && $this->_bad_algorithm_candidate($algorithm)) { return 16; } switch ($algorithm) { case 'none': return 0; - case 'aes128-gcm@openssh.com': case 'aes128-cbc': case 'aes128-ctr': case 'arcfour': @@ -1928,7 +2038,6 @@ class SSH2 case 'twofish192-cbc': case 'twofish192-ctr': return 24; - case 'aes256-gcm@openssh.com': case 'aes256-cbc': case 'aes256-ctr': case 'arcfour256': @@ -1936,97 +2045,55 @@ class SSH2 case 'twofish256-cbc': case 'twofish256-ctr': return 32; - case 'chacha20-poly1305@openssh.com': - return 64; } return null; } /** * Maps an encryption algorithm name to an instance of a subclass of - * \phpseclib3\Crypt\Common\SymmetricKey. + * \phpseclib\Crypt\Base. * * @param string $algorithm Name of the encryption algorithm - * @return mixed Instance of \phpseclib3\Crypt\Common\SymmetricKey or null for unknown + * @return mixed Instance of \phpseclib\Crypt\Base or null for unknown * @access private */ - private static function encryption_algorithm_to_crypt_instance($algorithm) + function _encryption_algorithm_to_crypt_instance($algorithm) { switch ($algorithm) { case '3des-cbc': - return new TripleDES('cbc'); + return new TripleDES(); case '3des-ctr': - return new TripleDES('ctr'); + return new TripleDES(Base::MODE_CTR); case 'aes256-cbc': case 'aes192-cbc': case 'aes128-cbc': - return new Rijndael('cbc'); + return new Rijndael(); case 'aes256-ctr': case 'aes192-ctr': case 'aes128-ctr': - return new Rijndael('ctr'); + return new Rijndael(Base::MODE_CTR); case 'blowfish-cbc': - return new Blowfish('cbc'); + return new Blowfish(); case 'blowfish-ctr': - return new Blowfish('ctr'); + return new Blowfish(Base::MODE_CTR); case 'twofish128-cbc': case 'twofish192-cbc': case 'twofish256-cbc': case 'twofish-cbc': - return new Twofish('cbc'); + return new Twofish(); case 'twofish128-ctr': case 'twofish192-ctr': case 'twofish256-ctr': - return new Twofish('ctr'); + return new Twofish(Base::MODE_CTR); case 'arcfour': case 'arcfour128': case 'arcfour256': return new RC4(); - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - return new Rijndael('gcm'); - case 'chacha20-poly1305@openssh.com': - return new ChaCha20(); } return null; } /** - * Maps an encryption algorithm name to an instance of a subclass of - * \phpseclib3\Crypt\Hash. - * - * @param string $algorithm Name of the encryption algorithm - * @return mixed Instance of \phpseclib3\Crypt\Hash or null for unknown - * @access private - */ - private static function mac_algorithm_to_hash_instance($algorithm) - { - switch ($algorithm) { - case 'umac-64@openssh.com': - case 'umac-64-etm@openssh.com': - return [new Hash('umac-64'), 16]; - case 'umac-128@openssh.com': - case 'umac-128-etm@openssh.com': - return [new Hash('umac-128'), 16]; - case 'hmac-sha2-512': - case 'hmac-sha2-512-etm@openssh.com': - return [new Hash('sha512'), 64]; - case 'hmac-sha2-256': - case 'hmac-sha2-256-etm@openssh.com': - return [new Hash('sha256'), 32]; - case 'hmac-sha1': - case 'hmac-sha1-etm@openssh.com': - return [new Hash('sha1'), 20]; - case 'hmac-sha1-96': - return [new Hash('sha1-96'), 20]; - case 'hmac-md5': - return [new Hash('md5'), 16]; - case 'hmac-md5-96': - return [new Hash('md5-96'), 16]; - } - } - - /* * Tests whether or not proposed algorithm has a potential for issues * * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html @@ -2035,7 +2102,7 @@ class SSH2 * @return bool * @access private */ - private static function bad_algorithm_candidate($algorithm) + function _bad_algorithm_candidate($algorithm) { switch ($algorithm) { case 'arcfour256': @@ -2050,54 +2117,54 @@ class SSH2 /** * Login * - * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA object or an array + * The $password parameter can be a plaintext password, a \phpseclib\Crypt\RSA object or an array * * @param string $username - * @param string[] ...$args * @return bool * @see self::_login() * @access public */ - public function login($username, ...$args) + function login($username) { - $this->auth[] = func_get_args(); + $args = func_get_args(); + $this->auth[] = $args; // try logging with 'none' as an authentication method first since that's what // PuTTY does if (substr($this->server_identifier, 0, 13) != 'SSH-2.0-CoreFTP') { - if ($this->sublogin($username)) { + if ($this->_login($username)) { return true; } - if (!count($args)) { + if (count($args) == 1) { return false; } } - return $this->sublogin($username, ...$args); + return call_user_func_array(array(&$this, '_login'), $args); } /** * Login Helper * * @param string $username - * @param string[] ...$args * @return bool * @see self::_login_helper() * @access private */ - protected function sublogin($username, ...$args) + function _login($username) { if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { - if (!$this->connect()) { + if (!$this->_connect()) { return false; } } + $args = array_slice(func_get_args(), 1); if (empty($args)) { - return $this->login_helper($username); + return $this->_login_helper($username); } foreach ($args as $arg) { - if ($this->login_helper($username, $arg)) { + if ($this->_login_helper($username, $arg)) { return true; } } @@ -2107,61 +2174,69 @@ class SSH2 /** * Login Helper * - * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} - * by sending dummy SSH_MSG_IGNORE messages.} - * * @param string $username * @param string $password * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors * @access private + * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages. */ - private function login_helper($username, $password = null) + function _login_helper($username, $password = null) { if (!($this->bitmap & self::MASK_CONNECTED)) { return false; } if (!($this->bitmap & self::MASK_LOGIN_REQ)) { - $packet = Strings::packSSH2('Cs', NET_SSH2_MSG_SERVICE_REQUEST, 'ssh-userauth'); - $this->send_binary_packet($packet); + $packet = pack( + 'CNa*', + NET_SSH2_MSG_SERVICE_REQUEST, + strlen('ssh-userauth'), + 'ssh-userauth' + ); + + if (!$this->_send_binary_packet($packet)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { if ($this->retry_connect) { $this->retry_connect = false; - if (!$this->connect()) { + if (!$this->_connect()) { return false; } - return $this->login_helper($username, $password); + return $this->_login_helper($username, $password); } - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } - list($type, $service) = Strings::unpackSSH2('Cs', $response); - if ($type != NET_SSH2_MSG_SERVICE_ACCEPT || $service != 'ssh-userauth') { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Ctype', $this->_string_shift($response, 1))); + + if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) { + user_error('Expected SSH_MSG_SERVICE_ACCEPT'); + return false; } $this->bitmap |= self::MASK_LOGIN_REQ; } if (strlen($this->last_interactive_response)) { - return !is_string($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password); + return !is_string($password) && !is_array($password) ? false : $this->_keyboard_interactive_process($password); } - if ($password instanceof PrivateKey) { - return $this->privatekey_login($username, $password); - } - - if ($password instanceof Agent) { - return $this->ssh_agent_login($username, $password); + if ($password instanceof RSA) { + return $this->_privatekey_login($username, $password); + } elseif ($password instanceof Agent) { + return $this->_ssh_agent_login($username, $password); } if (is_array($password)) { - if ($this->keyboard_interactive_login($username, $password)) { + if ($this->_keyboard_interactive_login($username, $password)) { $this->bitmap |= self::MASK_LOGIN; return true; } @@ -2169,23 +2244,33 @@ class SSH2 } if (!isset($password)) { - $packet = Strings::packSSH2( - 'Cs3', - NET_SSH2_MSG_USERAUTH_REQUEST, - $username, - 'ssh-connection', - 'none' + $packet = pack( + 'CNa*Na*Na*', + NET_SSH2_MSG_USERAUTH_REQUEST, + strlen($username), + $username, + strlen('ssh-connection'), + 'ssh-connection', + strlen('none'), + 'none' ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; + } + + if (!strlen($response)) { + return false; } + extract(unpack('Ctype', $this->_string_shift($response, 1))); - list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= self::MASK_LOGIN; @@ -2196,17 +2281,17 @@ class SSH2 } } - if (!is_string($password)) { - throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string'); - } - - $packet = Strings::packSSH2( - 'Cs3bs', + $packet = pack( + 'CNa*Na*Na*CNa*', NET_SSH2_MSG_USERAUTH_REQUEST, + strlen($username), $username, + strlen('ssh-connection'), 'ssh-connection', + strlen('password'), 'password', - false, + 0, + strlen($password), $password ); @@ -2214,40 +2299,62 @@ class SSH2 if (!defined('NET_SSH2_LOGGING')) { $logged = null; } else { - $logged = Strings::packSSH2( - 'Cs3bs', + $logged = pack( + 'CNa*Na*Na*CNa*', NET_SSH2_MSG_USERAUTH_REQUEST, - $username, + strlen('username'), + 'username', + strlen('ssh-connection'), 'ssh-connection', + strlen('password'), 'password', - false, + 0, + strlen('password'), 'password' ); } - $this->send_binary_packet($packet, $logged); + if (!$this->_send_binary_packet($packet, $logged)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; + } + + if (!strlen($response)) { + return false; } + extract(unpack('Ctype', $this->_string_shift($response, 1))); - list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed - $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); - - list($message) = Strings::unpackSSH2('s', $response); - $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $message; - - return $this->disconnect_helper(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); + $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length); + return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); case NET_SSH2_MSG_USERAUTH_FAILURE: // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees // multi-factor authentication - list($auth_methods, $partial_success) = Strings::unpackSSH2('Lb', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $auth_methods = explode(',', $this->_string_shift($response, $length)); + if (!strlen($response)) { + return false; + } + extract(unpack('Cpartial_success', $this->_string_shift($response, 1))); + $partial_success = $partial_success != 0; + if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) { - if ($this->keyboard_interactive_login($username, $password)) { + if ($this->_keyboard_interactive_login($username, $password)) { $this->bitmap |= self::MASK_LOGIN; return true; } @@ -2272,51 +2379,77 @@ class SSH2 * @return bool * @access private */ - private function keyboard_interactive_login($username, $password) + function _keyboard_interactive_login($username, $password) { - $packet = Strings::packSSH2( - 'Cs5', + $packet = pack( + 'CNa*Na*Na*Na*Na*', NET_SSH2_MSG_USERAUTH_REQUEST, + strlen($username), $username, + strlen('ssh-connection'), 'ssh-connection', + strlen('keyboard-interactive'), 'keyboard-interactive', - '', // language tag - '' // submethods + 0, + '', + 0, + '' ); - $this->send_binary_packet($packet); - return $this->keyboard_interactive_process($password); + if (!$this->_send_binary_packet($packet)) { + return false; + } + + return $this->_keyboard_interactive_process($password); } /** * Handle the keyboard-interactive requests / responses. * - * @param mixed[] ...$responses * @return bool - * @throws \RuntimeException on connection error * @access private */ - private function keyboard_interactive_process(...$responses) + function _keyboard_interactive_process() { + $responses = func_get_args(); + if (strlen($this->last_interactive_response)) { $response = $this->last_interactive_response; } else { - $orig = $response = $this->get_binary_packet(); + $orig = $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } } - list($type) = Strings::unpackSSH2('C', $response); + if (!strlen($response)) { + return false; + } + extract(unpack('Ctype', $this->_string_shift($response, 1))); + switch ($type) { case NET_SSH2_MSG_USERAUTH_INFO_REQUEST: - list( - , // name; may be empty - , // instruction; may be empty - , // language tag; may be empty - $num_prompts - ) = Strings::unpackSSH2('s3N', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $this->_string_shift($response, $length); // name; may be empty + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $this->_string_shift($response, $length); // instruction; may be empty + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $this->_string_shift($response, $length); // language tag; may be empty + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nnum_prompts', $this->_string_shift($response, 4))); for ($i = 0; $i < count($responses); $i++) { if (is_array($responses[$i])) { @@ -2330,10 +2463,13 @@ class SSH2 if (isset($this->keyboard_requests_responses)) { for ($i = 0; $i < $num_prompts; $i++) { - list( - $prompt, // prompt - ie. "Password: "; must not be empty - // echo - ) = Strings::unpackSSH2('sC', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + // prompt - ie. "Password: "; must not be empty + $prompt = $this->_string_shift($response, $length); + //$echo = $this->_string_shift($response) != chr(0); foreach ($this->keyboard_requests_responses as $key => $value) { if (substr($prompt, 0, strlen($key)) == $key) { $responses[] = $value; @@ -2347,7 +2483,7 @@ class SSH2 if (strlen($this->last_interactive_response)) { $this->last_interactive_response = ''; } else { - $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); + $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); } if (!count($responses) && $num_prompts) { @@ -2362,13 +2498,15 @@ class SSH2 // see http://tools.ietf.org/html/rfc4256#section-3.4 $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); for ($i = 0; $i < count($responses); $i++) { - $packet.= Strings::packSSH2('s', $responses[$i]); - $logged.= Strings::packSSH2('s', 'dummy-answer'); + $packet.= pack('Na*', strlen($responses[$i]), $responses[$i]); + $logged.= pack('Na*', strlen('dummy-answer'), 'dummy-answer'); } - $this->send_binary_packet($packet, $logged); + if (!$this->_send_binary_packet($packet, $logged)) { + return false; + } - $this->updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); + $this->_updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); /* After receiving the response, the server MUST send either an @@ -2377,7 +2515,7 @@ class SSH2 */ // maybe phpseclib should force close the connection after x request / responses? unless something like that is done // there could be an infinite loop of request / responses. - return $this->keyboard_interactive_process(); + return $this->_keyboard_interactive_process(); case NET_SSH2_MSG_USERAUTH_SUCCESS: return true; case NET_SSH2_MSG_USERAUTH_FAILURE: @@ -2391,16 +2529,16 @@ class SSH2 * Login with an ssh-agent provided key * * @param string $username - * @param \phpseclib3\System\SSH\Agent $agent + * @param \phpseclib\System\SSH\Agent $agent * @return bool * @access private */ - private function ssh_agent_login($username, Agent $agent) + function _ssh_agent_login($username, $agent) { $this->agent = $agent; $keys = $agent->requestIdentities(); foreach ($keys as $key) { - if ($this->privatekey_login($username, $key)) { + if ($this->_privatekey_login($username, $key)) { return true; } } @@ -2411,130 +2549,116 @@ class SSH2 /** * Login with an RSA private key * - * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} - * by sending dummy SSH_MSG_IGNORE messages.} - * * @param string $username - * @param \phpseclib3\Crypt\Common\PrivateKey $privatekey + * @param \phpseclib\Crypt\RSA $privatekey * @return bool - * @throws \RuntimeException on connection error * @access private + * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages. */ - private function privatekey_login($username, PrivateKey $privatekey) + function _privatekey_login($username, $privatekey) { - $publickey = $privatekey->getPublicKey(); - - if ($publickey instanceof RSA) { - $privatekey = $privatekey->withPadding(RSA::SIGNATURE_PKCS1); - $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa']; - if (isset($this->preferred['hostkey'])) { - $algos = array_intersect($this->preferred['hostkey'] , $algos); - } - $algo = self::array_intersect_first($algos, $this->server_host_key_algorithms); - switch ($algo) { - case 'rsa-sha2-512': - $hash = 'sha512'; - $signatureType = 'rsa-sha2-512'; - break; - case 'rsa-sha2-256': - $hash = 'sha256'; - $signatureType = 'rsa-sha2-256'; - break; - //case 'ssh-rsa': - default: - $hash = 'sha1'; - $signatureType = 'ssh-rsa'; - } - } else if ($publickey instanceof EC) { - $privatekey = $privatekey->withSignatureFormat('SSH2'); - $curveName = $privatekey->getCurve(); - switch ($curveName) { - case 'Ed25519': - $hash = 'sha512'; - $signatureType = 'ssh-ed25519'; - break; - case 'secp256r1': // nistp256 - $hash = 'sha256'; - $signatureType = 'ecdsa-sha2-nistp256'; - break; - case 'secp384r1': // nistp384 - $hash = 'sha384'; - $signatureType = 'ecdsa-sha2-nistp384'; - break; - case 'secp521r1': // nistp521 - $hash = 'sha512'; - $signatureType = 'ecdsa-sha2-nistp521'; - break; - default: - if (is_array($curveName)) { - throw new UnsupportedCurveException('Specified Curves are not supported by SSH2'); - } - throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported by phpseclib3\'s SSH2 implementation'); - } - } else if ($publickey instanceof DSA) { - $privatekey = $privatekey->withSignatureFormat('SSH2'); - $hash = 'sha1'; - $signatureType = 'ssh-dss'; - } else { - throw new UnsupportedAlgorithmException('Please use either an RSA key, an EC one or a DSA key'); + // see http://tools.ietf.org/html/rfc4253#page-15 + $publickey = $privatekey->getPublicKey(RSA::PUBLIC_FORMAT_RAW); + if ($publickey === false) { + return false; } - $publickeyStr = $publickey->toString('OpenSSH', ['binary' => true]); + $publickey = array( + 'e' => $publickey['e']->toBytes(true), + 'n' => $publickey['n']->toBytes(true) + ); + $publickey = pack( + 'Na*Na*Na*', + strlen('ssh-rsa'), + 'ssh-rsa', + strlen($publickey['e']), + $publickey['e'], + strlen($publickey['n']), + $publickey['n'] + ); + + switch ($this->signature_format) { + case 'rsa-sha2-512': + $hash = 'sha512'; + $signatureType = 'rsa-sha2-512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + $signatureType = 'rsa-sha2-256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + $signatureType = 'ssh-rsa'; + } - $part1 = Strings::packSSH2( - 'Csss', + $part1 = pack( + 'CNa*Na*Na*', NET_SSH2_MSG_USERAUTH_REQUEST, + strlen($username), $username, + strlen('ssh-connection'), 'ssh-connection', + strlen('publickey'), 'publickey' ); - $part2 = Strings::packSSH2('ss', $signatureType, $publickeyStr); + $part2 = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($publickey), $publickey); $packet = $part1 . chr(0) . $part2; - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; + } + + if (!strlen($response)) { + return false; } + extract(unpack('Ctype', $this->_string_shift($response, 1))); - list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_FAILURE: - list($message) = Strings::unpackSSH2('s', $response); - $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $message; + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $this->_string_shift($response, $length); return false; case NET_SSH2_MSG_USERAUTH_PK_OK: // we'll just take it on faith that the public key blob and the public key algorithm name are as // they should be - $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); - break; - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new ConnectionClosedException('Unexpected response to publickey authentication pt 1'); + $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); } $packet = $part1 . chr(1) . $part2; - $privatekey = $privatekey->withHash($hash); - $signature = $privatekey->sign(Strings::packSSH2('s', $this->session_id) . $packet); - if ($publickey instanceof RSA) { - $signature = Strings::packSSH2('ss', $signatureType, $signature); - } - $packet.= Strings::packSSH2('s', $signature); + $privatekey->setSignatureMode(RSA::SIGNATURE_PKCS1); + $privatekey->setHash($hash); + $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet)); + $signature = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($signature), $signature); + $packet.= pack('Na*', strlen($signature), $signature); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; + } + + if (!strlen($response)) { + return false; } + extract(unpack('Ctype', $this->_string_shift($response, 1))); - list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_FAILURE: // either the login is bad or the server employs multi-factor authentication @@ -2544,8 +2668,7 @@ class SSH2 return true; } - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new ConnectionClosedException('Unexpected response to publickey authentication pt 2'); + return false; } /** @@ -2557,7 +2680,7 @@ class SSH2 * @param mixed $timeout * @access public */ - public function setTimeout($timeout) + function setTimeout($timeout) { $this->timeout = $this->curTimeout = $timeout; } @@ -2567,7 +2690,7 @@ class SSH2 * * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. * - * @param int $interval + * @param mixed $timeout * @access public */ function setKeepAlive($interval) @@ -2580,7 +2703,7 @@ class SSH2 * * @access public */ - public function getStdError() + function getStdError() { return $this->stdErrorLog; } @@ -2588,16 +2711,15 @@ class SSH2 /** * Execute Command * - * If $callback is set to false then \phpseclib3\Net\SSH2::get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. + * If $callback is set to false then \phpseclib\Net\SSH2::_get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. * In all likelihood, this is not a feature you want to be taking advantage of. * * @param string $command * @param Callback $callback * @return string - * @throws \RuntimeException on connection error * @access public */ - public function exec($command, $callback = null) + function exec($command, $callback = null) { $this->curTimeout = $this->timeout; $this->is_timeout = false; @@ -2608,7 +2730,8 @@ class SSH2 } if ($this->in_request_pty_exec) { - throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); + user_error('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); + return false; } // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to @@ -2620,61 +2743,75 @@ class SSH2 // uses 0x4000, that's what will be used here, as well. $packet_size = 0x4000; - $packet = Strings::packSSH2( - 'CsN3', + $packet = pack( + 'CNa*N3', NET_SSH2_MSG_CHANNEL_OPEN, + strlen('session'), 'session', self::CHANNEL_EXEC, $this->window_size_server_to_client[self::CHANNEL_EXEC], $packet_size ); - $this->send_binary_packet($packet); + + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN; - $response = $this->get_channel_packet(self::CHANNEL_EXEC); + $response = $this->_get_channel_packet(self::CHANNEL_EXEC); if ($response === false) { return false; } if ($this->request_pty === true) { $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); - $packet = Strings::packSSH2( - 'CNsCsN4s', + $packet = pack( + 'CNNa*CNa*N5a*', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_EXEC], + strlen('pty-req'), 'pty-req', 1, + strlen('vt100'), 'vt100', $this->windowColumns, $this->windowRows, 0, 0, + strlen($terminal_modes), $terminal_modes ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; + } + + if (!strlen($response)) { + return false; } + list(, $type) = unpack('C', $this->_string_shift($response, 1)); - list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_CHANNEL_SUCCESS: break; case NET_SSH2_MSG_CHANNEL_FAILURE: default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Unable to request pseudo-terminal'); + user_error('Unable to request pseudo-terminal'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } $this->in_request_pty_exec = true; } // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things - // down. the one place where it might be desirable is if you're doing something like \phpseclib3\Net\SSH2::exec('ping localhost &'). + // down. the one place where it might be desirable is if you're doing something like \phpseclib\Net\SSH2::exec('ping localhost &'). // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but // neither will your script. @@ -2682,19 +2819,23 @@ class SSH2 // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates. - $packet = Strings::packSSH2( - 'CNsCs', + $packet = pack( + 'CNNa*CNa*', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_EXEC], + strlen('exec'), 'exec', 1, + strlen($command), $command ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; - $response = $this->get_channel_packet(self::CHANNEL_EXEC); + $response = $this->_get_channel_packet(self::CHANNEL_EXEC); if ($response === false) { return false; } @@ -2707,7 +2848,7 @@ class SSH2 $output = ''; while (true) { - $temp = $this->get_channel_packet(self::CHANNEL_EXEC); + $temp = $this->_get_channel_packet(self::CHANNEL_EXEC); switch (true) { case $temp === true: return is_callable($callback) ? true : $output; @@ -2715,8 +2856,8 @@ class SSH2 return false; default: if (is_callable($callback)) { - if ($callback($temp) === true) { - $this->close_channel(self::CHANNEL_EXEC); + if (call_user_func($callback, $temp) === true) { + $this->_close_channel(self::CHANNEL_EXEC); return true; } } else { @@ -2732,11 +2873,9 @@ class SSH2 * @see self::read() * @see self::write() * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors * @access private */ - private function initShell() + function _initShell() { if ($this->in_request_pty_exec === true) { return true; @@ -2745,48 +2884,60 @@ class SSH2 $this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size; $packet_size = 0x4000; - $packet = Strings::packSSH2( - 'CsN3', + $packet = pack( + 'CNa*N3', NET_SSH2_MSG_CHANNEL_OPEN, + strlen('session'), 'session', self::CHANNEL_SHELL, $this->window_size_server_to_client[self::CHANNEL_SHELL], $packet_size ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_OPEN; - $response = $this->get_channel_packet(self::CHANNEL_SHELL); + $response = $this->_get_channel_packet(self::CHANNEL_SHELL); if ($response === false) { return false; } $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); - $packet = Strings::packSSH2( - 'CNsCsN4s', + $packet = pack( + 'CNNa*CNa*N5a*', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SHELL], + strlen('pty-req'), 'pty-req', 1, + strlen('vt100'), 'vt100', $this->windowColumns, $this->windowRows, 0, 0, + strlen($terminal_modes), $terminal_modes ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } - $response = $this->get_binary_packet(); + $response = $this->_get_binary_packet(); if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } - list($type) = Strings::unpackSSH2('C', $response); + if (!strlen($response)) { + return false; + } + list(, $type) = unpack('C', $this->_string_shift($response, 1)); switch ($type) { case NET_SSH2_MSG_CHANNEL_SUCCESS: @@ -2794,22 +2945,25 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_FAILURE: break; default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \UnexpectedValueException('Unable to request pseudo-terminal'); + user_error('Unable to request pseudo-terminal'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } - $packet = Strings::packSSH2( - 'CNsb', + $packet = pack( + 'CNNa*C', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SHELL], + strlen('shell'), 'shell', - true // want reply + 1 ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; - $response = $this->get_channel_packet(self::CHANNEL_SHELL); + $response = $this->_get_channel_packet(self::CHANNEL_SHELL); if ($response === false) { return false; } @@ -2829,7 +2983,7 @@ class SSH2 * @return int * @access public */ - private function get_interactive_channel() + function _get_interactive_channel() { switch (true) { case $this->in_subsystem: @@ -2847,7 +3001,7 @@ class SSH2 * @return int * @access public */ - private function get_open_channel() + function _get_open_channel() { $channel = self::CHANNEL_EXEC; do { @@ -2859,41 +3013,6 @@ class SSH2 return false; } - /** - * Request agent forwarding of remote server - * - * @return bool - * @access public - */ - public function requestAgentForwarding() - { - $request_channel = $this->get_open_channel(); - if ($request_channel === false) { - return false; - } - - $packet = Strings::packSSH2( - 'CNsC', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[$request_channel], - 'auth-agent-req@openssh.com', - 1 - ); - - $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $this->send_binary_packet($packet); - - $response = $this->get_channel_packet($request_channel); - if ($response === false) { - return false; - } - - $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; - - return true; - } - /** * Returns the output of an interactive shell * @@ -2903,27 +3022,28 @@ class SSH2 * @see self::write() * @param string $expect * @param int $mode - * @return string|bool|null - * @throws \RuntimeException on connection error + * @return string|bool * @access public */ - public function read($expect = '', $mode = self::READ_SIMPLE) + function read($expect = '', $mode = self::READ_SIMPLE) { $this->curTimeout = $this->timeout; $this->is_timeout = false; if (!$this->isAuthenticated()) { - throw new InsufficientSetupException('Operation disallowed prior to login()'); + user_error('Operation disallowed prior to login()'); + return false; } - if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { - throw new \RuntimeException('Unable to initiate an interactive shell session'); + if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { + user_error('Unable to initiate an interactive shell session'); + return false; } - $channel = $this->get_interactive_channel(); + $channel = $this->_get_interactive_channel(); if ($mode == self::READ_NEXT) { - return $this->get_channel_packet($channel); + return $this->_get_channel_packet($channel); } $match = $expect; @@ -2934,12 +3054,12 @@ class SSH2 } $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; if ($pos !== false) { - return Strings::shift($this->interactiveBuffer, $pos + strlen($match)); + return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match)); } - $response = $this->get_channel_packet($channel); + $response = $this->_get_channel_packet($channel); if (is_bool($response)) { $this->in_request_pty_exec = false; - return $response ? Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer)) : false; + return $response ? $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer)) : false; } $this->interactiveBuffer.= $response; @@ -2952,20 +3072,21 @@ class SSH2 * @see self::read() * @param string $cmd * @return bool - * @throws \RuntimeException on connection error * @access public */ - public function write($cmd) + function write($cmd) { if (!$this->isAuthenticated()) { - throw new InsufficientSetupException('Operation disallowed prior to login()'); + user_error('Operation disallowed prior to login()'); + return false; } - if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { - throw new \RuntimeException('Unable to initiate an interactive shell session'); + if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { + user_error('Unable to initiate an interactive shell session'); + return false; } - return $this->send_channel_packet($this->get_interactive_channel(), $cmd); + return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd); } /** @@ -2982,41 +3103,49 @@ class SSH2 * @return bool * @access public */ - public function startSubsystem($subsystem) + function startSubsystem($subsystem) { $this->window_size_server_to_client[self::CHANNEL_SUBSYSTEM] = $this->window_size; - $packet = Strings::packSSH2( - 'CsN3', + $packet = pack( + 'CNa*N3', NET_SSH2_MSG_CHANNEL_OPEN, + strlen('session'), 'session', self::CHANNEL_SUBSYSTEM, $this->window_size, 0x4000 ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_OPEN; - $response = $this->get_channel_packet(self::CHANNEL_SUBSYSTEM); + $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM); if ($response === false) { return false; } - $packet = Strings::packSSH2( - 'CNsCs', + $packet = pack( + 'CNNa*CNa*', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SUBSYSTEM], + strlen('subsystem'), 'subsystem', 1, + strlen($subsystem), $subsystem ); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST; - $response = $this->get_channel_packet(self::CHANNEL_SUBSYSTEM); + $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM); + if ($response === false) { return false; } @@ -3036,10 +3165,10 @@ class SSH2 * @return bool * @access public */ - public function stopSubsystem() + function stopSubsystem() { $this->in_subsystem = false; - $this->close_channel(self::CHANNEL_SUBSYSTEM); + $this->_close_channel(self::CHANNEL_SUBSYSTEM); return true; } @@ -3050,9 +3179,9 @@ class SSH2 * * @access public */ - public function reset() + function reset() { - $this->close_channel($this->get_interactive_channel()); + $this->_close_channel($this->_get_interactive_channel()); } /** @@ -3062,7 +3191,7 @@ class SSH2 * * @access public */ - public function isTimeout() + function isTimeout() { return $this->is_timeout; } @@ -3072,13 +3201,12 @@ class SSH2 * * @access public */ - public function disconnect() + function disconnect() { - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) { fclose($this->realtime_log_file); } - unset(self::$connections[$this->getResourceId()]); } /** @@ -3089,7 +3217,7 @@ class SSH2 * * @access public */ - public function __destruct() + function __destruct() { $this->disconnect(); } @@ -3100,7 +3228,7 @@ class SSH2 * @return bool * @access public */ - public function isConnected() + function isConnected() { return (bool) ($this->bitmap & self::MASK_CONNECTED); } @@ -3111,7 +3239,7 @@ class SSH2 * @return bool * @access public */ - public function isAuthenticated() + function isAuthenticated() { return (bool) ($this->bitmap & self::MASK_LOGIN); } @@ -3122,55 +3250,59 @@ class SSH2 * Inspired by http://php.net/manual/en/mysqli.ping.php * * @return bool + * @access public */ - public function ping() + function ping() { if (!$this->isAuthenticated()) { if (!empty($this->auth)) { - return $this->reconnect(); + return $this->_reconnect(); } return false; } $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE] = $this->window_size; $packet_size = 0x4000; - $packet = Strings::packSSH2( - 'CsN3', + $packet = pack( + 'CNa*N3', NET_SSH2_MSG_CHANNEL_OPEN, + strlen('session'), 'session', self::CHANNEL_KEEP_ALIVE, $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE], $packet_size ); - try { - $this->send_binary_packet($packet); + if (!@$this->_send_binary_packet($packet)) { + return $this->_reconnect(); + } - $this->channel_status[self::CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN; + $this->channel_status[self::CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN; - $response = $this->get_channel_packet(self::CHANNEL_KEEP_ALIVE); - } catch (\RuntimeException $e) { - return $this->reconnect(); + $response = @$this->_get_channel_packet(self::CHANNEL_KEEP_ALIVE); + if ($response !== false) { + $this->_close_channel(self::CHANNEL_KEEP_ALIVE); + return true; } - $this->close_channel(NET_SSH2_CHANNEL_KEEP_ALIVE); - return true; + return $this->_reconnect(); } /** * In situ reconnect method * * @return boolean + * @access private */ - private function reconnect() + function _reconnect() { - $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); + $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); $this->retry_connect = true; - if (!$this->connect()) { + if (!$this->_connect()) { return false; } foreach ($this->auth as $auth) { - $result = $this->login(...$auth); + $result = call_user_func_array(array(&$this, 'login'), $auth); } return $result; } @@ -3181,9 +3313,9 @@ class SSH2 * @param int $reason * @access private */ - protected function reset_connection($reason) + function _reset_connection($reason) { - $this->disconnect_helper($reason); + $this->_disconnect($reason); $this->decrypt = $this->encrypt = false; $this->decrypt_block_size = $this->encrypt_block_size = 8; $this->hmac_check = $this->hmac_create = false; @@ -3199,23 +3331,22 @@ class SSH2 * See '6. Binary Packet Protocol' of rfc4253 for more info. * * @see self::_send_binary_packet() - * @param bool $skip_channel_filter * @return string * @access private */ - private function get_binary_packet($skip_channel_filter = false) + function _get_binary_packet($skip_channel_filter = false) { if ($skip_channel_filter) { - $read = [$this->fsock]; + $read = array($this->fsock); $write = $except = null; if ($this->curTimeout <= 0) { if ($this->keepAlive <= 0) { @stream_select($read, $write, $except, null); } else { - if (!@stream_select($read, $write, $except, $this->keepAlive)) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - return $this->get_binary_packet(true); + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + return $this->_get_binary_packet(true); } } } else { @@ -3224,17 +3355,17 @@ class SSH2 return true; } - $read = [$this->fsock]; + $read = array($this->fsock); $write = $except = null; $start = microtime(true); if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { - if (!@stream_select($read, $write, $except, $this->keepAlive)) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); $elapsed = microtime(true) - $start; $this->curTimeout-= $elapsed; - return $this->get_binary_packet(true); + return $this->_get_binary_packet(true); } $elapsed = microtime(true) - $start; $this->curTimeout-= $elapsed; @@ -3243,8 +3374,8 @@ class SSH2 $sec = floor($this->curTimeout); $usec = 1000000 * ($this->curTimeout - $sec); - // this can return a "stream_select(): unable to select [4]: Interrupted system call" error - if (!@stream_select($read, $write, $except, $sec, $usec)) { + // on windows this returns a "Warning: Invalid CRT parameters detected" error + if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { $this->is_timeout = true; return true; } @@ -3255,7 +3386,8 @@ class SSH2 if (!is_resource($this->fsock) || feof($this->fsock)) { $this->bitmap = 0; - throw new ConnectionClosedException('Connection closed prematurely'); + user_error('Connection closed prematurely'); + return false; } $start = microtime(true); @@ -3265,121 +3397,63 @@ class SSH2 return ''; } - if ($this->decrypt) { - switch ($this->decrypt->name) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - $this->decrypt->setNonce( - $this->decrypt->fixed . - $this->decrypt->invocation_counter - ); - Strings::increment_str($this->decrypt->invocation_counter); - $this->decrypt->setAAD($temp = Strings::shift($raw, 4)); - extract(unpack('Npacket_length', $temp)); - /** - * @var integer $packet_length - */ - - $raw.= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); - $stop = microtime(true); - $tag = stream_get_contents($this->fsock, $this->decrypt_block_size); - $this->decrypt->setTag($tag); - $raw = $this->decrypt->decrypt($raw); - $raw = $temp . $raw; - $remaining_length = 0; - break; - case 'chacha20-poly1305@openssh.com': - $nonce = pack('N2', 0, $this->get_seq_no); - - $this->lengthDecrypt->setNonce($nonce); - $temp = $this->lengthDecrypt->decrypt($aad = Strings::shift($raw, 4)); - extract(unpack('Npacket_length', $temp)); - /** - * @var integer $packet_length - */ - - $raw.= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); - $stop = microtime(true); - $tag = stream_get_contents($this->fsock, 16); - - $this->decrypt->setNonce($nonce); - $this->decrypt->setCounter(0); - // this is the same approach that's implemented in Salsa20::createPoly1305Key() - // but we don't want to use the same AEAD construction that RFC8439 describes - // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) - $this->decrypt->setPoly1305Key( - $this->decrypt->encrypt(str_repeat("\0", 32)) - ); - $this->decrypt->setAAD($aad); - $this->decrypt->setCounter(1); - $this->decrypt->setTag($tag); - $raw = $this->decrypt->decrypt($raw); - $raw = $temp . $raw; - $remaining_length = 0; - break; - default: - if (!$this->hmac_check instanceof Hash || !$this->hmac_check->etm) { - $raw = $this->decrypt->decrypt($raw); - break; - } - extract(unpack('Npacket_length', $temp = Strings::shift($raw, 4))); - /** - * @var integer $packet_length - */ - $raw.= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); - $stop = microtime(true); - $encrypted = $temp . $raw; - $raw = $temp . $this->decrypt->decrypt($raw); - $remaining_length = 0; - } + if ($this->decrypt !== false) { + $raw = $this->decrypt->decrypt($raw); + } + if ($raw === false) { + user_error('Unable to decrypt content'); + return false; } if (strlen($raw) < 5) { return false; } - extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5))); - /** - * @var integer $packet_length - * @var integer $padding_length - */ + extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5))); - if (!isset($remaining_length)) { - $remaining_length = $packet_length + 4 - $this->decrypt_block_size; - } + $remaining_length = $packet_length + 4 - $this->decrypt_block_size; - $buffer = $this->read_remaining_bytes($remaining_length); + // quoting , + // "implementations SHOULD check that the packet length is reasonable" + // PuTTY uses 0x9000 as the actual max packet size and so to shall we + if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) { + if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt->name) && !($this->bitmap & SSH2::MASK_LOGIN)) { + $this->bad_key_size_fix = true; + $this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + return false; + } + user_error('Invalid size'); + return false; + } - if (!isset($stop)) { - $stop = microtime(true); + $buffer = ''; + while ($remaining_length > 0) { + $temp = stream_get_contents($this->fsock, $remaining_length); + if ($temp === false || feof($this->fsock)) { + $this->bitmap = 0; + user_error('Error reading from socket'); + return false; + } + $buffer.= $temp; + $remaining_length-= strlen($temp); } + + $stop = microtime(true); if (strlen($buffer)) { - $raw.= $this->decrypt ? $this->decrypt->decrypt($buffer) : $buffer; + $raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer; } - $payload = Strings::shift($raw, $packet_length - $padding_length - 1); - $padding = Strings::shift($raw, $padding_length); // should leave $raw empty + $payload = $this->_string_shift($raw, $packet_length - $padding_length - 1); + $padding = $this->_string_shift($raw, $padding_length); // should leave $raw empty - if ($this->hmac_check instanceof Hash) { + if ($this->hmac_check !== false) { $hmac = stream_get_contents($this->fsock, $this->hmac_size); if ($hmac === false || strlen($hmac) != $this->hmac_size) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); - throw new \RuntimeException('Error reading socket'); - } - - $reconstructed = !$this->hmac_check->etm ? - pack('NCa*', $packet_length, $padding_length, $payload . $padding) : - $encrypted; - if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { - $this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no)); - if ($hmac != $this->hmac_check->hash($reconstructed)) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); - throw new \RuntimeException('Invalid UMAC'); - } - } else { - if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); - throw new \RuntimeException('Invalid HMAC'); - } + $this->bitmap = 0; + user_error('Error reading socket'); + return false; + } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) { + user_error('Invalid HMAC'); + return false; } } @@ -3394,68 +3468,11 @@ class SSH2 $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; $message_number = '<- ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; - $this->append_log($message_number, $payload); + $this->_append_log($message_number, $payload); $this->last_packet = $current; } - return $this->filter($payload, $skip_channel_filter); - } - - /** - * Read Remaining Bytes - * - * @see self::get_binary_packet() - * @param int $remaining_length - * @return string - * @access private - */ - private function read_remaining_bytes($remaining_length) - { - if (!$remaining_length) { - return ''; - } - - $adjustLength = false; - if ($this->decrypt) { - switch (true) { - case $this->decrypt->name == 'aes128-gcm@openssh.com': - case $this->decrypt->name == 'aes256-gcm@openssh.com': - case $this->decrypt->name == 'chacha20-poly1305@openssh.com': - case $this->hmac_check instanceof Hash && $this->hmac_check->etm: - $remaining_length+= $this->decrypt_block_size - 4; - $adjustLength = true; - } - } - - // quoting , - // "implementations SHOULD check that the packet length is reasonable" - // PuTTY uses 0x9000 as the actual max packet size and so to shall we - // don't do this when GCM mode is used since GCM mode doesn't encrypt the length - if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) { - if (!$this->bad_key_size_fix && self::bad_algorithm_candidate($this->decrypt ? $this->decrypt->name : '') && !($this->bitmap & SSH2::MASK_LOGIN)) { - $this->bad_key_size_fix = true; - $this->reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - return false; - } - throw new \RuntimeException('Invalid size'); - } - - if ($adjustLength) { - $remaining_length-= $this->decrypt_block_size - 4; - } - - $buffer = ''; - while ($remaining_length > 0) { - $temp = stream_get_contents($this->fsock, $remaining_length); - if ($temp === false || feof($this->fsock)) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new \RuntimeException('Error reading from socket'); - } - $buffer.= $temp; - $remaining_length-= strlen($temp); - } - - return $buffer; + return $this->_filter($payload, $skip_channel_filter); } /** @@ -3464,46 +3481,55 @@ class SSH2 * Because some binary packets need to be ignored... * * @see self::_get_binary_packet() - * @param string $payload - * @param bool $skip_channel_filter * @return string * @access private */ - private function filter($payload, $skip_channel_filter) + function _filter($payload, $skip_channel_filter) { switch (ord($payload[0])) { case NET_SSH2_MSG_DISCONNECT: - Strings::shift($payload, 1); - list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); - $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n$message"; + $this->_string_shift($payload, 1); + if (strlen($payload) < 8) { + return false; + } + extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8))); + $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length); $this->bitmap = 0; return false; case NET_SSH2_MSG_IGNORE: - $payload = $this->get_binary_packet($skip_channel_filter); + $payload = $this->_get_binary_packet($skip_channel_filter); break; case NET_SSH2_MSG_DEBUG: - Strings::shift($payload, 2); // second byte is "always_display" - list($message) = Strings::unpackSSH2('s', $payload); - $this->errors[] = "SSH_MSG_DEBUG: $message"; - $payload = $this->get_binary_packet($skip_channel_filter); + $this->_string_shift($payload, 2); + if (strlen($payload) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($payload, 4))); + $this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length); + $payload = $this->_get_binary_packet($skip_channel_filter); break; case NET_SSH2_MSG_UNIMPLEMENTED: return false; case NET_SSH2_MSG_KEXINIT: if ($this->session_id !== false) { - if (!$this->key_exchange($payload)) { + $this->send_kex_first = false; + if (!$this->_key_exchange($payload)) { $this->bitmap = 0; return false; } - $payload = $this->get_binary_packet($skip_channel_filter); + $payload = $this->_get_binary_packet($skip_channel_filter); } } // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) { - Strings::shift($payload, 1); - list($this->banner_message) = Strings::unpackSSH2('s', $payload); - $payload = $this->get_binary_packet(); + $this->_string_shift($payload, 1); + if (strlen($payload) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($payload, 4))); + $this->banner_message = $this->_string_shift($payload, $length); + $payload = $this->_get_binary_packet(); } // only called when we've already logged in @@ -3514,9 +3540,9 @@ class SSH2 extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { if (ord(substr($payload, 9 + $length))) { // want reply - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); } - $payload = $this->get_binary_packet($skip_channel_filter); + $payload = $this->_get_binary_packet($skip_channel_filter); } } break; @@ -3526,36 +3552,45 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_EOF: if (!$skip_channel_filter && !empty($this->server_channels)) { $this->binary_packet_buffer = $payload; - $this->get_channel_packet(true); - $payload = $this->get_binary_packet(); + $this->_get_channel_packet(true); + $payload = $this->_get_binary_packet(); } break; case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4 - Strings::shift($payload, 1); - list($request_name) = Strings::unpackSSH2('s', $payload); - $this->errors[] = "SSH_MSG_GLOBAL_REQUEST: $request_name"; - - try { - $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE)); - } catch (\RuntimeException $e) { - return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + if (strlen($payload) < 4) { + return false; } + extract(unpack('Nlength', $this->_string_shift($payload, 4))); + $this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . $this->_string_shift($payload, $length); - $payload = $this->get_binary_packet($skip_channel_filter); + if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) { + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + + $payload = $this->_get_binary_packet($skip_channel_filter); break; case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1 - Strings::shift($payload, 1); - list($data, $server_channel) = Strings::unpackSSH2('sN', $payload); + $this->_string_shift($payload, 1); + if (strlen($payload) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($payload, 4))); + $data = $this->_string_shift($payload, $length); + if (strlen($payload) < 4) { + return false; + } + extract(unpack('Nserver_channel', $this->_string_shift($payload, 4))); switch ($data) { case 'auth-agent': case 'auth-agent@openssh.com': if (isset($this->agent)) { $new_channel = self::CHANNEL_AGENT_FORWARD; - list( - $remote_window_size, - $remote_maximum_packet_size - ) = Strings::unpackSSH2('NN', $payload); + if (strlen($payload) < 8) { + return false; + } + extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4))); + extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4))); $this->packet_size_client_to_server[$new_channel] = $remote_window_size; $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size; @@ -3574,35 +3609,39 @@ class SSH2 $this->server_channels[$new_channel] = $server_channel; $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION; - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } } break; default: - $packet = Strings::packSSH2( - 'CN2ss', - NET_SSH2_MSG_CHANNEL_OPEN_FAILURE, + $packet = pack( + 'CN3a*Na*', + NET_SSH2_MSG_REQUEST_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, - '', // description - '' // language tag + 0, + '', + 0, + '' ); - try { - $this->send_binary_packet($packet); - } catch (\RuntimeException $e) { - return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + if (!$this->_send_binary_packet($packet)) { + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } } - - $payload = $this->get_binary_packet($skip_channel_filter); + $payload = $this->_get_binary_packet($skip_channel_filter); break; case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST: - Strings::shift($payload, 1); - list($channel, $window_size) = Strings::unpackSSH2('NN', $payload); - + $this->_string_shift($payload, 1); + if (strlen($payload) < 8) { + return false; + } + extract(unpack('Nchannel', $this->_string_shift($payload, 4))); + extract(unpack('Nwindow_size', $this->_string_shift($payload, 4))); $this->window_size_client_to_server[$channel]+= $window_size; - $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->get_binary_packet($skip_channel_filter); + $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet($skip_channel_filter); } } @@ -3616,7 +3655,7 @@ class SSH2 * * @access public */ - public function enableQuietMode() + function enableQuietMode() { $this->quiet_mode = true; } @@ -3628,7 +3667,7 @@ class SSH2 * * @access public */ - public function disableQuietMode() + function disableQuietMode() { $this->quiet_mode = false; } @@ -3641,7 +3680,7 @@ class SSH2 * @access public * @return bool */ - public function isQuietModeEnabled() + function isQuietModeEnabled() { return $this->quiet_mode; } @@ -3651,7 +3690,7 @@ class SSH2 * * @access public */ - public function enablePTY() + function enablePTY() { $this->request_pty = true; } @@ -3661,10 +3700,10 @@ class SSH2 * * @access public */ - public function disablePTY() + function disablePTY() { if ($this->in_request_pty_exec) { - $this->close_channel(self::CHANNEL_EXEC); + $this->_close_channel(self::CHANNEL_EXEC); $this->in_request_pty_exec = false; } $this->request_pty = false; @@ -3678,7 +3717,7 @@ class SSH2 * @access public * @return bool */ - public function isPTYEnabled() + function isPTYEnabled() { return $this->request_pty; } @@ -3690,11 +3729,10 @@ class SSH2 * * @param int $client_channel * @param bool $skip_extended - * @return mixed - * @throws \RuntimeException on connection error + * @return mixed|bool * @access private */ - protected function get_channel_packet($client_channel, $skip_extended = false) + function _get_channel_packet($client_channel, $skip_extended = false) { if (!empty($this->channel_buffers[$client_channel])) { return array_shift($this->channel_buffers[$client_channel]); @@ -3705,23 +3743,36 @@ class SSH2 $response = $this->binary_packet_buffer; $this->binary_packet_buffer = false; } else { - $response = $this->get_binary_packet(true); + $response = $this->_get_binary_packet(true); if ($response === true && $this->is_timeout) { if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { - $this->close_channel($client_channel); + $this->_close_channel($client_channel); } return true; } if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + $this->bitmap = 0; + user_error('Connection closed by server'); + return false; } } if ($client_channel == -1 && $response === true) { return true; } - list($type, $channel) = Strings::unpackSSH2('CN', $response); + if (!strlen($response)) { + return false; + } + extract(unpack('Ctype', $this->_string_shift($response, 1))); + + if (strlen($response) < 4) { + return false; + } + if ($type == NET_SSH2_MSG_CHANNEL_OPEN) { + extract(unpack('Nlength', $this->_string_shift($response, 4))); + } else { + extract(unpack('Nchannel', $this->_string_shift($response, 4))); + } // will not be setup yet on incoming channel open request if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) { @@ -3732,7 +3783,9 @@ class SSH2 // PuTTY does something more analogous to the following: //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) { $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } $this->window_size_server_to_client[$channel]+= $this->window_resize; } @@ -3740,11 +3793,15 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: /* if ($client_channel == self::CHANNEL_EXEC) { - $this->send_channel_packet($client_channel, chr(0)); + $this->_send_channel_packet($client_channel, chr(0)); } */ // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR - list($data_type_code, $data) = Strings::unpackSSH2('Ns', $response); + if (strlen($response) < 8) { + return false; + } + extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8))); + $data = $this->_string_shift($response, $length); $this->stdErrorLog.= $data; if ($skip_extended || $this->quiet_mode) { continue 2; @@ -3753,7 +3810,7 @@ class SSH2 return $data; } if (!isset($this->channel_buffers[$channel])) { - $this->channel_buffers[$channel] = []; + $this->channel_buffers[$channel] = array(); } $this->channel_buffers[$channel][] = $data; @@ -3762,29 +3819,40 @@ class SSH2 if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) { continue 2; } - list($value) = Strings::unpackSSH2('s', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $value = $this->_string_shift($response, $length); switch ($value) { case 'exit-signal': - list( - , // FALSE - $signal_name, - , // core dumped - $error_message - ) = Strings::unpackSSH2('bsbs', $response); - - $this->errors[] = "SSH_MSG_CHANNEL_REQUEST (exit-signal): $signal_name"; - if (strlen($error_message)) { - $this->errors[count($this->errors) - 1].= "\r\n$error_message"; + $this->_string_shift($response, 1); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length); + $this->_string_shift($response, 1); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + if ($length) { + $this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length); } - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF; continue 3; case 'exit-status': - list(, $this->exit_status) = Strings::unpackSSH2('CN', $response); + if (strlen($response) < 5) { + return false; + } + extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5))); + $this->exit_status = $exit_status; // "The client MAY ignore these messages." // -- http://tools.ietf.org/html/rfc4254#section-6.10 @@ -3801,24 +3869,32 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_OPEN: switch ($type) { case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: - list( - $this->server_channels[$channel], - $window_size, - $this->packet_size_client_to_server[$channel] - ) = Strings::unpackSSH2('NNN', $response); - + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nserver_channel', $this->_string_shift($response, 4))); + $this->server_channels[$channel] = $server_channel; + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nwindow_size', $this->_string_shift($response, 4))); if ($window_size < 0) { $window_size&= 0x7FFFFFFF; $window_size+= 0x80000000; } $this->window_size_client_to_server[$channel] = $window_size; - $result = $client_channel == $channel ? true : $this->get_channel_packet($client_channel, $skip_extended); - $this->on_channel_open(); + if (strlen($response) < 4) { + return false; + } + $temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4)); + $this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server']; + $result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended); + $this->_on_channel_open(); return $result; //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Unable to open channel'); + user_error('Unable to open channel'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } break; case NET_SSH2_MSG_CHANNEL_REQUEST: @@ -3828,11 +3904,11 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_FAILURE: return false; default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Unable to fulfill channel request'); + user_error('Unable to fulfill channel request'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } case NET_SSH2_MSG_CHANNEL_CLOSE: - return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->get_channel_packet($client_channel, $skip_extended); + return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended); } } @@ -3846,15 +3922,19 @@ class SSH2 // this actually seems to make things twice as fast. more to the point, the message right after // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise. // in OpenSSH it slows things down but only by a couple thousandths of a second. - $this->send_channel_packet($channel, chr(0)); + $this->_send_channel_packet($channel, chr(0)); } */ - list($data) = Strings::unpackSSH2('s', $response); + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($response, 4))); + $data = $this->_string_shift($response, $length); if ($channel == self::CHANNEL_AGENT_FORWARD) { - $agent_response = $this->agent->forwardData($data); + $agent_response = $this->agent->_forward_data($data); if (!is_bool($agent_response)) { - $this->send_channel_packet($channel, $agent_response); + $this->_send_channel_packet($channel, $agent_response); } break; } @@ -3863,7 +3943,7 @@ class SSH2 return $data; } if (!isset($this->channel_buffers[$channel])) { - $this->channel_buffers[$channel] = []; + $this->channel_buffers[$channel] = array(); } $this->channel_buffers[$channel][] = $data; break; @@ -3874,7 +3954,7 @@ class SSH2 $this->bitmap&= ~self::MASK_SHELL; } if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); } $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; @@ -3884,8 +3964,8 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_EOF: break; default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Error reading channel data'); + user_error('Error reading channel data'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } } } @@ -3901,11 +3981,12 @@ class SSH2 * @return bool * @access private */ - protected function send_binary_packet($data, $logged = null) + function _send_binary_packet($data, $logged = null) { if (!is_resource($this->fsock) || feof($this->fsock)) { $this->bitmap = 0; - throw new ConnectionClosedException('Connection closed prematurely'); + user_error('Connection closed prematurely'); + return false; } //if ($this->compress) { @@ -3916,88 +3997,26 @@ class SSH2 // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9 $packet_length = strlen($data) + 9; - if ($this->encrypt && $this->encrypt->usesNonce()) { - $packet_length-= 4; - } // round up to the nearest $this->encrypt_block_size $packet_length+= (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size; // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length $padding_length = $packet_length - strlen($data) - 5; - switch (true) { - case $this->encrypt && $this->encrypt->usesNonce(): - case $this->hmac_create instanceof Hash && $this->hmac_create->etm: - $padding_length+= 4; - $packet_length+= 4; - } - $padding = Random::string($padding_length); // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding); - $hmac = ''; - if ($this->hmac_create instanceof Hash && !$this->hmac_create->etm) { - if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { - $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); - $hmac = $this->hmac_create->hash($packet); - } else { - $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); - } - } - - if ($this->encrypt) { - switch ($this->encrypt->name) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - $this->encrypt->setNonce( - $this->encrypt->fixed . - $this->encrypt->invocation_counter - ); - Strings::increment_str($this->encrypt->invocation_counter); - $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF")); - $packet = $temp . $this->encrypt->encrypt(substr($packet, 4)); - break; - case 'chacha20-poly1305@openssh.com': - $nonce = pack('N2', 0, $this->send_seq_no); - - $this->encrypt->setNonce($nonce); - $this->lengthEncrypt->setNonce($nonce); - - $length = $this->lengthEncrypt->encrypt($packet & "\xFF\xFF\xFF\xFF"); - - $this->encrypt->setCounter(0); - // this is the same approach that's implemented in Salsa20::createPoly1305Key() - // but we don't want to use the same AEAD construction that RFC8439 describes - // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) - $this->encrypt->setPoly1305Key( - $this->encrypt->encrypt(str_repeat("\0", 32)) - ); - $this->encrypt->setAAD($length); - $this->encrypt->setCounter(1); - $packet = $length . $this->encrypt->encrypt(substr($packet, 4)); - break; - default: - $packet = $this->hmac_create instanceof Hash && $this->hmac_create->etm ? - ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) : - $this->encrypt->encrypt($packet); - } - } + $hmac = $this->hmac_create !== false ? $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)) : ''; + $this->send_seq_no++; - if ($this->hmac_create instanceof Hash && $this->hmac_create->etm) { - if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { - $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); - $hmac = $this->hmac_create->hash($packet); - } else { - $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); - } + if ($this->encrypt !== false) { + $packet = $this->encrypt->encrypt($packet); } - $this->send_seq_no++; - - $packet.= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac; + $packet.= $hmac; $start = microtime(true); - $sent = @fputs($this->fsock, $packet); + $result = strlen($packet) == @fputs($this->fsock, $packet); $stop = microtime(true); if (defined('NET_SSH2_LOGGING')) { @@ -4005,14 +4024,11 @@ class SSH2 $message_number = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN (' . ord($data[0]) . ')'; $message_number = '-> ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; - $this->append_log($message_number, isset($logged) ? $logged : $data); + $this->_append_log($message_number, isset($logged) ? $logged : $data); $this->last_packet = $current; } - if (strlen($packet) != $sent) { - $this->bitmap = 0; - throw new \RuntimeException("Only $sent of " . strlen($packet) . " bytes were sent"); - } + return $result; } /** @@ -4024,11 +4040,11 @@ class SSH2 * @param string $message * @access private */ - private function append_log($message_number, $message) + function _append_log($message_number, $message) { // remove the byte identifying the message type from all but the first two messages (ie. the identification strings) if (strlen($message_number) > 2) { - Strings::shift($message); + $this->_string_shift($message); } switch (NET_SSH2_LOGGING) { @@ -4058,25 +4074,25 @@ class SSH2 $start = '
      ';
                               $stop = '
      '; } - echo $start . $this->format_log([$message], [$message_number]) . $stop; + echo $start . $this->_format_log(array($message), array($message_number)) . $stop; @flush(); @ob_flush(); break; - // basically the same thing as self::LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILENAME + // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily // at the beginning of the file case self::LOG_REALTIME_FILE: if (!isset($this->realtime_log_file)) { // PHP doesn't seem to like using constants in fopen() - $filename = NET_SSH2_LOG_REALTIME_FILENAME; + $filename = self::LOG_REALTIME_FILENAME; $fp = fopen($filename, 'w'); $this->realtime_log_file = $fp; } if (!is_resource($this->realtime_log_file)) { break; } - $entry = $this->format_log([$message], [$message_number]); + $entry = $this->_format_log(array($message), array($message_number)); if ($this->realtime_log_wrap) { $temp = "<<< START >>>\r\n"; $entry.= $temp; @@ -4102,13 +4118,13 @@ class SSH2 * @return bool * @access private */ - protected function send_channel_packet($client_channel, $data) + function _send_channel_packet($client_channel, $data) { while (strlen($data)) { if (!$this->window_size_client_to_server[$client_channel]) { $this->bitmap^= self::MASK_WINDOW_ADJUST; // using an invalid channel will let the buffers be built up for the valid channels - $this->get_channel_packet(-1); + $this->_get_channel_packet(-1); $this->bitmap^= self::MASK_WINDOW_ADJUST; } @@ -4121,15 +4137,18 @@ class SSH2 $this->window_size_client_to_server[$client_channel] ); - $temp = Strings::shift($data, $max_size); - $packet = Strings::packSSH2( - 'CNs', + $temp = $this->_string_shift($data, $max_size); + $packet = pack( + 'CN2a*', NET_SSH2_MSG_CHANNEL_DATA, $this->server_channels[$client_channel], + strlen($temp), $temp ); $this->window_size_client_to_server[$client_channel]-= strlen($temp); - $this->send_binary_packet($packet); + if (!$this->_send_binary_packet($packet)) { + return false; + } } return true; @@ -4138,7 +4157,7 @@ class SSH2 /** * Closes and flushes a channel * - * \phpseclib3\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server + * \phpseclib\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server * and for SFTP channels are presumably closed when the client disconnects. This functions is intended * for SCP more than anything. * @@ -4147,21 +4166,21 @@ class SSH2 * @return bool * @access private */ - private function close_channel($client_channel, $want_reply = false) + function _close_channel($client_channel, $want_reply = false) { // see http://tools.ietf.org/html/rfc4254#section-5.3 - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); if (!$want_reply) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); } $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; $this->curTimeout = 5; - while (!is_bool($this->get_channel_packet($client_channel))) { + while (!is_bool($this->_get_channel_packet($client_channel))) { } if ($this->is_timeout) { @@ -4169,7 +4188,7 @@ class SSH2 } if ($want_reply) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); } if ($this->bitmap & self::MASK_SHELL) { @@ -4182,16 +4201,13 @@ class SSH2 * * @param int $reason * @return bool - * @access protected + * @access private */ - protected function disconnect_helper($reason) + function _disconnect($reason) { if ($this->bitmap & self::MASK_CONNECTED) { - $data = Strings::packSSH2('CNss', NET_SSH2_MSG_DISCONNECT, $reason, '', ''); - try { - $this->send_binary_packet($data); - } catch (\Exception $e) { - } + $data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, ''); + $this->_send_binary_packet($data); } $this->bitmap = 0; @@ -4202,6 +4218,23 @@ class SSH2 return false; } + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + * @access private + */ + function _string_shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } + /** * Define Array * @@ -4209,11 +4242,11 @@ class SSH2 * named constants from it, using the value as the name of the constant and the index as the value of the constant. * If any of the constants that would be defined already exists, none of the constants will be defined. * - * @param mixed[] ...$args - * @access protected + * @access private */ - protected function define_array(...$args) + function _define_array() { + $args = func_get_args(); foreach ($args as $arg) { foreach ($arg as $key => $value) { if (!defined($value)) { @@ -4233,7 +4266,7 @@ class SSH2 * @access public * @return array|false|string */ - public function getLog() + function getLog() { if (!defined('NET_SSH2_LOGGING')) { return false; @@ -4243,7 +4276,7 @@ class SSH2 case self::LOG_SIMPLE: return $this->message_number_log; case self::LOG_COMPLEX: - $log = $this->format_log($this->message_log, $this->message_number_log); + $log = $this->_format_log($this->message_log, $this->message_number_log); return PHP_SAPI == 'cli' ? $log : '
      ' . $log . '
      '; default: return false; @@ -4258,7 +4291,7 @@ class SSH2 * @access private * @return string */ - protected function format_log($message_log, $message_number_log) + function _format_log($message_log, $message_number_log) { $output = ''; for ($i = 0; $i < count($message_log); $i++) { @@ -4269,10 +4302,8 @@ class SSH2 if (strlen($current_log)) { $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; } - $fragment = Strings::shift($current_log, $this->log_short_width); - $hex = substr(preg_replace_callback('#.#s', function ($matches) { - return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); - }, $fragment), strlen($this->log_boundary)); + $fragment = $this->_string_shift($current_log, $this->log_short_width); + $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary)); // replace non ASCII printable characters with dots // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters // also replace < with a . since < messes up the output on web browsers @@ -4287,7 +4318,21 @@ class SSH2 } /** - * Helper function for agent->on_channel_open() + * Helper function for _format_log + * + * For use with preg_replace_callback() + * + * @param array $matches + * @access private + * @return string + */ + function _format_log_helper($matches) + { + return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); + } + + /** + * Helper function for agent->_on_channel_open() * * Used when channels are created to inform agent * of said channel opening. Must be called after @@ -4295,10 +4340,10 @@ class SSH2 * * @access private */ - private function on_channel_open() + function _on_channel_open() { if (isset($this->agent)) { - $this->agent->registerChannelOpen($this); + $this->agent->_on_channel_open($this); } } @@ -4311,7 +4356,7 @@ class SSH2 * @return mixed False if intersection is empty, else intersected value. * @access private */ - private static function array_intersect_first($array1, $array2) + function _array_intersect_first($array1, $array2) { foreach ($array1 as $value) { if (in_array($value, $array2)) { @@ -4327,7 +4372,7 @@ class SSH2 * @return string[] * @access public */ - public function getErrors() + function getErrors() { return $this->errors; } @@ -4338,7 +4383,7 @@ class SSH2 * @return string * @access public */ - public function getLastError() + function getLastError() { $count = count($this->errors); @@ -4353,39 +4398,169 @@ class SSH2 * @return string * @access public */ - public function getServerIdentification() + function getServerIdentification() { - $this->connect(); + $this->_connect(); return $this->server_identifier; } + /** + * Return a list of the key exchange algorithms the server supports. + * + * @return array + * @access public + */ + function getKexAlgorithms() + { + $this->_connect(); + + return $this->kex_algorithms; + } + + /** + * Return a list of the host key (public key) algorithms the server supports. + * + * @return array + * @access public + */ + function getServerHostKeyAlgorithms() + { + $this->_connect(); + + return $this->server_host_key_algorithms; + } + + /** + * Return a list of the (symmetric key) encryption algorithms the server supports, when receiving stuff from the client. + * + * @return array + * @access public + */ + function getEncryptionAlgorithmsClient2Server() + { + $this->_connect(); + + return $this->encryption_algorithms_client_to_server; + } + + /** + * Return a list of the (symmetric key) encryption algorithms the server supports, when sending stuff to the client. + * + * @return array + * @access public + */ + function getEncryptionAlgorithmsServer2Client() + { + $this->_connect(); + + return $this->encryption_algorithms_server_to_client; + } + + /** + * Return a list of the MAC algorithms the server supports, when receiving stuff from the client. + * + * @return array + * @access public + */ + function getMACAlgorithmsClient2Server() + { + $this->_connect(); + + return $this->mac_algorithms_client_to_server; + } + + /** + * Return a list of the MAC algorithms the server supports, when sending stuff to the client. + * + * @return array + * @access public + */ + function getMACAlgorithmsServer2Client() + { + $this->_connect(); + + return $this->mac_algorithms_server_to_client; + } + + /** + * Return a list of the compression algorithms the server supports, when receiving stuff from the client. + * + * @return array + * @access public + */ + function getCompressionAlgorithmsClient2Server() + { + $this->_connect(); + + return $this->compression_algorithms_client_to_server; + } + + /** + * Return a list of the compression algorithms the server supports, when sending stuff to the client. + * + * @return array + * @access public + */ + function getCompressionAlgorithmsServer2Client() + { + $this->_connect(); + + return $this->compression_algorithms_server_to_client; + } + + /** + * Return a list of the languages the server supports, when sending stuff to the client. + * + * @return array + * @access public + */ + function getLanguagesServer2Client() + { + $this->_connect(); + + return $this->languages_server_to_client; + } + + /** + * Return a list of the languages the server supports, when receiving stuff from the client. + * + * @return array + * @access public + */ + function getLanguagesClient2Server() + { + $this->_connect(); + + return $this->languages_client_to_server; + } + /** * Returns a list of algorithms the server supports * * @return array * @access public */ - public function getServerAlgorithms() + function getServerAlgorithms() { - $this->connect(); + $this->_connect(); - return [ + return array( 'kex' => $this->kex_algorithms, 'hostkey' => $this->server_host_key_algorithms, - 'client_to_server' => [ + 'client_to_server' => array( 'crypt' => $this->encryption_algorithms_client_to_server, 'mac' => $this->mac_algorithms_client_to_server, 'comp' => $this->compression_algorithms_client_to_server, 'lang' => $this->languages_client_to_server - ], - 'server_to_client' => [ + ), + 'server_to_client' => array( 'crypt' => $this->encryption_algorithms_server_to_client, 'mac' => $this->mac_algorithms_server_to_client, 'comp' => $this->compression_algorithms_server_to_client, 'lang' => $this->languages_server_to_client - ] - ]; + ) + ); } /** @@ -4394,33 +4569,29 @@ class SSH2 * @return array * @access public */ - public static function getSupportedKEXAlgorithms() + function getSupportedKEXAlgorithms() { - $kex_algorithms = [ + $kex_algorithms = array( // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the // libssh repository for more information. - 'curve25519-sha256', 'curve25519-sha256@libssh.org', - 'ecdh-sha2-nistp256', // RFC 5656 - 'ecdh-sha2-nistp384', // RFC 5656 - 'ecdh-sha2-nistp521', // RFC 5656 - 'diffie-hellman-group-exchange-sha256',// RFC 4419 'diffie-hellman-group-exchange-sha1', // RFC 4419 // Diffie-Hellman Key Agreement (DH) using integer modulo prime // groups. - 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1', // REQUIRED - 'diffie-hellman-group15-sha512', - 'diffie-hellman-group16-sha512', - 'diffie-hellman-group17-sha512', - 'diffie-hellman-group18-sha512', - 'diffie-hellman-group1-sha1', // REQUIRED - ]; + ); + + if (!function_exists('sodium_crypto_box_publickey_from_secretkey')) { + $kex_algorithms = array_diff( + $kex_algorithms, + array('curve25519-sha256@libssh.org') + ); + } return $kex_algorithms; } @@ -4431,18 +4602,14 @@ class SSH2 * @return array * @access public */ - public static function getSupportedHostKeyAlgorithms() + function getSupportedHostKeyAlgorithms() { - return [ - 'ssh-ed25519', // https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-02 - 'ecdsa-sha2-nistp256', // RFC 5656 - 'ecdsa-sha2-nistp384', // RFC 5656 - 'ecdsa-sha2-nistp521', // RFC 5656 + return array( 'rsa-sha2-256', // RFC 8332 'rsa-sha2-512', // RFC 8332 'ssh-rsa', // RECOMMENDED sign Raw RSA Key 'ssh-dss' // REQUIRED sign Raw DSS Key - ]; + ); } /** @@ -4451,13 +4618,9 @@ class SSH2 * @return array * @access public */ - public static function getSupportedEncryptionAlgorithms() + function getSupportedEncryptionAlgorithms() { - $algos = [ - // from : - 'aes128-gcm@openssh.com', - 'aes256-gcm@openssh.com', - + $algos = array( // from : 'arcfour256', 'arcfour128', @@ -4469,16 +4632,6 @@ class SSH2 'aes192-ctr', // RECOMMENDED AES with 192-bit key 'aes256-ctr', // RECOMMENDED AES with 256-bit key - // from : - // one of the big benefits of chacha20-poly1305 is speed. the problem is... - // libsodium doesn't generate the poly1305 keys in the way ssh does and openssl's PHP bindings don't even - // seem to support poly1305 currently. so even if libsodium or openssl are being used for the chacha20 - // part, pure-PHP has to be used for the poly1305 part and that's gonna cause a big slow down. - // speed-wise it winds up being faster to use AES (when openssl or mcrypt are available) and some HMAC - // (which is always gonna be super fast to compute thanks to the hash extension, which - // "is bundled and compiled into PHP by default") - 'chacha20-poly1305@openssh.com', - 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key @@ -4502,46 +4655,34 @@ class SSH2 '3des-cbc', // REQUIRED three-key 3DES in CBC mode //'none' // OPTIONAL no encryption; NOT RECOMMENDED - ]; + ); - if (self::$crypto_engine) { - $engines = [self::$crypto_engine]; + if ($this->crypto_engine) { + $engines = array($this->crypto_engine); } else { - $engines = [ - 'libsodium', - 'OpenSSL (GCM)', - 'OpenSSL', - 'mcrypt', - 'Eval', - 'PHP' - ]; + $engines = array( + Base::ENGINE_OPENSSL, + Base::ENGINE_MCRYPT, + Base::ENGINE_INTERNAL + ); } - $ciphers = []; - + $ciphers = array(); foreach ($engines as $engine) { foreach ($algos as $algo) { - $obj = self::encryption_algorithm_to_crypt_instance($algo); - if ($obj instanceof Rijndael ) { + $obj = $this->_encryption_algorithm_to_crypt_instance($algo); + if ($obj instanceof Rijndael) { $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo)); } switch ($algo) { - case 'chacha20-poly1305@openssh.com': case 'arcfour128': case 'arcfour256': - if ($engine != 'Eval') { + if ($engine != Base::ENGINE_INTERNAL) { continue 2; } - break; - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - if ($engine == 'OpenSSL') { - continue 2; - } - $obj->setNonce('dummydummydu'); } if ($obj->isValidEngine($engine)) { - $algos = array_diff($algos, [$algo]); + $algos = array_diff($algos, array($algo)); $ciphers[] = $algo; } } @@ -4556,29 +4697,18 @@ class SSH2 * @return array * @access public */ - public static function getSupportedMACAlgorithms() + function getSupportedMACAlgorithms() { - return [ - 'hmac-sha2-256-etm@openssh.com', - 'hmac-sha2-512-etm@openssh.com', - 'umac-64-etm@openssh.com', - 'umac-128-etm@openssh.com', - 'hmac-sha1-etm@openssh.com', - + return array( // from : 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32) - 'hmac-sha2-512',// OPTIONAL HMAC-SHA512 (digest length = key length = 64) - - // from : - 'umac-64@openssh.com', - 'umac-128@openssh.com', 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20) 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20) 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16) 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16) //'none' // OPTIONAL no MAC; NOT RECOMMENDED - ]; + ); } /** @@ -4587,12 +4717,12 @@ class SSH2 * @return array * @access public */ - public static function getSupportedCompressionAlgorithms() + function getSupportedCompressionAlgorithms() { - return [ + return array( 'none' // REQUIRED no compression //'zlib' // OPTIONAL ZLIB (LZ77) compression - ]; + ); } /** @@ -4603,24 +4733,24 @@ class SSH2 * @return array * @access public */ - public function getAlgorithmsNegotiated() + function getAlgorithmsNegotiated() { - $this->connect(); + $this->_connect(); - return [ + return array( 'kex' => $this->kex_algorithm, 'hostkey' => $this->signature_format, - 'client_to_server' => [ + 'client_to_server' => array( 'crypt' => $this->encrypt->name, 'mac' => $this->hmac_create->name, 'comp' => 'none', - ], - 'server_to_client' => [ + ), + 'server_to_client' => array( 'crypt' => $this->decrypt->name, 'mac' => $this->hmac_check->name, 'comp' => 'none', - ] - ]; + ) + ); } /** @@ -4630,50 +4760,50 @@ class SSH2 * @param array $methods * @access public */ - public function setPreferredAlgorithms(array $methods) + function setPreferredAlgorithms($methods) { $preferred = $methods; if (isset($preferred['kex'])) { $preferred['kex'] = array_intersect( $preferred['kex'], - static::getSupportedKEXAlgorithms() + $this->getSupportedKEXAlgorithms() ); } if (isset($preferred['hostkey'])) { $preferred['hostkey'] = array_intersect( $preferred['hostkey'], - static::getSupportedHostKeyAlgorithms() + $this->getSupportedHostKeyAlgorithms() ); } - $keys = ['client_to_server', 'server_to_client']; + $keys = array('client_to_server', 'server_to_client'); foreach ($keys as $key) { if (isset($preferred[$key])) { $a = &$preferred[$key]; if (isset($a['crypt'])) { $a['crypt'] = array_intersect( $a['crypt'], - static::getSupportedEncryptionAlgorithms() + $this->getSupportedEncryptionAlgorithms() ); } if (isset($a['comp'])) { $a['comp'] = array_intersect( $a['comp'], - static::getSupportedCompressionAlgorithms() + $this->getSupportedCompressionAlgorithms() ); } if (isset($a['mac'])) { $a['mac'] = array_intersect( $a['mac'], - static::getSupportedMACAlgorithms() + $this->getSupportedMACAlgorithms() ); } } } - $keys = [ + $keys = array( 'kex', 'hostkey', 'client_to_server/crypt', @@ -4682,7 +4812,7 @@ class SSH2 'server_to_client/crypt', 'server_to_client/comp', 'server_to_client/mac', - ]; + ); foreach ($keys as $key) { $p = $preferred; $m = $methods; @@ -4701,7 +4831,8 @@ class SSH2 $msg = count($diff) == 1 ? ' is not a supported algorithm' : ' are not supported algorithms'; - throw new UnsupportedAlgorithmException(implode(', ', $diff) . $msg); + user_error(implode(', ', $diff) . $msg); + return false; } } @@ -4717,7 +4848,7 @@ class SSH2 * @return string * @access public */ - public function getBannerMessage() + function getBannerMessage() { return $this->banner_message; } @@ -4729,68 +4860,169 @@ class SSH2 * is recommended. Returns false if the server signature is not signed correctly with the public host key. * * @return mixed - * @throws \RuntimeException on badly formatted keys - * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format * @access public */ - public function getServerPublicHostKey() + function getServerPublicHostKey() { if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { - if (!$this->connect()) { + if (!$this->_connect()) { return false; } } $signature = $this->signature; - $server_public_host_key = base64_encode($this->server_public_host_key); + $server_public_host_key = $this->server_public_host_key; + + if (strlen($server_public_host_key) < 4) { + return false; + } + extract(unpack('Nlength', $this->_string_shift($server_public_host_key, 4))); + $this->_string_shift($server_public_host_key, $length); if ($this->signature_validated) { return $this->bitmap ? - $this->signature_format . ' ' . $server_public_host_key : + $this->signature_format . ' ' . base64_encode($this->server_public_host_key) : false; } $this->signature_validated = true; switch ($this->signature_format) { - case 'ssh-ed25519': - case 'ecdsa-sha2-nistp256': - case 'ecdsa-sha2-nistp384': - case 'ecdsa-sha2-nistp521': - $key = EC::loadFormat('OpenSSH', $server_public_host_key) - ->withSignatureFormat('SSH2'); + case 'ssh-dss': + $zero = new BigInteger(); + + if (strlen($server_public_host_key) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); + $p = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); + + if (strlen($server_public_host_key) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); + $q = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); + + if (strlen($server_public_host_key) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); + $g = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); + + if (strlen($server_public_host_key) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); + $y = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); + + /* The value for 'dss_signature_blob' is encoded as a string containing + r, followed by s (which are 160-bit integers, without lengths or + padding, unsigned, and in network byte order). */ + $temp = unpack('Nlength', $this->_string_shift($signature, 4)); + if ($temp['length'] != 40) { + user_error('Invalid signature'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $r = new BigInteger($this->_string_shift($signature, 20), 256); + $s = new BigInteger($this->_string_shift($signature, 20), 256); + + switch (true) { + case $r->equals($zero): + case $r->compare($q) >= 0: + case $s->equals($zero): + case $s->compare($q) >= 0: + user_error('Invalid signature'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $w = $s->modInverse($q); + + $u1 = $w->multiply(new BigInteger(sha1($this->exchange_hash), 16)); + list(, $u1) = $u1->divide($q); + + $u2 = $w->multiply($r); + list(, $u2) = $u2->divide($q); + + $g = $g->modPow($u1, $p); + $y = $y->modPow($u2, $p); + + $v = $g->multiply($y); + list(, $v) = $v->divide($p); + list(, $v) = $v->divide($q); + + if (!$v->equals($r)) { + user_error('Bad server signature'); + return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + } + + break; + case 'ssh-rsa': + case 'rsa-sha2-256': + case 'rsa-sha2-512': + if (strlen($server_public_host_key) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); + $e = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); + + if (strlen($server_public_host_key) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); + $rawN = $this->_string_shift($server_public_host_key, $temp['length']); + $n = new BigInteger($rawN, -256); + $nLength = strlen(ltrim($rawN, "\0")); + + /* + if (strlen($signature) < 4) { + return false; + } + $temp = unpack('Nlength', $this->_string_shift($signature, 4)); + $signature = $this->_string_shift($signature, $temp['length']); + + $rsa = new RSA(); switch ($this->signature_format) { - case 'ssh-ed25519': + case 'rsa-sha2-512': $hash = 'sha512'; break; - case 'ecdsa-sha2-nistp256': + case 'rsa-sha2-256': $hash = 'sha256'; break; - case 'ecdsa-sha2-nistp384': - $hash = 'sha384'; - break; - case 'ecdsa-sha2-nistp521': - $hash = 'sha512'; + //case 'ssh-rsa': + default: + $hash = 'sha1'; } - $key = $key->withHash($hash); - break; - case 'ssh-dss': - $key = DSA::loadFormat('OpenSSH', $server_public_host_key) - ->withSignatureFormat('SSH2') - ->withHash('sha1'); - break; - case 'ssh-rsa': - case 'rsa-sha2-256': - case 'rsa-sha2-512': - if (strlen($signature) < 15) { + $rsa->setHash($hash); + $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); + $rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW); + + if (!$rsa->verify($this->exchange_hash, $signature)) { + user_error('Bad server signature'); + return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + } + */ + + if (strlen($signature) < 4) { return false; } - Strings::shift($signature, 11); - $temp = unpack('Nlength', Strings::shift($signature, 4)); - $signature = Strings::shift($signature, $temp['length']); + $temp = unpack('Nlength', $this->_string_shift($signature, 4)); + $s = new BigInteger($this->_string_shift($signature, $temp['length']), 256); + + // validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the + // following URL: + // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf + + // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source. + + if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) { + user_error('Invalid signature'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $s = $s->modPow($e, $n); + $s = $s->toBytes(); - $key = RSA::loadFormat('OpenSSH', $server_public_host_key) - ->withPadding(RSA::SIGNATURE_PKCS1); switch ($this->signature_format) { case 'rsa-sha2-512': $hash = 'sha512'; @@ -4802,18 +5034,32 @@ class SSH2 default: $hash = 'sha1'; } - $key = $key->withHash($hash); + $hashObj = new Hash($hash); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash)); + break; + case 'rsa-sha2-256': + $h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash)); + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + $h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash)); + } + $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h; + + if ($s != $h) { + user_error('Bad server signature'); + return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + } break; default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - throw new NoSupportedAlgorithmsException('Unsupported signature format'); + user_error('Unsupported signature format'); + return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } - if (!$key->verify($this->exchange_hash, $signature)) { - return $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - }; - - return $this->signature_format . ' ' . $server_public_host_key; + return $this->signature_format . ' ' . base64_encode($this->server_public_host_key); } /** @@ -4822,7 +5068,7 @@ class SSH2 * @return false|int * @access public */ - public function getExitStatus() + function getExitStatus() { if (is_null($this->exit_status)) { return false; @@ -4836,7 +5082,7 @@ class SSH2 * @return int * @access public */ - public function getWindowColumns() + function getWindowColumns() { return $this->windowColumns; } @@ -4847,7 +5093,7 @@ class SSH2 * @return int * @access public */ - public function getWindowRows() + function getWindowRows() { return $this->windowRows; } @@ -4858,7 +5104,7 @@ class SSH2 * @param int $value * @access public */ - public function setWindowColumns($value) + function setWindowColumns($value) { $this->windowColumns = $value; } @@ -4869,7 +5115,7 @@ class SSH2 * @param int $value * @access public */ - public function setWindowRows($value) + function setWindowRows($value) { $this->windowRows = $value; } @@ -4881,68 +5127,20 @@ class SSH2 * @param int $rows * @access public */ - public function setWindowSize($columns = 80, $rows = 24) + function setWindowSize($columns = 80, $rows = 24) { $this->windowColumns = $columns; $this->windowRows = $rows; } /** - * To String Magic Method - * - * @return string - * @access public - */ - public function __toString() - { - return $this->getResourceId(); - } - - /** - * Get Resource ID - * - * We use {} because that symbols should not be in URL according to - * {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}. - * It will safe us from any conflicts, because otherwise regexp will - * match all alphanumeric domains. - * - * @return string - */ - public function getResourceId() - { - return '{' . spl_object_hash($this) . '}'; - } - - /** - * Return existing connection - * - * @param string $id - * - * @return bool|SSH2 will return false if no such connection - */ - public static function getConnectionByResourceId($id) - { - return isset(self::$connections[$id]) ? self::$connections[$id] : false; - } - - /** - * Return all excising connections - * - * @return SSH2[] - */ - public static function getConnections() - { - return self::$connections; - } - - /* * Update packet types in log history * * @param string $old * @param string $new * @access private */ - private function updateLogHistory($old, $new) + function _updateLogHistory($old, $new) { if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) { $this->message_number_log[count($this->message_number_log) - 1] = str_replace( diff --git a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php index d2b955ae5..2b25250bd 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php +++ b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php @@ -3,8 +3,6 @@ /** * Pure-PHP ssh-agent client. * - * {@internal See http://api.libssh.org/rfc/PROTOCOL.agent} - * * PHP version 5 * * Here are some examples of how to use this library: @@ -12,9 +10,9 @@ * login('username', $agent)) { * exit('Login Failed'); * } @@ -30,20 +28,18 @@ * @copyright 2014 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net + * @internal See http://api.libssh.org/rfc/PROTOCOL.agent */ -namespace phpseclib3\System\SSH; +namespace phpseclib\System\SSH; -use phpseclib3\Crypt\RSA; -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\System\SSH\Agent\Identity; -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib\Crypt\RSA; +use phpseclib\System\SSH\Agent\Identity; /** * Pure-PHP ssh-agent client identity factory * - * requestIdentities() method pumps out \phpseclib3\System\SSH\Agent\Identity objects + * requestIdentities() method pumps out \phpseclib\System\SSH\Agent\Identity objects * * @package SSH\Agent * @author Jim Wigginton @@ -51,10 +47,11 @@ use phpseclib3\Crypt\PublicKeyLoader; */ class Agent { - use Common\Traits\ReadBytes; - - // Message numbers - + /**#@+ + * Message numbers + * + * @access private + */ // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) const SSH_AGENTC_REQUEST_IDENTITIES = 11; // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). @@ -63,15 +60,20 @@ class Agent const SSH_AGENTC_SIGN_REQUEST = 13; // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) const SSH_AGENT_SIGN_RESPONSE = 14; + /**#@-*/ - // Agent forwarding status - + /**@+ + * Agent forwarding status + * + * @access private + */ // no forwarding requested and not active const FORWARD_NONE = 0; // request agent forwarding when opportune const FORWARD_REQUEST = 1; // forwarding has been request and is active const FORWARD_ACTIVE = 2; + /**#@-*/ /** * Unused @@ -84,53 +86,38 @@ class Agent * @var resource * @access private */ - private $fsock; + var $fsock; /** * Agent forwarding status * - * @var int * @access private */ - private $forward_status = self::FORWARD_NONE; + var $forward_status = self::FORWARD_NONE; /** * Buffer for accumulating forwarded authentication * agent data arriving on SSH data channel destined * for agent unix socket * - * @var string * @access private */ - private $socket_buffer = ''; + var $socket_buffer = ''; /** * Tracking the number of bytes we are expecting * to arrive for the agent socket on the SSH data * channel - * - * @var int - * @access private - */ - private $expected_bytes = 0; - - /** - * The current request channel - * - * @var int - * @access private */ - private $request_channel; + var $expected_bytes = 0; /** * Default Constructor * - * @return \phpseclib3\System\SSH\Agent - * @throws \phpseclib3\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found - * @throws \RuntimeException on connection errors + * @return \phpseclib\System\SSH\Agent * @access public */ - public function __construct($address = null) + function __construct($address = null) { if (!$address) { switch (true) { @@ -141,13 +128,14 @@ class Agent $address = $_ENV['SSH_AUTH_SOCK']; break; default: - throw new BadConfigurationException('SSH_AUTH_SOCK not found'); + user_error('SSH_AUTH_SOCK not found'); + return false; } } $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); if (!$this->fsock) { - throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); + user_error("Unable to connect to ssh-agent (Error $errno: $errstr)"); } } @@ -155,50 +143,85 @@ class Agent * Request Identities * * See "2.5.2 Requesting a list of protocol 2 keys" - * Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects + * Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects * * @return array - * @throws \RuntimeException on receipt of unexpected packets * @access public */ - public function requestIdentities() + function requestIdentities() { if (!$this->fsock) { - return []; + return array(); } $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); if (strlen($packet) != fputs($this->fsock, $packet)) { - throw new \RuntimeException('Connection closed while requesting identities'); + user_error('Connection closed while requesting identities'); + return array(); } - $length = current(unpack('N', $this->readBytes(4))); - $packet = $this->readBytes($length); - - list($type, $keyCount) = Strings::unpackSSH2('CN', $packet); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $length = current(unpack('N', $temp)); + $type = ord(fread($this->fsock, 1)); if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { - throw new \RuntimeException('Unable to request identities'); + user_error('Unable to request identities'); + return array(); } - $identities = []; + $identities = array(); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $keyCount = current(unpack('N', $temp)); for ($i = 0; $i < $keyCount; $i++) { - list($key_blob, $comment) = Strings::unpackSSH2('ss', $packet); - $temp = $key_blob; - list($key_type) = Strings::unpackSSH2('s', $temp); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $length = current(unpack('N', $temp)); + $key_blob = fread($this->fsock, $length); + if (strlen($key_blob) != $length) { + user_error('Connection closed while requesting identities'); + return array(); + } + $key_str = 'ssh-rsa ' . base64_encode($key_blob); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while requesting identities'); + return array(); + } + $length = current(unpack('N', $temp)); + if ($length) { + $temp = fread($this->fsock, $length); + if (strlen($temp) != $length) { + user_error('Connection closed while requesting identities'); + return array(); + } + $key_str.= ' ' . $temp; + } + $length = current(unpack('N', substr($key_blob, 0, 4))); + $key_type = substr($key_blob, 4, $length); switch ($key_type) { case 'ssh-rsa': + $key = new RSA(); + $key->loadKey($key_str); + break; case 'ssh-dss': - case 'ssh-ed25519': - case 'ecdsa-sha2-nistp256': - case 'ecdsa-sha2-nistp384': - case 'ecdsa-sha2-nistp521': - $key = PublicKeyLoader::load($key_type . ' ' . base64_encode($key_blob)); + // not currently supported + break; } // resources are passed by reference by default if (isset($key)) { - $identity = (new Identity($this->fsock)) - ->withPublicKey($key) - ->withPublicKeyBlob($key_blob); + $identity = new Identity($this->fsock); + $identity->setPublicKey($key); + $identity->setPublicKeyBlob($key_blob); $identities[] = $identity; unset($key); } @@ -211,11 +234,11 @@ class Agent * Signal that agent forwarding should * be requested when a channel is opened * - * @param \phpseclib3\Net\SSH2 $ssh + * @param Net_SSH2 $ssh * @return bool * @access public */ - public function startSSHForwarding($ssh) + function startSSHForwarding($ssh) { if ($this->forward_status == self::FORWARD_NONE) { $this->forward_status = self::FORWARD_REQUEST; @@ -225,16 +248,38 @@ class Agent /** * Request agent forwarding of remote server * - * @param \phpseclib3\Net\SSH2 $ssh + * @param Net_SSH2 $ssh * @return bool * @access private */ - private function request_forwarding($ssh) + function _request_forwarding($ssh) { - if (!$ssh->requestAgentForwarding()) { + $request_channel = $ssh->_get_open_channel(); + if ($request_channel === false) { + return false; + } + + $packet = pack( + 'CNNa*C', + NET_SSH2_MSG_CHANNEL_REQUEST, + $ssh->server_channels[$request_channel], + strlen('auth-agent-req@openssh.com'), + 'auth-agent-req@openssh.com', + 1 + ); + + $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; + + if (!$ssh->_send_binary_packet($packet)) { return false; } + $response = $ssh->_get_channel_packet($request_channel); + if ($response === false) { + return false; + } + + $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; $this->forward_status = self::FORWARD_ACTIVE; return true; @@ -247,13 +292,13 @@ class Agent * open to give the SSH Agent an opportunity * to take further action. i.e. request agent forwarding * - * @param \phpseclib3\Net\SSH2 $ssh + * @param Net_SSH2 $ssh * @access private */ - public function registerChannelOpen($ssh) + function _on_channel_open($ssh) { if ($this->forward_status == self::FORWARD_REQUEST) { - $this->request_forwarding($ssh); + $this->_request_forwarding($ssh); } } @@ -261,11 +306,10 @@ class Agent * Forward data to SSH Agent and return data reply * * @param string $data - * @return string Data from SSH Agent - * @throws \RuntimeException on connection errors - * @access public + * @return data from SSH Agent + * @access private */ - public function forwardData($data) + function _forward_data($data) { if ($this->expected_bytes > 0) { $this->socket_buffer.= $data; @@ -281,15 +325,25 @@ class Agent } if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { - throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); + user_error('Connection closed attempting to forward data to SSH agent'); + return false; } $this->socket_buffer = ''; $this->expected_bytes = 0; - $agent_reply_bytes = current(unpack('N', $this->readBytes(4))); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed while reading data response'); + return false; + } + $agent_reply_bytes = current(unpack('N', $temp)); - $agent_reply_data = $this->readBytes($agent_reply_bytes); + $agent_reply_data = fread($this->fsock, $agent_reply_bytes); + if (strlen($agent_reply_data) != $agent_reply_bytes) { + user_error('Connection closed while reading data response'); + return false; + } $agent_reply_data = current(unpack('a*', $agent_reply_data)); return pack('Na*', $agent_reply_bytes, $agent_reply_data); diff --git a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php index 20b0a958f..68b6bfdfa 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php +++ b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php @@ -1,10 +1,7 @@ * @access internal */ -class Identity implements PrivateKey +class Identity { - use \phpseclib3\System\SSH\Common\Traits\ReadBytes; - - // Signature Flags - // See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 + /**@+ + * Signature Flags + * + * See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 + * + * @access private + */ const SSH_AGENT_RSA2_256 = 2; const SSH_AGENT_RSA2_512 = 4; + /**#@-*/ /** * Key Object * - * @var \phpseclib3\Crypt\RSA + * @var \phpseclib\Crypt\RSA * @access private * @see self::getPublicKey() */ - private $key; + var $key; /** * Key Blob @@ -63,7 +59,7 @@ class Identity implements PrivateKey * @access private * @see self::sign() */ - private $key_blob; + var $key_blob; /** * Socket Resource @@ -72,7 +68,7 @@ class Identity implements PrivateKey * @access private * @see self::sign() */ - private $fsock; + var $fsock; /** * Signature flags @@ -82,29 +78,16 @@ class Identity implements PrivateKey * @see self::sign() * @see self::setHash() */ - private $flags = 0; - - /** - * Curve Aliases - * - * @var array - * @access private - */ - private static $curveAliases = [ - 'secp256r1' => 'nistp256', - 'secp384r1' => 'nistp384', - 'secp521r1' => 'nistp521', - 'Ed25519' => 'Ed25519' - ]; + var $flags = 0; /** * Default Constructor. * * @param resource $fsock - * @return \phpseclib3\System\SSH\Agent\Identity + * @return \phpseclib\System\SSH\Agent\Identity * @access private */ - public function __construct($fsock) + function __construct($fsock) { $this->fsock = $fsock; } @@ -112,38 +95,29 @@ class Identity implements PrivateKey /** * Set Public Key * - * Called by \phpseclib3\System\SSH\Agent::requestIdentities() + * Called by \phpseclib\System\SSH\Agent::requestIdentities() * - * @param \phpseclib3\Crypt\Common\PublicKey $key + * @param \phpseclib\Crypt\RSA $key * @access private */ - public function withPublicKey($key) + function setPublicKey($key) { - if ($key instanceof EC) { - if (is_array($key->getCurve()) || !isset(self::$curveAliases[$key->getCurve()])) { - throw new UnsupportedAlgorithmException('The only supported curves are nistp256, nistp384, nistp512 and Ed25519'); - } - } - - $new = clone $this; - $new->key = $key; - return $new; + $this->key = $key; + $this->key->setPublicKey(); } /** * Set Public Key * - * Called by \phpseclib3\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key + * Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key * but this saves a small amount of computation. * * @param string $key_blob * @access private */ - public function withPublicKeyBlob($key_blob) + function setPublicKeyBlob($key_blob) { - $new = clone $this; - $new->key_blob = $key_blob; - return $new; + $this->key_blob = $key_blob; } /** @@ -151,121 +125,51 @@ class Identity implements PrivateKey * * Wrapper for $this->key->getPublicKey() * - * @param string $type optional + * @param int $format optional * @return mixed * @access public */ - public function getPublicKey($type = 'PKCS8') - { - return $this->key; - } - - /** - * Sets the hash - * - * @param string $hash - * @access public - */ - public function withHash($hash) - { - $new = clone $this; - - $hash = strtolower($hash); - - if ($this->key instanceof RSA) { - $new->flags = 0; - switch ($hash) { - case 'sha1': - break; - case 'sha256': - $new->flags = self::SSH_AGENT_RSA2_256; - break; - case 'sha512': - $new->flags = self::SSH_AGENT_RSA2_512; - break; - default: - throw new UnsupportedAlgorithmException('The only supported hashes for RSA are sha1, sha256 and sha512'); - } - } - if ($this->key instanceof EC) { - switch ($this->key->getCurve()) { - case 'secp256r1': - $expectedHash = 'sha256'; - break; - case 'secp384r1': - $expectedHash = 'sha384'; - break; - //case 'secp521r1': - //case 'Ed25519': - default: - $expectedHash = 'sha512'; - } - if ($hash != $expectedHash) { - throw new UnsupportedAlgorithmException('The only supported hash for ' . self::$curveAliases[$key->getCurve()] . ' is ' . $expectedHash); - } - } - if ($this->key instanceof DSA) { - if ($hash != 'sha1') { - throw new UnsupportedAlgorithmException('The only supported hash for DSA is sha1'); - } - } - return $new; - } - - /** - * Sets the padding - * - * Only PKCS1 padding is supported - * - * @param string $padding - * @access public - */ - public function withPadding($padding) + function getPublicKey($format = null) { - if (!$this->key instanceof RSA) { - throw new UnsupportedAlgorithmException('Only RSA keys support padding'); - } - if ($padding != RSA::SIGNATURE_PKCS1 && $padding != RSA::SIGNATURE_RELAXED_PKCS1) { - throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures'); - } - return $this; + return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format); } /** - * Determines the signature padding mode + * Set Signature Mode * - * Valid values are: ASN1, SSH2, Raw + * Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie. + * ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1 * + * @param int $mode * @access public - * @param string $format */ - public function withSignatureFormat($format) + function setSignatureMode($mode) { - if ($this->key instanceof RSA) { - throw new UnsupportedAlgorithmException('Only DSA and EC keys support signature format setting'); - } - if ($format != 'SSH2') { - throw new UnsupportedAlgorithmException('Only SSH2-formatted signatures are currently supported'); - } - - return $this; } /** - * Returns the curve + * Set Hash * - * Returns a string if it's a named curve, an array if not + * ssh-agent doesn't support using hashes for RSA other than SHA1 * + * @param string $hash * @access public - * @return string|array */ - public function getCurve() + function setHash($hash) { - if (!$this->key instanceof EC) { - throw new UnsupportedAlgorithmException('Only EC keys have curves'); + $this->flags = 0; + switch ($hash) { + case 'sha1': + break; + case 'sha256': + $this->flags = self::SSH_AGENT_RSA2_256; + break; + case 'sha512': + $this->flags = self::SSH_AGENT_RSA2_512; + break; + default: + user_error('The only supported hashes for RSA are sha1, sha256 and sha512'); } - - return $this->key->getCurve(); } /** @@ -275,62 +179,63 @@ class Identity implements PrivateKey * * @param string $message * @return string - * @throws \RuntimeException on connection errors - * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported * @access public */ - public function sign($message) + function sign($message) { // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE - $packet = Strings::packSSH2( - 'CssN', - Agent::SSH_AGENTC_SIGN_REQUEST, - $this->key_blob, - $message, - $this->flags - ); - $packet = Strings::packSSH2('s', $packet); + $packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags); + $packet = pack('Na*', strlen($packet), $packet); if (strlen($packet) != fputs($this->fsock, $packet)) { - throw new \RuntimeException('Connection closed during signing'); + user_error('Connection closed during signing'); + return false; } - $length = current(unpack('N', $this->readBytes(4))); - $packet = $this->readBytes($length); - - list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet); + $temp = fread($this->fsock, 4); + if (strlen($temp) != 4) { + user_error('Connection closed during signing'); + return false; + } + $length = current(unpack('N', $temp)); + $type = ord(fread($this->fsock, 1)); if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { - throw new \RuntimeException('Unable to retrieve signature'); + user_error('Unable to retrieve signature'); + return false; } - if (!$this->key instanceof RSA) { - return $signature_blob; + $signature_blob = fread($this->fsock, $length - 1); + if (strlen($signature_blob) != $length - 1) { + user_error('Connection closed during signing'); + return false; } - - list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob); + $length = current(unpack('N', $this->_string_shift($signature_blob, 4))); + if ($length != strlen($signature_blob)) { + user_error('Malformed signature blob'); + } + $length = current(unpack('N', $this->_string_shift($signature_blob, 4))); + if ($length > strlen($signature_blob) + 4) { + user_error('Malformed signature blob'); + } + $type = $this->_string_shift($signature_blob, $length); + $this->_string_shift($signature_blob, 4); return $signature_blob; } /** - * Returns the private key + * String Shift * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); - } - - /** - * Sets the password + * Inspired by array_shift * - * @access public - * @param string|boolean $password + * @param string $string + * @param int $index + * @return string + * @access private */ - public function withPassword($password = false) + function _string_shift(&$string, $index = 1) { - throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; } } diff --git a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php deleted file mode 100644 index 297808e42..000000000 --- a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\System\SSH\Common\Traits; - -/** - * ReadBytes trait - * - * @package SSH - * @author Jim Wigginton - * @access public - */ -trait ReadBytes -{ - /** - * Read data - * - * @param int $length - * @throws \RuntimeException on connection errors - * @access public - */ - public function readBytes($length) - { - $temp = fread($this->fsock, $length); - if (strlen($temp) != $length) { - throw new \RuntimeException("Expected $length bytes; got " . strlen($temp)); - } - return $temp; - } -} diff --git a/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php index bd4ba0b5a..0da0999fd 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php +++ b/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php @@ -1,18 +1,14 @@ Date: Thu, 4 Feb 2021 21:05:17 +0100 Subject: phpseclib missing files --- vendor/composer/InstalledVersions.php | 4 +- vendor/composer/installed.php | 4 +- .../phpseclib/phpseclib/phpseclib/Crypt/Base.php | 2699 ++++++++++++++++++++ vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php | 342 +++ vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php | 1646 ++++++++++++ 5 files changed, 4691 insertions(+), 4 deletions(-) create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php create mode 100644 vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 97df88926..e597e0eb3 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -30,7 +30,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', + 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -272,7 +272,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', + 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', ), ), ); diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 9ddb06cc3..945fe4368 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', + 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '34b28cd8d36c7805e65c442ff1588ccf5165387a', + 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', ), ), ); diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php new file mode 100644 index 000000000..efbcd242b --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php @@ -0,0 +1,2699 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Base Class for all \phpseclib\Crypt\* cipher classes + * + * @package Base + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +abstract class Base +{ + /**#@+ + * @access public + * @see \phpseclib\Crypt\Base::encrypt() + * @see \phpseclib\Crypt\Base::decrypt() + */ + /** + * Encrypt / decrypt using the Counter mode. + * + * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + */ + const MODE_CTR = -1; + /** + * Encrypt / decrypt using the Electronic Code Book mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + */ + const MODE_ECB = 1; + /** + * Encrypt / decrypt using the Code Book Chaining mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + */ + const MODE_CBC = 2; + /** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + */ + const MODE_CFB = 3; + /** + * Encrypt / decrypt using the Cipher Feedback mode (8bit) + */ + const MODE_CFB8 = 38; + /** + * Encrypt / decrypt using the Output Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + */ + const MODE_OFB = 4; + /** + * Encrypt / decrypt using streaming mode. + */ + const MODE_STREAM = 5; + /**#@-*/ + + /** + * Whirlpool available flag + * + * @see \phpseclib\Crypt\Base::_hashInlineCryptFunction() + * @var bool + * @access private + */ + static $WHIRLPOOL_AVAILABLE; + + /**#@+ + * @access private + * @see \phpseclib\Crypt\Base::__construct() + */ + /** + * Base value for the internal implementation $engine switch + */ + const ENGINE_INTERNAL = 1; + /** + * Base value for the mcrypt implementation $engine switch + */ + const ENGINE_MCRYPT = 2; + /** + * Base value for the mcrypt implementation $engine switch + */ + const ENGINE_OPENSSL = 3; + /**#@-*/ + + /** + * The Encryption Mode + * + * @see self::__construct() + * @var int + * @access private + */ + var $mode; + + /** + * The Block Length of the block cipher + * + * @var int + * @access private + */ + var $block_size = 16; + + /** + * The Key + * + * @see self::setKey() + * @var string + * @access private + */ + var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + /** + * The Initialization Vector + * + * @see self::setIV() + * @var string + * @access private + */ + var $iv; + + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::_clearBuffers() + * @var string + * @access private + */ + var $encryptIV; + + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::_clearBuffers() + * @var string + * @access private + */ + var $decryptIV; + + /** + * Continuous Buffer status + * + * @see self::enableContinuousBuffer() + * @var bool + * @access private + */ + var $continuousBuffer = false; + + /** + * Encryption buffer for CTR, OFB and CFB modes + * + * @see self::encrypt() + * @see self::_clearBuffers() + * @var array + * @access private + */ + var $enbuffer; + + /** + * Decryption buffer for CTR, OFB and CFB modes + * + * @see self::decrypt() + * @see self::_clearBuffers() + * @var array + * @access private + */ + var $debuffer; + + /** + * mcrypt resource for encryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::encrypt() + * @var resource + * @access private + */ + var $enmcrypt; + + /** + * mcrypt resource for decryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::decrypt() + * @var resource + * @access private + */ + var $demcrypt; + + /** + * Does the enmcrypt resource need to be (re)initialized? + * + * @see \phpseclib\Crypt\Twofish::setKey() + * @see \phpseclib\Crypt\Twofish::setIV() + * @var bool + * @access private + */ + var $enchanged = true; + + /** + * Does the demcrypt resource need to be (re)initialized? + * + * @see \phpseclib\Crypt\Twofish::setKey() + * @see \phpseclib\Crypt\Twofish::setIV() + * @var bool + * @access private + */ + var $dechanged = true; + + /** + * mcrypt resource for CFB mode + * + * mcrypt's CFB mode, in (and only in) buffered context, + * is broken, so phpseclib implements the CFB mode by it self, + * even when the mcrypt php extension is available. + * + * In order to do the CFB-mode work (fast) phpseclib + * use a separate ECB-mode mcrypt resource. + * + * @link http://phpseclib.sourceforge.net/cfb-demo.phps + * @see self::encrypt() + * @see self::decrypt() + * @see self::_setupMcrypt() + * @var resource + * @access private + */ + var $ecb; + + /** + * Optimizing value while CFB-encrypting + * + * Only relevant if $continuousBuffer enabled + * and $engine == self::ENGINE_MCRYPT + * + * It's faster to re-init $enmcrypt if + * $buffer bytes > $cfb_init_len than + * using the $ecb resource furthermore. + * + * This value depends of the chosen cipher + * and the time it would be needed for it's + * initialization [by mcrypt_generic_init()] + * which, typically, depends on the complexity + * on its internaly Key-expanding algorithm. + * + * @see self::encrypt() + * @var int + * @access private + */ + var $cfb_init_len = 600; + + /** + * Does internal cipher state need to be (re)initialized? + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + * @var bool + * @access private + */ + var $changed = true; + + /** + * Padding status + * + * @see self::enablePadding() + * @var bool + * @access private + */ + var $padding = true; + + /** + * Is the mode one that is paddable? + * + * @see self::__construct() + * @var bool + * @access private + */ + var $paddable = false; + + /** + * Holds which crypt engine internaly should be use, + * which will be determined automatically on __construct() + * + * Currently available $engines are: + * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) + * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) + * + * @see self::_setEngine() + * @see self::encrypt() + * @see self::decrypt() + * @var int + * @access private + */ + var $engine; + + /** + * Holds the preferred crypt engine + * + * @see self::_setEngine() + * @see self::setPreferredEngine() + * @var int + * @access private + */ + var $preferredEngine; + + /** + * The mcrypt specific name of the cipher + * + * Only used if $engine == self::ENGINE_MCRYPT + * + * @link http://www.php.net/mcrypt_module_open + * @link http://www.php.net/mcrypt_list_algorithms + * @see self::_setupMcrypt() + * @var string + * @access private + */ + var $cipher_name_mcrypt; + + /** + * The openssl specific name of the cipher + * + * Only used if $engine == self::ENGINE_OPENSSL + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + * @access private + */ + var $cipher_name_openssl; + + /** + * The openssl specific name of the cipher in ECB mode + * + * If OpenSSL does not support the mode we're trying to use (CTR) + * it can still be emulated with ECB mode. + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + * @access private + */ + var $cipher_name_openssl_ecb; + + /** + * The default salt used by setPassword() + * + * @see self::setPassword() + * @var string + * @access private + */ + var $password_default_salt = 'phpseclib/salt'; + + /** + * The name of the performance-optimized callback function + * + * Used by encrypt() / decrypt() + * only if $engine == self::ENGINE_INTERNAL + * + * @see self::encrypt() + * @see self::decrypt() + * @see self::_setupInlineCrypt() + * @see self::$use_inline_crypt + * @var Callback + * @access private + */ + var $inline_crypt; + + /** + * Holds whether performance-optimized $inline_crypt() can/should be used. + * + * @see self::encrypt() + * @see self::decrypt() + * @see self::inline_crypt + * @var mixed + * @access private + */ + var $use_inline_crypt = true; + + /** + * If OpenSSL can be used in ECB but not in CTR we can emulate CTR + * + * @see self::_openssl_ctr_process() + * @var bool + * @access private + */ + var $openssl_emulate_ctr = false; + + /** + * Determines what options are passed to openssl_encrypt/decrypt + * + * @see self::isValidEngine() + * @var mixed + * @access private + */ + var $openssl_options; + + /** + * Has the key length explicitly been set or should it be derived from the key, itself? + * + * @see self::setKeyLength() + * @var bool + * @access private + */ + var $explicit_key_length = false; + + /** + * Don't truncate / null pad key + * + * @see self::_clearBuffers() + * @var bool + * @access private + */ + var $skip_key_adjustment = false; + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. + * + * $mode could be: + * + * - self::MODE_ECB + * + * - self::MODE_CBC + * + * - self::MODE_CTR + * + * - self::MODE_CFB + * + * - self::MODE_OFB + * + * If not explicitly set, self::MODE_CBC will be used. + * + * @param int $mode + * @access public + */ + function __construct($mode = self::MODE_CBC) + { + // $mode dependent settings + switch ($mode) { + case self::MODE_ECB: + $this->paddable = true; + $this->mode = self::MODE_ECB; + break; + case self::MODE_CTR: + case self::MODE_CFB: + case self::MODE_CFB8: + case self::MODE_OFB: + case self::MODE_STREAM: + $this->mode = $mode; + break; + case self::MODE_CBC: + default: + $this->paddable = true; + $this->mode = self::MODE_CBC; + } + + $this->_setEngine(); + } + + /** + * Sets the initialization vector. (optional) + * + * SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used. If not explicitly set, it'll be assumed + * to be all zero's. + * + * @access public + * @param string $iv + * @internal Can be overwritten by a sub class, but does not have to be + */ + function setIV($iv) + { + if ($this->mode == self::MODE_ECB) { + return; + } + + $this->iv = $iv; + $this->changed = true; + } + + /** + * Sets the key length. + * + * Keys with explicitly set lengths need to be treated accordingly + * + * @access public + * @param int $length + */ + function setKeyLength($length) + { + $this->explicit_key_length = true; + $this->changed = true; + $this->_setEngine(); + } + + /** + * Returns the current key length in bits + * + * @access public + * @return int + */ + function getKeyLength() + { + return $this->key_length << 3; + } + + /** + * Returns the current block length in bits + * + * @access public + * @return int + */ + function getBlockLength() + { + return $this->block_size << 3; + } + + /** + * Sets the key. + * + * The min/max length(s) of the key depends on the cipher which is used. + * If the key not fits the length(s) of the cipher it will paded with null bytes + * up to the closest valid key length. If the key is more than max length, + * we trim the excess bits. + * + * If the key is not explicitly set, it'll be assumed to be all null bytes. + * + * @access public + * @param string $key + * @internal Could, but not must, extend by the child Crypt_* class + */ + function setKey($key) + { + if (!$this->explicit_key_length) { + $this->setKeyLength(strlen($key) << 3); + $this->explicit_key_length = false; + } + + $this->key = $key; + $this->changed = true; + $this->_setEngine(); + } + + /** + * Sets the password. + * + * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: + * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: + * $hash, $salt, $count, $dkLen + * + * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php + * + * @see Crypt/Hash.php + * @param string $password + * @param string $method + * @return bool + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + function setPassword($password, $method = 'pbkdf2') + { + $key = ''; + + switch ($method) { + default: // 'pbkdf2' or 'pbkdf1' + $func_args = func_get_args(); + + // Hash function + $hash = isset($func_args[2]) ? $func_args[2] : 'sha1'; + + // WPA and WPA2 use the SSID as the salt + $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt; + + // RFC2898#section-4.2 uses 1,000 iterations by default + // WPA and WPA2 use 4,096. + $count = isset($func_args[4]) ? $func_args[4] : 1000; + + // Keylength + if (isset($func_args[5])) { + $dkLen = $func_args[5]; + } else { + $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length; + } + + switch (true) { + case $method == 'pbkdf1': + $hashObj = new Hash(); + $hashObj->setHash($hash); + if ($dkLen > $hashObj->getLength()) { + user_error('Derived key too long'); + return false; + } + $t = $password . $salt; + for ($i = 0; $i < $count; ++$i) { + $t = $hashObj->hash($t); + } + $key = substr($t, 0, $dkLen); + + $this->setKey(substr($key, 0, $dkLen >> 1)); + $this->setIV(substr($key, $dkLen >> 1)); + + return true; + // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable + case !function_exists('hash_pbkdf2'): + case !function_exists('hash_algos'): + case !in_array($hash, hash_algos()): + $i = 1; + $hmac = new Hash(); + $hmac->setHash($hash); + $hmac->setKey($password); + while (strlen($key) < $dkLen) { + $f = $u = $hmac->hash($salt . pack('N', $i++)); + for ($j = 2; $j <= $count; ++$j) { + $u = $hmac->hash($u); + $f^= $u; + } + $key.= $f; + } + $key = substr($key, 0, $dkLen); + break; + default: + $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true); + } + } + + $this->setKey($key); + + return true; + } + + /** + * Encrypts a message. + * + * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher + * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's + * necessary are discussed in the following + * URL: + * + * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} + * + * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. + * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that + * length. + * + * @see self::decrypt() + * @access public + * @param string $plaintext + * @return string $ciphertext + * @internal Could, but not must, extend by the child Crypt_* class + */ + function encrypt($plaintext) + { + if ($this->paddable) { + $plaintext = $this->_pad($plaintext); + } + + if ($this->engine === self::ENGINE_OPENSSL) { + if ($this->changed) { + $this->_clearBuffers(); + $this->changed = false; + } + switch ($this->mode) { + case self::MODE_STREAM: + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + case self::MODE_ECB: + $result = @openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; + case self::MODE_CBC: + $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); + if (!defined('OPENSSL_RAW_DATA')) { + $result = substr($result, 0, -$this->block_size); + } + if ($this->continuousBuffer) { + $this->encryptIV = substr($result, -$this->block_size); + } + return $result; + case self::MODE_CTR: + return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $ciphertext = ''; + if ($this->continuousBuffer) { + $iv = &$this->encryptIV; + $pos = &$this->enbuffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + $plaintext = substr($plaintext, $i); + } + + $overflow = $len % $this->block_size; + + if ($overflow) { + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + $iv = $this->_string_pop($ciphertext, $this->block_size); + + $size = $len - $overflow; + $block = $iv ^ substr($plaintext, -$overflow); + $iv = substr_replace($iv, $block, 0, $overflow); + $ciphertext.= $block; + $pos = $overflow; + } elseif ($len) { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + + return $ciphertext; + case self::MODE_CFB8: + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->encryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + return $ciphertext; + case self::MODE_OFB: + return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); + } + } + + if ($this->engine === self::ENGINE_MCRYPT) { + if ($this->changed) { + $this->_setupMcrypt(); + $this->changed = false; + } + if ($this->enchanged) { + @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + $this->enchanged = false; + } + + // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's + // rewritten CFB implementation the above outputs the same thing twice. + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $block_size = $this->block_size; + $iv = &$this->encryptIV; + $pos = &$this->enbuffer['pos']; + $len = strlen($plaintext); + $ciphertext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + $this->enbuffer['enmcrypt_init'] = true; + } + if ($len >= $block_size) { + if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { + if ($this->enbuffer['enmcrypt_init'] === true) { + @mcrypt_generic_init($this->enmcrypt, $this->key, $iv); + $this->enbuffer['enmcrypt_init'] = false; + } + $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); + $iv = substr($ciphertext, -$block_size); + $len%= $block_size; + } else { + while ($len >= $block_size) { + $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); + $ciphertext.= $iv; + $len-= $block_size; + $i+= $block_size; + } + } + } + + if ($len) { + $iv = @mcrypt_generic($this->ecb, $iv); + $block = $iv ^ substr($plaintext, -$len); + $iv = substr_replace($iv, $block, 0, $len); + $ciphertext.= $block; + $pos = $len; + } + + return $ciphertext; + } + + $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext); + + if (!$this->continuousBuffer) { + @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + } + + return $ciphertext; + } + + if ($this->changed) { + $this->_setup(); + $this->changed = false; + } + if ($this->use_inline_crypt) { + $inline = $this->inline_crypt; + return $inline('encrypt', $this, $plaintext); + } + + $buffer = &$this->enbuffer; + $block_size = $this->block_size; + $ciphertext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->encryptIV; + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $block = $this->_encryptBlock($block ^ $xor); + $xor = $block; + $ciphertext.= $block; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->encryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'].= $this->_encryptBlock($xor); + } + $this->_increment_str($xor); + $key = $this->_string_shift($buffer['ciphertext'], $block_size); + $ciphertext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $key = $this->_encryptBlock($xor); + $this->_increment_str($xor); + $ciphertext.= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + if ($this->continuousBuffer) { + $iv = &$this->encryptIV; + $pos = &$buffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size); + $ciphertext.= $iv; + $len-= $block_size; + $i+= $block_size; + } + if ($len) { + $iv = $this->_encryptBlock($iv); + $block = $iv ^ substr($plaintext, $i); + $iv = substr_replace($iv, $block, 0, $len); + $ciphertext.= $block; + $pos = $len; + } + break; + case self::MODE_CFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i = 0; $i < $len; ++$i) { + $ciphertext .= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv)); + $iv = substr($iv, 1) . $c; + } + + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->encryptIV = substr($ciphertext, -$block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB: + $xor = $this->encryptIV; + if (strlen($buffer['xor'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['xor'])) { + $xor = $this->_encryptBlock($xor); + $buffer['xor'].= $xor; + } + $key = $this->_string_shift($buffer['xor'], $block_size); + $ciphertext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $xor = $this->_encryptBlock($xor); + $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['xor'] = substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $ciphertext = $this->_encryptBlock($plaintext); + break; + } + + return $ciphertext; + } + + /** + * Decrypts a message. + * + * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until + * it is. + * + * @see self::encrypt() + * @access public + * @param string $ciphertext + * @return string $plaintext + * @internal Could, but not must, extend by the child Crypt_* class + */ + function decrypt($ciphertext) + { + if ($this->paddable) { + // we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}: + // "The data is padded with "\0" to make sure the length of the data is n * blocksize." + $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0)); + } + + if ($this->engine === self::ENGINE_OPENSSL) { + if ($this->changed) { + $this->_clearBuffers(); + $this->changed = false; + } + switch ($this->mode) { + case self::MODE_STREAM: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + break; + case self::MODE_ECB: + if (!defined('OPENSSL_RAW_DATA')) { + $ciphertext.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true); + } + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + break; + case self::MODE_CBC: + if (!defined('OPENSSL_RAW_DATA')) { + $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size); + $ciphertext.= substr(@openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size); + $offset = 2 * $this->block_size; + } else { + $offset = $this->block_size; + } + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); + if ($this->continuousBuffer) { + $this->decryptIV = substr($ciphertext, -$offset, $this->block_size); + } + break; + case self::MODE_CTR: + $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $plaintext = ''; + if ($this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$this->buffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + $ciphertext = substr($ciphertext, $i); + } + $overflow = $len % $this->block_size; + if ($overflow) { + $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + if ($len - $overflow) { + $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); + } + $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + $plaintext.= $iv ^ substr($ciphertext, -$overflow); + $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); + $pos = $overflow; + } elseif ($len) { + $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + break; + case self::MODE_CFB8: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->decryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB: + $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); + } + + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + } + + if ($this->engine === self::ENGINE_MCRYPT) { + $block_size = $this->block_size; + if ($this->changed) { + $this->_setupMcrypt(); + $this->changed = false; + } + if ($this->dechanged) { + @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + $this->dechanged = false; + } + + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$this->debuffer['pos']; + $len = strlen($ciphertext); + $plaintext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + } + if ($len >= $block_size) { + $cb = substr($ciphertext, $i, $len - $len % $block_size); + $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; + $iv = substr($cb, -$block_size); + $len%= $block_size; + } + if ($len) { + $iv = @mcrypt_generic($this->ecb, $iv); + $plaintext.= $iv ^ substr($ciphertext, -$len); + $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); + $pos = $len; + } + + return $plaintext; + } + + $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext); + + if (!$this->continuousBuffer) { + @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + } + + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + } + + if ($this->changed) { + $this->_setup(); + $this->changed = false; + } + if ($this->use_inline_crypt) { + $inline = $this->inline_crypt; + return $inline('decrypt', $this, $ciphertext); + } + + $block_size = $this->block_size; + + $buffer = &$this->debuffer; + $plaintext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->decryptIV; + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $plaintext.= $this->_decryptBlock($block) ^ $xor; + $xor = $block; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->decryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'].= $this->_encryptBlock($xor); + $this->_increment_str($xor); + } + $key = $this->_string_shift($buffer['ciphertext'], $block_size); + $plaintext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $key = $this->_encryptBlock($xor); + $this->_increment_str($xor); + $plaintext.= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + if ($this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$buffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len-= $max; + $pos = 0; + } else { + $i = $len; + $pos+= $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->_encryptBlock($iv); + $cb = substr($ciphertext, $i, $block_size); + $plaintext.= $iv ^ $cb; + $iv = $cb; + $len-= $block_size; + $i+= $block_size; + } + if ($len) { + $iv = $this->_encryptBlock($iv); + $plaintext.= $iv ^ substr($ciphertext, $i); + $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len); + $pos = $len; + } + break; + case self::MODE_CFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i = 0; $i < $len; ++$i) { + $plaintext .= $ciphertext[$i] ^ $this->_encryptBlock($iv); + $iv = substr($iv, 1) . $ciphertext[$i]; + } + + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->decryptIV = substr($ciphertext, -$block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB: + $xor = $this->decryptIV; + if (strlen($buffer['xor'])) { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + if (strlen($block) > strlen($buffer['xor'])) { + $xor = $this->_encryptBlock($xor); + $buffer['xor'].= $xor; + } + $key = $this->_string_shift($buffer['xor'], $block_size); + $plaintext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $xor = $this->_encryptBlock($xor); + $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer['xor'] = substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $plaintext = $this->_decryptBlock($ciphertext); + break; + } + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + } + + /** + * OpenSSL CTR Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for CTR is the same for both encrypting and decrypting this function is re-used by both Base::encrypt() + * and Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this + * function will emulate CTR with ECB when necessary. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + * @access private + */ + function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer) + { + $ciphertext = ''; + + $block_size = $this->block_size; + $key = $this->key; + + if ($this->openssl_emulate_ctr) { + $xor = $encryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $result = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; + $buffer['ciphertext'].= $result; + } + $this->_increment_str($xor); + $otp = $this->_string_shift($buffer['ciphertext'], $block_size); + $ciphertext.= $block ^ $otp; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $otp = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp; + $this->_increment_str($xor); + $ciphertext.= $block ^ $otp; + } + } + if ($this->continuousBuffer) { + $encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + + return $ciphertext; + } + + if (strlen($buffer['ciphertext'])) { + $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + + if (!strlen($plaintext)) { + return $ciphertext; + } + } + + $overflow = strlen($plaintext) % $block_size; + if ($overflow) { + $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 + $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); + $temp = $this->_string_pop($encrypted, $block_size); + $ciphertext.= $encrypted . ($plaintext2 ^ $temp); + if ($this->continuousBuffer) { + $buffer['ciphertext'] = substr($temp, $overflow); + $encryptIV = $temp; + } + } elseif (!strlen($buffer['ciphertext'])) { + $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); + $temp = $this->_string_pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $temp; + } + } + if ($this->continuousBuffer) { + if (!defined('OPENSSL_RAW_DATA')) { + $encryptIV.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + } + $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + if ($overflow) { + $this->_increment_str($encryptIV); + } + } + + return $ciphertext; + } + + /** + * OpenSSL OFB Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for OFB is the same for both encrypting and decrypting this function is re-used by both Base::encrypt() + * and Base::decrypt(). + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + * @access private + */ + function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer) + { + if (strlen($buffer['xor'])) { + $ciphertext = $plaintext ^ $buffer['xor']; + $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + } else { + $ciphertext = ''; + } + + $block_size = $this->block_size; + + $len = strlen($plaintext); + $key = $this->key; + $overflow = $len % $block_size; + + if (strlen($plaintext)) { + if ($overflow) { + $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); + $xor = $this->_string_pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $xor; + } + $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow); + if ($this->continuousBuffer) { + $buffer['xor'] = $xor; + } + } else { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); + if ($this->continuousBuffer) { + $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); + } + } + } + + return $ciphertext; + } + + /** + * phpseclib <-> OpenSSL Mode Mapper + * + * May need to be overwritten by classes extending this one in some cases + * + * @return int + * @access private + */ + function _openssl_translate_mode() + { + switch ($this->mode) { + case self::MODE_ECB: + return 'ecb'; + case self::MODE_CBC: + return 'cbc'; + case self::MODE_CTR: + return 'ctr'; + case self::MODE_CFB: + return 'cfb'; + case self::MODE_CFB8: + return 'cfb8'; + case self::MODE_OFB: + return 'ofb'; + } + } + + /** + * Pad "packets". + * + * Block ciphers working by encrypting between their specified [$this->]block_size at a time + * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to + * pad the input so that it is of the proper length. + * + * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, + * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping + * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is + * transmitted separately) + * + * @see self::disablePadding() + * @access public + */ + function enablePadding() + { + $this->padding = true; + } + + /** + * Do not pad packets. + * + * @see self::enablePadding() + * @access public + */ + function disablePadding() + { + $this->padding = false; + } + + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->encrypt(substr($plaintext, 16, 16)); + * + * + * echo $rijndael->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\*() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * @see self::disableContinuousBuffer() + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + function enableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + + $this->continuousBuffer = true; + + $this->_setEngine(); + } + + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * @see self::enableContinuousBuffer() + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + function disableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + if (!$this->continuousBuffer) { + return; + } + + $this->continuousBuffer = false; + $this->changed = true; + + $this->_setEngine(); + } + + /** + * Test for engine validity + * + * @see self::__construct() + * @param int $engine + * @access public + * @return bool + */ + function isValidEngine($engine) + { + switch ($engine) { + case self::ENGINE_OPENSSL: + if ($this->mode == self::MODE_STREAM && $this->continuousBuffer) { + return false; + } + $this->openssl_emulate_ctr = false; + $result = $this->cipher_name_openssl && + extension_loaded('openssl') && + // PHP 5.3.0 - 5.3.2 did not let you set IV's + version_compare(PHP_VERSION, '5.3.3', '>='); + if (!$result) { + return false; + } + + // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer + // $options openssl_encrypt expected a boolean $raw_data. + if (!defined('OPENSSL_RAW_DATA')) { + $this->openssl_options = true; + } else { + $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; + } + + $methods = openssl_get_cipher_methods(); + if (in_array($this->cipher_name_openssl, $methods)) { + return true; + } + // not all of openssl's symmetric cipher's support ctr. for those + // that don't we'll emulate it + switch ($this->mode) { + case self::MODE_CTR: + if (in_array($this->cipher_name_openssl_ecb, $methods)) { + $this->openssl_emulate_ctr = true; + return true; + } + } + return false; + case self::ENGINE_MCRYPT: + return $this->cipher_name_mcrypt && + extension_loaded('mcrypt') && + in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms()); + case self::ENGINE_INTERNAL: + return true; + } + + return false; + } + + /** + * Sets the preferred crypt engine + * + * Currently, $engine could be: + * + * - \phpseclib\Crypt\Base::ENGINE_OPENSSL [very fast] + * + * - \phpseclib\Crypt\Base::ENGINE_MCRYPT [fast] + * + * - \phpseclib\Crypt\Base::ENGINE_INTERNAL [slow] + * + * If the preferred crypt engine is not available the fastest available one will be used + * + * @see self::__construct() + * @param int $engine + * @access public + */ + function setPreferredEngine($engine) + { + switch ($engine) { + //case self::ENGINE_OPENSSL; + case self::ENGINE_MCRYPT: + case self::ENGINE_INTERNAL: + $this->preferredEngine = $engine; + break; + default: + $this->preferredEngine = self::ENGINE_OPENSSL; + } + + $this->_setEngine(); + } + + /** + * Returns the engine currently being utilized + * + * @see self::_setEngine() + * @access public + */ + function getEngine() + { + return $this->engine; + } + + /** + * Sets the engine as appropriate + * + * @see self::__construct() + * @access private + */ + function _setEngine() + { + $this->engine = null; + + $candidateEngines = array( + $this->preferredEngine, + self::ENGINE_OPENSSL, + self::ENGINE_MCRYPT + ); + foreach ($candidateEngines as $engine) { + if ($this->isValidEngine($engine)) { + $this->engine = $engine; + break; + } + } + if (!$this->engine) { + $this->engine = self::ENGINE_INTERNAL; + } + + if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { + // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, + // (re)open them with the module named in $this->cipher_name_mcrypt + @mcrypt_module_close($this->enmcrypt); + @mcrypt_module_close($this->demcrypt); + $this->enmcrypt = null; + $this->demcrypt = null; + + if ($this->ecb) { + @mcrypt_module_close($this->ecb); + $this->ecb = null; + } + } + + $this->changed = true; + } + + /** + * Encrypts a block + * + * Note: Must be extended by the child \phpseclib\Crypt\* class + * + * @access private + * @param string $in + * @return string + */ + abstract function _encryptBlock($in); + + /** + * Decrypts a block + * + * Note: Must be extended by the child \phpseclib\Crypt\* class + * + * @access private + * @param string $in + * @return string + */ + abstract function _decryptBlock($in); + + /** + * Setup the key (expansion) + * + * Only used if $engine == self::ENGINE_INTERNAL + * + * Note: Must extend by the child \phpseclib\Crypt\* class + * + * @see self::_setup() + * @access private + */ + abstract function _setupKey(); + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == self::ENGINE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + * @access private + * @internal _setup() is always called before en/decryption. + * @internal Could, but not must, extend by the child Crypt_* class + */ + function _setup() + { + $this->_clearBuffers(); + $this->_setupKey(); + + if ($this->use_inline_crypt) { + $this->_setupInlineCrypt(); + } + } + + /** + * Setup the self::ENGINE_MCRYPT $engine + * + * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers + * Used (only) if $engine = self::ENGINE_MCRYPT + * + * _setupMcrypt() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + * @access private + * @internal Could, but not must, extend by the child Crypt_* class + */ + function _setupMcrypt() + { + $this->_clearBuffers(); + $this->enchanged = $this->dechanged = true; + + if (!isset($this->enmcrypt)) { + static $mcrypt_modes = array( + self::MODE_CTR => 'ctr', + self::MODE_ECB => MCRYPT_MODE_ECB, + self::MODE_CBC => MCRYPT_MODE_CBC, + self::MODE_CFB => 'ncfb', + self::MODE_CFB8 => MCRYPT_MODE_CFB, + self::MODE_OFB => MCRYPT_MODE_NOFB, + self::MODE_STREAM => MCRYPT_MODE_STREAM, + ); + + $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + + // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() + // to workaround mcrypt's broken ncfb implementation in buffered mode + // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + if ($this->mode == self::MODE_CFB) { + $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + } + } // else should mcrypt_generic_deinit be called? + + if ($this->mode == self::MODE_CFB) { + @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + } + } + + /** + * Pads a string + * + * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. + * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to + * chr($this->block_size - (strlen($text) % $this->block_size) + * + * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless + * and padding will, hence forth, be enabled. + * + * @see self::_unpad() + * @param string $text + * @access private + * @return string + */ + function _pad($text) + { + $length = strlen($text); + + if (!$this->padding) { + if ($length % $this->block_size == 0) { + return $text; + } else { + user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})"); + $this->padding = true; + } + } + + $pad = $this->block_size - ($length % $this->block_size); + + return str_pad($text, $length + $pad, chr($pad)); + } + + /** + * Unpads a string. + * + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. + * + * @see self::_pad() + * @param string $text + * @access private + * @return string + */ + function _unpad($text) + { + if (!$this->padding) { + return $text; + } + + $length = ord($text[strlen($text) - 1]); + + if (!$length || $length > $this->block_size) { + return false; + } + + return substr($text, 0, -$length); + } + + /** + * Clears internal buffers + * + * Clearing/resetting the internal buffers is done everytime + * after disableContinuousBuffer() or on cipher $engine (re)init + * ie after setKey() or setIV() + * + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + function _clearBuffers() + { + $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true); + + // mcrypt's handling of invalid's $iv: + // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size); + $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0"); + + if (!$this->skip_key_adjustment) { + $this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0"); + } + } + + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @access private + * @return string + */ + function _string_shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } + + /** + * String Pop + * + * Inspired by array_pop + * + * @param string $string + * @param int $index + * @access private + * @return string + */ + function _string_pop(&$string, $index = 1) + { + $substr = substr($string, -$index); + $string = substr($string, 0, -$index); + return $substr; + } + + /** + * Increment the current string + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $var + * @access private + */ + function _increment_str(&$var) + { + for ($i = 4; $i <= strlen($var); $i+= 4) { + $temp = substr($var, -$i, 4); + switch ($temp) { + case "\xFF\xFF\xFF\xFF": + $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); + break; + case "\x7F\xFF\xFF\xFF": + $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); + return; + default: + $temp = unpack('Nnum', $temp); + $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); + return; + } + } + + $remainder = strlen($var) % 4; + + if ($remainder == 0) { + return; + } + + $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); + $temp = substr(pack('N', $temp['num'] + 1), -$remainder); + $var = substr_replace($var, $temp, 0, $remainder); + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * Stores the created (or existing) callback function-name + * in $this->inline_crypt + * + * Internally for phpseclib developers: + * + * _setupInlineCrypt() would be called only if: + * + * - $engine == self::ENGINE_INTERNAL and + * + * - $use_inline_crypt === true + * + * - each time on _setup(), after(!) _setupKey() + * + * + * This ensures that _setupInlineCrypt() has always a + * full ready2go initializated internal cipher $engine state + * where, for example, the keys allready expanded, + * keys/block_size calculated and such. + * + * It is, each time if called, the responsibility of _setupInlineCrypt(): + * + * - to set $this->inline_crypt to a valid and fully working callback function + * as a (faster) replacement for encrypt() / decrypt() + * + * - NOT to create unlimited callback functions (for memory reasons!) + * no matter how often _setupInlineCrypt() would be called. At some + * point of amount they must be generic re-useable. + * + * - the code of _setupInlineCrypt() it self, + * and the generated callback code, + * must be, in following order: + * - 100% safe + * - 100% compatible to encrypt()/decrypt() + * - using only php5+ features/lang-constructs/php-extensions if + * compatibility (down to php4) or fallback is provided + * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) + * - >= 10% faster than encrypt()/decrypt() [which is, by the way, + * the reason for the existence of _setupInlineCrypt() :-)] + * - memory-nice + * - short (as good as possible) + * + * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. + * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib\Crypt\* class. + * - The following variable names are reserved: + * - $_* (all variable names prefixed with an underscore) + * - $self (object reference to it self. Do not use $this, but $self instead) + * - $in (the content of $in has to en/decrypt by the generated code) + * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only + * + * + * @see self::_setup() + * @see self::_createInlineCryptFunction() + * @see self::encrypt() + * @see self::decrypt() + * @access private + * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt() + */ + function _setupInlineCrypt() + { + // If, for any reason, an extending \phpseclib\Crypt\Base() \phpseclib\Crypt\* class + // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false + // ie in the class var declaration of $use_inline_crypt in general for the \phpseclib\Crypt\* class, + // in the constructor at object instance-time + // or, if it's runtime-specific, at runtime + + $this->use_inline_crypt = false; + } + + /** + * Creates the performance-optimized function for en/decrypt() + * + * Internally for phpseclib developers: + * + * _createInlineCryptFunction(): + * + * - merge the $cipher_code [setup'ed by _setupInlineCrypt()] + * with the current [$this->]mode of operation code + * + * - create the $inline function, which called by encrypt() / decrypt() + * as its replacement to speed up the en/decryption operations. + * + * - return the name of the created $inline callback function + * + * - used to speed up en/decryption + * + * + * + * The main reason why can speed up things [up to 50%] this way are: + * + * - using variables more effective then regular. + * (ie no use of expensive arrays but integers $k_0, $k_1 ... + * or even, for example, the pure $key[] values hardcoded) + * + * - avoiding 1000's of function calls of ie _encryptBlock() + * but inlining the crypt operations. + * in the mode of operation for() loop. + * + * - full loop unroll the (sometimes key-dependent) rounds + * avoiding this way ++$i counters and runtime-if's etc... + * + * The basic code architectur of the generated $inline en/decrypt() + * lambda function, in pseudo php, is: + * + * + * +----------------------------------------------------------------------------------------------+ + * | callback $inline = create_function: | + * | lambda_function_0001_crypt_ECB($action, $text) | + * | { | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_crypt']; // general init code. | + * | // ie: $sbox'es declarations used for | + * | // encrypt and decrypt'ing. | + * | | + * | switch ($action) { | + * | case 'encrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | + * | ie: specified $key or $box | + * | declarations for encrypt'ing. | + * | | + * | foreach ($ciphertext) { | + * | $in = $block_size of $ciphertext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for encryption. | + * | // $cipher_code['encrypt_block'] has to | + * | // encrypt the content of the $in variable | + * | | + * | $plaintext .= $in; | + * | } | + * | return $plaintext; | + * | | + * | case 'decrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_decrypt']; // decrypt sepcific init code | + * | ie: specified $key or $box | + * | declarations for decrypt'ing. | + * | foreach ($plaintext) { | + * | $in = $block_size of $plaintext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for decryption. | + * | // $cipher_code['decrypt_block'] has to | + * | // decrypt the content of the $in variable | + * | $ciphertext .= $in; | + * | } | + * | return $ciphertext; | + * | } | + * | } | + * +----------------------------------------------------------------------------------------------+ + * + * + * See also the \phpseclib\Crypt\*::_setupInlineCrypt()'s for + * productive inline $cipher_code's how they works. + * + * Structure of: + * + * $cipher_code = array( + * 'init_crypt' => (string) '', // optional + * 'init_encrypt' => (string) '', // optional + * 'init_decrypt' => (string) '', // optional + * 'encrypt_block' => (string) '', // required + * 'decrypt_block' => (string) '' // required + * ); + * + * + * @see self::_setupInlineCrypt() + * @see self::encrypt() + * @see self::decrypt() + * @param array $cipher_code + * @access private + * @return string (the name of the created callback function) + */ + function _createInlineCryptFunction($cipher_code) + { + $block_size = $this->block_size; + + // optional + $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : ''; + $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : ''; + $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : ''; + // required + $encrypt_block = $cipher_code['encrypt_block']; + $decrypt_block = $cipher_code['decrypt_block']; + + // Generating mode of operation inline code, + // merged with the $cipher_code algorithm + // for encrypt- and decryption. + switch ($this->mode) { + case self::MODE_ECB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $in = substr($_text, $_i, '.$block_size.'); + '.$encrypt_block.' + $_ciphertext.= $in; + } + + return $_ciphertext; + '; + + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); + $_ciphertext_len = strlen($_text); + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $in = substr($_text, $_i, '.$block_size.'); + '.$decrypt_block.' + $_plaintext.= $in; + } + + return $self->_unpad($_plaintext); + '; + break; + case self::MODE_CTR: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $self->encryptIV; + $_buffer = &$self->enbuffer; + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + '.$encrypt_block.' + $self->_increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.'); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + $in = $_xor; + '.$encrypt_block.' + $self->_increment_str($_xor); + $_key = $in; + $_ciphertext.= $_block ^ $_key; + } + } + if ($self->continuousBuffer) { + $self->encryptIV = $_xor; + if ($_start = $_plaintext_len % '.$block_size.') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $self->decryptIV; + $_buffer = &$self->debuffer; + + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + '.$encrypt_block.' + $self->_increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.'); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + $in = $_xor; + '.$encrypt_block.' + $self->_increment_str($_xor); + $_key = $in; + $_plaintext.= $_block ^ $_key; + } + } + if ($self->continuousBuffer) { + $self->decryptIV = $_xor; + if ($_start = $_ciphertext_len % '.$block_size.') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_plaintext; + '; + break; + case self::MODE_CFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_buffer = &$self->enbuffer; + + if ($self->continuousBuffer) { + $_iv = &$self->encryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $self->encryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = '.$block_size.' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); + } + while ($_len >= '.$block_size.') { + $in = $_iv; + '.$encrypt_block.'; + $_iv = $in ^ substr($_text, $_i, '.$block_size.'); + $_ciphertext.= $_iv; + $_len-= '.$block_size.'; + $_i+= '.$block_size.'; + } + if ($_len) { + $in = $_iv; + '.$encrypt_block.' + $_iv = $in; + $_block = $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, $_block, 0, $_len); + $_ciphertext.= $_block; + $_pos = $_len; + } + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_buffer = &$self->debuffer; + + if ($self->continuousBuffer) { + $_iv = &$self->decryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $self->decryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = '.$block_size.' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_plaintext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); + } + while ($_len >= '.$block_size.') { + $in = $_iv; + '.$encrypt_block.' + $_iv = $in; + $cb = substr($_text, $_i, '.$block_size.'); + $_plaintext.= $_iv ^ $cb; + $_iv = $cb; + $_len-= '.$block_size.'; + $_i+= '.$block_size.'; + } + if ($_len) { + $in = $_iv; + '.$encrypt_block.' + $_iv = $in; + $_plaintext.= $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); + $_pos = $_len; + } + + return $_plaintext; + '; + break; + case self::MODE_CFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $self->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + '.$encrypt_block.' + $_ciphertext .= ($_c = $_text[$_i] ^ $in); + $_iv = substr($_iv, 1) . $_c; + } + + if ($self->continuousBuffer) { + if ($_len >= '.$block_size.') { + $self->encryptIV = substr($_ciphertext, -'.$block_size.'); + } else { + $self->encryptIV = substr($self->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len); + } + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $self->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + '.$encrypt_block.' + $_plaintext .= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $_text[$_i]; + } + + if ($self->continuousBuffer) { + if ($_len >= '.$block_size.') { + $self->decryptIV = substr($_text, -'.$block_size.'); + } else { + $self->decryptIV = substr($self->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len); + } + } + + return $_plaintext; + '; + break; + case self::MODE_OFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $self->encryptIV; + $_buffer = &$self->enbuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = $self->_string_shift($_buffer["xor"], '.$block_size.'); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor; + } + $_key = $_xor; + } + if ($self->continuousBuffer) { + $self->encryptIV = $_xor; + if ($_start = $_plaintext_len % '.$block_size.') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $self->decryptIV; + $_buffer = &$self->debuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $_block = substr($_text, $_i, '.$block_size.'); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = $self->_string_shift($_buffer["xor"], '.$block_size.'); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $in = $_xor; + '.$encrypt_block.' + $_xor = $in; + $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor; + } + $_key = $_xor; + } + if ($self->continuousBuffer) { + $self->decryptIV = $_xor; + if ($_start = $_ciphertext_len % '.$block_size.') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_plaintext; + '; + break; + case self::MODE_STREAM: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + '.$encrypt_block.' + return $_ciphertext; + '; + $decrypt = $init_decrypt . ' + $_plaintext = ""; + '.$decrypt_block.' + return $_plaintext; + '; + break; + // case self::MODE_CBC: + default: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + $in = $self->encryptIV; + + for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + $in = substr($_text, $_i, '.$block_size.') ^ $in; + '.$encrypt_block.' + $_ciphertext.= $in; + } + + if ($self->continuousBuffer) { + $self->encryptIV = $in; + } + + return $_ciphertext; + '; + + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); + $_ciphertext_len = strlen($_text); + + $_iv = $self->decryptIV; + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + $in = $_block = substr($_text, $_i, '.$block_size.'); + '.$decrypt_block.' + $_plaintext.= $in ^ $_iv; + $_iv = $_block; + } + + if ($self->continuousBuffer) { + $self->decryptIV = $_iv; + } + + return $self->_unpad($_plaintext); + '; + break; + } + + // Create the $inline function and return its name as string. Ready to run! + eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };'); + return $func; + } + + /** + * Holds the lambda_functions table (classwide) + * + * Each name of the lambda function, created from + * _setupInlineCrypt() && _createInlineCryptFunction() + * is stored, classwide (!), here for reusing. + * + * The string-based index of $function is a classwide + * unique value representing, at least, the $mode of + * operation (or more... depends of the optimizing level) + * for which $mode the lambda function was created. + * + * @access private + * @return array &$functions + */ + function &_getLambdaFunctions() + { + static $functions = array(); + return $functions; + } + + /** + * Generates a digest from $bytes + * + * @see self::_setupInlineCrypt() + * @access private + * @param string $bytes + * @return string + */ + function _hashInlineCryptFunction($bytes) + { + if (!isset(self::$WHIRLPOOL_AVAILABLE)) { + self::$WHIRLPOOL_AVAILABLE = extension_loaded('hash') && in_array('whirlpool', hash_algos()); + } + + $result = ''; + $hash = $bytes; + + switch (true) { + case self::$WHIRLPOOL_AVAILABLE: + foreach (str_split($bytes, 64) as $t) { + $hash = hash('whirlpool', $hash, true); + $result .= $t ^ $hash; + } + return $result . hash('whirlpool', $hash, true); + default: + $len = strlen($bytes); + for ($i = 0; $i < $len; $i+=20) { + $t = substr($bytes, $i, 20); + $hash = pack('H*', sha1($hash)); + $result .= $t ^ $hash; + } + return $result . pack('H*', sha1($hash)); + } + } + + /** + * Convert float to int + * + * On ARM CPUs converting floats to ints doesn't always work + * + * @access private + * @param string $x + * @return int + */ + function safe_intval($x) + { + switch (true) { + case is_int($x): + // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding" + case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': + return $x; + } + return (fmod($x, 0x80000000) & 0x7FFFFFFF) | + ((fmod(floor($x / 0x80000000), 2) & 1) << 31); + } + + /** + * eval()'able string for in-line float to int + * + * @access private + * @return string + */ + function safe_intval_inline() + { + switch (true) { + case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: + case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': + return '%s'; + break; + default: + $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; + return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; + } + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php new file mode 100644 index 000000000..cf13496cd --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php @@ -0,0 +1,342 @@ + + * login('username', 'password')) { + * exit('bad login'); + * } + * $scp = new \phpseclib\Net\SCP($ssh); + * + * $scp->put('abcd', str_repeat('x', 1024*1024)); + * ?> + *
      + * + * @category Net + * @package SCP + * @author Jim Wigginton + * @copyright 2010 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Net; + +/** + * Pure-PHP implementations of SCP. + * + * @package SCP + * @author Jim Wigginton + * @access public + */ +class SCP +{ + /**#@+ + * @access public + * @see \phpseclib\Net\SCP::put() + */ + /** + * Reads data from a local file. + */ + const SOURCE_LOCAL_FILE = 1; + /** + * Reads data from a string. + */ + const SOURCE_STRING = 2; + /**#@-*/ + + /**#@+ + * @access private + * @see \phpseclib\Net\SCP::_send() + * @see \phpseclib\Net\SCP::_receive() + */ + /** + * SSH1 is being used. + */ + const MODE_SSH1 = 1; + /** + * SSH2 is being used. + */ + const MODE_SSH2 = 2; + /**#@-*/ + + /** + * SSH Object + * + * @var object + * @access private + */ + var $ssh; + + /** + * Packet Size + * + * @var int + * @access private + */ + var $packet_size; + + /** + * Mode + * + * @var int + * @access private + */ + var $mode; + + /** + * Default Constructor. + * + * Connects to an SSH server + * + * @param \phpseclib\Net\SSH1|\phpseclib\Net\SSH2 $ssh + * @return \phpseclib\Net\SCP + * @access public + */ + function __construct($ssh) + { + if ($ssh instanceof SSH2) { + $this->mode = self::MODE_SSH2; + } elseif ($ssh instanceof SSH1) { + $this->packet_size = 50000; + $this->mode = self::MODE_SSH1; + } else { + return; + } + + $this->ssh = $ssh; + } + + /** + * Uploads a file to the SCP server. + * + * By default, \phpseclib\Net\SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. + * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SCP::get(), you will get a file, twelve bytes + * long, containing 'filename.ext' as its contents. + * + * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will + * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how + * large $remote_file will be, as well. + * + * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take + * care of that, yourself. + * + * @param string $remote_file + * @param string $data + * @param int $mode + * @param callable $callback + * @return bool + * @access public + */ + function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null) + { + if (!isset($this->ssh)) { + return false; + } + + if (empty($remote_file)) { + user_error('remote_file cannot be blank', E_USER_NOTICE); + return false; + } + + if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to + return false; + } + + $temp = $this->_receive(); + if ($temp !== chr(0)) { + return false; + } + + if ($this->mode == self::MODE_SSH2) { + $this->packet_size = $this->ssh->packet_size_client_to_server[SSH2::CHANNEL_EXEC] - 4; + } + + $remote_file = basename($remote_file); + + if ($mode == self::SOURCE_STRING) { + $size = strlen($data); + } else { + if (!is_file($data)) { + user_error("$data is not a valid file", E_USER_NOTICE); + return false; + } + + $fp = @fopen($data, 'rb'); + if (!$fp) { + return false; + } + $size = filesize($data); + } + + $this->_send('C0644 ' . $size . ' ' . $remote_file . "\n"); + + $temp = $this->_receive(); + if ($temp !== chr(0)) { + return false; + } + + $sent = 0; + while ($sent < $size) { + $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size); + $this->_send($temp); + $sent+= strlen($temp); + + if (is_callable($callback)) { + call_user_func($callback, $sent); + } + } + $this->_close(); + + if ($mode != self::SOURCE_STRING) { + fclose($fp); + } + + return true; + } + + /** + * Downloads a file from the SCP server. + * + * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if + * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the + * operation + * + * @param string $remote_file + * @param string $local_file + * @return mixed + * @access public + */ + function get($remote_file, $local_file = false) + { + if (!isset($this->ssh)) { + return false; + } + + if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from + return false; + } + + $this->_send("\0"); + + if (!preg_match('#(?[^ ]+) (?\d+) (?.+)#', rtrim($this->_receive()), $info)) { + return false; + } + + $this->_send("\0"); + + $size = 0; + + if ($local_file !== false) { + $fp = @fopen($local_file, 'wb'); + if (!$fp) { + return false; + } + } + + $content = ''; + while ($size < $info['size']) { + $data = $this->_receive(); + // SCP usually seems to split stuff out into 16k chunks + $size+= strlen($data); + + if ($local_file === false) { + $content.= $data; + } else { + fputs($fp, $data); + } + } + + $this->_close(); + + if ($local_file !== false) { + fclose($fp); + return true; + } + + return $content; + } + + /** + * Sends a packet to an SSH server + * + * @param string $data + * @access private + */ + function _send($data) + { + switch ($this->mode) { + case self::MODE_SSH2: + $this->ssh->_send_channel_packet(SSH2::CHANNEL_EXEC, $data); + break; + case self::MODE_SSH1: + $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data); + $this->ssh->_send_binary_packet($data); + } + } + + /** + * Receives a packet from an SSH server + * + * @return string + * @access private + */ + function _receive() + { + switch ($this->mode) { + case self::MODE_SSH2: + return $this->ssh->_get_channel_packet(SSH2::CHANNEL_EXEC, true); + case self::MODE_SSH1: + if (!$this->ssh->bitmap) { + return false; + } + while (true) { + $response = $this->ssh->_get_binary_packet(); + switch ($response[SSH1::RESPONSE_TYPE]) { + case NET_SSH1_SMSG_STDOUT_DATA: + if (strlen($response[SSH1::RESPONSE_DATA]) < 4) { + return false; + } + extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA])); + return $this->ssh->_string_shift($response[SSH1::RESPONSE_DATA], $length); + case NET_SSH1_SMSG_STDERR_DATA: + break; + case NET_SSH1_SMSG_EXITSTATUS: + $this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION)); + fclose($this->ssh->fsock); + $this->ssh->bitmap = 0; + return false; + default: + user_error('Unknown packet received', E_USER_NOTICE); + return false; + } + } + } + } + + /** + * Closes the connection to an SSH server + * + * @access private + */ + function _close() + { + switch ($this->mode) { + case self::MODE_SSH2: + $this->ssh->_close_channel(SSH2::CHANNEL_EXEC, true); + break; + case self::MODE_SSH1: + $this->ssh->disconnect(); + } + } +} diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php new file mode 100644 index 000000000..e372b8b92 --- /dev/null +++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php @@ -0,0 +1,1646 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('ls -la'); + * ?> + * + * + * Here's another short example: + * + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $ssh->read('username@username:~$'); + * $ssh->write("ls -la\n"); + * echo $ssh->read('username@username:~$'); + * ?> + * + * + * More information on the SSHv1 specification can be found by reading + * {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}. + * + * @category Net + * @package SSH1 + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Net; + +use phpseclib\Crypt\DES; +use phpseclib\Crypt\Random; +use phpseclib\Crypt\TripleDES; +use phpseclib\Math\BigInteger; + +/** + * Pure-PHP implementation of SSHv1. + * + * @package SSH1 + * @author Jim Wigginton + * @access public + */ +class SSH1 +{ + /**#@+ + * Encryption Methods + * + * @see \phpseclib\Net\SSH1::getSupportedCiphers() + * @access public + */ + /** + * No encryption + * + * Not supported. + */ + const CIPHER_NONE = 0; + /** + * IDEA in CFB mode + * + * Not supported. + */ + const CIPHER_IDEA = 1; + /** + * DES in CBC mode + */ + const CIPHER_DES = 2; + /** + * Triple-DES in CBC mode + * + * All implementations are required to support this + */ + const CIPHER_3DES = 3; + /** + * TRI's Simple Stream encryption CBC + * + * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, does define it (see cipher.h), + * although it doesn't use it (see cipher.c) + */ + const CIPHER_BROKEN_TSS = 4; + /** + * RC4 + * + * Not supported. + * + * @internal According to the SSH1 specs: + * + * "The first 16 bytes of the session key are used as the key for + * the server to client direction. The remaining 16 bytes are used + * as the key for the client to server direction. This gives + * independent 128-bit keys for each direction." + * + * This library currently only supports encryption when the same key is being used for both directions. This is + * because there's only one $crypto object. Two could be added ($encrypt and $decrypt, perhaps). + */ + const CIPHER_RC4 = 5; + /** + * Blowfish + * + * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, defines it (see cipher.h) and + * uses it (see cipher.c) + */ + const CIPHER_BLOWFISH = 6; + /**#@-*/ + + /**#@+ + * Authentication Methods + * + * @see \phpseclib\Net\SSH1::getSupportedAuthentications() + * @access public + */ + /** + * .rhosts or /etc/hosts.equiv + */ + const AUTH_RHOSTS = 1; + /** + * pure RSA authentication + */ + const AUTH_RSA = 2; + /** + * password authentication + * + * This is the only method that is supported by this library. + */ + const AUTH_PASSWORD = 3; + /** + * .rhosts with RSA host authentication + */ + const AUTH_RHOSTS_RSA = 4; + /**#@-*/ + + /**#@+ + * Terminal Modes + * + * @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html + * @access private + */ + const TTY_OP_END = 0; + /**#@-*/ + + /** + * The Response Type + * + * @see \phpseclib\Net\SSH1::_get_binary_packet() + * @access private + */ + const RESPONSE_TYPE = 1; + + /** + * The Response Data + * + * @see \phpseclib\Net\SSH1::_get_binary_packet() + * @access private + */ + const RESPONSE_DATA = 2; + + /**#@+ + * Execution Bitmap Masks + * + * @see \phpseclib\Net\SSH1::bitmap + * @access private + */ + const MASK_CONSTRUCTOR = 0x00000001; + const MASK_CONNECTED = 0x00000002; + const MASK_LOGIN = 0x00000004; + const MASK_SHELL = 0x00000008; + /**#@-*/ + + /**#@+ + * @access public + * @see \phpseclib\Net\SSH1::getLog() + */ + /** + * Returns the message numbers + */ + const LOG_SIMPLE = 1; + /** + * Returns the message content + */ + const LOG_COMPLEX = 2; + /** + * Outputs the content real-time + */ + const LOG_REALTIME = 3; + /** + * Dumps the content real-time to a file + */ + const LOG_REALTIME_FILE = 4; + /**#@-*/ + + /**#@+ + * @access public + * @see \phpseclib\Net\SSH1::read() + */ + /** + * Returns when a string matching $expect exactly is found + */ + const READ_SIMPLE = 1; + /** + * Returns when a string matching the regular expression $expect is found + */ + const READ_REGEX = 2; + /**#@-*/ + + /** + * The SSH identifier + * + * @var string + * @access private + */ + var $identifier = 'SSH-1.5-phpseclib'; + + /** + * The Socket Object + * + * @var object + * @access private + */ + var $fsock; + + /** + * The cryptography object + * + * @var object + * @access private + */ + var $crypto = false; + + /** + * Execution Bitmap + * + * The bits that are set represent functions that have been called already. This is used to determine + * if a requisite function has been successfully executed. If not, an error should be thrown. + * + * @var int + * @access private + */ + var $bitmap = 0; + + /** + * The Server Key Public Exponent + * + * Logged for debug purposes + * + * @see self::getServerKeyPublicExponent() + * @var string + * @access private + */ + var $server_key_public_exponent; + + /** + * The Server Key Public Modulus + * + * Logged for debug purposes + * + * @see self::getServerKeyPublicModulus() + * @var string + * @access private + */ + var $server_key_public_modulus; + + /** + * The Host Key Public Exponent + * + * Logged for debug purposes + * + * @see self::getHostKeyPublicExponent() + * @var string + * @access private + */ + var $host_key_public_exponent; + + /** + * The Host Key Public Modulus + * + * Logged for debug purposes + * + * @see self::getHostKeyPublicModulus() + * @var string + * @access private + */ + var $host_key_public_modulus; + + /** + * Supported Ciphers + * + * Logged for debug purposes + * + * @see self::getSupportedCiphers() + * @var array + * @access private + */ + var $supported_ciphers = array( + self::CIPHER_NONE => 'No encryption', + self::CIPHER_IDEA => 'IDEA in CFB mode', + self::CIPHER_DES => 'DES in CBC mode', + self::CIPHER_3DES => 'Triple-DES in CBC mode', + self::CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC', + self::CIPHER_RC4 => 'RC4', + self::CIPHER_BLOWFISH => 'Blowfish' + ); + + /** + * Supported Authentications + * + * Logged for debug purposes + * + * @see self::getSupportedAuthentications() + * @var array + * @access private + */ + var $supported_authentications = array( + self::AUTH_RHOSTS => '.rhosts or /etc/hosts.equiv', + self::AUTH_RSA => 'pure RSA authentication', + self::AUTH_PASSWORD => 'password authentication', + self::AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication' + ); + + /** + * Server Identification + * + * @see self::getServerIdentification() + * @var string + * @access private + */ + var $server_identification = ''; + + /** + * Protocol Flags + * + * @see self::__construct() + * @var array + * @access private + */ + var $protocol_flags = array(); + + /** + * Protocol Flag Log + * + * @see self::getLog() + * @var array + * @access private + */ + var $protocol_flag_log = array(); + + /** + * Message Log + * + * @see self::getLog() + * @var array + * @access private + */ + var $message_log = array(); + + /** + * Real-time log file pointer + * + * @see self::_append_log() + * @var resource + * @access private + */ + var $realtime_log_file; + + /** + * Real-time log file size + * + * @see self::_append_log() + * @var int + * @access private + */ + var $realtime_log_size; + + /** + * Real-time log file wrap boolean + * + * @see self::_append_log() + * @var bool + * @access private + */ + var $realtime_log_wrap; + + /** + * Interactive Buffer + * + * @see self::read() + * @var array + * @access private + */ + var $interactiveBuffer = ''; + + /** + * Timeout + * + * @see self::setTimeout() + * @access private + */ + var $timeout; + + /** + * Current Timeout + * + * @see self::_get_channel_packet() + * @access private + */ + var $curTimeout; + + /** + * Log Boundary + * + * @see self::_format_log() + * @access private + */ + var $log_boundary = ':'; + + /** + * Log Long Width + * + * @see self::_format_log() + * @access private + */ + var $log_long_width = 65; + + /** + * Log Short Width + * + * @see self::_format_log() + * @access private + */ + var $log_short_width = 16; + + /** + * Hostname + * + * @see self::__construct() + * @see self::_connect() + * @var string + * @access private + */ + var $host; + + /** + * Port Number + * + * @see self::__construct() + * @see self::_connect() + * @var int + * @access private + */ + var $port; + + /** + * Timeout for initial connection + * + * Set by the constructor call. Calling setTimeout() is optional. If it's not called functions like + * exec() won't timeout unless some PHP setting forces it too. The timeout specified in the constructor, + * however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be + * 10 seconds. It is used by fsockopen() in that function. + * + * @see self::__construct() + * @see self::_connect() + * @var int + * @access private + */ + var $connectionTimeout; + + /** + * Default cipher + * + * @see self::__construct() + * @see self::_connect() + * @var int + * @access private + */ + var $cipher; + + /** + * Default Constructor. + * + * Connects to an SSHv1 server + * + * @param string $host + * @param int $port + * @param int $timeout + * @param int $cipher + * @return \phpseclib\Net\SSH1 + * @access public + */ + function __construct($host, $port = 22, $timeout = 10, $cipher = self::CIPHER_3DES) + { + $this->protocol_flags = array( + 1 => 'NET_SSH1_MSG_DISCONNECT', + 2 => 'NET_SSH1_SMSG_PUBLIC_KEY', + 3 => 'NET_SSH1_CMSG_SESSION_KEY', + 4 => 'NET_SSH1_CMSG_USER', + 9 => 'NET_SSH1_CMSG_AUTH_PASSWORD', + 10 => 'NET_SSH1_CMSG_REQUEST_PTY', + 12 => 'NET_SSH1_CMSG_EXEC_SHELL', + 13 => 'NET_SSH1_CMSG_EXEC_CMD', + 14 => 'NET_SSH1_SMSG_SUCCESS', + 15 => 'NET_SSH1_SMSG_FAILURE', + 16 => 'NET_SSH1_CMSG_STDIN_DATA', + 17 => 'NET_SSH1_SMSG_STDOUT_DATA', + 18 => 'NET_SSH1_SMSG_STDERR_DATA', + 19 => 'NET_SSH1_CMSG_EOF', + 20 => 'NET_SSH1_SMSG_EXITSTATUS', + 33 => 'NET_SSH1_CMSG_EXIT_CONFIRMATION' + ); + + $this->_define_array($this->protocol_flags); + + $this->host = $host; + $this->port = $port; + $this->connectionTimeout = $timeout; + $this->cipher = $cipher; + } + + /** + * Connect to an SSHv1 server + * + * @return bool + * @access private + */ + function _connect() + { + $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout); + if (!$this->fsock) { + user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error $errno. $errstr")); + return false; + } + + $this->server_identification = $init_line = fgets($this->fsock, 255); + + if (defined('NET_SSH1_LOGGING')) { + $this->_append_log('<-', $this->server_identification); + $this->_append_log('->', $this->identifier . "\r\n"); + } + + if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) { + user_error('Can only connect to SSH servers'); + return false; + } + if ($parts[1][0] != 1) { + user_error("Cannot connect to SSH $parts[1] servers"); + return false; + } + + fputs($this->fsock, $this->identifier."\r\n"); + + $response = $this->_get_binary_packet(); + if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) { + user_error('Expected SSH_SMSG_PUBLIC_KEY'); + return false; + } + + $anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8); + + $this->_string_shift($response[self::RESPONSE_DATA], 4); + + if (strlen($response[self::RESPONSE_DATA]) < 2) { + return false; + } + $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); + $server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); + $this->server_key_public_exponent = $server_key_public_exponent; + + if (strlen($response[self::RESPONSE_DATA]) < 2) { + return false; + } + $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); + $server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); + + $this->server_key_public_modulus = $server_key_public_modulus; + + $this->_string_shift($response[self::RESPONSE_DATA], 4); + + if (strlen($response[self::RESPONSE_DATA]) < 2) { + return false; + } + $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); + $host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); + $this->host_key_public_exponent = $host_key_public_exponent; + + if (strlen($response[self::RESPONSE_DATA]) < 2) { + return false; + } + $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); + $host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); + + $this->host_key_public_modulus = $host_key_public_modulus; + + $this->_string_shift($response[self::RESPONSE_DATA], 4); + + // get a list of the supported ciphers + if (strlen($response[self::RESPONSE_DATA]) < 4) { + return false; + } + extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4))); + + foreach ($this->supported_ciphers as $mask => $name) { + if (($supported_ciphers_mask & (1 << $mask)) == 0) { + unset($this->supported_ciphers[$mask]); + } + } + + // get a list of the supported authentications + if (strlen($response[self::RESPONSE_DATA]) < 4) { + return false; + } + extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4))); + foreach ($this->supported_authentications as $mask => $name) { + if (($supported_authentications_mask & (1 << $mask)) == 0) { + unset($this->supported_authentications[$mask]); + } + } + + $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie)); + + $session_key = Random::string(32); + $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0)); + + if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) { + $double_encrypted_session_key = $this->_rsa_crypt( + $double_encrypted_session_key, + array( + $server_key_public_exponent, + $server_key_public_modulus + ) + ); + $double_encrypted_session_key = $this->_rsa_crypt( + $double_encrypted_session_key, + array( + $host_key_public_exponent, + $host_key_public_modulus + ) + ); + } else { + $double_encrypted_session_key = $this->_rsa_crypt( + $double_encrypted_session_key, + array( + $host_key_public_exponent, + $host_key_public_modulus + ) + ); + $double_encrypted_session_key = $this->_rsa_crypt( + $double_encrypted_session_key, + array( + $server_key_public_exponent, + $server_key_public_modulus + ) + ); + } + + $cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : self::CIPHER_3DES; + $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0); + + if (!$this->_send_binary_packet($data)) { + user_error('Error sending SSH_CMSG_SESSION_KEY'); + return false; + } + + switch ($cipher) { + //case self::CIPHER_NONE: + // $this->crypto = new \phpseclib\Crypt\Null(); + // break; + case self::CIPHER_DES: + $this->crypto = new DES(); + $this->crypto->disablePadding(); + $this->crypto->enableContinuousBuffer(); + $this->crypto->setKey(substr($session_key, 0, 8)); + break; + case self::CIPHER_3DES: + $this->crypto = new TripleDES(TripleDES::MODE_3CBC); + $this->crypto->disablePadding(); + $this->crypto->enableContinuousBuffer(); + $this->crypto->setKey(substr($session_key, 0, 24)); + break; + //case self::CIPHER_RC4: + // $this->crypto = new RC4(); + // $this->crypto->enableContinuousBuffer(); + // $this->crypto->setKey(substr($session_key, 0, 16)); + // break; + } + + $response = $this->_get_binary_packet(); + + if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { + user_error('Expected SSH_SMSG_SUCCESS'); + return false; + } + + $this->bitmap = self::MASK_CONNECTED; + + return true; + } + + /** + * Login + * + * @param string $username + * @param string $password + * @return bool + * @access public + */ + function login($username, $password = '') + { + if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { + $this->bitmap |= self::MASK_CONSTRUCTOR; + if (!$this->_connect()) { + return false; + } + } + + if (!($this->bitmap & self::MASK_CONNECTED)) { + return false; + } + + $data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username); + + if (!$this->_send_binary_packet($data)) { + user_error('Error sending SSH_CMSG_USER'); + return false; + } + + $response = $this->_get_binary_packet(); + + if ($response === true) { + return false; + } + if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) { + user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); + return false; + } + + $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password); + + if (!$this->_send_binary_packet($data)) { + user_error('Error sending SSH_CMSG_AUTH_PASSWORD'); + return false; + } + + // remove the username and password from the last logged packet + if (defined('NET_SSH1_LOGGING') && NET_SSH1_LOGGING == self::LOG_COMPLEX) { + $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen('password'), 'password'); + $this->message_log[count($this->message_log) - 1] = $data; + } + + $response = $this->_get_binary_packet(); + + if ($response === true) { + return false; + } + if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) { + return false; + } else { + user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); + return false; + } + } + + /** + * Set Timeout + * + * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. + * Setting $timeout to false or 0 will mean there is no timeout. + * + * @param mixed $timeout + */ + function setTimeout($timeout) + { + $this->timeout = $this->curTimeout = $timeout; + } + + /** + * Executes a command on a non-interactive shell, returns the output, and quits. + * + * An SSH1 server will close the connection after a command has been executed on a non-interactive shell. SSH2 + * servers don't, however, this isn't an SSH2 client. The way this works, on the server, is by initiating a + * shell with the -s option, as discussed in the following links: + * + * {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html} + * {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html} + * + * To execute further commands, a new \phpseclib\Net\SSH1 object will need to be created. + * + * Returns false on failure and the output, otherwise. + * + * @see self::interactiveRead() + * @see self::interactiveWrite() + * @param string $cmd + * @param bool $block + * @return mixed + * @access public + */ + function exec($cmd, $block = true) + { + if (!($this->bitmap & self::MASK_LOGIN)) { + user_error('Operation disallowed prior to login()'); + return false; + } + + $data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd); + + if (!$this->_send_binary_packet($data)) { + user_error('Error sending SSH_CMSG_EXEC_CMD'); + return false; + } + + if (!$block) { + return true; + } + + $output = ''; + $response = $this->_get_binary_packet(); + + if ($response !== false) { + do { + $output.= substr($response[self::RESPONSE_DATA], 4); + $response = $this->_get_binary_packet(); + } while (is_array($response) && $response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS); + } + + $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION); + + // i don't think it's really all that important if this packet gets sent or not. + $this->_send_binary_packet($data); + + fclose($this->fsock); + + // reset the execution bitmap - a new \phpseclib\Net\SSH1 object needs to be created. + $this->bitmap = 0; + + return $output; + } + + /** + * Creates an interactive shell + * + * @see self::interactiveRead() + * @see self::interactiveWrite() + * @return bool + * @access private + */ + function _initShell() + { + // connect using the sample parameters in protocol-1.5.txt. + // according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text + // terminal is a command line interpreter or shell". thus, opening a terminal session to run the shell. + $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, self::TTY_OP_END); + + if (!$this->_send_binary_packet($data)) { + user_error('Error sending SSH_CMSG_REQUEST_PTY'); + return false; + } + + $response = $this->_get_binary_packet(); + + if ($response === true) { + return false; + } + if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { + user_error('Expected SSH_SMSG_SUCCESS'); + return false; + } + + $data = pack('C', NET_SSH1_CMSG_EXEC_SHELL); + + if (!$this->_send_binary_packet($data)) { + user_error('Error sending SSH_CMSG_EXEC_SHELL'); + return false; + } + + $this->bitmap |= self::MASK_SHELL; + + //stream_set_blocking($this->fsock, 0); + + return true; + } + + /** + * Inputs a command into an interactive shell. + * + * @see self::interactiveWrite() + * @param string $cmd + * @return bool + * @access public + */ + function write($cmd) + { + return $this->interactiveWrite($cmd); + } + + /** + * Returns the output of an interactive shell when there's a match for $expect + * + * $expect can take the form of a string literal or, if $mode == self::READ_REGEX, + * a regular expression. + * + * @see self::write() + * @param string $expect + * @param int $mode + * @return bool + * @access public + */ + function read($expect, $mode = self::READ_SIMPLE) + { + if (!($this->bitmap & self::MASK_LOGIN)) { + user_error('Operation disallowed prior to login()'); + return false; + } + + if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { + user_error('Unable to initiate an interactive shell session'); + return false; + } + + $match = $expect; + while (true) { + if ($mode == self::READ_REGEX) { + preg_match($expect, $this->interactiveBuffer, $matches); + $match = isset($matches[0]) ? $matches[0] : ''; + } + $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; + if ($pos !== false) { + return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match)); + } + $response = $this->_get_binary_packet(); + + if ($response === true) { + return $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); + } + $this->interactiveBuffer.= substr($response[self::RESPONSE_DATA], 4); + } + } + + /** + * Inputs a command into an interactive shell. + * + * @see self::interactiveRead() + * @param string $cmd + * @return bool + * @access public + */ + function interactiveWrite($cmd) + { + if (!($this->bitmap & self::MASK_LOGIN)) { + user_error('Operation disallowed prior to login()'); + return false; + } + + if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { + user_error('Unable to initiate an interactive shell session'); + return false; + } + + $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd); + + if (!$this->_send_binary_packet($data)) { + user_error('Error sending SSH_CMSG_STDIN'); + return false; + } + + return true; + } + + /** + * Returns the output of an interactive shell when no more output is available. + * + * Requires PHP 4.3.0 or later due to the use of the stream_select() function. If you see stuff like + * "^[[00m", you're seeing ANSI escape codes. According to + * {@link http://support.microsoft.com/kb/101875 How to Enable ANSI.SYS in a Command Window}, "Windows NT + * does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user, + * there's not going to be much recourse. + * + * @see self::interactiveRead() + * @return string + * @access public + */ + function interactiveRead() + { + if (!($this->bitmap & self::MASK_LOGIN)) { + user_error('Operation disallowed prior to login()'); + return false; + } + + if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { + user_error('Unable to initiate an interactive shell session'); + return false; + } + + $read = array($this->fsock); + $write = $except = null; + if (stream_select($read, $write, $except, 0)) { + $response = $this->_get_binary_packet(); + return substr($response[self::RESPONSE_DATA], 4); + } else { + return ''; + } + } + + /** + * Disconnect + * + * @access public + */ + function disconnect() + { + $this->_disconnect(); + } + + /** + * Destructor. + * + * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call + * disconnect(). + * + * @access public + */ + function __destruct() + { + $this->_disconnect(); + } + + /** + * Disconnect + * + * @param string $msg + * @access private + */ + function _disconnect($msg = 'Client Quit') + { + if ($this->bitmap) { + $data = pack('C', NET_SSH1_CMSG_EOF); + $this->_send_binary_packet($data); + /* + $response = $this->_get_binary_packet(); + if ($response === true) { + $response = array(self::RESPONSE_TYPE => -1); + } + switch ($response[self::RESPONSE_TYPE]) { + case NET_SSH1_SMSG_EXITSTATUS: + $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION); + break; + default: + $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg); + } + */ + $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg); + + $this->_send_binary_packet($data); + fclose($this->fsock); + $this->bitmap = 0; + } + } + + /** + * Gets Binary Packets + * + * See 'The Binary Packet Protocol' of protocol-1.5.txt for more info. + * + * Also, this function could be improved upon by adding detection for the following exploit: + * http://www.securiteam.com/securitynews/5LP042K3FY.html + * + * @see self::_send_binary_packet() + * @return array + * @access private + */ + function _get_binary_packet() + { + if (feof($this->fsock)) { + //user_error('connection closed prematurely'); + return false; + } + + if ($this->curTimeout) { + $read = array($this->fsock); + $write = $except = null; + + $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + $sec = floor($this->curTimeout); + $usec = 1000000 * ($this->curTimeout - $sec); + // on windows this returns a "Warning: Invalid CRT parameters detected" error + if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { + //$this->_disconnect('Timeout'); + return true; + } + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + } + + $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + $data = fread($this->fsock, 4); + if (strlen($data) < 4) { + return false; + } + $temp = unpack('Nlength', $data); + + $padding_length = 8 - ($temp['length'] & 7); + $length = $temp['length'] + $padding_length; + $raw = ''; + + while ($length > 0) { + $temp = fread($this->fsock, $length); + if (strlen($temp) != $length) { + return false; + } + $raw.= $temp; + $length-= strlen($temp); + } + $stop = strtok(microtime(), ' ') + strtok(''); + + if (strlen($raw) && $this->crypto !== false) { + $raw = $this->crypto->decrypt($raw); + } + + $padding = substr($raw, 0, $padding_length); + $type = $raw[$padding_length]; + $data = substr($raw, $padding_length + 1, -4); + + if (strlen($raw) < 4) { + return false; + } + $temp = unpack('Ncrc', substr($raw, -4)); + + //if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) { + // user_error('Bad CRC in packet from server'); + // return false; + //} + + $type = ord($type); + + if (defined('NET_SSH1_LOGGING')) { + $temp = isset($this->protocol_flags[$type]) ? $this->protocol_flags[$type] : 'UNKNOWN'; + $temp = '<- ' . $temp . + ' (' . round($stop - $start, 4) . 's)'; + $this->_append_log($temp, $data); + } + + return array( + self::RESPONSE_TYPE => $type, + self::RESPONSE_DATA => $data + ); + } + + /** + * Sends Binary Packets + * + * Returns true on success, false on failure. + * + * @see self::_get_binary_packet() + * @param string $data + * @return bool + * @access private + */ + function _send_binary_packet($data) + { + if (feof($this->fsock)) { + //user_error('connection closed prematurely'); + return false; + } + + $length = strlen($data) + 4; + + $padding = Random::string(8 - ($length & 7)); + + $orig = $data; + $data = $padding . $data; + $data.= pack('N', $this->_crc($data)); + + if ($this->crypto !== false) { + $data = $this->crypto->encrypt($data); + } + + $packet = pack('Na*', $length, $data); + + $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + $result = strlen($packet) == fputs($this->fsock, $packet); + $stop = strtok(microtime(), ' ') + strtok(''); + + if (defined('NET_SSH1_LOGGING')) { + $temp = isset($this->protocol_flags[ord($orig[0])]) ? $this->protocol_flags[ord($orig[0])] : 'UNKNOWN'; + $temp = '-> ' . $temp . + ' (' . round($stop - $start, 4) . 's)'; + $this->_append_log($temp, $orig); + } + + return $result; + } + + /** + * Cyclic Redundancy Check (CRC) + * + * PHP's crc32 function is implemented slightly differently than the one that SSH v1 uses, so + * we've reimplemented it. A more detailed discussion of the differences can be found after + * $crc_lookup_table's initialization. + * + * @see self::_get_binary_packet() + * @see self::_send_binary_packet() + * @param string $data + * @return int + * @access private + */ + function _crc($data) + { + static $crc_lookup_table = array( + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + ); + + // For this function to yield the same output as PHP's crc32 function, $crc would have to be + // set to 0xFFFFFFFF, initially - not 0x00000000 as it currently is. + $crc = 0x00000000; + $length = strlen($data); + + for ($i=0; $i<$length; $i++) { + // We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all + // be zero. PHP, unfortunately, doesn't always do this. 0x80000000 >> 8, as an example, + // yields 0xFF800000 - not 0x00800000. The following link elaborates: + // http://www.php.net/manual/en/language.operators.bitwise.php#57281 + $crc = (($crc >> 8) & 0x00FFFFFF) ^ $crc_lookup_table[($crc & 0xFF) ^ ord($data[$i])]; + } + + // In addition to having to set $crc to 0xFFFFFFFF, initially, the return value must be XOR'd with + // 0xFFFFFFFF for this function to return the same thing that PHP's crc32 function would. + return $crc; + } + + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + * @access private + */ + function _string_shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } + + /** + * RSA Encrypt + * + * Returns mod(pow($m, $e), $n), where $n should be the product of two (large) primes $p and $q and where $e + * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1. Could just make anything that + * calls this call modexp, instead, but I think this makes things clearer, maybe... + * + * @see self::__construct() + * @param BigInteger $m + * @param array $key + * @return BigInteger + * @access private + */ + function _rsa_crypt($m, $key) + { + /* + $rsa = new RSA(); + $rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW); + $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1); + return $rsa->encrypt($m); + */ + + // To quote from protocol-1.5.txt: + // The most significant byte (which is only partial as the value must be + // less than the public modulus, which is never a power of two) is zero. + // + // The next byte contains the value 2 (which stands for public-key + // encrypted data in the PKCS standard [PKCS#1]). Then, there are non- + // zero random bytes to fill any unused space, a zero byte, and the data + // to be encrypted in the least significant bytes, the last byte of the + // data in the least significant byte. + + // Presumably the part of PKCS#1 they're refering to is "Section 7.2.1 Encryption Operation", + // under "7.2 RSAES-PKCS1-v1.5" and "7 Encryption schemes" of the following URL: + // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf + $modulus = $key[1]->toBytes(); + $length = strlen($modulus) - strlen($m) - 3; + $random = ''; + while (strlen($random) != $length) { + $block = Random::string($length - strlen($random)); + $block = str_replace("\x00", '', $block); + $random.= $block; + } + $temp = chr(0) . chr(2) . $random . chr(0) . $m; + + $m = new BigInteger($temp, 256); + $m = $m->modPow($key[0], $key[1]); + + return $m->toBytes(); + } + + /** + * Define Array + * + * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of + * named constants from it, using the value as the name of the constant and the index as the value of the constant. + * If any of the constants that would be defined already exists, none of the constants will be defined. + * + * @access private + */ + function _define_array() + { + $args = func_get_args(); + foreach ($args as $arg) { + foreach ($arg as $key => $value) { + if (!defined($value)) { + define($value, $key); + } else { + break 2; + } + } + } + } + + /** + * Returns a log of the packets that have been sent and received. + * + * Returns a string if NET_SSH1_LOGGING == self::LOG_COMPLEX, an array if NET_SSH1_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING') + * + * @access public + * @return array|false|string + */ + function getLog() + { + if (!defined('NET_SSH1_LOGGING')) { + return false; + } + + switch (NET_SSH1_LOGGING) { + case self::LOG_SIMPLE: + return $this->message_number_log; + break; + case self::LOG_COMPLEX: + return $this->_format_log($this->message_log, $this->protocol_flags_log); + break; + default: + return false; + } + } + + /** + * Formats a log for printing + * + * @param array $message_log + * @param array $message_number_log + * @access private + * @return string + */ + function _format_log($message_log, $message_number_log) + { + $output = ''; + for ($i = 0; $i < count($message_log); $i++) { + $output.= $message_number_log[$i] . "\r\n"; + $current_log = $message_log[$i]; + $j = 0; + do { + if (strlen($current_log)) { + $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; + } + $fragment = $this->_string_shift($current_log, $this->log_short_width); + $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary)); + // replace non ASCII printable characters with dots + // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters + // also replace < with a . since < messes up the output on web browsers + $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); + $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; + $j++; + } while (strlen($current_log)); + $output.= "\r\n"; + } + + return $output; + } + + /** + * Helper function for _format_log + * + * For use with preg_replace_callback() + * + * @param array $matches + * @access private + * @return string + */ + function _format_log_helper($matches) + { + return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); + } + + /** + * Return the server key public exponent + * + * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, + * the raw bytes. This behavior is similar to PHP's md5() function. + * + * @param bool $raw_output + * @return string + * @access public + */ + function getServerKeyPublicExponent($raw_output = false) + { + return $raw_output ? $this->server_key_public_exponent->toBytes() : $this->server_key_public_exponent->toString(); + } + + /** + * Return the server key public modulus + * + * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, + * the raw bytes. This behavior is similar to PHP's md5() function. + * + * @param bool $raw_output + * @return string + * @access public + */ + function getServerKeyPublicModulus($raw_output = false) + { + return $raw_output ? $this->server_key_public_modulus->toBytes() : $this->server_key_public_modulus->toString(); + } + + /** + * Return the host key public exponent + * + * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, + * the raw bytes. This behavior is similar to PHP's md5() function. + * + * @param bool $raw_output + * @return string + * @access public + */ + function getHostKeyPublicExponent($raw_output = false) + { + return $raw_output ? $this->host_key_public_exponent->toBytes() : $this->host_key_public_exponent->toString(); + } + + /** + * Return the host key public modulus + * + * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, + * the raw bytes. This behavior is similar to PHP's md5() function. + * + * @param bool $raw_output + * @return string + * @access public + */ + function getHostKeyPublicModulus($raw_output = false) + { + return $raw_output ? $this->host_key_public_modulus->toBytes() : $this->host_key_public_modulus->toString(); + } + + /** + * Return a list of ciphers supported by SSH1 server. + * + * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output + * is set to true, returns, instead, an array of constants. ie. instead of array('Triple-DES in CBC mode'), you'll + * get array(self::CIPHER_3DES). + * + * @param bool $raw_output + * @return array + * @access public + */ + function getSupportedCiphers($raw_output = false) + { + return $raw_output ? array_keys($this->supported_ciphers) : array_values($this->supported_ciphers); + } + + /** + * Return a list of authentications supported by SSH1 server. + * + * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output + * is set to true, returns, instead, an array of constants. ie. instead of array('password authentication'), you'll + * get array(self::AUTH_PASSWORD). + * + * @param bool $raw_output + * @return array + * @access public + */ + function getSupportedAuthentications($raw_output = false) + { + return $raw_output ? array_keys($this->supported_authentications) : array_values($this->supported_authentications); + } + + /** + * Return the server identification. + * + * @return string + * @access public + */ + function getServerIdentification() + { + return rtrim($this->server_identification); + } + + /** + * Logs data packets + * + * Makes sure that only the last 1MB worth of packets will be logged + * + * @param int $protocol_flags + * @param string $message + * @access private + */ + function _append_log($protocol_flags, $message) + { + switch (NET_SSH1_LOGGING) { + // useful for benchmarks + case self::LOG_SIMPLE: + $this->protocol_flags_log[] = $protocol_flags; + break; + // the most useful log for SSH1 + case self::LOG_COMPLEX: + $this->protocol_flags_log[] = $protocol_flags; + $this->_string_shift($message); + $this->log_size+= strlen($message); + $this->message_log[] = $message; + while ($this->log_size > self::LOG_MAX_SIZE) { + $this->log_size-= strlen(array_shift($this->message_log)); + array_shift($this->protocol_flags_log); + } + break; + // dump the output out realtime; packets may be interspersed with non packets, + // passwords won't be filtered out and select other packets may not be correctly + // identified + case self::LOG_REALTIME: + echo "
      \r\n" . $this->_format_log(array($message), array($protocol_flags)) . "\r\n
      \r\n"; + @flush(); + @ob_flush(); + break; + // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE + // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. + // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily + // at the beginning of the file + case self::LOG_REALTIME_FILE: + if (!isset($this->realtime_log_file)) { + // PHP doesn't seem to like using constants in fopen() + $filename = self::LOG_REALTIME_FILE; + $fp = fopen($filename, 'w'); + $this->realtime_log_file = $fp; + } + if (!is_resource($this->realtime_log_file)) { + break; + } + $entry = $this->_format_log(array($message), array($protocol_flags)); + if ($this->realtime_log_wrap) { + $temp = "<<< START >>>\r\n"; + $entry.= $temp; + fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp)); + } + $this->realtime_log_size+= strlen($entry); + if ($this->realtime_log_size > self::LOG_MAX_SIZE) { + fseek($this->realtime_log_file, 0); + $this->realtime_log_size = strlen($entry); + $this->realtime_log_wrap = true; + } + fputs($this->realtime_log_file, $entry); + } + } +} -- cgit v1.2.3 From 41f84dabcc14415a47f24ed25a90495bbfcda52a Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 4 Feb 2021 21:21:22 +0100 Subject: use phpseclib for key transformations --- include/crypto.php | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/include/crypto.php b/include/crypto.php index 0d3a5842d..f86d1153c 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -1,7 +1,7 @@ loadKey([ 'e' => new BigInteger($e, 256), 'n' => new BigInteger($m, 256) ]); - hz_syslog('metopem: ' . $key->toString('PKCS8')); - return $key->toString('PKCS8'); + return $rsa->getPublicKey(); /* $der = pkcs8_encode($m,$e); $key = DerToPem($der,false); @@ -423,10 +423,10 @@ function pubrsatome($key,&$m,&$e) { function rsatopem($key) { - $key = PublicKeyLoader::load($key); - hz_syslog('rsatopem: ' . $key->toString('PKCS8')); + $rsa = new RSA(); + $rsa->setPublicKey($key); - return $key->toString('PKCS8'); + return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); /* pubrsatome($key,$m,$e); @@ -434,10 +434,10 @@ function rsatopem($key) { } function pemtorsa($key) { - $key = PublicKeyLoader::load($key); - hz_syslog('pemtorsa: ' . $key->toString('PKCS1')); + $rsa = new RSA(); + $rsa->setPublicKey($key); - return $key->toString('PKCS1'); + return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); /* pemtome($key,$m,$e); return(metorsa($m,$e));*/ @@ -446,9 +446,12 @@ function pemtorsa($key) { function pemtome($key,&$m,&$e) { - $key = PublicKeyLoader::load($key); - $m = new BigInteger($key->n, 256); - $e = new BigInteger($key->e, 256); + $rsa = new RSA(); + $rsa->loadKey($key); + $rsa->setPublicKey(); + + $e = $rsa->modulus->toBytes(); + $m = $rsa->exponent->toBytes(); /* $rsa = new RSA(); @@ -473,13 +476,12 @@ function pemtome($key,&$m,&$e) { function metorsa($m,$e) { - $key = PublicKeyLoader::load([ + $rsa = new RSA(); + $rsa->loadKey([ 'e' => new BigInteger($e, 256), 'n' => new BigInteger($m, 256) ]); - hz_syslog('metorsa: ' . $key->toString('PKCS8')); - - return $key->toString('PKCS8'); + return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); /* $der = pkcs1_encode($m,$e); $key = DerToRsa($der); -- cgit v1.2.3 From 6bb73e14b6521ea7c2d4f77d2954e4f8744bb736 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 4 Feb 2021 21:31:37 +0100 Subject: key conversion functions cleanup --- include/crypto.php | 146 +++++++---------------------------------------------- 1 file changed, 19 insertions(+), 127 deletions(-) diff --git a/include/crypto.php b/include/crypto.php index f86d1153c..66bd113bc 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -3,9 +3,6 @@ use phpseclib\Crypt\RSA; use phpseclib\Math\BigInteger; -require_once('library/ASNValue.class.php'); -require_once('library/asn1.php'); - function rsa_sign($data,$key,$alg = 'sha256') { if(! $key) return 'no key'; @@ -311,81 +308,6 @@ function new_keypair($bits) { } -function DerToPem($Der, $Private=false) -{ - //Encode: - $Der = base64_encode($Der); - //Split lines: - $lines = str_split($Der, 65); - $body = implode("\n", $lines); - //Get title: - $title = $Private? 'RSA PRIVATE KEY' : 'PUBLIC KEY'; - //Add wrapping: - $result = "-----BEGIN {$title}-----\n"; - $result .= $body . "\n"; - $result .= "-----END {$title}-----\n"; - - return $result; -} - -function DerToRsa($Der) -{ - //Encode: - $Der = base64_encode($Der); - //Split lines: - $lines = str_split($Der, 64); - $body = implode("\n", $lines); - //Get title: - $title = 'RSA PUBLIC KEY'; - //Add wrapping: - $result = "-----BEGIN {$title}-----\n"; - $result .= $body . "\n"; - $result .= "-----END {$title}-----\n"; - - return $result; -} - - -function pkcs8_encode($Modulus,$PublicExponent) { - //Encode key sequence - $modulus = new ASNValue(ASNValue::TAG_INTEGER); - $modulus->SetIntBuffer($Modulus); - $publicExponent = new ASNValue(ASNValue::TAG_INTEGER); - $publicExponent->SetIntBuffer($PublicExponent); - $keySequenceItems = array($modulus, $publicExponent); - $keySequence = new ASNValue(ASNValue::TAG_SEQUENCE); - $keySequence->SetSequence($keySequenceItems); - //Encode bit string - $bitStringValue = $keySequence->Encode(); - $bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte - $bitString = new ASNValue(ASNValue::TAG_BITSTRING); - $bitString->Value = $bitStringValue; - //Encode body - $bodyValue = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" . $bitString->Encode(); - $body = new ASNValue(ASNValue::TAG_SEQUENCE); - $body->Value = $bodyValue; - //Get DER encoded public key: - $PublicDER = $body->Encode(); - return $PublicDER; -} - - -function pkcs1_encode($Modulus,$PublicExponent) { - //Encode key sequence - $modulus = new ASNValue(ASNValue::TAG_INTEGER); - $modulus->SetIntBuffer($Modulus); - $publicExponent = new ASNValue(ASNValue::TAG_INTEGER); - $publicExponent->SetIntBuffer($PublicExponent); - $keySequenceItems = array($modulus, $publicExponent); - $keySequence = new ASNValue(ASNValue::TAG_SEQUENCE); - $keySequence->SetSequence($keySequenceItems); - //Encode bit string - $bitStringValue = $keySequence->Encode(); - return $bitStringValue; -} - - -// http://stackoverflow.com/questions/27568570/how-to-convert-raw-modulus-exponent-to-rsa-public-key-pem-format /** * @param string $m modulo * @param string $e exponent @@ -400,27 +322,12 @@ function metopem($m, $e) { ]); return $rsa->getPublicKey(); -/* $der = pkcs8_encode($m,$e); - $key = DerToPem($der,false); - return $key;*/ } - -function pubrsatome($key,&$m,&$e) { - require_once('library/asn1.php'); - - $lines = explode("\n",$key); - unset($lines[0]); - unset($lines[count($lines)]); - $x = base64_decode(implode('',$lines)); - - $r = ASN_BASE::parseASNString($x); - - $m = base64url_decode($r[0]->asnData[0]->asnData); - $e = base64url_decode($r[0]->asnData[1]->asnData); -} - - +/** + * @param string key + * @return string + */ function rsatopem($key) { $rsa = new RSA(); @@ -428,22 +335,26 @@ function rsatopem($key) { return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); - -/* pubrsatome($key,$m,$e); - return(metopem($m,$e));*/ } +/** + * @param string key + * @return string + */ function pemtorsa($key) { + $rsa = new RSA(); $rsa->setPublicKey($key); return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); -/* pemtome($key,$m,$e); - return(metorsa($m,$e));*/ - } +/** + * @param string $key key + * @param string $m reference modulo + * @param string $e reference exponent + */ function pemtome($key,&$m,&$e) { $rsa = new RSA(); @@ -453,27 +364,13 @@ function pemtome($key,&$m,&$e) { $e = $rsa->modulus->toBytes(); $m = $rsa->exponent->toBytes(); - -/* $rsa = new RSA(); - $rsa->loadKey($key); - $rsa->setPublicKey(); - - $modulus = $rsa->modulus->toBytes(); - $exponent = $rsa->exponent->toBytes(); - - - - $lines = explode("\n",$key); - unset($lines[0]); - unset($lines[count($lines)]); - $x = base64_decode(implode('',$lines)); - - $r = ASN_BASE::parseASNString($x); - - $m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData); - $e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);*/ } +/** + * @param string $m modulo + * @param string $e exponent + * @return string + */ function metorsa($m,$e) { $rsa = new RSA(); @@ -483,19 +380,14 @@ function metorsa($m,$e) { ]); return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); -/* $der = pkcs1_encode($m,$e); - $key = DerToRsa($der); - return $key;*/ } - function salmon_key($pubkey) { pemtome($pubkey,$m,$e); return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ; } - function convert_salmon_key($key) { if(strstr($key,',')) -- cgit v1.2.3 From 03e1f5f8a41c88e8feea19784d7521435e7e4b2e Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 4 Feb 2021 21:49:25 +0100 Subject: remove unused function --- include/crypto.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/include/crypto.php b/include/crypto.php index 66bd113bc..e2132337f 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -366,23 +366,6 @@ function pemtome($key,&$m,&$e) { } -/** - * @param string $m modulo - * @param string $e exponent - * @return string - */ -function metorsa($m,$e) { - - $rsa = new RSA(); - $rsa->loadKey([ - 'e' => new BigInteger($e, 256), - 'n' => new BigInteger($m, 256) - ]); - return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); - -} - - function salmon_key($pubkey) { pemtome($pubkey,$m,$e); return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ; -- cgit v1.2.3 From 19007dd8ebc0d4364cff56c923f5ea8fad018b76 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 4 Feb 2021 22:16:48 +0100 Subject: move key conversion to separate lib --- Zotlabs/Lib/Activity.php | 2 +- Zotlabs/Module/Wfinger.php | 73 +++++++++++++++++++++++----------------------- Zotlabs/Module/Xrd.php | 38 ++++++++++++------------ Zotlabs/Web/HTTPSig.php | 4 +-- 4 files changed, 60 insertions(+), 57 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index cedc9adc8..abb28fc64 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1566,7 +1566,7 @@ class Activity { if ($person_obj['id'] === $person_obj['publicKey']['owner']) { $pubkey = $person_obj['publicKey']['publicKeyPem']; if (strstr($pubkey, 'RSA ')) { - $pubkey = rsatopem($pubkey); + $pubkey = Keyutils::rsaToPem($pubkey); } } } diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php index d24a31a15..6f2864615 100644 --- a/Zotlabs/Module/Wfinger.php +++ b/Zotlabs/Module/Wfinger.php @@ -3,34 +3,35 @@ namespace Zotlabs\Module; require_once('include/zot.php'); +use Zotlabs\Lib\Keyutils; use Zotlabs\Lib\Libzot; class Wfinger extends \Zotlabs\Web\Controller { function init() { - + session_write_close(); $result = array(); - + $scheme = ''; - + if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS']) $scheme = 'https'; elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) $scheme = 'https'; - + $zot = intval($_REQUEST['zot']); - + if(($scheme !== 'https') && (! $zot)) { header($_SERVER["SERVER_PROTOCOL"] . ' ' . 500 . ' ' . 'Webfinger requires HTTPS'); killme(); } - - + + $resource = $_REQUEST['resource']; logger('webfinger: ' . $resource,LOGGER_DEBUG); - + $root_resource = false; $pchan = false; @@ -39,9 +40,9 @@ class Wfinger extends \Zotlabs\Web\Controller { $root_resource = true; $r = null; - + if(($resource) && (! $root_resource)) { - + if(strpos($resource,'acct:') === 0) { $channel = str_replace('acct:','',$resource); if(substr($channel,0,1) === '@' && strpos(substr($channel,1),'@')) { @@ -56,12 +57,12 @@ class Wfinger extends \Zotlabs\Web\Controller { goaway('https://' . $host . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=' . $zot : '')); } $channel = substr($channel,0,strpos($channel,'@')); - } + } } if(strpos($resource,'http') === 0) { $channel = str_replace('~','',basename($resource)); } - + if(substr($channel,0,1) === '[' ) { $channel = substr($channel,1); $channel = substr($channel,0,-1); @@ -74,16 +75,16 @@ class Wfinger extends \Zotlabs\Web\Controller { $r[0] = pchan_to_chan($r[0]); } } - else { + else { $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_address = '%s' limit 1", dbesc($channel) ); } } - + header('Access-Control-Allow-Origin: *'); - + if($root_resource) { $result['subject'] = $resource; @@ -100,52 +101,52 @@ class Wfinger extends \Zotlabs\Web\Controller { - + } if($resource && $r) { - + $h = q("select hubloc_addr from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", dbesc($r[0]['channel_hash']) ); - + $result['subject'] = $resource; - + $aliases = array( z_root() . (($pchan) ? '/pchan/' : '/channel/') . $r[0]['channel_address'], z_root() . '/~' . $r[0]['channel_address'], z_root() . '/@' . $r[0]['channel_address'] ); - + if($h) { foreach($h as $hh) { $aliases[] = 'acct:' . $hh['hubloc_addr']; } } - + $result['aliases'] = []; - + $result['properties'] = [ 'http://webfinger.net/ns/name' => $r[0]['channel_name'], 'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name'], 'https://w3id.org/security/v1#publicKeyPem' => $r[0]['xchan_pubkey'], 'http://purl.org/zot/federation' => 'zot6,zot' ]; - - foreach($aliases as $alias) + + foreach($aliases as $alias) if($alias != $resource) $result['aliases'][] = $alias; - + if($pchan) { $result['links'] = [ - + [ 'rel' => 'http://webfinger.net/rel/avatar', 'type' => $r[0]['xchan_photo_mimetype'], 'href' => $r[0]['xchan_photo_l'] ], - + [ 'rel' => 'http://webfinger.net/rel/profile-page', 'href' => $r[0]['xchan_url'], @@ -153,7 +154,7 @@ class Wfinger extends \Zotlabs\Web\Controller { [ 'rel' => 'magic-public-key', - 'href' => 'data:application/magic-public-key,' . salmon_key($r[0]['channel_pubkey']), + 'href' => 'data:application/magic-public-key,' . Keyutils::salmonKey($r[0]['channel_pubkey']), ] ]; @@ -167,13 +168,13 @@ class Wfinger extends \Zotlabs\Web\Controller { [ 'rel' => 'http://webfinger.net/rel/avatar', 'type' => $r[0]['xchan_photo_mimetype'], - 'href' => $r[0]['xchan_photo_l'] + 'href' => $r[0]['xchan_photo_l'] ], [ 'rel' => 'http://microformats.org/profile/hcard', 'type' => 'text/html', - 'href' => z_root() . '/hcard/' . $r[0]['channel_address'] + 'href' => z_root() . '/hcard/' . $r[0]['channel_address'] ], [ @@ -187,8 +188,8 @@ class Wfinger extends \Zotlabs\Web\Controller { ], [ - 'rel' => 'http://schemas.google.com/g/2010#updates-from', - 'type' => 'application/atom+xml', + 'rel' => 'http://schemas.google.com/g/2010#updates-from', + 'type' => 'application/atom+xml', 'href' => z_root() . '/ofeed/' . $r[0]['channel_address'] ], @@ -221,7 +222,7 @@ class Wfinger extends \Zotlabs\Web\Controller { [ 'rel' => 'magic-public-key', - 'href' => 'data:application/magic-public-key,' . salmon_key($r[0]['channel_pubkey']), + 'href' => 'data:application/magic-public-key,' . Keyutils::salmonKey($r[0]['channel_pubkey']), ] ]; } @@ -236,12 +237,12 @@ class Wfinger extends \Zotlabs\Web\Controller { header($_SERVER["SERVER_PROTOCOL"] . ' ' . 400 . ' ' . 'Bad Request'); killme(); } - + $arr = [ 'channel' => $r[0], 'pchan' => $pchan, 'request' => $_REQUEST, 'result' => $result ]; call_hooks('webfinger',$arr); json_return_and_die($arr['result'],'application/jrd+json'); - + } - + } diff --git a/Zotlabs/Module/Xrd.php b/Zotlabs/Module/Xrd.php index 959e31cbe..21574eb8d 100644 --- a/Zotlabs/Module/Xrd.php +++ b/Zotlabs/Module/Xrd.php @@ -1,19 +1,21 @@ $r[0]['channel_address'], '$accturi' => $resource, @@ -60,14 +62,14 @@ class Xrd extends \Zotlabs\Web\Controller { '$modexp' => 'data:application/magic-public-key,' . $salmon_key, '$subscribe' => z_root() . '/follow?f=&url={uri}', )); - - + + $arr = array('user' => $r[0], 'xml' => $o); call_hooks('personal_xrd', $arr); - + echo $arr['xml']; killme(); - + } - + } diff --git a/Zotlabs/Web/HTTPSig.php b/Zotlabs/Web/HTTPSig.php index 7c3903682..8dd999e59 100644 --- a/Zotlabs/Web/HTTPSig.php +++ b/Zotlabs/Web/HTTPSig.php @@ -3,8 +3,8 @@ namespace Zotlabs\Web; use Zotlabs\Lib\ActivityStreams; +use Zotlabs\Lib\Keyutils; use Zotlabs\Lib\Webfinger; -use Zotlabs\Web\HTTPHeaders; use Zotlabs\Lib\Libzot; /** @@ -252,7 +252,7 @@ class HTTPSig { return rsatopem($key); } elseif(substr($key,0,5) === 'data:') { - return convert_salmon_key($key); + return Keyutils::convertSalmonKey($key); } else { return $key; -- cgit v1.2.3 From 9e226414252e02eb1340fdaf75f76f00d6ded77c Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 4 Feb 2021 22:20:55 +0100 Subject: add Lib/Keyutils --- Zotlabs/Lib/Keyutils.php | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Zotlabs/Lib/Keyutils.php diff --git a/Zotlabs/Lib/Keyutils.php b/Zotlabs/Lib/Keyutils.php new file mode 100644 index 000000000..d4b660c04 --- /dev/null +++ b/Zotlabs/Lib/Keyutils.php @@ -0,0 +1,99 @@ +loadKey([ + 'e' => new BigInteger($e, 256), + 'n' => new BigInteger($m, 256) + ]); + return $rsa->getPublicKey(); + + } + + /** + * @param string key + * @return string + */ + public static function rsaToPem($key) { + + $rsa = new RSA(); + $rsa->setPublicKey($key); + + return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); + + } + + /** + * @param string key + * @return string + */ + public static function pemToRsa($key) { + + $rsa = new RSA(); + $rsa->setPublicKey($key); + + return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); + + } + + /** + * @param string $key key + * @param string $m reference modulo + * @param string $e reference exponent + */ + public static function pemToMe($key, &$m, &$e) { + + $rsa = new RSA(); + $rsa->loadKey($key); + $rsa->setPublicKey(); + + $e = $rsa->modulus->toBytes(); + $m = $rsa->exponent->toBytes(); + + } + + /** + * @param string $pubkey + * @return string + */ + public static function salmonKey($pubkey) { + self::pemToMe($pubkey, $m, $e); + return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true); + } + + /** + * @param string $key + * @return string + */ + public static function convertSalmonKey($key) { + if (strstr($key, ',')) + $rawkey = substr($key, strpos($key, ',') + 1); + else + $rawkey = substr($key, 5); + + $key_info = explode('.', $rawkey); + + $m = base64url_decode($key_info[1]); + $e = base64url_decode($key_info[2]); + + return self::meToPem($m, $e); + } + +} \ No newline at end of file -- cgit v1.2.3 From a9070382e7ce072e445b507a3e0d3e2c763d948c Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 4 Feb 2021 22:26:29 +0100 Subject: bump version --- boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot.php b/boot.php index 490e847af..4d18d4844 100644 --- a/boot.php +++ b/boot.php @@ -50,7 +50,7 @@ require_once('include/attach.php'); require_once('include/bbcode.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '5.3.2' ); +define ( 'STD_VERSION', '5.3.3' ); define ( 'ZOT_REVISION', '6.0' ); define ( 'DB_UPDATE_VERSION', 1241 ); -- cgit v1.2.3 From 8bb77bcfd638b3921df0092ad0e1d39113b14e57 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Fri, 5 Feb 2021 15:32:09 +0100 Subject: Fix new Imagemagick object --- include/photo/photo_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index 87b1d96fe..8de5185af 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -111,7 +111,7 @@ function guess_image_type($filename, $data = '') { elseif (is_array($data) && array_key_exists('body', $data)) $body = $data['body']; if ($body) { - $image = new Imagick($filename); + $image = new Imagick(); $image->readImageBlob($body); $r = $image->identifyImage(); if ($r && is_array($r) && array_key_exists($r['mimetype'], $types)) -- cgit v1.2.3 From e1d622c49f95aec51e5c1bd521dcd6fe2a9a5372 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sat, 6 Feb 2021 11:36:22 +0100 Subject: Use datetime interval in public tag cloud query to support queueworker deduplication --- include/taxonomy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/taxonomy.php b/include/taxonomy.php index 7745b6a5b..5fa4fde3f 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -345,7 +345,7 @@ function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) { } if($recent) - $sql_extra .= " and item.created > '" . datetime_convert('UTC','UTC', 'now - ' . intval($recent) . ' days ') . "' "; + $sql_extra .= " and item.created > NOW() - INTERVAL " . db_quoteinterval(intval($recent) . ' DAY') . " "; if($safemode) { -- cgit v1.2.3 From d316d9436bde512f520c5d1615d107b8e74744df Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Feb 2021 10:17:05 +0000 Subject: mixed up variables --- Zotlabs/Lib/Keyutils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Lib/Keyutils.php b/Zotlabs/Lib/Keyutils.php index d4b660c04..616ecfcf6 100644 --- a/Zotlabs/Lib/Keyutils.php +++ b/Zotlabs/Lib/Keyutils.php @@ -64,8 +64,8 @@ class Keyutils { $rsa->loadKey($key); $rsa->setPublicKey(); - $e = $rsa->modulus->toBytes(); - $m = $rsa->exponent->toBytes(); + $m = $rsa->modulus->toBytes(); + $e = $rsa->exponent->toBytes(); } -- cgit v1.2.3 From eb05e5a20515419cc8bd4df33cd40c50391785e4 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Feb 2021 10:55:35 +0000 Subject: revert include/crypto to its previous state for reference - we are now using Lib/Keyutils for key conversion --- include/crypto.php | 158 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 44 deletions(-) diff --git a/include/crypto.php b/include/crypto.php index e2132337f..84d639f3f 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -1,7 +1,7 @@ loadKey([ - 'e' => new BigInteger($e, 256), - 'n' => new BigInteger($m, 256) - ]); - return $rsa->getPublicKey(); +function DerToRsa($Der) +{ + //Encode: + $Der = base64_encode($Der); + //Split lines: + $lines = str_split($Der, 64); + $body = implode("\n", $lines); + //Get title: + $title = 'RSA PUBLIC KEY'; + //Add wrapping: + $result = "-----BEGIN {$title}-----\n"; + $result .= $body . "\n"; + $result .= "-----END {$title}-----\n"; + return $result; } -/** - * @param string key - * @return string - */ -function rsatopem($key) { - $rsa = new RSA(); - $rsa->setPublicKey($key); +function pkcs8_encode($Modulus,$PublicExponent) { + //Encode key sequence + $modulus = new ASNValue(ASNValue::TAG_INTEGER); + $modulus->SetIntBuffer($Modulus); + $publicExponent = new ASNValue(ASNValue::TAG_INTEGER); + $publicExponent->SetIntBuffer($PublicExponent); + $keySequenceItems = array($modulus, $publicExponent); + $keySequence = new ASNValue(ASNValue::TAG_SEQUENCE); + $keySequence->SetSequence($keySequenceItems); + //Encode bit string + $bitStringValue = $keySequence->Encode(); + $bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte + $bitString = new ASNValue(ASNValue::TAG_BITSTRING); + $bitString->Value = $bitStringValue; + //Encode body + $bodyValue = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" . $bitString->Encode(); + $body = new ASNValue(ASNValue::TAG_SEQUENCE); + $body->Value = $bodyValue; + //Get DER encoded public key: + $PublicDER = $body->Encode(); + return $PublicDER; +} - return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); +function pkcs1_encode($Modulus,$PublicExponent) { + //Encode key sequence + $modulus = new ASNValue(ASNValue::TAG_INTEGER); + $modulus->SetIntBuffer($Modulus); + $publicExponent = new ASNValue(ASNValue::TAG_INTEGER); + $publicExponent->SetIntBuffer($PublicExponent); + $keySequenceItems = array($modulus, $publicExponent); + $keySequence = new ASNValue(ASNValue::TAG_SEQUENCE); + $keySequence->SetSequence($keySequenceItems); + //Encode bit string + $bitStringValue = $keySequence->Encode(); + return $bitStringValue; } -/** - * @param string key - * @return string - */ -function pemtorsa($key) { - $rsa = new RSA(); - $rsa->setPublicKey($key); +// http://stackoverflow.com/questions/27568570/how-to-convert-raw-modulus-exponent-to-rsa-public-key-pem-format +function metopem($m,$e) { + $der = pkcs8_encode($m,$e); + $key = DerToPem($der,false); + return $key; +} + + +function pubrsatome($key,&$m,&$e) { + require_once('library/asn1.php'); + + $lines = explode("\n",$key); + unset($lines[0]); + unset($lines[count($lines)]); + $x = base64_decode(implode('',$lines)); - return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); + $r = ASN_BASE::parseASNString($x); + $m = base64url_decode($r[0]->asnData[0]->asnData); + $e = base64url_decode($r[0]->asnData[1]->asnData); +} + + +function rsatopem($key) { + pubrsatome($key,$m,$e); + return(metopem($m,$e)); +} + +function pemtorsa($key) { + pemtome($key,$m,$e); + return(metorsa($m,$e)); } -/** - * @param string $key key - * @param string $m reference modulo - * @param string $e reference exponent - */ function pemtome($key,&$m,&$e) { + $lines = explode("\n",$key); + unset($lines[0]); + unset($lines[count($lines)]); + $x = base64_decode(implode('',$lines)); - $rsa = new RSA(); - $rsa->loadKey($key); - $rsa->setPublicKey(); + $r = ASN_BASE::parseASNString($x); - $e = $rsa->modulus->toBytes(); - $m = $rsa->exponent->toBytes(); + $m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData); + $e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData); +} +function metorsa($m,$e) { + $der = pkcs1_encode($m,$e); + $key = DerToRsa($der); + return $key; } + + function salmon_key($pubkey) { pemtome($pubkey,$m,$e); return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ; } + function convert_salmon_key($key) { if(strstr($key,',')) -- cgit v1.2.3 From a8e0bd1f122ecfc35d7834f73d2fff9b276ace29 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Feb 2021 13:37:48 +0000 Subject: keyutils tests --- tests/unit/Lib/KeyutilsTest.php | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/unit/Lib/KeyutilsTest.php diff --git a/tests/unit/Lib/KeyutilsTest.php b/tests/unit/Lib/KeyutilsTest.php new file mode 100644 index 000000000..67b71d70e --- /dev/null +++ b/tests/unit/Lib/KeyutilsTest.php @@ -0,0 +1,87 @@ +loadKey([ + 'e' => new BigInteger($e, 256), + 'n' => new BigInteger($m, 256) + ]); + + self::assertEquals($gen_key->getPublicKey(), $orig_key); + } + +} -- cgit v1.2.3 From 1bcf84f27510e9afe20a3c6a509ca7062aba0aa9 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Feb 2021 16:04:56 +0000 Subject: fix test --- tests/unit/Lib/KeyutilsTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/unit/Lib/KeyutilsTest.php b/tests/unit/Lib/KeyutilsTest.php index 67b71d70e..162b2b279 100644 --- a/tests/unit/Lib/KeyutilsTest.php +++ b/tests/unit/Lib/KeyutilsTest.php @@ -49,7 +49,9 @@ W2xGFku1h9fT+kNCi0YnTZlbmXEQKo2/Qha/nMCvA+idfDcHw9DVZNIMpH5kk3JC GxBR2GGV8LISqKpZqZ+9AzZeqt8aCSC2/h8nq5nCWLVMTtJIiV/1GE5aEe2fR9GS Az76YS3wXMqvWx19XE+v74sBNqhtxrZfQRfeHalDv1nUkcBkaYglQmggZ2jd+p6d soJHIKiLs/8fMzRqLyrqZwIDAQAB - -----END PUBLIC KEY-----'; +-----END PUBLIC KEY-----'; + + $orig_key = str_replace(["\r", "\n"], "\r\n", $orig_key); Keyutils::pemToMe($orig_key, $m, $e); $gen_key = Keyutils::meToPem($m, $e); @@ -71,7 +73,9 @@ W2xGFku1h9fT+kNCi0YnTZlbmXEQKo2/Qha/nMCvA+idfDcHw9DVZNIMpH5kk3JC GxBR2GGV8LISqKpZqZ+9AzZeqt8aCSC2/h8nq5nCWLVMTtJIiV/1GE5aEe2fR9GS Az76YS3wXMqvWx19XE+v74sBNqhtxrZfQRfeHalDv1nUkcBkaYglQmggZ2jd+p6d soJHIKiLs/8fMzRqLyrqZwIDAQAB - -----END PUBLIC KEY-----'; +-----END PUBLIC KEY-----'; + + $orig_key = str_replace(["\r", "\n"], "\r\n", $orig_key); Keyutils::pemToMe($orig_key, $m, $e); -- cgit v1.2.3 From 320e95aaae47ca039bb948fbcdceaab94e9a46f9 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Feb 2021 16:08:31 +0000 Subject: composer --- vendor/composer/ClassLoader.php | 32 --------- vendor/composer/InstalledVersions.php | 127 +++++++++------------------------- vendor/composer/autoload_classmap.php | 4 ++ vendor/composer/autoload_real.php | 2 +- vendor/composer/autoload_static.php | 4 ++ vendor/composer/installed.php | 12 ++-- 6 files changed, 46 insertions(+), 135 deletions(-) diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 4d989a212..1a58957d2 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -42,8 +42,6 @@ namespace Composer\Autoload; */ class ClassLoader { - private $vendorDir; - // PSR-4 private $prefixLengthsPsr4 = array(); private $prefixDirsPsr4 = array(); @@ -59,13 +57,6 @@ class ClassLoader private $missingClasses = array(); private $apcuPrefix; - private static $registeredLoaders = array(); - - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - } - public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -309,15 +300,6 @@ class ClassLoader public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - //no-op - } elseif ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } } /** @@ -326,10 +308,6 @@ class ClassLoader public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } } /** @@ -389,16 +367,6 @@ class ClassLoader return $file; } - /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. - * - * @return self[] - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - private function findFileWithExtension($class, $ext) { // PSR-4 lookup diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index e597e0eb3..49f5297d5 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -12,7 +12,6 @@ namespace Composer; -use Composer\Autoload\ClassLoader; use Composer\Semver\VersionParser; @@ -25,12 +24,12 @@ class InstalledVersions private static $installed = array ( 'root' => array ( - 'pretty_version' => 'dev-5.2RC', - 'version' => 'dev-5.2RC', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'aliases' => array ( ), - 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', + 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -267,17 +266,15 @@ private static $installed = array ( ), 'zotlabs/hubzilla' => array ( - 'pretty_version' => 'dev-5.2RC', - 'version' => 'dev-5.2RC', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'aliases' => array ( ), - 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', + 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', ), ), ); -private static $canGetVendors; -private static $installedByVendor = array(); @@ -287,17 +284,7 @@ private static $installedByVendor = array(); public static function getInstalledPackages() { -$packages = array(); -foreach (self::getInstalled() as $installed) { -$packages[] = array_keys($installed['versions']); -} - - -if (1 === \count($packages)) { -return $packages[0]; -} - -return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); +return array_keys(self::$installed['versions']); } @@ -310,13 +297,7 @@ return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); public static function isInstalled($packageName) { -foreach (self::getInstalled() as $installed) { -if (isset($installed['versions'][$packageName])) { -return true; -} -} - -return false; +return isset(self::$installed['versions'][$packageName]); } @@ -351,50 +332,42 @@ return $provided->matches($constraint); public static function getVersionRanges($packageName) { -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } $ranges = array(); -if (isset($installed['versions'][$packageName]['pretty_version'])) { -$ranges[] = $installed['versions'][$packageName]['pretty_version']; +if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; } -if (array_key_exists('aliases', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); +if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); } -if (array_key_exists('replaced', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); +if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); } -if (array_key_exists('provided', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); +if (array_key_exists('provided', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); } return implode(' || ', $ranges); } -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - public static function getVersion($packageName) { -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } -if (!isset($installed['versions'][$packageName]['version'])) { +if (!isset(self::$installed['versions'][$packageName]['version'])) { return null; } -return $installed['versions'][$packageName]['version']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +return self::$installed['versions'][$packageName]['version']; } @@ -403,19 +376,15 @@ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed public static function getPrettyVersion($packageName) { -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } -if (!isset($installed['versions'][$packageName]['pretty_version'])) { +if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { return null; } -return $installed['versions'][$packageName]['pretty_version']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +return self::$installed['versions'][$packageName]['pretty_version']; } @@ -424,19 +393,15 @@ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed public static function getReference($packageName) { -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); } -if (!isset($installed['versions'][$packageName]['reference'])) { +if (!isset(self::$installed['versions'][$packageName]['reference'])) { return null; } -return $installed['versions'][$packageName]['reference']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +return self::$installed['versions'][$packageName]['reference']; } @@ -445,9 +410,7 @@ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed public static function getRootPackage() { -$installed = self::getInstalled(); - -return $installed[0]['root']; +return self::$installed['root']; } @@ -482,33 +445,5 @@ return self::$installed; public static function reload($data) { self::$installed = $data; -self::$installedByVendor = array(); -} - - - - -private static function getInstalled() -{ -if (null === self::$canGetVendors) { -self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); -} - -$installed = array(); - -if (self::$canGetVendors) { - -foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { -if (isset(self::$installedByVendor[$vendorDir])) { -$installed[] = self::$installedByVendor[$vendorDir]; -} elseif (is_file($vendorDir.'/composer/installed.php')) { -$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; -} -} -} - -$installed[] = self::$installed; - -return $installed; } } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index da2dfa8f4..5f6184ca5 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -384,6 +384,9 @@ return array( 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', + 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/DummyTest.php', + 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php', 'Ramsey\\Collection\\AbstractArray' => $vendorDir . '/ramsey/collection/src/AbstractArray.php', 'Ramsey\\Collection\\AbstractCollection' => $vendorDir . '/ramsey/collection/src/AbstractCollection.php', 'Ramsey\\Collection\\AbstractSet' => $vendorDir . '/ramsey/collection/src/AbstractSet.php', @@ -1123,6 +1126,7 @@ return array( 'Zotlabs\\Lib\\Chatroom' => $baseDir . '/Zotlabs/Lib/Chatroom.php', 'Zotlabs\\Lib\\Config' => $baseDir . '/Zotlabs/Lib/Config.php', 'Zotlabs\\Lib\\Connect' => $baseDir . '/Zotlabs/Lib/Connect.php', + 'Zotlabs\\Lib\\Crypto' => $baseDir . '/Zotlabs/Lib/Crypto.php', 'Zotlabs\\Lib\\DB_Upgrade' => $baseDir . '/Zotlabs/Lib/DB_Upgrade.php', 'Zotlabs\\Lib\\DReport' => $baseDir . '/Zotlabs/Lib/DReport.php', 'Zotlabs\\Lib\\Enotify' => $baseDir . '/Zotlabs/Lib/Enotify.php', diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index fbfac821c..264e26beb 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -25,7 +25,7 @@ class ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d require __DIR__ . '/platform_check.php'; spl_autoload_register(array('ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 5abdb7dce..e61c918c6 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -574,6 +574,9 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php', + 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/DummyTest.php', + 'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php', 'Ramsey\\Collection\\AbstractArray' => __DIR__ . '/..' . '/ramsey/collection/src/AbstractArray.php', 'Ramsey\\Collection\\AbstractCollection' => __DIR__ . '/..' . '/ramsey/collection/src/AbstractCollection.php', 'Ramsey\\Collection\\AbstractSet' => __DIR__ . '/..' . '/ramsey/collection/src/AbstractSet.php', @@ -1313,6 +1316,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Lib\\Chatroom' => __DIR__ . '/../..' . '/Zotlabs/Lib/Chatroom.php', 'Zotlabs\\Lib\\Config' => __DIR__ . '/../..' . '/Zotlabs/Lib/Config.php', 'Zotlabs\\Lib\\Connect' => __DIR__ . '/../..' . '/Zotlabs/Lib/Connect.php', + 'Zotlabs\\Lib\\Crypto' => __DIR__ . '/../..' . '/Zotlabs/Lib/Crypto.php', 'Zotlabs\\Lib\\DB_Upgrade' => __DIR__ . '/../..' . '/Zotlabs/Lib/DB_Upgrade.php', 'Zotlabs\\Lib\\DReport' => __DIR__ . '/../..' . '/Zotlabs/Lib/DReport.php', 'Zotlabs\\Lib\\Enotify' => __DIR__ . '/../..' . '/Zotlabs/Lib/Enotify.php', diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 945fe4368..8e180f966 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,12 +1,12 @@ array ( - 'pretty_version' => 'dev-5.2RC', - 'version' => 'dev-5.2RC', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'aliases' => array ( ), - 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', + 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -243,12 +243,12 @@ ), 'zotlabs/hubzilla' => array ( - 'pretty_version' => 'dev-5.2RC', - 'version' => 'dev-5.2RC', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'aliases' => array ( ), - 'reference' => 'a6162d3134cd7fcde4f45064b75f90008a7f8177', + 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', ), ), ); -- cgit v1.2.3 From 6b8b42fb211d488388044621d8cff9e6d85e2b0f Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Feb 2021 16:16:56 +0000 Subject: fix line separators --- tests/unit/Lib/KeyutilsTest.php | 182 ++++++++++++++++++++-------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/tests/unit/Lib/KeyutilsTest.php b/tests/unit/Lib/KeyutilsTest.php index 162b2b279..2e9a2f893 100644 --- a/tests/unit/Lib/KeyutilsTest.php +++ b/tests/unit/Lib/KeyutilsTest.php @@ -1,91 +1,91 @@ -loadKey([ - 'e' => new BigInteger($e, 256), - 'n' => new BigInteger($m, 256) - ]); - - self::assertEquals($gen_key->getPublicKey(), $orig_key); - } - -} +loadKey([ + 'e' => new BigInteger($e, 256), + 'n' => new BigInteger($m, 256) + ]); + + self::assertEquals($gen_key->getPublicKey(), $orig_key); + } + +} -- cgit v1.2.3 From 5aee2f172ecdf58e13dd328c787fd199c48d24c5 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Feb 2021 20:05:05 +0000 Subject: =?UTF-8?q?restructure=20keyuti=C3=83ls=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unit/Lib/KeyutilsTest.php | 82 ++++++++++++++++++----------------- vendor/composer/InstalledVersions.php | 4 +- vendor/composer/installed.php | 4 +- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/tests/unit/Lib/KeyutilsTest.php b/tests/unit/Lib/KeyutilsTest.php index 2e9a2f893..bb5f84728 100644 --- a/tests/unit/Lib/KeyutilsTest.php +++ b/tests/unit/Lib/KeyutilsTest.php @@ -33,59 +33,63 @@ use Zotlabs\Lib\Keyutils; * * @covers Zotlabs\Lib\Keyutils */ -class KeyutilsTest extends UnitTestCase { - public function testMeToPem() { - $orig_key = '-----BEGIN PUBLIC KEY----- -MIICITANBgkqhkiG9w0BAQEFAAOCAg4AMIICCQKCAgB2Kuku7L3ElK4Et4x4Dpur -Ij5dqrcI0j7o6w39RR09ikPe43S99IVqTvTuvdOcWqkqrFffM82+GWZpco1GdTdv -wnRUCLNpDWnVU3YnwruPHDHgdybJf0gBvP1dbcOe3H3KPZVQ6WWInH6r3B3p9MCT -9AXeeC11CJCk/tNb4MPqhyG7/0MkiCJ4mNnjqQX97X2kS1mCkduVs7H6ZW//DCpR -oBft2cvCLoURUbwW0wlBnFiLH9IrRNMSCX3BZaML04NKDGSbp/n6GDTM9tX/HEf1 -OH2q8vh11I64hGWsVqWu8ogitiZxXCZAZ57YlQ5ZYwqWAwHtw2XICn9ddPIHeYt7 -PadOocf0L4tBdJcP7DAPuJyJSymT+zIkVD5M2h3hyORbaqpVBTMNhKyQEaTipijk -B26MS7GQSURJ1csKXSe792YV9dwBzlihX9MxT6r3sFhifUJ8PVklgHzOZ0zw9CHH -W2xGFku1h9fT+kNCi0YnTZlbmXEQKo2/Qha/nMCvA+idfDcHw9DVZNIMpH5kk3JC -GxBR2GGV8LISqKpZqZ+9AzZeqt8aCSC2/h8nq5nCWLVMTtJIiV/1GE5aEe2fR9GS -Az76YS3wXMqvWx19XE+v74sBNqhtxrZfQRfeHalDv1nUkcBkaYglQmggZ2jd+p6d -soJHIKiLs/8fMzRqLyrqZwIDAQAB ------END PUBLIC KEY-----'; - $orig_key = str_replace(["\r", "\n"], "\r\n", $orig_key); - Keyutils::pemToMe($orig_key, $m, $e); - $gen_key = Keyutils::meToPem($m, $e); - self::assertEquals($orig_key, $gen_key); - } +class KeyutilsTest extends UnitTestCase { + protected function getPubPKCS1() { + $key = '-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEArXcEXQSkk25bwDxq5Ym85/OwernfOz0hgve46Jm1KXCF0+yeje8J +BDbQTsMgkF+G8eP1er3oz3E0qlIFpYrza5o6kaaLETSroTyZR5QW5S21r/QJHE+4 +F08bw1zp9hrlvoOCE/g/W0mr3asO/x7LrQRKOETlZ/U6HGexTdYLyKlXJtB+VKjI +XKAHxfVLRW2AvnFj+deowS1OhTN8ECpz88xG9wnh5agoq7Uol0WZNNm0p4oR6+cd +zTPx/mBwcOoSqHLlO7ZACbx/VyD5G7mQKWfGP4b96D8FcUO74531my+aKIpLF4Io +1JN4R4a4P8tZ8BkCnMvpuq9TF1s6vEthYQIDAQAB +-----END RSA PUBLIC KEY-----'; + return str_replace(["\r", "\n"], "\r\n", $key); + } - public function testPemToMe() { - $orig_key = '-----BEGIN PUBLIC KEY----- -MIICITANBgkqhkiG9w0BAQEFAAOCAg4AMIICCQKCAgB2Kuku7L3ElK4Et4x4Dpur -Ij5dqrcI0j7o6w39RR09ikPe43S99IVqTvTuvdOcWqkqrFffM82+GWZpco1GdTdv -wnRUCLNpDWnVU3YnwruPHDHgdybJf0gBvP1dbcOe3H3KPZVQ6WWInH6r3B3p9MCT -9AXeeC11CJCk/tNb4MPqhyG7/0MkiCJ4mNnjqQX97X2kS1mCkduVs7H6ZW//DCpR -oBft2cvCLoURUbwW0wlBnFiLH9IrRNMSCX3BZaML04NKDGSbp/n6GDTM9tX/HEf1 -OH2q8vh11I64hGWsVqWu8ogitiZxXCZAZ57YlQ5ZYwqWAwHtw2XICn9ddPIHeYt7 -PadOocf0L4tBdJcP7DAPuJyJSymT+zIkVD5M2h3hyORbaqpVBTMNhKyQEaTipijk -B26MS7GQSURJ1csKXSe792YV9dwBzlihX9MxT6r3sFhifUJ8PVklgHzOZ0zw9CHH -W2xGFku1h9fT+kNCi0YnTZlbmXEQKo2/Qha/nMCvA+idfDcHw9DVZNIMpH5kk3JC -GxBR2GGV8LISqKpZqZ+9AzZeqt8aCSC2/h8nq5nCWLVMTtJIiV/1GE5aEe2fR9GS -Az76YS3wXMqvWx19XE+v74sBNqhtxrZfQRfeHalDv1nUkcBkaYglQmggZ2jd+p6d -soJHIKiLs/8fMzRqLyrqZwIDAQAB + protected function getPubPKCS8() { + $key = '-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUKfOIkFX/Zcv6bmaTIYO6OO2g +XQOne+iPfXo6YDdrtvvQNZwW5P/fptrgBzmUBkpuc/sEEKpMV2bGhBLsWSlPBYHe +2ewwLwyzbnuHvGhc1PzwMNQ7R60ubVDQT6sBVigYGZIDBgUPjAXeqmg5qgWWh04H +8Zf/YxyoGEovWDMxGQIDAQAB -----END PUBLIC KEY-----'; + return str_replace(["\r", "\n"], "\r\n", $key); + } - $orig_key = str_replace(["\r", "\n"], "\r\n", $orig_key); + public function testMeToPem() { + Keyutils::pemToMe($this->getPubPKCS8(), $m, $e); + $gen_key = Keyutils::meToPem($m, $e); + self::assertEquals($this->getPubPKCS8(), $gen_key); + } + + public function testRsaToPem() { + $rsa = new RSA(); + $rsa->setPublicKey($this->getPubPKCS8()); + $key = $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); + $gen_key = Keyutils::rsaToPem($key); + self::assertEquals($gen_key, $this->getPubPKCS8()); + } - Keyutils::pemToMe($orig_key, $m, $e); + public function testPemToRsa() { + $rsa = new RSA(); + $rsa->setPublicKey($this->getPubPKCS1()); + $key = $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); + $gen_key = Keyutils::pemToRsa($key); + self::assertEquals($gen_key, $this->getPubPKCS1()); + } + public function testPemToMe() { + Keyutils::pemToMe($this->getPubPKCS8(), $m, $e); $gen_key = new RSA(); $gen_key->loadKey([ 'e' => new BigInteger($e, 256), 'n' => new BigInteger($m, 256) ]); - - self::assertEquals($gen_key->getPublicKey(), $orig_key); + self::assertEquals($gen_key->getPublicKey(), $this->getPubPKCS8()); } } diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 49f5297d5..4e4b8790a 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', + 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', + 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', ), ), ); diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 8e180f966..f9d9d5f93 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', + 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '1bcf84f27510e9afe20a3c6a509ca7062aba0aa9', + 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', ), ), ); -- cgit v1.2.3 From b4693870ba647455e6bd0a3919a544130cee118b Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 9 Feb 2021 13:50:03 +0000 Subject: port Lib/Crypto from zap --- Zotlabs/Lib/Crypto.php | 205 ++++++++++++++++++++++++++++++++++ Zotlabs/Lib/JSalmon.php | 4 +- Zotlabs/Lib/LDSignatures.php | 12 +- Zotlabs/Lib/Libzot.php | 16 +-- Zotlabs/Lib/Zotfinger.php | 12 +- Zotlabs/Module/Channel.php | 3 +- Zotlabs/Module/Connedit.php | 3 +- Zotlabs/Module/Fhublocs.php | 22 ++-- Zotlabs/Module/Getfile.php | 3 +- Zotlabs/Module/Import.php | 5 +- Zotlabs/Module/Prate.php | 60 +++++----- Zotlabs/Module/Probe.php | 17 +-- Zotlabs/Module/Rate.php | 70 ++++++------ Zotlabs/Web/HTTPSig.php | 11 +- Zotlabs/Zot/Auth.php | 38 ++++--- Zotlabs/Zot/Finger.php | 5 +- Zotlabs/Zot/Receiver.php | 20 ++-- Zotlabs/Zot6/Receiver.php | 15 +-- boot.php | 4 +- include/account.php | 36 +++--- include/channel.php | 17 +-- include/crypto.php | 7 +- include/dir_fns.php | 3 +- include/follow.php | 18 +-- include/items.php | 7 +- include/text.php | 11 +- include/xchan.php | 13 ++- include/zot.php | 111 +++++++++--------- tests/unit/Lib/KeyutilsTest.php | 2 - tests/unit/Web/HttpSigTest.php | 6 +- vendor/composer/InstalledVersions.php | 4 +- vendor/composer/installed.php | 4 +- 32 files changed, 502 insertions(+), 262 deletions(-) create mode 100644 Zotlabs/Lib/Crypto.php diff --git a/Zotlabs/Lib/Crypto.php b/Zotlabs/Lib/Crypto.php new file mode 100644 index 000000000..3dba1bcf3 --- /dev/null +++ b/Zotlabs/Lib/Crypto.php @@ -0,0 +1,205 @@ + 'sha1', + 'private_key_bits' => $bits, + 'encrypt_key' => false + ]; + + $conf = get_config('system','openssl_conf_file'); + + if ($conf) { + $openssl_options['config'] = $conf; + } + + $result = openssl_pkey_new($openssl_options); + + if (empty($result)) { + return false; + } + + // Get private key + + $response = [ 'prvkey' => '', 'pubkey' => '' ]; + + openssl_pkey_export($result, $response['prvkey']); + + // Get public key + $pkey = openssl_pkey_get_details($result); + $response['pubkey'] = $pkey["key"]; + + return $response; + + } + + public static function sign($data,$key,$alg = 'sha256') { + + if (! $key) { + return false; + } + + $sig = ''; + openssl_sign($data,$sig,$key,$alg); + return $sig; + } + + public static function verify($data,$sig,$key,$alg = 'sha256') { + + if (! $key) { + return false; + } + + try { + $verify = openssl_verify($data,$sig,$key,$alg); + } + catch (Exception $e) { + $verify = (-1); + } + + if ($verify === (-1)) { + while ($msg = openssl_error_string()) { + logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR); + } + btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); + } + + return (($verify > 0) ? true : false); + } + + public static function encapsulate($data,$pubkey,$alg) { + + if (! ($alg && $pubkey)) { + return $data; + } + + $alg_base = $alg; + $padding = OPENSSL_PKCS1_PADDING; + + $exts = explode('.',$alg); + if (count($exts) > 1) { + switch ($exts[1]) { + case 'oaep': + $padding = OPENSSL_PKCS1_OAEP_PADDING; + break; + default: + break; + } + $alg_base = $exts[0]; + } + + $method = null; + + foreach (self::$openssl_algorithms as $ossl) { + if ($ossl[0] === $alg_base) { + $method = $ossl; + break; + } + } + + if ($method) { + $result = [ 'encrypted' => true ]; + + $key = openssl_random_pseudo_bytes(256); + $iv = openssl_random_pseudo_bytes(256); + + $key1 = substr($key, 0, $method[2]); + $iv1 = substr($iv, 0, $method[3]); + + $result['data'] = base64url_encode(openssl_encrypt($data,$method[1],$key1,OPENSSL_RAW_DATA,$iv1),true); + + openssl_public_encrypt($key, $k, $pubkey, $padding); + openssl_public_encrypt($iv, $i, $pubkey, $padding); + + $result['alg'] = $alg; + $result['key'] = base64url_encode($k,true); + $result['iv'] = base64url_encode($i,true); + return $result; + + } + else { + $x = [ 'data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data ]; + call_hooks('crypto_encapsulate', $x); + return $x['result']; + } + } + + public static function unencapsulate($data,$prvkey) { + + if (! (is_array($data) && array_key_exists('encrypted',$data) && array_key_exists('alg',$data) && $data['alg'])) { + logger('not encrypted'); + + return $data; + } + + $alg_base = $data['alg']; + $padding = OPENSSL_PKCS1_PADDING; + + $exts = explode('.',$data['alg']); + if (count($exts) > 1) { + switch ($exts[1]) { + case 'oaep': + $padding = OPENSSL_PKCS1_OAEP_PADDING; + break; + default: + break; + } + $alg_base = $exts[0]; + } + + $method = null; + + foreach (self::$openssl_algorithms as $ossl) { + if ($ossl[0] === $alg_base) { + $method = $ossl; + break; + } + } + + if ($method) { + openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey,$padding); + openssl_private_decrypt(base64url_decode($data['iv']), $i,$prvkey,$padding); + return openssl_decrypt(base64url_decode($data['data']),$method[1],substr($k,0,$method[2]),OPENSSL_RAW_DATA,substr($i,0,$method[3])); + } + else { + $x = [ 'data' => $data, 'prvkey' => $prvkey, 'alg' => $data['alg'], 'result' => $data ]; + call_hooks('crypto_unencapsulate',$x); + return $x['result']; + } + } +} diff --git a/Zotlabs/Lib/JSalmon.php b/Zotlabs/Lib/JSalmon.php index 7f63cf914..f9fe99706 100644 --- a/Zotlabs/Lib/JSalmon.php +++ b/Zotlabs/Lib/JSalmon.php @@ -18,7 +18,7 @@ class JSalmon { $precomputed = '.' . base64url_encode($data_type,true) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng'; - $signature = base64url_encode(rsa_sign($data . $precomputed, $key), true); + $signature = base64url_encode(Crypto::sign($data . $precomputed, $key), true); return ([ 'signed' => true, @@ -54,7 +54,7 @@ class JSalmon { $key = HTTPSig::get_key(EMPTY_STR,'zot6',base64url_decode($x['sigs']['key_id'])); logger('key: ' . print_r($key,true)); if($key['portable_id'] && $key['public_key']) { - if(rsa_verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) { + if(Crypto::verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) { logger('verified'); $ret = [ 'success' => true, 'signer' => $key['portable_id'], 'hubloc' => $key['hubloc'] ]; } diff --git a/Zotlabs/Lib/LDSignatures.php b/Zotlabs/Lib/LDSignatures.php index 2eba66ccf..1c2095f10 100644 --- a/Zotlabs/Lib/LDSignatures.php +++ b/Zotlabs/Lib/LDSignatures.php @@ -12,7 +12,7 @@ class LDSignatures { $ohash = self::hash(self::signable_options($data['signature'])); $dhash = self::hash(self::signable_data($data)); - $x = rsa_verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey); + $x = Crypto::verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey); logger('LD-verify: ' . intval($x)); return $x; @@ -35,11 +35,11 @@ class LDSignatures { $ohash = self::hash(self::signable_options($options)); $dhash = self::hash(self::signable_data($data)); - $options['signatureValue'] = base64_encode(rsa_sign($ohash . $dhash,$channel['channel_prvkey'])); + $options['signatureValue'] = base64_encode(Crypto::sign($ohash . $dhash,$channel['channel_prvkey'])); $signed = array_merge([ - '@context' => [ - ACTIVITYSTREAMS_JSONLD_REV, + '@context' => [ + ACTIVITYSTREAMS_JSONLD_REV, 'https://w3id.org/security/v1' ], ],$options); @@ -88,7 +88,7 @@ class LDSignatures { return ''; jsonld_set_document_loader('jsonld_document_loader'); - + try { $d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]); } @@ -117,7 +117,7 @@ class LDSignatures { $precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng=='; - $signature = base64url_encode(rsa_sign($data . $precomputed,$channel['channel_prvkey'])); + $signature = base64url_encode(Crypto::sign($data . $precomputed,$channel['channel_prvkey'])); return ([ 'id' => $arr['id'], diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 0ead8402e..a615cee6e 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -130,7 +130,7 @@ class Libzot { if ($remote_key) { $algorithm = self::best_algorithm($methods); if ($algorithm) { - $data = crypto_encapsulate(json_encode($data), $remote_key, $algorithm); + $data = Crypto::encapsulate(json_encode($data), $remote_key, $algorithm); } } @@ -143,7 +143,7 @@ class Libzot { * * @param string $methods * Comma separated list of encryption methods - * @return string first match from our site method preferences crypto_methods() array + * @return string first match from our site method preferences Crypto::methods() array * of a method which is common to both sites; or 'aes256cbc' if no matches are found. */ static function best_algorithm($methods) { @@ -167,7 +167,7 @@ class Libzot { if ($methods) { $x = explode(',', $methods); if ($x) { - $y = crypto_methods(); + $y = Crypto::methods(); if ($y) { foreach ($y as $yv) { $yv = trim($yv); @@ -763,8 +763,8 @@ class Libzot { 'xchan_guid' => $arr['id'], 'xchan_guid_sig' => $arr['id_sig'], 'xchan_pubkey' => $arr['public_key'], - 'xchan_photo_mimetype' => $arr['photo']['type'], - 'xchan_photo_l' => $arr['photo']['url'], + 'xchan_photo_mimetype' => $arr['photo_mimetype'], + 'xchan_photo_l' => $arr['photo'], 'xchan_addr' => escape_tags($arr['primary_location']['address']), 'xchan_url' => escape_tags($arr['primary_location']['url']), 'xchan_connurl' => $arr['primary_location']['connections_url'], @@ -772,7 +772,7 @@ class Libzot { 'xchan_connpage' => $arr['connect_url'], 'xchan_name' => (($arr['name']) ? escape_tags($arr['name']) : '-'), 'xchan_network' => 'zot6', - 'xchan_photo_date' => $arr['photo']['updated'], + 'xchan_photo_date' => $arr['photo_updated'], 'xchan_name_date' => $arr['name_updated'], 'xchan_hidden' => intval(1 - intval($arr['searchable'])), 'xchan_selfcensored' => $arr['adult_content'], @@ -983,7 +983,7 @@ class Libzot { logger('Headers: ' . print_r($arr['header'], true), LOGGER_DATA, LOG_DEBUG); } - $x = crypto_unencapsulate($x, get_config('system', 'prvkey')); + $x = Crypto::unencapsulate($x, get_config('system', 'prvkey')); if (!is_array($x)) { $x = json_decode($x, true); @@ -3020,7 +3020,7 @@ class Libzot { $ret['site']['directory_url'] = z_root() . '/dirsearch'; - $ret['site']['encryption'] = crypto_methods(); + $ret['site']['encryption'] = Crypto::methods(); $ret['site']['zot'] = System::get_zot_revision(); // hide detailed site information if you're off the grid diff --git a/Zotlabs/Lib/Zotfinger.php b/Zotlabs/Lib/Zotfinger.php index faaf28f35..840d91403 100644 --- a/Zotlabs/Lib/Zotfinger.php +++ b/Zotlabs/Lib/Zotfinger.php @@ -18,8 +18,8 @@ class Zotfinger { if($channel && $m) { - $headers = [ - 'Accept' => 'application/x-zot+json', + $headers = [ + 'Accept' => 'application/x-zot+json', 'Content-Type' => 'application/x-zot+json', 'X-Zot-Token' => random_string(), 'Digest' => HTTPSig::generate_digest_header($data), @@ -29,9 +29,9 @@ class Zotfinger { $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false); } else { - $h = [ 'Accept: application/x-zot+json' ]; + $h = [ 'Accept: application/x-zot+json' ]; } - + $result = []; $redirects = 0; @@ -43,11 +43,11 @@ class Zotfinger { if ($verify) { $result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6'); } - + $result['data'] = json_decode($x['body'],true); if($result['data'] && is_array($result['data']) && array_key_exists('encrypted',$result['data']) && $result['data']['encrypted']) { - $result['data'] = json_decode(crypto_unencapsulate($result['data'],get_config('system','prvkey')),true); + $result['data'] = json_decode(Crypto::unencapsulate($result['data'],get_config('system','prvkey')),true); } logger('decrypted: ' . print_r($result,true)); diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 915e0ea60..a513523a7 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -6,6 +6,7 @@ namespace Zotlabs\Module; use App; use Zotlabs\Lib\Activity; use Zotlabs\Lib\ActivityStreams; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\Libzot; use Zotlabs\Lib\PermissionDescription; use Zotlabs\Web\Controller; @@ -70,7 +71,7 @@ class Channel extends Controller { ); if ($s) { - $data = json_encode(crypto_encapsulate($data, $s[0]['hubloc_sitekey'], Libzot::best_algorithm($s[0]['site_crypto']))); + $data = json_encode(Crypto::encapsulate($data, $s[0]['hubloc_sitekey'], Libzot::best_algorithm($s[0]['site_crypto']))); } } else { diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 582563451..44211c8b9 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -9,6 +9,7 @@ namespace Zotlabs\Module; use App; use Zotlabs\Lib\Apps; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\Libzot; use Zotlabs\Lib\Libsync; use Zotlabs\Daemon\Master; @@ -178,7 +179,7 @@ class Connedit extends Controller { if(! $is_self) { $signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text; - $sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey'])); + $sig = base64url_encode(Crypto::sign($signed,$channel['channel_prvkey'])); $rated = ((intval($rating) || strlen($rating_text)) ? true : false); diff --git a/Zotlabs/Module/Fhublocs.php b/Zotlabs/Module/Fhublocs.php index dcd399a1f..42dac5b12 100644 --- a/Zotlabs/Module/Fhublocs.php +++ b/Zotlabs/Module/Fhublocs.php @@ -15,12 +15,12 @@ class Fhublocs extends \Zotlabs\Web\Controller { if(! is_site_admin()) return; - + $o = ''; - + $r = q("select * from channel where channel_removed = 0"); $sitekey = get_config('system','pubkey'); - + if($r) { foreach($r as $rr) { @@ -38,14 +38,14 @@ class Fhublocs extends \Zotlabs\Web\Controller { if($found) { $o .= 'Hubloc exists for ' . $rr['channel_name'] . EOL; continue; - } + } } $y = q("select xchan_addr from xchan where xchan_hash = '%s' limit 1", dbesc($rr['channel_hash']) ); if($y) $primary_address = $y[0]['xchan_addr']; - + $hub_address = channel_reddress($rr); $primary = (($hub_address === $primary_address) ? 1 : 0); @@ -56,9 +56,9 @@ class Fhublocs extends \Zotlabs\Web\Controller { dbesc($rr['channel_hash']), dbesc(z_root()) ); - + // Create a verified hub location pointing to this site. - + /* $h = hubloc_store_lowlevel( [ @@ -69,7 +69,7 @@ class Fhublocs extends \Zotlabs\Web\Controller { 'hubloc_network' => 'zot', 'hubloc_primary' => $primary, 'hubloc_url' => z_root(), - 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$rr['channel_prvkey'])), + 'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$rr['channel_prvkey'])), 'hubloc_host' => \App::get_hostname(), 'hubloc_callback' => z_root() . '/post', 'hubloc_sitekey' => $sitekey @@ -99,11 +99,11 @@ class Fhublocs extends \Zotlabs\Web\Controller { $o . 'local hubloc created for ' . $rr['channel_name'] . EOL; else $o .= 'DB update failed for ' . $rr['channel_name'] . EOL; - + } - + return $o; - + } } } diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php index 20cc23ac0..28d7eabb5 100644 --- a/Zotlabs/Module/Getfile.php +++ b/Zotlabs/Module/Getfile.php @@ -1,6 +1,7 @@ 'zot', 'hubloc_primary' => (($seize) ? 1 : 0), 'hubloc_url' => z_root(), - 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])), + 'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])), 'hubloc_host' => \App::get_hostname(), 'hubloc_callback' => z_root() . '/post', 'hubloc_sitekey' => get_config('system','pubkey'), @@ -256,7 +257,7 @@ class Import extends \Zotlabs\Web\Controller { 'hubloc_network' => 'zot6', 'hubloc_primary' => (($seize) ? 1 : 0), 'hubloc_url' => z_root(), - 'hubloc_url_sig' => 'sha256.' . base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])), + 'hubloc_url_sig' => 'sha256.' . base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])), 'hubloc_host' => \App::get_hostname(), 'hubloc_callback' => z_root() . '/zot', 'hubloc_sitekey' => get_config('system','pubkey'), diff --git a/Zotlabs/Module/Prate.php b/Zotlabs/Module/Prate.php index 2a8539ed0..8b71657b8 100644 --- a/Zotlabs/Module/Prate.php +++ b/Zotlabs/Module/Prate.php @@ -2,21 +2,23 @@ namespace Zotlabs\Module; +use Zotlabs\Lib\Crypto; + class Prate extends \Zotlabs\Web\Controller { function init() { if($_SERVER['REQUEST_METHOD'] === 'post') return; - + if(! local_channel()) return; - + $channel = \App::get_channel(); - + $target = argv(1); if(! $target) return; - + $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", dbesc($channel['channel_hash']), dbesc($target) @@ -25,34 +27,34 @@ class Prate extends \Zotlabs\Web\Controller { json_return_and_die(array('rating' => $r[0]['xlink_rating'],'rating_text' => $r[0]['xlink_rating_text'])); killme(); } - + function post() { - + if(! local_channel()) return; - + $channel = \App::get_channel(); - + $target = trim($_REQUEST['target']); if(! $target) return; - + if($target === $channel['channel_hash']) return; - + $rating = intval($_POST['rating']); if($rating < (-10)) $rating = (-10); if($rating > 10) $rating = 10; - + $rating_text = trim(escape_tags($_REQUEST['rating_text'])); - + $signed = $target . '.' . $rating . '.' . $rating_text; - - $sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey'])); - - + + $sig = base64url_encode(Crypto::sign($signed,$channel['channel_prvkey'])); + + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($target) @@ -87,19 +89,19 @@ class Prate extends \Zotlabs\Web\Controller { if($record) { \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record)); } - + json_return_and_die(array('result' => true));; } - - - - - - - - - - - - + + + + + + + + + + + + } diff --git a/Zotlabs/Module/Probe.php b/Zotlabs/Module/Probe.php index d338b08ea..3bc4dac72 100644 --- a/Zotlabs/Module/Probe.php +++ b/Zotlabs/Module/Probe.php @@ -3,6 +3,7 @@ namespace Zotlabs\Module; use App; use Zotlabs\Lib\Apps; +use Zotlabs\Lib\Crypto; require_once('include/zot.php'); @@ -24,18 +25,18 @@ class Probe extends \Zotlabs\Web\Controller { nav_set_selected('Remote Diagnostics'); $o .= '

      Remote Diagnostics

      '; - + $o .= '
      '; $o .= 'Lookup address: '; - $o .= '
      '; - + $o .= ''; + $o .= '

      '; - + if(x($_GET,'addr')) { $channel = App::get_channel(); $addr = trim($_GET['addr']); $do_import = ((intval($_GET['import']) && is_site_admin()) ? true : false); - + $j = \Zotlabs\Zot\Finger::run($addr,$channel,false); $o .= '
      ';
      @@ -43,17 +44,17 @@ class Probe extends \Zotlabs\Web\Controller {
       				$o .= "https connection failed. Trying again with auto failover to http.\r\n\r\n";
       				$j = \Zotlabs\Zot\Finger::run($addr,$channel,true);
       				if(! $j['success']) {
      -					return $o;	
      +					return $o;
       				}
       			}
       			if($do_import && $j)
       				$x = import_xchan($j);
       			if($j && $j['permissions'] && $j['permissions']['iv'])
      -				$j['permissions'] = json_decode(crypto_unencapsulate($j['permissions'],$channel['channel_prvkey']),true);
      +				$j['permissions'] = json_decode(Crypto::unencapsulate($j['permissions'],$channel['channel_prvkey']),true);
       			$o .= str_replace("\n",'
      ',print_r($j,true)); $o .= '
      '; } return $o; } - + } diff --git a/Zotlabs/Module/Rate.php b/Zotlabs/Module/Rate.php index c03aaa54f..d29c370fc 100644 --- a/Zotlabs/Module/Rate.php +++ b/Zotlabs/Module/Rate.php @@ -3,21 +3,23 @@ namespace Zotlabs\Module; +use Zotlabs\Lib\Crypto; + class Rate extends \Zotlabs\Web\Controller { function init() { - + if(! local_channel()) return; - + $channel = \App::get_channel(); - + $target = $_REQUEST['target']; if(! $target) return; - + \App::$data['target'] = $target; - + if($target) { $r = q("SELECT * FROM xchan where xchan_hash like '%s' LIMIT 1", dbesc($target) @@ -36,43 +38,43 @@ class Rate extends \Zotlabs\Web\Controller { } } } - - + + return; - + } - - + + function post() { - + if(! local_channel()) return; - + if(! \App::$data['target']) return; - + if(! $_REQUEST['execute']) return; - + $channel = \App::get_channel(); - + $rating = intval($_POST['rating']); if($rating < (-10)) $rating = (-10); if($rating > 10) $rating = 10; - + $rating_text = trim(escape_tags($_REQUEST['rating_text'])); - + $signed = \App::$data['target'] . '.' . $rating . '.' . $rating_text; - - $sig = base64url_encode(rsa_sign($signed,$channel['channel_prvkey'])); - + + $sig = base64url_encode(Crypto::sign($signed,$channel['channel_prvkey'])); + $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc(\App::$data['target']) ); - + if($z) { $record = $z[0]['xlink_id']; $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s' @@ -100,39 +102,39 @@ class Rate extends \Zotlabs\Web\Controller { if($z) $record = $z[0]['xlink_id']; } - + if($record) { \Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record)); } - + } - + function get() { - + if(! local_channel()) { notice( t('Permission denied.') . EOL); return; } - + // if(! \App::$data['target']) { // notice( t('No recipients.') . EOL); // return; // } - + $rating_enabled = get_config('system','rating_enabled'); if(! $rating_enabled) { notice('Ratings are disabled on this site.'); return; } - + $channel = \App::get_channel(); - + $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", dbesc($channel['channel_hash']), dbesc(\App::$data['target']) ); if($r) { - \App::$data['xlink'] = $r[0]; + \App::$data['xlink'] = $r[0]; $rating_val = $r[0]['xlink_rating']; $rating_text = $r[0]['xlink_rating_text']; } @@ -140,7 +142,7 @@ class Rate extends \Zotlabs\Web\Controller { $rating_val = 0; $rating_text = ''; } - + if($rating_enabled) { $rating = replace_macros(get_markup_template('rating_slider.tpl'),array( '$min' => -10, @@ -150,7 +152,7 @@ class Rate extends \Zotlabs\Web\Controller { else { $rating = false; } - + $o = replace_macros(get_markup_template('rating_form.tpl'),array( '$header' => t('Rating'), '$website' => t('Website:'), @@ -165,8 +167,8 @@ class Rate extends \Zotlabs\Web\Controller { '$slide' => $slide, '$submit' => t('Submit') )); - + return $o; - + } } diff --git a/Zotlabs/Web/HTTPSig.php b/Zotlabs/Web/HTTPSig.php index 8dd999e59..2535c9016 100644 --- a/Zotlabs/Web/HTTPSig.php +++ b/Zotlabs/Web/HTTPSig.php @@ -3,6 +3,7 @@ namespace Zotlabs\Web; use Zotlabs\Lib\ActivityStreams; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\Keyutils; use Zotlabs\Lib\Webfinger; use Zotlabs\Lib\Libzot; @@ -157,7 +158,7 @@ class HTTPSig { return $result; } - $x = rsa_verify($signed_data,$sig_block['signature'],$cached_key['public_key'],$algorithm); + $x = Crypto::verify($signed_data,$sig_block['signature'],$cached_key['public_key'],$algorithm); logger('verified: ' . $x, LOGGER_DEBUG); @@ -171,7 +172,7 @@ class HTTPSig { $fetched_key = self::get_key($key,$keytype,$result['signer'],true); if ($fetched_key && $fetched_key['public_key']) { - $y = rsa_verify($signed_data,$sig_block['signature'],$fetched_key['public_key'],$algorithm); + $y = Crypto::verify($signed_data,$sig_block['signature'],$fetched_key['public_key'],$algorithm); logger('verified: (cache reload) ' . $x, LOGGER_DEBUG); } @@ -417,7 +418,7 @@ class HTTPSig { $headerval = 'keyId="' . $keyid . '",algorithm="' . $algorithm . '",headers="' . $x['headers'] . '",signature="' . $x['signature'] . '"'; if($encryption) { - $x = crypto_encapsulate($headerval,$encryption['key'],$encryption['algorithm']); + $x = Crypto::encapsulate($headerval,$encryption['key'],$encryption['algorithm']); if(is_array($x)) { $headerval = 'iv="' . $x['iv'] . '",key="' . $x['key'] . '",alg="' . $x['alg'] . '",data="' . $x['data'] . '"'; } @@ -491,7 +492,7 @@ class HTTPSig { $headers = rtrim($headers,"\n"); } - $sig = base64_encode(rsa_sign($headers,$prvkey,$alg)); + $sig = base64_encode(Crypto::sign($headers,$prvkey,$alg)); $ret['headers'] = $fields; $ret['signature'] = $sig; @@ -567,7 +568,7 @@ class HTTPSig { $data = $matches[1]; if($iv && $key && $alg && $data) { - return crypto_unencapsulate([ 'encrypted' => true, 'iv' => $iv, 'key' => $key, 'alg' => $alg, 'data' => $data ] , $prvkey); + return Crypto::unencapsulate([ 'encrypted' => true, 'iv' => $iv, 'key' => $key, 'alg' => $alg, 'data' => $data ] , $prvkey); } return ''; diff --git a/Zotlabs/Zot/Auth.php b/Zotlabs/Zot/Auth.php index 8d198f506..6ce2174f7 100644 --- a/Zotlabs/Zot/Auth.php +++ b/Zotlabs/Zot/Auth.php @@ -2,6 +2,8 @@ namespace Zotlabs\Zot; +use Zotlabs\Lib\Crypto; + class Auth { protected $test; @@ -68,7 +70,7 @@ class Auth { if(strstr($this->desturl,z_root() . '/rmagic')) goaway(z_root()); - $this->Finalise(); + $this->Finalise(); } @@ -76,7 +78,7 @@ class Auth { // Try and find a hubloc for the person attempting to auth. // Since we're matching by address, we have to return all entries - // some of which may be from re-installed hubs; and we'll need to + // some of which may be from re-installed hubs; and we'll need to // try each sequentially to see if one can pass the test $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash @@ -130,9 +132,9 @@ class Auth { // Also check that they are coming from the same site as they authenticated with originally. - $already_authed = (((remote_channel()) && ($hubloc['hubloc_hash'] == remote_channel()) + $already_authed = (((remote_channel()) && ($hubloc['hubloc_hash'] == remote_channel()) && ($hubloc['hubloc_url'] === $_SESSION['remote_hub'])) ? true : false); - + if($this->delegate && $this->delegate !== $_SESSION['delegate_channel']) $already_authed = false; @@ -158,17 +160,17 @@ class Auth { return false; } - // Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the + // Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the // site private key - // The actual channel sending the packet ($c[0]) is not important, but this provides a + // The actual channel sending the packet ($c[0]) is not important, but this provides a // generic zot packet with a sender which can be verified $x = q("select site_crypto from site where site_url = '%s' limit 1", dbesc($hubloc['hubloc_url']) ); - $p = zot_build_packet($channel,$type = 'auth_check', - array(array('guid' => $hubloc['hubloc_guid'],'guid_sig' => $hubloc['hubloc_guid_sig'])), + $p = zot_build_packet($channel,$type = 'auth_check', + array(array('guid' => $hubloc['hubloc_guid'],'guid_sig' => $hubloc['hubloc_guid_sig'])), $hubloc['hubloc_sitekey'], (($x) ? $x[0]['site_crypto'] : ''), $this->sec); $this->Debug('auth check packet created using sitekey ' . $hubloc['hubloc_sitekey']); @@ -192,12 +194,12 @@ class Auth { $this->Debug('auth check request returned ' . print_r($j, true)); - if(! $j['success']) + if(! $j['success']) return false; // legit response, but we do need to check that this wasn't answered by a man-in-middle - if (! rsa_verify($this->sec . $hubloc['xchan_hash'],base64url_decode($j['confirm']),$hubloc['xchan_pubkey'])) { + if (! Crypto::verify($this->sec . $hubloc['xchan_hash'],base64url_decode($j['confirm']),$hubloc['xchan_pubkey'])) { logger('final confirmation failed.'); if($this->test) $this->Debug('final confirmation failed. ' . $sec . print_r($j,true) . print_r($hubloc,true)); @@ -290,7 +292,7 @@ class Auth { * Magic Auth * ========== * - * So-called "magic auth" takes place by a special exchange. On the site where the "channel to be authenticated" lives (e.g. $mysite), + * So-called "magic auth" takes place by a special exchange. On the site where the "channel to be authenticated" lives (e.g. $mysite), * a redirection is made via $mysite/magic to the zot endpoint of the remote site ($remotesite) with special GET parameters. * * The endpoint is typically https://$remotesite/post - or whatever was specified as the callback url in prior communications @@ -299,7 +301,7 @@ class Auth { * Five GET parameters are supplied: * * auth => the urlencoded webbie (channel@host.domain) of the channel requesting access * * dest => the desired destination URL (urlencoded) - * * sec => a random string which is also stored on $mysite for use during the verification phase. + * * sec => a random string which is also stored on $mysite for use during the verification phase. * * version => the zot revision * * delegate => optional urlencoded webbie of a local channel to invoke delegation rights for * @@ -336,8 +338,8 @@ class Auth { * } * \endcode * - * auth_check messages MUST use encapsulated encryption. This message is sent to the origination site, which checks the 'secret' to see - * if it is the same as the 'sec' which it passed originally. It also checks the secret_sig which is the secret signed by the + * auth_check messages MUST use encapsulated encryption. This message is sent to the origination site, which checks the 'secret' to see + * if it is the same as the 'sec' which it passed originally. It also checks the secret_sig which is the secret signed by the * destination channel's private key and base64url encoded. If everything checks out, a json packet is returned: * * \code{.json} @@ -351,10 +353,10 @@ class Auth { * \endcode * * 'confirm' in this case is the base64url encoded RSA signature of the concatenation of 'secret' with the - * base64url encoded whirlpool hash of the requestor's guid and guid_sig; signed with the source channel private key. - * This prevents a man-in-the-middle from inserting a rogue success packet. Upon receipt and successful - * verification of this packet, the destination site will redirect to the original destination URL and indicate a successful remote login. - * Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is + * base64url encoded whirlpool hash of the requestor's guid and guid_sig; signed with the source channel private key. + * This prevents a man-in-the-middle from inserting a rogue success packet. Upon receipt and successful + * verification of this packet, the destination site will redirect to the original destination URL and indicate a successful remote login. + * Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is * a string whose contents are not defined by protocol. Example: "basic" or "gold". * * @param[in,out] \App &$a diff --git a/Zotlabs/Zot/Finger.php b/Zotlabs/Zot/Finger.php index 778b701cd..cadde5415 100644 --- a/Zotlabs/Zot/Finger.php +++ b/Zotlabs/Zot/Finger.php @@ -2,6 +2,7 @@ namespace Zotlabs\Zot; +use Zotlabs\Lib\Crypto; use Zotlabs\Web\HTTPSig; /** @@ -109,7 +110,7 @@ class Finger { $result = z_post_url('http://' . $host . $rhs,$postvars, $retries, [ 'headers' => $xhead ]); } } - } + } else { $rhs .= '?f=&address=' . urlencode($address) . '&token=' . self::$token; @@ -135,7 +136,7 @@ class Finger { if($x && (! $verify['header_valid'])) { $signed_token = ((is_array($x) && array_key_exists('signed_token', $x)) ? $x['signed_token'] : null); if($signed_token) { - $valid = rsa_verify('token.' . self::$token, base64url_decode($signed_token), $x['key']); + $valid = Crypto::verify('token.' . self::$token, base64url_decode($signed_token), $x['key']); if(! $valid) { logger('invalid signed token: ' . $url . $rhs, LOGGER_NORMAL, LOG_ERR); diff --git a/Zotlabs/Zot/Receiver.php b/Zotlabs/Zot/Receiver.php index c521c9d64..7fc445f66 100644 --- a/Zotlabs/Zot/Receiver.php +++ b/Zotlabs/Zot/Receiver.php @@ -2,6 +2,8 @@ namespace Zotlabs\Zot; +use Zotlabs\Lib\Crypto; + class Receiver { protected $data; @@ -30,7 +32,7 @@ class Receiver { $this->encrypted = ((array_key_exists('iv',$data)) ? true : false); if($this->encrypted) { - $this->data = @json_decode(@crypto_unencapsulate($data,$prvkey),true); + $this->data = @json_decode(@Crypto::unencapsulate($data,$prvkey),true); } if(! $this->data) $this->data = $data; @@ -72,7 +74,7 @@ class Receiver { $this->validated = true; } - + function Dispatch() { /* Handle tasks which don't require sender validation */ @@ -144,8 +146,8 @@ class Receiver { * $contents->iv and $contents->key are random strings encrypted with this site's RSA public key and then base64url encoded. * * Once decrypted, one will find the normal json_encoded zot message packet. - * - * Defined packet types are: notify, purge, refresh, force_refresh, auth_check, ping, and pickup + * + * Defined packet types are: notify, purge, refresh, force_refresh, auth_check, ping, and pickup * * Standard packet: (used by notify, purge, refresh, force_refresh, and auth_check) * \code{.json} @@ -167,7 +169,7 @@ class Receiver { * \endcode * * Signature fields are all signed with the sender channel private key and base64url encoded. - * Recipients are arrays of guid and guid_sig, which were previously signed with the recipients private + * Recipients are arrays of guid and guid_sig, which were previously signed with the recipients private * key and base64url encoded and later obtained via channel discovery. Absence of recipients indicates * a public message or visible to all potential listeners on this site. * @@ -186,7 +188,7 @@ class Receiver { * * In the pickup packet, the sig fields correspond to the respective data * element signed with this site's system private key and then base64url encoded. - * The "secret" is the same as the original secret from the notify packet. + * The "secret" is the same as the original secret from the notify packet. * * If verification is successful, a json structure is returned containing a * success indicator and an array of type 'pickup'. @@ -283,18 +285,18 @@ class Receiver { * } * \endcode * - * The ping packet can be used to verify that a site has not been re-installed, and to + * The ping packet can be used to verify that a site has not been re-installed, and to * initiate corrective action if it has. The url_sig is signed with the site private key * and base64url encoded - and this should verify with the enclosed sitekey. Failure to * verify indicates the site is corrupt or otherwise unable to communicate using zot. * This return packet is not otherwise verified, so should be compared with other * results obtained from this site which were verified prior to taking action. For instance - * if you have one verified result with this signature and key, and other records for this + * if you have one verified result with this signature and key, and other records for this * url which have different signatures and keys, it indicates that the site was re-installed * and corrective action may commence (remove or mark invalid any entries with different * signatures). * If you have no records which match this url_sig and key - no corrective action should - * be taken as this packet may have been returned by an imposter. + * be taken as this packet may have been returned by an imposter. * * @param[in,out] App &$a */ diff --git a/Zotlabs/Zot6/Receiver.php b/Zotlabs/Zot6/Receiver.php index a9a7ab0df..6440c5da5 100644 --- a/Zotlabs/Zot6/Receiver.php +++ b/Zotlabs/Zot6/Receiver.php @@ -3,6 +3,7 @@ namespace Zotlabs\Zot6; use Zotlabs\Lib\Config; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\Libzot; use Zotlabs\Web\HTTPSig; @@ -70,7 +71,7 @@ class Receiver { $this->encrypted = ((array_key_exists('encrypted',$this->data) && intval($this->data['encrypted'])) ? true : false); if ($this->encrypted && $this->prvkey) { - $uncrypted = crypto_unencapsulate($this->data,$this->prvkey); + $uncrypted = Crypto::unencapsulate($this->data,$this->prvkey); if ($uncrypted) { $this->data = json_decode($uncrypted,true); } @@ -88,7 +89,7 @@ class Receiver { if ($this->error) { // make timing attacks on the decryption engine a bit more difficult usleep(mt_rand(10000,100000)); - return($this->response); + return($this->response); } if ($this->data) { @@ -126,7 +127,7 @@ class Receiver { $x = Libzot::register_hub($this->sigdata['signer']); if($x['success']) { $hub = Libzot::valid_hub($this->sender,$this->site_id); - } + } if(! $hub) { $this->response['message'] = 'sender unknown'; return false; @@ -168,8 +169,8 @@ class Receiver { } } return $result; - } - + } + function Dispatch() { switch ($this->messagetype) { @@ -207,13 +208,13 @@ class Receiver { $this->EncryptResponse(); } - return($this->response); + return($this->response); } function EncryptResponse() { $algorithm = Libzot::best_algorithm($this->hub['site_crypto']); if ($algorithm) { - $this->response = crypto_encapsulate(json_encode($this->response),$this->hub['hubloc_sitekey'], $algorithm); + $this->response = Crypto::encapsulate(json_encode($this->response),$this->hub['hubloc_sitekey'], $algorithm); } } diff --git a/boot.php b/boot.php index 4d18d4844..0c70f0229 100644 --- a/boot.php +++ b/boot.php @@ -28,6 +28,8 @@ */ // composer autoloader for all namespaced Classes +use Zotlabs\Lib\Crypto; + require_once('vendor/autoload.php'); require_once('include/config.php'); @@ -1570,7 +1572,7 @@ function fix_system_urls($oldurl, $newurl) { dbesc($channel_address . '@' . $rhs), dbesc($newurl), dbesc(str_replace($oldurl,$newurl,$rv['hubloc_id_url'])), - dbesc(($rv['hubloc_network'] === 'zot6') ? \Zotlabs\Lib\Libzot::sign($newurl,$c[0]['channel_prvkey']) : base64url_encode(rsa_sign($newurl,$c[0]['channel_prvkey']))), + dbesc(($rv['hubloc_network'] === 'zot6') ? \Zotlabs\Lib\Libzot::sign($newurl,$c[0]['channel_prvkey']) : base64url_encode(Crypto::sign($newurl,$c[0]['channel_prvkey']))), dbesc($newhost), dbesc(($rv['hubloc_network'] === 'zot6') ? $newurl . '/zot' : $newurl . '/post'), dbesc($rv['xchan_hash']), diff --git a/include/account.php b/include/account.php index bea84cea7..34936c33f 100644 --- a/include/account.php +++ b/include/account.php @@ -4,6 +4,8 @@ * @brief Somme account related functions. */ +use Zotlabs\Lib\Crypto; + require_once('include/config.php'); require_once('include/network.php'); require_once('include/plugin.php'); @@ -26,8 +28,8 @@ function check_account_email($email) { $email = punify($email); $result = array('error' => false, 'message' => ''); - // Caution: empty email isn't counted as an error in this function. - // Check for empty value separately. + // Caution: empty email isn't counted as an error in this function. + // Check for empty value separately. if(! strlen($email)) return $result; @@ -36,7 +38,7 @@ function check_account_email($email) { $result['message'] .= t('Not a valid email address') . EOL; elseif(! allowed_email($email)) $result['message'] = t('Your email domain is not among those allowed on this site'); - else { + else { $r = q("select account_email from account where account_email = '%s' limit 1", dbesc($email) ); @@ -175,7 +177,7 @@ function create_account($arr) { // Ensure that there is a host keypair. if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { - $hostkey = new_keypair(4096); + $hostkey = Crypto::new_keypair(4096); set_config('system', 'pubkey', $hostkey['pubkey']); set_config('system', 'prvkey', $hostkey['prvkey']); } @@ -306,8 +308,8 @@ function verify_email_address($arr) { ); $res = z_mail( - [ - 'toEmail' => $arr['email'], + [ + 'toEmail' => $arr['email'], 'messageSubject' => sprintf( t('Registration confirmation for %s'), get_config('system','sitename')), 'textVersion' => $email_msg, ] @@ -375,8 +377,8 @@ function send_reg_approval_email($arr) { )); $res = z_mail( - [ - 'toEmail' => $admin['email'], + [ + 'toEmail' => $admin['email'], 'messageSubject' => sprintf( t('Registration request at %s'), get_config('system','sitename')), 'textVersion' => $email_msg, ] @@ -403,7 +405,7 @@ function send_register_success_email($email,$password) { )); $res = z_mail( - [ + [ 'toEmail' => $email, 'messageSubject' => sprintf( t('Registration details for %s'), get_config('system','sitename')), 'textVersion' => $email_msg, @@ -446,7 +448,7 @@ function account_allow($hash) { intval(ACCOUNT_BLOCKED), intval($register[0]['uid']) ); - + q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", intval(ACCOUNT_PENDING), intval(ACCOUNT_PENDING), @@ -466,7 +468,7 @@ function account_allow($hash) { )); $res = z_mail( - [ + [ 'toEmail' => $account[0]['account_email'], 'messageSubject' => sprintf( t('Registration details for %s'), get_config('system','sitename')), 'textVersion' => $email_msg, @@ -556,13 +558,13 @@ function account_approve($hash) { intval(ACCOUNT_BLOCKED), intval($register[0]['uid']) ); - + q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", intval(ACCOUNT_PENDING), intval(ACCOUNT_PENDING), intval($register[0]['uid']) ); - + q("update account set account_flags = (account_flags & ~%d) where (account_flags & %d)>0 and account_id = %d", intval(ACCOUNT_UNVERIFIED), intval(ACCOUNT_UNVERIFIED), @@ -583,7 +585,7 @@ function account_approve($hash) { else { $_SESSION['login_return_url'] = 'new_channel'; authenticate_success($account[0],null,true,true,false,true); - } + } return true; } @@ -592,14 +594,14 @@ function account_approve($hash) { /** * @brief Checks for accounts that have past their expiration date. * - * If the account has a service class which is not the site default, + * If the account has a service class which is not the site default, * the service class is reset to the site default and expiration reset to never. * If the account has no service class it is expired and subsequently disabled. * called from include/poller.php as a scheduled task. * * Reclaiming resources which are no longer within the service class limits is - * not the job of this function, but this can be implemented by plugin if desired. - * Default behaviour is to stop allowing additional resources to be consumed. + * not the job of this function, but this can be implemented by plugin if desired. + * Default behaviour is to stop allowing additional resources to be consumed. */ function downgrade_accounts() { diff --git a/include/channel.php b/include/channel.php index 2d79cd074..08b5ee889 100644 --- a/include/channel.php +++ b/include/channel.php @@ -9,6 +9,7 @@ use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\PermissionLimits; use Zotlabs\Access\Permissions; use Zotlabs\Daemon\Master; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\System; use Zotlabs\Render\Comanche; use Zotlabs\Lib\Libzot; @@ -107,7 +108,7 @@ function create_sys_channel() { if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { require_once('include/crypto.php'); - $hostkey = new_keypair(4096); + $hostkey = Crypto::new_keypair(4096); set_config('system', 'pubkey', $hostkey['pubkey']); set_config('system', 'prvkey', $hostkey['prvkey']); } @@ -232,10 +233,10 @@ function create_identity($arr) { } $guid = Libzot::new_uid($nick); - $key = new_keypair(4096); + $key = Crypto::new_keypair(4096); // legacy zot - $zsig = base64url_encode(rsa_sign($guid,$key['prvkey'])); + $zsig = base64url_encode(Crypto::sign($guid,$key['prvkey'])); $zhash = make_xchan_hash($guid,$zsig); // zot6 @@ -345,7 +346,7 @@ function create_identity($arr) { 'hubloc_addr' => channel_reddress($ret['channel']), 'hubloc_primary' => intval($primary), 'hubloc_url' => z_root(), - 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey'])), + 'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$ret['channel']['channel_prvkey'])), 'hubloc_host' => App::get_hostname(), 'hubloc_callback' => z_root() . '/post', 'hubloc_sitekey' => get_config('system','pubkey'), @@ -603,9 +604,9 @@ function change_channel_keys($channel) { $stored = []; - $key = new_keypair(4096); + $key = Crypto::new_keypair(4096); - $sig = base64url_encode(rsa_sign($channel['channel_guid'],$key['prvkey'])); + $sig = base64url_encode(Crypto::sign($channel['channel_guid'],$key['prvkey'])); $hash = make_xchan_hash($channel['channel_guid'],$sig); $stored['old_guid'] = $channel['channel_guid']; @@ -614,7 +615,7 @@ function change_channel_keys($channel) { $stored['old_hash'] = $channel['channel_hash']; $stored['new_key'] = $key['pubkey']; - $stored['new_sig'] = base64url_encode(rsa_sign($key['pubkey'],$channel['channel_prvkey'])); + $stored['new_sig'] = base64url_encode(Crypto::sign($key['pubkey'],$channel['channel_prvkey'])); // Save this info for the notifier to collect @@ -651,7 +652,7 @@ function change_channel_keys($channel) { foreach($h as $hv) { $hv['hubloc_guid_sig'] = $sig; $hv['hubloc_hash'] = $hash; - $hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$modified['channel_prvkey'])); + $hv['hubloc_url_sig'] = base64url_encode(Crypto::sign(z_root(),$modified['channel_prvkey'])); hubloc_store_lowlevel($hv); } } diff --git a/include/crypto.php b/include/crypto.php index 84d639f3f..d91d3749c 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -1,5 +1,7 @@ $j['permissions']['data'], 'alg' => $j['permissions']['alg'], 'key' => $j['permissions']['key'], @@ -140,7 +142,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) $xchan_hash = ''; $sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : ''); - + $r = q("select * from xchan where (xchan_addr = '%s' or xchan_url = '%s') $sql_options ", dbesc($url), diff --git a/include/items.php b/include/items.php index 83108455f..223fba147 100644 --- a/include/items.php +++ b/include/items.php @@ -4,6 +4,7 @@ * @brief Items related functions. */ +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\Enotify; use Zotlabs\Lib\MarkdownSoap; use Zotlabs\Lib\MessageFilter; @@ -1652,7 +1653,7 @@ function item_sign(&$item) { if(! $r) return; - $item['sig'] = base64url_encode(rsa_sign($item['body'], $r[0]['channel_prvkey'])); + $item['sig'] = base64url_encode(Crypto::sign($item['body'], $r[0]['channel_prvkey'])); $item['item_verified'] = 1; } @@ -2971,7 +2972,7 @@ function item_community_tag($channel,$item) { $pitem = $items[0]; $auth = get_iconfig($item,'system','communitytagauth'); if($auth) { - if(rsa_verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['owner']['xchan_pubkey']) || rsa_verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['author']['xchan_pubkey'])) { + if(Crypto::verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['owner']['xchan_pubkey']) || Crypto::verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['author']['xchan_pubkey'])) { logger('tag_deliver: tagging the post: ' . $channel['channel_name']); $tag_the_post = true; } @@ -2980,7 +2981,7 @@ function item_community_tag($channel,$item) { if(($pitem['owner_xchan'] === $channel['channel_hash']) && (! intval(get_pconfig($channel['channel_id'],'system','blocktags')))) { logger('tag_deliver: community tag recipient: ' . $channel['channel_name']); $tag_the_post = true; - $sig = rsa_sign('tagauth.' . $item['mid'],$channel['channel_prvkey']); + $sig = Crypto::sign('tagauth.' . $item['mid'],$channel['channel_prvkey']); logger('tag_deliver: setting iconfig for ' . $item['id']); set_iconfig($item['id'],'system','communitytagauth',base64url_encode($sig),1); } diff --git a/include/text.php b/include/text.php index 1e08d136c..b7cc0ba20 100644 --- a/include/text.php +++ b/include/text.php @@ -9,6 +9,7 @@ use Michelf\MarkdownExtra; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Exception\UnableToBuildUuidException; +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\SvgSanitizer; require_once("include/bbcode.php"); @@ -3248,7 +3249,7 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') { $item['body'] = preg_replace("/(\[zrl=".preg_quote($old,'/')."\/(photo|photos|gallery)\/".$channel['channel_address'].".+\]\[zmg=\d+x\d+\])".preg_quote($old,'/')."\/(.+\[\/zmg\])/", '${1}'.$new.'/${3}', $item['body']); $item['body'] = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']); - $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey'])); + $item['sig'] = base64url_encode(Crypto::sign($item['body'],$channel['channel_prvkey'])); $item['item_verified'] = 1; $item['plink'] = str_replace($old,$new,$item['plink']); @@ -3881,6 +3882,14 @@ function unserialise($x) { return ((is_array($y)) ? $y : $x); } +function obscurify($s) { + return str_rot47(base64url_encode($s)); +} + +function unobscurify($s) { + return base64url_decode(str_rot47($s)); +} + /** * @brief Remove new lines and tabs from strings. * diff --git a/include/xchan.php b/include/xchan.php index 5de828e7f..07fdb8b47 100644 --- a/include/xchan.php +++ b/include/xchan.php @@ -1,5 +1,6 @@ ', '<' . $newxchan['xchan_hash'] . '>', + dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', $rv[$allow])), - dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', + dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>', $rv[$deny])), intval($rv[$column]) ); @@ -243,7 +244,7 @@ function xchan_change_key($oldx,$newx,$data) { 'xprof' => 'xprof_hash', 'xtag' => 'xtag_hash' ]; - + $acls = [ 'channel' => 'channel_id', diff --git a/include/zot.php b/include/zot.php index d61873ba2..f96792656 100644 --- a/include/zot.php +++ b/include/zot.php @@ -8,6 +8,7 @@ * */ +use Zotlabs\Lib\Crypto; use Zotlabs\Lib\DReport; use Zotlabs\Lib\Libzot; use Zotlabs\Lib\Activity; @@ -123,15 +124,15 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot 'type' => $type, 'sender' => [ 'guid' => $channel['channel_guid'], - 'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), + 'guid_sig' => base64url_encode(Crypto::sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), 'url' => z_root(), - 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'],$sig_method)), + 'url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'],$sig_method)), 'sitekey' => get_config('system','pubkey') ], 'callback' => '/post', 'version' => Zotlabs\Lib\System::get_zot_revision(), - 'encryption' => crypto_methods(), - 'signing' => signing_methods() + 'encryption' => Crypto::methods(), + 'signing' => Crypto::signing_methods() ]; if ($recipients) { @@ -143,7 +144,7 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot if ($secret) { $data['secret'] = preg_replace('/[^0-9a-fA-F]/','',$secret); - $data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey'],$sig_method)); + $data['secret_sig'] = base64url_encode(Crypto::sign($secret,$channel['channel_prvkey'],$sig_method)); } if ($extra) { @@ -157,7 +158,7 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot if($remote_key) { $algorithm = zot_best_algorithm($methods); - $data = crypto_encapsulate(json_encode($data),$remote_key, $algorithm); + $data = Crypto::encapsulate(json_encode($data),$remote_key, $algorithm); } return json_encode($data); @@ -197,15 +198,15 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg 'type' => $type, 'sender' => [ 'guid' => $channel['channel_guid'], - 'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), + 'guid_sig' => base64url_encode(Crypto::sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), 'url' => z_root(), - 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'],$sig_method)), + 'url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'],$sig_method)), 'sitekey' => get_config('system','pubkey') ], 'callback' => '/post', 'version' => Zotlabs\Lib\System::get_zot_revision(), - 'encryption' => crypto_methods(), - 'signing' => signing_methods() + 'encryption' => Crypto::methods(), + 'signing' => Crypto::signing_methods() ]; if ($recipients) { @@ -221,7 +222,7 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg if ($secret) { $data['secret'] = preg_replace('/[^0-9a-fA-F]/','',$secret); - $data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey'],$sig_method)); + $data['secret_sig'] = base64url_encode(Crypto::sign($secret,$channel['channel_prvkey'],$sig_method)); } if ($extra) { @@ -235,7 +236,7 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg if($remote_key) { $algorithm = zot_best_algorithm($methods); - $data = crypto_encapsulate(json_encode($data),$remote_key, $algorithm); + $data = Crypto::encapsulate(json_encode($data),$remote_key, $algorithm); } return json_encode($data); @@ -249,7 +250,7 @@ function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg * * @param string $methods * comma separated list of encryption methods - * @return string first match from our site method preferences crypto_methods() array + * @return string first match from our site method preferences Crypto::methods() array * of a method which is common to both sites; or 'aes256cbc' if no matches are found. */ function zot_best_algorithm($methods) { @@ -272,7 +273,7 @@ function zot_best_algorithm($methods) { if($methods) { $x = explode(',', $methods); if($x) { - $y = crypto_methods(); + $y = Crypto::methods(); if($y) { foreach($y as $yv) { $yv = trim($yv); @@ -443,7 +444,7 @@ function zot_refresh($them, $channel = null, $force = false) { $signed_token = ((is_array($j) && array_key_exists('signed_token',$j)) ? $j['signed_token'] : null); if($signed_token) { - $valid = rsa_verify('token.' . $token,base64url_decode($signed_token),$j['key']); + $valid = Crypto::verify('token.' . $token,base64url_decode($signed_token),$j['key']); if(! $valid) { logger('invalid signed token: ' . $url . $rhs, LOGGER_NORMAL, LOG_ERR); return false; @@ -461,7 +462,7 @@ function zot_refresh($them, $channel = null, $force = false) { if($channel) { if($j['permissions']['data']) { - $permissions = crypto_unencapsulate( + $permissions = Crypto::unencapsulate( [ 'data' => $j['permissions']['data'], 'key' => $j['permissions']['key'], @@ -719,8 +720,8 @@ function zot_register_hub($arr) { */ foreach($sig_methods as $method) { - if((rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$record['key'],$method)) - && (rsa_verify($arr['url'],base64url_decode($arr['url_sig']),$record['key'],$method)) + if((Crypto::verify($arr['guid'],base64url_decode($arr['guid_sig']),$record['key'],$method)) + && (Crypto::verify($arr['url'],base64url_decode($arr['url_sig']),$record['key'],$method)) && ($arr['guid'] === $record['guid']) && ($arr['guid_sig'] === $record['guid_sig'])) { $c = import_xchan($record); @@ -790,7 +791,7 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { $verified = false; foreach($sig_methods as $method) { - if(! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key'],$method)) { + if(! Crypto::verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key'],$method)) { logger('Unable to verify channel signature for ' . $arr['address'] . ' using ' . $method); continue; } @@ -925,28 +926,28 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { $local = q("select channel_account_id, channel_id from channel where channel_portable_id = '%s' limit 1", dbesc($xchan_hash) ); - + if($local) { - // @FIXME This should be removed in future when profile photo update by file sync procedure will be applied + // @FIXME This should be removed in future when profile photo update by file sync procedure will be applied // on most hubs in the network // <--- $ph = z_fetch_url($arr['photo'], true); - + if($ph['success']) { - + // Do not fetch already received thumbnails $x = q("SELECT resource_id FROM photo WHERE uid = %d AND imgscale = %d AND filesize = %d LIMIT 1", intval($local[0]['channel_id']), intval(PHOTO_RES_PROFILE_300), strlen($ph['body']) - ); + ); if($x) $hash = $x[0]['resource_id']; else $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']); } - + if($hash) { // unless proven otherwise $is_default_profile = 1; @@ -972,7 +973,7 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { } } // ---> - + // reset the names in case they got messed up when we had a bug in this function $photos = array( z_root() . '/photo/profile/l/' . $local[0]['channel_id'], @@ -1128,7 +1129,7 @@ function zot_process_response($hub, $arr, $outq) { if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) { if(array_key_exists('iv',$x['delivery_report'])) { - $j = crypto_unencapsulate($x['delivery_report'],get_config('system','prvkey')); + $j = Crypto::unencapsulate($x['delivery_report'],get_config('system','prvkey')); if($j) { $x['delivery_report'] = json_decode($j,true); } @@ -1253,14 +1254,14 @@ function zot_fetch($arr) { $data = [ 'type' => 'pickup', 'url' => z_root(), - 'callback_sig' => base64url_encode(rsa_sign(z_root() . '/post', get_config('system','prvkey'))), + 'callback_sig' => base64url_encode(Crypto::sign(z_root() . '/post', get_config('system','prvkey'))), 'callback' => z_root() . '/post', 'secret' => $secret, - 'secret_sig' => base64url_encode(rsa_sign($secret, get_config('system','prvkey'))) + 'secret_sig' => base64url_encode(Crypto::sign($secret, get_config('system','prvkey'))) ]; $algorithm = zot_best_algorithm($hub['site_crypto']); - $datatosend = json_encode(crypto_encapsulate(json_encode($data),$hub['hubloc_sitekey'], $algorithm)); + $datatosend = json_encode(Crypto::encapsulate(json_encode($data),$hub['hubloc_sitekey'], $algorithm)); $import = zot_zot($url,$datatosend); @@ -1272,7 +1273,7 @@ function zot_fetch($arr) { $result = zot_import($import, $arr['sender']['url']); if($result) { - $result = crypto_encapsulate(json_encode($result),$hub['hubloc_sitekey'], $algorithm); + $result = Crypto::encapsulate(json_encode($result),$hub['hubloc_sitekey'], $algorithm); return $result; } @@ -1314,7 +1315,7 @@ function zot_import($arr, $sender_url) { } if(array_key_exists('iv', $data)) { - $data = json_decode(crypto_unencapsulate($data,get_config('system','prvkey')),true); + $data = json_decode(Crypto::unencapsulate($data,get_config('system','prvkey')),true); } if(! is_array($data)) { @@ -1342,7 +1343,7 @@ function zot_import($arr, $sender_url) { $result = null; if(array_key_exists('iv',$i['notify'])) { - $i['notify'] = json_decode(crypto_unencapsulate($i['notify'],get_config('system','prvkey')),true); + $i['notify'] = json_decode(Crypto::unencapsulate($i['notify'],get_config('system','prvkey')),true); } logger('Notify: ' . print_r($i['notify'],true), LOGGER_DATA, LOG_DEBUG); @@ -2466,7 +2467,7 @@ function process_rating_delivery($sender, $arr) { dbesc($sender['hash']) ); - if((! $z) || (! rsa_verify($arr['target'] . '.' . $arr['rating'] . '.' . $arr['rating_text'], base64url_decode($arr['signature']),$z[0]['xchan_pubkey']))) { + if((! $z) || (! Crypto::verify($arr['target'] . '.' . $arr['rating'] . '.' . $arr['rating_text'], base64url_decode($arr['signature']),$z[0]['xchan_pubkey']))) { logger('failed to verify rating'); return; } @@ -2652,7 +2653,7 @@ function sync_locations($sender, $arr, $absolute = false) { $arr['locations'][0]['primary'] = true; foreach($arr['locations'] as $location) { - if(! rsa_verify($location['url'],base64url_decode($location['url_sig']),$sender['key'])) { + if(! Crypto::verify($location['url'],base64url_decode($location['url_sig']),$sender['key'])) { logger('Unable to verify site signature for ' . $location['url']); $ret['message'] .= sprintf( t('Unable to verify site signature for %s'), $location['url']) . EOL; continue; @@ -3126,7 +3127,7 @@ function import_site($arr, $pubkey) { if( (! is_array($arr)) || (! $arr['url']) || (! $arr['url_sig'])) return false; - if(! rsa_verify($arr['url'], base64url_decode($arr['url_sig']), $pubkey)) { + if(! Crypto::verify($arr['url'], base64url_decode($arr['url_sig']), $pubkey)) { logger('Bad url_sig'); return false; } @@ -3509,12 +3510,12 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if($keychange) { // verify the keychange operation - if(! rsa_verify($arr['channel']['channel_pubkey'],base64url_decode($arr['keychange']['new_sig']),$channel['channel_prvkey'])) { + if(! Crypto::verify($arr['channel']['channel_pubkey'],base64url_decode($arr['keychange']['new_sig']),$channel['channel_prvkey'])) { logger('sync keychange: verification failed'); continue; } - $sig = base64url_encode(rsa_sign($channel['channel_guid'],$arr['channel']['channel_prvkey'])); + $sig = base64url_encode(Crypto::sign($channel['channel_guid'],$arr['channel']['channel_prvkey'])); $hash = make_xchan_hash($channel['channel_guid'],$sig); @@ -3551,7 +3552,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { foreach($h as $hv) { $hv['hubloc_guid_sig'] = $sig; $hv['hubloc_hash'] = $hash; - $hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])); + $hv['hubloc_url_sig'] = base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])); hubloc_store_lowlevel($hv); } } @@ -4329,7 +4330,7 @@ function zot_rekey_request($sender,$data) { $xchan = $r[0]; - if(! rsa_verify($data['new_key'],base64url_decode($data['new_sig']),$xchan['xchan_pubkey'])) { + if(! Crypto::verify($data['new_key'],base64url_decode($data['new_sig']),$xchan['xchan_pubkey'])) { json_return_and_die($ret); } @@ -4367,7 +4368,7 @@ function zotinfo($arr) { $feed = ((x($arr,'feed')) ? intval($arr['feed']) : 0); if($ztarget) { - if((! $zkey) || (! $zsig) || (! rsa_verify($ztarget,base64url_decode($zsig),$zkey))) { + if((! $zkey) || (! $zsig) || (! Crypto::verify($ztarget,base64url_decode($zsig),$zkey))) { logger('zfinger: invalid target signature'); $ret['message'] = t("invalid target signature"); return($ret); @@ -4531,7 +4532,7 @@ function zotinfo($arr) { // Communication details if($token) - $ret['signed_token'] = base64url_encode(rsa_sign('token.' . $token,$e['channel_prvkey'],$sig_method)); + $ret['signed_token'] = base64url_encode(Crypto::sign('token.' . $token,$e['channel_prvkey'],$sig_method)); $ret['guid'] = $e['xchan_guid']; @@ -4587,7 +4588,7 @@ function zotinfo($arr) { // because ztarget refers to an xchan and we don't necessarily know the origination // location. - $ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey) : $permissions); + $ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey,) : $permissions); if($permissions['view_profile']) $ret['profile'] = $profile; @@ -4622,9 +4623,9 @@ function zot_site_info($channel_key = '') { $ret['site'] = []; $ret['site']['url'] = z_root(); if($channel_key) { - $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$channel_key,$sig_method)); + $ret['site']['url_sig'] = base64url_encode(Crypto::sign(z_root(),$channel_key,$sig_method)); } - $ret['site']['url_site_sig'] = base64url_encode(rsa_sign(z_root(),$signing_key,$sig_method)); + $ret['site']['url_site_sig'] = base64url_encode(Crypto::sign(z_root(),$signing_key,$sig_method)); $ret['site']['post'] = z_root() . '/post'; $ret['site']['openWebAuth'] = z_root() . '/owa'; $ret['site']['authRedirect'] = z_root() . '/magic'; @@ -4644,8 +4645,8 @@ function zot_site_info($channel_key = '') { $ret['site']['directory_url'] = z_root() . '/dirsearch'; - $ret['site']['encryption'] = crypto_methods(); - $ret['site']['signing'] = signing_methods(); + $ret['site']['encryption'] = Crypto::methods(); + $ret['site']['signing'] = Crypto::signing_methods(); $ret['site']['zot'] = Zotlabs\Lib\System::get_zot_revision(); // hide detailed site information if you're off the grid @@ -4724,7 +4725,7 @@ function check_zotinfo($channel, $locations, &$ret) { // the sys channel must have a location (hubloc) $valid_location = false; if((count($locations) === 1) && ($locations[0]['primary']) && (! $locations[0]['deleted'])) { - if((rsa_verify($locations[0]['url'],base64url_decode($locations[0]['url_sig']),$channel['channel_pubkey'])) + if((Crypto::verify($locations[0]['url'],base64url_decode($locations[0]['url_sig']),$channel['channel_pubkey'])) && ($locations[0]['sitekey'] === get_config('system','pubkey')) && ($locations[0]['url'] === z_root())) $valid_location = true; @@ -4752,7 +4753,7 @@ function check_zotinfo($channel, $locations, &$ret) { 'hubloc_network' => 'zot', 'hubloc_primary' => 1, 'hubloc_url' => z_root(), - 'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])), + 'hubloc_url_sig' => base64url_encode(Crypto::sign(z_root(),$channel['channel_prvkey'])), 'hubloc_host' => App::get_hostname(), 'hubloc_callback' => z_root() . '/post', 'hubloc_sitekey' => get_config('system','pubkey'), @@ -4931,7 +4932,7 @@ function zot_reply_ping() { $ret['success'] = true; $ret['site'] = array(); $ret['site']['url'] = z_root(); - $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),get_config('system','prvkey'))); + $ret['site']['url_sig'] = base64url_encode(Crypto::sign(z_root(),get_config('system','prvkey'))); $ret['site']['sitekey'] = get_config('system','pubkey'); json_return_and_die($ret); @@ -4979,10 +4980,10 @@ function zot_reply_pickup($data) { logger('mod_zot: Checking sitekey: ' . $sitekey, LOGGER_DATA, LOG_DEBUG); - if(rsa_verify($data['callback'],base64url_decode($data['callback_sig']),$sitekey)) { + if(Crypto::verify($data['callback'],base64url_decode($data['callback_sig']),$sitekey)) { $forgery = false; } - if(rsa_verify($data['secret'],base64url_decode($data['secret_sig']),$sitekey)) { + if(Crypto::verify($data['secret'],base64url_decode($data['secret_sig']),$sitekey)) { $secret_fail = false; } if((! $forgery) && (! $secret_fail)) @@ -5076,7 +5077,7 @@ function zot_reply_pickup($data) { ); $algorithm = zot_best_algorithm(($x) ? $x[0]['site_crypto'] : ''); - $encrypted = crypto_encapsulate(json_encode($ret),$sitekey,$algorithm); + $encrypted = Crypto::encapsulate(json_encode($ret),$sitekey,$algorithm); json_return_and_die($encrypted); // @FIXME: There is a possibility that the transmission will get interrupted @@ -5133,7 +5134,7 @@ function zot_reply_auth_check($data,$encrypted_packet) { // First verify their signature. We will have obtained a zot-info packet from them as part of the sender // verification. - if ((! $y) || (! rsa_verify($data['secret'], base64url_decode($data['secret_sig']),$y[0]['xchan_pubkey']))) { + if ((! $y) || (! Crypto::verify($data['secret'], base64url_decode($data['secret_sig']),$y[0]['xchan_pubkey']))) { logger('mod_zot: auth_check: sender not found or secret_sig invalid.'); $ret['message'] .= 'sender not found or sig invalid ' . print_r($y,true) . EOL; @@ -5158,7 +5159,7 @@ function zot_reply_auth_check($data,$encrypted_packet) { json_return_and_die($ret); } - $confirm = base64url_encode(rsa_sign($data['secret'] . $recip_hash,$c[0]['channel_prvkey'])); + $confirm = base64url_encode(Crypto::sign($data['secret'] . $recip_hash,$c[0]['channel_prvkey'])); // This additionally checks for forged sites since we already stored the expected result in meta // and we've already verified that this is them via zot_gethub() and that their key signed our token diff --git a/tests/unit/Lib/KeyutilsTest.php b/tests/unit/Lib/KeyutilsTest.php index bb5f84728..d1b0b5ab8 100644 --- a/tests/unit/Lib/KeyutilsTest.php +++ b/tests/unit/Lib/KeyutilsTest.php @@ -34,8 +34,6 @@ use Zotlabs\Lib\Keyutils; * @covers Zotlabs\Lib\Keyutils */ - - class KeyutilsTest extends UnitTestCase { protected function getPubPKCS1() { diff --git a/tests/unit/Web/HttpSigTest.php b/tests/unit/Web/HttpSigTest.php index bd11b96c8..5524e0510 100644 --- a/tests/unit/Web/HttpSigTest.php +++ b/tests/unit/Web/HttpSigTest.php @@ -71,7 +71,7 @@ class HttpSigTest extends UnitTestCase { } /** - * @uses ::crypto_unencapsulate + * @uses ::Crypto::unencapsulate */ function testDecrypt_sigheader() { $header = 'Header: iv="value_iv" key="value_key" alg="value_alg" data="value_data"'; @@ -86,7 +86,7 @@ class HttpSigTest extends UnitTestCase { $this->assertSame($result, HTTPSig::decrypt_sigheader($header, 'site private key')); } /** - * @uses ::crypto_unencapsulate + * @uses ::Crypto::unencapsulate */ function testDecrypt_sigheaderUseSitePrivateKey() { // Create a stub for global function get_config() with expectation @@ -95,7 +95,7 @@ class HttpSigTest extends UnitTestCase { $header = 'Header: iv="value_iv" key="value_key" alg="value_alg" data="value_data"'; $result = [ - 'encrypted' => true, + 'encrypted' => true, 'iv' => 'value_iv', 'key' => 'value_key', 'alg' => 'value_alg', diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 4e4b8790a..875700f7a 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', + 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', + 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', ), ), ); diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index f9d9d5f93..7c1ac62d8 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', + 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '6b8b42fb211d488388044621d8cff9e6d85e2b0f', + 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', ), ), ); -- cgit v1.2.3 From 3b3c93f9b37a049690bc60ceae75883b28d89a2a Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 9 Feb 2021 14:05:00 +0000 Subject: undo accidental revert in last commit --- Zotlabs/Lib/Libzot.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index a615cee6e..c2e388264 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -763,8 +763,8 @@ class Libzot { 'xchan_guid' => $arr['id'], 'xchan_guid_sig' => $arr['id_sig'], 'xchan_pubkey' => $arr['public_key'], - 'xchan_photo_mimetype' => $arr['photo_mimetype'], - 'xchan_photo_l' => $arr['photo'], + 'xchan_photo_mimetype' => $arr['photo']['type'], + 'xchan_photo_l' => $arr['photo']['url'], 'xchan_addr' => escape_tags($arr['primary_location']['address']), 'xchan_url' => escape_tags($arr['primary_location']['url']), 'xchan_connurl' => $arr['primary_location']['connections_url'], @@ -772,7 +772,7 @@ class Libzot { 'xchan_connpage' => $arr['connect_url'], 'xchan_name' => (($arr['name']) ? escape_tags($arr['name']) : '-'), 'xchan_network' => 'zot6', - 'xchan_photo_date' => $arr['photo_updated'], + 'xchan_photo_date' => $arr['photo']['updated'], 'xchan_name_date' => $arr['name_updated'], 'xchan_hidden' => intval(1 - intval($arr['searchable'])), 'xchan_selfcensored' => $arr['adult_content'], -- cgit v1.2.3 From e75ae1766232a8e3ae94ee207ec5a51f7882c82f Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 9 Feb 2021 14:09:26 +0000 Subject: whitespace --- Zotlabs/Lib/Crypto.php | 86 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Zotlabs/Lib/Crypto.php b/Zotlabs/Lib/Crypto.php index 3dba1bcf3..7c4654ec0 100644 --- a/Zotlabs/Lib/Crypto.php +++ b/Zotlabs/Lib/Crypto.php @@ -1,6 +1,7 @@ false ]; - $conf = get_config('system','openssl_conf_file'); + $conf = get_config('system', 'openssl_conf_file'); if ($conf) { $openssl_options['config'] = $conf; @@ -56,45 +57,44 @@ class Crypto { // Get private key - $response = [ 'prvkey' => '', 'pubkey' => '' ]; + $response = ['prvkey' => '', 'pubkey' => '']; openssl_pkey_export($result, $response['prvkey']); // Get public key - $pkey = openssl_pkey_get_details($result); + $pkey = openssl_pkey_get_details($result); $response['pubkey'] = $pkey["key"]; return $response; } - public static function sign($data,$key,$alg = 'sha256') { + public static function sign($data, $key, $alg = 'sha256') { - if (! $key) { + if (!$key) { return false; } $sig = ''; - openssl_sign($data,$sig,$key,$alg); + openssl_sign($data, $sig, $key, $alg); return $sig; } - public static function verify($data,$sig,$key,$alg = 'sha256') { + public static function verify($data, $sig, $key, $alg = 'sha256') { - if (! $key) { + if (!$key) { return false; } try { - $verify = openssl_verify($data,$sig,$key,$alg); - } - catch (Exception $e) { + $verify = openssl_verify($data, $sig, $key, $alg); + } catch (Exception $e) { $verify = (-1); } if ($verify === (-1)) { while ($msg = openssl_error_string()) { - logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR); + logger('openssl_verify: ' . $msg, LOGGER_NORMAL, LOG_ERR); } btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); } @@ -102,16 +102,16 @@ class Crypto { return (($verify > 0) ? true : false); } - public static function encapsulate($data,$pubkey,$alg) { + public static function encapsulate($data, $pubkey, $alg) { - if (! ($alg && $pubkey)) { + if (!($alg && $pubkey)) { return $data; } $alg_base = $alg; $padding = OPENSSL_PKCS1_PADDING; - $exts = explode('.',$alg); + $exts = explode('.', $alg); if (count($exts) > 1) { switch ($exts[1]) { case 'oaep': @@ -133,35 +133,35 @@ class Crypto { } if ($method) { - $result = [ 'encrypted' => true ]; + $result = ['encrypted' => true]; - $key = openssl_random_pseudo_bytes(256); - $iv = openssl_random_pseudo_bytes(256); + $key = openssl_random_pseudo_bytes(256); + $iv = openssl_random_pseudo_bytes(256); - $key1 = substr($key, 0, $method[2]); - $iv1 = substr($iv, 0, $method[3]); + $key1 = substr($key, 0, $method[2]); + $iv1 = substr($iv, 0, $method[3]); - $result['data'] = base64url_encode(openssl_encrypt($data,$method[1],$key1,OPENSSL_RAW_DATA,$iv1),true); + $result['data'] = base64url_encode(openssl_encrypt($data, $method[1], $key1, OPENSSL_RAW_DATA, $iv1), true); - openssl_public_encrypt($key, $k, $pubkey, $padding); - openssl_public_encrypt($iv, $i, $pubkey, $padding); + openssl_public_encrypt($key, $k, $pubkey, $padding); + openssl_public_encrypt($iv, $i, $pubkey, $padding); - $result['alg'] = $alg; - $result['key'] = base64url_encode($k,true); - $result['iv'] = base64url_encode($i,true); - return $result; + $result['alg'] = $alg; + $result['key'] = base64url_encode($k, true); + $result['iv'] = base64url_encode($i, true); + return $result; } else { - $x = [ 'data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data ]; + $x = ['data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data]; call_hooks('crypto_encapsulate', $x); return $x['result']; } } - public static function unencapsulate($data,$prvkey) { + public static function unencapsulate($data, $prvkey) { - if (! (is_array($data) && array_key_exists('encrypted',$data) && array_key_exists('alg',$data) && $data['alg'])) { + if (!(is_array($data) && array_key_exists('encrypted', $data) && array_key_exists('alg', $data) && $data['alg'])) { logger('not encrypted'); return $data; @@ -170,7 +170,7 @@ class Crypto { $alg_base = $data['alg']; $padding = OPENSSL_PKCS1_PADDING; - $exts = explode('.',$data['alg']); + $exts = explode('.', $data['alg']); if (count($exts) > 1) { switch ($exts[1]) { case 'oaep': @@ -192,13 +192,13 @@ class Crypto { } if ($method) { - openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey,$padding); - openssl_private_decrypt(base64url_decode($data['iv']), $i,$prvkey,$padding); - return openssl_decrypt(base64url_decode($data['data']),$method[1],substr($k,0,$method[2]),OPENSSL_RAW_DATA,substr($i,0,$method[3])); + openssl_private_decrypt(base64url_decode($data['key']), $k, $prvkey, $padding); + openssl_private_decrypt(base64url_decode($data['iv']), $i, $prvkey, $padding); + return openssl_decrypt(base64url_decode($data['data']), $method[1], substr($k, 0, $method[2]), OPENSSL_RAW_DATA, substr($i, 0, $method[3])); } else { - $x = [ 'data' => $data, 'prvkey' => $prvkey, 'alg' => $data['alg'], 'result' => $data ]; - call_hooks('crypto_unencapsulate',$x); + $x = ['data' => $data, 'prvkey' => $prvkey, 'alg' => $data['alg'], 'result' => $data]; + call_hooks('crypto_unencapsulate', $x); return $x['result']; } } -- cgit v1.2.3 From e6450acc0355c9a8384882e08ccb9aafabe7030d Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 9 Feb 2021 19:13:32 +0000 Subject: version --- boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot.php b/boot.php index 0c70f0229..d491a989c 100644 --- a/boot.php +++ b/boot.php @@ -52,7 +52,7 @@ require_once('include/attach.php'); require_once('include/bbcode.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '5.3.3' ); +define ( 'STD_VERSION', '5.3.4' ); define ( 'ZOT_REVISION', '6.0' ); define ( 'DB_UPDATE_VERSION', 1241 ); -- cgit v1.2.3 From 391db616297fab5db1531d31e36884af245ae9ac Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 10 Feb 2021 19:27:00 +0000 Subject: revert z_(un)obscure() until (un)obscurify() will be implemented and a update will take care of the data in db --- include/crypto.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/crypto.php b/include/crypto.php index d91d3749c..b09356fc7 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -462,12 +462,12 @@ function convert_salmon_key($key) { function z_obscure($s) { - return json_encode(Crypto::encapsulate($s,get_config('system','pubkey'))); + return json_encode(crypto_encapsulate($s,get_config('system','pubkey'))); } function z_unobscure($s) { if(strpos($s,"{\"") !== 0) return $s; - return Crypto::unencapsulate(json_decode($s,true),get_config('system','prvkey')); + return crypto_unencapsulate(json_decode($s,true),get_config('system','prvkey')); } -- cgit v1.2.3 From 464a0634d63707412afb7df9b2fe0d2e23258753 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 10 Feb 2021 20:40:28 +0000 Subject: use (un)obscurify --- Zotlabs/Module/Pconfig.php | 70 +++++++++++++++++++++++----------------------- include/crypto.php | 2 -- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/Zotlabs/Module/Pconfig.php b/Zotlabs/Module/Pconfig.php index b2b5d4386..8a71ab974 100644 --- a/Zotlabs/Module/Pconfig.php +++ b/Zotlabs/Module/Pconfig.php @@ -8,16 +8,16 @@ use Zotlabs\Lib\Libsync; class Pconfig extends \Zotlabs\Web\Controller { function post() { - + if(! local_channel()) return; - - + + if($_SESSION['delegate']) return; - + check_form_security_token_redirectOnErr('/pconfig', 'pconfig'); - + $cat = trim(escape_tags($_POST['cat'])); $k = trim(escape_tags($_POST['k'])); $v = trim($_POST['v']); @@ -27,16 +27,16 @@ class Pconfig extends \Zotlabs\Web\Controller { if (preg_match('|^a:[0-9]+:{.*}$|s',$v) || preg_match('|O:8:"stdClass":[0-9]+:{.*}$|s',$v)) { return; } - + if(in_array(argv(2),$this->disallowed_pconfig())) { notice( t('This setting requires special processing and editing has been blocked.') . EOL); return; } - + if(strpos($k,'password') !== false) { - $v = z_obscure($v); + $v = obscurify($v); } - + set_pconfig(local_channel(),$cat,$k,$v); Libsync::build_sync_packet(); @@ -46,24 +46,24 @@ class Pconfig extends \Zotlabs\Web\Controller { goaway(z_root() . '/pconfig/' . $cat . '/' . $k); } - - + + function get() { - + if(! local_channel()) { return login(); } - + $content = '

      ' . t('Configuration Editor') . '

      '; $content .= '
      ' . t('Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature.') . '
      ' . EOL . EOL; - - - + + + if(argc() == 3) { $content .= 'pconfig[' . local_channel() . ']' . EOL; $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . ']' . EOL . EOL; $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . '][' . escape_tags(argv(2)) . '] = ' . get_pconfig(local_channel(),escape_tags(argv(1)),escape_tags(argv(2))) . EOL; - + if(in_array(argv(2),$this->disallowed_pconfig())) { notice( t('This setting requires special processing and editing has been blocked.') . EOL); return $content; @@ -71,8 +71,8 @@ class Pconfig extends \Zotlabs\Web\Controller { else $content .= $this->pconfig_form(escape_tags(argv(1)),escape_tags(argv(2))); } - - + + if(argc() == 2) { $content .= 'pconfig[' . local_channel() . ']' . EOL; load_pconfig(local_channel(),escape_tags(argv(1))); @@ -80,9 +80,9 @@ class Pconfig extends \Zotlabs\Web\Controller { $content .= 'pconfig[' . local_channel() . '][' . escape_tags(argv(1)) . '][' . $k . '] = ' . escape_tags($x) . EOL; } } - + if(argc() == 1) { - + $r = q("select * from pconfig where uid = " . local_channel()); if($r) { foreach($r as $rr) { @@ -91,33 +91,33 @@ class Pconfig extends \Zotlabs\Web\Controller { } } return $content; - + } - - + + function pconfig_form($cat,$k) { - + $o = '
      '; $o .= ''; - + $v = get_pconfig(local_channel(),$cat,$k); - if(strpos($k,'password') !== false) - $v = z_unobscure($v); - + if(strpos($k,'password') !== false) + $v = unobscurify($v); + $o .= ''; $o .= ''; - + if(strpos($v,"\n")) $o .= ''; else $o .= ''; - - $o .= EOL . EOL; + + $o .= EOL . EOL; $o .= ''; $o .= '
      '; - + return $o; - + } @@ -127,5 +127,5 @@ class Pconfig extends \Zotlabs\Web\Controller { 'permissions_role' ); } - + } diff --git a/include/crypto.php b/include/crypto.php index b09356fc7..40e68a4e7 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -1,7 +1,5 @@ Date: Wed, 10 Feb 2021 20:59:30 +0000 Subject: update 1242 --- Zotlabs/Update/_1242.php | 21 +++++++++++++++++++++ boot.php | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Zotlabs/Update/_1242.php diff --git a/Zotlabs/Update/_1242.php b/Zotlabs/Update/_1242.php new file mode 100644 index 000000000..c2c9a66d0 --- /dev/null +++ b/Zotlabs/Update/_1242.php @@ -0,0 +1,21 @@ + Date: Thu, 11 Feb 2021 11:13:06 +0000 Subject: actor will be stored in the next step decode_note() --- Zotlabs/Lib/Activity.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index abb28fc64..3965aa1e3 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2094,6 +2094,7 @@ class Activity { $obj_actor = ((isset($act->obj['actor'])) ? $act->obj['actor'] : $act->get_actor('attributedTo', $act->obj)); // ensure we store the original actor + self::actor_store($obj_actor['id'], $obj_actor); $mention = self::get_actor_bbmention($obj_actor['id']); @@ -2817,9 +2818,6 @@ class Activity { logger('not a valid activity'); break; } - if (is_array($a->actor) && array_key_exists('id', $a->actor)) { - Activity::actor_store($a->actor['id'], $a->actor); - } $item = Activity::decode_note($a); -- cgit v1.2.3 From d3e70acacd9576fbe1aaa3e12a64966eb79fac29 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 11 Feb 2021 21:00:10 +0000 Subject: make encode_item_collection() deal with extra query args --- Zotlabs/Lib/Activity.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 3965aa1e3..780dd26b4 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -275,17 +275,27 @@ class Activity { $numpages = $total / App::$pager['itemspage']; $lastpage = (($numpages > intval($numpages)) ? intval($numpages) + 1 : $numpages); + $url_parts = parse_url($id); - $stripped = preg_replace('/([&|\?]page=[0-9]*)/', '', $id); - $stripped = rtrim($stripped, '/'); + $ret['partOf'] = z_root() . '/' . $url_parts['path']; - $ret['partOf'] = z_root() . '/' . $stripped; + $extra_query_args = ''; + $query_args = null; + if(isset($url_parts['query'])) { + parse_str($url_parts['query'], $query_args); + } + + if(is_array($query_args)) { + unset($query_args['page']); + foreach($query_args as $k => $v) + $extra_query_args .= '&' . urlencode($k) . '=' . urlencode($v); + } if (App::$pager['page'] < $lastpage) { - $ret['next'] = z_root() . '/' . $stripped . '?page=' . (intval(App::$pager['page']) + 1); + $ret['next'] = z_root() . '/' . $url_parts['path'] . '?page=' . (intval(App::$pager['page']) + 1) . $extra_query_args; } if (App::$pager['page'] > 1) { - $ret['prev'] = z_root() . '/' . $stripped . '?page=' . (intval(App::$pager['page']) - 1); + $ret['prev'] = z_root() . '/' . $url_parts['path'] . '?page=' . (intval(App::$pager['page']) - 1) . $extra_query_args; } } else { @@ -1489,6 +1499,7 @@ class Activity { } static function actor_store($url, $person_obj) { + hz_syslog('actor_store: ' . $url); if (!is_array($person_obj)) return; -- cgit v1.2.3 From 8054d7ad6662d3c39ad4b75aaed892960e40153f Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 11 Feb 2021 21:01:16 +0000 Subject: remove logging --- Zotlabs/Lib/Activity.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 780dd26b4..d4d1cd28c 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1499,7 +1499,6 @@ class Activity { } static function actor_store($url, $person_obj) { - hz_syslog('actor_store: ' . $url); if (!is_array($person_obj)) return; -- cgit v1.2.3 From 0ffb09aa40d4bb2e05dd3b1ae306cb924f86ea12 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 11 Feb 2021 21:05:45 +0000 Subject: onepoll: add date_begin argument to poll url --- Zotlabs/Daemon/Onepoll.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php index 568745608..2200276e0 100644 --- a/Zotlabs/Daemon/Onepoll.php +++ b/Zotlabs/Daemon/Onepoll.php @@ -136,6 +136,7 @@ class Onepoll { if ($url) { logger('fetching outbox'); + $url = $url . '?date_begin=' . urlencode($last_update); $obj = new ASCollection($url, $importer, 0, $max); $messages = $obj->get(); if ($messages) { -- cgit v1.2.3 From 22e0175ab739bf72ce73f1682068179e3dbea79c Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 13 Feb 2021 19:30:15 +0000 Subject: fix ping_site() issue --- Zotlabs/Lib/Libzot.php | 5 ++ Zotlabs/Module/Home.php | 118 +++++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index c2e388264..45d536638 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -3140,6 +3140,11 @@ class Libzot { ); } + // this site obviously isn't dead because they are trying to communicate with us. + q("update site set site_dead = 0 where site_dead = 1 and site_url = '%s' ", + dbesc($hub['hubloc_url']) + ); + return $hub['hubloc_url']; } diff --git a/Zotlabs/Module/Home.php b/Zotlabs/Module/Home.php index 7f2d6424d..2bfab986f 100644 --- a/Zotlabs/Module/Home.php +++ b/Zotlabs/Module/Home.php @@ -1,100 +1,114 @@ 'application/x-zot+json', 'Digest' => HTTPSig::generate_digest_header($ret)]; + $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; + $h = HTTPSig::create_sig($headers, $key, z_root()); + HTTPSig::set_headers($h); + + echo $ret; + killme(); + } $splash = ((argc() > 1 && argv(1) === 'splash') ? true : false); - - $channel = \App::get_channel(); - if(local_channel() && $channel && $channel['xchan_url'] && ! $splash) { + + $channel = App::get_channel(); + if (local_channel() && $channel && $channel['xchan_url'] && !$splash) { $dest = (($ret['startpage']) ? $ret['startpage'] : ''); - if(! $dest) - $dest = get_config('system','startpage'); - if(! $dest) + if (!$dest) + $dest = get_config('system', 'startpage'); + if (!$dest) $dest = z_root() . '/network'; - + goaway($dest); } - if(remote_channel() && (! $splash) && $_SESSION['atoken']) { + if (remote_channel() && (!$splash) && $_SESSION['atoken']) { $r = q("select * from atoken where atoken_id = %d", intval($_SESSION['atoken']) ); - if($r) { + if ($r) { $x = channelx_by_n($r[0]['atoken_uid']); - if($x) { + if ($x) { goaway(z_root() . '/channel/' . $x['channel_address']); } } - } + } - - if(get_account_id() && ! $splash) { + if (get_account_id() && !$splash) { goaway(z_root() . '/new_channel'); } - + } - - + function get($update = 0, $load = false) { - + $o = ''; - - - if(x($_SESSION,'theme')) + + if (x($_SESSION, 'theme')) unset($_SESSION['theme']); - if(x($_SESSION,'mobile_theme')) + if (x($_SESSION, 'mobile_theme')) unset($_SESSION['mobile_theme']); - + $splash = ((argc() > 1 && argv(1) === 'splash') ? true : false); - - call_hooks('home_content',$o); - if($o) + + call_hooks('home_content', $o); + if ($o) return $o; - - $frontpage = get_config('system','frontpage'); - if($frontpage) { - if(strpos($frontpage,'include:') !== false) { - $file = trim(str_replace('include:' , '', $frontpage)); - if(file_exists($file)) { - \App::$page['template'] = 'full'; - \App::$page['title'] = t('$Projectname'); - $o .= file_get_contents($file); + + $frontpage = get_config('system', 'frontpage'); + if ($frontpage) { + if (strpos($frontpage, 'include:') !== false) { + $file = trim(str_replace('include:', '', $frontpage)); + if (file_exists($file)) { + App::$page['template'] = 'full'; + App::$page['title'] = t('$Projectname'); + $o .= file_get_contents($file); return $o; } } - if(strpos($frontpage,'http') !== 0) + if (strpos($frontpage, 'http') !== 0) $frontpage = z_root() . '/' . $frontpage; - if(intval(get_config('system','mirror_frontpage'))) { + if (intval(get_config('system', 'mirror_frontpage'))) { $o = '' . t('$Projectname') . ''; echo $o; killme(); } goaway($frontpage); } - - - $sitename = get_config('system','sitename'); - if($sitename) - $o .= '

      ' . sprintf( t('Welcome to %s') ,$sitename) . '

      '; - - $loginbox = get_config('system','login_on_homepage'); - if(intval($loginbox) || $loginbox === false) + + $sitename = get_config('system', 'sitename'); + if ($sitename) + $o .= '

      ' . sprintf(t('Welcome to %s'), $sitename) . '

      '; + + $loginbox = get_config('system', 'login_on_homepage'); + if (intval($loginbox) || $loginbox === false) $o .= login(true); - + return $o; - + } - + } -- cgit v1.2.3 From 5e8e6dc45805b8eac7a8fb690f04c007ebd573d9 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 13 Feb 2021 20:20:46 +0000 Subject: changelog --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 2c384ca97..1e4b28abf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +Hubzilla 5.2.2 (2021-02-13) + - Fix issue with ping_site() + + Hubzilla 5.2.1 (2021-01-16) - Fix attach_upgrade() to catch all broken entries in attach - Fix collect_recipients() public policy filter for zot6 -- cgit v1.2.3 From d6b259bb270d57d6b9bca818d9771b8b25b8221d Mon Sep 17 00:00:00 2001 From: "M. Dent" Date: Sun, 14 Feb 2021 17:16:25 +0100 Subject: FIX: Display urls won't show to permitted remote observers --- Zotlabs/Module/Display.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 04aeb6d5c..2aa4f6548 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -269,17 +269,20 @@ class Display extends \Zotlabs\Web\Controller { $sysid = 0; $r = q("SELECT item.id as item_id from item - WHERE mid = '%s' + WHERE ( (mid = '%s' AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' AND item.deny_gid = '' AND item_private = 0 ) and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) - OR uid = %d ) - $sql_extra ) + OR uid = %d ) ) ) OR + (mid = '%s' $sql_extra ) ) $item_normal limit 1", dbesc($target_item['parent_mid']), - intval($sysid) + intval($sysid), + dbesc($target_item['parent_mid']) ); + + } } -- cgit v1.2.3 From ed993920015cfae7f0e939b1733ab125c85e1dda Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 15 Feb 2021 08:20:42 +0000 Subject: move substitution of new lines with
      to the end of bbcode(). This will fix issue #1512. --- include/bbcode.php | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/include/bbcode.php b/include/bbcode.php index e1a5c7e47..dfc64f814 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -1153,23 +1153,8 @@ function bbcode($Text, $options = []) { $Text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fixtable_lf',$Text); - // Convert new line chars to html
      tags - - // nlbr seems to be hopelessly messed up - // $Text = nl2br($Text); - - // We'll emulate it. - - $Text = str_replace("\r\n", "\n", $Text); - $Text = str_replace(array("\r", "\n"), array('
      ', '
      '), $Text); - - if ($preserve_nl) - $Text = str_replace(array("\n", "\r"), array('', ''), $Text); - - $Text = str_replace(array("\t", " "), array("    ", "  "), $Text); - // Check for [code] text if (strpos($Text,'[code]') !== false) { $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $Text); @@ -1633,6 +1618,19 @@ function bbcode($Text, $options = []) { $Text = bb_replace_images($Text, $saved_images); + // Convert new line chars to html
      tags + + // nlbr seems to be hopelessly messed up + // $Text = nl2br($Text); + + // We'll emulate it. + + $Text = str_replace("\r\n", "\n", $Text); + $Text = str_replace(array("\r", "\n"), array('
      ', '
      '), $Text); + + if ($preserve_nl) + $Text = str_replace(array("\n", "\r"), array('', ''), $Text); + call_hooks('bbcode', $Text); return $Text; -- cgit v1.2.3 From d72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 15 Feb 2021 10:15:57 +0000 Subject: fix preview generating duplicate IDs --- include/conversation.php | 2 +- view/tpl/conv_item.tpl | 2 +- view/tpl/threaded_conversation.tpl | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/conversation.php b/include/conversation.php index 08d16a413..1b0db52e3 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -923,7 +923,6 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa // logger('nouveau: ' . print_r($threads,true)); - $o .= replace_macros($page_template, array( '$baseurl' => z_root(), '$photo_item' => $content_html, @@ -935,6 +934,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa '$wait' => t('Loading...'), '$conversation_tools' => t('Conversation Tools'), '$dropping' => ($page_dropping?t('Delete Selected Items'):False), + '$preview' => $preview )); return $o; diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl index b021509d3..361392796 100644 --- a/view/tpl/conv_item.tpl +++ b/view/tpl/conv_item.tpl @@ -141,7 +141,7 @@ {{$item.conlabels.1}} - + {{$item.conlabels.2}} diff --git a/view/tpl/threaded_conversation.tpl b/view/tpl/threaded_conversation.tpl index 5bc7d8386..6e773088e 100644 --- a/view/tpl/threaded_conversation.tpl +++ b/view/tpl/threaded_conversation.tpl @@ -1,9 +1,13 @@ +{{if !$preview }}
      +{{/if}} {{if $photo_item}} {{$photo_item}} {{/if}} {{foreach $threads as $thread_item}} {{include file="{{$thread_item.template}}" item=$thread_item}} {{/foreach}} +{{if !$preview }}
      +{{/if}} -- cgit v1.2.3 From ba29a6ce4d37b9466d25632975562a5ffe2d5f13 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 15 Feb 2021 18:23:26 +0000 Subject: composer update smarty --- composer.lock | 14 +++++++------- include/zot.php | 7 ++++++- vendor/composer/InstalledVersions.php | 10 +++++----- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + vendor/composer/installed.json | 20 +++++++++++++------- vendor/composer/installed.php | 10 +++++----- vendor/smarty/smarty/CHANGELOG.md | 17 +++++++++++++++++ vendor/smarty/smarty/LICENSE | 2 +- vendor/smarty/smarty/composer.json | 2 +- .../smarty/lexer/smarty_internal_templateparser.y | 10 ++++++++-- vendor/smarty/smarty/libs/Smarty.class.php | 7 +++---- vendor/smarty/smarty/libs/SmartyBC.class.php | 2 +- ...rty_internal_compile_private_special_variable.php | 4 ++-- .../smarty_internal_config_file_compiler.php | 4 ++-- .../libs/sysplugins/smarty_internal_errorhandler.php | 2 +- .../smarty_internal_parsetree_template.php | 16 ++++++++-------- 17 files changed, 82 insertions(+), 47 deletions(-) diff --git a/composer.lock b/composer.lock index fcd90e12d..b78c8cf41 100644 --- a/composer.lock +++ b/composer.lock @@ -1406,23 +1406,23 @@ }, { "name": "smarty/smarty", - "version": "v3.1.36", + "version": "v3.1.38", "source": { "type": "git", "url": "https://github.com/smarty-php/smarty.git", - "reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451" + "reference": "63b3c0aed0f614880cda21a5c08c606e97b489bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smarty-php/smarty/zipball/fd148f7ade295014fff77f89ee3d5b20d9d55451", - "reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451", + "url": "https://api.github.com/repos/smarty-php/smarty/zipball/63b3c0aed0f614880cda21a5c08c606e97b489bb", + "reference": "63b3c0aed0f614880cda21a5c08c606e97b489bb", "shasum": "" }, "require": { "php": ">=5.2" }, "require-dev": { - "phpunit/phpunit": "6.4.1", + "phpunit/phpunit": "^7.5 || ^6.5 || ^5.7 || ^4.8", "smarty/smarty-lexer": "^3.1" }, "type": "library", @@ -1463,9 +1463,9 @@ "forum": "http://www.smarty.net/forums/", "irc": "irc://irc.freenode.org/smarty", "issues": "https://github.com/smarty-php/smarty/issues", - "source": "https://github.com/smarty-php/smarty/tree/v3.1.36" + "source": "https://github.com/smarty-php/smarty/tree/v3.1.38" }, - "time": "2020-04-14T14:44:26+00:00" + "time": "2021-01-08T14:05:42+00:00" }, { "name": "symfony/polyfill-ctype", diff --git a/include/zot.php b/include/zot.php index f96792656..82efc8596 100644 --- a/include/zot.php +++ b/include/zot.php @@ -470,8 +470,13 @@ function zot_refresh($them, $channel = null, $force = false) { 'alg' => $j['permissions']['alg'] ], $channel['channel_prvkey']); - if($permissions) + if($permissions) { + if(is_array($permissions)) + hz_syslog(print_r($permissions,true)); + $permissions = json_decode($permissions,true); + + } logger('decrypted permissions: ' . print_r($permissions,true), LOGGER_DATA, LOG_DEBUG); } else diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 875700f7a..0052c5978 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', + 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -232,12 +232,12 @@ private static $installed = array ( ), 'smarty/smarty' => array ( - 'pretty_version' => 'v3.1.36', - 'version' => '3.1.36.0', + 'pretty_version' => 'v3.1.38', + 'version' => '3.1.38.0', 'aliases' => array ( ), - 'reference' => 'fd148f7ade295014fff77f89ee3d5b20d9d55451', + 'reference' => '63b3c0aed0f614880cda21a5c08c606e97b489bb', ), 'symfony/polyfill-ctype' => array ( @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', + 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', ), ), ); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 5f6184ca5..c76365e9d 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -1653,6 +1653,7 @@ return array( 'Zotlabs\\Update\\_1239' => $baseDir . '/Zotlabs/Update/_1239.php', 'Zotlabs\\Update\\_1240' => $baseDir . '/Zotlabs/Update/_1240.php', 'Zotlabs\\Update\\_1241' => $baseDir . '/Zotlabs/Update/_1241.php', + 'Zotlabs\\Update\\_1242' => $baseDir . '/Zotlabs/Update/_1242.php', 'Zotlabs\\Web\\Controller' => $baseDir . '/Zotlabs/Web/Controller.php', 'Zotlabs\\Web\\HTTPHeaders' => $baseDir . '/Zotlabs/Web/HTTPHeaders.php', 'Zotlabs\\Web\\HTTPSig' => $baseDir . '/Zotlabs/Web/HTTPSig.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index e61c918c6..96763f684 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -1843,6 +1843,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Zotlabs\\Update\\_1239' => __DIR__ . '/../..' . '/Zotlabs/Update/_1239.php', 'Zotlabs\\Update\\_1240' => __DIR__ . '/../..' . '/Zotlabs/Update/_1240.php', 'Zotlabs\\Update\\_1241' => __DIR__ . '/../..' . '/Zotlabs/Update/_1241.php', + 'Zotlabs\\Update\\_1242' => __DIR__ . '/../..' . '/Zotlabs/Update/_1242.php', 'Zotlabs\\Web\\Controller' => __DIR__ . '/../..' . '/Zotlabs/Web/Controller.php', 'Zotlabs\\Web\\HTTPHeaders' => __DIR__ . '/../..' . '/Zotlabs/Web/HTTPHeaders.php', 'Zotlabs\\Web\\HTTPSig' => __DIR__ . '/../..' . '/Zotlabs/Web/HTTPSig.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 3fa4a6fac..9bb39f769 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1432,27 +1432,27 @@ }, { "name": "smarty/smarty", - "version": "v3.1.36", - "version_normalized": "3.1.36.0", + "version": "v3.1.38", + "version_normalized": "3.1.38.0", "source": { "type": "git", "url": "https://github.com/smarty-php/smarty.git", - "reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451" + "reference": "63b3c0aed0f614880cda21a5c08c606e97b489bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smarty-php/smarty/zipball/fd148f7ade295014fff77f89ee3d5b20d9d55451", - "reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451", + "url": "https://api.github.com/repos/smarty-php/smarty/zipball/63b3c0aed0f614880cda21a5c08c606e97b489bb", + "reference": "63b3c0aed0f614880cda21a5c08c606e97b489bb", "shasum": "" }, "require": { "php": ">=5.2" }, "require-dev": { - "phpunit/phpunit": "6.4.1", + "phpunit/phpunit": "^7.5 || ^6.5 || ^5.7 || ^4.8", "smarty/smarty-lexer": "^3.1" }, - "time": "2020-04-14T14:44:26+00:00", + "time": "2021-01-08T14:05:42+00:00", "type": "library", "extra": { "branch-alias": { @@ -1488,6 +1488,12 @@ "keywords": [ "templating" ], + "support": { + "forum": "http://www.smarty.net/forums/", + "irc": "irc://irc.freenode.org/smarty", + "issues": "https://github.com/smarty-php/smarty/issues", + "source": "https://github.com/smarty-php/smarty/tree/v3.1.38" + }, "install-path": "../smarty/smarty" }, { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 7c1ac62d8..003ab8b0f 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', + 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -209,12 +209,12 @@ ), 'smarty/smarty' => array ( - 'pretty_version' => 'v3.1.36', - 'version' => '3.1.36.0', + 'pretty_version' => 'v3.1.38', + 'version' => '3.1.38.0', 'aliases' => array ( ), - 'reference' => 'fd148f7ade295014fff77f89ee3d5b20d9d55451', + 'reference' => '63b3c0aed0f614880cda21a5c08c606e97b489bb', ), 'symfony/polyfill-ctype' => array ( @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '5aee2f172ecdf58e13dd328c787fd199c48d24c5', + 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', ), ), ); diff --git a/vendor/smarty/smarty/CHANGELOG.md b/vendor/smarty/smarty/CHANGELOG.md index 7eb151bf8..06b898223 100644 --- a/vendor/smarty/smarty/CHANGELOG.md +++ b/vendor/smarty/smarty/CHANGELOG.md @@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.1.38] - 2021-01-08 + +### Fixed +- Smarty::SMARTY_VERSION wasn't updated https://github.com/smarty-php/smarty/issues/628 + +## [3.1.37] - 2021-01-07 + +### Changed +- Changed error handlers and handling of undefined constants for php8-compatibility (set $errcontext argument optional) https://github.com/smarty-php/smarty/issues/605 +- Changed expected error levels in unit tests for php8-compatibility +- Travis unit tests now run for all php versions >= 5.3, including php8 +- Travis runs on Xenial where possible + +### Fixed +- PHP5.3 compatibility fixes +- Brought lexer source functionally up-to-date with compiled version + ## [3.1.36] - 2020-04-14 ### Fixed diff --git a/vendor/smarty/smarty/LICENSE b/vendor/smarty/smarty/LICENSE index fb8ca6c6f..595e5993d 100644 --- a/vendor/smarty/smarty/LICENSE +++ b/vendor/smarty/smarty/LICENSE @@ -3,7 +3,7 @@ Smarty: the PHP compiling template engine 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. + version 3.0 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 diff --git a/vendor/smarty/smarty/composer.json b/vendor/smarty/smarty/composer.json index 889cb9444..183f9f240 100644 --- a/vendor/smarty/smarty/composer.json +++ b/vendor/smarty/smarty/composer.json @@ -40,7 +40,7 @@ } }, "require-dev": { - "phpunit/phpunit": "6.4.1", + "phpunit/phpunit": "^7.5 || ^6.5 || ^5.7 || ^4.8", "smarty/smarty-lexer": "^3.1" } } diff --git a/vendor/smarty/smarty/lexer/smarty_internal_templateparser.y b/vendor/smarty/smarty/lexer/smarty_internal_templateparser.y index b8c00e5d9..c6890642f 100644 --- a/vendor/smarty/smarty/lexer/smarty_internal_templateparser.y +++ b/vendor/smarty/smarty/lexer/smarty_internal_templateparser.y @@ -249,7 +249,13 @@ template ::= template PHP(B). { // template text template ::= template TEXT(B). { - $this->current_buffer->append_subtree($this, $this->compiler->processText(B)); + $text = $this->yystack[ $this->yyidx + 0 ]->minor; + + if ((string)$text == '') { + $this->current_buffer->append_subtree($this, null); + } + + $this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip)); } // strip on template ::= template STRIPON. { @@ -308,7 +314,7 @@ smartytag(A)::= SIMPLETAG(B). { $tag = trim(substr(B, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength())); if ($tag == 'strip') { $this->strip = true; - A = null;; + A = null; } else { if (defined($tag)) { if ($this->security) { diff --git a/vendor/smarty/smarty/libs/Smarty.class.php b/vendor/smarty/smarty/libs/Smarty.class.php index 9e0ca7670..6564be6d2 100644 --- a/vendor/smarty/smarty/libs/Smarty.class.php +++ b/vendor/smarty/smarty/libs/Smarty.class.php @@ -6,7 +6,7 @@ * 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. + * version 3.0 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 @@ -27,7 +27,6 @@ * @author Uwe Tews * @author Rodney Rehm * @package Smarty - * @version 3.1.34-dev */ /** * set SMARTY_DIR to absolute path to Smarty library files. @@ -112,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.36'; + const SMARTY_VERSION = '3.1.38'; /** * define variable scopes */ @@ -800,7 +799,7 @@ class Smarty extends Smarty_Internal_TemplateBase * @param mixed $index index of directory to get, null to get all * @param bool $isConfig true for config_dir * - * @return array list of template directories, or directory of $index + * @return array|string list of template directories, or directory of $index */ public function getTemplateDir($index = null, $isConfig = false) { diff --git a/vendor/smarty/smarty/libs/SmartyBC.class.php b/vendor/smarty/smarty/libs/SmartyBC.class.php index 836f98153..0550e46dc 100644 --- a/vendor/smarty/smarty/libs/SmartyBC.class.php +++ b/vendor/smarty/smarty/libs/SmartyBC.class.php @@ -6,7 +6,7 @@ * 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. + * version 3.0 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 diff --git a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php index b317c9f33..de7d4a224 100644 --- a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php +++ b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php @@ -94,9 +94,9 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C break; } if (strpos($_index[ 1 ], '$') === false && strpos($_index[ 1 ], '\'') === false) { - return "@constant('{$_index[1]}')"; + return "(defined('{$_index[1]}') ? constant('{$_index[1]}') : null)"; } else { - return "@constant({$_index[1]})"; + return "(defined({$_index[1]}) ? constant({$_index[1]}) : null)"; } // no break case 'config': diff --git a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php index a842fa8f3..90c5dcefa 100644 --- a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php +++ b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php @@ -115,7 +115,7 @@ class Smarty_Internal_Config_File_Compiler $this->smarty->_debug->start_compile($this->template); } // init the lexer/parser to compile the config file - /* @var Smarty_Internal_ConfigFileLexer $this ->lex */ + /* @var Smarty_Internal_ConfigFileLexer $this->lex */ $this->lex = new $this->lexer_class( str_replace( array( @@ -127,7 +127,7 @@ class Smarty_Internal_Config_File_Compiler ) . "\n", $this ); - /* @var Smarty_Internal_ConfigFileParser $this ->parser */ + /* @var Smarty_Internal_ConfigFileParser $this->parser */ $this->parser = new $this->parser_class($this->lex, $this); if (function_exists('mb_internal_encoding') && function_exists('ini_get') diff --git a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_errorhandler.php b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_errorhandler.php index 0ba00659d..56dca18fa 100644 --- a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_errorhandler.php +++ b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_errorhandler.php @@ -65,7 +65,7 @@ class Smarty_Internal_ErrorHandler * * @return bool */ - public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) + public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext = array()) { $_is_muted_directory = false; // add the SMARTY_DIR to the list of muted directories diff --git a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_parsetree_template.php b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_parsetree_template.php index 477232ef8..ab4c3ec3b 100644 --- a/vendor/smarty/smarty/libs/sysplugins/smarty_internal_parsetree_template.php +++ b/vendor/smarty/smarty/libs/sysplugins/smarty_internal_parsetree_template.php @@ -127,12 +127,12 @@ class Smarty_Internal_ParseTree_Template extends Smarty_Internal_ParseTree } private function getChunkedSubtrees() { - $chunks = []; + $chunks = array(); $currentMode = null; - $currentChunk = []; + $currentChunk = array(); for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) { - if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, ['textstripped', 'text', 'tag'])) { + if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, array('textstripped', 'text', 'tag'))) { continue; } @@ -150,19 +150,19 @@ class Smarty_Internal_ParseTree_Template extends Smarty_Internal_ParseTree if ($newMode == $currentMode) { $currentChunk[] = $this->subtrees[ $key ]; } else { - $chunks[] = [ + $chunks[] = array( 'mode' => $currentMode, 'subtrees' => $currentChunk - ]; + ); $currentMode = $newMode; - $currentChunk = [$this->subtrees[ $key ]]; + $currentChunk = array($this->subtrees[ $key ]); } } if ($currentMode && $currentChunk) { - $chunks[] = [ + $chunks[] = array( 'mode' => $currentMode, 'subtrees' => $currentChunk - ]; + ); } return $chunks; } -- cgit v1.2.3 From 4171a0136ad4f14bdd5d7621b4c7decd3e942c8c Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 15 Feb 2021 18:25:04 +0000 Subject: revert debug code --- include/zot.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/zot.php b/include/zot.php index 82efc8596..e68da4209 100644 --- a/include/zot.php +++ b/include/zot.php @@ -471,11 +471,7 @@ function zot_refresh($them, $channel = null, $force = false) { ], $channel['channel_prvkey']); if($permissions) { - if(is_array($permissions)) - hz_syslog(print_r($permissions,true)); - $permissions = json_decode($permissions,true); - } logger('decrypted permissions: ' . print_r($permissions,true), LOGGER_DATA, LOG_DEBUG); } -- cgit v1.2.3 From 18c8f1b903e90ca3632520b90d21ec3770bf6e0b Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 15 Feb 2021 18:27:20 +0000 Subject: composer update brick/math --- composer.lock | 18 +- vendor/brick/math/CHANGELOG.md | 403 +++++++++++++++++++++ vendor/brick/math/SECURITY.md | 3 +- vendor/brick/math/composer.json | 6 +- vendor/brick/math/psalm-baseline.xml | 40 -- vendor/brick/math/psalm.xml | 56 --- vendor/brick/math/random-tests.php | 26 +- vendor/brick/math/src/BigDecimal.php | 22 +- vendor/brick/math/src/BigInteger.php | 25 +- vendor/brick/math/src/BigNumber.php | 42 ++- vendor/brick/math/src/BigRational.php | 16 +- vendor/brick/math/src/Internal/Calculator.php | 5 +- .../src/Internal/Calculator/BcMathCalculator.php | 26 +- .../src/Internal/Calculator/NativeCalculator.php | 28 +- vendor/composer/InstalledVersions.php | 10 +- vendor/composer/installed.json | 20 +- vendor/composer/installed.php | 10 +- 17 files changed, 579 insertions(+), 177 deletions(-) create mode 100644 vendor/brick/math/CHANGELOG.md delete mode 100644 vendor/brick/math/psalm-baseline.xml delete mode 100644 vendor/brick/math/psalm.xml diff --git a/composer.lock b/composer.lock index b78c8cf41..66d92e9d4 100644 --- a/composer.lock +++ b/composer.lock @@ -73,26 +73,26 @@ }, { "name": "brick/math", - "version": "0.9.1", + "version": "0.9.2", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "283a40c901101e66de7061bd359252c013dcc43c" + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/283a40c901101e66de7061bd359252c013dcc43c", - "reference": "283a40c901101e66de7061bd359252c013dcc43c", + "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^7.5.15|^8.5", - "vimeo/psalm": "^3.5" + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.3.2" }, "type": "library", "autoload": { @@ -117,7 +117,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/master" + "source": "https://github.com/brick/math/tree/0.9.2" }, "funding": [ { @@ -125,7 +125,7 @@ "type": "tidelift" } ], - "time": "2020-08-18T23:57:15+00:00" + "time": "2021-01-20T22:51:39+00:00" }, { "name": "bshaffer/oauth2-server-php", diff --git a/vendor/brick/math/CHANGELOG.md b/vendor/brick/math/CHANGELOG.md new file mode 100644 index 000000000..61ab09d18 --- /dev/null +++ b/vendor/brick/math/CHANGELOG.md @@ -0,0 +1,403 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19 + +✨ New features + +- `BigInteger::not()` returns the bitwise `NOT` value + +🐛 **Bug fixes** + +- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers +- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available + +## [0.9.0](https://github.com/brick/math/releases/tag/0.9.0) - 2020-08-18 + +👌 **Improvements** + +- `BigNumber::of()` now accepts `.123` and `123.` formats, both of which return a `BigDecimal` + +💥 **Breaking changes** + +- Deprecated method `BigInteger::powerMod()` has been removed - use `modPow()` instead +- Deprecated method `BigInteger::parse()` has been removed - use `fromBase()` instead + +## [0.8.9](https://github.com/brick/math/releases/tag/0.8.9) - 2020-01-08 + +⚡️ **Performance improvements** + +A few additional optimizations in `BigInteger` and `BigDecimal` when one of the operands can be returned as is. Thanks to @tomtomsen in #24. + +## [0.8.8](https://github.com/brick/math/releases/tag/0.8.8) - 2019-04-25 + +🐛 **Bug fixes** + +- `BigInteger::toBase()` could return an empty string for zero values (BCMath & Native calculators only, GMP calculator unaffected) + +✨ **New features** + +- `BigInteger::toArbitraryBase()` converts a number to an arbitrary base, using a custom alphabet +- `BigInteger::fromArbitraryBase()` converts a string in an arbitrary base, using a custom alphabet, back to a number + +These methods can be used as the foundation to convert strings between different bases/alphabets, using BigInteger as an intermediate representation. + +💩 **Deprecations** + +- `BigInteger::parse()` is now deprecated in favour of `fromBase()` + +`BigInteger::fromBase()` works the same way as `parse()`, with 2 minor differences: + +- the `$base` parameter is required, it does not default to `10` +- it throws a `NumberFormatException` instead of an `InvalidArgumentException` when the number is malformed + +## [0.8.7](https://github.com/brick/math/releases/tag/0.8.7) - 2019-04-20 + +**Improvements** + +- Safer conversion from `float` when using custom locales +- **Much faster** `NativeCalculator` implementation 🚀 + +You can expect **at least a 3x performance improvement** for common arithmetic operations when using the library on systems without GMP or BCMath; it gets exponentially faster on multiplications with a high number of digits. This is due to calculations now being performed on whole blocks of digits (the block size depending on the platform, 32-bit or 64-bit) instead of digit-by-digit as before. + +## [0.8.6](https://github.com/brick/math/releases/tag/0.8.6) - 2019-04-11 + +**New method** + +`BigNumber::sum()` returns the sum of one or more numbers. + +## [0.8.5](https://github.com/brick/math/releases/tag/0.8.5) - 2019-02-12 + +**Bug fix**: `of()` factory methods could fail when passing a `float` in environments using a `LC_NUMERIC` locale with a decimal separator other than `'.'` (#20). + +Thanks @manowark 👍 + +## [0.8.4](https://github.com/brick/math/releases/tag/0.8.4) - 2018-12-07 + +**New method** + +`BigDecimal::sqrt()` calculates the square root of a decimal number, to a given scale. + +## [0.8.3](https://github.com/brick/math/releases/tag/0.8.3) - 2018-12-06 + +**New method** + +`BigInteger::sqrt()` calculates the square root of a number (thanks @peter279k). + +**New exception** + +`NegativeNumberException` is thrown when calling `sqrt()` on a negative number. + +## [0.8.2](https://github.com/brick/math/releases/tag/0.8.2) - 2018-11-08 + +**Performance update** + +- Further improvement of `toInt()` performance +- `NativeCalculator` can now perform some multiplications more efficiently + +## [0.8.17](https://github.com/brick/math/releases/tag/0.8.17) - 2020-08-19 + +🐛 **Bug fix** + +- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers +- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available + +## [0.8.16](https://github.com/brick/math/releases/tag/0.8.16) - 2020-08-18 + +🚑 **Critical fix** + +- This version reintroduces the deprecated `BigInteger::parse()` method, that has been removed by mistake in version `0.8.9` and should have lasted for the whole `0.8` release cycle. + +✨ **New features** + +- `BigInteger::modInverse()` calculates a modular multiplicative inverse +- `BigInteger::fromBytes()` creates a `BigInteger` from a byte string +- `BigInteger::toBytes()` converts a `BigInteger` to a byte string +- `BigInteger::randomBits()` creates a pseudo-random `BigInteger` of a given bit length +- `BigInteger::randomRange()` creates a pseudo-random `BigInteger` between two bounds + +💩 **Deprecations** + +- `BigInteger::powerMod()` is now deprecated in favour of `modPow()` + +## [0.8.15](https://github.com/brick/math/releases/tag/0.8.15) - 2020-04-15 + +🐛 **Fixes** + +- added missing `ext-json` requirement, due to `BigNumber` implementing `JsonSerializable` + +⚡️ **Optimizations** + +- additional optimization in `BigInteger::remainder()` + +## [0.8.14](https://github.com/brick/math/releases/tag/0.8.14) - 2020-02-18 + +✨ **New features** + +- `BigInteger::getLowestSetBit()` returns the index of the rightmost one bit + +## [0.8.13](https://github.com/brick/math/releases/tag/0.8.13) - 2020-02-16 + +✨ **New features** + +- `BigInteger::isEven()` tests whether the number is even +- `BigInteger::isOdd()` tests whether the number is odd +- `BigInteger::testBit()` tests if a bit is set +- `BigInteger::getBitLength()` returns the number of bits in the minimal representation of the number + +## [0.8.12](https://github.com/brick/math/releases/tag/0.8.12) - 2020-02-03 + +🛠️ **Maintenance release** + +Classes are now annotated for better static analysis with [psalm](https://psalm.dev/). + +This is a maintenance release: no bug fixes, no new features, no breaking changes. + +## [0.8.11](https://github.com/brick/math/releases/tag/0.8.11) - 2020-01-23 + +✨ **New feature** + +`BigInteger::powerMod()` performs a power-with-modulo operation. Useful for crypto. + +## [0.8.10](https://github.com/brick/math/releases/tag/0.8.10) - 2020-01-21 + +✨ **New feature** + +`BigInteger::mod()` returns the **modulo** of two numbers. The *modulo* differs from the *remainder* when the signs of the operands are different. + +## [0.8.1](https://github.com/brick/math/releases/tag/0.8.1) - 2018-11-07 + +Performance optimization of `toInt()` methods. + +## [0.8.0](https://github.com/brick/math/releases/tag/0.8.0) - 2018-10-13 + +**Breaking changes** + +The following deprecated methods have been removed. Use the new method name instead: + +| Method removed | Replacement method | +| --- | --- | +| `BigDecimal::getIntegral()` | `BigDecimal::getIntegralPart()` | +| `BigDecimal::getFraction()` | `BigDecimal::getFractionalPart()` | + +--- + +**New features** + +`BigInteger` has been augmented with 5 new methods for bitwise operations: + +| New method | Description | +| --- | --- | +| `and()` | performs a bitwise `AND` operation on two numbers | +| `or()` | performs a bitwise `OR` operation on two numbers | +| `xor()` | performs a bitwise `XOR` operation on two numbers | +| `shiftedLeft()` | returns the number shifted left by a number of bits | +| `shiftedRight()` | returns the number shifted right by a number of bits | + +Thanks to @DASPRiD 👍 + +## [0.7.3](https://github.com/brick/math/releases/tag/0.7.3) - 2018-08-20 + +**New method:** `BigDecimal::hasNonZeroFractionalPart()` + +**Renamed/deprecated methods:** + +- `BigDecimal::getIntegral()` has been renamed to `getIntegralPart()` and is now deprecated +- `BigDecimal::getFraction()` has been renamed to `getFractionalPart()` and is now deprecated + +## [0.7.2](https://github.com/brick/math/releases/tag/0.7.2) - 2018-07-21 + +**Performance update** + +`BigInteger::parse()` and `toBase()` now use GMP's built-in base conversion features when available. + +## [0.7.1](https://github.com/brick/math/releases/tag/0.7.1) - 2018-03-01 + +This is a maintenance release, no code has been changed. + +- When installed with `--no-dev`, the autoloader does not autoload tests anymore +- Tests and other files unnecessary for production are excluded from the dist package + +This will help make installations more compact. + +## [0.7.0](https://github.com/brick/math/releases/tag/0.7.0) - 2017-10-02 + +Methods renamed: + +- `BigNumber:sign()` has been renamed to `getSign()` +- `BigDecimal::unscaledValue()` has been renamed to `getUnscaledValue()` +- `BigDecimal::scale()` has been renamed to `getScale()` +- `BigDecimal::integral()` has been renamed to `getIntegral()` +- `BigDecimal::fraction()` has been renamed to `getFraction()` +- `BigRational::numerator()` has been renamed to `getNumerator()` +- `BigRational::denominator()` has been renamed to `getDenominator()` + +Classes renamed: + +- `ArithmeticException` has been renamed to `MathException` + +## [0.6.2](https://github.com/brick/math/releases/tag/0.6.2) - 2017-10-02 + +The base class for all exceptions is now `MathException`. +`ArithmeticException` has been deprecated, and will be removed in 0.7.0. + +## [0.6.1](https://github.com/brick/math/releases/tag/0.6.1) - 2017-10-02 + +A number of methods have been renamed: + +- `BigNumber:sign()` is deprecated; use `getSign()` instead +- `BigDecimal::unscaledValue()` is deprecated; use `getUnscaledValue()` instead +- `BigDecimal::scale()` is deprecated; use `getScale()` instead +- `BigDecimal::integral()` is deprecated; use `getIntegral()` instead +- `BigDecimal::fraction()` is deprecated; use `getFraction()` instead +- `BigRational::numerator()` is deprecated; use `getNumerator()` instead +- `BigRational::denominator()` is deprecated; use `getDenominator()` instead + +The old methods will be removed in version 0.7.0. + +## [0.6.0](https://github.com/brick/math/releases/tag/0.6.0) - 2017-08-25 + +- Minimum PHP version is now [7.1](https://gophp71.org/); for PHP 5.6 and PHP 7.0 support, use version `0.5` +- Deprecated method `BigDecimal::withScale()` has been removed; use `toScale()` instead +- Method `BigNumber::toInteger()` has been renamed to `toInt()` + +## [0.5.4](https://github.com/brick/math/releases/tag/0.5.4) - 2016-10-17 + +`BigNumber` classes now implement [JsonSerializable](http://php.net/manual/en/class.jsonserializable.php). +The JSON output is always a string. + +## [0.5.3](https://github.com/brick/math/releases/tag/0.5.3) - 2016-03-31 + +This is a bugfix release. Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. + +## [0.5.2](https://github.com/brick/math/releases/tag/0.5.2) - 2015-08-06 + +The `$scale` parameter of `BigDecimal::dividedBy()` is now optional again. + +## [0.5.1](https://github.com/brick/math/releases/tag/0.5.1) - 2015-07-05 + +**New method: `BigNumber::toScale()`** + +This allows to convert any `BigNumber` to a `BigDecimal` with a given scale, using rounding if necessary. + +## [0.5.0](https://github.com/brick/math/releases/tag/0.5.0) - 2015-07-04 + +**New features** +- Common `BigNumber` interface for all classes, with the following methods: + - `sign()` and derived methods (`isZero()`, `isPositive()`, ...) + - `compareTo()` and derived methods (`isEqualTo()`, `isGreaterThan()`, ...) that work across different `BigNumber` types + - `toBigInteger()`, `toBigDecimal()`, `toBigRational`() conversion methods + - `toInteger()` and `toFloat()` conversion methods to native types +- Unified `of()` behaviour: every class now accepts any type of number, provided that it can be safely converted to the current type +- New method: `BigDecimal::exactlyDividedBy()`; this method automatically computes the scale of the result, provided that the division yields a finite number of digits +- New methods: `BigRational::quotient()` and `remainder()` +- Fine-grained exceptions: `DivisionByZeroException`, `RoundingNecessaryException`, `NumberFormatException` +- Factory methods `zero()`, `one()` and `ten()` available in all classes +- Rounding mode reintroduced in `BigInteger::dividedBy()` + +This release also comes with many performance improvements. + +--- + +**Breaking changes** +- `BigInteger`: + - `getSign()` is renamed to `sign()` + - `toString()` is renamed to `toBase()` + - `BigInteger::dividedBy()` now throws an exception by default if the remainder is not zero; use `quotient()` to get the previous behaviour +- `BigDecimal`: + - `getSign()` is renamed to `sign()` + - `getUnscaledValue()` is renamed to `unscaledValue()` + - `getScale()` is renamed to `scale()` + - `getIntegral()` is renamed to `integral()` + - `getFraction()` is renamed to `fraction()` + - `divideAndRemainder()` is renamed to `quotientAndRemainder()` + - `dividedBy()` now takes a **mandatory** `$scale` parameter **before** the rounding mode + - `toBigInteger()` does not accept a `$roundingMode` parameter any more + - `toBigRational()` does not simplify the fraction any more; explicitly add `->simplified()` to get the previous behaviour +- `BigRational`: + - `getSign()` is renamed to `sign()` + - `getNumerator()` is renamed to `numerator()` + - `getDenominator()` is renamed to `denominator()` + - `of()` is renamed to `nd()`, while `parse()` is renamed to `of()` +- Miscellaneous: + - `ArithmeticException` is moved to an `Exception\` sub-namespace + - `of()` factory methods now throw `NumberFormatException` instead of `InvalidArgumentException` + +## [0.4.3](https://github.com/brick/math/releases/tag/0.4.3) - 2016-03-31 + +Backport of two bug fixes from the 0.5 branch: +- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected +- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. + +## [0.4.2](https://github.com/brick/math/releases/tag/0.4.2) - 2015-06-16 + +New method: `BigDecimal::stripTrailingZeros()` + +## [0.4.1](https://github.com/brick/math/releases/tag/0.4.1) - 2015-06-12 + +Introducing a `BigRational` class, to perform calculations on fractions of any size. + +## [0.4.0](https://github.com/brick/math/releases/tag/0.4.0) - 2015-06-12 + +Rounding modes have been removed from `BigInteger`, and are now a concept specific to `BigDecimal`. + +`BigInteger::dividedBy()` now always returns the quotient of the division. + +## [0.3.5](https://github.com/brick/math/releases/tag/0.3.5) - 2016-03-31 + +Backport of two bug fixes from the 0.5 branch: + +- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected +- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. + +## [0.3.4](https://github.com/brick/math/releases/tag/0.3.4) - 2015-06-11 + +New methods: +- `BigInteger::remainder()` returns the remainder of a division only +- `BigInteger::gcd()` returns the greatest common divisor of two numbers + +## [0.3.3](https://github.com/brick/math/releases/tag/0.3.3) - 2015-06-07 + +Fix `toString()` not handling negative numbers. + +## [0.3.2](https://github.com/brick/math/releases/tag/0.3.2) - 2015-06-07 + +`BigInteger` and `BigDecimal` now have a `getSign()` method that returns: +- `-1` if the number is negative +- `0` if the number is zero +- `1` if the number is positive + +## [0.3.1](https://github.com/brick/math/releases/tag/0.3.1) - 2015-06-05 + +Minor performance improvements + +## [0.3.0](https://github.com/brick/math/releases/tag/0.3.0) - 2015-06-04 + +The `$roundingMode` and `$scale` parameters have been swapped in `BigDecimal::dividedBy()`. + +## [0.2.2](https://github.com/brick/math/releases/tag/0.2.2) - 2015-06-04 + +Stronger immutability guarantee for `BigInteger` and `BigDecimal`. + +So far, it would have been possible to break immutability of these classes by calling the `unserialize()` internal function. This release fixes that. + +## [0.2.1](https://github.com/brick/math/releases/tag/0.2.1) - 2015-06-02 + +Added `BigDecimal::divideAndRemainder()` + +## [0.2.0](https://github.com/brick/math/releases/tag/0.2.0) - 2015-05-22 + +- `min()` and `max()` do not accept an `array` any more, but a variable number of parameters +- **minimum PHP version is now 5.6** +- continuous integration with PHP 7 + +## [0.1.1](https://github.com/brick/math/releases/tag/0.1.1) - 2014-09-01 + +- Added `BigInteger::power()` +- Added HHVM support + +## [0.1.0](https://github.com/brick/math/releases/tag/0.1.0) - 2014-08-31 + +First beta release. + diff --git a/vendor/brick/math/SECURITY.md b/vendor/brick/math/SECURITY.md index 6bdc74f0d..cc8289bb5 100644 --- a/vendor/brick/math/SECURITY.md +++ b/vendor/brick/math/SECURITY.md @@ -2,10 +2,11 @@ ## Supported Versions -Only the latest release stream is supported. +Only the last two release streams are supported. | Version | Supported | | ------- | ------------------ | +| 0.9.x | :white_check_mark: | | 0.8.x | :white_check_mark: | | < 0.8 | :x: | diff --git a/vendor/brick/math/composer.json b/vendor/brick/math/composer.json index d347b6bde..c89955d12 100644 --- a/vendor/brick/math/composer.json +++ b/vendor/brick/math/composer.json @@ -14,13 +14,13 @@ ], "license": "MIT", "require": { - "php": "^7.1|^8.0", + "php": "^7.1 || ^8.0", "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "^7.5.15|^8.5", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", "php-coveralls/php-coveralls": "^2.2", - "vimeo/psalm": "^3.5" + "vimeo/psalm": "4.3.2" }, "autoload": { "psr-4": { diff --git a/vendor/brick/math/psalm-baseline.xml b/vendor/brick/math/psalm-baseline.xml deleted file mode 100644 index fe05b998c..000000000 --- a/vendor/brick/math/psalm-baseline.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - string - string - string - - - [$q, $r] - - - array - - - \bcdiv($a, $b, 0) - \bcmod($a, $b) - \bcpowmod($base, $exp, $mod, 0) - - - - - $a - $a - $a - $b - $blockA - $blockA - - - $i - $i - $i - $j - - - $e / 2 - - - diff --git a/vendor/brick/math/psalm.xml b/vendor/brick/math/psalm.xml deleted file mode 100644 index 123263ef4..000000000 --- a/vendor/brick/math/psalm.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/brick/math/random-tests.php b/vendor/brick/math/random-tests.php index c59529f6f..d9053fc11 100644 --- a/vendor/brick/math/random-tests.php +++ b/vendor/brick/math/random-tests.php @@ -64,7 +64,7 @@ use Brick\Math\Internal\Calculator; * @param string $a The left operand. * @param string $b The right operand. */ - function runTests(string $a, string $b) : void + private function runTests(string $a, string $b) : void { $this->test("$a + $b", function(Calculator $c) use($a, $b) { return $c->add($a, $b); @@ -123,8 +123,11 @@ use Brick\Math\Internal\Calculator; */ private function test(string $test, Closure $callback) : void { - static $counter = 0; - static $lastOutputTime = null; + static $testCounter = 0; + static $lastOutputTime = 0.0; + static $currentSecond = 0; + static $currentSecondTestCounter = 0; + static $testsPerSecond = 0; $gmpResult = $callback($this->gmp); $bcmathResult = $callback($this->bcmath); @@ -138,13 +141,20 @@ use Brick\Math\Internal\Calculator; self::failure('GMP', 'Native', $test); } - $counter++; + $testCounter++; + $currentSecondTestCounter++; + $time = microtime(true); + $second = (int) $time; - if ($lastOutputTime === null) { - $lastOutputTime = $time; - } elseif ($time - $lastOutputTime >= 0.1) { - echo "\r", number_format($counter); + if ($second !== $currentSecond) { + $currentSecond = $second; + $testsPerSecond = $currentSecondTestCounter; + $currentSecondTestCounter = 0; + } + + if ($time - $lastOutputTime >= 0.1) { + echo "\r", number_format($testCounter), ' (', number_format($testsPerSecond) . ' / s)'; $lastOutputTime = $time; } } diff --git a/vendor/brick/math/src/BigDecimal.php b/vendor/brick/math/src/BigDecimal.php index 287177140..7707b166e 100644 --- a/vendor/brick/math/src/BigDecimal.php +++ b/vendor/brick/math/src/BigDecimal.php @@ -96,7 +96,10 @@ final class BigDecimal extends BigNumber */ public static function zero() : BigDecimal { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigDecimal|null $zero + */ static $zero; if ($zero === null) { @@ -115,7 +118,10 @@ final class BigDecimal extends BigNumber */ public static function one() : BigDecimal { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigDecimal|null $one + */ static $one; if ($one === null) { @@ -134,7 +140,10 @@ final class BigDecimal extends BigNumber */ public static function ten() : BigDecimal { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigDecimal|null $ten + */ static $ten; if ($ten === null) { @@ -677,11 +686,7 @@ final class BigDecimal extends BigNumber */ public function toBigInteger() : BigInteger { - if ($this->scale === 0) { - $zeroScaleDecimal = $this; - } else { - $zeroScaleDecimal = $this->dividedBy(1, 0); - } + $zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0); return BigInteger::create($zeroScaleDecimal->value); } @@ -763,6 +768,7 @@ final class BigDecimal extends BigNumber * This method is only here to implement interface Serializable and cannot be accessed directly. * * @internal + * @psalm-suppress RedundantPropertyInitializationCheck * * @param string $value * diff --git a/vendor/brick/math/src/BigInteger.php b/vendor/brick/math/src/BigInteger.php index cee3ce82b..0dcc8f3b3 100644 --- a/vendor/brick/math/src/BigInteger.php +++ b/vendor/brick/math/src/BigInteger.php @@ -217,6 +217,8 @@ final class BigInteger extends BigNumber * * Using the default random bytes generator, this method is suitable for cryptographic use. * + * @psalm-param callable(int): string $randomBytesGenerator + * * @param int $numBits The number of bits. * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a * string of random bytes of the given length. Defaults to the @@ -256,6 +258,8 @@ final class BigInteger extends BigNumber * * Using the default random bytes generator, this method is suitable for cryptographic use. * + * @psalm-param (callable(int): string)|null $randomBytesGenerator + * * @param BigNumber|int|float|string $min The lower bound. Must be convertible to a BigInteger. * @param BigNumber|int|float|string $max The upper bound. Must be convertible to a BigInteger. * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, @@ -300,7 +304,10 @@ final class BigInteger extends BigNumber */ public static function zero() : BigInteger { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigInteger|null $zero + */ static $zero; if ($zero === null) { @@ -319,7 +326,10 @@ final class BigInteger extends BigNumber */ public static function one() : BigInteger { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigInteger|null $one + */ static $one; if ($one === null) { @@ -338,7 +348,10 @@ final class BigInteger extends BigNumber */ public static function ten() : BigInteger { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigInteger|null $ten + */ static $ten; if ($ten === null) { @@ -1070,7 +1083,10 @@ final class BigInteger extends BigNumber if ($signed) { if ($this->isNegative()) { - $hex = \bin2hex(~\hex2bin($hex)); + $bin = \hex2bin($hex); + assert($bin !== false); + + $hex = \bin2hex(~$bin); $hex = self::fromBase($hex, 16)->plus(1)->toBase(16); $hexLength = \strlen($hex); @@ -1116,6 +1132,7 @@ final class BigInteger extends BigNumber * This method is only here to implement interface Serializable and cannot be accessed directly. * * @internal + * @psalm-suppress RedundantPropertyInitializationCheck * * @param string $value * diff --git a/vendor/brick/math/src/BigNumber.php b/vendor/brick/math/src/BigNumber.php index 59fcc7ce5..38c8c554e 100644 --- a/vendor/brick/math/src/BigNumber.php +++ b/vendor/brick/math/src/BigNumber.php @@ -67,13 +67,10 @@ abstract class BigNumber implements \Serializable, \JsonSerializable return new BigInteger((string) $value); } - if (\is_float($value)) { - $value = self::floatToString($value); - } else { - $value = (string) $value; - } + /** @psalm-suppress RedundantCastGivenDocblockType We cannot trust the untyped $value here! */ + $value = \is_float($value) ? self::floatToString($value) : (string) $value; - $throw = function() use ($value) : void { + $throw = static function() use ($value) : void { throw new NumberFormatException(\sprintf( 'The given value "%s" does not represent a valid number.', $value @@ -84,7 +81,7 @@ abstract class BigNumber implements \Serializable, \JsonSerializable $throw(); } - $getMatch = function(string $value) use ($matches) : ?string { + $getMatch = static function(string $value) use ($matches) : ?string { return isset($matches[$value]) && $matches[$value] !== '' ? $matches[$value] : null; }; @@ -93,7 +90,13 @@ abstract class BigNumber implements \Serializable, \JsonSerializable $denominator = $getMatch('denominator'); if ($numerator !== null) { - $numerator = self::cleanUp($sign . $numerator); + assert($denominator !== null); + + if ($sign !== null) { + $numerator = $sign . $numerator; + } + + $numerator = self::cleanUp($numerator); $denominator = self::cleanUp($denominator); if ($denominator === '0') { @@ -121,14 +124,14 @@ abstract class BigNumber implements \Serializable, \JsonSerializable } if ($point !== null || $exponent !== null) { - $fractional = $fractional ?? ''; - $exponent = $exponent !== null ? (int) $exponent : 0; + $fractional = ($fractional ?? ''); + $exponent = ($exponent !== null) ? (int) $exponent : 0; if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) { throw new NumberFormatException('Exponent too large.'); } - $unscaledValue = self::cleanUp($sign . $integral . $fractional); + $unscaledValue = self::cleanUp(($sign ?? ''). $integral . $fractional); $scale = \strlen($fractional) - $exponent; @@ -142,7 +145,7 @@ abstract class BigNumber implements \Serializable, \JsonSerializable return new BigDecimal($unscaledValue, $scale); } - $integral = self::cleanUp($sign . $integral); + $integral = self::cleanUp(($sign ?? '') . $integral); return new BigInteger($integral); } @@ -181,10 +184,11 @@ abstract class BigNumber implements \Serializable, \JsonSerializable * @return static * * @psalm-pure + * @psalm-suppress TooManyArguments + * @psalm-suppress UnsafeInstantiation */ protected static function create(... $args) : BigNumber { - /** @psalm-suppress TooManyArguments */ return new static(... $args); } @@ -199,6 +203,8 @@ abstract class BigNumber implements \Serializable, \JsonSerializable * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * + * @psalm-suppress LessSpecificReturnStatement + * @psalm-suppress MoreSpecificReturnType * @psalm-pure */ public static function min(...$values) : BigNumber @@ -231,6 +237,8 @@ abstract class BigNumber implements \Serializable, \JsonSerializable * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * + * @psalm-suppress LessSpecificReturnStatement + * @psalm-suppress MoreSpecificReturnType * @psalm-pure */ public static function max(...$values) : BigNumber @@ -263,6 +271,8 @@ abstract class BigNumber implements \Serializable, \JsonSerializable * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * + * @psalm-suppress LessSpecificReturnStatement + * @psalm-suppress MoreSpecificReturnType * @psalm-pure */ public static function sum(...$values) : BigNumber @@ -273,11 +283,7 @@ abstract class BigNumber implements \Serializable, \JsonSerializable foreach ($values as $value) { $value = static::of($value); - if ($sum === null) { - $sum = $value; - } else { - $sum = self::add($sum, $value); - } + $sum = $sum === null ? $value : self::add($sum, $value); } if ($sum === null) { diff --git a/vendor/brick/math/src/BigRational.php b/vendor/brick/math/src/BigRational.php index ff035c5c0..7fbabd7f1 100644 --- a/vendor/brick/math/src/BigRational.php +++ b/vendor/brick/math/src/BigRational.php @@ -108,7 +108,10 @@ final class BigRational extends BigNumber */ public static function zero() : BigRational { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigRational|null $zero + */ static $zero; if ($zero === null) { @@ -127,7 +130,10 @@ final class BigRational extends BigNumber */ public static function one() : BigRational { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigRational|null $one + */ static $one; if ($one === null) { @@ -146,7 +152,10 @@ final class BigRational extends BigNumber */ public static function ten() : BigRational { - /** @psalm-suppress ImpureStaticVariable */ + /** + * @psalm-suppress ImpureStaticVariable + * @var BigRational|null $ten + */ static $ten; if ($ten === null) { @@ -458,6 +467,7 @@ final class BigRational extends BigNumber * This method is only here to implement interface Serializable and cannot be accessed directly. * * @internal + * @psalm-suppress RedundantPropertyInitializationCheck * * @param string $value * diff --git a/vendor/brick/math/src/Internal/Calculator.php b/vendor/brick/math/src/Internal/Calculator.php index 44795acbb..99b478193 100644 --- a/vendor/brick/math/src/Internal/Calculator.php +++ b/vendor/brick/math/src/Internal/Calculator.php @@ -677,6 +677,9 @@ abstract class Calculator } /** + * @psalm-suppress InvalidOperand + * @see https://github.com/vimeo/psalm/issues/4456 + * * @param string $number A positive, binary number. * * @return string @@ -685,7 +688,7 @@ abstract class Calculator { $xor = \str_repeat("\xff", \strlen($number)); - $number = $number ^ $xor; + $number ^= $xor; for ($i = \strlen($number) - 1; $i >= 0; $i--) { $byte = \ord($number[$i]); diff --git a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php index c087245bd..6632b378a 100644 --- a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php @@ -41,6 +41,9 @@ class BcMathCalculator extends Calculator /** * {@inheritdoc} + * + * @psalm-suppress InvalidNullableReturnType + * @psalm-suppress NullableReturnStatement */ public function divQ(string $a, string $b) : string { @@ -49,9 +52,16 @@ class BcMathCalculator extends Calculator /** * {@inheritdoc} + * + * @psalm-suppress InvalidNullableReturnType + * @psalm-suppress NullableReturnStatement */ public function divR(string $a, string $b) : string { + if (version_compare(PHP_VERSION, '7.2') >= 0) { + return \bcmod($a, $b, 0); + } + return \bcmod($a, $b); } @@ -61,7 +71,15 @@ class BcMathCalculator extends Calculator public function divQR(string $a, string $b) : array { $q = \bcdiv($a, $b, 0); - $r = \bcmod($a, $b); + + if (version_compare(PHP_VERSION, '7.2') >= 0) { + $r = \bcmod($a, $b, 0); + } else { + $r = \bcmod($a, $b); + } + + assert($q !== null); + assert($r !== null); return [$q, $r]; } @@ -76,6 +94,9 @@ class BcMathCalculator extends Calculator /** * {@inheritdoc} + * + * @psalm-suppress InvalidNullableReturnType + * @psalm-suppress NullableReturnStatement */ public function modPow(string $base, string $exp, string $mod) : string { @@ -84,6 +105,9 @@ class BcMathCalculator extends Calculator /** * {@inheritDoc} + * + * @psalm-suppress NullableReturnStatement + * @psalm-suppress InvalidNullableReturnType */ public function sqrt(string $n) : string { diff --git a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php index d248e6849..a5f8a9b48 100644 --- a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php @@ -53,6 +53,10 @@ class NativeCalculator extends Calculator */ public function add(string $a, string $b) : string { + /** + * @psalm-var numeric-string $a + * @psalm-var numeric-string $b + */ $result = $a + $b; if (is_int($result)) { @@ -69,11 +73,7 @@ class NativeCalculator extends Calculator [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); - if ($aNeg === $bNeg) { - $result = $this->doAdd($aDig, $bDig); - } else { - $result = $this->doSub($aDig, $bDig); - } + $result = $aNeg === $bNeg ? $this->doAdd($aDig, $bDig) : $this->doSub($aDig, $bDig); if ($aNeg) { $result = $this->neg($result); @@ -95,6 +95,10 @@ class NativeCalculator extends Calculator */ public function mul(string $a, string $b) : string { + /** + * @psalm-var numeric-string $a + * @psalm-var numeric-string $b + */ $result = $a * $b; if (is_int($result)) { @@ -169,9 +173,11 @@ class NativeCalculator extends Calculator return [$this->neg($a), '0']; } + /** @psalm-var numeric-string $a */ $na = $a * 1; // cast to number if (is_int($na)) { + /** @psalm-var numeric-string $b */ $nb = $b * 1; if (is_int($nb)) { @@ -221,6 +227,8 @@ class NativeCalculator extends Calculator $e -= $odd; $aa = $this->mul($a, $a); + + /** @psalm-suppress PossiblyInvalidArgument We're sure that $e / 2 is an int now */ $result = $this->pow($aa, $e / 2); if ($odd === 1) { @@ -316,10 +324,14 @@ class NativeCalculator extends Calculator if ($i < 0) { $blockLength += $i; + /** @psalm-suppress LoopInvalidation */ $i = 0; } + /** @psalm-var numeric-string $blockA */ $blockA = \substr($a, $i, $blockLength); + + /** @psalm-var numeric-string $blockB */ $blockB = \substr($b, $i, $blockLength); $sum = (string) ($blockA + $blockB + $carry); @@ -386,10 +398,14 @@ class NativeCalculator extends Calculator if ($i < 0) { $blockLength += $i; + /** @psalm-suppress LoopInvalidation */ $i = 0; } + /** @psalm-var numeric-string $blockA */ $blockA = \substr($a, $i, $blockLength); + + /** @psalm-var numeric-string $blockB */ $blockB = \substr($b, $i, $blockLength); $sum = $blockA - $blockB - $carry; @@ -450,6 +466,7 @@ class NativeCalculator extends Calculator if ($i < 0) { $blockALength += $i; + /** @psalm-suppress LoopInvalidation */ $i = 0; } @@ -463,6 +480,7 @@ class NativeCalculator extends Calculator if ($j < 0) { $blockBLength += $j; + /** @psalm-suppress LoopInvalidation */ $j = 0; } diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 0052c5978..c0e4918cd 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', + 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -45,12 +45,12 @@ private static $installed = array ( ), 'brick/math' => array ( - 'pretty_version' => '0.9.1', - 'version' => '0.9.1.0', + 'pretty_version' => '0.9.2', + 'version' => '0.9.2.0', 'aliases' => array ( ), - 'reference' => '283a40c901101e66de7061bd359252c013dcc43c', + 'reference' => 'dff976c2f3487d42c1db75a3b180e2b9f0e72ce0', ), 'bshaffer/oauth2-server-php' => array ( @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', + 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', ), ), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 9bb39f769..e67369af2 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -66,29 +66,29 @@ }, { "name": "brick/math", - "version": "0.9.1", - "version_normalized": "0.9.1.0", + "version": "0.9.2", + "version_normalized": "0.9.2.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "283a40c901101e66de7061bd359252c013dcc43c" + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/283a40c901101e66de7061bd359252c013dcc43c", - "reference": "283a40c901101e66de7061bd359252c013dcc43c", + "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^7.5.15|^8.5", - "vimeo/psalm": "^3.5" + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.3.2" }, - "time": "2020-08-18T23:57:15+00:00", + "time": "2021-01-20T22:51:39+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -113,7 +113,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/master" + "source": "https://github.com/brick/math/tree/0.9.2" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 003ab8b0f..12ef7bdcc 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', + 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -22,12 +22,12 @@ ), 'brick/math' => array ( - 'pretty_version' => '0.9.1', - 'version' => '0.9.1.0', + 'pretty_version' => '0.9.2', + 'version' => '0.9.2.0', 'aliases' => array ( ), - 'reference' => '283a40c901101e66de7061bd359252c013dcc43c', + 'reference' => 'dff976c2f3487d42c1db75a3b180e2b9f0e72ce0', ), 'bshaffer/oauth2-server-php' => array ( @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => 'd72a096fa55e1b0c9d78a0fc0fa5a0b72988c69d', + 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', ), ), ); -- cgit v1.2.3 From 02401ea9fd5d53f590305c0f9834685cda58723d Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 15 Feb 2021 18:29:24 +0000 Subject: composer update ramsey/collection --- composer.lock | 24 +- vendor/composer/InstalledVersions.php | 10 +- vendor/composer/installed.json | 26 +- vendor/composer/installed.php | 10 +- vendor/ramsey/collection/CHANGELOG.md | 120 --------- vendor/ramsey/collection/README.md | 150 +++--------- vendor/ramsey/collection/SECURITY.md | 113 +++++++++ vendor/ramsey/collection/composer.json | 10 +- vendor/ramsey/collection/src/AbstractArray.php | 37 ++- .../ramsey/collection/src/AbstractCollection.php | 268 +++++++-------------- vendor/ramsey/collection/src/AbstractSet.php | 24 +- vendor/ramsey/collection/src/ArrayInterface.php | 4 +- vendor/ramsey/collection/src/Collection.php | 8 +- .../ramsey/collection/src/CollectionInterface.php | 53 ++-- vendor/ramsey/collection/src/DoubleEndedQueue.php | 141 ++--------- .../collection/src/DoubleEndedQueueInterface.php | 31 ++- vendor/ramsey/collection/src/GenericArray.php | 2 + vendor/ramsey/collection/src/Map/AbstractMap.php | 96 ++------ .../ramsey/collection/src/Map/AbstractTypedMap.php | 22 +- .../collection/src/Map/AssociativeArrayMap.php | 3 + vendor/ramsey/collection/src/Map/MapInterface.php | 55 +++-- .../collection/src/Map/NamedParameterMap.php | 34 +-- vendor/ramsey/collection/src/Map/TypedMap.php | 15 +- .../collection/src/Map/TypedMapInterface.php | 3 + vendor/ramsey/collection/src/Queue.php | 95 ++------ vendor/ramsey/collection/src/QueueInterface.php | 17 +- vendor/ramsey/collection/src/Set.php | 8 +- .../collection/src/Tool/ValueExtractorTrait.php | 8 +- .../collection/src/Tool/ValueToStringTrait.php | 7 +- 29 files changed, 521 insertions(+), 873 deletions(-) delete mode 100644 vendor/ramsey/collection/CHANGELOG.md create mode 100644 vendor/ramsey/collection/SECURITY.md diff --git a/composer.lock b/composer.lock index 66d92e9d4..293d93d3d 100644 --- a/composer.lock +++ b/composer.lock @@ -722,16 +722,16 @@ }, { "name": "ramsey/collection", - "version": "1.1.1", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1" + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/24d93aefb2cd786b7edd9f45b554aea20b28b9b1", - "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1", + "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", "shasum": "" }, "require": { @@ -741,19 +741,19 @@ "captainhook/captainhook": "^5.3", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "ergebnis/composer-normalize": "^2.6", - "fzaninotto/faker": "^1.5", + "fakerphp/faker": "^1.5", "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.6", + "jangregor/phpstan-prophecy": "^0.8", "mockery/mockery": "^1.3", "phpstan/extension-installer": "^1", "phpstan/phpstan": "^0.12.32", "phpstan/phpstan-mockery": "^0.12.5", "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5", + "phpunit/phpunit": "^8.5 || ^9", "psy/psysh": "^0.10.4", "slevomat/coding-standard": "^6.3", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^3.12.2" + "vimeo/psalm": "^4.4" }, "type": "library", "autoload": { @@ -783,15 +783,19 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.1.1" + "source": "https://github.com/ramsey/collection/tree/1.1.3" }, "funding": [ { "url": "https://github.com/ramsey", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" } ], - "time": "2020-09-10T20:58:17+00:00" + "time": "2021-01-21T17:40:04+00:00" }, { "name": "ramsey/uuid", diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index c0e4918cd..fd17711f2 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', + 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -144,12 +144,12 @@ private static $installed = array ( ), 'ramsey/collection' => array ( - 'pretty_version' => '1.1.1', - 'version' => '1.1.1.0', + 'pretty_version' => '1.1.3', + 'version' => '1.1.3.0', 'aliases' => array ( ), - 'reference' => '24d93aefb2cd786b7edd9f45b554aea20b28b9b1', + 'reference' => '28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1', ), 'ramsey/uuid' => array ( @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', + 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', ), ), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index e67369af2..91d335ca0 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -721,17 +721,17 @@ }, { "name": "ramsey/collection", - "version": "1.1.1", - "version_normalized": "1.1.1.0", + "version": "1.1.3", + "version_normalized": "1.1.3.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1" + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/24d93aefb2cd786b7edd9f45b554aea20b28b9b1", - "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1", + "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", "shasum": "" }, "require": { @@ -741,21 +741,21 @@ "captainhook/captainhook": "^5.3", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "ergebnis/composer-normalize": "^2.6", - "fzaninotto/faker": "^1.5", + "fakerphp/faker": "^1.5", "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.6", + "jangregor/phpstan-prophecy": "^0.8", "mockery/mockery": "^1.3", "phpstan/extension-installer": "^1", "phpstan/phpstan": "^0.12.32", "phpstan/phpstan-mockery": "^0.12.5", "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5", + "phpunit/phpunit": "^8.5 || ^9", "psy/psysh": "^0.10.4", "slevomat/coding-standard": "^6.3", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^3.12.2" + "vimeo/psalm": "^4.4" }, - "time": "2020-09-10T20:58:17+00:00", + "time": "2021-01-21T17:40:04+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -785,12 +785,16 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.1.1" + "source": "https://github.com/ramsey/collection/tree/1.1.3" }, "funding": [ { "url": "https://github.com/ramsey", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" } ], "install-path": "../ramsey/collection" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 12ef7bdcc..7cad9b54b 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', + 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -121,12 +121,12 @@ ), 'ramsey/collection' => array ( - 'pretty_version' => '1.1.1', - 'version' => '1.1.1.0', + 'pretty_version' => '1.1.3', + 'version' => '1.1.3.0', 'aliases' => array ( ), - 'reference' => '24d93aefb2cd786b7edd9f45b554aea20b28b9b1', + 'reference' => '28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1', ), 'ramsey/uuid' => array ( @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '4171a0136ad4f14bdd5d7621b4c7decd3e942c8c', + 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', ), ), ); diff --git a/vendor/ramsey/collection/CHANGELOG.md b/vendor/ramsey/collection/CHANGELOG.md deleted file mode 100644 index 6333f3966..000000000 --- a/vendor/ramsey/collection/CHANGELOG.md +++ /dev/null @@ -1,120 +0,0 @@ -# ramsey/collection Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [Unreleased] -### Added -### Changed -### Deprecated -### Removed -### Fixed -### Security - -## [1.1.1] - 2020-09-10 - -### Fixed - -* Fixed broken `AbstractCollection::map()` implementation. - -## [1.1.0] - 2020-08-10 - -### Fixed - -* Fixed `AbstractCollection::diff()`, `AbstractCollection::intersect()` and - `AbstractCollection::merge()` when used with Generic collections. -* Fixed `AbstractCollection::diff()` and `AbstractCollection::intersect()` - returning inconsistent results when used on collections containing objects. -* Removed warning about deprecated dependency when running `composer install` - -## [1.0.1] - 2020-01-04 - -### Fixed - -* Fixed `AbstractCollection::offsetSet()` so that it uses the provided `$offset` - when setting `$value` in the array. - -## [1.0.0] - 2018-12-31 - -### Added - -* Added support for *queue* data structures to represent collections of ordered - entities. Together with *double-ended queues* (a.k.a. *deques*), - first-in-first-out (FIFO), last-in-first-out (LIFO), and other queue and stack - behaviors may be implemented. This functionality includes interfaces - `QueueInterface` and `DoubleEndedQueueInterface` and classes `Queue` and - `DoubleEndedQueue`. -* Added support for *set* data structures, representing collections that cannot - contain any duplicated elements; includes classes `AbstractSet` and `Set`. -* Added support for *typed map* data structures to represent maps of elements - where both keys and values have specified data types; includes - `TypedMapInterface` and the classes `AbstractTypedMap` and `TypedMap`. -* Added new manipulation and analyze methods for collections: `column()`, - `first()`, `last()`, `sort()`, `filter()`, `where()`, `map()`, `diff()`, - `intersect()`, and `merge()`. See [CollectionInterface](https://github.com/ramsey/collection/blob/master/src/CollectionInterface.php) - for more information. -* Added the following new exceptions specific to the ramsey/collection library: - `CollectionMismatchException`, `InvalidArgumentException`, - `InvalidSortOrderException`, `NoSuchElementException`, `OutOfBoundsException`, - `UnsupportedOperationException`, and `ValueExtractionException`. - -### Changed - -* Minimum PHP version supported is 7.2. -* Strict types are enforced throughout. - -### Removed - -* Removed support for HHVM. - -### Security - -* Fixed possible exploit using `AbstractArray::unserialize()` - (see [#47](https://github.com/ramsey/collection/issues/47)). - -## [0.3.0] - 2016-05-23 - -### Added - -* Added `MapInterface::keys()` method to return the keys from a `MapInterface` - object. This was added to the `AbstractMap` class. - -### Removed - -* Removed `getType()` and constructor methods from `AbstractCollection`. Children - of `AbstractCollection` must now implement `getType()`, which should return a - string value that defines the data type of items for the collection. - -### Fixed - -* Improve error messages in exceptions when `Collection` and `NamedParameterMap` - items fail type checks. - -## [0.2.1] - 2016-02-22 - -### Fixed - -* Allow non-strict checking of values in typed collections. - -## [0.2.0] - 2016-02-05 - -### Added - -* Support typed collections. - -## [0.1.0] - 2015-10-27 - -### Added - -* Support generic arrays and maps. - -[Unreleased]: https://github.com/ramsey/collection/compare/1.1.0...HEAD -[1.1.0]: https://github.com/ramsey/collection/compare/1.0.1...1.1.0 -[1.0.1]: https://github.com/ramsey/collection/compare/1.0.0...1.0.1 -[1.0.0]: https://github.com/ramsey/collection/compare/0.3.0...1.0.0 -[0.3.0]: https://github.com/ramsey/collection/compare/0.2.1...0.3.0 -[0.2.1]: https://github.com/ramsey/collection/compare/0.2.0...0.2.1 -[0.2.0]: https://github.com/ramsey/collection/compare/0.1.0...0.2.0 -[0.1.0]: https://github.com/ramsey/collection/commits/0.1.0 diff --git a/vendor/ramsey/collection/README.md b/vendor/ramsey/collection/README.md index 1b7897eb4..ce7a554d2 100644 --- a/vendor/ramsey/collection/README.md +++ b/vendor/ramsey/collection/README.md @@ -1,12 +1,22 @@ -# ramsey/collection - -[![Source Code][badge-source]][source] -[![Latest Version][badge-release]][packagist] -[![Software License][badge-license]][license] -[![PHP Version][badge-php]][php] -[![Build Status][badge-build]][build] -[![Coverage Status][badge-coverage]][coverage] -[![Total Downloads][badge-downloads]][downloads] +

      ramsey/collection

      + +

      + A PHP library for representing and manipulating collections. +

      + +

      + Source Code + Download Package + PHP Programming Language + Build Status + Codecov Code Coverage + Psalm Type Coverage + Read License + Package downloads on Packagist + Chat with the maintainers +

      + +## About ramsey/collection is a PHP 7.2+ library for representing and manipulating collections. @@ -16,7 +26,6 @@ This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating in this project and its community, you are expected to uphold this code. - ## Installation Install this package as a dependency using [Composer](https://getcomposer.org). @@ -27,8 +36,6 @@ composer require ramsey/collection ## Usage -The [latest class API documentation][apidocs] is available online. - Examples of how to use this framework can be found in the [Wiki pages](https://github.com/ramsey/collection/wiki/Examples). @@ -49,99 +56,22 @@ composer install Now, you are ready to develop! -### Tooling - -This project uses [CaptainHook](https://github.com/CaptainHookPhp/captainhook) -to validate all staged changes prior to commit. - -#### Composer Commands - -To see all the commands available in the project `br` namespace for -Composer, type: - -``` bash -composer list br -``` - -##### Composer Command Autocompletion - -If you'd like to have Composer command auto-completion, you may use -[bamarni/symfony-console-autocomplete](https://github.com/bamarni/symfony-console-autocomplete). -Install it globally with Composer: - -``` bash -composer global require bamarni/symfony-console-autocomplete -``` - -Then, in your shell configuration file — usually `~/.bash_profile` or `~/.zshrc`, -but it could be different depending on your settings — ensure that your global -Composer `bin` directory is in your `PATH`, and evaluate the -`symfony-autocomplete` command. This will look like this: - -``` bash -export PATH="$(composer config home)/vendor/bin:$PATH" -eval "$(symfony-autocomplete)" -``` - -Now, you can use the `tab` key to auto-complete Composer commands: - -``` bash -composer br:[TAB][TAB] -``` - -#### Coding Standards - -This project follows a superset of [PSR-12](https://www.php-fig.org/psr/psr-12/) -coding standards, enforced by [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer). -The project PHP_CodeSniffer configuration may be found in `phpcs.xml.dist`. - -CaptainHook will run PHP_CodeSniffer before committing. It will attempt to fix -any errors it can, and it will reject the commit if there are any un-fixable -issues. Many issues can be fixed automatically and will be done so pre-commit. - -You may lint the entire codebase using PHP_CodeSniffer with the following -commands: - -``` bash -# Lint -composer br:lint - -# Lint and autofix -composer br:lint:fix -``` - -#### Static Analysis - -This project uses a combination of [PHPStan](https://github.com/phpstan/phpstan) -and [Psalm](https://github.com/vimeo/psalm) to provide static analysis of PHP -code. Configurations for these are in `phpstan.neon.dist` and `psalm.xml`, -respectively. +## Coordinated Disclosure -CaptainHook will run PHPStan and Psalm before committing. The pre-commit hook -does not attempt to fix any static analysis errors. Instead, the commit will -fail, and you must fix the errors manually. - -You may run static analysis manually across the whole codebase with the -following command: - -``` bash -# Static analysis -composer br:analyze -``` +Keeping user information safe and secure is a top priority, and we welcome the +contribution of external security researchers. If you believe you've found a +security issue in software that is maintained in this repository, please read +[SECURITY.md][] for instructions on submitting a vulnerability report. -### Project Structure +## ramsey/collection for Enterprise -This project uses [pds/skeleton](https://github.com/php-pds/skeleton) as its -base folder structure and layout. +Available as part of the Tidelift Subscription. -| Name | Description | -| ------------------| ---------------------------------------------- | -| **bin/** | Commands and scripts for this project | -| **build/** | Cache, logs, reports, etc. for project builds | -| **docs/** | Project-specific documentation | -| **resources/** | Additional resources for this project | -| **src/** | Project library and application source code | -| **tests/** | Tests for this project | +The maintainers of ramsey/collection and thousands of other packages are working +with Tidelift to deliver commercial support and maintenance for the open source +packages you use to build your applications. Save time, reduce risk, and improve +code health, while paying the maintainers of the exact packages you use. +[Learn more.](https://tidelift.com/subscription/pkg/packagist-ramsey-collection?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ## Copyright and License @@ -151,20 +81,4 @@ MIT License (MIT). Please see [LICENSE](LICENSE) for more information. [java]: http://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html -[apidocs]: https://docs.benramsey.com/ramsey-collection/latest/ - -[badge-source]: http://img.shields.io/badge/source-ramsey/collection-blue.svg?style=flat-square -[badge-release]: https://img.shields.io/packagist/v/ramsey/collection.svg?style=flat-square&label=release -[badge-license]: https://img.shields.io/packagist/l/ramsey/collection.svg?style=flat-square -[badge-php]: https://img.shields.io/packagist/php-v/ramsey/collection.svg?style=flat-square -[badge-build]: https://img.shields.io/travis/ramsey/collection/master.svg?style=flat-square -[badge-coverage]: https://img.shields.io/coveralls/github/ramsey/collection/master.svg?style=flat-square -[badge-downloads]: https://img.shields.io/packagist/dt/ramsey/collection.svg?style=flat-square&colorB=mediumvioletred - -[source]: https://github.com/ramsey/collection -[packagist]: https://packagist.org/packages/ramsey/collection -[license]: https://github.com/ramsey/collection/blob/master/LICENSE -[php]: https://php.net -[build]: https://travis-ci.org/ramsey/collection -[coverage]: https://coveralls.io/r/ramsey/collection?branch=master -[downloads]: https://packagist.org/packages/ramsey/collection +[security.md]: https://github.com/ramsey/collection/blob/master/SECURITY.md diff --git a/vendor/ramsey/collection/SECURITY.md b/vendor/ramsey/collection/SECURITY.md new file mode 100644 index 000000000..b052f3b65 --- /dev/null +++ b/vendor/ramsey/collection/SECURITY.md @@ -0,0 +1,113 @@ + + +# Vulnerability Disclosure Policy + +Keeping user information safe and secure is a top priority, and we welcome the +contribution of external security researchers. + +## Scope + +If you believe you've found a security issue in software that is maintained in +this repository, we encourage you to notify us. + +| Version | In scope | Source code | +| :-----: | :------: | :---------- | +| latest | ✅ | https://github.com/ramsey/collection | + +## How to Submit a Report + +To submit a vulnerability report, please contact us at . +Your submission will be reviewed and validated by a member of our team. + +## Safe Harbor + +We support safe harbor for security researchers who: + +* Make a good faith effort to avoid privacy violations, destruction of data, and + interruption or degradation of our services. +* Only interact with accounts you own or with explicit permission of the account + holder. If you do encounter Personally Identifiable Information (PII) contact + us immediately, do not proceed with access, and immediately purge any local + information. +* Provide us with a reasonable amount of time to resolve vulnerabilities prior + to any disclosure to the public or a third-party. + +We will consider activities conducted consistent with this policy to constitute +"authorized" conduct and will not pursue civil action or initiate a complaint to +law enforcement. We will help to the extent we can if legal action is initiated +by a third party against you. + +Please submit a report to us before engaging in conduct that may be inconsistent +with or unaddressed by this policy. + +## Preferences + +* Please provide detailed reports with reproducible steps and a clearly defined + impact. +* Include the version number of the vulnerable package in your report +* Social engineering (e.g. phishing, vishing, smishing) is prohibited. + +## Encryption Key for security@ramsey.dev + +For increased privacy when reporting sensitive issues, you may encrypt your +messages using the following key: + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +nmgawbBHA02D5xEqB5SU3WJu +=eJNx +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/vendor/ramsey/collection/composer.json b/vendor/ramsey/collection/composer.json index 9e443d93c..0c5d09578 100644 --- a/vendor/ramsey/collection/composer.json +++ b/vendor/ramsey/collection/composer.json @@ -25,19 +25,19 @@ "captainhook/captainhook": "^5.3", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "ergebnis/composer-normalize": "^2.6", - "fzaninotto/faker": "^1.5", + "fakerphp/faker": "^1.5", "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.6", + "jangregor/phpstan-prophecy": "^0.8", "mockery/mockery": "^1.3", "phpstan/extension-installer": "^1", "phpstan/phpstan": "^0.12.32", "phpstan/phpstan-mockery": "^0.12.5", "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5", + "phpunit/phpunit": "^8.5 || ^9", "psy/psysh": "^0.10.4", "slevomat/coding-standard": "^6.3", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^3.12.2" + "vimeo/psalm": "^4.4" }, "config": { "sort-packages": true @@ -63,7 +63,7 @@ "@br:analyze:psalm" ], "br:analyze:phpstan": "phpstan --memory-limit=1G analyse", - "br:analyze:psalm": "psalm --diff --diff-methods --config=psalm.xml", + "br:analyze:psalm": "psalm --diff --config=psalm.xml", "br:build:clean": "git clean -fX build/.", "br:build:clear-cache": "git clean -fX build/cache/.", "br:lint": "phpcs --cache=build/cache/phpcs.cache", diff --git a/vendor/ramsey/collection/src/AbstractArray.php b/vendor/ramsey/collection/src/AbstractArray.php index f8b4be2ce..2c6e0dedd 100644 --- a/vendor/ramsey/collection/src/AbstractArray.php +++ b/vendor/ramsey/collection/src/AbstractArray.php @@ -23,20 +23,23 @@ use function unserialize; /** * This class provides a basic implementation of `ArrayInterface`, to minimize * the effort required to implement this interface. + * + * @template T + * @template-implements ArrayInterface */ abstract class AbstractArray implements ArrayInterface { /** * The items of this array. * - * @var mixed[] + * @var array */ protected $data = []; /** * Constructs a new array object. * - * @param mixed[] $data The initial items to add to this array. + * @param array $data The initial items to add to this array. */ public function __construct(array $data = []) { @@ -51,8 +54,6 @@ abstract class AbstractArray implements ArrayInterface * Returns an iterator for this array. * * @link http://php.net/manual/en/iteratoraggregate.getiterator.php IteratorAggregate::getIterator() - * - * @return ArrayIterator */ public function getIterator(): Traversable { @@ -64,7 +65,7 @@ abstract class AbstractArray implements ArrayInterface * * @link http://php.net/manual/en/arrayaccess.offsetexists.php ArrayAccess::offsetExists() * - * @param mixed $offset The offset to check. + * @param array-key $offset The offset to check. */ public function offsetExists($offset): bool { @@ -76,9 +77,9 @@ abstract class AbstractArray implements ArrayInterface * * @link http://php.net/manual/en/arrayaccess.offsetget.php ArrayAccess::offsetGet() * - * @param mixed $offset The offset for which a value should be returned. + * @param array-key $offset The offset for which a value should be returned. * - * @return mixed|null the value stored at the offset, or null if the offset + * @return T|null the value stored at the offset, or null if the offset * does not exist. */ public function offsetGet($offset) @@ -91,10 +92,11 @@ abstract class AbstractArray implements ArrayInterface * * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() * - * @param mixed|null $offset The offset to set. If `null`, the value may be + * @param array-key|null $offset The offset to set. If `null`, the value may be * set at a numerically-indexed offset. - * @param mixed $value The value to set at the given offset. + * @param T $value The value to set at the given offset. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function offsetSet($offset, $value): void { if ($offset === null) { @@ -109,7 +111,7 @@ abstract class AbstractArray implements ArrayInterface * * @link http://php.net/manual/en/arrayaccess.offsetunset.php ArrayAccess::offsetUnset() * - * @param mixed $offset The offset to remove from the array. + * @param array-key $offset The offset to remove from the array. */ public function offsetUnset($offset): void { @@ -139,7 +141,10 @@ abstract class AbstractArray implements ArrayInterface */ public function unserialize($serialized): void { - $this->data = unserialize($serialized, ['allowed_classes' => false]); + /** @var array $data */ + $data = unserialize($serialized, ['allowed_classes' => false]); + + $this->data = $data; } /** @@ -152,27 +157,19 @@ abstract class AbstractArray implements ArrayInterface return count($this->data); } - /** - * Removes all items from this array. - */ public function clear(): void { $this->data = []; } /** - * Returns a native PHP array representation of this array object. - * - * @return mixed[] + * @inheritDoc */ public function toArray(): array { return $this->data; } - /** - * Returns `true` if this array is empty. - */ public function isEmpty(): bool { return count($this->data) === 0; diff --git a/vendor/ramsey/collection/src/AbstractCollection.php b/vendor/ramsey/collection/src/AbstractCollection.php index 546f1adba..2facf0e89 100644 --- a/vendor/ramsey/collection/src/AbstractCollection.php +++ b/vendor/ramsey/collection/src/AbstractCollection.php @@ -14,11 +14,11 @@ declare(strict_types=1); namespace Ramsey\Collection; +use Closure; use Ramsey\Collection\Exception\CollectionMismatchException; use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Exception\InvalidSortOrderException; use Ramsey\Collection\Exception\OutOfBoundsException; -use Ramsey\Collection\Exception\ValueExtractionException; use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueExtractorTrait; use Ramsey\Collection\Tool\ValueToStringTrait; @@ -40,6 +40,10 @@ use function usort; /** * This class provides a basic implementation of `CollectionInterface`, to * minimize the effort required to implement this interface + * + * @template T + * @template-extends AbstractArray + * @template-implements CollectionInterface */ abstract class AbstractCollection extends AbstractArray implements CollectionInterface { @@ -48,14 +52,7 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt use ValueExtractorTrait; /** - * Ensures that this collection contains the specified element. - * - * @param mixed $element The element to add to the collection. - * - * @return bool `true` if this collection changed as a result of the call. - * - * @throws InvalidArgumentException when the element does not match the - * specified type for this collection. + * @inheritDoc */ public function add($element): bool { @@ -65,10 +62,7 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt } /** - * Returns `true` if this collection contains the specified element. - * - * @param mixed $element The element to check whether the collection contains. - * @param bool $strict Whether to perform a strict type check on the value. + * @inheritDoc */ public function contains($element, bool $strict = true): bool { @@ -76,14 +70,7 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt } /** - * Sets the given value to the given offset in the array. - * - * @param mixed|null $offset The position to set the value in the array, or - * `null` to append the value to the array. - * @param mixed $value The value to set at the given offset. - * - * @throws InvalidArgumentException when the value does not match the - * specified type for this collection. + * @inheritDoc */ public function offsetSet($offset, $value): void { @@ -102,12 +89,7 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt } /** - * Removes a single instance of the specified element from this collection, - * if it is present. - * - * @param mixed $element The element to remove from the collection. - * - * @return bool `true` if an element was removed as a result of this call. + * @inheritDoc */ public function remove($element): bool { @@ -121,31 +103,25 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt } /** - * Returns the values from given property or method. - * - * @param string $propertyOrMethod The property or method name to filter by. - * - * @return mixed[] - * - * @throws ValueExtractionException if property or method is not defined. + * @inheritDoc */ public function column(string $propertyOrMethod): array { $temp = []; foreach ($this->data as $item) { - $temp[] = $this->extractValue($item, $propertyOrMethod); + /** @var mixed $value */ + $value = $this->extractValue($item, $propertyOrMethod); + + /** @psalm-suppress MixedAssignment */ + $temp[] = $value; } return $temp; } /** - * Returns the first item of the collection. - * - * @return mixed - * - * @throws OutOfBoundsException when the collection is empty. + * @inheritDoc */ public function first() { @@ -155,15 +131,14 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt reset($this->data); - return current($this->data); + /** @var T $first */ + $first = current($this->data); + + return $first; } /** - * Returns the last item of the collection. - * - * @return mixed - * - * @throws OutOfBoundsException when the collection is empty. + * @inheritDoc */ public function last() { @@ -171,27 +146,13 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt throw new OutOfBoundsException('Can\'t determine last item. Collection is empty'); } + /** @var T $item */ $item = end($this->data); reset($this->data); return $item; } - /** - * Returns a sorted collection. - * - * {@inheritdoc} - * - * @param string $propertyOrMethod The property or method to sort by. - * @param string $order The sort order for the resulting collection (one of - * this interface's `SORT_*` constants). - * - * @return CollectionInterface - * - * @throws InvalidSortOrderException if neither "asc" nor "desc" was given - * as the order. - * @throws ValueExtractionException if property or method is not defined. - */ public function sort(string $propertyOrMethod, string $order = self::SORT_ASC): CollectionInterface { if (!in_array($order, [self::SORT_ASC, self::SORT_DESC], true)) { @@ -200,25 +161,26 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt $collection = clone $this; - usort($collection->data, function ($a, $b) use ($propertyOrMethod, $order) { - $aValue = $this->extractValue($a, $propertyOrMethod); - $bValue = $this->extractValue($b, $propertyOrMethod); + usort( + $collection->data, + /** + * @param T $a + * @param T $b + */ + function ($a, $b) use ($propertyOrMethod, $order): int { + /** @var mixed $aValue */ + $aValue = $this->extractValue($a, $propertyOrMethod); - return ($aValue <=> $bValue) * ($order === self::SORT_DESC ? -1 : 1); - }); + /** @var mixed $bValue */ + $bValue = $this->extractValue($b, $propertyOrMethod); + + return ($aValue <=> $bValue) * ($order === self::SORT_DESC ? -1 : 1); + } + ); return $collection; } - /** - * Returns a filtered collection. - * - * {@inheritdoc} - * - * @param callable $callback A callable to use for filtering elements. - * - * @return CollectionInterface - */ public function filter(callable $callback): CollectionInterface { $collection = clone $this; @@ -228,84 +190,31 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt } /** - * Returns a collection of matching items. - * * {@inheritdoc} - * - * @param string $propertyOrMethod The property or method to evaluate. - * @param mixed $value The value to match. - * - * @return CollectionInterface - * - * @throws ValueExtractionException if property or method is not defined. */ public function where(string $propertyOrMethod, $value): CollectionInterface { return $this->filter(function ($item) use ($propertyOrMethod, $value) { + /** @var mixed $accessorValue */ $accessorValue = $this->extractValue($item, $propertyOrMethod); return $accessorValue === $value; }); } - /** - * Applies a callback to each item of the collection. - * - * {@inheritdoc} - * - * @param callable $callback A callable to apply to each item of the - * collection. - * - * @return CollectionInterface - */ public function map(callable $callback): CollectionInterface { - $collection = clone $this; - $collection->data = array_map($callback, $collection->data); - - return $collection; + return new Collection('mixed', array_map($callback, $this->data)); } - /** - * Create a new collection with divergent items between current and given - * collection. - * - * @param CollectionInterface $other The collection to check for divergent - * items. - * - * @return CollectionInterface - * - * @throws CollectionMismatchException if the given collection is not of the - * same type. - */ public function diff(CollectionInterface $other): CollectionInterface { - if (!$other instanceof static) { - throw new CollectionMismatchException('Collection must be of type ' . static::class); - } - - // When using generics (Collection.php, Set.php, etc), - // we also need to make sure that the internal types match each other - if ($other->getType() !== $this->getType()) { - throw new CollectionMismatchException('Collection items must be of type ' . $this->getType()); - } + $this->compareCollectionTypes($other); - $comparator = function ($a, $b): int { - // If the two values are object, we convert them to unique scalars. - // If the collection contains mixed values (unlikely) where some are objects - // and some are not, we leave them as they are. - // The comparator should still work and the result of $a < $b should - // be consistent but unpredictable since not documented. - if (is_object($a) && is_object($b)) { - $a = spl_object_id($a); - $b = spl_object_id($b); - } - - return $a === $b ? 0 : ($a < $b ? 1 : -1); - }; + $diffAtoB = array_udiff($this->data, $other->toArray(), $this->getComparator()); + $diffBtoA = array_udiff($other->toArray(), $this->data, $this->getComparator()); - $diffAtoB = array_udiff($this->data, $other->data, $comparator); - $diffBtoA = array_udiff($other->data, $this->data, $comparator); + /** @var array $diff */ $diff = array_merge($diffAtoB, $diffBtoA); $collection = clone $this; @@ -314,45 +223,12 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt return $collection; } - /** - * Create a new collection with intersecting item between current and given - * collection. - * - * @param CollectionInterface $other The collection to check for - * intersecting items. - * - * @return CollectionInterface - * - * @throws CollectionMismatchException if the given collection is not of the - * same type. - */ public function intersect(CollectionInterface $other): CollectionInterface { - if (!$other instanceof static) { - throw new CollectionMismatchException('Collection must be of type ' . static::class); - } - - // When using generics (Collection.php, Set.php, etc), - // we also need to make sure that the internal types match each other - if ($other->getType() !== $this->getType()) { - throw new CollectionMismatchException('Collection items must be of type ' . $this->getType()); - } + $this->compareCollectionTypes($other); - $comparator = function ($a, $b): int { - // If the two values are object, we convert them to unique scalars. - // If the collection contains mixed values (unlikely) where some are objects - // and some are not, we leave them as they are. - // The comparator should still work and the result of $a < $b should - // be consistent but unpredictable since not documented. - if (is_object($a) && is_object($b)) { - $a = spl_object_id($a); - $b = spl_object_id($b); - } - - return $a === $b ? 0 : ($a < $b ? 1 : -1); - }; - - $intersect = array_uintersect($this->data, $other->data, $comparator); + /** @var array $intersect */ + $intersect = array_uintersect($this->data, $other->toArray(), $this->getComparator()); $collection = clone $this; $collection->data = $intersect; @@ -360,15 +236,6 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt return $collection; } - /** - * Merge current items and items of given collections into a new one. - * - * @param CollectionInterface ...$collections The collections to merge. - * - * @return CollectionInterface - * - * @throws CollectionMismatchException if any of the given collections are not of the same type. - */ public function merge(CollectionInterface ...$collections): CollectionInterface { $temp = [$this->data]; @@ -391,6 +258,7 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt $temp[] = $collection->toArray(); } + /** @var array $merge */ $merge = array_merge(...$temp); $collection = clone $this; @@ -404,6 +272,46 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt */ public function unserialize($serialized): void { - $this->data = unserialize($serialized, ['allowed_classes' => [$this->getType()]]); + /** @var array $data */ + $data = unserialize($serialized, ['allowed_classes' => [$this->getType()]]); + + $this->data = $data; + } + + /** + * @param CollectionInterface $other + */ + private function compareCollectionTypes(CollectionInterface $other): void + { + if (!$other instanceof static) { + throw new CollectionMismatchException('Collection must be of type ' . static::class); + } + + // When using generics (Collection.php, Set.php, etc), + // we also need to make sure that the internal types match each other + if ($other->getType() !== $this->getType()) { + throw new CollectionMismatchException('Collection items must be of type ' . $this->getType()); + } + } + + private function getComparator(): Closure + { + return /** + * @param T $a + * @param T $b + */ + function ($a, $b): int { + // If the two values are object, we convert them to unique scalars. + // If the collection contains mixed values (unlikely) where some are objects + // and some are not, we leave them as they are. + // The comparator should still work and the result of $a < $b should + // be consistent but unpredictable since not documented. + if (is_object($a) && is_object($b)) { + $a = spl_object_id($a); + $b = spl_object_id($b); + } + + return $a === $b ? 0 : ($a < $b ? 1 : -1); + }; } } diff --git a/vendor/ramsey/collection/src/AbstractSet.php b/vendor/ramsey/collection/src/AbstractSet.php index 674fda03d..3bd22965f 100644 --- a/vendor/ramsey/collection/src/AbstractSet.php +++ b/vendor/ramsey/collection/src/AbstractSet.php @@ -14,25 +14,18 @@ declare(strict_types=1); namespace Ramsey\Collection; -use Ramsey\Collection\Exception\InvalidArgumentException; - /** * This class contains the basic implementation of a collection that does not * allow duplicated values (a set), to minimize the effort required to implement * this specific type of collection. + * + * @template T + * @template-extends AbstractCollection */ abstract class AbstractSet extends AbstractCollection { /** - * Adds the specified element to this set, if it is not already present. - * - * @param mixed $element The element to add to the set. - * - * @return bool `true` if this set did not already contain the specified - * element. - * - * @throws InvalidArgumentException when the element does not match the - * specified type for this set. + * @inheritDoc */ public function add($element): bool { @@ -44,14 +37,7 @@ abstract class AbstractSet extends AbstractCollection } /** - * Sets the given value to the given offset in this set, if it is not - * already present. - * - * @param mixed|null $offset The offset is ignored and is treated as `null`. - * @param mixed $value The value to set at the given offset. - * - * @throws InvalidArgumentException when the value does not match the - * specified type for this set. + * @inheritDoc */ public function offsetSet($offset, $value): void { diff --git a/vendor/ramsey/collection/src/ArrayInterface.php b/vendor/ramsey/collection/src/ArrayInterface.php index 81835cc80..19fbff336 100644 --- a/vendor/ramsey/collection/src/ArrayInterface.php +++ b/vendor/ramsey/collection/src/ArrayInterface.php @@ -21,6 +21,8 @@ use Serializable; /** * `ArrayInterface` provides traversable array functionality to data types. + * + * @template T */ interface ArrayInterface extends ArrayAccess, @@ -36,7 +38,7 @@ interface ArrayInterface extends /** * Returns a native PHP array representation of this array object. * - * @return mixed[] + * @return array */ public function toArray(): array; diff --git a/vendor/ramsey/collection/src/Collection.php b/vendor/ramsey/collection/src/Collection.php index e4db68dfe..2f8deddaa 100644 --- a/vendor/ramsey/collection/src/Collection.php +++ b/vendor/ramsey/collection/src/Collection.php @@ -69,6 +69,9 @@ namespace Ramsey\Collection; * // the collection is a collection of My\Foo objects * } * ``` + * + * @template T + * @template-extends AbstractCollection */ class Collection extends AbstractCollection { @@ -88,7 +91,7 @@ class Collection extends AbstractCollection * * @param string $collectionType The type (FQCN) associated with this * collection. - * @param mixed[] $data The initial items to store in the collection. + * @param array $data The initial items to store in the collection. */ public function __construct(string $collectionType, array $data = []) { @@ -96,9 +99,6 @@ class Collection extends AbstractCollection parent::__construct($data); } - /** - * Returns the type associated with this collection. - */ public function getType(): string { return $this->collectionType; diff --git a/vendor/ramsey/collection/src/CollectionInterface.php b/vendor/ramsey/collection/src/CollectionInterface.php index c865fa9f5..dfef6ca86 100644 --- a/vendor/ramsey/collection/src/CollectionInterface.php +++ b/vendor/ramsey/collection/src/CollectionInterface.php @@ -19,6 +19,9 @@ namespace Ramsey\Collection; * * Some collections allow duplicate elements and others do not. Some are ordered * and others unordered. + * + * @template T + * @template-extends ArrayInterface */ interface CollectionInterface extends ArrayInterface { @@ -52,18 +55,20 @@ interface CollectionInterface extends ArrayInterface * (rather than returning `false`). This preserves the invariant that a * collection always contains the specified element after this call returns. * - * @param mixed $element The element to add to the collection. + * @param T $element The element to add to the collection. * * @return bool `true` if this collection changed as a result of the call. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function add($element): bool; /** * Returns `true` if this collection contains the specified element. * - * @param mixed $element The element to check whether the collection contains. + * @param T $element The element to check whether the collection contains. * @param bool $strict Whether to perform a strict type check on the value. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function contains($element, bool $strict = true): bool; /** @@ -75,10 +80,11 @@ interface CollectionInterface extends ArrayInterface * Removes a single instance of the specified element from this collection, * if it is present. * - * @param mixed $element The element to remove from the collection. + * @param T $element The element to remove from the collection. * * @return bool `true` if an element was removed as a result of this call. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function remove($element): bool; /** @@ -86,21 +92,21 @@ interface CollectionInterface extends ArrayInterface * * @param string $propertyOrMethod The property or method name to filter by. * - * @return mixed[] + * @return list */ public function column(string $propertyOrMethod): array; /** * Returns the first item of the collection. * - * @return mixed + * @return T */ public function first(); /** * Returns the last item of the collection. * - * @return mixed + * @return T */ public function last(); @@ -114,7 +120,7 @@ interface CollectionInterface extends ArrayInterface * @param string $order The sort order for the resulting collection (one of * this interface's `SORT_*` constants). * - * @return CollectionInterface + * @return CollectionInterface */ public function sort(string $propertyOrMethod, string $order = self::SORT_ASC): self; @@ -128,9 +134,9 @@ interface CollectionInterface extends ArrayInterface * See the {@link http://php.net/manual/en/function.array-filter.php PHP array_filter() documentation} * for examples of how the `$callback` parameter works. * - * @param callable $callback A callable to use for filtering elements. + * @param callable(T):bool $callback A callable to use for filtering elements. * - * @return CollectionInterface + * @return CollectionInterface */ public function filter(callable $callback): self; @@ -141,25 +147,28 @@ interface CollectionInterface extends ArrayInterface * a new one. * * @param string $propertyOrMethod The property or method to evaluate. - * @param mixed $value The value to match. + * @param mixed $value The value to match. * - * @return CollectionInterface + * @return CollectionInterface */ public function where(string $propertyOrMethod, $value): self; /** * Apply a given callback method on each item of the collection. * - * This will always leave the original collection untouched and will return - * a new one. + * This will always leave the original collection untouched. The new + * collection is created by mapping the callback to each item of the + * original collection. * * See the {@link http://php.net/manual/en/function.array-map.php PHP array_map() documentation} * for examples of how the `$callback` parameter works. * - * @param callable $callback A callable to apply to each item of the - * collection. + * @param callable(T):TCallbackReturn $callback A callable to apply to each + * item of the collection. + * + * @return CollectionInterface * - * @return CollectionInterface + * @template TCallbackReturn */ public function map(callable $callback): self; @@ -167,10 +176,10 @@ interface CollectionInterface extends ArrayInterface * Create a new collection with divergent items between current and given * collection. * - * @param CollectionInterface $other The collection to check for divergent + * @param CollectionInterface $other The collection to check for divergent * items. * - * @return CollectionInterface + * @return CollectionInterface */ public function diff(CollectionInterface $other): self; @@ -178,19 +187,19 @@ interface CollectionInterface extends ArrayInterface * Create a new collection with intersecting item between current and given * collection. * - * @param CollectionInterface $other The collection to check for + * @param CollectionInterface $other The collection to check for * intersecting items. * - * @return CollectionInterface + * @return CollectionInterface */ public function intersect(CollectionInterface $other): self; /** * Merge current items and items of given collections into a new one. * - * @param CollectionInterface ...$collections The collections to merge. + * @param CollectionInterface ...$collections The collections to merge. * - * @return CollectionInterface + * @return CollectionInterface */ public function merge(CollectionInterface ...$collections): self; } diff --git a/vendor/ramsey/collection/src/DoubleEndedQueue.php b/vendor/ramsey/collection/src/DoubleEndedQueue.php index 4eb4dbeab..6ebdca5ad 100644 --- a/vendor/ramsey/collection/src/DoubleEndedQueue.php +++ b/vendor/ramsey/collection/src/DoubleEndedQueue.php @@ -20,6 +20,10 @@ use Ramsey\Collection\Exception\NoSuchElementException; /** * This class provides a basic implementation of `DoubleEndedQueueInterface`, to * minimize the effort required to implement this interface. + * + * @template T + * @template-extends Queue + * @template-implements DoubleEndedQueueInterface */ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface { @@ -31,19 +35,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface private $tail = -1; /** - * Sets the given value to the given offset in the queue. - * - * Since arbitrary offsets may not be manipulated in a queue, this method - * serves only to fulfill the `ArrayAccess` interface requirements. It is - * invoked by other operations when adding values to the queue. - * - * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() - * - * @param mixed|null $offset The offset is ignored and is treated as `null`. - * @param mixed $value The value to set at the given offset. - * - * @throws InvalidArgumentException when the value does not match the - * specified type for this queue. + * @inheritDoc */ public function offsetSet($offset, $value): void { @@ -60,16 +52,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Ensures that the specified element is inserted at the front of this queue. - * - * @see self::offerFirst() - * - * @param mixed $element The element to add to this queue. - * - * @return bool `true` if this queue changed as a result of the call. - * - * @throws InvalidArgumentException when the value does not match the - * specified type for this queue. + * @inheritDoc */ public function addFirst($element): bool { @@ -88,16 +71,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Ensures that the specified element in inserted at the end of this queue. - * - * @see Queue::add() - * - * @param mixed $element The element to add to this queue. - * - * @return bool `true` if this queue changed as a result of the call. - * - * @throws InvalidArgumentException when the value does not match the - * specified type for this queue. + * @inheritDoc */ public function addLast($element): bool { @@ -105,13 +79,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Inserts the specified element at the front this queue. - * - * @see self::addFirst() - * - * @param mixed $element The element to add to this queue. - * - * @return bool `true` if the element was added to this queue, else `false`. + * @inheritDoc */ public function offerFirst($element): bool { @@ -123,14 +91,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Inserts the specified element at the end this queue. - * - * @see self::addLast() - * @see Queue::offer() - * - * @param mixed $element The element to add to this queue. - * - * @return bool `true` if the element was added to this queue, else `false`. + * @inheritDoc */ public function offerLast($element): bool { @@ -138,17 +99,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Retrieves and removes the head of this queue. - * - * This method differs from `pollFirst()` only in that it throws an - * exception if this queue is empty. - * - * @see self::pollFirst() - * @see Queue::remove() - * - * @return mixed the head of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ public function removeFirst() { @@ -156,38 +107,21 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Retrieves and removes the tail of this queue. - * - * This method differs from `pollLast()` only in that it throws an exception - * if this queue is empty. - * - * @see self::pollLast() - * - * @return mixed the tail of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ public function removeLast() { - if ($this->count() === 0) { + $tail = $this->pollLast(); + + if ($tail === null) { throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); } - $tail = $this[$this->tail]; - - unset($this[$this->tail]); - $this->tail--; - return $tail; } /** - * Retrieves and removes the head of this queue, or returns `null` if this - * queue is empty. - * - * @see self::removeFirst() - * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @inheritDoc */ public function pollFirst() { @@ -195,12 +129,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Retrieves and removes the tail of this queue, or returns `null` if this - * queue is empty. - * - * @see self::removeLast() - * - * @return mixed|null the tail of this queue, or `null` if this queue is empty. + * @inheritDoc */ public function pollLast() { @@ -217,17 +146,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Retrieves, but does not remove, the head of this queue. - * - * This method differs from `peekFirst()` only in that it throws an - * exception if this queue is empty. - * - * @see self::peekFirst() - * @see Queue::element() - * - * @return mixed the head of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ public function firstElement() { @@ -235,16 +154,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Retrieves, but does not remove, the tail of this queue. - * - * This method differs from `peekLast()` only in that it throws an exception - * if this queue is empty. - * - * @see self::peekLast() - * - * @return mixed the tail of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ public function lastElement() { @@ -256,13 +166,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Retrieves, but does not remove, the head of this queue, or returns `null` - * if this queue is empty. - * - * @see self::firstElement() - * @see Queue::peek() - * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @inheritDoc */ public function peekFirst() { @@ -270,12 +174,7 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface } /** - * Retrieves, but does not remove, the tail of this queue, or returns `null` - * if this queue is empty. - * - * @see self::lastElement() - * - * @return mixed|null the tail of this queue, or `null` if this queue is empty + * @inheritDoc */ public function peekLast() { diff --git a/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php b/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php index 6b23cf553..67aae5e2e 100644 --- a/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php +++ b/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php @@ -158,6 +158,9 @@ use Ramsey\Collection\Exception\NoSuchElementException; * ability to insert nulls. This is so because `null` is used as a special * return value by various methods to indicated that the double-ended queue is * empty. + * + * @template T + * @template-extends QueueInterface */ interface DoubleEndedQueueInterface extends QueueInterface { @@ -168,7 +171,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * When using a capacity-restricted double-ended queue, it is generally * preferable to use the `offerFirst()` method. * - * @param mixed $element The element to add to the front of this queue. + * @param T $element The element to add to the front of this queue. * * @return bool `true` if this queue changed as a result of the call. * @@ -177,6 +180,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function addFirst($element): bool; /** @@ -188,7 +192,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * * This method is equivalent to `add()`. * - * @param mixed $element The element to add to the end of this queue. + * @param T $element The element to add to the end of this queue. * * @return bool `true` if this queue changed as a result of the call. * @@ -197,6 +201,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function addLast($element): bool; /** @@ -207,10 +212,11 @@ interface DoubleEndedQueueInterface extends QueueInterface * preferable to `addFirst()`, which can fail to insert an element only by * throwing an exception. * - * @param mixed $element The element to add to the front of this queue. + * @param T $element The element to add to the front of this queue. * * @return bool `true` if the element was added to this queue, else `false`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function offerFirst($element): bool; /** @@ -221,10 +227,11 @@ interface DoubleEndedQueueInterface extends QueueInterface * preferable to `addLast()` which can fail to insert an element only by * throwing an exception. * - * @param mixed $element The element to add to the end of this queue. + * @param T $element The element to add to the end of this queue. * * @return bool `true` if the element was added to this queue, else `false`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function offerLast($element): bool; /** @@ -233,7 +240,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * This method differs from `pollFirst()` only in that it throws an * exception if this queue is empty. * - * @return mixed the first element in this queue. + * @return T the first element in this queue. * * @throws NoSuchElementException if this queue is empty. */ @@ -245,7 +252,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * This method differs from `pollLast()` only in that it throws an exception * if this queue is empty. * - * @return mixed the last element in this queue. + * @return T the last element in this queue. * * @throws NoSuchElementException if this queue is empty. */ @@ -255,7 +262,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * Retrieves and removes the head of this queue, or returns `null` if this * queue is empty. * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ public function pollFirst(); @@ -263,7 +270,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * Retrieves and removes the tail of this queue, or returns `null` if this * queue is empty. * - * @return mixed|null the tail of this queue, or `null` if this queue is empty. + * @return T|null the tail of this queue, or `null` if this queue is empty. */ public function pollLast(); @@ -273,7 +280,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * This method differs from `peekFirst()` only in that it throws an * exception if this queue is empty. * - * @return mixed the head of this queue. + * @return T the head of this queue. * * @throws NoSuchElementException if this queue is empty. */ @@ -285,7 +292,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * This method differs from `peekLast()` only in that it throws an exception * if this queue is empty. * - * @return mixed the tail of this queue. + * @return T the tail of this queue. * * @throws NoSuchElementException if this queue is empty. */ @@ -295,7 +302,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * Retrieves, but does not remove, the head of this queue, or returns `null` * if this queue is empty. * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ public function peekFirst(); @@ -303,7 +310,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * Retrieves, but does not remove, the tail of this queue, or returns `null` * if this queue is empty. * - * @return mixed|null the tail of this queue, or `null` if this queue is empty. + * @return T|null the tail of this queue, or `null` if this queue is empty. */ public function peekLast(); } diff --git a/vendor/ramsey/collection/src/GenericArray.php b/vendor/ramsey/collection/src/GenericArray.php index 2f9ab7677..9b95df387 100644 --- a/vendor/ramsey/collection/src/GenericArray.php +++ b/vendor/ramsey/collection/src/GenericArray.php @@ -16,6 +16,8 @@ namespace Ramsey\Collection; /** * `GenericArray` represents a standard array object. + * + * @template-extends AbstractArray */ class GenericArray extends AbstractArray { diff --git a/vendor/ramsey/collection/src/Map/AbstractMap.php b/vendor/ramsey/collection/src/Map/AbstractMap.php index 6b2e97a08..70f71160c 100644 --- a/vendor/ramsey/collection/src/Map/AbstractMap.php +++ b/vendor/ramsey/collection/src/Map/AbstractMap.php @@ -24,23 +24,22 @@ use function in_array; /** * This class provides a basic implementation of `MapInterface`, to minimize the * effort required to implement this interface. + * + * @template T + * @template-extends AbstractArray + * @template-implements MapInterface */ abstract class AbstractMap extends AbstractArray implements MapInterface { /** - * Sets the given value to the given offset in the map. - * - * @param mixed $offset The offset to set. - * @param mixed $value The value to set at the given offset. - * - * @throws InvalidArgumentException if the offset provided is `null`. + * @inheritDoc */ public function offsetSet($offset, $value): void { if ($offset === null) { throw new InvalidArgumentException( 'Map elements are key/value pairs; a key must be provided for ' - . 'value ' . $value + . 'value ' . var_export($value, true) ); } @@ -48,9 +47,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Returns `true` if this map contains a mapping for the specified key. - * - * @param mixed $key The key to check in the map. + * @inheritDoc */ public function containsKey($key): bool { @@ -58,11 +55,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Returns `true` if this map maps one or more keys to the specified value. - * - * This performs a strict type check on the value. - * - * @param mixed $value The value to check in the map. + * @inheritDoc */ public function containsValue($value): bool { @@ -70,9 +63,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Return an array of the keys contained in this map. - * - * @return mixed[] + * @inheritDoc */ public function keys(): array { @@ -80,14 +71,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Returns the value to which the specified key is mapped, `null` if this - * map contains no mapping for the key, or (optionally) `$defaultValue` if - * this map contains no mapping for the key. - * - * @param mixed $key The key to return from the map. - * @param mixed $defaultValue The default value to use if `$key` is not found. - * - * @return mixed|null the value or `null` if the key could not be found. + * @inheritDoc */ public function get($key, $defaultValue = null) { @@ -99,16 +83,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Associates the specified value with the specified key in this map. - * - * If the map previously contained a mapping for the key, the old value is - * replaced by the specified value. - * - * @param mixed $key The key to put or replace in the map. - * @param mixed $value The value to store at `$key`. - * - * @return mixed|null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ public function put($key, $value) { @@ -119,17 +94,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Associates the specified value with the specified key in this map only if - * it is not already set. - * - * If there is already a value associated with `$key`, this returns that - * value without replacing it. - * - * @param mixed $key The key to put in the map. - * @param mixed $value The value to store at `$key`. - * - * @return mixed|null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ public function putIfAbsent($key, $value) { @@ -143,12 +108,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Removes the mapping for a key from this map if it is present. - * - * @param mixed $key The key to remove from the map. - * - * @return mixed|null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ public function remove($key) { @@ -159,15 +119,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Removes the entry for the specified key only if it is currently mapped to - * the specified value. - * - * This performs a strict type check on the value. - * - * @param mixed $key The key to remove from the map. - * @param mixed $value The value to match. - * - * @return bool true if the value was removed. + * @inheritDoc */ public function removeIf($key, $value): bool { @@ -181,14 +133,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Replaces the entry for the specified key only if it is currently mapped - * to some value. - * - * @param mixed $key The key to replace. - * @param mixed $value The value to set at `$key`. - * - * @return mixed|null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ public function replace($key, $value) { @@ -202,16 +147,7 @@ abstract class AbstractMap extends AbstractArray implements MapInterface } /** - * Replaces the entry for the specified key only if currently mapped to the - * specified value. - * - * This performs a strict type check on the value. - * - * @param mixed $key The key to remove from the map. - * @param mixed $oldValue The value to match. - * @param mixed $newValue The value to use as a replacement. - * - * @return bool true if the value was replaced. + * @inheritDoc */ public function replaceIf($key, $oldValue, $newValue): bool { diff --git a/vendor/ramsey/collection/src/Map/AbstractTypedMap.php b/vendor/ramsey/collection/src/Map/AbstractTypedMap.php index 80cec2e22..ff9f69177 100644 --- a/vendor/ramsey/collection/src/Map/AbstractTypedMap.php +++ b/vendor/ramsey/collection/src/Map/AbstractTypedMap.php @@ -21,6 +21,12 @@ use Ramsey\Collection\Tool\ValueToStringTrait; /** * This class provides a basic implementation of `TypedMapInterface`, to * minimize the effort required to implement this interface. + * + * @phpstan-ignore-next-line + * @template K as array-key + * @template T + * @template-extends AbstractMap + * @template-implements TypedMapInterface */ abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface { @@ -28,16 +34,22 @@ abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface use ValueToStringTrait; /** - * Sets the given value to the given offset in the map. + * @param K|null $offset + * @param T $value * - * @param mixed $offset The offset to set. - * @param mixed $value The value to set at the given offset. + * @inheritDoc * - * @throws InvalidArgumentException if the offset or value do not match the - * expected types. + * @psalm-suppress MoreSpecificImplementedParamType */ public function offsetSet($offset, $value): void { + if ($offset === null) { + throw new InvalidArgumentException( + 'Map elements are key/value pairs; a key must be provided for ' + . 'value ' . var_export($value, true) + ); + } + if ($this->checkType($this->getKeyType(), $offset) === false) { throw new InvalidArgumentException( 'Key must be of type ' . $this->getKeyType() . '; key is ' diff --git a/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php b/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php index f97e21728..3274dc9de 100644 --- a/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php +++ b/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php @@ -16,6 +16,9 @@ namespace Ramsey\Collection\Map; /** * `AssociativeArrayMap` represents a standard associative array object. + * + * @template T + * @template-extends AbstractMap */ class AssociativeArrayMap extends AbstractMap { diff --git a/vendor/ramsey/collection/src/Map/MapInterface.php b/vendor/ramsey/collection/src/Map/MapInterface.php index 500bdb2d0..04e52a238 100644 --- a/vendor/ramsey/collection/src/Map/MapInterface.php +++ b/vendor/ramsey/collection/src/Map/MapInterface.php @@ -20,13 +20,16 @@ use Ramsey\Collection\ArrayInterface; * An object that maps keys to values. * * A map cannot contain duplicate keys; each key can map to at most one value. + * + * @template T + * @template-extends ArrayInterface */ interface MapInterface extends ArrayInterface { /** * Returns `true` if this map contains a mapping for the specified key. * - * @param mixed $key The key to check in the map. + * @param array-key $key The key to check in the map. */ public function containsKey($key): bool; @@ -35,14 +38,15 @@ interface MapInterface extends ArrayInterface * * This performs a strict type check on the value. * - * @param mixed $value The value to check in the map. + * @param T $value The value to check in the map. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function containsValue($value): bool; /** * Return an array of the keys contained in this map. * - * @return mixed[] + * @return list */ public function keys(): array; @@ -51,11 +55,12 @@ interface MapInterface extends ArrayInterface * map contains no mapping for the key, or (optionally) `$defaultValue` if * this map contains no mapping for the key. * - * @param mixed $key The key to return from the map. - * @param mixed $defaultValue The default value to use if `$key` is not found. + * @param array-key $key The key to return from the map. + * @param T|null $defaultValue The default value to use if `$key` is not found. * - * @return mixed|null the value or `null` if the key could not be found. + * @return T|null the value or `null` if the key could not be found. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function get($key, $defaultValue = null); /** @@ -64,12 +69,13 @@ interface MapInterface extends ArrayInterface * If the map previously contained a mapping for the key, the old value is * replaced by the specified value. * - * @param mixed $key The key to put or replace in the map. - * @param mixed $value The value to store at `$key`. + * @param array-key $key The key to put or replace in the map. + * @param T $value The value to store at `$key`. * - * @return mixed|null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function put($key, $value); /** @@ -79,22 +85,24 @@ interface MapInterface extends ArrayInterface * If there is already a value associated with `$key`, this returns that * value without replacing it. * - * @param mixed $key The key to put in the map. - * @param mixed $value The value to store at `$key`. + * @param array-key $key The key to put in the map. + * @param T $value The value to store at `$key`. * - * @return mixed|null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function putIfAbsent($key, $value); /** * Removes the mapping for a key from this map if it is present. * - * @param mixed $key The key to remove from the map. + * @param array-key $key The key to remove from the map. * - * @return mixed|null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function remove($key); /** @@ -103,23 +111,25 @@ interface MapInterface extends ArrayInterface * * This performs a strict type check on the value. * - * @param mixed $key The key to remove from the map. - * @param mixed $value The value to match. + * @param array-key $key The key to remove from the map. + * @param T $value The value to match. * * @return bool true if the value was removed. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function removeIf($key, $value): bool; /** * Replaces the entry for the specified key only if it is currently mapped * to some value. * - * @param mixed $key The key to replace. - * @param mixed $value The value to set at `$key`. + * @param array-key $key The key to replace. + * @param T $value The value to set at `$key`. * - * @return mixed|null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function replace($key, $value); /** @@ -128,11 +138,12 @@ interface MapInterface extends ArrayInterface * * This performs a strict type check on the value. * - * @param mixed $key The key to remove from the map. - * @param mixed $oldValue The value to match. - * @param mixed $newValue The value to use as a replacement. + * @param array-key $key The key to remove from the map. + * @param T $oldValue The value to match. + * @param T $newValue The value to use as a replacement. * * @return bool true if the value was replaced. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function replaceIf($key, $oldValue, $newValue): bool; } diff --git a/vendor/ramsey/collection/src/Map/NamedParameterMap.php b/vendor/ramsey/collection/src/Map/NamedParameterMap.php index 7adfa0afd..ecc52f73a 100644 --- a/vendor/ramsey/collection/src/Map/NamedParameterMap.php +++ b/vendor/ramsey/collection/src/Map/NamedParameterMap.php @@ -25,6 +25,8 @@ use function is_int; /** * `NamedParameterMap` represents a mapping of values to a set of named keys * that may optionally be typed + * + * @template-extends AbstractMap */ class NamedParameterMap extends AbstractMap { @@ -34,15 +36,15 @@ class NamedParameterMap extends AbstractMap /** * Named parameters defined for this map. * - * @var array + * @var array */ protected $namedParameters; /** * Constructs a new `NamedParameterMap`. * - * @param array $namedParameters The named parameters defined for this map. - * @param mixed[] $data An initial set of data to set on this map. + * @param array $namedParameters The named parameters defined for this map. + * @param array $data An initial set of data to set on this map. */ public function __construct(array $namedParameters, array $data = []) { @@ -53,7 +55,7 @@ class NamedParameterMap extends AbstractMap /** * Returns named parameters set for this `NamedParameterMap`. * - * @return array + * @return array */ public function getNamedParameters(): array { @@ -61,17 +63,17 @@ class NamedParameterMap extends AbstractMap } /** - * Sets the given value to the given offset in the map. - * - * @param mixed $offset The offset to set. - * @param mixed $value The value to set at the given offset. - * - * @throws InvalidArgumentException if the offset provided is not a - * defined named parameter, or if the value is not of the type defined - * for the given named parameter. + * @inheritDoc */ public function offsetSet($offset, $value): void { + if ($offset === null) { + throw new InvalidArgumentException( + 'Map elements are key/value pairs; a key must be provided for ' + . 'value ' . var_export($value, true) + ); + } + if (!array_key_exists($offset, $this->namedParameters)) { throw new InvalidArgumentException( 'Attempting to set value for unconfigured parameter \'' @@ -94,9 +96,9 @@ class NamedParameterMap extends AbstractMap * Given an array of named parameters, constructs a proper mapping of * named parameters to types. * - * @param array $namedParameters The named parameters to filter. + * @param array $namedParameters The named parameters to filter. * - * @return array + * @return array */ protected function filterNamedParameters(array $namedParameters): array { @@ -105,11 +107,11 @@ class NamedParameterMap extends AbstractMap foreach ($namedParameters as $key => $value) { if (is_int($key)) { - $names[] = (string) $value; + $names[] = $value; $types[] = 'mixed'; } else { $names[] = $key; - $types[] = (string) $value; + $types[] = $value; } } diff --git a/vendor/ramsey/collection/src/Map/TypedMap.php b/vendor/ramsey/collection/src/Map/TypedMap.php index 84d075f80..752475fee 100644 --- a/vendor/ramsey/collection/src/Map/TypedMap.php +++ b/vendor/ramsey/collection/src/Map/TypedMap.php @@ -79,6 +79,11 @@ use Ramsey\Collection\Tool\TypeTrait; * } * } * ``` + * + * @phpstan-ignore-next-line + * @template K as array-key + * @template T + * @template-extends AbstractTypedMap */ class TypedMap extends AbstractTypedMap { @@ -97,7 +102,7 @@ class TypedMap extends AbstractTypedMap /** * The data type of values stored in this collection. * - * A map values's type is immutable once it is set. For this reason, this + * A map value's type is immutable once it is set. For this reason, this * property is set private. * * @var string data type of the map value. @@ -110,7 +115,7 @@ class TypedMap extends AbstractTypedMap * * @param string $keyType The data type of the map's keys. * @param string $valueType The data type of the map's values. - * @param mixed[] $data The initial data to set for this map. + * @param array $data The initial data to set for this map. */ public function __construct(string $keyType, string $valueType, array $data = []) { @@ -119,17 +124,11 @@ class TypedMap extends AbstractTypedMap parent::__construct($data); } - /** - * Return the type used on the key. - */ public function getKeyType(): string { return $this->keyType; } - /** - * Return the type forced on the values. - */ public function getValueType(): string { return $this->valueType; diff --git a/vendor/ramsey/collection/src/Map/TypedMapInterface.php b/vendor/ramsey/collection/src/Map/TypedMapInterface.php index 54c783695..51b6a81a2 100644 --- a/vendor/ramsey/collection/src/Map/TypedMapInterface.php +++ b/vendor/ramsey/collection/src/Map/TypedMapInterface.php @@ -17,6 +17,9 @@ namespace Ramsey\Collection\Map; /** * A `TypedMapInterface` represents a map of elements where key and value are * typed. + * + * @template T + * @template-extends MapInterface */ interface TypedMapInterface extends MapInterface { diff --git a/vendor/ramsey/collection/src/Queue.php b/vendor/ramsey/collection/src/Queue.php index 4f53ff5e6..4af2fdf76 100644 --- a/vendor/ramsey/collection/src/Queue.php +++ b/vendor/ramsey/collection/src/Queue.php @@ -22,6 +22,10 @@ use Ramsey\Collection\Tool\ValueToStringTrait; /** * This class provides a basic implementation of `QueueInterface`, to minimize * the effort required to implement this interface. + * + * @template T + * @template-extends AbstractArray + * @template-implements QueueInterface */ class Queue extends AbstractArray implements QueueInterface { @@ -50,7 +54,7 @@ class Queue extends AbstractArray implements QueueInterface * specified data. * * @param string $queueType The type (FQCN) associated with this queue. - * @param mixed[] $data The initial items to store in the collection. + * @param array $data The initial items to store in the collection. */ public function __construct(string $queueType, array $data = []) { @@ -59,19 +63,11 @@ class Queue extends AbstractArray implements QueueInterface } /** - * Sets the given value to the given offset in the queue. + * {@inheritDoc} * * Since arbitrary offsets may not be manipulated in a queue, this method * serves only to fulfill the `ArrayAccess` interface requirements. It is * invoked by other operations when adding values to the queue. - * - * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() - * - * @param mixed|null $offset The offset is ignored and is treated as `null`. - * @param mixed $value The value to set at the given offset. - * - * @throws InvalidArgumentException when the value does not match the - * specified type for this queue. */ public function offsetSet($offset, $value): void { @@ -86,19 +82,7 @@ class Queue extends AbstractArray implements QueueInterface } /** - * Ensures that this queue contains the specified element. - * - * This method differs from `offer()` only in that it throws an exception if - * it cannot add the element to the queue. - * - * @see self::offer() - * - * @param mixed $element The element to add to this queue. - * - * @return bool `true` if this queue changed as a result of the call. - * - * @throws InvalidArgumentException when the element does not match the - * specified type for this queue. + * @inheritDoc */ public function add($element): bool { @@ -108,39 +92,23 @@ class Queue extends AbstractArray implements QueueInterface } /** - * Retrieves, but does not remove, the head of this queue. - * - * This method differs from `peek()` only in that it throws an exception if - * this queue is empty. - * - * @see self::peek() - * - * @return mixed the head of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ public function element() { - if ($this->count() === 0) { + $element = $this->peek(); + + if ($element === null) { throw new NoSuchElementException( 'Can\'t return element from Queue. Queue is empty.' ); } - return $this[$this->index]; + return $element; } /** - * Inserts the specified element into this queue. - * - * This method differs from `add()` only in that it does not throw an - * exception if it cannot add the element to the queue. - * - * @see self::add() - * - * @param mixed $element The element to add to this queue. - * - * @return bool `true` if the element was added to this queue, else `false`. + * @inheritDoc */ public function offer($element): bool { @@ -152,12 +120,7 @@ class Queue extends AbstractArray implements QueueInterface } /** - * Retrieves, but does not remove, the head of this queue, or returns `null` - * if this queue is empty. - * - * @see self::element() - * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @inheritDoc */ public function peek() { @@ -169,12 +132,7 @@ class Queue extends AbstractArray implements QueueInterface } /** - * Retrieves and removes the head of this queue, or returns `null` - * if this queue is empty. - * - * @see self::remove() - * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @inheritDoc */ public function poll() { @@ -191,34 +149,19 @@ class Queue extends AbstractArray implements QueueInterface } /** - * Retrieves and removes the head of this queue. - * - * This method differs from `poll()` only in that it throws an exception if - * this queue is empty. - * - * @see self::poll() - * - * @return mixed the head of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ public function remove() { - if ($this->count() === 0) { + $head = $this->poll(); + + if ($head === null) { throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); } - $head = $this[$this->index]; - - unset($this[$this->index]); - $this->index++; - return $head; } - /** - * Returns the type associated with this queue. - */ public function getType(): string { return $this->queueType; diff --git a/vendor/ramsey/collection/src/QueueInterface.php b/vendor/ramsey/collection/src/QueueInterface.php index 6c7f2ac2c..7ebbb5d06 100644 --- a/vendor/ramsey/collection/src/QueueInterface.php +++ b/vendor/ramsey/collection/src/QueueInterface.php @@ -92,6 +92,9 @@ use Ramsey\Collection\Exception\NoSuchElementException; * Even in the implementations that permit it, `null` should not be inserted * into a queue, as `null` is also used as a special return value by the * `poll()` method to indicate that the queue contains no elements. + * + * @template T + * @template-extends ArrayInterface */ interface QueueInterface extends ArrayInterface { @@ -116,7 +119,7 @@ interface QueueInterface extends ArrayInterface * * @see self::offer() * - * @param mixed $element The element to add to this queue. + * @param T $element The element to add to this queue. * * @return bool `true` if this queue changed as a result of the call. * @@ -125,6 +128,7 @@ interface QueueInterface extends ArrayInterface * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function add($element): bool; /** @@ -135,7 +139,7 @@ interface QueueInterface extends ArrayInterface * * @see self::peek() * - * @return mixed the head of this queue. + * @return T the head of this queue. * * @throws NoSuchElementException if this queue is empty. */ @@ -151,10 +155,11 @@ interface QueueInterface extends ArrayInterface * * @see self::add() * - * @param mixed $element The element to add to this queue. + * @param T $element The element to add to this queue. * * @return bool `true` if the element was added to this queue, else `false`. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function offer($element): bool; /** @@ -163,7 +168,7 @@ interface QueueInterface extends ArrayInterface * * @see self::element() * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ public function peek(); @@ -173,7 +178,7 @@ interface QueueInterface extends ArrayInterface * * @see self::remove() * - * @return mixed|null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ public function poll(); @@ -185,7 +190,7 @@ interface QueueInterface extends ArrayInterface * * @see self::poll() * - * @return mixed the head of this queue. + * @return T the head of this queue. * * @throws NoSuchElementException if this queue is empty. */ diff --git a/vendor/ramsey/collection/src/Set.php b/vendor/ramsey/collection/src/Set.php index 42fb66c36..ac1c5cbf0 100644 --- a/vendor/ramsey/collection/src/Set.php +++ b/vendor/ramsey/collection/src/Set.php @@ -34,6 +34,9 @@ namespace Ramsey\Collection; * $bar = new \My\Foo(); * $set->add($bar); // returns TRUE, $bar !== $foo * ``` + * + * @template T + * @template-extends AbstractSet */ class Set extends AbstractSet { @@ -51,7 +54,7 @@ class Set extends AbstractSet * specified data. * * @param string $setType The type (FQCN) associated with this set. - * @param mixed[] $data The initial items to store in the set. + * @param array $data The initial items to store in the set. */ public function __construct(string $setType, array $data = []) { @@ -59,9 +62,6 @@ class Set extends AbstractSet parent::__construct($data); } - /** - * Returns the type associated with this set. - */ public function getType(): string { return $this->setType; diff --git a/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php b/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php index 7bc4878db..f9be1be28 100644 --- a/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php +++ b/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php @@ -29,7 +29,7 @@ trait ValueExtractorTrait /** * Extracts the value of the given property or method from the object. * - * @param object $object The object to extract the value from. + * @param mixed $object The object to extract the value from. * @param string $propertyOrMethod The property or method for which the * value should be extracted. * @@ -37,8 +37,12 @@ trait ValueExtractorTrait * * @throws ValueExtractionException if the method or property is not defined. */ - protected function extractValue(object $object, string $propertyOrMethod) + protected function extractValue($object, string $propertyOrMethod) { + if (!is_object($object)) { + throw new ValueExtractionException('Unable to extract a value from a non-object'); + } + if (property_exists($object, $propertyOrMethod)) { return $object->$propertyOrMethod; } diff --git a/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php b/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php index 34a9a0a68..721ade002 100644 --- a/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php +++ b/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php @@ -71,7 +71,12 @@ trait ValueToStringTrait return '(' . get_resource_type($value) . ' resource #' . (int) $value . ')'; } - // after this line $value is an object since is not null, scalar, array or resource + // If we don't know what it is, use var_export(). + if (!is_object($value)) { + return '(' . var_export($value, true) . ')'; + } + + // From here, $value should be an object. // __toString() is implemented if (is_callable([$value, '__toString'])) { -- cgit v1.2.3 From 0cd4c3410121b9b584dc1b108e555832843b2576 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 15 Feb 2021 18:35:40 +0000 Subject: compser update sabre/dav /vobject --- composer.lock | 25 +- vendor/composer/InstalledVersions.php | 16 +- vendor/composer/installed.json | 29 +- vendor/composer/installed.php | 16 +- vendor/sabre/dav/.gitignore | 40 - vendor/sabre/dav/.travis.yml | 2 +- vendor/sabre/dav/CHANGELOG.md | 2526 -------------------- vendor/sabre/dav/CONTRIBUTING.md | 109 - vendor/sabre/dav/bin/build.php | 8 +- vendor/sabre/dav/bin/googlecode_upload.py | 0 vendor/sabre/dav/bin/migrateto20.php | 5 +- vendor/sabre/dav/bin/migrateto21.php | 2 +- vendor/sabre/dav/bin/migrateto30.php | 2 +- vendor/sabre/dav/bin/migrateto32.php | 2 +- vendor/sabre/dav/bin/sabredav.php | 2 +- vendor/sabre/dav/composer.json | 2 +- vendor/sabre/dav/lib/CalDAV/Backend/PDO.php | 23 +- .../dav/lib/CalDAV/CalendarQueryValidator.php | 26 +- vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php | 1 + vendor/sabre/dav/lib/CalDAV/SharingPlugin.php | 4 - .../dav/lib/CalDAV/Xml/Filter/CalendarData.php | 1 - vendor/sabre/dav/lib/CardDAV/Backend/PDO.php | 3 +- vendor/sabre/dav/lib/CardDAV/Plugin.php | 21 +- .../CardDAV/Xml/Request/AddressBookQueryReport.php | 1 - vendor/sabre/dav/lib/DAV/Browser/Plugin.php | 4 +- .../dav/lib/DAV/Exception/MethodNotAllowed.php | 3 +- vendor/sabre/dav/lib/DAV/FSExt/File.php | 5 +- vendor/sabre/dav/lib/DAV/Server.php | 2 +- vendor/sabre/dav/lib/DAV/Sharing/Plugin.php | 1 - vendor/sabre/dav/lib/DAV/Tree.php | 2 + vendor/sabre/dav/lib/DAV/Version.php | 2 +- .../dav/lib/DAV/Xml/Property/GetLastModified.php | 3 +- vendor/sabre/dav/lib/DAV/Xml/Property/Href.php | 3 - .../dav/lib/DAV/Xml/Property/ResourceType.php | 3 +- vendor/sabre/dav/phpstan.neon | 2 - .../tests/Sabre/CalDAV/Backend/AbstractPDOTest.php | 1397 ----------- .../tests/Sabre/CalDAV/Backend/AbstractTest.php | 184 -- .../sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php | 247 -- .../tests/Sabre/CalDAV/Backend/PDOMySQLTest.php | 10 - .../tests/Sabre/CalDAV/Backend/PDOSqliteTest.php | 10 - .../dav/tests/Sabre/CalDAV/CalendarObjectTest.php | 351 --- .../tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php | 121 - .../Sabre/CalDAV/CalendarQueryValidatorTest.php | 823 ------- .../sabre/dav/tests/Sabre/CalDAV/CalendarTest.php | 229 -- .../CalDAV/ExpandEventsDTSTARTandDTENDTest.php | 114 - .../ExpandEventsDTSTARTandDTENDbyDayTest.php | 104 - .../Sabre/CalDAV/ExpandEventsDoubleEventsTest.php | 104 - .../dav/tests/Sabre/CalDAV/FreeBusyReportTest.php | 158 -- .../Sabre/CalDAV/GetEventsByTimerangeTest.php | 82 - .../dav/tests/Sabre/CalDAV/ICSExportPluginTest.php | 366 --- .../sabre/dav/tests/Sabre/CalDAV/Issue166Test.php | 63 - .../sabre/dav/tests/Sabre/CalDAV/Issue172Test.php | 140 -- .../sabre/dav/tests/Sabre/CalDAV/Issue203Test.php | 138 -- .../sabre/dav/tests/Sabre/CalDAV/Issue205Test.php | 99 - .../sabre/dav/tests/Sabre/CalDAV/Issue211Test.php | 90 - .../sabre/dav/tests/Sabre/CalDAV/Issue220Test.php | 101 - .../sabre/dav/tests/Sabre/CalDAV/Issue228Test.php | 80 - .../Sabre/CalDAV/Notifications/CollectionTest.php | 78 - .../tests/Sabre/CalDAV/Notifications/NodeTest.php | 88 - vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php | 1071 --------- .../Sabre/CalDAV/Principal/CollectionTest.php | 20 - .../tests/Sabre/CalDAV/Principal/ProxyReadTest.php | 91 - .../Sabre/CalDAV/Principal/ProxyWriteTest.php | 39 - .../dav/tests/Sabre/CalDAV/Principal/UserTest.php | 111 - .../dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php | 47 - .../dav/tests/Sabre/CalDAV/SharedCalendarTest.php | 172 -- .../dav/tests/Sabre/CalDAV/SharingPluginTest.php | 383 --- vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php | 102 - .../dav/tests/Sabre/CalDAV/ValidateICalTest.php | 392 --- .../dav/tests/Sabre/CardDAV/AbstractPluginTest.php | 43 - .../tests/Sabre/CardDAV/AddressBookQueryTest.php | 351 --- .../tests/Sabre/CardDAV/AddressBookRootTest.php | 31 - .../dav/tests/Sabre/CardDAV/AddressBookTest.php | 171 -- .../Sabre/CardDAV/Backend/AbstractPDOTest.php | 351 --- .../sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php | 257 -- .../tests/Sabre/CardDAV/Backend/PDOMySQLTest.php | 10 - .../tests/Sabre/CardDAV/Backend/PDOSqliteTest.php | 10 - vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php | 194 -- .../dav/tests/Sabre/CardDAV/IDirectoryTest.php | 28 - .../sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php | 99 - .../sabre/dav/tests/Sabre/CardDAV/PluginTest.php | 101 - .../Sabre/CardDAV/SogoStripContentTypeTest.php | 67 - .../dav/tests/Sabre/CardDAV/VCFExportTest.php | 130 - .../dav/tests/Sabre/CardDAV/ValidateFilterTest.php | 204 -- .../dav/tests/Sabre/CardDAV/ValidateVCardTest.php | 293 --- .../sabre/dav/tests/Sabre/DAV/AbstractServer.php | 62 - .../Sabre/DAV/Auth/Backend/AbstractBasicTest.php | 90 - .../Sabre/DAV/Auth/Backend/AbstractDigestTest.php | 134 -- .../Sabre/DAV/Auth/Backend/AbstractPDOTest.php | 42 - .../tests/Sabre/DAV/Auth/Backend/ApacheTest.php | 72 - .../dav/tests/Sabre/DAV/Auth/Backend/FileTest.php | 38 - .../dav/tests/Sabre/DAV/Auth/Backend/Mock.php | 81 - .../tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php | 10 - .../tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php | 10 - .../sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php | 127 - vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php | 124 - .../Sabre/DAV/Browser/GuessContentTypeTest.php | 67 - .../Sabre/DAV/Browser/MapGetToPropFindTest.php | 40 - .../dav/tests/Sabre/DAV/Browser/PluginTest.php | 176 -- vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php | 36 - vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php | 285 --- .../dav/tests/Sabre/DAV/Exception/LockedTest.php | 67 - .../Sabre/DAV/Exception/PaymentRequiredTest.php | 14 - vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php | 27 - .../sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php | 99 - .../sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php | 252 -- .../dav/tests/Sabre/DAV/HTTPPreferParsingTest.php | 175 -- .../sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php | 131 - vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php | 354 --- vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php | 93 - .../tests/Sabre/DAV/Locks/Backend/AbstractTest.php | 189 -- .../dav/tests/Sabre/DAV/Locks/Backend/FileTest.php | 21 - .../tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php | 10 - .../dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php | 20 - .../sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php | 119 - .../sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php | 886 ------- .../sabre/dav/tests/Sabre/DAV/Mock/Collection.php | 157 -- vendor/sabre/dav/tests/Sabre/DAV/Mock/File.php | 151 -- .../sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php | 54 - .../sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php | 90 - .../dav/tests/Sabre/DAV/PartialUpdate/FileMock.php | 111 - .../tests/Sabre/DAV/PartialUpdate/PluginTest.php | 122 - .../Sabre/DAV/PartialUpdate/SpecificationTest.php | 90 - .../sabre/dav/tests/Sabre/DAV/ServerEventsTest.php | 114 - .../sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php | 354 --- .../sabre/dav/tests/Sabre/DAV/ServerPluginTest.php | 96 - .../sabre/dav/tests/Sabre/DAV/ServerPropsTest.php | 194 -- .../sabre/dav/tests/Sabre/DAV/ServerRangeTest.php | 252 -- .../sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php | 433 ---- .../tests/Sabre/DAV/ServerUpdatePropertiesTest.php | 97 - .../sabre/dav/tests/Sabre/DAV/SimpleFileTest.php | 19 - .../sabre/dav/tests/Sabre/DAV/StringUtilTest.php | 119 - .../tests/Sabre/DAV/TemporaryFileFilterTest.php | 204 -- vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php | 35 - vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php | 238 -- vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php | 24 - .../sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php | 311 --- .../dav/tests/Sabre/DAVACL/AllowAccessTest.php | 120 - .../dav/tests/Sabre/DAVACL/BlockAccessTest.php | 180 -- .../Sabre/DAVACL/Exception/AceConflictTest.php | 37 - .../Exception/NeedPrivilegesExceptionTest.php | 47 - .../Sabre/DAVACL/Exception/NoAbstractTest.php | 37 - .../Exception/NotRecognizedPrincipalTest.php | 37 - .../DAVACL/Exception/NotSupportedPrivilegeTest.php | 37 - .../tests/Sabre/DAVACL/ExpandPropertiesTest.php | 308 --- .../sabre/dav/tests/Sabre/DAVACL/MockACLNode.php | 49 - .../sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php | 58 - .../dav/tests/Sabre/DAVACL/PluginAdminTest.php | 76 - .../tests/Sabre/DAVACL/PluginPropertiesTest.php | 399 ---- .../Sabre/DAVACL/PluginUpdatePropertiesTest.php | 111 - .../DAVACL/PrincipalBackend/AbstractPDOTest.php | 219 -- .../tests/Sabre/DAVACL/PrincipalBackend/Mock.php | 158 -- .../Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php | 10 - .../DAVACL/PrincipalBackend/PDOSqliteTest.php | 10 - .../tests/Sabre/DAVACL/PrincipalCollectionTest.php | 55 - .../Sabre/DAVACL/PrincipalPropertySearchTest.php | 389 --- .../DAVACL/PrincipalSearchPropertySetTest.php | 135 -- .../sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php | 192 -- .../dav/tests/Sabre/DAVACL/SimplePluginTest.php | 302 --- vendor/sabre/dav/tests/Sabre/DAVServerTest.php | 305 --- vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php | 23 - vendor/sabre/dav/tests/Sabre/TestUtil.php | 66 - vendor/sabre/dav/tests/bootstrap.php | 65 - vendor/sabre/vobject/.gitignore | 9 - vendor/sabre/vobject/.php_cs.dist | 12 - vendor/sabre/vobject/.travis.yml | 49 - vendor/sabre/vobject/CHANGELOG.md | 868 ------- vendor/sabre/vobject/bin/bench.php | 0 .../sabre/vobject/bin/bench_freebusygenerator.php | 2 +- vendor/sabre/vobject/bin/bench_manipulatevcard.php | 2 +- vendor/sabre/vobject/bin/fetch_windows_zones.php | 5 +- vendor/sabre/vobject/bin/generateicalendardata.php | 4 +- vendor/sabre/vobject/bin/mergeduplicates.php | 4 +- vendor/sabre/vobject/bin/rrulebench.php | 2 +- vendor/sabre/vobject/composer.json | 3 +- vendor/sabre/vobject/lib/Cli.php | 9 +- vendor/sabre/vobject/lib/Component.php | 4 +- vendor/sabre/vobject/lib/Component/VCalendar.php | 2 +- vendor/sabre/vobject/lib/Component/VCard.php | 2 +- vendor/sabre/vobject/lib/FreeBusyData.php | 8 +- vendor/sabre/vobject/lib/FreeBusyGenerator.php | 3 +- vendor/sabre/vobject/lib/Parameter.php | 8 +- vendor/sabre/vobject/lib/Parser/MimeDir.php | 2 +- vendor/sabre/vobject/lib/Property/Boolean.php | 3 +- .../vobject/lib/Property/ICalendar/CalAddress.php | 3 +- .../vobject/lib/Property/ICalendar/DateTime.php | 2 +- vendor/sabre/vobject/lib/Property/IntegerValue.php | 3 +- .../vobject/lib/Property/VCard/LanguageTag.php | 3 +- vendor/sabre/vobject/lib/Recur/EventIterator.php | 2 +- vendor/sabre/vobject/lib/Recur/RRuleIterator.php | 12 +- vendor/sabre/vobject/lib/Version.php | 2 +- .../vobject/lib/timezonedata/windowszones.php | 17 +- vendor/sabre/vobject/phpstan.neon | 4 - vendor/sabre/vobject/tests/bootstrap.php | 15 - vendor/sabre/vobject/tests/phpunit.xml | 21 - 195 files changed, 173 insertions(+), 24294 deletions(-) delete mode 100644 vendor/sabre/dav/.gitignore delete mode 100644 vendor/sabre/dav/CHANGELOG.md delete mode 100644 vendor/sabre/dav/CONTRIBUTING.md mode change 100644 => 100755 vendor/sabre/dav/bin/build.php mode change 100644 => 100755 vendor/sabre/dav/bin/googlecode_upload.py mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto20.php mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto21.php mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto30.php mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto32.php mode change 100644 => 100755 vendor/sabre/dav/bin/sabredav.php delete mode 100644 vendor/sabre/dav/phpstan.neon delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Mock/Collection.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Mock/File.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/DAVServerTest.php delete mode 100644 vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php delete mode 100644 vendor/sabre/dav/tests/Sabre/TestUtil.php delete mode 100644 vendor/sabre/dav/tests/bootstrap.php delete mode 100644 vendor/sabre/vobject/.gitignore delete mode 100644 vendor/sabre/vobject/.php_cs.dist delete mode 100644 vendor/sabre/vobject/.travis.yml delete mode 100644 vendor/sabre/vobject/CHANGELOG.md mode change 100644 => 100755 vendor/sabre/vobject/bin/bench.php mode change 100644 => 100755 vendor/sabre/vobject/bin/fetch_windows_zones.php mode change 100644 => 100755 vendor/sabre/vobject/bin/generateicalendardata.php mode change 100644 => 100755 vendor/sabre/vobject/bin/mergeduplicates.php delete mode 100644 vendor/sabre/vobject/phpstan.neon delete mode 100644 vendor/sabre/vobject/tests/bootstrap.php delete mode 100644 vendor/sabre/vobject/tests/phpunit.xml diff --git a/composer.lock b/composer.lock index 293d93d3d..18d2cd586 100644 --- a/composer.lock +++ b/composer.lock @@ -891,16 +891,16 @@ }, { "name": "sabre/dav", - "version": "4.1.3", + "version": "4.1.5", "source": { "type": "git", "url": "https://github.com/sabre-io/dav.git", - "reference": "b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e" + "reference": "c1afdc77a95efea6ee40c03c45f57c3c0c80ec22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/dav/zipball/b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e", - "reference": "b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e", + "url": "https://api.github.com/repos/sabre-io/dav/zipball/c1afdc77a95efea6ee40c03c45f57c3c0c80ec22", + "reference": "c1afdc77a95efea6ee40c03c45f57c3c0c80ec22", "shasum": "" }, "require": { @@ -924,7 +924,7 @@ }, "require-dev": { "evert/phpdoc-md": "~0.1.0", - "friendsofphp/php-cs-fixer": "^2.16.7", + "friendsofphp/php-cs-fixer": "^2.17.1", "monolog/monolog": "^1.18", "phpstan/phpstan": "^0.12", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" @@ -973,7 +973,7 @@ "issues": "https://github.com/sabre-io/dav/issues", "source": "https://github.com/fruux/sabre-dav" }, - "time": "2020-11-09T07:48:35+00:00" + "time": "2021-02-12T07:54:23+00:00" }, { "name": "sabre/event", @@ -1163,16 +1163,16 @@ }, { "name": "sabre/vobject", - "version": "4.3.3", + "version": "4.3.5", "source": { "type": "git", "url": "https://github.com/sabre-io/vobject.git", - "reference": "58f9f9b46a1080c0130bd86f4df9a568aacb9c79" + "reference": "d8a0a9ae215a8acfb51afc29101c7344670b9c83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/vobject/zipball/58f9f9b46a1080c0130bd86f4df9a568aacb9c79", - "reference": "58f9f9b46a1080c0130bd86f4df9a568aacb9c79", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/d8a0a9ae215a8acfb51afc29101c7344670b9c83", + "reference": "d8a0a9ae215a8acfb51afc29101c7344670b9c83", "shasum": "" }, "require": { @@ -1181,8 +1181,9 @@ "sabre/xml": "^2.1" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.16.7", + "friendsofphp/php-cs-fixer": "~2.17.1", "phpstan/phpstan": "^0.12", + "phpunit/php-invoker": "^2.0 || ^3.1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" }, "suggest": { @@ -1262,7 +1263,7 @@ "issues": "https://github.com/sabre-io/vobject/issues", "source": "https://github.com/fruux/sabre-vobject" }, - "time": "2020-11-09T04:31:38+00:00" + "time": "2021-02-12T06:28:04+00:00" }, { "name": "sabre/xml", diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index fd17711f2..88cdba06c 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', + 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -169,12 +169,12 @@ private static $installed = array ( ), 'sabre/dav' => array ( - 'pretty_version' => '4.1.3', - 'version' => '4.1.3.0', + 'pretty_version' => '4.1.5', + 'version' => '4.1.5.0', 'aliases' => array ( ), - 'reference' => 'b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e', + 'reference' => 'c1afdc77a95efea6ee40c03c45f57c3c0c80ec22', ), 'sabre/event' => array ( @@ -205,12 +205,12 @@ private static $installed = array ( ), 'sabre/vobject' => array ( - 'pretty_version' => '4.3.3', - 'version' => '4.3.3.0', + 'pretty_version' => '4.3.5', + 'version' => '4.3.5.0', 'aliases' => array ( ), - 'reference' => '58f9f9b46a1080c0130bd86f4df9a568aacb9c79', + 'reference' => 'd8a0a9ae215a8acfb51afc29101c7344670b9c83', ), 'sabre/xml' => array ( @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', + 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', ), ), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 91d335ca0..ab8f9899a 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -896,17 +896,17 @@ }, { "name": "sabre/dav", - "version": "4.1.3", - "version_normalized": "4.1.3.0", + "version": "4.1.5", + "version_normalized": "4.1.5.0", "source": { "type": "git", "url": "https://github.com/sabre-io/dav.git", - "reference": "b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e" + "reference": "c1afdc77a95efea6ee40c03c45f57c3c0c80ec22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/dav/zipball/b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e", - "reference": "b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e", + "url": "https://api.github.com/repos/sabre-io/dav/zipball/c1afdc77a95efea6ee40c03c45f57c3c0c80ec22", + "reference": "c1afdc77a95efea6ee40c03c45f57c3c0c80ec22", "shasum": "" }, "require": { @@ -930,7 +930,7 @@ }, "require-dev": { "evert/phpdoc-md": "~0.1.0", - "friendsofphp/php-cs-fixer": "^2.16.7", + "friendsofphp/php-cs-fixer": "^2.17.1", "monolog/monolog": "^1.18", "phpstan/phpstan": "^0.12", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" @@ -940,7 +940,7 @@ "ext-imap": "*", "ext-pdo": "*" }, - "time": "2020-11-09T07:48:35+00:00", + "time": "2021-02-12T07:54:23+00:00", "bin": [ "bin/sabredav", "bin/naturalselection" @@ -1180,17 +1180,17 @@ }, { "name": "sabre/vobject", - "version": "4.3.3", - "version_normalized": "4.3.3.0", + "version": "4.3.5", + "version_normalized": "4.3.5.0", "source": { "type": "git", "url": "https://github.com/sabre-io/vobject.git", - "reference": "58f9f9b46a1080c0130bd86f4df9a568aacb9c79" + "reference": "d8a0a9ae215a8acfb51afc29101c7344670b9c83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/vobject/zipball/58f9f9b46a1080c0130bd86f4df9a568aacb9c79", - "reference": "58f9f9b46a1080c0130bd86f4df9a568aacb9c79", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/d8a0a9ae215a8acfb51afc29101c7344670b9c83", + "reference": "d8a0a9ae215a8acfb51afc29101c7344670b9c83", "shasum": "" }, "require": { @@ -1199,14 +1199,15 @@ "sabre/xml": "^2.1" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.16.7", + "friendsofphp/php-cs-fixer": "~2.17.1", "phpstan/phpstan": "^0.12", + "phpunit/php-invoker": "^2.0 || ^3.1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" }, "suggest": { "hoa/bench": "If you would like to run the benchmark scripts" }, - "time": "2020-11-09T04:31:38+00:00", + "time": "2021-02-12T06:28:04+00:00", "bin": [ "bin/vobject", "bin/generate_vcards" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 7cad9b54b..2b6305c54 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', + 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -146,12 +146,12 @@ ), 'sabre/dav' => array ( - 'pretty_version' => '4.1.3', - 'version' => '4.1.3.0', + 'pretty_version' => '4.1.5', + 'version' => '4.1.5.0', 'aliases' => array ( ), - 'reference' => 'b903eeedfbdcd6cab7935661ec6dc2d90cdf8a1e', + 'reference' => 'c1afdc77a95efea6ee40c03c45f57c3c0c80ec22', ), 'sabre/event' => array ( @@ -182,12 +182,12 @@ ), 'sabre/vobject' => array ( - 'pretty_version' => '4.3.3', - 'version' => '4.3.3.0', + 'pretty_version' => '4.3.5', + 'version' => '4.3.5.0', 'aliases' => array ( ), - 'reference' => '58f9f9b46a1080c0130bd86f4df9a568aacb9c79', + 'reference' => 'd8a0a9ae215a8acfb51afc29101c7344670b9c83', ), 'sabre/xml' => array ( @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '18c8f1b903e90ca3632520b90d21ec3770bf6e0b', + 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', ), ), ); diff --git a/vendor/sabre/dav/.gitignore b/vendor/sabre/dav/.gitignore deleted file mode 100644 index f287cca1a..000000000 --- a/vendor/sabre/dav/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -# Unit tests -tests/temp -tests/.sabredav -tests/cov - -# Custom settings for tests -tests/config.user.php - -# PHPUnit test Cache -.phpunit.result.cache - -# ViM -*.swp - -# Composer -composer.lock -vendor - -# Composer binaries -bin/vobject -bin/generate_vcards -bin/phpdocmd - -# Assuming every .php file in the root is for testing -/*.php - -# Other testing stuff -/tmpdata -/data -/public - -# Build -build -build.properties - -# Docs -docs/api -docs/wikidocs - -.php_cs.cache diff --git a/vendor/sabre/dav/.travis.yml b/vendor/sabre/dav/.travis.yml index 95331ac0d..6214d80b3 100644 --- a/vendor/sabre/dav/.travis.yml +++ b/vendor/sabre/dav/.travis.yml @@ -27,7 +27,7 @@ matrix: include: - name: 'PHP8' dist: bionic - php: nightly + php: 8.0 env: - RUN_PHPCSFIXER="FALSE" - REPORT_COVERAGE="FALSE" diff --git a/vendor/sabre/dav/CHANGELOG.md b/vendor/sabre/dav/CHANGELOG.md deleted file mode 100644 index 9db36f927..000000000 --- a/vendor/sabre/dav/CHANGELOG.md +++ /dev/null @@ -1,2526 +0,0 @@ -ChangeLog -========= - -4.1.3 (2020-11-09) -------------------------- -* #1306: Return 409 when trying to PUT a file into a non-existent collection - -4.1.2 (2020-10-04) -------------------------- -* #1296: Add experimental support for PHP 8.0 - -4.1.1 (2020-07-13) -------------------------- -* Fix PHPdoc of Tree:move method -* Allow using custom SAPI implementations -* Include baseUri in lock responses - -4.1.0 (2020-03-20) -------------------------- -* Support PHP 7.4 -* Drop support for PHP 7.0 -* CalDAV: send MIME-Version header in scheduling emails - -4.0.3 (2020-01-10) -------------------------- -* DAV: Streaming PROPFIND server implementation -* DAVACL: Fix uppercase of NotAuthenticated class -* CalDAV: Return only calendar objects owned by principal itself -* CalDAV: Convert scheduling object data from resource to string -* Browser Plugin: Fix content type guessing if setBaseUri is set to a folder - - -4.0.2 (2019-10-18) -------------------------- -* Fix error with PHP 7.4 -* CardDAV: Fix content-type for Thunderbird - - -4.0.1 (2019-08-20) -------------------------- -* TemporaryFileFilterPlugin: Fix Strict Error -* CalDAV\Plugin: Fix null path - - -4.0.0 (2019-07-01) -------------------------- -* Lock: Support lock timeout value Infinity -* Lock: Hide lock token in lock discovery when not set -* BrowserPlugin: Show display name of nodes -* FSExt: Fix folder (file) move issue if rename fails -* IMipPlugin: Add sender name in invite mail headers -* IMipPlugin: Fix email subject and recipient -* Fix issues with empty content-type header -* Apply new code style -* Fix for litmus test suite - test case: props propfind_invalid2 -* Depend on sabre/xml 2.0.1 -* Depend on sabre/http 5.0 -* Now supports PHP 7.3 -* Now requires PHP 7. -* Using `strict_types` in every php file. -* #896: Using the [sabre/event][evnt] `WildcardEmitter`. This allows event - handlers to listen to events using a wildcard. -* #896: Event listeners that in the past listened to `beforeMethod` or `method` - no longer get called. They must listen to `beforeMethod:*` and `method:*` now. -* #322: Imap authentication backend. (@c0d3z3r0). -* #889: Support for selective property querying in CardDAV's addressbook-query. - (@DeepDiver1975). -* #982: Make sure that files that are siblings of directories, are reported - as files (@nickvergessen) - - -4.0.0-beta1 (2019-05-08) -------------------------- -* Lock: Support lock timeout value Infinity -* Lock: Hide lock token in lock discovery when not set -* BrowserPlugin: Show display name of nodes -* FSExt: Fix folder (file) move issue if rename fails -* IMipPlugin: Add sender name in invite mail headers -* IMipPlugin: Fix email subject and recipient - - -4.0.0-alpha5 (2018-10-15) -------------------------- -* Fix issues with empty content-type header - - -4.0.0-alpha4 (2018-10-12) -------------------------- -* Apply new code style -* Fix for litmus test suite - test case: props propfind_invalid2 -* Depend on sabre/xml 2.0.1 - - -4.0.0-alpha3 (2018-10-05) -------------------------- -* Fixes for PHP 7.3 -* Depend on sabre/http 5.0 - - -4.0.0-alpha2 (2018-09-27) -------------------------- -* Now supports PHP 7.3 - - -4.0.0-alpha1 (2018-06-05) -------------------------- - -* Now requires PHP 7. -* Using `strict_types` in every php file. -* #896: Using the [sabre/event][evnt] `WildcardEmitter`. This allows event - handlers to listen to events using a wildcard. -* #896: Event listeners that in the past listened to `beforeMethod` or `method` - no longer get called. They must listen to `beforeMethod:*` and `method:*` now. -* #322: Imap authentication backend. (@c0d3z3r0). -* #889: Support for selective property querying in CardDAV's addressbook-query. - (@DeepDiver1975). -* #982: Make sure that files that are siblings of directories, are reported - as files (@nickvergessen) - - -3.3.0-alpha1 (2018-06-04) -------------------------- - -* SimpleCollection can now take arrays and strings as argument for super - simple tree creation. -* Added `Sabre\DAV\Server::start()`. This replaces `::exec()`. `::exec()` - is now deprecated, but we're keeping it around for a year or two to make - the transition easier. -* `getChildren()` function in any collection may now return an iterator - instead of an array. This can result in memory savings for large - collections. -* `Tree::getChildren()` now returns an Iterator instead of an array. -* Added `$overrideName` to all `Sabre\DAV\FS` and `Sabre\DAV\FSExt` classes, - so users can specify under what name these nodes show up in the tree. -* #889 Added support for filtering vCard properties in the addressbook-query - REPORT (@DeepDiver1975). -* #918: Add a lot of sqlite indexes. This should speed up sqlite-based - installations quite a bit. -* #982: Make sure that files that are siblings of directories, are reported - as files (@nickvergessen) -* #1058: Don't open file resource on HEAD request (@icewind1991) -* #1031: Fix copyNode for case of file named 0 (@phil-davis) - - -3.2.3 (????-??-??) ------------------- - -* #982: Make sure that files that are siblings of directories, are reported - as files (@nickvergessen) - - -3.2.2 (2017-02-14) ------------------- - -* #943: Fix CardDAV XML reporting bug, which was affecting several CardDAV - clients. Bug was introduced in 3.2.1. -* The zip release ships with [sabre/vobject 4.1.2][vobj], - [sabre/http 4.2.2][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.2.0][uri] and [sabre/xml 1.5.0][xml]. - - -3.2.1 (2017-01-28) ------------------- - -* #877: Fix for syncing large calendars when using the Sqlite PDO backend. - (@theseer). -* #889 Added support for filtering vCard properties in the addressbook-query - REPORT (@DeepDiver1975). -* The zip release ships with [sabre/vobject 4.1.2][vobj], - [sabre/http 4.2.2][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.2.0][uri] and [sabre/xml 1.5.0][xml]. - - -3.2.0 (2016-06-27) ------------------- - -* The default ACL rules allow an unauthenticated user to read information - about nodes that don't have their own ACL defined. This was a security - problem. -* The zip release ships with [sabre/vobject 4.1.0][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.2][xml]. - - -3.2.0-beta1 (2016-05-20) ------------------------- - -* #833: Calendars throw exceptions when the sharing plugin is not enabled. -* #834: Return vCards exactly as they were stored if we don't need to convert - in between versions. -* The zip release ships with [sabre/vobject 4.1.0][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. - - -3.2.0-alpha1 (2016-05-09) -------------------------- - -* Database changes for CalDAV. If you are using the CalDAV PDO backends, you - must migrate. Run `./bin/migrateto32.php` for more info. -* Support for WebDAV Resource Sharing, an upcoming standard. -* Added support for sharing in the CalDAV PDO backend! Users can now invite - others to their calendar and give them read/read-write access! -* #397: Support for PSR-3. You can now log exceptions with your favourite - psr3-compatible logging tool. -* #825: Actual proper, tested support for PostgreSQL. We require version 9.5. -* Removed database migration script for sabre/dav 1.7. To update from that - version you now first need to update to sabre/dav 3.1. -* Removed deprecated function: `Sabre\DAV\Auth\Plugin::getCurrentUser()`. -* #774: Fixes for getting free disk space on Windows. -* #803: Major changes in the sharing API. If you were using an old sabre/dav - sharing api, head to the website for more detailed migration notes. -* #657: Support for optional auth using `{DAV:}unauthorized` and `{DAV:}all` - privileges. This allows you to assign a privilege to a resource, allowing - non-authenticated users to access it. For instance, this could allow you - to create a public read-only collection. -* #812 #814: ICS/VCF exporter now includes a more useful filename in its - `Content-Disposition` header. (@Xenopathic). -* #801: BC break: If you were using the `Href` object before, it's behavior - now changed a bit, and `LocalHref` was added to replace the old, default - behavior of `Href`. See the migration doc for more info. -* Removed `Sabre\DAVACL\Plugin::$allowAccessToNodesWithoutACL` setting. - Instead, you can provide a set of default ACL rules with - `Sabre\DAVACL\Plugin::setDefaultAcl()`. -* Introduced `Sabre\DAVACL\ACLTrait` which contains a default implementation - of `Sabre\DAV\IACL` with some sane defaults. We're using this trait all over - the place now, reducing the amount of boilerplate. -* Plugins can now control the "Supported Privilege Set". -* Added Sharing, ICSExport and VCFExport plugins to `groupwareserver.php` - example. -* The `{DAV:}all` privilege is now no longer abstract, so it can be assigned - directly. We're using the `{DAV:}all` privilege now in a lot of cases where - we before assigned both `{DAV:}read` and `{DAV:}write`. -* Resources that are not collections no longer support the `{DAV:}bind` and - `{DAV:}unbind` privileges. -* Corrected the CalDAV-scheduling related privileges. -* Doing an `UNLOCK` no longer requires the `{DAV:}write-content` privilege. -* Added a new `getPrincipalByUri` plugin event. Allowing plugins to request - quickly where a principal lives on a server. -* Renamed `phpunit.xml` to `phpunit.xml.dist` to make local modifications easy. -* Functionality from `IShareableCalendar` is merged into `ISharedCalendar`. -* #751: Fixed XML responses from failing `MKCOL` requests. -* #600: Support for `principal-match` ACL `REPORT`. -* #599: Support for `acl-principal-prop-set` ACL `REPORT`. -* #798: Added an index on `firstoccurence` field in MySQL CalDAV backend. This - should speed up common calendar-query requests. -* #759: DAV\Client is now able to actually correctly resolve relative urls. -* #671: We are no longer checking the `read-free-busy` privilege on individual - calendars during freebusy operations in the scheduling plugin. Instead, we - check the `schedule-query-freebusy` privilege on the target users' inbox, - which validates access for the entire account, per the spec. -* The zip release ships with [sabre/vobject 4.1.0][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. - - -3.1.5 (2018-10-19) ------------------- - -* Fixed: Creating a new calendar on some MySQL configurations caused an error. -* #889 Added support for filtering vCard properties in the addressbook-query - REPORT (@DeepDiver1975). - - - -3.1.4 (2016-05-28) ------------------- - -* #834: Backport from `master`: Return vCards exactly as they were stored if - we don't need to convert in between versions. This should speed up many - large addressbook syncs sometimes up to 50%. -* The zip release ships with [sabre/vobject 4.1.0][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.2][xml]. - - -3.1.3 (2016-04-06) ------------------- - -* Set minimum libxml version to 2.7.0 in `composer.json`. -* #805: It wasn't possible to create calendars that hold events, journals and - todos using MySQL, because the `components` column was 1 byte too small. -* The zip release ships with [sabre/vobject 4.1.0][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. - - -3.1.2 (2016-03-12) ------------------- - -* #784: Sync logs for address books were not correctly cleaned up after - deleting them. -* #787: Cannot use non-seekable stream-wrappers with range requests. -* Faster XML parsing and generating due to sabre/xml update. -* #793: The Sqlite schema is now more strict and more similar to the MySQL - schema. This solves a problem within Baikal. -* The zip release ships with [sabre/vobject 4.0.3][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. - - -3.1.1 (2016-01-25) ------------------- - -* #755: The brower plugin and some operations would break when scheduling and - delegation would both be enabled. -* #757: A bunch of unittest improvements (@jakobsack). -* The zip release ships with [sabre/vobject 4.0.2][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.3.0][xml]. - - -3.1.0 (2016-01-06) ------------------- - -* Better error message when the browser plugin is not enabled. -* Added a super minimal server example. -* #730: Switched all mysql tables to `utf8mb4` character set, allowing you to - use emoji in some tables where you couldn't before. -* #710: Provide an Auth backend that acts as a helper for people implementing - OAuth2 Bearer token. (@fkooman). -* #729: Not all calls to `Sabre\DAV\Tree::getChildren()` were properly cached. -* #727: Added another workaround to make CalDAV work for Windows 10 clients. -* #742: Fixes to make sure that vobject 4 is correctly supported. -* #726: Better error reporting in `Client::propPatch`. We're now throwing - exceptions. -* #608: When a HTTP error is triggered during `Client:propFind`, we're now - throwing `Sabre\HTTP\ClientHttpException` instead of `Sabre\DAV\Exception`. - This new exception contains a LOT more information about the problem. -* #721: Events are now handled in the correct order for `COPY` requests. - Before this subtle bugs could appear that could cause data-loss. -* #747: Now throwing exceptions and setting the HTTP status to 500 in subtle - cases where no other plugin set a correct HTTP status. -* #686: Corrected PDO principal backend's findByURI for email addresses that - don't match the exact capitalization. -* #512: The client now has it's own `User-Agent`. -* #720: Some browser improvements. -* The zip release ships with [sabre/vobject 4.0.1][vobj], - [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.3.0][xml]. - - -3.1.0-alpha2 (2015-09-05) -------------------------- - -* Massive calendars and addressbooks should see a big drop in peak memory - usage. -* Fixed a privilege bug in the availability system. -* #697: Added a "tableName" member to the PropertyStorage PDO backend. (@Frzk). -* #699: PostgreSQL fix for the Locks PDO backend. (@TCKnet) -* Removed the `simplefsserver.php` example file. It's not simple enough. -* #703: PropPatch in client is not correctly encoded. -* #709: Throw exception when running into empty - `supported-calendar-component-set`. -* #711: Don't trigger deserializers for empty elements in `{DAV:}prop`. This - fixes issues when using sabre/dav as a client. -* The zip release ships with [sabre/vobject 4.0.0-alpha2][vobj], - [sabre/http 4.1.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.2.0][xml]. - - -3.1.0-alpha1 (2015-07-19) -------------------------- - -* Now requires PHP 5.5 -* Upgraded to vobject 4, which is a lot faster. -* Support for PHP 7. -* #690: Support for `calendar-availability`, draft 05. - [reference][calendar-availability]. -* #691: Workaround for broken Windows Phone client. -* The zip release ships with [sabre/vobject 4.0.0-alpha1][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml]. - - -3.0.10 (2016-??-??) ------------------- - -* #889 Added support for filtering vCard properties in the addressbook-query - REPORT (@DeepDiver1975). - - -3.0.9 (2016-04-06) ------------------- - -* Set minimum libxml version to 2.7.0 in `composer.json`. -* #727: Added another workaround to make CalDAV work for Windows 10 clients. -* #805: It wasn't possible to create calendars that hold events, journals and - todos using MySQL, because the `components` column was 1 byte too small. -* The zip release ships with [sabre/vobject 3.5.1][vobj], - [sabre/http 4.2.1][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. - - -3.0.8 (2016-03-12) ------------------- - -* #784: Sync logs for address books were not correctly cleaned up after - deleting them. -* #787: Cannot use non-seekable stream-wrappers with range requests. -* Faster XML parsing and generating due to sabre/xml update. -* The zip release ships with [sabre/vobject 3.5.0][vobj], - [sabre/http 4.2.1][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. - - -3.0.7 (2016-01-12) ------------------- - -* #752: PHP 7 support for 3.0 branch. (@DeepDiver1975) -* The zip release ships with [sabre/vobject 3.5.0][vobj], - [sabre/http 4.2.1][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.3.0][xml]. - - -3.0.6 (2016-01-04) ------------------- - -* #730: Switched all mysql tables to `utf8mb4` character set, allowing you to - use emoji in some tables where you couldn't before. -* #729: Not all calls to `Sabre\DAV\Tree::getChildren()` were properly cached. -* #734: Return `418 I'm a Teapot` when generating a multistatus response that - has resources with no returned properties. -* #740: Bugs in `migrate20.php` script. -* The zip release ships with [sabre/vobject 3.4.8][vobj], - [sabre/http 4.1.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.3.0][xml]. - - -3.0.5 (2015-09-15) ------------------- - -* #704: Fixed broken uri encoding in multistatus responses. This affected - at least CyberDuck, but probably also others. -* The zip release ships with [sabre/vobject 3.4.7][vobj], -* The zip release ships with [sabre/vobject 3.4.7][vobj], - [sabre/http 4.1.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.2.0][xml]. - - -3.0.4 (2015-09-06) ------------------- - -* #703: PropPatch in client is not correctly encoded. -* #709: Throw exception when running into empty - `supported-calendar-component-set`. -* #711: Don't trigger deserializers for empty elements in `{DAV:}prop`. This - fixes issues when using sabre/dav as a client. -* #705: A `MOVE` request that gets prevented from deleting the source resource - will still remove the target resource. Now all events are triggered before - any destructive operations. -* The zip release ships with [sabre/vobject 3.4.7][vobj], - [sabre/http 4.1.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.2.0][xml]. - - -3.0.3 (2015-08-06) ------------------- - -* #700: Digest Auth fails on `HEAD` requests. -* Fixed example files to no longer use now-deprecated realm argument. -* The zip release ships with [sabre/vobject 3.4.6][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml]. - - -3.0.2 (2015-07-21) ------------------- - -* #657: Migration script would break when coming a cross an iCalendar object - with no UID. -* #691: Workaround for broken Windows Phone client. -* Fixed a whole bunch of incorrect php docblocks. -* The zip release ships with [sabre/vobject 3.4.5][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml]. - - -3.0.1 (2015-07-02) ------------------- - -* #674: Postgres sql file fixes. (@davesouthey) -* #677: Resources with the name '0' would not get retrieved when using - `Depth: infinity` in a `PROPFIND` request. -* #680: Fix 'autoprefixing' of dead `{DAV:}href` properties. -* #675: NTLM support in DAV\Client. (@k42b3) -* The zip release ships with [sabre/vobject 3.4.5][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml]. - - -3.0.0 (2015-06-02) ------------------- - -* No changes since last beta. -* The zip release ships with [sabre/vobject 3.4.5][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. - - -3.0.0-beta3 (2015-05-29) ------------------------- - -* Fixed deserializing href properties with no value. -* Fixed deserializing `{DAV:}propstat` without a `{DAV:}prop`. -* #668: More information about vcf-export-plugin in browser plugin. -* #669: Add export button to browser plugin for address books. (@mgee) -* #670: multiget report hrefs were not decoded. -* The zip release ships with [sabre/vobject 3.4.4][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. - - -3.0.0-beta2 (2015-05-27) ------------------------- - -* A node's properties should not overwrite properties that were already set. -* Some uris were not correctly encoded in notifications. -* The zip release ships with [sabre/vobject 3.4.4][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. - - -3.0.0-beta1 (2015-05-25) ------------------------- - -* `migrate22.php` is now called `migrate30.php`. -* Using php-cs-fixer for automated coding standards enforcement and fixing. -* #660: principals could break html output. -* #662: Fixed several bugs in the `share` request parser. -* #665: Fix a bug in serialization of complex properties in the proppatch - request in the client. -* #666: expand-property report did not correctly prepend the base uri when - generating uris, this caused delegation to break. -* #659: Don't throw errors when when etag-related checks are done on - collections. -* Fully supporting the updated `Prefer` header syntax, as defined in - [rfc7240][rfc7240]. -* The zip release ships with [sabre/vobject 3.4.3][vobj], - [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. - - -3.0.0-alpha1 (2015-05-19) -------------------------- - -* It's now possible to get all property information from files using the - browser plugin. -* Browser plugin will now show a 'calendar export' button when the - ics-export plugin is enabled. -* Some nodes that by default showed the current time as their last - modification time, now no longer has a last modification time. -* CardDAV namespace was missing from default namespaceMap. -* #646: Properties can now control their own HTML output in the browser plugin. -* #646: Nicer HTML output for the `{DAV:}acl` property. -* Browser plugin no longer shows a few properties that take up a lot of space, - but are likely not really interesting for most users. -* #654: Added a collection, `Sabre\DAVACL\FS\HomeCollection` for automatically - creating a private home collection per-user. -* Changed all MySQL columns from `VARCHAR` to `VARBINARY` where possible. -* Improved older migration scripts a bit to allow easier testing. -* The zip release ships with [sabre/vobject 3.4.3][vobj], - [sabre/http 4.0.0-alpha3][http], [sabre/event 2.0.2][evnt], - [sabre/uri 1.0.1][uri] and [sabre/xml 0.4.3][xml]. - - -2.2.0-alpha4 (2015-04-13) -------------------------- - -* Complete rewrite of the XML system. We now use our own [sabre/xml][xml], - which has a much smarter XML Reader and Writer. -* BC Break: It's no longer possible to instantiate the Locks plugin without - a locks backend. I'm not sure why this ever made sense. -* Simplified the Locking system and fixed a bug related to if tokens checking - locks unrelated to the current request. -* `FSExt` Directory and File no longer do custom property storage. This - functionality is already covered pretty well by the `PropertyStorage` plugin, - so please switch. -* Renamed `Sabre\CardDAV\UserAddressBooks` to `Sabre\CardDAV\AddressBookHome` - to be more consistent with `CalendarHome` as well as the CardDAV - specification. -* `Sabre\DAV\IExtendedCollection` now receives a `Sabre\DAV\MkCol` object as - its second argument, and no longer receives seperate properties and - resourcetype arguments. -* `MKCOL` now integrates better with propertystorage plugins. -* #623: Remove need of temporary files when working with Range requests. - (@dratini0) -* The zip release ships with [sabre/vobject 3.4.2][vobj], - [sabre/http 4.0.0-alpha1][http], [sabre/event 2.0.1][evnt], - [sabre/uri 1.0.0][uri] and [sabre/xml 0.4.3][xml]. - - -2.2.0-alpha3 (2015-02-25) -------------------------- - -* Contains all the changes introduced between 2.1.2 and 2.1.3. -* The zip release ships with [sabre/vobject 3.4.2][vobj], - [sabre/http 4.0.0-alpha1][http], [sabre/event 2.0.1][evnt] and - [sabre/uri 1.0.0][uri]. - - -2.2.0-alpha2 (2015-01-09) -------------------------- - -* Renamed `Sabre\DAV\Auth\Backend\BackendInterface::requireAuth` to - `challenge`, which is a more correct and better sounding name. -* The zip release ships with [sabre/vobject 3.3.5][vobj], - [sabre/http 3.0.4][http], [sabre/event 2.0.1][evnt]. - - -2.2.0-alpha1 (2014-12-10) -------------------------- - -* The browser plugin now has a new page with information about your sabredav - server, and shows information about every plugin that's loaded in the - system. -* #191: The Authentication system can now support multiple authentication - backends. -* Removed: all `$tableName` arguments from every PDO backend. This was already - deprecated, but has now been fully removed. All of these have been replaced - with public properties. -* Deleted several classes that were already deprecated much earlier: - * `Sabre\CalDAV\CalendarRootNode` - * `Sabre\CalDAV\UserCalendars` - * `Sabre\DAV\Exception\FileNotFound` - * `Sabre\DAV\Locks\Backend\FS` - * `Sabre\DAV\PartialUpdate\IFile` - * `Sabre\DAV\URLUtil` -* Removed: `Sabre\DAV\Client::addTrustedCertificates` and - `Sabre\DAV\Client::setVerifyPeer`. -* Removed: `Sabre\DAV\Plugin::getPlugin()` can now no longer return plugins - based on its class name. -* Removed: `Sabre\DAVACL\Plugin::getPrincipalByEmail()`. -* #560: GuessContentType plugin will now set content-type to - `application/octet-stream` if a better content-type could not be determined. -* #568: Added a `componentType` argument to `ICSExportPlugin`, allowing you to - specifically fetch `VEVENT`, `VTODO` or `VJOURNAL`. -* #582: Authentication backend interface changed to be stateless. If you - implemented your own authentication backend, make sure you upgrade your class - to the latest API! -* #582: `Sabre\DAV\Auth\Plugin::getCurrentUser()` is now deprecated. Use - `Sabre\DAV\Auth\Plugin::getCurrentPrincipal()` instead. -* #193: Fix `Sabre\DAV\FSExt\Directory::getQuotaInfo()` on windows. - - -2.1.11 (2016-10-06) -------------------- - -* #805: It wasn't possible to create calendars that hold events, journals and - todos using MySQL, because the `components` column was 1 byte too small. -* The zip release ships with [sabre/vobject 3.5.3][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.10 (2016-03-10) -------------------- - -* #784: Sync logs for address books were not correctly cleaned up after - deleting them. -* The zip release ships with [sabre/vobject 3.5.0][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.9 (2016-01-25) ------------------- - -* #674: PHP7 support (@DeepDiver1975). -* The zip release ships with [sabre/vobject 3.5.0][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.8 (2016-01-04) ------------------- - -* #729: Fixed a caching problem in the Tree object. -* #740: Bugs in `migrate20.php` script. -* The zip release ships with [sabre/vobject 3.4.8][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.7 (2015-09-05) ------------------- - -* #705: A `MOVE` request that gets prevented from deleting the source resource - will still remove the target resource. Now all events are triggered before - any destructive operations. -* The zip release ships with [sabre/vobject 3.4.7][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.6 (2015-07-21) ------------------- - -* #657: Migration script would break when coming a cross an iCalendar object - with no UID. -* #691: Workaround for broken Windows Phone client. -* The zip release ships with [sabre/vobject 3.4.5][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.5 (2015-07-11) ------------------- - -* #677: Resources with the name '0' would not get retrieved when using - `Depth: infinity` in a `PROPFIND` request. -* The zip release ships with [sabre/vobject 3.4.5][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.4 (2015-05-25) ------------------- - -* #651: Double-encoded path in the browser plugin. Should fix a few broken - links in some setups. -* #650: Correctly cleaning up change info after deleting calendars (@ErrOrnAmE). -* #658: Updating `schedule-calendar-default-URL` does not work well, so we're - disabling it until there's a better fix. -* The zip release ships with [sabre/vobject 3.4.3][vobj], - [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. - - -2.1.3 (2015-02-25) ------------------- - -* #586: `SCHEDULE-STATUS` should not contain a reason-phrase. -* #539: Fixed a bug related to scheduling in shared calendars. -* #595: Support for calendar-timezone in iCalendar exports. -* #581: findByUri would send empty prefixes to the principal backend (@soydeedo) -* #611: Escaping a bit more HTML output in the browser plugin. (@LukasReschke) -* #610: Don't allow discovery of arbitrary files using `..` in the browser - plugin (@LukasReschke). -* Browser plugin now shows quota properties. -* #612: PropertyStorage didn't delete properties from nodes when a node's - parents get deleted. -* #581: Fixed problems related to finding attendee information during - scheduling. -* The zip release ships with [sabre/vobject 3.4.2][vobj], - [sabre/http 3.0.4][http], and [sabre/event 2.0.1][evnt]. - - -2.1.2 (2014-12-10) ------------------- - -* #566: Another issue related to the migration script, which would cause - scheduling to not work well for events that were already added before the - migration. -* #567: Doing freebusy requests on accounts that had 0 calendars would throw - a `E_NOTICE`. -* #572: `HEAD` requests trigger a PHP warning. -* #579: Browser plugin can throw exception for a few resourcetypes that didn't - have an icon defined. -* The zip release ships with [sabre/vobject 3.3.4][vobj], - [sabre/http 3.0.4][http], and [sabre/event 2.0.1][evnt]. - - -2.1.1 (2014-11-22) ------------------- - -* #561: IMip Plugin didn't strip mailto: from email addresses. -* #566: Migration process had 2 problems related to adding the `uid` field - to the `calendarobjects` table. -* The zip release ships with [sabre/vobject 3.3.4][vobj], - [sabre/http 3.0.2][http], and [sabre/event 2.0.1][evnt]. - - -2.1.0 (2014-11-19) ------------------- - -* #541: CalDAV PDO backend didn't respect overridden PDO table names. -* #550: Scheduling invites are no longer delivered into shared calendars. -* #554: `calendar-multiget` `REPORT` did not work on inbox items. -* #555: The `calendar-timezone` property is now respected for floating times - and all-day events in the `calendar-query`, `calendar-multiget` and - `free-busy-query` REPORTs. -* #555: The `calendar-timezone` property is also respected for scheduling - free-busy requests. -* #547: CalDAV system too aggressively 'corrects' incoming iCalendar data, and - as a result doesn't return an etag for common cases. -* The zip release ships with [sabre/vobject 3.3.4][vobj], - [sabre/http 3.0.2][http], and [sabre/event 2.0.1][evnt]. - - -2.1.0-alpha2 (2014-10-23) -------------------------- - -* Added: calendar-user-address-set to default principal search properties - list. This should fix iOS attendee autocomplete support. -* Changed: Moved all 'notifications' functionality from `Sabre\CalDAV\Plugin` - to a new plugin: `Sabre\CalDAV\Notifications\Plugin`. If you want to use - notifications-related functionality, just add this plugin. -* Changed: Accessing the caldav inbox, outbox or notification collection no - longer triggers getCalendarsForUser() on backends. -* #533: New invites are no longer delivered to taks-only calendars. -* #538: Added `calendarObjectChange` event. -* Scheduling speedups. -* #539: added `afterResponse` event. (@joserobleda) -* Deprecated: All the "tableName" constructor arguments for all the PDO - backends are now deprecated. They still work, but will be removed in the - next major sabredav version. Every argument that is now deprecated can now - be accessed as a public property on the respective backends. -* #529: Added getCalendarObjectByUID to PDO backend, speeding up scheduling - operations on large calendars. -* The zip release ships with [sabre/vobject 3.3.3][vobj], - [sabre/http 3.0.2][http], and [sabre/event 2.0.1][evnt]. - - -2.1.0-alpha1 (2014-09-23) -------------------------- - -* Added: Support for [rfc6638][rfc6638], also known as CalDAV Scheduling. -* Added: Automatically converting between vCard 3, 4 and jCard using the - `Accept:` header, in CardDAV reports, and automatically converting from - jCard to vCard upon `PUT`. It's important to note that your backends _may_ - now receive both vCard 3.0 and 4.0. -* Added: #444. Collections can now opt-in to support high-speed `MOVE`. -* Changed: PropertyStorage backends now have a `move` method. -* Added: `beforeMove`, and `afterMove` events. -* Changed: A few database changes for the CalDAV PDO backend. Make sure you - run `bin/migrate21.php` to upgrade your database schema. -* Changed: CalDAV backends have a new method: `getCalendarObjectByUID`. This - method MUST be implemented by all backends, but the `AbstractBackend` has a - simple default implementation for this. -* Changed: `Sabre\CalDAV\UserCalendars` has been renamed to - `Sabre\CalDAV\CalendarHome`. -* Changed: `Sabre\CalDAV\CalendarRootNode` has been renamed to - `Sabre\CalDAV\CalendarRoot`. -* Changed: The IMipHandler has been completely removed. With CalDAV scheduling - support, it is no longer needed. It's functionality has been replaced by - `Sabre\CalDAV\Schedule\IMipPlugin`, which can now send emails for clients - other than iCal. -* Removed: `Sabre\DAV\ObjectTree` and `Sabre\DAV\Tree\FileSystem`. All this - functionality has been merged into `Sabre\DAV\Tree`. -* Changed: PrincipalBackend now has a findByUri method. -* Changed: `PrincipalBackend::searchPrincipals` has a new optional `test` - argument. -* Added: Support for the `{http://calendarserver.org/ns/}email-address-set` - property. -* #460: PropertyStorage must move properties during `MOVE` requests. -* Changed: Restructured the zip distribution to be a little bit more lean - and consistent. -* #524: Full support for the `test="anyof"` attribute in principal-search - `REPORT`. -* #472: Always returning lock tokens in the lockdiscovery property. -* Directory entries in the Browser plugin are sorted by type and name. - (@aklomp) -* #486: It's now possible to return additional properties when an 'allprop' - PROPFIND request is being done. (@aklomp) -* Changed: Now return HTTP errors when an addressbook-query REPORT is done - on a uri that's not a vcard. This should help with debugging this common - mistake. -* Changed: `PUT` requests with a `Content-Range` header now emit a 400 status - instead of 501, as per RFC7231. -* Added: Browser plugin can now display the contents of the - `{DAV:}supported-privilege-set` property. -* Added: Now reporting `CALDAV:max-resource-size`, but we're not actively - restricting it yet. -* Changed: CalDAV plugin is now responsible for reporting - `CALDAV:supported-collation-set` and `CALDAV:supported-calendar-data` - properties. -* Added: Now reporting `CARDDAV:max-resource-size`, but we're not actively - restricting it yet. -* Added: Support for `CARDDAV:supported-collation-set`. -* Changed: CardDAV plugin is now responsible for reporting - `CARDDAV:supported-address-data`. This functionality has been removed from - the CardDAV PDO backend. -* When a REPORT is not supported, we now emit HTTP error 415, instead of 403. -* #348: `HEAD` requests now work wherever `GET` also works. -* Changed: Lower priority for the iMip plugins `schedule` event listener. -* Added: #523 Custom CalDAV backends can now mark any calendar as read-only. -* The zip release ships with [sabre/vobject 3.3.3][vobj], - [sabre/http 3.0.0][http], and [sabre/event 2.0.0][evnt]. - - -2.0.9 (2015-09-04) ------------------- - -* #705: A `MOVE` request that gets prevented from deleting the source resource - will still remove the target resource. Now all events are triggered before - any destructive operations. -* The zip release ships with [sabre/vobject 3.4.6][vobj], - [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. - - - -2.0.8 (2015-07-11) ------------------- - -* #677: Resources with the name '0' would not get retrieved when using - `Depth: infinity` in a `PROPFIND` request. -* The zip release ships with [sabre/vobject 3.3.5][vobj], - [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. - - -2.0.7 (2015-05-25) ------------------- - -* #650: Correctly cleaning up change info after deleting calendars (@ErrOrnAmE). -* The zip release ships with [sabre/vobject 3.3.4][vobj], - [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. - - -2.0.6 (2014-12-10) ------------------- - -* Added `Sabre\CalDAV\CalendarRoot` as an alias for - `Sabre\CalDAV\CalendarRootNode`. The latter is going to be deprecated in 2.1, - so this makes it slightly easier to write code that works in both branches. -* #497: Making sure we're initializing the sync-token field with a value after - migration. -* The zip release ships with [sabre/vobject 3.3.4][vobj], - [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. - - -2.0.5 (2014-10-14) ------------------- - -* #514: CalDAV PDO backend didn't work when overriding the 'calendar changes' - database table name. -* #515: 304 status code was not being sent when checking preconditions. -* The zip release ships with [sabre/vobject 3.3.3][vobj], - [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. - - -2.0.4 (2014-08-27) ------------------- - -* #483: typo in calendars creation for PostgreSQL. -* #487: Locks are now automatically removed after a node has been deleted. -* #496: Improve CalDAV and CardDAV sync when there is no webdav-sync support. -* Added: Automatically mapping internal sync-tokens to getctag. -* The zip release ships with [sabre/vobject 3.3.1][vobj], - [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. - - -2.0.3 (2014-07-14) ------------------- - -* #474: Fixed PropertyStorage `pathFilter()`. -* #476: CSP policy incorrect, causing stylesheets to not load in the browser - plugin. -* #475: Href properties in the browser plugin sometimes included a backslash. -* #478: `TooMuchMatches` exception never worked. This was fixed, and we also - took this opportunity to rename it to `TooManyMatches`. -* The zip release ships with [sabre/vobject 3.2.4][vobj], - [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. - - -2.0.2 (2014-06-12) ------------------- - -* #470: Fixed compatibility with PHP < 5.4.14. -* #467: Fixed a problem in `examples/calendarserver.php`. -* #466: All the postgresql sample files have been updated. -* Fixed: An error would be thrown if a client did a propfind on a node the - user didn't have access to. -* Removed: Old and broken example code from the `examples/` directory. -* The zip release ships with [sabre/vobject 3.2.3][vobj], - [sabre/http 2.0.3][http], and [sabre/event 1.0.1][evnt]. - - -2.0.1 (2014-05-28) ------------------- - -* #459: PROPFIND requests on Files with no Depth header would return a fatal - error. -* #464: A PROPFIND allprops request should not return properties with status - 404. -* The zip release ships with [sabre/vobject 3.2.2][vobj], - [sabre/http 2.0.3][http], and [sabre/event 1.0.0][evnt]. - - -2.0.0 (2014-05-22) ------------------- - -* The zip release ships with [sabre/vobject 3.2.2][vobj], - [sabre/http 2.0.3][http], and [sabre/event 1.0.0][evnt]. -* Fixed: #456: Issue in sqlite migration script. -* Updated: MySQL database schema optimized by using more efficient column types. -* Cleaned up browser design. - - -2.0.0-beta1 (2014-05-15) -------------------------- - -* The zip release ships with [sabre/vobject 3.2.2][vobj], - [sabre/http 2.0.3][http], and [sabre/event 1.0.0][evnt]. -* BC Break: Property updating and fetching got refactored. Read the [migration - document][mi20] for more information. This allows for creation of a generic - property storage, and other property-related functionality that was not - possible before. -* BC Break: Removed `propertyUpdate`, `beforeGetProperties` and - `afterGetProperties` events. -* Fixed: #413: Memory optimizations for the CardDAV PDO backend. -* Updated: Brand new browser plugin with more debugging features and a design - that is slightly less painful. -* Added: Support for the `{DAV:}supported-method-set` property server-wide. -* Making it easier for implementors to override how the CardDAV addressbook - home is located. -* Fixed: Issue #422 Preconditions were not being set on PUT on non-existent - files. Not really a chance for data-loss, but incorrect nevertheless. -* Fixed: Issue #428: Etag check with `If:` fails if the target is a collection. -* Fixed: Issues #430, #431, #433: Locks plugin didn't not properly release - filesystem based locks. -* Fixed: #443. Support for creating new calendar subscriptions for OS X 10.9.2 - and up. -* Removed: `Sabre\DAV\Server::NODE_*` constants. -* Moved all precondition checking into a central place, instead of having to - think about it on a per-method basis. -* jCal transformation for calendar-query REPORT now works again. -* Switched to PSR-4 -* Fixed: #175. Returning ETag header upon a failed `If-Match` or - `If-None-Match` check. -* Removed: `lib/Sabre/autoload.php`. Use `vendor/autoload.php` instead. -* Removed: all the rfc documentation from the sabre/dav source. This made the - package needlessly larger. -* Updated: Issue #439. Lots of updates in PATCH support. The - Sabre_DAV_PartialUpdate_IFile interface is now deprecated and will be - removed in a future version. -* Added: `Sabre\DAV\Exception\LengthRequired`. - -1.9.0-alpha2 (2014-01-14) -------------------------- - -* The zip release ships with sabre/vobject 3.1.3, sabre/http 2.0.1, and - sabre/event 1.0.0. -* Added: Browser can now inspect any node, if ?sabreaction=browser is appended. -* Fixed: Issue #178. Support for multiple items in the Timeout header. -* Fixed: Issue #382. Stricter checking if calendar-query is allowed to run. -* Added: Depth: Infinity support for PROPFIND request. Thanks Thomas Müller and - Markus Goetz. - - -1.9.0-alpha1 (2013-11-07) -------------------------- - -* The zip release ships with sabre/vobject 3.1.3, sabre/http 2.0.0alpha5, and - sabre/event 1.0.0. -* BC Break: The CardDAV and CalDAV BackendInterface each have a new method: - getMultipleCards and getMultipleCalendarObjects. The Abstract and PDO backends - have default implementations, but if you implement that interface directly, - this method is now required. -* BC Break: XML property classes now receive an extra argument in their - unserialize method ($propertyMap). This allows for recursively parsing - properties, if needed. -* BC Break: Now using sabre/event for event emitting/subscription. For plugin - authors this means Server::subscribeEvent is now Server::on, and - Server::broadcastEvent is now Server::emit. -* BC Break: Almost all core functionality moved into a CorePlugin. -* BC Break: Most events triggered by the server got an overhaul. -* Changed: Sabre\HTTP now moved into a dedicated sabre/http package. -* Added: Support for WebDAV-sync (rfc6578). -* Added: Support for caldav-subscriptions, which is an easy way for caldav - clients to manage a list of subscriptions on the server. -* Added: Support for emitting and receiving jCal instead of iCalendar for - CalDAV. -* Added: BasicCallback authenticaton backend, for creating simple authentication - systems without having to define any classes. -* Added: A $transactionType property on the server class. This can be used for - logging and performance measuring purposes. -* Fixed: If event handlers modify the request body from a PUT request, an ETag - is no longer sent back. -* Added: Sabre\DAV\IMultiGet to optimize requests that retrieve information - about lists of resources. -* Added: MultiGet support to default CalDAV and CardDAV backends, speeding up - the multiget and sync reports quite a bit! -* Added: ICSExportPlugin can now generate jCal, filter on time-ranges and expand - recurrences. -* Fixed: Read-only access to calendars still allows the sharee to modify basic - calendar properties, such as the displayname and color. -* Changed: The default supportedPrivilegeSet has changed. Most privileges are no - longer marked as abstract. -* Changed: More elegant ACL management for CalendarObject and Card nodes. -* Added: Browser plugin now marks a carddav directory as type Directory, and a - shared calendar as 'Shared'. -* Added: When debugExceptions is turned on, all previous exceptions are also - traversed. -* Removed: Got rid of the Version classes for CalDAV, CardDAV, HTTP, and DAVACL. - Now that there's no separate packages anymore, this makes a bit more sense. -* Added: Generalized the multistatus response parser a bit more, for better - re-use. -* Added: Sabre\DAV\Client now has support for complex properties for PROPPATCH. - (Issue #299). -* Added: Sabre\DAV\Client has support for gzip and deflate encoding. -* Added: Sabre\DAV\Client now has support for sending objects as streams. -* Added: Deserializer for {DAV:}current-user-privilege-set. -* Added: Addressbooks or backends can now specify custom acl rules when creating - cards. -* Added: The ability for plugins to validate custom tokens in If: headers. -* Changed: Completely refactored the Lock plugin to deal with the new If: header - system. -* Added: Checking preconditions for MOVE, COPY, DELETE and PROPPATCH methods. -* Added: has() method on DAV\Property\SupportedReportSet. -* Added: If header now gets checked (with ETag) all the time. Before the dealing - with the If-header was a responsibility of the Locking plugin. -* Fixed: Outbox access for delegates. -* Added: Issue 333: It's now possible to override the calendar-home in the - CalDAV plugin. -* Added: A negotiateContentType to HTTP\Request. A convenience method. -* Fixed: Issue 349: Denying copying or moving a resource into it's own subtree. -* Fixed: SabreDAV catches every exception again. -* Added: Issue #358, adding a component=vevent parameter to the content-types - for calendar objects, if the caldav backend provides this info. - - -1.8.12-stable (2015-01-21) --------------------------- - -* The zip release ships with sabre/vobject 2.1.7. -* #568: Support empty usernames and passwords in basic auth. - - -1.8.11 (2014-12-10) -------------------- - -* The zip release ships with sabre/vobject 2.1.6. -* Updated: MySQL database schema optimized by using more efficient column types. -* #516: The DAV client will now only redirect to HTTP and HTTPS urls. - - -1.8.10 (2014-05-15) -------------------- - -* The zip release ships with sabre/vobject 2.1.4. -* includes changes from version 1.7.12. - - -1.8.9 (2014-02-26) ------------------- - -* The zip release ships with sabre/vobject 2.1.3. -* includes changes from version 1.7.11. - - -1.8.8 (2014-02-09) ------------------- - -* includes changes from version 1.7.10. -* The zip release ships with sabre/vobject 2.1.3. - -1.8.7 (2013-10-02) ------------------- - -* the zip release ships with sabre/vobject 2.1.3. -* includes changes from version 1.7.9. - - -1.8.6 (2013-06-18) ------------------- - -* The zip release ships with sabre/vobject 2.1.0. -* Includes changes from version 1.7.8. - - -1.8.5 (2013-04-11) ------------------- - -* The zip release ships with sabre/vobject 2.0.7. -* Includes changes from version 1.7.7. - - -1.8.4 (2013-04-08) ------------------- - -* The zip release ships with sabre/vobject 2.0.7. -* Includes changes from version 1.7.6. - - -1.8.3 (2013-03-01) ------------------- - -* The zip release ships with sabre/vobject 2.0.6. -* Includes changes from version 1.7.5. -* Fixed: organizer email-address for shared calendars is now prefixed with - mailto:, as it should. - - -1.8.2 (2013-01-19) ------------------- - -* The zip release ships with sabre/vobject 2.0.5. -* Includes changes from version 1.7.4. - - -1.8.1 (2012-12-01) ------------------- - -* The zip release ships with sabre/vobject 2.0.5. -* Includes changes from version 1.7.3. -* Fixed: Typo in 1.7 migration script caused it to fail. - - -1.8.0 (2012-11-08) ------------------- - -* The zip release ships with sabre/vobject 2.0.5. -* BC Break: Moved the entire codebase to PHP namespaces. -* BC Break: Every backend package (CalDAV, CardDAV, Auth, Locks, Principals) now - has consistent naming conventions. There's a BackendInterface, and an - AbstractBackend class. -* BC Break: Changed a bunch of constructor signatures in the CalDAV package, to - reduce dependencies on the ACL package. -* BC Break: Sabre_CalDAV_ISharedCalendar now also has a getShares method, so - sharees can figure out who is also on a shared calendar. -* Added: Sabre_DAVACL_IPrincipalCollection interface, to advertise support for - principal-property-search on any node. -* Added: Simple console script to fire up a fileserver in the current directory - using PHP 5.4's built-in webserver. -* Added: Sharee's can now also read out the list of invites for a shared - calendar. -* Added: The Proxy principal classes now both implement an interface, for - greater flexibility. - - -1.7.13 (2014-07-28) -------------------- - -* The zip release ships with sabre/vobject 2.1.4. -* Changed: Removed phing and went with a custom build script for now. - - -1.7.12 (2014-05-15) -------------------- - -* The zip release ships with sabre/vobject 2.1.4. -* Updated: Issue #439. Lots of updates in PATCH support. The - Sabre_DAV_PartialUpdate_IFile interface is now deprecated and will be removed - in a future version. -* Fixed: Restoring old setting after changing libxml_disable_entity_loader. -* Fixed: Issue #422: Preconditions were not being set on PUT on non-existent - files. Not really a chance for data-loss, but incorrect nevertheless. -* Fixed: Issue #427: Now checking preconditions on DELETE requests. -* Fixed: Issue #428: Etag check with If: fails if the target is a collection. -* Fixed: Issue #393: PATCH request with missing end-range was handled - incorrectly. -* Added: Sabre_DAV_Exception_LengthRequired to omit 411 errors. - - -1.7.11 (2014-02-26) -------------------- - -* The zip release ships with sabre/vobject 2.1.3. -* Fixed: Issue #407: large downloads failed. -* Fixed: Issue #414: XXE security problem on older PHP versions. - - -1.7.10 (2014-02-09) -------------------- - -* Fixed: Issue #374: Don't urlescape colon (:) when it's not required. -* Fixed: Potential security vulnerability in the http client. - - -1.7.9 (2013-10-02) ------------------- - -* The zip release ships with sabre/vobject 2.1.3. -* Fixed: Issue #365. Incorrect output when principal urls have spaces in them. -* Added: Issue #367: Automatically adding a UID to vcards that don't have them. - - -1.7.8 (2013-06-17) ------------------- - -* The zip release ships with sabre/vobject 2.1.0. -* Changed: Sabre\DAV\Client::verifyPeer is now a protected property (instead of - private). -* Fixed: Text was incorrectly escaped in the Href and HrefList properties, - disallowing urls with ampersands (&) in them. -* Added: deserializer for Sabre\DAVACL\Property\CurrentUserPrivilegeSet. -* Fixed: Issue 335: Client only deserializes properties with status 200. -* Fixed: Issue 341: Escaping xml in 423 Locked error responses. -* Added: Issue 339: beforeGetPropertiesForPath event. - - -1.7.7 (2013-04-11) ------------------- - -* The zip release ships with sabre/vobject 2.0.7. -* Fixed: Assets in the browser plugins were not being served on windows - machines. - - -1.7.6 (2013-04-08) ------------------- - -* The zip release ships with sabre/vobject 2.0.7. -* Fixed: vcardurl in database schema can now hold 255 characters instead of 80 - (which is often way to small). -* Fixed: The browser plugin potentially allowed people to open any arbitrary - file on windows servers (CVE-2013-1939). - - -1.7.5 (2013-03-01) ------------------- - -* The zip release ships with sabre/vobject 2.0.6. -* Change: No longer advertising support for 4.0 vcards. iOS and OS X address - book don't handle this well, and just advertising 3.0 support seems like the - most logical course of action. -* Added: ->setVerifyPeers to Sabre_DAV_Client (greatly resisting against it, - don't use this..). - - -1.7.4 (2013-01-19) ------------------- - -* The zip release ships with sabre/vobject 2.0.5. -* Changed: To be compatible with MS Office 2011 for Mac, a workaround was - removed that was added to support old versions of Windows XP (pre-SP3). - Indeed! We needed a crazy workaround to work with one MS product in the past, - and we can't keep that workaround to be compatible with another MS product. -* Fixed: expand-properties REPORT had incorrect values for the href element. -* Fixed: Range requests now work for non-seekable streams. (Thanks Alfred - Klomp). -* Fixed: Changed serialization of {DAV:}getlastmodified and {DAV:}supportedlock - to improve compatibility with MS Office 2011 for Mac. -* Changed: reverted the automatic translation of 'DAV:' xml namespaces to - 'urn:DAV' when parsing files. Issues were reported with libxml 2.6.32, on a - relatively recent debian release, so we'll wait till 2015 to take this one out - again. -* Added: Sabre_DAV_Exception_ServiceUnavailable, for emitting 503's. - - -1.7.3 (2012-12-01) ------------------- - -* The zip release ships with sabre/vobject 2.0.5. -* Fixed: Removing double slashes from getPropertiesForPath. -* Change: Marked a few more properties in the CardDAV as protected, instead of - private. -* Fixed: SharingPlugin now plays nicer with other plugins with similar - functionality. -* Fixed: Issue 174. Sending back HTTP/1.0 for requests with this version. - - -1.7.2 (2012-11-08) ------------------- - -* The zip release ships with sabre/vobject 2.0.5. -* Added: ACL plugin advertises support for 'calendarserver-principal- - property-search'. -* Fixed: [#153] Allowing for relative http principals in iMip requests. -* Added: Support for cs:first-name and cs:last-name properties in sharing - invites. -* Fixed: Made a bunch of properties protected, where they were private before. -* Added: Some non-standard properties for sharing to improve compatibility. -* Fixed: some bugfixes in postgres sql script. -* Fixed: When requesting some properties using PROPFIND, they could show up as - both '200 Ok' and '403 Forbidden'. -* Fixed: calendar-proxy principals were not checked for deeper principal - membership than 1 level. -* Fixed: setGroupMemberSet argument now correctly receives relative principal - urls, instead of the absolute ones. -* Fixed: Server class will filter out any bonus properties if any extra were - returned. This means the implementor of the IProperty class can be a bit - lazier when implementing. Note: bug numbers after this line refer to Google - Code tickets. We're using github now. - - -1.7.1 (2012-10-07) ------------------- - -* Fixed: include path problem in the migration script. - - -1.7.0 (2012-10-06) ------------------- - -* BC Break: The calendarobjects database table has a bunch of new fields, and a - migration script is required to ensure everything will keep working. Read the - wiki for more details. -* BC Break: The ICalendar interface now has a new method: calendarQuery. -* BC Break: In this version a number of classes have been deleted, that have - been previously deprecated. Namely: - Sabre_DAV_Directory (now: - Sabre_DAV_Collection) - Sabre_DAV_SimpleDirectory (now: - Sabre_DAV_SimpleCollection) -* BC Break: Sabre_CalDAV_Schedule_IMip::sendMessage now has an extra argument. - If you extended this class, you should fix this method. It's only used for - informational purposes. -* BC Break: The DAV: namespace is no longer converted to urn:DAV. This was a - workaround for a bug in older PHP versions (pre-5.3). -* Removed: Sabre.includes.php was deprecated, and is now removed. -* Removed: Sabre_CalDAV_Server was deprecated, and is now removed. Please use - Sabre_DAV_Server and check the examples in the examples/ directory. -* Changed: The Sabre_VObject library now spawned into it's own project! The - VObject library is still included in the SabreDAV zip package. -* Added: Experimental interfaces to allow implementation of caldav-sharing. Note - that no implementation is provided yet, just the api hooks. -* Added: Free-busy reporting compliant with the caldav-scheduling standard. This - allows iCal and other clients to fetch other users' free-busy data. -* Added: Experimental NotificationSupport interface to add caldav notifications. -* Added: VCF Export plugin. If enabled, it can generate an export of an entire - addressbook. -* Added: Support for PATCH using a SabreDAV format, to live-patch files. -* Added: Support for Prefer: return-minimal and Brief: t headers for PROPFIND - and PROPPATCH requests. -* Changed: Responsibility for dealing with the calendar-query is now moved from - the CalDAV plugin to the CalDAV backends. This allows for heavy optimizations. -* Changed: The CalDAV PDO backend is now a lot faster for common calendar - queries. -* Changed: We are now using the composer autoloader. -* Changed: The CalDAV backend now all implement an interface. -* Changed: Instead of Sabre_DAV_Property, Sabre_DAV_PropertyInterface is now the - basis of every property class. -* Update: Caching results for principal lookups. This should cut down queries - and performance for a number of heavy requests. -* Update: ObjectTree caches lookups much more aggresively, which will help - especially speeding up a bunch of REPORT queries. -* Added: Support for the schedule-calendar-transp property. -* Fixed: Marking both the text/calendar and text/x-vcard as UTF-8 encoded. -* Fixed: Workaround for the SOGO connector, as it doesn't understand receiving - "text/x-vcard; charset=utf-8" for a contenttype. -* Added: Sabre_DAV_Client now throws more specific exceptions in cases where we - already has an exception class. -* Added: Sabre_DAV_PartialUpdate. This plugin allows you to use the PATCH method - to update parts of a file. -* Added: Tons of timezone name mappings for Microsoft Exchange. -* Added: Support for an 'exception' event in the server class. -* Fixed: Uploaded VCards without a UID are now rejected. (thanks Dominik!) -* Fixed: Rejecting calendar objects if they are not in the - supported-calendar-component list. (thanks Armin!) -* Fixed: Issue 219: serialize() now reorders correctly. -* Fixed: Sabre_DAV_XMLUtil no longer returns empty $dom->childNodes if there is - whitespace in $dom. -* Fixed: Returning 409 Conflict instead of 500 when an attempt is made to create - a file as a child of something that's not a collection. -* Fixed: Issue 237: xml-encoding values in SabreDAV error responses. -* Fixed: Returning 403, instead of 501 when an unknown REPORT is requested. -* Fixed: Postfixing slash on {DAV:}owner properties. -* Fixed: Several embarrassing spelling mistakes in docblocks. - - -1.6.10 (2013-06-17) -------------------- - -* Fixed: Text was incorrectly escaped in the Href and HrefList properties, - disallowing urls with ampersands (&) in them. -* Fixed: Issue 341: Escaping xml in 423 Locked error responses. - - -1.6.9 (2013-04-11) ------------------- - -* Fixed: Assets in the browser plugins were not being served on windows - machines. - - -1.6.8 (2013-04-08) ------------------- - -* Fixed: vcardurl in database schema can now hold 255 characters instead of 80 - (which is often way to small). -* Fixed: The browser plugin potentially allowed people to open any arbitrary - file on windows servers. (CVE-2013-1939). - - -1.6.7 (2013-03-01) ------------------- - -* Change: No longer advertising support for 4.0 vcards. iOS and OS X address - book don't handle this well, and just advertising 3.0 support seems like the - most logical course of action. -* Added: ->setVerifyPeers to Sabre_DAV_Client (greatly resisting against it, - don't use this..). - - -1.6.6 (2013-01-19) ------------------- - -* Fixed: Backported a fix for broken XML serialization in error responses. - (Thanks @DeepDiver1975!) - - -1.6.5 (2012-10-04) ------------------- - -* Fixed: Workaround for line-ending bug OS X 10.8 addressbook has. -* Added: Ability to allow users to set SSL certificates for the Client class. - (Thanks schiesbn!). -* Fixed: Directory indexes with lots of nodes should be a lot faster. -* Fixed: Issue 235: E_NOTICE thrown when doing a propfind request with - Sabre_DAV_Client, and no valid properties are returned. -* Fixed: Issue with filtering on alarms in tasks. - - -1.6.4 (2012-08-02) ------------------- - -* Fixed: Issue 220: Calendar-query filters may fail when filtering on alarms, if - an overridden event has it's alarm removed. -* Fixed: Compatibility for OS/X 10.8 iCal in the IMipHandler. -* Fixed: Issue 222: beforeWriteContent shouldn't be called for lock requests. -* Fixed: Problem with POST requests to the outbox if mailto: was not lower - cased. -* Fixed: Yearly recurrence rule expansion on leap-days no behaves correctly. -* Fixed: Correctly checking if recurring, all-day events with no dtstart fall in - a timerange if the start of the time-range exceeds the start of the instance - of an event, but not the end. -* Fixed: All-day recurring events wouldn't match if an occurence ended exactly - on the start of a time-range. -* Fixed: HTTP basic auth did not correctly deal with passwords containing colons - on some servers. -* Fixed: Issue 228: DTEND is now non-inclusive for all-day events in the - calendar-query REPORT and free-busy calculations. - - -1.6.3 (2012-06-12) ------------------- - -* Added: It's now possible to specify in Sabre_DAV_Client which type of - authentication is to be used. -* Fixed: Issue 206: Sabre_DAV_Client PUT requests are fixed. -* Fixed: Issue 205: Parsing an iCalendar 0-second date interval. -* Fixed: Issue 112: Stronger validation of iCalendar objects. Now making sure - every iCalendar object only contains 1 component, and disallowing vcards, - forcing every component to have a UID. -* Fixed: Basic validation for vcards in the CardDAV plugin. -* Fixed: Issue 213: Workaround for an Evolution bug, that prevented it from - updating events. -* Fixed: Issue 211: A time-limit query on a non-relative alarm trigger in a - recurring event could result in an endless loop. -* Fixed: All uri fields are now a maximum of 200 characters. The Bynari outlook - plugin used much longer strings so this should improve compatibility. -* Fixed: Added a workaround for a bug in KDE 4.8.2 contact syncing. See - https://bugs.kde.org/show_bug.cgi?id=300047 -* Fixed: Issue 217: Sabre_DAV_Tree_FileSystem was pretty broken. - - -1.6.2 (2012-04-16) ------------------- - -* Fixed: Sabre_VObject_Node::$parent should have been public. -* Fixed: Recurrence rules of events are now taken into consideration when doing - time-range queries on alarms. -* Fixed: Added a workaround for the fact that php's DateInterval cannot parse - weeks and days at the same time. -* Added: Sabre_DAV_Server::$exposeVersion, allowing you to hide SabreDAV's - version number from various outputs. -* Fixed: DTSTART values would be incorrect when expanding events. -* Fixed: DTSTART and DTEND would be incorrect for expansion of WEEKLY BYDAY - recurrences. -* Fixed: Issue 203: A problem with overridden events hitting the exact date and - time of a subsequent event in the recurrence set. -* Fixed: There was a problem with recurrence rules, for example the 5th tuesday - of the month, if this day did not exist. -* Added: New HTTP status codes from draft-nottingham-http-new-status-04. - - -1.6.1 (2012-03-05) ------------------- - -* Added: createFile and put() can now return an ETag. -* Added: Sending back an ETag on for operations on CardDAV backends. This should - help with OS X 10.6 Addressbook compatibility. -* Fixed: Fixed a bug where an infinite loop could occur in the recurrence - iterator if the recurrence was YEARLY, with a BYMONTH rule, and either BYDAY - or BYMONTHDAY match the first day of the month. -* Fixed: Events that are excluded using EXDATE are still counted in the COUNT= - parameter in the RRULE property. -* Added: Support for time-range filters on VALARM components. -* Fixed: Correctly filtering all-day events. -* Fixed: Sending back correct mimetypes from the browser plugin (thanks - Jürgen). -* Fixed: Issue 195: Sabre_CardDAV pear package had an incorrect dependency. -* Fixed: Calendardata would be destroyed when performing a MOVE request. - - -1.6.0 (2012-02-22) ------------------- - -* BC Break: Now requires PHP 5.3 -* BC Break: Any node that implemented Sabre_DAVACL_IACL must now also implement - the getSupportedPrivilegeSet method. See website for details. -* BC Break: Moved functions from Sabre_CalDAV_XMLUtil to - Sabre_VObject_DateTimeParser. -* BC Break: The Sabre_DAVACL_IPrincipalCollection now has two new methods: - 'searchPrincipals' and 'updatePrincipal'. -* BC Break: Sabre_DAV_ILockable is removed and all related per-node locking - functionality. -* BC Break: Sabre_DAV_Exception_FileNotFound is now deprecated in favor of - Sabre_DAV_Exception_NotFound. The former will be removed in a later version. -* BC Break: Removed Sabre_CalDAV_ICalendarUtil, use Sabre_VObject instead. -* BC Break: Sabre_CalDAV_Server is now deprecated, check out the documentation - on how to setup a caldav server with just Sabre_DAV_Server. -* BC Break: Default Principals PDO backend now needs a new field in the - 'principals' table. See the website for details. -* Added: Ability to create new calendars and addressbooks from within the - browser plugin. -* Added: Browser plugin: icons for various nodes. -* Added: Support for FREEBUSY reports! -* Added: Support for creating principals with admin-level privileges. -* Added: Possibility to let server send out invitation emails on behalf of - CalDAV client, using Sabre_CalDAV_Schedule_IMip. -* Changed: beforeCreateFile event now passes data argument by reference. -* Changed: The 'propertyMap' property from Sabre_VObject_Reader, must now be - specified in Sabre_VObject_Property::$classMap. -* Added: Ability for plugins to tell the ACL plugin which principal plugins are - searchable. -* Added: [DAVACL] Per-node overriding of supported privileges. This allows for - custom privileges where needed. -* Added: [DAVACL] Public 'principalSearch' method on the DAVACL plugin, which - allows for easy searching for principals, based on their properties. -* Added: Sabre_VObject_Component::getComponents() to return a list of only - components and not properties. -* Added: An includes.php file in every sub-package (CalDAV, CardDAV, DAV, - DAVACL, HTTP, VObject) as an alternative to the autoloader. This often works - much faster. -* Added: Support for the 'Me card', which allows Addressbook.app users specify - which vcard is their own. -* Added: Support for updating principal properties in the DAVACL principal - backends. -* Changed: Major refactoring in the calendar-query REPORT code. Should make - things more flexible and correct. -* Changed: The calendar-proxy-[read|write] principals will now only appear in - the tree, if they actually exist in the Principal backend. This should reduce - some problems people have been having with this. -* Changed: Sabre_VObject_Element_* classes are now renamed to - Sabre_VObject_Property. Old classes are retained for backwards compatibility, - but this will be removed in the future. -* Added: Sabre_VObject_FreeBusyGenerator to generate free-busy reports based on - lists of events. -* Added: Sabre_VObject_RecurrenceIterator to find all the dates and times for - recurring events. -* Fixed: Issue 97: Correctly handling RRULE for the calendar-query REPORT. -* Fixed: Issue 154: Encoding of VObject parameters with no value was incorrect. -* Added: Support for {DAV:}acl-restrictions property from RFC3744. -* Added: The contentlength for calendar objects can now be supplied by a CalDAV - backend, allowing for more optimizations. -* Fixed: Much faster implementation of Sabre_DAV_URLUtil::encodePath. -* Fixed: {DAV:}getcontentlength may now be not specified. -* Fixed: Issue 66: Using rawurldecode instead of urldecode to decode paths from - clients. This means that + will now be treated as a literal rather than a - space, and this should improve compatibility with the Windows built-in client. -* Added: Sabre_DAV_Exception_PaymentRequired exception, to emit HTTP 402 status - codes. -* Added: Some mysql unique constraints to example files. -* Fixed: Correctly formatting HTTP dates. -* Fixed: Issue 94: Sending back Last-Modified header for 304 responses. -* Added: Sabre_VObject_Component_VEvent, Sabre_VObject_Component_VJournal, - Sabre_VObject_Component_VTodo and Sabre_VObject_Component_VCalendar. -* Changed: Properties are now also automatically mapped to their appropriate - classes, if they are created using the add() or __set() methods. -* Changed: Cloning VObject objects now clones the entire tree, rather than just - the default shallow copy. -* Added: Support for recurrence expansion in the CALDAV:calendar-multiget and - CALDAV:calendar-query REPORTS. -* Changed: CalDAV PDO backend now sorts calendars based on the internal - 'calendarorder' field. -* Added: Issue 181: Carddav backends may no optionally not supply the carddata - in getCards, if etag and size are specified. This may speed up certain - requests. -* Added: More arguments to beforeWriteContent and beforeCreateFile (see - WritingPlugins wiki document). -* Added: Hook for iCalendar validation. This allows us to validate iCalendar - objects when they're uploaded. At the moment we're just validating syntax. -* Added: VObject now support Windows Timezone names correctly (thanks mrpace2). -* Added: If a timezonename could not be detected, we fall back on the default - PHP timezone. -* Added: Now a Composer package (thanks willdurand). -* Fixed: Support for \N as a newline character in the VObject reader. -* Added: afterWriteContent, afterCreateFile and afterUnbind events. -* Added: Postgresql example files. Not part of the unittests though, so use at - your own risk. -* Fixed: Issue 182: Removed backticks from sql queries, so it will work with - Postgres. - - -1.5.9 (2012-04-16) ------------------- - -* Fixed: Issue with parsing timezone identifiers that were surrounded by quotes. - (Fixes emClient compatibility). - - -1.5.8 (2012-02-22) ------------------- - -* Fixed: Issue 95: Another timezone parsing issue, this time in calendar-query. - - -1.5.7 (2012-02-19) ------------------- - -* Fixed: VObject properties are now always encoded before components. -* Fixed: Sabre_DAVACL had issues with multiple levels of privilege aggregration. -* Changed: Added 'GuessContentType' plugin to fileserver.php example. -* Fixed: The Browser plugin will now trigger the correct events when creating - files. -* Fixed: The ICSExportPlugin now considers ACL's. -* Added: Made it optional to supply carddata from an Addressbook backend when - requesting getCards. This can make some operations much faster, and could - result in much lower memory use. -* Fixed: Issue 187: Sabre_DAV_UUIDUtil was missing from includes file. -* Fixed: Issue 191: beforeUnlock was triggered twice. - - -1.5.6 (2012-01-07) ------------------- - -* Fixed: Issue 174: VObject could break UTF-8 characters. -* Fixed: pear package installation issues. - - -1.5.5 (2011-12-16) ------------------- - -* Fixed: CalDAV time-range filter workaround for recurring events. -* Fixed: Bug in Sabre_DAV_Locks_Backend_File that didn't allow multiple files to - be locked at the same time. - - -1.5.4 (2011-10-28) ------------------- - -* Fixed: GuessContentType plugin now supports mixed case file extensions. -* Fixed: DATE-TIME encoding was wrong in VObject. (we used 'DATETIME'). -* Changed: Sending back HTTP 204 after a PUT request on an existing resource - instead of HTTP 200. This should fix Evolution CardDAV client compatibility. -* Fixed: Issue 95: Parsing X-LIC-LOCATION if it's available. -* Added: All VObject elements now have a reference to their parent node. - - -1.5.3 (2011-09-28) ------------------- - -* Fixed: Sabre_DAV_Collection was missing from the includes file. -* Fixed: Issue 152. iOS 1.4.2 apparantly requires HTTP/1.1 200 OK to be in - uppercase. -* Fixed: Issue 153: Support for files with mixed newline styles in - Sabre_VObject. -* Fixed: Issue 159: Automatically converting any vcard and icalendardata to - UTF-8. -* Added: Sabre_DAV_SimpleFile class for easy static file creation. -* Added: Issue 158: Support for the CARDDAV:supported-address-data property. - - -1.5.2 (2011-09-21) ------------------- - -* Fixed: carddata and calendardata MySQL fields are now of type 'mediumblob'. - 'TEXT' was too small sometimes to hold all the data. -* Fixed: {DAV:}supported-report-set is now correctly reporting the reports for - IAddressBook. -* Added: Sabre_VObject_Property::add() to add duplicate parameters to - properties. -* Added: Issue 151: Sabre_CalDAV_ICalendar and Sabre_CalDAV_ICalendarObject - interfaces. -* Fixed: Issue 140: Not returning 201 Created if an event cancelled the creation - of a file. -* Fixed: Issue 150: Faster URLUtil::encodePath() implementation. -* Fixed: Issue 144: Browser plugin could interfere with - TemporaryFileFilterPlugin if it was loaded first. -* Added: It's not possible to specify more 'alternate uris' in principal - backends. - - -1.5.1 (2011-08-24) ------------------- - -* Fixed: Issue 137. Hiding action interface in HTML browser for non-collections. -* Fixed: addressbook-query is now correctly returned from the - {DAV:}supported-report-set property. -* Fixed: Issue 142: Bugs in groupwareserver.php example. -* Fixed: Issue 139: Rejecting PUT requests with Content-Range. - - -1.5.0 (2011-08-12) ------------------- - -* Added: CardDAV support. -* Added: An experimental WebDAV client. -* Added: MIME-Directory grouping support in the VObject library. This is very - useful for people attempting to parse vcards. -* BC Break: Adding parameters with the VObject libraries now overwrites the - previous parameter, rather than just add it. This makes more sense for 99% of - the cases. -* BC Break: lib/Sabre.autoload.php is now removed in favor of - lib/Sabre/autoload.php. -* Deprecated: Sabre_DAV_Directory is now deprecated and will be removed in a - future version. Use Sabre_DAV_Collection instead. -* Deprecated: Sabre_DAV_SimpleDirectory is now deprecated and will be removed in - a future version. Use Sabre_DAV_SimpleCollection instead. -* Fixed: Problem with overriding tablenames for the CalDAV backend. -* Added: Clark-notation parser to XML utility. -* Added: unset() support to VObject components. -* Fixed: Refactored CalDAV property fetching to be faster and simpler. -* Added: Central string-matcher for CalDAV and CardDAV plugins. -* Added: i;unicode-casemap support -* Fixed: VObject bug: wouldn't parse parameters if they weren't specified in - uppercase. -* Fixed: VObject bug: Parameters now behave more like Properties. -* Fixed: VObject bug: Parameters with no value are now correctly parsed. -* Changed: If calendars don't specify which components they allow, 'all' - components are assumed (e.g.: VEVENT, VTODO, VJOURNAL). -* Changed: Browser plugin now uses POST variable 'sabreAction' instead of - 'action' to reduce the chance of collisions. - - -1.4.4 (2011-07-07) ------------------- - -* Fixed: Issue 131: Custom CalDAV backends could break in certain cases. -* Added: The option to override the default tablename all PDO backends use. - (Issue 60). -* Fixed: Issue 124: 'File' authentication backend now takes realm into - consideration. -* Fixed: Sabre_DAV_Property_HrefList now properly deserializes. This allows - users to update the {DAV:}group-member-set property. -* Added: Helper functions for DateTime-values in Sabre_VObject package. -* Added: VObject library can now automatically map iCalendar properties to - custom classes. - - -1.4.3 (2011-04-25) ------------------- - -* Fixed: Issue 123: Added workaround for Windows 7 UNLOCK bug. -* Fixed: datatype of lastmodified field in mysql.calendars.sql. Please change - the DATETIME field to an INT to ensure this field will work correctly. -* Change: Sabre_DAV_Property_Principal is now renamed to - Sabre_DAVACL_Property_Principal. -* Added: API level support for ACL HTTP method. -* Fixed: Bug in serializing {DAV:}acl property. -* Added: deserializer for {DAV:}resourcetype property. -* Added: deserializer for {DAV:}acl property. -* Added: deserializer for {DAV:}principal property. - - -1.4.2-beta (2011-04-01) ------------------------ - -* Added: It's not possible to disable listing of nodes that are denied read - access by ACL. -* Fixed: Changed a few properties in CalDAV classes from private to protected. -* Fixed: Issue 119: Terrible things could happen when relying on guessBaseUri, - the server was running on the root of the domain and a user tried to access a - file ending in .php. This is a slight BC break. -* Fixed: Issue 118: Lock tokens in If headers without a uri should be treated as - the request uri, not 'all relevant uri's. -* Fixed: Issue 120: PDO backend was incorrectly fetching too much locks in cases - where there were similar named locked files in a directory. - - -1.4.1-beta (2011-02-26) ------------------------ - -* Fixed: Sabre_DAV_Locks_Backend_PDO returned too many locks. -* Fixed: Sabre_HTTP_Request::getHeader didn't return Content-Type when running - on apache, so a few workarounds were added. -* Change: Slightly changed CalDAV Backend API's, to allow for heavy - optimizations. This is non-bc breaking. - - -1.4.0-beta (2011-02-12) ------------------------ - -* Added: Partly RFC3744 ACL support. -* Added: Calendar-delegation (caldav-proxy) support. -* BC break: In order to fix Issue 99, a new argument had to be added to - Sabre_DAV_Locks_Backend_*::getLocks classes. Consult the classes for details. -* Deprecated: Sabre_DAV_Locks_Backend_FS is now deprecated and will be removed - in a later version. Use PDO or the new File class instead. -* Deprecated: The Sabre_CalDAV_ICalendarUtil class is now marked deprecated, and - will be removed in a future version. Please use Sabre_VObject instead. -* Removed: All principal-related functionality has been removed from the - Sabre_DAV_Auth_Plugin, and moved to the Sabre_DAVACL_Plugin. -* Added: VObject library, for easy vcard/icalendar parsing using a natural - interface. -* Added: Ability to automatically generate full .ics feeds off calendars. To - use: Add the Sabre_CalDAV_ICSExportPlugin, and add ?export to your calendar - url. -* Added: Plugins can now specify a pluginname, for easy access using - Sabre_DAV_Server::getPlugin(). -* Added: beforeGetProperties event. -* Added: updateProperties event. -* Added: Principal listings and calendar-access can now be done privately, - disallowing users from accessing or modifying other users' data. -* Added: You can now pass arrays to the Sabre_DAV_Server constructor. If it's an - array with node-objects, a Root collection will automatically be created, and - the nodes are used as top-level children. -* Added: The principal base uri is now customizable. It used to be hardcoded to - 'principals/[user]'. -* Added: getSupportedReportSet method in ServerPlugin class. This allows you to - easily specify which reports you're implementing. -* Added: A '..' link to the HTML browser. -* Fixed: Issue 99: Locks on child elements were ignored when their parent nodes - were deleted. -* Fixed: Issue 90: lockdiscovery property and LOCK response now include a - {DAV}lockroot element. -* Fixed: Issue 96: support for 'default' collation in CalDAV text-match filters. -* Fixed: Issue 102: Ensuring that copy and move with identical source and - destination uri's fails. -* Fixed: Issue 105: Supporting MKCALENDAR with no body. -* Fixed: Issue 109: Small fixes in Sabre_HTTP_Util. -* Fixed: Issue 111: Properly catching the ownername in a lock (if it's a string) -* Fixed: Sabre_DAV_ObjectTree::nodeExist always returned false for the root - node. -* Added: Global way to easily supply new resourcetypes for certain node classes. -* Fixed: Issue 59: Allowing the user to override the authentication realm in - Sabre_CalDAV_Server. -* Update: Issue 97: Looser time-range checking if there's a recurrence rule in - an event. This fixes 'missing recurring events'. - - -1.3.0 (2010-10-14) ------------------- - -* Added: childExists method to Sabre_DAV_ICollection. This is an api break, so - if you implement Sabre_DAV_ICollection directly, add the method. -* Changed: Almost all HTTP method implementations now take a uri argument, - including events. This allows for internal rerouting of certain calls. If you - have custom plugins, make sure they use this argument. If they don't, they - will likely still work, but it might get in the way of future changes. -* Changed: All getETag methods MUST now surround the etag with double-quotes. - This was a mistake made in all previous SabreDAV versions. If you don't do - this, any If-Match, If-None-Match and If: headers using Etags will work - incorrectly. (Issue 85). -* Added: Sabre_DAV_Auth_Backend_AbstractBasic class, which can be used to easily - implement basic authentication. -* Removed: Sabre_DAV_PermissionDenied class. Use Sabre_DAV_Forbidden instead. -* Removed: Sabre_DAV_IDirectory interface, use Sabre_DAV_ICollection instead. -* Added: Browser plugin now uses {DAV:}displayname if this property is - available. -* Added: Cache layer in the ObjectTree. -* Added: Tree classes now have a delete and getChildren method. -* Fixed: If-Modified-Since and If-Unmodified-Since would be incorrect if the - date is an exact match. -* Fixed: Support for multiple ETags in If-Match and If-None-Match headers. -* Fixed: Improved baseUrl handling. -* Fixed: Issue 67: Non-seekable stream support in ::put()/::get(). -* Fixed: Issue 65: Invalid dates are now ignored. -* Updated: Refactoring in Sabre_CalDAV to make everything a bit more ledgable. -* Fixed: Issue 88, Issue 89: Fixed compatibility for running SabreDAV on - Windows. -* Fixed: Issue 86: Fixed Content-Range top-boundary from 'file size' to 'file - size'-1. - - -1.2.5 (2010-08-18) ------------------- - -* Fixed: Issue 73: guessBaseUrl fails for some servers. -* Fixed: Issue 67: SabreDAV works better with non-seekable streams. -* Fixed: If-Modified-Since and If-Unmodified-Since would be incorrect if - the date is an exact match. - - -1.2.4 (2010-07-13) ------------------- - -* Fixed: Issue 62: Guessing baseUrl fails when url contains a query-string. -* Added: Apache configuration sample for CGI/FastCGI setups. -* Fixed: Issue 64: Only returning calendar-data when it was actually requested. - - -1.2.3 (2010-06-26) ------------------- - -* Fixed: Issue 57: Supporting quotes around etags in If-Match and If-None-Match - - -1.2.2 (2010-06-21) ------------------- - -* Updated: SabreDAV now attempts to guess the BaseURI if it's not set. -* Updated: Better compatibility with BitKinex -* Fixed: Issue 56: Incorrect behaviour for If-None-Match headers and GET - requests. -* Fixed: Issue with certain encoded paths in Browser Plugin. - - -1.2.1 (2010-06-07) ------------------- - -* Fixed: Issue 50, patch by Mattijs Hoitink. -* Fixed: Issue 51, Adding windows 7 lockfiles to TemporaryFileFilter. -* Fixed: Issue 38, Allowing custom filters to be added to TemporaryFileFilter. -* Fixed: Issue 53, ETags in the If: header were always failing. This behaviour - is now corrected. -* Added: Apache Authentication backend, in case authentication through .htaccess - is desired. -* Updated: Small improvements to example files. - - -1.2.0 (2010-05-24) ------------------- - -* Fixed: Browser plugin now displays international characters. -* Changed: More properties in CalDAV classes are now protected instead of - private. - - -1.2.0beta3 (2010-05-14) ------------------------ - -* Fixed: Custom properties were not properly sent back for allprops requests. -* Fixed: Issue 49, incorrect parsing of PROPPATCH, affecting Office 2007. -* Changed: Removed CalDAV items from includes.php, and added a few missing ones. - - -1.2.0beta2 (2010-05-04) ------------------------ - -* Fixed: Issue 46: Fatal error for some non-existent nodes. -* Updated: some example sql to include email address. -* Added: 208 and 508 statuscodes from RFC5842. -* Added: Apache2 configuration examples - - -1.2.0beta1 (2010-04-28) ------------------------ - -* Fixed: redundant namespace declaration in resourcetypes. -* Fixed: 2 locking bugs triggered by litmus when no Sabre_DAV_ILockable - interface is used. -* Changed: using http://sabredav.org/ns for all custom xml properties. -* Added: email address property to principals. -* Updated: CalendarObject validation. - - -1.2.0alpha4 (2010-04-24) ------------------------- - -* Added: Support for If-Range, If-Match, If-None-Match, If-Modified-Since, - If-Unmodified-Since. -* Changed: Brand new build system. Functionality is split up between Sabre, - Sabre_HTTP, Sabre_DAV and Sabre_CalDAV packages. In addition to that a new - non-pear package will be created with all this functionality combined. -* Changed: Autoloader moved to Sabre/autoload.php. -* Changed: The Allow: header is now more accurate, with appropriate HTTP methods - per uri. -* Changed: Now throwing back Sabre_DAV_Exception_MethodNotAllowed on a few - places where Sabre_DAV_Exception_NotImplemented was used. - - -1.2.0alpha3 (2010-04-20) ------------------------- - -* Update: Complete rewrite of property updating. Now easier to use and atomic. -* Fixed: Issue 16, automatically adding trailing / to baseUri. -* Added: text/plain is used for .txt files in GuessContentType plugin. -* Added: support for principal-property-search and principal-search-property-set - reports. -* Added: Issue 31: Hiding exception information by default. Can be turned on - with the Sabre_DAV_Server::$debugExceptions property. - - -1.2.0alpha2 (2010-04-08) ------------------------- - -* Added: Calendars are now private and can only be read by the owner. -* Fixed: double namespace declaration in multistatus responses. -* Added: MySQL database dumps. MySQL is now also supported next to SQLite. -* Added: expand-properties REPORT from RFC 3253. -* Added: Sabre_DAV_Property_IHref interface for properties exposing urls. -* Added: Issue 25: Throwing error on broken Finder behaviour. -* Changed: Authentication backend is now aware of current user. - - -1.2.0alpha1 (2010-03-31) ------------------------- - -* Fixed: Issue 26: Workaround for broken GVFS behaviour with encoded special - characters. -* Fixed: Issue 34: Incorrect Lock-Token response header for LOCK. Fixes Office - 2010 compatibility. -* Added: Issue 35: SabreDAV version to header to OPTIONS response to ease - debugging. -* Fixed: Issue 36: Incorrect variable name, throwing error in some requests. -* Fixed: Issue 37: Incorrect smultron regex in temporary filefilter. -* Fixed: Issue 33: Converting ISO-8859-1 characters to UTF-8. -* Fixed: Issue 39 & Issue 40: Basename fails on non-utf-8 locales. -* Added: More unittests. -* Added: SabreDAV version to all error responses. -* Added: URLUtil class for decoding urls. -* Changed: Now using pear.sabredav.org pear channel. -* Changed: Sabre_DAV_Server::getCopyAndMoveInfo is now a public method. - - -1.1.2-alpha (2010-03-18) ------------------------- - -* Added: RFC5397 - current-user-principal support. -* Fixed: Issue 27: encoding entities in property responses. -* Added: naturalselection script now allows the user to specify a 'minimum - number of bytes' for deletion. This should reduce load due to less crawling -* Added: Full support for the calendar-query report. -* Added: More unittests. -* Added: Support for complex property deserialization through the static - ::unserialize() method. -* Added: Support for modifying calendar-component-set -* Fixed: Issue 29: Added TIMEOUT_INFINITE constant - - -1.1.1-alpha (2010-03-11) ------------------------- - -* Added: RFC5689 - Extended MKCOL support. -* Fixed: Evolution support for CalDAV. -* Fixed: PDO-locks backend was pretty much completely broken. This is 100% - unittested now. -* Added: support for ctags. -* Fixed: Comma's between HTTP methods in 'Allow' method. -* Changed: default argument for Sabre_DAV_Locks_Backend_FS. This means a - datadirectory must always be specified from now on. -* Changed: Moved Sabre_DAV_Server::parseProps to - Sabre_DAV_XMLUtil::parseProperties. -* Changed: Sabre_DAV_IDirectory is now Sabre_DAV_ICollection. -* Changed: Sabre_DAV_Exception_PermissionDenied is now - Sabre_DAV_Exception_Forbidden. -* Changed: Sabre_CalDAV_ICalendarCollection is removed. -* Added: Sabre_DAV_IExtendedCollection. -* Added: Many more unittests. -* Added: support for calendar-timezone property. - - -1.1.0-alpha (2010-03-01) ------------------------- - -* Note: This version is forked from version 1.0.5, so release dates may be out - of order. -* Added: CalDAV - RFC 4791 -* Removed: Sabre_PHP_Exception. PHP has a built-in ErrorException for this. -* Added: PDO authentication backend. -* Added: Example sql for auth, caldav, locks for sqlite. -* Added: Sabre_DAV_Browser_GuessContentType plugin -* Changed: Authentication plugin refactored, making it possible to implement - non-digest authentication. -* Fixed: Better error display in browser plugin. -* Added: Support for {DAV:}supported-report-set -* Added: XML utility class with helper functions for the WebDAV protocol. -* Added: Tons of unittests -* Added: PrincipalCollection and Principal classes -* Added: Sabre_DAV_Server::getProperties for easy property retrieval -* Changed: {DAV:}resourceType defaults to 0 -* Changed: Any non-null resourceType now gets a / appended to the href value. - Before this was just for {DAV:}collection's, but this is now also the case for - for example {DAV:}principal. -* Changed: The Href property class can now optionally create non-relative uri's. -* Changed: Sabre_HTTP_Response now returns false if headers are already sent and - header-methods are called. -* Fixed: Issue 19: HEAD requests on Collections -* Fixed: Issue 21: Typo in Sabre_DAV_Property_Response -* Fixed: Issue 18: Doesn't work with Evolution Contacts - - -1.0.15 (2010-05-28) -------------------- - -* Added: Issue 31: Hiding exception information by default. Can be turned on - with the Sabre_DAV_Server::$debugExceptions property. -* Added: Moved autoload from lib/ to lib/Sabre/autoload.php. This is also the - case in the upcoming 1.2.0, so it will improve future compatibility. - - -1.0.14 (2010-04-15) -------------------- - -* Fixed: double namespace declaration in multistatus responses. - - -1.0.13 (2010-03-30) -------------------- - -* Fixed: Issue 40: Last references to basename/dirname - - -1.0.12 (2010-03-30) -------------------- - -* Fixed: Issue 37: Incorrect smultron regex in temporary filefilter. -* Fixed: Issue 26: Workaround for broken GVFS behaviour with encoded special - characters. -* Fixed: Issue 33: Converting ISO-8859-1 characters to UTF-8. -* Fixed: Issue 39: Basename fails on non-utf-8 locales. -* Added: More unittests. -* Added: SabreDAV version to all error responses. -* Added: URLUtil class for decoding urls. -* Updated: Now using pear.sabredav.org pear channel. - - -1.0.11 (2010-03-23) -------------------- - -* Non-public release. This release is identical to 1.0.10, but it is used to - test releasing packages to pear.sabredav.org. - - -1.0.10 (2010-03-22) -------------------- - -* Fixed: Issue 34: Invalid Lock-Token header response. -* Added: Issue 35: Adding SabreDAV version to HTTP OPTIONS responses. - - -1.0.9 (2010-03-19) ------------------- - -* Fixed: Issue 27: Entities not being encoded in PROPFIND responses. -* Fixed: Issue 29: Added missing TIMEOUT_INFINITE constant. - - -1.0.8 (2010-03-03) ------------------- - -* Fixed: Issue 21: typos causing errors -* Fixed: Issue 23: Comma's between methods in Allow header. -* Added: Sabre_DAV_ICollection interface, to aid in future compatibility. -* Added: Sabre_DAV_Exception_Forbidden exception. This will replace - Sabre_DAV_Exception_PermissionDenied in the future, and can already be used to - ensure future compatibility. - - -1.0.7 (2010-02-24) ------------------- - -* Fixed: Issue 19 regression for MS Office - - -1.0.6 (2010-02-23) ------------------- - -* Fixed: Issue 19: HEAD requests on Collections - - -1.0.5 (2010-01-22) ------------------- - -* Fixed: Fatal error when a malformed url was used for unlocking, in conjuction - with Sabre.autoload.php due to a incorrect filename. -* Fixed: Improved unittests and build system - - -1.0.4 (2010-01-11) ------------------- - -* Fixed: needed 2 different releases. One for googlecode and one for pearfarm. - This is to retain the old method to install SabreDAV until pearfarm becomes - the standard installation method. - - -1.0.3 (2010-01-11) ------------------- - -* Added: RFC4709 support (davmount) -* Added: 6 unittests -* Added: naturalselection. A tool to keep cache directories below a specified - theshold. -* Changed: Now using pearfarm.org channel server. - - -1.0.1 (2009-12-22) ------------------- - -* Fixed: Issue 15: typos in examples -* Fixed: Minor pear installation issues - - -1.0.0 (2009-11-02) ------------------- - -* Added: SimpleDirectory class. This class allows creating static directory - structures with ease. -* Changed: Custom complex properties and exceptions now get an instance of - Sabre_DAV_Server as their first argument in serialize() -* Changed: Href complex property now prepends server's baseUri -* Changed: delete before an overwriting copy/move is now handles by server class - instead of tree classes -* Changed: events must now explicitly return false to stop execution. Before, - execution would be stopped by anything loosely evaluating to false. -* Changed: the getPropertiesForPath method now takes a different set of - arguments, and returns a different response. This allows plugin developers to - return statuses for properties other than 200 and 404. The hrefs are now also - always calculated relative to the baseUri, and not the uri of the request. -* Changed: generatePropFindResponse is renamed to generateMultiStatus, and now - takes a list of properties similar to the response of getPropertiesForPath. - This was also needed to improve flexibility for plugin development. -* Changed: Auth plugins are no longer included. They were not yet stable - quality, so they will probably be reintroduced in a later version. -* Changed: PROPPATCH also used generateMultiStatus now. -* Removed: unknownProperties event. This is replaced by the afterGetProperties - event, which should provide more flexibility. -* Fixed: Only calling getSize() on IFile instances in httpHead() -* Added: beforeBind event. This is invoked upon file or directory creation -* Added: beforeWriteContent event, this is invoked by PUT and LOCK on an - existing resource. -* Added: beforeUnbind event. This is invoked right before deletion of any - resource. -* Added: afterGetProperties event. This event can be used to make modifications - to property responses. -* Added: beforeLock and beforeUnlock events. -* Added: afterBind event. -* Fixed: Copy and Move could fail in the root directory. This is now fixed. -* Added: Plugins can now be retrieved by their classname. This is useful for - inter-plugin communication. -* Added: The Auth backend can now return usernames and user-id's. -* Added: The Auth backend got a getUsers method -* Added: Sabre_DAV_FSExt_Directory now returns quota info - - -0.12.1-beta (2009-09-11) ------------------------- - -* Fixed: UNLOCK bug. Unlock didn't work at all - - -0.12-beta (2009-09-10) ----------------------- - -* Updated: Browser plugin now shows multiple {DAV:}resourcetype values if - available. -* Added: Experimental PDO backend for Locks Manager -* Fixed: Sending Content-Length: 0 for every empty response. This improves NGinx - compatibility. -* Fixed: Last modification time is reported in UTC timezone. This improves - Finder compatibility. - - -0.11-beta (2009-08-11) ----------------------- - -* Updated: Now in Beta -* Updated: Pear package no longer includes docs/ directory. These just contained - rfc's, which are publicly available. This reduces the package from ~800k to - ~60k -* Added: generatePropfindResponse now takes a baseUri argument -* Added: ResourceType property can now contain multiple resourcetypes. -* Fixed: Issue 13. - - -0.10-alpha (2009-08-03) ------------------------ - -* Added: Plugin to automatically map GET requests to non-files to PROPFIND - (Sabre_DAV_Browser_MapGetToPropFind). This should allow easier debugging of - complicated WebDAV setups. -* Added: Sabre_DAV_Property_Href class. For future use. -* Added: Ability to choose to use auth-int, auth or both for HTTP Digest - authentication. (Issue 11) -* Changed: Made more methods in Sabre_DAV_Server public. -* Fixed: TemporaryFileFilter plugin now intercepts HTTP LOCK requests to - non-existent files. (Issue 12) -* Added: Central list of defined xml namespace prefixes. This can reduce - Bandwidth and legibility for xml bodies with user-defined namespaces. -* Added: now a PEAR-compatible package again, thanks to Michael Gauthier -* Changed: moved default copy and move logic from ObjectTree to Tree class - -0.9a-alpha (2009-07-21) ----------------------- - -* Fixed: Broken release - -0.9-alpha (2009-07-21) ----------------------- - -* Changed: Major refactoring, removed most of the logic from the Tree objects. - The Server class now directly works with the INode, IFile and IDirectory - objects. If you created your own Tree objects, this will most likely break in - this release. -* Changed: Moved all the Locking logic from the Tree and Server classes into a - separate plugin. -* Changed: TemporaryFileFilter is now a plugin. -* Added: Comes with an autoloader script. This can be used instead of the - includer script, and is preferred by some people. -* Added: AWS Authentication class. -* Added: simpleserversetup.py script. This will quickly get a fileserver up and - running. -* Added: When subscribing to events, it is now possible to supply a priority. - This is for example needed to ensure that the Authentication Plugin is used - before any other Plugin. -* Added: 22 new tests. -* Added: Users-manager plugin for .htdigest files. Experimental and subject to - change. -* Added: RFC 2324 HTTP 418 status code -* Fixed: Exclusive locks could in some cases be picked up as shared locks -* Fixed: Digest auth for non-apache servers had a bug (still not actually tested - this well). - - -0.8-alpha (2009-05-30) ----------------------- - -* Changed: Renamed all exceptions! This is a compatibility break. Every - Exception now follows Sabre_DAV_Exception_FileNotFound convention instead of - Sabre_DAV_FileNotFoundException. -* Added: Browser plugin now allows uploading and creating directories straight - from the browser. -* Added: 12 more unittests -* Fixed: Locking bug, which became prevalent on Windows Vista. -* Fixed: Netdrive support -* Fixed: TemporaryFileFilter filtered out too many files. Fixed some of the - regexes. -* Fixed: Added README and ChangeLog to package - - -0.7-alpha (2009-03-29) ----------------------- - -* Added: System to return complex properties from PROPFIND. -* Added: support for {DAV:}supportedlock. -* Added: support for {DAV:}lockdiscovery. -* Added: 6 new tests. -* Added: New plugin system. -* Added: Simple HTML directory plugin, for browser access. -* Added: Server class now sends back standard pre-condition error xml bodies. - This was new since RFC4918. -* Added: Sabre_DAV_Tree_Aggregate, which can 'host' multiple Tree objects into - one. -* Added: simple basis for HTTP REPORT method. This method is not used yet, but - can be used by plugins to add reports. -* Changed: ->getSize is only called for files, no longer for collections. r303 -* Changed: Sabre_DAV_FilterTree is now Sabre_DAV_Tree_Filter -* Changed: Sabre_DAV_TemporaryFileFilter is now called - Sabre_DAV_Tree_TemporaryFileFilter. -* Changed: removed functions (get(/set)HTTPRequest(/Response)) from Server - class, and using a public property instead. -* Fixed: bug related to parsing proppatch and propfind requests. Didn't show up - in most clients, but it needed fixing regardless. (r255) -* Fixed: auth-int is now properly supported within HTTP Digest. -* Fixed: Using application/xml for a mimetype vs. text/xml as per RFC4918 sec - 8.2. -* Fixed: TemporaryFileFilter now lets through GET's if they actually exist on - the backend. (r274) -* Fixed: Some methods didn't get passed through in the FilterTree (r283). -* Fixed: LockManager is now slightly more complex, Tree classes slightly less. - (r287) - - -0.6-alpha (2009-02-16) ----------------------- - -* Added: Now uses streams for files, instead of strings. This means it won't - require to hold entire files in memory, which can be an issue if you're - dealing with big files. Note that this breaks compatibility for put() and - createFile methods. -* Added: HTTP Digest Authentication helper class. -* Added: Support for HTTP Range header -* Added: Support for ETags within If: headers -* Added: The API can now return ETags and override the default Content-Type -* Added: starting with basic framework for unittesting, using PHPUnit. -* Added: 49 unittests. -* Added: Abstraction for the HTTP request. -* Updated: Using Clark Notation for tags in properties. This means tags are - serialized as {namespace}tagName instead of namespace#tagName -* Fixed: HTTP_BasicAuth class now works as expected. -* Fixed: DAV_Server uses / for a default baseUrl. -* Fixed: Last modification date is no longer ignored in PROPFIND. -* Fixed: PROPFIND now sends back information about the requestUri even when - "Depth: 1" is specified. - - -0.5-alpha (2009-01-14) ----------------------- - -* Added: Added a very simple example for implementing a mapping to PHP file - streams. This should allow easy implementation of for example a WebDAV to FTP - proxy. -* Added: HTTP Basic Authentication helper class. -* Added: Sabre_HTTP_Response class. This centralizes HTTP operations and will be - a start towards the creating of a testing framework. -* Updated: Backwards compatibility break: all require_once() statements are - removed from all the files. It is now recommended to use autoloading of - classes, or just including lib/Sabre.includes.php. This fix was made to allow - easier integration into applications not using this standard inclusion model. -* Updated: Better in-file documentation. -* Updated: Sabre_DAV_Tree can now work with Sabre_DAV_LockManager. -* Updated: Fixes a shared-lock bug. -* Updated: Removed ?> from the bottom of each php file. -* Updated: Split up some operations from Sabre_DAV_Server to - Sabre_HTTP_Response. -* Fixed: examples are now actually included in the pear package. - - -0.4-alpha (2008-11-05) ----------------------- - -* Passes all litmus tests! -* Added: more examples -* Added: Custom property support -* Added: Shared lock support -* Added: Depth support to locks -* Added: Locking on unmapped urls (non-existent nodes) -* Fixed: Advertising as WebDAV class 3 support - - -0.3-alpha (2008-06-29) ----------------------- - -* Fully working in MS Windows clients. -* Added: temporary file filter: support for smultron files. -* Added: Phing build scripts -* Added: PEAR package -* Fixed: MOVE bug identified using finder. -* Fixed: Using gzuncompress instead of gzdecode in the temporary file filter. - This seems more common. - - -0.2-alpha (2008-05-27) ----------------------- - -* Somewhat working in Windows clients -* Added: Working PROPPATCH method (doesn't support custom properties yet) -* Added: Temporary filename handling system -* Added: Sabre_DAV_IQuota to return quota information -* Added: PROPFIND now reads the request body and only supplies the requested - properties - - -0.1-alpha (2008-04-04) ----------------------- - -* First release! -* Passes litmus: basic, http and copymove test. -* Fully working in Finder and DavFS2. - -Project started: 2007-12-13 - -[vobj]: http://sabre.io/vobject/ -[evnt]: http://sabre.io/event/ -[http]: http://sabre.io/http/ -[uri]: http://sabre.io/uri/ -[xml]: http://sabre.io/xml/ -[mi20]: http://sabre.io/dav/upgrade/1.8-to-2.0/ -[rfc6638]: http://tools.ietf.org/html/rfc6638 "CalDAV Scheduling" -[rfc7240]: http://tools.ietf.org/html/rfc7240 -[calendar-availability]: https://tools.ietf.org/html/draft-daboo-calendar-availability-05 diff --git a/vendor/sabre/dav/CONTRIBUTING.md b/vendor/sabre/dav/CONTRIBUTING.md deleted file mode 100644 index b937db64f..000000000 --- a/vendor/sabre/dav/CONTRIBUTING.md +++ /dev/null @@ -1,109 +0,0 @@ -Contributing to sabre projects -============================== - -Want to contribute to sabre/dav? Here are some guidelines to ensure your patch -gets accepted. - - -Building a new feature? Contact us first ----------------------------------------- - -We may not want to accept every feature that comes our way. Sometimes -features are out of scope for our projects. - -We don't want to waste your time, so by having a quick chat with us first, -you may find out quickly if the feature makes sense to us, and we can give -some tips on how to best build the feature. - -If we don't accept the feature, it could be for a number of reasons. For -instance, we've rejected features in the past because we felt uncomfortable -assuming responsibility for maintaining the feature. - -In those cases, it's often possible to keep the feature separate from the -sabre projects. sabre/dav for instance has a plugin system, and there's no -reason the feature can't live in a project you own. - -In that case, definitely let us know about your plugin as well, so we can -feature it on [sabre.io][4]. - -We are often on [IRC][5], in the #sabredav channel on freenode. If there's -no one there, post a message on the [mailing list][6]. - - -Coding standards ----------------- - -sabre projects follow: - -1. [PSR-1][1] -2. [PSR-4][2] - -sabre projects don't follow [PSR-2][3]. - -In addition to that, here's a list of basic rules: - -1. PHP 5.4 array syntax must be used every where. This means you use `[` and - `]` instead of `array(` and `)`. -2. Use PHP namespaces everywhere. -3. Use 4 spaces for indentation. -4. Try to keep your lines under 80 characters. This is not a hard rule, as - there are many places in the source where it felt more sensibile to not - do so. In particular, function declarations are never split over multiple - lines. -5. Opening braces (`{`) are _always_ on the same line as the `class`, `if`, - `function`, etc. they belong to. -6. `public` must be omitted from method declarations. It must also be omitted - for static properties. -7. All files should use unix-line endings (`\n`). -8. Files must omit the closing php tag (`?>`). -9. `true`, `false` and `null` are always lower-case. -10. Constants are always upper-case. -11. Any of the rules stated before may be broken where this is the pragmatic - thing to do. - - -Unit test requirements ----------------------- - -Any new feature or change requires unittests. We use [PHPUnit][7] for all our -tests. - -Adding unittests will greatly increase the likelyhood of us quickly accepting -your pull request. If unittests are not included though for whatever reason, -we'd still _love_ your pull request. - -We may have to write the tests ourselves, which can increase the time it takes -to accept the patch, but we'd still really like your contribution! - -To run the testsuite jump into the directory `cd tests` and trigger `phpunit`. -Make sure you did a `composer install` beforehand. - -Release process ---------------- - -Generally, these are the steps taken to do releases. - -1. Update the changelog. Every repo will have a `CHANGELOG.md` file. This file - should have a new version, and contain all the changes since the last - release. I generally run a `git diff` to figure out if I missed any changes. - This file should also have the current date. -2. If there were BC breaks, this usually now means a major version bump. -3. Ensure that `lib/Version.php` or `lib/DAV/Version.php` also matches this - version number. -4. Tag the release (Example `git tag 3.0.1` and push the tag (`git push --tags`). -5. (only for the sabre/dav project), create a zip distribution. Run - `php bin/build.php`. -6. For the relevant project, go to github and click the 'releases' tab. On this - tab I create the release with the relevant version. I also set the - description of the release to the same information of the changelog. In the - case of the `sabre/dav` project I also upload the zip distribution here. -7. Write a blog post on sabre.io. This also automatically updates twitter. - - -[1]: http://www.php-fig.org/psr/psr-1/ -[2]: http://www.php-fig.org/psr/psr-4/ -[3]: http://www.php-fig.org/psr/psr-2/ -[4]: http://sabre.io/ -[5]: irc://freenode.net/#sabredav -[6]: http://groups.google.com/group/sabredav-discuss -[7]: http://phpunit.de/ diff --git a/vendor/sabre/dav/bin/build.php b/vendor/sabre/dav/bin/build.php old mode 100644 new mode 100755 index 54174a777..4dd25d9c9 --- a/vendor/sabre/dav/bin/build.php +++ b/vendor/sabre/dav/bin/build.php @@ -32,7 +32,7 @@ if ($argc > 2) { if (!isset($tasks[$currentTask])) { echo 'Task not found: ', $currentTask, "\n"; - die(1); + exit(1); } // Creating the dependency graph @@ -43,7 +43,7 @@ while (count($oldTaskList) > 0) { foreach ($oldTaskList as $task => $foo) { if (!isset($tasks[$task])) { echo 'Dependency not found: '.$task, "\n"; - die(1); + exit(1); } $dependencies = $tasks[$task]; @@ -107,7 +107,7 @@ function test() system(__DIR__.'/phpunit --configuration '.$baseDir.'/tests/phpunit.xml.dist --stop-on-failure', $code); if (0 != $code) { echo "PHPUnit reported error code $code\n"; - die(1); + exit(1); } } @@ -139,7 +139,7 @@ function buildzip() system('cd build/SabreDAV; composer install -n', $code); if (0 !== $code) { echo "Composer reported error code $code\n"; - die(1); + exit(1); } echo " Removing pointless files\n"; diff --git a/vendor/sabre/dav/bin/googlecode_upload.py b/vendor/sabre/dav/bin/googlecode_upload.py old mode 100644 new mode 100755 diff --git a/vendor/sabre/dav/bin/migrateto20.php b/vendor/sabre/dav/bin/migrateto20.php old mode 100644 new mode 100755 index c7a8d9e35..fb24fe599 --- a/vendor/sabre/dav/bin/migrateto20.php +++ b/vendor/sabre/dav/bin/migrateto20.php @@ -72,7 +72,7 @@ switch ($driver) { break; default: echo 'Error: unsupported driver: '.$driver."\n"; - die(-1); + exit(-1); } foreach (['calendar', 'addressbook'] as $itemType) { @@ -130,7 +130,6 @@ foreach (['calendar', 'addressbook'] as $itemType) { break; case 'sqlite': - $pdo->exec("ALTER TABLE $tableName RENAME TO $tableNameOld"); switch ($itemType) { @@ -370,7 +369,6 @@ CREATE TABLE cards ( break; case 'sqlite': - $pdo->exec(' CREATE TABLE cards ( id integer primary key asc, @@ -395,7 +393,6 @@ CREATE TABLE cards ( break; case 'sqlite': - $pdo->exec(' ALTER TABLE cards ADD etag text; ALTER TABLE cards ADD size integer; diff --git a/vendor/sabre/dav/bin/migrateto21.php b/vendor/sabre/dav/bin/migrateto21.php old mode 100644 new mode 100755 index 909643583..2c15b0a21 --- a/vendor/sabre/dav/bin/migrateto21.php +++ b/vendor/sabre/dav/bin/migrateto21.php @@ -73,7 +73,7 @@ switch ($driver) { break; default: echo 'Error: unsupported driver: '.$driver."\n"; - die(-1); + exit(-1); } echo "Upgrading 'calendarobjects'\n"; diff --git a/vendor/sabre/dav/bin/migrateto30.php b/vendor/sabre/dav/bin/migrateto30.php old mode 100644 new mode 100755 index 25e544c2a..9798cadd2 --- a/vendor/sabre/dav/bin/migrateto30.php +++ b/vendor/sabre/dav/bin/migrateto30.php @@ -72,7 +72,7 @@ switch ($driver) { break; default: echo 'Error: unsupported driver: '.$driver."\n"; - die(-1); + exit(-1); } echo "Upgrading 'propertystorage'\n"; diff --git a/vendor/sabre/dav/bin/migrateto32.php b/vendor/sabre/dav/bin/migrateto32.php old mode 100644 new mode 100755 index 57fd35507..09ac55d13 --- a/vendor/sabre/dav/bin/migrateto32.php +++ b/vendor/sabre/dav/bin/migrateto32.php @@ -75,7 +75,7 @@ switch ($driver) { break; default: echo 'Error: unsupported driver: '.$driver."\n"; - die(-1); + exit(-1); } echo "Creating 'calendarinstances'\n"; diff --git a/vendor/sabre/dav/bin/sabredav.php b/vendor/sabre/dav/bin/sabredav.php old mode 100644 new mode 100755 index 28341b587..71047b8f8 --- a/vendor/sabre/dav/bin/sabredav.php +++ b/vendor/sabre/dav/bin/sabredav.php @@ -20,7 +20,7 @@ class CliLog $log = new CliLog(); if ('cli-server' !== php_sapi_name()) { - die('This script is intended to run on the built-in php webserver'); + exit('This script is intended to run on the built-in php webserver'); } // Finding composer diff --git a/vendor/sabre/dav/composer.json b/vendor/sabre/dav/composer.json index fa912faf5..7c9596d21 100644 --- a/vendor/sabre/dav/composer.json +++ b/vendor/sabre/dav/composer.json @@ -33,7 +33,7 @@ "ext-json": "*" }, "require-dev" : { - "friendsofphp/php-cs-fixer": "^2.16.7", + "friendsofphp/php-cs-fixer": "^2.17.1", "phpstan/phpstan": "^0.12", "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", "evert/phpdoc-md" : "~0.1.0", diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php index 7a07724b3..0d5df3968 100644 --- a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php +++ b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php @@ -7,6 +7,7 @@ namespace Sabre\CalDAV\Backend; use Sabre\CalDAV; use Sabre\DAV; use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\PropPatch; use Sabre\DAV\Xml\Element\Sharee; use Sabre\VObject; @@ -289,7 +290,7 @@ SQL * * @param mixed $calendarId */ - public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) + public function updateCalendar($calendarId, PropPatch $propPatch) { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); @@ -779,17 +780,20 @@ SQL $componentType = $filters['comp-filters'][0]['name']; // Checking if we need post-filters - if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['time-range'] && !$filters['comp-filters'][0]['prop-filters']) { + $has_time_range = array_key_exists('time-range', $filters['comp-filters'][0]) && $filters['comp-filters'][0]['time-range']; + if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$has_time_range && !$filters['comp-filters'][0]['prop-filters']) { $requirePostFilter = false; } // There was a time-range filter - if ('VEVENT' == $componentType && isset($filters['comp-filters'][0]['time-range'])) { + if ('VEVENT' == $componentType && $has_time_range) { $timeRange = $filters['comp-filters'][0]['time-range']; // If start time OR the end time is not specified, we can do a // 100% accurate mysql query. - if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && (!$timeRange['start'] || !$timeRange['end'])) { - $requirePostFilter = false; + if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && $timeRange) { + if ((array_key_exists('start', $timeRange) && !$timeRange['start']) || (array_key_exists('end', $timeRange) && !$timeRange['end'])) { + $requirePostFilter = false; + } } } } @@ -809,11 +813,11 @@ SQL $values['componenttype'] = $componentType; } - if ($timeRange && $timeRange['start']) { + if ($timeRange && array_key_exists('start', $timeRange) && $timeRange['start']) { $query .= ' AND lastoccurence > :startdate'; $values['startdate'] = $timeRange['start']->getTimeStamp(); } - if ($timeRange && $timeRange['end']) { + if ($timeRange && array_key_exists('end', $timeRange) && $timeRange['end']) { $query .= ' AND firstoccurence < :enddate'; $values['enddate'] = $timeRange['end']->getTimeStamp(); } @@ -1153,10 +1157,9 @@ SQL; * * Read the PropPatch documentation for more info and examples. * - * @param mixed $subscriptionId - * @param \Sabre\DAV\PropPatch $propPatch + * @param mixed $subscriptionId */ - public function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) + public function updateSubscription($subscriptionId, PropPatch $propPatch) { $supportedProperties = array_keys($this->subscriptionPropertyMap); $supportedProperties[] = '{http://calendarserver.org/ns/}source'; diff --git a/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php b/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php index 7ce1c05b7..ee525da7a 100644 --- a/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php +++ b/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php @@ -67,9 +67,17 @@ class CalendarQueryValidator return false; } - if ($filter['time-range']) { + if (array_key_exists('time-range', $filter) && $filter['time-range']) { foreach ($parent->{$filter['name']} as $subComponent) { - if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) { + $start = null; + $end = null; + if (array_key_exists('start', $filter['time-range'])) { + $start = $filter['time-range']['start']; + } + if (array_key_exists('end', $filter['time-range'])) { + $end = $filter['time-range']['end']; + } + if ($this->validateTimeRange($subComponent, $start, $end)) { continue 2; } } @@ -128,9 +136,17 @@ class CalendarQueryValidator return false; } - if ($filter['time-range']) { + if (array_key_exists('time-range', $filter) && $filter['time-range']) { foreach ($parent->{$filter['name']} as $subComponent) { - if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) { + $start = null; + $end = null; + if (array_key_exists('start', $filter['time-range'])) { + $start = $filter['time-range']['start']; + } + if (array_key_exists('end', $filter['time-range'])) { + $end = $filter['time-range']['end']; + } + if ($this->validateTimeRange($subComponent, $start, $end)) { continue 2; } } @@ -258,11 +274,9 @@ class CalendarQueryValidator case 'VEVENT': case 'VTODO': case 'VJOURNAL': - return $component->isInTimeRange($start, $end); case 'VALARM': - // If the valarm is wrapped in a recurring event, we need to // expand the recursions, and validate each. // diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php b/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php index a1f8202ec..38a7ca96f 100644 --- a/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php +++ b/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php @@ -486,6 +486,7 @@ class Plugin extends ServerPlugin $currentObject = null; $objectNode = null; + $oldICalendarData = null; $isNewNode = false; $result = $home->getCalendarObjectByUID($uid); diff --git a/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php b/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php index 090cc34bf..f7dca9be6 100644 --- a/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php +++ b/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php @@ -213,7 +213,6 @@ class SharingPlugin extends DAV\ServerPlugin // Both the DAV:share-resource and CALENDARSERVER:share requests // behave identically. case '{'.Plugin::NS_CALENDARSERVER.'}share': - $sharingPlugin = $this->server->getPlugin('sharing'); $sharingPlugin->shareResource($path, $message->sharees); @@ -228,7 +227,6 @@ class SharingPlugin extends DAV\ServerPlugin // The invite-reply document is sent when the user replies to an // invitation of a calendar share. case '{'.Plugin::NS_CALENDARSERVER.'}invite-reply': - // This only works on the calendar-home-root node. if (!$node instanceof CalendarHome) { return; @@ -272,7 +270,6 @@ class SharingPlugin extends DAV\ServerPlugin return false; case '{'.Plugin::NS_CALENDARSERVER.'}publish-calendar': - // We can only deal with IShareableCalendar objects if (!$node instanceof ISharedCalendar) { return; @@ -300,7 +297,6 @@ class SharingPlugin extends DAV\ServerPlugin return false; case '{'.Plugin::NS_CALENDARSERVER.'}unpublish-calendar': - // We can only deal with IShareableCalendar objects if (!$node instanceof ISharedCalendar) { return; diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php index baa4250ab..c9656d8a3 100644 --- a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php @@ -60,7 +60,6 @@ class CalendarData implements XmlDeserializable foreach ($elems as $elem) { switch ($elem['name']) { case '{'.Plugin::NS_CALDAV.'}expand': - $result['expand'] = [ 'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null, diff --git a/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php b/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php index a33de48de..966d7ba09 100644 --- a/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php +++ b/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php @@ -6,6 +6,7 @@ namespace Sabre\CardDAV\Backend; use Sabre\CardDAV; use Sabre\DAV; +use Sabre\DAV\PropPatch; /** * PDO CardDAV backend. @@ -93,7 +94,7 @@ class PDO extends AbstractBackend implements SyncSupport * * @param string $addressBookId */ - public function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) + public function updateAddressBook($addressBookId, PropPatch $propPatch) { $supportedProperties = [ '{DAV:}displayname', diff --git a/vendor/sabre/dav/lib/CardDAV/Plugin.php b/vendor/sabre/dav/lib/CardDAV/Plugin.php index 09d1f593d..c2d31d9df 100644 --- a/vendor/sabre/dav/lib/CardDAV/Plugin.php +++ b/vendor/sabre/dav/lib/CardDAV/Plugin.php @@ -587,14 +587,21 @@ class Plugin extends DAV\ServerPlugin foreach ($vProperties as $vProperty) { // If we got all the way here, we'll need to validate the // text-match filter. - $success = DAV\StringUtil::textMatch($vProperty[$filter['name']]->getValue(), $filter['text-match']['value'], $filter['text-match']['collation'], $filter['text-match']['match-type']); + if (isset($vProperty[$filter['name']])) { + $success = DAV\StringUtil::textMatch( + $vProperty[$filter['name']]->getValue(), + $filter['text-match']['value'], + $filter['text-match']['collation'], + $filter['text-match']['match-type'] + ); + if ($filter['text-match']['negate-condition']) { + $success = !$success; + } + } if ($success) { break; } } - if ($filter['text-match']['negate-condition']) { - $success = !$success; - } } // else // There are two conditions where we can already determine whether @@ -628,15 +635,15 @@ class Plugin extends DAV\ServerPlugin $success = false; foreach ($texts as $haystack) { $success = DAV\StringUtil::textMatch($haystack, $filter['value'], $filter['collation'], $filter['match-type']); + if ($filter['negate-condition']) { + $success = !$success; + } // Breaking on the first match if ($success) { break; } } - if ($filter['negate-condition']) { - $success = !$success; - } if ($success && 'anyof' === $test) { return true; diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php b/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php index d3651ae61..e1096fe28 100644 --- a/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php +++ b/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php @@ -146,7 +146,6 @@ class AddressBookQueryReport implements XmlDeserializable } break; case '{'.Plugin::NS_CARDDAV.'}filter': - if (!is_null($newProps['filters'])) { throw new BadRequest('You can only include 1 {'.Plugin::NS_CARDDAV.'}filter element'); } diff --git a/vendor/sabre/dav/lib/DAV/Browser/Plugin.php b/vendor/sabre/dav/lib/DAV/Browser/Plugin.php index 915f2895b..2f155d9ea 100644 --- a/vendor/sabre/dav/lib/DAV/Browser/Plugin.php +++ b/vendor/sabre/dav/lib/DAV/Browser/Plugin.php @@ -157,6 +157,9 @@ class Plugin extends DAV\ServerPlugin public function httpPOST(RequestInterface $request, ResponseInterface $response) { $contentType = $request->getHeader('Content-Type'); + if (!\is_string($contentType)) { + return; + } list($contentType) = explode(';', $contentType); if ('application/x-www-form-urlencoded' !== $contentType && 'multipart/form-data' !== $contentType) { @@ -209,7 +212,6 @@ class Plugin extends DAV\ServerPlugin // @codeCoverageIgnoreStart case 'put': - if ($_FILES) { $file = current($_FILES); } else { diff --git a/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php b/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php index d1ac349bd..dbf42ed9f 100644 --- a/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php +++ b/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Sabre\DAV\Exception; use Sabre\DAV; +use Sabre\DAV\Server; /** * MethodNotAllowed. @@ -34,7 +35,7 @@ class MethodNotAllowed extends DAV\Exception * * @return array */ - public function getHTTPHeaders(\Sabre\DAV\Server $server) + public function getHTTPHeaders(Server $server) { $methods = $server->getAllowedMethods($server->getRequestUri()); diff --git a/vendor/sabre/dav/lib/DAV/FSExt/File.php b/vendor/sabre/dav/lib/DAV/FSExt/File.php index 060ef5a48..74849b564 100644 --- a/vendor/sabre/dav/lib/DAV/FSExt/File.php +++ b/vendor/sabre/dav/lib/DAV/FSExt/File.php @@ -41,7 +41,7 @@ class File extends Node implements DAV\PartialUpdate\IPatchSupport * * The second argument is the type of update we're doing. * This is either: - * * 1. append + * * 1. append (default) * * 2. update based on a start byte * * 3. update based on an end byte *; @@ -75,6 +75,9 @@ class File extends Node implements DAV\PartialUpdate\IPatchSupport $f = fopen($this->path, 'c'); fseek($f, $offset, SEEK_END); break; + default: + $f = fopen($this->path, 'a'); + break; } if (is_string($data)) { fwrite($f, $data); diff --git a/vendor/sabre/dav/lib/DAV/Server.php b/vendor/sabre/dav/lib/DAV/Server.php index 4c213c1bd..de663d0c1 100644 --- a/vendor/sabre/dav/lib/DAV/Server.php +++ b/vendor/sabre/dav/lib/DAV/Server.php @@ -25,8 +25,8 @@ use Sabre\Xml\Writer; */ class Server implements LoggerAwareInterface, EmitterInterface { - use WildcardEmitterTrait; use LoggerAwareTrait; + use WildcardEmitterTrait; /** * Infinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree. diff --git a/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php b/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php index 3a41e67b4..e7adbeee6 100644 --- a/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php +++ b/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php @@ -179,7 +179,6 @@ class Plugin extends ServerPlugin switch ($documentType) { case '{DAV:}share-resource': - $this->shareResource($path, $message->sharees); $response->setStatus(200); // Adding this because sending a response body may cause issues, diff --git a/vendor/sabre/dav/lib/DAV/Tree.php b/vendor/sabre/dav/lib/DAV/Tree.php index aedc0155d..2417979a6 100644 --- a/vendor/sabre/dav/lib/DAV/Tree.php +++ b/vendor/sabre/dav/lib/DAV/Tree.php @@ -292,6 +292,8 @@ class Tree $destinationName = $source->getName(); } + $destination = null; + if ($source instanceof IFile) { $data = $source->get(); diff --git a/vendor/sabre/dav/lib/DAV/Version.php b/vendor/sabre/dav/lib/DAV/Version.php index 70948305e..b25d6c07a 100644 --- a/vendor/sabre/dav/lib/DAV/Version.php +++ b/vendor/sabre/dav/lib/DAV/Version.php @@ -16,5 +16,5 @@ class Version /** * Full version number. */ - public const VERSION = '4.1.3'; + public const VERSION = '4.1.5'; } diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php b/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php index c6f6d421c..efc15c293 100644 --- a/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php +++ b/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php @@ -98,7 +98,6 @@ class GetLastModified implements Element */ public static function xmlDeserialize(Reader $reader) { - return - new self(new DateTime($reader->parseInnerTree())); + return new self(new DateTime($reader->parseInnerTree())); } } diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php b/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php index 0ed14dcf3..f88ce814a 100644 --- a/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php +++ b/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php @@ -39,9 +39,6 @@ class Href implements Element, HtmlOutput * * You must either pass a string for a single href, or an array of hrefs. * - * If auto-prefix is set to false, the hrefs will be treated as absolute - * and not relative to the servers base uri. - * * @param string|string[] $hrefs */ public function __construct($hrefs) diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php b/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php index 6532b70c9..75ddcba3f 100644 --- a/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php +++ b/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php @@ -94,8 +94,7 @@ class ResourceType extends Element\Elements implements HtmlOutput */ public static function xmlDeserialize(Reader $reader) { - return - new self(parent::xmlDeserialize($reader)); + return new self(parent::xmlDeserialize($reader)); } /** diff --git a/vendor/sabre/dav/phpstan.neon b/vendor/sabre/dav/phpstan.neon deleted file mode 100644 index 5335bc651..000000000 --- a/vendor/sabre/dav/phpstan.neon +++ /dev/null @@ -1,2 +0,0 @@ -parameters: - level: 0 diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php deleted file mode 100644 index 9460b8922..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php +++ /dev/null @@ -1,1397 +0,0 @@ -dropTables([ - 'calendarobjects', - 'calendars', - 'calendarinstances', - 'calendarchanges', - 'calendarsubscriptions', - 'schedulingobjects', - ]); - $this->createSchema('calendars'); - - $this->pdo = $this->getDb(); - } - - public function testConstruct() - { - $backend = new PDO($this->pdo); - $this->assertTrue($backend instanceof PDO); - } - - /** - * @depends testConstruct - */ - public function testGetCalendarsForUserNoCalendars() - { - $backend = new PDO($this->pdo); - $calendars = $backend->getCalendarsForUser('principals/user2'); - $this->assertEquals([], $calendars); - } - - /** - * @depends testConstruct - */ - public function testCreateCalendarAndFetch() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [ - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']), - '{DAV:}displayname' => 'Hello!', - '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'), - ]); - $calendars = $backend->getCalendarsForUser('principals/user2'); - - $elementCheck = [ - 'uri' => 'somerandomid', - '{DAV:}displayname' => 'Hello!', - '{urn:ietf:params:xml:ns:caldav}calendar-description' => '', - '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'), - 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER, - ]; - - $this->assertIsArray($calendars); - $this->assertEquals(1, count($calendars)); - - foreach ($elementCheck as $name => $value) { - $this->assertArrayHasKey($name, $calendars[0]); - $this->assertEquals($value, $calendars[0][$name]); - } - } - - /** - * @depends testConstruct - */ - public function testUpdateCalendarAndFetch() - { - $backend = new PDO($this->pdo); - - //Creating a new calendar - $newId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $propPatch = new PropPatch([ - '{DAV:}displayname' => 'myCalendar', - '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'), - ]); - - // Updating the calendar - $backend->updateCalendar($newId, $propPatch); - $result = $propPatch->commit(); - - // Verifying the result of the update - $this->assertTrue($result); - - // Fetching all calendars from this user - $calendars = $backend->getCalendarsForUser('principals/user2'); - - // Checking if all the information is still correct - $elementCheck = [ - 'id' => $newId, - 'uri' => 'somerandomid', - '{DAV:}displayname' => 'myCalendar', - '{urn:ietf:params:xml:ns:caldav}calendar-description' => '', - '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => '', - '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/2', - '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'), - ]; - - $this->assertIsArray($calendars); - $this->assertEquals(1, count($calendars)); - - foreach ($elementCheck as $name => $value) { - $this->assertArrayHasKey($name, $calendars[0]); - $this->assertEquals($value, $calendars[0][$name]); - } - } - - /** - * @depends testConstruct - */ - public function testUpdateCalendarBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - - //Creating a new calendar - $newId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $propPatch = new PropPatch([ - '{DAV:}displayname' => 'myCalendar', - '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'), - ]); - - // Updating the calendar - $backend->updateCalendar('raaaa', $propPatch); - } - - /** - * @depends testUpdateCalendarAndFetch - */ - public function testUpdateCalendarUnknownProperty() - { - $backend = new PDO($this->pdo); - - //Creating a new calendar - $newId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $propPatch = new PropPatch([ - '{DAV:}displayname' => 'myCalendar', - '{DAV:}yourmom' => 'wittycomment', - ]); - - // Updating the calendar - $backend->updateCalendar($newId, $propPatch); - $propPatch->commit(); - - // Verifying the result of the update - $this->assertEquals([ - '{DAV:}yourmom' => 403, - '{DAV:}displayname' => 424, - ], $propPatch->getResult()); - } - - /** - * @depends testCreateCalendarAndFetch - */ - public function testDeleteCalendar() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [ - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']), - '{DAV:}displayname' => 'Hello!', - ]); - - $backend->deleteCalendar($returnedId); - - $calendars = $backend->getCalendarsForUser('principals/user2'); - $this->assertEquals([], $calendars); - } - - /** - * @depends testCreateCalendarAndFetch - */ - public function testDeleteCalendarBadID() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [ - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']), - '{DAV:}displayname' => 'Hello!', - ]); - - $backend->deleteCalendar('bad-id'); - } - - /** - * @depends testCreateCalendarAndFetch - */ - public function testCreateCalendarIncorrectComponentSet() - { - $this->expectException('Sabre\DAV\Exception'); - $backend = new PDO($this->pdo); - - //Creating a new calendar - $newId = $backend->createCalendar('principals/user2', 'somerandomid', [ - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => 'blabla', - ]); - } - - public function testCreateCalendarObject() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\''); - - $row = $result->fetch(\PDO::FETCH_ASSOC); - if (is_resource($row['calendardata'])) { - $row['calendardata'] = stream_get_contents($row['calendardata']); - } - - $this->assertEquals([ - 'etag' => md5($object), - 'size' => strlen($object), - 'calendardata' => $object, - 'firstoccurence' => strtotime('20120101'), - 'lastoccurence' => strtotime('20120101') + (3600 * 24), - 'componenttype' => 'VEVENT', - ], $row); - } - - public function testGetMultipleObjects() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'id-1', $object); - $backend->createCalendarObject($returnedId, 'id-2', $object); - - $check = [ - [ - 'id' => 1, - 'etag' => '"'.md5($object).'"', - 'uri' => 'id-1', - 'size' => strlen($object), - 'calendardata' => $object, - 'lastmodified' => null, - ], - [ - 'id' => 2, - 'etag' => '"'.md5($object).'"', - 'uri' => 'id-2', - 'size' => strlen($object), - 'calendardata' => $object, - 'lastmodified' => null, - ], - ]; - - $result = $backend->getMultipleCalendarObjects($returnedId, ['id-1', 'id-2']); - - foreach ($check as $index => $props) { - foreach ($props as $key => $expected) { - $actual = $result[$index][$key]; - - switch ($key) { - case 'lastmodified': - $this->assertIsInt($actual); - break; - case 'calendardata': - if (is_resource($actual)) { - $actual = stream_get_contents($actual); - } - // no break intentional - default: - $this->assertEquals($expected, $actual); - } - } - } - } - - /** - * @depends testGetMultipleObjects - */ - public function testGetMultipleObjectsBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $backend->getMultipleCalendarObjects('bad-id', ['foo-bar']); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectNoComponent() - { - $this->expectException('Sabre\DAV\Exception\BadRequest'); - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectDuration() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nDURATION:P2D\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\''); - - $row = $result->fetch(\PDO::FETCH_ASSOC); - if (is_resource($row['calendardata'])) { - $row['calendardata'] = stream_get_contents($row['calendardata']); - } - - $this->assertEquals([ - 'etag' => md5($object), - 'size' => strlen($object), - 'calendardata' => $object, - 'firstoccurence' => strtotime('20120101'), - 'lastoccurence' => strtotime('20120101') + (3600 * 48), - 'componenttype' => 'VEVENT', - ], $row); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nDURATION:P2D\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject('bad-id', 'random-id', $object); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectNoDTEND() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\''); - $row = $result->fetch(\PDO::FETCH_ASSOC); - if (is_resource($row['calendardata'])) { - $row['calendardata'] = stream_get_contents($row['calendardata']); - } - - $this->assertEquals([ - 'etag' => md5($object), - 'size' => strlen($object), - 'calendardata' => $object, - 'firstoccurence' => strtotime('2012-01-01 10:00:00'), - 'lastoccurence' => strtotime('2012-01-01 10:00:00'), - 'componenttype' => 'VEVENT', - ], $row); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectWithDTEND() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nDTEND:20120101T110000Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\''); - $row = $result->fetch(\PDO::FETCH_ASSOC); - if (is_resource($row['calendardata'])) { - $row['calendardata'] = stream_get_contents($row['calendardata']); - } - - $this->assertEquals([ - 'etag' => md5($object), - 'size' => strlen($object), - 'calendardata' => $object, - 'firstoccurence' => strtotime('2012-01-01 10:00:00'), - 'lastoccurence' => strtotime('2012-01-01 11:00:00'), - 'componenttype' => 'VEVENT', - ], $row); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectInfiniteRecurrence() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nRRULE:FREQ=DAILY\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\''); - $row = $result->fetch(\PDO::FETCH_ASSOC); - if (is_resource($row['calendardata'])) { - $row['calendardata'] = stream_get_contents($row['calendardata']); - } - - $this->assertEquals([ - 'etag' => md5($object), - 'size' => strlen($object), - 'calendardata' => $object, - 'firstoccurence' => strtotime('2012-01-01 10:00:00'), - 'lastoccurence' => strtotime(PDO::MAX_DATE), - 'componenttype' => 'VEVENT', - ], $row); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectEndingRecurrence() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE-TIME:20120101T100000Z\r\nDTEND;VALUE=DATE-TIME:20120101T110000Z\r\nUID:foo\r\nRRULE:FREQ=DAILY;COUNT=1000\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\''); - $row = $result->fetch(\PDO::FETCH_ASSOC); - if (is_resource($row['calendardata'])) { - $row['calendardata'] = stream_get_contents($row['calendardata']); - } - - $this->assertEquals([ - 'etag' => md5($object), - 'size' => strlen($object), - 'calendardata' => $object, - 'firstoccurence' => strtotime('2012-01-01 10:00:00'), - 'lastoccurence' => strtotime('2012-01-01 11:00:00') + (3600 * 24 * 999), - 'componenttype' => 'VEVENT', - ], $row); - } - - /** - * @depends testCreateCalendarObject - */ - public function testCreateCalendarObjectTask() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nDUE;VALUE=DATE-TIME:20120101T100000Z\r\nEND:VTODO\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\''); - $row = $result->fetch(\PDO::FETCH_ASSOC); - if (is_resource($row['calendardata'])) { - $row['calendardata'] = stream_get_contents($row['calendardata']); - } - - $this->assertEquals([ - 'etag' => md5($object), - 'size' => strlen($object), - 'calendardata' => $object, - 'firstoccurence' => null, - 'lastoccurence' => null, - 'componenttype' => 'VTODO', - ], $row); - } - - /** - * @depends testCreateCalendarObject - */ - public function testGetCalendarObjects() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $data = $backend->getCalendarObjects($returnedId); - - $this->assertEquals(1, count($data)); - $data = $data[0]; - - $this->assertEquals('random-id', $data['uri']); - $this->assertEquals(strlen($object), $data['size']); - } - - /** - * @depends testGetCalendarObjects - */ - public function testGetCalendarObjectsBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $backend->getCalendarObjects('bad-id'); - } - - /** - * @depends testGetCalendarObjects - */ - public function testGetCalendarObjectBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $backend->getCalendarObject('bad-id', 'foo-bar'); - } - - /** - * @depends testCreateCalendarObject - */ - public function testGetCalendarObjectByUID() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - $backend->createCalendarObject($returnedId, 'random-id', $object); - - $this->assertNull( - $backend->getCalendarObjectByUID('principals/user2', 'bar') - ); - $this->assertEquals( - 'somerandomid/random-id', - $backend->getCalendarObjectByUID('principals/user2', 'foo') - ); - } - - /** - * @depends testCreateCalendarObject - */ - public function testUpdateCalendarObject() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - $object2 = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20130101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - $backend->createCalendarObject($returnedId, 'random-id', $object); - $backend->updateCalendarObject($returnedId, 'random-id', $object2); - - $data = $backend->getCalendarObject($returnedId, 'random-id'); - - if (is_resource($data['calendardata'])) { - $data['calendardata'] = stream_get_contents($data['calendardata']); - } - - $this->assertEquals($object2, $data['calendardata']); - $this->assertEquals('random-id', $data['uri']); - } - - /** - * @depends testUpdateCalendarObject - */ - public function testUpdateCalendarObjectBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $backend->updateCalendarObject('bad-id', 'object-id', 'objectdata'); - } - - /** - * @depends testCreateCalendarObject - */ - public function testDeleteCalendarObject() - { - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - $backend->createCalendarObject($returnedId, 'random-id', $object); - $backend->deleteCalendarObject($returnedId, 'random-id'); - - $data = $backend->getCalendarObject($returnedId, 'random-id'); - $this->assertNull($data); - } - - /** - * @depends testDeleteCalendarObject - */ - public function testDeleteCalendarObjectBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []); - - $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"; - $backend->createCalendarObject($returnedId, 'random-id', $object); - $backend->deleteCalendarObject('bad-id', 'random-id'); - } - - public function testCalendarQueryNoResult() - { - $abstract = new PDO($this->pdo); - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VJOURNAL', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $this->assertEquals([ - ], $abstract->calendarQuery([1, 1], $filters)); - } - - /** - * @depends testCalendarQueryNoResult - */ - public function testCalendarQueryBadId() - { - $this->expectException('InvalidArgumentException'); - $abstract = new PDO($this->pdo); - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VJOURNAL', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $abstract->calendarQuery('bad-id', $filters); - } - - public function testCalendarQueryTodo() - { - $backend = new PDO($this->pdo); - $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n"); - $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VTODO', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $this->assertEquals([ - 'todo', - ], $backend->calendarQuery([1, 1], $filters)); - } - - public function testCalendarQueryTodoNotMatch() - { - $backend = new PDO($this->pdo); - $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n"); - $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VTODO', - 'comp-filters' => [], - 'prop-filters' => [ - [ - 'name' => 'summary', - 'text-match' => null, - 'time-range' => null, - 'param-filters' => [], - 'is-not-defined' => false, - ], - ], - 'is-not-defined' => false, - 'time-range' => null, - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $this->assertEquals([ - ], $backend->calendarQuery([1, 1], $filters)); - } - - public function testCalendarQueryNoFilter() - { - $backend = new PDO($this->pdo); - $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n"); - $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $result = $backend->calendarQuery([1, 1], $filters); - $this->assertTrue(in_array('todo', $result)); - $this->assertTrue(in_array('event', $result)); - } - - public function testCalendarQueryTimeRange() - { - $backend = new PDO($this->pdo); - $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n"); - $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - $backend->createCalendarObject([1, 1], 'event2', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('20120103'), - 'end' => new \DateTime('20120104'), - ], - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $this->assertEquals([ - 'event2', - ], $backend->calendarQuery([1, 1], $filters)); - } - - public function testCalendarQueryTimeRangeNoEnd() - { - $backend = new PDO($this->pdo); - $backend->createCalendarObject([1, 1], 'todo', "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n"); - $backend->createCalendarObject([1, 1], 'event', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - $backend->createCalendarObject([1, 1], 'event2', "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('20120102'), - 'end' => null, - ], - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $this->assertEquals([ - 'event2', - ], $backend->calendarQuery([1, 1], $filters)); - } - - public function testGetChanges() - { - $backend = new PDO($this->pdo); - $id = $backend->createCalendar( - 'principals/user1', - 'bla', - [] - ); - $result = $backend->getChangesForCalendar($id, null, 1); - - $this->assertEquals([ - 'syncToken' => 1, - 'modified' => [], - 'deleted' => [], - 'added' => [], - ], $result); - - $currentToken = $result['syncToken']; - - $dummyTodo = "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n"; - - $backend->createCalendarObject($id, 'todo1.ics', $dummyTodo); - $backend->createCalendarObject($id, 'todo2.ics', $dummyTodo); - $backend->createCalendarObject($id, 'todo3.ics', $dummyTodo); - $backend->updateCalendarObject($id, 'todo1.ics', $dummyTodo); - $backend->deleteCalendarObject($id, 'todo2.ics'); - - $result = $backend->getChangesForCalendar($id, $currentToken, 1); - - $this->assertEquals([ - 'syncToken' => 6, - 'modified' => ['todo1.ics'], - 'deleted' => ['todo2.ics'], - 'added' => ['todo3.ics'], - ], $result); - - $result = $backend->getChangesForCalendar($id, null, 1); - - $this->assertEquals([ - 'syncToken' => 6, - 'modified' => [], - 'deleted' => [], - 'added' => ['todo1.ics', 'todo3.ics'], - ], $result); - } - - /** - * @depends testGetChanges - */ - public function testGetChangesBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - $id = $backend->createCalendar( - 'principals/user1', - 'bla', - [] - ); - $backend->getChangesForCalendar('bad-id', null, 1); - } - - public function testCreateSubscriptions() - { - $props = [ - '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false), - '{DAV:}displayname' => 'cal', - '{http://apple.com/ns/ical/}refreshrate' => 'P1W', - '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF', - '{http://calendarserver.org/ns/}subscribed-strip-todos' => true, - //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true, - '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true, - ]; - - $backend = new PDO($this->pdo); - $backend->createSubscription('principals/user1', 'sub1', $props); - - $subs = $backend->getSubscriptionsForUser('principals/user1'); - - $expected = $props; - $expected['id'] = 1; - $expected['uri'] = 'sub1'; - $expected['principaluri'] = 'principals/user1'; - - unset($expected['{http://calendarserver.org/ns/}source']); - $expected['source'] = 'http://example.org/cal.ics'; - - $this->assertEquals(1, count($subs)); - foreach ($expected as $k => $v) { - $this->assertEquals($subs[0][$k], $expected[$k]); - } - } - - public function testCreateSubscriptionFail() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $props = [ - ]; - - $backend = new PDO($this->pdo); - $backend->createSubscription('principals/user1', 'sub1', $props); - } - - public function testUpdateSubscriptions() - { - $props = [ - '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false), - '{DAV:}displayname' => 'cal', - '{http://apple.com/ns/ical/}refreshrate' => 'P1W', - '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF', - '{http://calendarserver.org/ns/}subscribed-strip-todos' => true, - //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true, - '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true, - ]; - - $backend = new PDO($this->pdo); - $backend->createSubscription('principals/user1', 'sub1', $props); - - $newProps = [ - '{DAV:}displayname' => 'new displayname', - '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal2.ics', false), - ]; - - $propPatch = new DAV\PropPatch($newProps); - $backend->updateSubscription(1, $propPatch); - $result = $propPatch->commit(); - - $this->assertTrue($result); - - $subs = $backend->getSubscriptionsForUser('principals/user1'); - - $expected = array_merge($props, $newProps); - $expected['id'] = 1; - $expected['uri'] = 'sub1'; - $expected['principaluri'] = 'principals/user1'; - - unset($expected['{http://calendarserver.org/ns/}source']); - $expected['source'] = 'http://example.org/cal2.ics'; - - $this->assertEquals(1, count($subs)); - foreach ($expected as $k => $v) { - $this->assertEquals($subs[0][$k], $expected[$k]); - } - } - - public function testUpdateSubscriptionsFail() - { - $props = [ - '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false), - '{DAV:}displayname' => 'cal', - '{http://apple.com/ns/ical/}refreshrate' => 'P1W', - '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF', - '{http://calendarserver.org/ns/}subscribed-strip-todos' => true, - //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true, - '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true, - ]; - - $backend = new PDO($this->pdo); - $backend->createSubscription('principals/user1', 'sub1', $props); - - $propPatch = new DAV\PropPatch([ - '{DAV:}displayname' => 'new displayname', - '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal2.ics', false), - '{DAV:}unknown' => 'foo', - ]); - - $backend->updateSubscription(1, $propPatch); - $propPatch->commit(); - - $this->assertEquals([ - '{DAV:}unknown' => 403, - '{DAV:}displayname' => 424, - '{http://calendarserver.org/ns/}source' => 424, - ], $propPatch->getResult()); - } - - public function testDeleteSubscriptions() - { - $props = [ - '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal.ics', false), - '{DAV:}displayname' => 'cal', - '{http://apple.com/ns/ical/}refreshrate' => 'P1W', - '{http://apple.com/ns/ical/}calendar-color' => '#FF00FFFF', - '{http://calendarserver.org/ns/}subscribed-strip-todos' => true, - //'{http://calendarserver.org/ns/}subscribed-strip-alarms' => true, - '{http://calendarserver.org/ns/}subscribed-strip-attachments' => true, - ]; - - $backend = new PDO($this->pdo); - $backend->createSubscription('principals/user1', 'sub1', $props); - - $newProps = [ - '{DAV:}displayname' => 'new displayname', - '{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/cal2.ics', false), - ]; - - $backend->deleteSubscription(1); - - $subs = $backend->getSubscriptionsForUser('principals/user1'); - $this->assertEquals(0, count($subs)); - } - - public function testSchedulingMethods() - { - $backend = new PDO($this->pdo); - - $calData = "BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n"; - - $backend->createSchedulingObject( - 'principals/user1', - 'schedule1.ics', - $calData - ); - - $calDataResource = "BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n"; - $stream = fopen('data://text/plain,'.$calData, 'r'); - - $backend->createSchedulingObject( - 'principals/user1', - 'schedule1-resource.ics', - $stream - ); - - $expected = [ - 'calendardata' => $calData, - 'uri' => 'schedule1.ics', - 'etag' => '"'.md5($calData).'"', - 'size' => strlen($calData), - ]; - - $expectedResource = [ - 'calendardata' => $calDataResource, - 'uri' => 'schedule1-resource.ics', - 'etag' => '"'.md5($calDataResource).'"', - 'size' => strlen($calDataResource), - ]; - - $result = $backend->getSchedulingObject('principals/user1', 'schedule1.ics'); - foreach ($expected as $k => $v) { - $this->assertArrayHasKey($k, $result); - if (is_resource($result[$k])) { - $result[$k] = stream_get_contents($result[$k]); - } - $this->assertEquals($v, $result[$k]); - } - - $resultResource = $backend->getSchedulingObject('principals/user1', 'schedule1-resource.ics'); - foreach ($expected as $k => $v) { - $this->assertArrayHasKey($k, $result); - if (is_resource($result[$k])) { - $result[$k] = stream_get_contents($result[$k]); - } - $this->assertEquals($v, $result[$k]); - } - - $backend->deleteSchedulingObject('principals/user1', 'schedule1-resource.ics'); - - $results = $backend->getSchedulingObjects('principals/user1'); - - $this->assertEquals(1, count($results)); - $result = $results[0]; - foreach ($expected as $k => $v) { - if (is_resource($result[$k])) { - $result[$k] = stream_get_contents($result[$k]); - } - $this->assertEquals($v, $result[$k]); - } - - $backend->deleteSchedulingObject('principals/user1', 'schedule1.ics'); - $result = $backend->getSchedulingObject('principals/user1', 'schedule1.ics'); - - $this->assertNull($result); - } - - public function testGetInvites() - { - $backend = new PDO($this->pdo); - - // creating a new calendar - $backend->createCalendar('principals/user1', 'somerandomid', []); - $calendar = $backend->getCalendarsForUser('principals/user1')[0]; - - $result = $backend->getInvites($calendar['id']); - $expected = [ - new Sharee([ - 'href' => 'principals/user1', - 'principal' => 'principals/user1', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - ]), - ]; - - $this->assertEquals($expected, $result); - } - - /** - * @depends testGetInvites - */ - public function testGetInvitesBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - - // creating a new calendar - $backend->createCalendar('principals/user1', 'somerandomid', []); - $calendar = $backend->getCalendarsForUser('principals/user1')[0]; - - $backend->getInvites('bad-id'); - } - - /** - * @depends testCreateCalendarAndFetch - */ - public function testUpdateInvites() - { - $backend = new PDO($this->pdo); - - // creating a new calendar - $backend->createCalendar('principals/user1', 'somerandomid', []); - $calendar = $backend->getCalendarsForUser('principals/user1')[0]; - - $ownerSharee = new Sharee([ - 'href' => 'principals/user1', - 'principal' => 'principals/user1', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - ]); - - // Add a new invite - $backend->updateInvites( - $calendar['id'], - [ - new Sharee([ - 'href' => 'mailto:user@example.org', - 'principal' => 'principals/user2', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - 'properties' => ['{DAV:}displayname' => 'User 2'], - ]), - ] - ); - - $result = $backend->getInvites($calendar['id']); - $expected = [ - $ownerSharee, - new Sharee([ - 'href' => 'mailto:user@example.org', - 'principal' => 'principals/user2', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - 'properties' => [ - '{DAV:}displayname' => 'User 2', - ], - ]), - ]; - $this->assertEquals($expected, $result); - - // Checking calendar_instances too - $expectedCalendar = [ - 'id' => [1, 2], - 'principaluri' => 'principals/user2', - '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/1', - '{http://sabredav.org/ns}sync-token' => '1', - 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ, - 'read-only' => true, - 'share-resource-uri' => '/ns/share/1', - ]; - $calendars = $backend->getCalendarsForUser('principals/user2'); - - foreach ($expectedCalendar as $k => $v) { - $this->assertEquals( - $v, - $calendars[0][$k], - 'Key '.$k.' in calendars array did not have the expected value.' - ); - } - - // Updating an invite - $backend->updateInvites( - $calendar['id'], - [ - new Sharee([ - 'href' => 'mailto:user@example.org', - 'principal' => 'principals/user2', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - ]), - ] - ); - - $result = $backend->getInvites($calendar['id']); - $expected = [ - $ownerSharee, - new Sharee([ - 'href' => 'mailto:user@example.org', - 'principal' => 'principals/user2', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - 'properties' => [ - '{DAV:}displayname' => 'User 2', - ], - ]), - ]; - $this->assertEquals($expected, $result); - - // Removing an invite - $backend->updateInvites( - $calendar['id'], - [ - new Sharee([ - 'href' => 'mailto:user@example.org', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS, - ]), - ] - ); - - $result = $backend->getInvites($calendar['id']); - $expected = [ - $ownerSharee, - ]; - $this->assertEquals($expected, $result); - - // Preventing the owner share from being removed - $backend->updateInvites( - $calendar['id'], - [ - new Sharee([ - 'href' => 'principals/user2', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS, - ]), - ] - ); - - $result = $backend->getInvites($calendar['id']); - $expected = [ - new Sharee([ - 'href' => 'principals/user1', - 'principal' => 'principals/user1', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - ]), - ]; - $this->assertEquals($expected, $result); - } - - /** - * @depends testUpdateInvites - */ - public function testUpdateInvitesBadId() - { - $this->expectException('InvalidArgumentException'); - $backend = new PDO($this->pdo); - // Add a new invite - $backend->updateInvites( - 'bad-id', - [] - ); - } - - /** - * @depends testUpdateInvites - */ - public function testUpdateInvitesNoPrincipal() - { - $backend = new PDO($this->pdo); - - // creating a new calendar - $backend->createCalendar('principals/user1', 'somerandomid', []); - $calendar = $backend->getCalendarsForUser('principals/user1')[0]; - - $ownerSharee = new Sharee([ - 'href' => 'principals/user1', - 'principal' => 'principals/user1', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - ]); - - // Add a new invite - $backend->updateInvites( - $calendar['id'], - [ - new Sharee([ - 'href' => 'mailto:user@example.org', - 'principal' => null, - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - 'properties' => ['{DAV:}displayname' => 'User 2'], - ]), - ] - ); - - $result = $backend->getInvites($calendar['id']); - $expected = [ - $ownerSharee, - new Sharee([ - 'href' => 'mailto:user@example.org', - 'principal' => null, - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_INVALID, - 'properties' => [ - '{DAV:}displayname' => 'User 2', - ], - ]), - ]; - $this->assertEqualsCanonicalizing($expected, $result); - } - - /** - * @depends testUpdateInvites - */ - public function testDeleteSharedCalendar() - { - $backend = new PDO($this->pdo); - - // creating a new calendar - $backend->createCalendar('principals/user1', 'somerandomid', []); - $calendar = $backend->getCalendarsForUser('principals/user1')[0]; - - $ownerSharee = new Sharee([ - 'href' => 'principals/user1', - 'principal' => 'principals/user1', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - ]); - - // Add a new invite - $backend->updateInvites( - $calendar['id'], - [ - new Sharee([ - 'href' => 'mailto:user@example.org', - 'principal' => 'principals/user2', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - 'properties' => ['{DAV:}displayname' => 'User 2'], - ]), - ] - ); - - $expectedCalendar = [ - 'id' => [1, 2], - 'principaluri' => 'principals/user2', - '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/1', - '{http://sabredav.org/ns}sync-token' => '1', - 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ, - 'read-only' => true, - 'share-resource-uri' => '/ns/share/1', - ]; - $calendars = $backend->getCalendarsForUser('principals/user2'); - - foreach ($expectedCalendar as $k => $v) { - $this->assertEquals( - $v, - $calendars[0][$k], - 'Key '.$k.' in calendars array did not have the expected value.' - ); - } - - // Removing the shared calendar. - $backend->deleteCalendar($calendars[0]['id']); - - $this->assertEquals( - [], - $backend->getCalendarsForUser('principals/user2') - ); - - $result = $backend->getInvites($calendar['id']); - $expected = [ - new Sharee([ - 'href' => 'principals/user1', - 'principal' => 'principals/user1', - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, - ]), - ]; - $this->assertEquals($expected, $result); - } - - public function testSetPublishStatus() - { - $this->expectException('Sabre\DAV\Exception\NotImplemented'); - $backend = new PDO($this->pdo); - $backend->setPublishStatus([1, 1], true); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php deleted file mode 100644 index 166de1dab..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractTest.php +++ /dev/null @@ -1,184 +0,0 @@ - 'anything']); - - $abstract->updateCalendar('randomid', $propPatch); - $result = $propPatch->commit(); - - $this->assertFalse($result); - } - - public function testCalendarQuery() - { - $abstract = new AbstractMock(); - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $this->assertEquals([ - 'event1.ics', - ], $abstract->calendarQuery(1, $filters)); - } - - public function testGetCalendarObjectByUID() - { - $abstract = new AbstractMock(); - $this->assertNull( - $abstract->getCalendarObjectByUID('principal1', 'zim') - ); - $this->assertEquals( - 'cal1/event1.ics', - $abstract->getCalendarObjectByUID('principal1', 'foo') - ); - $this->assertNull( - $abstract->getCalendarObjectByUID('principal3', 'foo') - ); - $this->assertNull( - $abstract->getCalendarObjectByUID('principal1', 'shared') - ); - } - - public function testGetMultipleCalendarObjects() - { - $abstract = new AbstractMock(); - $result = $abstract->getMultipleCalendarObjects(1, [ - 'event1.ics', - 'task1.ics', - ]); - - $expected = [ - [ - 'id' => 1, - 'calendarid' => 1, - 'uri' => 'event1.ics', - 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", - ], - [ - 'id' => 2, - 'calendarid' => 1, - 'uri' => 'task1.ics', - 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n", - ], - ]; - - $this->assertEquals($expected, $result); - } -} - -class AbstractMock extends AbstractBackend -{ - public function getCalendarsForUser($principalUri) - { - return [ - [ - 'id' => 1, - 'principaluri' => 'principal1', - 'uri' => 'cal1', - ], - [ - 'id' => 2, - 'principaluri' => 'principal1', - '{http://sabredav.org/ns}owner-principal' => 'principal2', - 'uri' => 'cal1', - ], - ]; - } - - public function createCalendar($principalUri, $calendarUri, array $properties) - { - } - - public function deleteCalendar($calendarId) - { - } - - public function getCalendarObjects($calendarId) - { - switch ($calendarId) { - case 1: - return [ - [ - 'id' => 1, - 'calendarid' => 1, - 'uri' => 'event1.ics', - ], - [ - 'id' => 2, - 'calendarid' => 1, - 'uri' => 'task1.ics', - ], - ]; - case 2: - return [ - [ - 'id' => 3, - 'calendarid' => 2, - 'uri' => 'shared-event.ics', - ], - ]; - } - } - - public function getCalendarObject($calendarId, $objectUri) - { - switch ($objectUri) { - case 'event1.ics': - return [ - 'id' => 1, - 'calendarid' => 1, - 'uri' => 'event1.ics', - 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", - ]; - case 'task1.ics': - return [ - 'id' => 2, - 'calendarid' => 1, - 'uri' => 'task1.ics', - 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n", - ]; - case 'shared-event.ics': - return [ - 'id' => 3, - 'calendarid' => 2, - 'uri' => 'event1.ics', - 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:shared\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", - ]; - } - } - - public function createCalendarObject($calendarId, $objectUri, $calendarData) - { - } - - public function updateCalendarObject($calendarId, $objectUri, $calendarData) - { - } - - public function deleteCalendarObject($calendarId, $objectUri) - { - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php deleted file mode 100644 index 01ac1b39e..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php +++ /dev/null @@ -1,247 +0,0 @@ -calendars = $calendars; - $this->calendarData = $calendarData; - } - - /** - * Returns a list of calendars for a principal. - * - * Every project is an array with the following keys: - * * id, a unique id that will be used by other functions to modify the - * calendar. This can be the same as the uri or a database key. - * * uri, which the basename of the uri with which the calendar is - * accessed. - * * principalUri. The owner of the calendar. Almost always the same as - * principalUri passed to this method. - * - * Furthermore it can contain webdav properties in clark notation. A very - * common one is '{DAV:}displayname'. - * - * @param string $principalUri - * - * @return array - */ - public function getCalendarsForUser($principalUri) - { - $r = []; - foreach ($this->calendars as $row) { - if ($row['principaluri'] == $principalUri) { - $r[] = $row; - } - } - - return $r; - } - - /** - * Creates a new calendar for a principal. - * - * If the creation was a success, an id must be returned that can be used to reference - * this calendar in other methods, such as updateCalendar. - * - * This function must return a server-wide unique id that can be used - * later to reference the calendar. - * - * @param string $principalUri - * @param string $calendarUri - * - * @return string|int - */ - public function createCalendar($principalUri, $calendarUri, array $properties) - { - $id = DAV\UUIDUtil::getUUID(); - $this->calendars[] = array_merge([ - 'id' => $id, - 'principaluri' => $principalUri, - 'uri' => $calendarUri, - '{'.CalDAV\Plugin::NS_CALDAV.'}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO']), - ], $properties); - - return $id; - } - - /** - * Updates properties for a calendar. - * - * The list of mutations is stored in a Sabre\DAV\PropPatch object. - * To do the actual updates, you must tell this object which properties - * you're going to process with the handle() method. - * - * Calling the handle method is like telling the PropPatch object "I - * promise I can handle updating this property". - * - * Read the PropPatch documentation for more info and examples. - * - * @param mixed $calendarId - */ - public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) - { - $propPatch->handleRemaining(function ($props) use ($calendarId) { - foreach ($this->calendars as $k => $calendar) { - if ($calendar['id'] === $calendarId) { - foreach ($props as $propName => $propValue) { - if (is_null($propValue)) { - unset($this->calendars[$k][$propName]); - } else { - $this->calendars[$k][$propName] = $propValue; - } - } - - return true; - } - } - }); - } - - /** - * Delete a calendar and all it's objects. - * - * @param string $calendarId - */ - public function deleteCalendar($calendarId) - { - foreach ($this->calendars as $k => $calendar) { - if ($calendar['id'] === $calendarId) { - unset($this->calendars[$k]); - } - } - } - - /** - * Returns all calendar objects within a calendar object. - * - * Every item contains an array with the following keys: - * * id - unique identifier which will be used for subsequent updates - * * calendardata - The iCalendar-compatible calendar data - * * uri - a unique key which will be used to construct the uri. This can be any arbitrary string. - * * lastmodified - a timestamp of the last modification time - * * etag - An arbitrary string, surrounded by double-quotes. (e.g.: - * ' "abcdef"') - * * calendarid - The calendarid as it was passed to this function. - * - * Note that the etag is optional, but it's highly encouraged to return for - * speed reasons. - * - * The calendardata is also optional. If it's not returned - * 'getCalendarObject' will be called later, which *is* expected to return - * calendardata. - * - * @param string $calendarId - * - * @return array - */ - public function getCalendarObjects($calendarId) - { - if (!isset($this->calendarData[$calendarId])) { - return []; - } - - $objects = $this->calendarData[$calendarId]; - - foreach ($objects as $uri => &$object) { - $object['calendarid'] = $calendarId; - $object['uri'] = $uri; - $object['lastmodified'] = null; - } - - return $objects; - } - - /** - * Returns information from a single calendar object, based on it's object - * uri. - * - * The object uri is only the basename, or filename and not a full path. - * - * The returned array must have the same keys as getCalendarObjects. The - * 'calendardata' object is required here though, while it's not required - * for getCalendarObjects. - * - * This method must return null if the object did not exist. - * - * @param mixed $calendarId - * @param string $objectUri - * - * @return array|null - */ - public function getCalendarObject($calendarId, $objectUri) - { - if (!isset($this->calendarData[$calendarId][$objectUri])) { - return null; - } - $object = $this->calendarData[$calendarId][$objectUri]; - $object['calendarid'] = $calendarId; - $object['uri'] = $objectUri; - $object['lastmodified'] = null; - - return $object; - } - - /** - * Creates a new calendar object. - * - * @param string $calendarId - * @param string $objectUri - * @param string $calendarData - */ - public function createCalendarObject($calendarId, $objectUri, $calendarData) - { - $this->calendarData[$calendarId][$objectUri] = [ - 'calendardata' => $calendarData, - 'calendarid' => $calendarId, - 'uri' => $objectUri, - ]; - - return '"'.md5($calendarData).'"'; - } - - /** - * Updates an existing calendarobject, based on it's uri. - * - * @param string $calendarId - * @param string $objectUri - * @param string $calendarData - */ - public function updateCalendarObject($calendarId, $objectUri, $calendarData) - { - $this->calendarData[$calendarId][$objectUri] = [ - 'calendardata' => $calendarData, - 'calendarid' => $calendarId, - 'uri' => $objectUri, - ]; - - return '"'.md5($calendarData).'"'; - } - - /** - * Deletes an existing calendar object. - * - * @param string $calendarId - * @param string $objectUri - */ - public function deleteCalendarObject($calendarId, $objectUri) - { - unset($this->calendarData[$calendarId][$objectUri]); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php deleted file mode 100644 index 66388def4..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php +++ /dev/null @@ -1,10 +0,0 @@ -backend = TestUtil::getBackend(); - - $calendars = $this->backend->getCalendarsForUser('principals/user1'); - $this->assertEquals(2, count($calendars)); - $this->calendar = new Calendar($this->backend, $calendars[0]); - } - - public function teardown(): void - { - unset($this->calendar); - unset($this->backend); - } - - public function testSetup() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $this->assertIsString($children[0]->getName()); - $this->assertIsString($children[0]->get()); - $this->assertIsString($children[0]->getETag()); - $this->assertEquals('text/calendar; charset=utf-8', $children[0]->getContentType()); - } - - public function testInvalidArg1() - { - $this->expectException('InvalidArgumentException'); - $obj = new CalendarObject( - new Backend\Mock([], []), - [], - [] - ); - } - - public function testInvalidArg2() - { - $this->expectException('InvalidArgumentException'); - $obj = new CalendarObject( - new Backend\Mock([], []), - [], - ['calendarid' => '1'] - ); - } - - /** - * @depends testSetup - */ - public function testPut() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - $newData = TestUtil::getTestCalendarData(); - - $children[0]->put($newData); - $this->assertEquals($newData, $children[0]->get()); - } - - /** - * @depends testSetup - */ - public function testPutStream() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - $newData = TestUtil::getTestCalendarData(); - - $stream = fopen('php://temp', 'r+'); - fwrite($stream, $newData); - rewind($stream); - $children[0]->put($stream); - $this->assertEquals($newData, $children[0]->get()); - } - - /** - * @depends testSetup - */ - public function testDelete() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - $obj->delete(); - - $children2 = $this->calendar->getChildren(); - $this->assertEquals(count($children) - 1, count($children2)); - } - - /** - * @depends testSetup - */ - public function testGetLastModified() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - - $lastMod = $obj->getLastModified(); - $this->assertTrue(is_int($lastMod) || ctype_digit($lastMod) || is_null($lastMod)); - } - - /** - * @depends testSetup - */ - public function testGetSize() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - - $size = $obj->getSize(); - $this->assertIsInt($size); - } - - public function testGetOwner() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - $this->assertEquals('principals/user1', $obj->getOwner()); - } - - public function testGetGroup() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - $this->assertNull($obj->getGroup()); - } - - public function testGetACL() - { - $expected = [ - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1/calendar-proxy-read', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/user1', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/user1/calendar-proxy-write', - 'protected' => true, - ], - ]; - - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - $this->assertEquals($expected, $obj->getACL()); - } - - public function testDefaultACL() - { - $backend = new Backend\Mock([], []); - $calendarObject = new CalendarObject($backend, ['principaluri' => 'principals/user1'], ['calendarid' => 1, 'uri' => 'foo']); - $expected = [ - [ - 'privilege' => '{DAV:}all', - 'principal' => 'principals/user1', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}all', - 'principal' => 'principals/user1/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1/calendar-proxy-read', - 'protected' => true, - ], - ]; - $this->assertEquals($expected, $calendarObject->getACL()); - } - - public function testSetACL() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - $obj->setACL([]); - } - - public function testGet() - { - $children = $this->calendar->getChildren(); - $this->assertTrue($children[0] instanceof CalendarObject); - - $obj = $children[0]; - - $expected = 'BEGIN:VCALENDAR -VERSION:2.0 -PRODID:-//Apple Inc.//iCal 4.0.1//EN -CALSCALE:GREGORIAN -BEGIN:VTIMEZONE -TZID:Asia/Seoul -BEGIN:DAYLIGHT -TZOFFSETFROM:+0900 -RRULE:FREQ=YEARLY;UNTIL=19880507T150000Z;BYMONTH=5;BYDAY=2SU -DTSTART:19870510T000000 -TZNAME:GMT+09:00 -TZOFFSETTO:+1000 -END:DAYLIGHT -BEGIN:STANDARD -TZOFFSETFROM:+1000 -DTSTART:19881009T000000 -TZNAME:GMT+09:00 -TZOFFSETTO:+0900 -END:STANDARD -END:VTIMEZONE -BEGIN:VEVENT -CREATED:20100225T154229Z -UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627 -TRANSP:TRANSPARENT -SUMMARY:Something here -DTSTAMP:20100228T130202Z -DTSTART;TZID=Asia/Seoul:20100223T060000 -DTEND;TZID=Asia/Seoul:20100223T070000 -ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com -SEQUENCE:2 -END:VEVENT -END:VCALENDAR'; - - $this->assertEquals($expected, $obj->get()); - } - - public function testGetRefetch() - { - $backend = new Backend\Mock([], [ - 1 => [ - 'foo' => [ - 'calendardata' => 'foo', - 'uri' => 'foo', - ], - ], - ]); - $obj = new CalendarObject($backend, ['id' => 1], ['uri' => 'foo']); - - $this->assertEquals('foo', $obj->get()); - } - - public function testGetEtag1() - { - $objectInfo = [ - 'calendardata' => 'foo', - 'uri' => 'foo', - 'etag' => 'bar', - 'calendarid' => 1, - ]; - - $backend = new Backend\Mock([], []); - $obj = new CalendarObject($backend, [], $objectInfo); - - $this->assertEquals('bar', $obj->getETag()); - } - - public function testGetEtag2() - { - $objectInfo = [ - 'calendardata' => 'foo', - 'uri' => 'foo', - 'calendarid' => 1, - ]; - - $backend = new Backend\Mock([], []); - $obj = new CalendarObject($backend, [], $objectInfo); - - $this->assertEquals('"'.md5('foo').'"', $obj->getETag()); - } - - public function testGetSupportedPrivilegesSet() - { - $objectInfo = [ - 'calendardata' => 'foo', - 'uri' => 'foo', - 'calendarid' => 1, - ]; - - $backend = new Backend\Mock([], []); - $obj = new CalendarObject($backend, [], $objectInfo); - $this->assertNull($obj->getSupportedPrivilegeSet()); - } - - public function testGetSize1() - { - $objectInfo = [ - 'calendardata' => 'foo', - 'uri' => 'foo', - 'calendarid' => 1, - ]; - - $backend = new Backend\Mock([], []); - $obj = new CalendarObject($backend, [], $objectInfo); - $this->assertEquals(3, $obj->getSize()); - } - - public function testGetSize2() - { - $objectInfo = [ - 'uri' => 'foo', - 'calendarid' => 1, - 'size' => 4, - ]; - - $backend = new Backend\Mock([], []); - $obj = new CalendarObject($backend, [], $objectInfo); - $this->assertEquals(4, $obj->getSize()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php deleted file mode 100644 index 660832ba4..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php +++ /dev/null @@ -1,121 +0,0 @@ -createComponent('VEVENT'); - $vevent->RRULE = 'FREQ=MONTHLY'; - $vevent->DTSTART = '20120101T120000Z'; - $vevent->UID = 'bla'; - - $valarm = $vcalendar->createComponent('VALARM'); - $valarm->TRIGGER = '-P15D'; - $vevent->add($valarm); - - $vcalendar->add($vevent); - - $filter = [ - 'name' => 'VCALENDAR', - 'is-not-defined' => false, - 'time-range' => null, - 'prop-filters' => [], - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'is-not-defined' => false, - 'time-range' => null, - 'prop-filters' => [], - 'comp-filters' => [ - [ - 'name' => 'VALARM', - 'is-not-defined' => false, - 'prop-filters' => [], - 'comp-filters' => [], - 'time-range' => [ - 'start' => new \DateTime('2012-05-10'), - 'end' => new \DateTime('2012-05-20'), - ], - ], - ], - ], - ], - ]; - - $validator = new CalendarQueryValidator(); - $this->assertTrue($validator->validate($vcalendar, $filter)); - - $vcalendar = new VObject\Component\VCalendar(); - - // A limited recurrence rule, should return false - $vevent = $vcalendar->createComponent('VEVENT'); - $vevent->RRULE = 'FREQ=MONTHLY;COUNT=1'; - $vevent->DTSTART = '20120101T120000Z'; - $vevent->UID = 'bla'; - - $valarm = $vcalendar->createComponent('VALARM'); - $valarm->TRIGGER = '-P15D'; - $vevent->add($valarm); - - $vcalendar->add($vevent); - - $this->assertFalse($validator->validate($vcalendar, $filter)); - } - - public function testAlarmWayBefore() - { - $vcalendar = new VObject\Component\VCalendar(); - - $vevent = $vcalendar->createComponent('VEVENT'); - $vevent->DTSTART = '20120101T120000Z'; - $vevent->UID = 'bla'; - - $valarm = $vcalendar->createComponent('VALARM'); - $valarm->TRIGGER = '-P2W1D'; - $vevent->add($valarm); - - $vcalendar->add($vevent); - - $filter = [ - 'name' => 'VCALENDAR', - 'is-not-defined' => false, - 'time-range' => null, - 'prop-filters' => [], - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'is-not-defined' => false, - 'time-range' => null, - 'prop-filters' => [], - 'comp-filters' => [ - [ - 'name' => 'VALARM', - 'is-not-defined' => false, - 'prop-filters' => [], - 'comp-filters' => [], - 'time-range' => [ - 'start' => new \DateTime('2011-12-10'), - 'end' => new \DateTime('2011-12-20'), - ], - ], - ], - ], - ], - ]; - - $validator = new CalendarQueryValidator(); - $this->assertTrue($validator->validate($vcalendar, $filter)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php deleted file mode 100644 index 9dc8ce188..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php +++ /dev/null @@ -1,823 +0,0 @@ -assertFalse($validator->validate($vcal, ['name' => 'VFOO'])); - } - - /** - * @param string $icalObject - * @param array $filters - * @param int $outcome - * @dataProvider provider - */ - public function testValid($icalObject, $filters, $outcome) - { - $validator = new CalendarQueryValidator(); - - // Wrapping filter in a VCALENDAR component filter, as this is always - // there anyway. - $filters = [ - 'name' => 'VCALENDAR', - 'comp-filters' => [$filters], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $vObject = VObject\Reader::read($icalObject); - - switch ($outcome) { - case 0: - $this->assertFalse($validator->validate($vObject, $filters)); - break; - case 1: - $this->assertTrue($validator->validate($vObject, $filters)); - break; - case -1: - try { - $validator->validate($vObject, $filters); - $this->fail('This test was supposed to fail'); - } catch (\Exception $e) { - // We need to test something to be valid for phpunit strict - // mode. - $this->assertTrue(true); - } catch (\Throwable $e) { - // PHP7 - $this->assertTrue(true); - } - break; - } - } - - public function provider() - { - $blob1 = << 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - $filter2 = $filter1; - $filter2['name'] = 'VTODO'; - - $filter3 = $filter1; - $filter3['is-not-defined'] = true; - - $filter4 = $filter1; - $filter4['name'] = 'VTODO'; - $filter4['is-not-defined'] = true; - - $filter5 = $filter1; - $filter5['comp-filters'] = [ - [ - 'name' => 'VALARM', - 'is-not-defined' => false, - 'comp-filters' => [], - 'prop-filters' => [], - 'time-range' => null, - ], - ]; - $filter6 = $filter1; - $filter6['prop-filters'] = [ - [ - 'name' => 'SUMMARY', - 'is-not-defined' => false, - 'param-filters' => [], - 'time-range' => null, - 'text-match' => null, - ], - ]; - $filter7 = $filter6; - $filter7['prop-filters'][0]['name'] = 'DESCRIPTION'; - - $filter8 = $filter6; - $filter8['prop-filters'][0]['is-not-defined'] = true; - - $filter9 = $filter7; - $filter9['prop-filters'][0]['is-not-defined'] = true; - - $filter10 = $filter5; - $filter10['prop-filters'] = $filter6['prop-filters']; - - // Param filters - $filter11 = $filter1; - $filter11['prop-filters'] = [ - [ - 'name' => 'DTSTART', - 'is-not-defined' => false, - 'param-filters' => [ - [ - 'name' => 'VALUE', - 'is-not-defined' => false, - 'text-match' => null, - ], - ], - 'time-range' => null, - 'text-match' => null, - ], - ]; - - $filter12 = $filter11; - $filter12['prop-filters'][0]['param-filters'][0]['name'] = 'TZID'; - - $filter13 = $filter11; - $filter13['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true; - - $filter14 = $filter12; - $filter14['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true; - - // Param text filter - $filter15 = $filter11; - $filter15['prop-filters'][0]['param-filters'][0]['text-match'] = [ - 'collation' => 'i;ascii-casemap', - 'value' => 'dAtE', - 'negate-condition' => false, - ]; - $filter16 = $filter15; - $filter16['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet'; - - $filter17 = $filter15; - $filter17['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true; - - $filter18 = $filter15; - $filter18['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true; - $filter18['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet'; - - // prop + text - $filter19 = $filter5; - $filter19['comp-filters'][0]['prop-filters'] = [ - [ - 'name' => 'action', - 'is-not-defined' => false, - 'time-range' => null, - 'param-filters' => [], - 'text-match' => [ - 'collation' => 'i;ascii-casemap', - 'value' => 'display', - 'negate-condition' => false, - ], - ], - ]; - - // Time range - $filter20 = [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')), - ], - ]; - // Time range, no end date - $filter21 = $filter20; - $filter21['time-range']['end'] = null; - - // Time range, no start date - $filter22 = $filter20; - $filter22['time-range']['start'] = null; - - // Time range, other dates - $filter23 = $filter20; - $filter23['time-range'] = [ - 'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')), - ]; - // Time range - $filter24 = [ - 'name' => 'VTODO', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')), - ], - ]; - // Time range, other dates (1 month in the future) - $filter25 = $filter24; - $filter25['time-range'] = [ - 'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')), - ]; - $filter26 = $filter24; - $filter26['time-range'] = [ - 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')), - ]; - - // Time range for VJOURNAL - $filter27 = [ - 'name' => 'VJOURNAL', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')), - ], - ]; - $filter28 = $filter27; - $filter28['time-range'] = [ - 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')), - ]; - // Time range for VFREEBUSY - $filter29 = [ - 'name' => 'VFREEBUSY', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')), - ], - ]; - // Time range filter on property - $filter30 = [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [ - [ - 'name' => 'DTSTART', - 'is-not-defined' => false, - 'param-filters' => [], - 'time-range' => [ - 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')), - ], - 'text-match' => null, - ], - ], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - // Time range for alarm - $filter31 = [ - 'name' => 'VEVENT', - 'prop-filters' => [], - 'comp-filters' => [ - [ - 'name' => 'VALARM', - 'is-not-defined' => false, - 'comp-filters' => [], - 'prop-filters' => [], - 'time-range' => [ - 'start' => new \DateTime('2011-01-01 10:45:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 11:15:00', new \DateTimeZone('GMT')), - ], - 'text-match' => null, - ], - ], - 'is-not-defined' => false, - 'time-range' => null, - ]; - $filter32 = $filter31; - $filter32['comp-filters'][0]['time-range'] = [ - 'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')), - ]; - - $filter33 = $filter31; - $filter33['name'] = 'VTODO'; - $filter34 = $filter32; - $filter34['name'] = 'VTODO'; - $filter35 = $filter31; - $filter35['name'] = 'VJOURNAL'; - $filter36 = $filter32; - $filter36['name'] = 'VJOURNAL'; - - // Time range filter on non-datetime property - $filter37 = [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [ - [ - 'name' => 'SUMMARY', - 'is-not-defined' => false, - 'param-filters' => [], - 'time-range' => [ - 'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')), - 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')), - ], - 'text-match' => null, - ], - ], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - $filter38 = [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2012-07-01 00:00:00', new \DateTimeZone('UTC')), - 'end' => new \DateTime('2012-08-01 00:00:00', new \DateTimeZone('UTC')), - ], - ]; - $filter39 = [ - 'name' => 'VEVENT', - 'comp-filters' => [ - [ - 'name' => 'VALARM', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2012-09-01 00:00:00', new \DateTimeZone('UTC')), - 'end' => new \DateTime('2012-10-01 00:00:00', new \DateTimeZone('UTC')), - ], - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - - return [ - // Component check - - [$blob1, $filter1, 1], - [$blob1, $filter2, 0], - [$blob1, $filter3, 0], - [$blob1, $filter4, 1], - - // Subcomponent check (4) - [$blob1, $filter5, 0], - [$blob2, $filter5, 1], - - // Property checki (6) - [$blob1, $filter6, 1], - [$blob1, $filter7, 0], - [$blob1, $filter8, 0], - [$blob1, $filter9, 1], - - // Subcomponent + property (10) - [$blob2, $filter10, 1], - - // Param filter (11) - [$blob3, $filter11, 1], - [$blob3, $filter12, 0], - [$blob3, $filter13, 0], - [$blob3, $filter14, 1], - - // Param + text (15) - [$blob3, $filter15, 1], - [$blob3, $filter16, 0], - [$blob3, $filter17, 0], - [$blob3, $filter18, 1], - - // Prop + text (19) - [$blob2, $filter19, 1], - - // Incorrect object (vcard) (20) - [$blob4, $filter1, -1], - - // Time-range for event (21) - [$blob5, $filter20, 1], - [$blob6, $filter20, 1], - [$blob7, $filter20, 1], - [$blob8, $filter20, 1], - - [$blob5, $filter21, 1], - [$blob5, $filter22, 1], - - [$blob5, $filter23, 0], - [$blob6, $filter23, 0], - [$blob7, $filter23, 0], - [$blob8, $filter23, 0], - - // Time-range for todo (31) - [$blob9, $filter24, 1], - [$blob9, $filter25, 0], - [$blob9, $filter26, 1], - [$blob10, $filter24, 1], - [$blob10, $filter25, 0], - [$blob10, $filter26, 1], - - [$blob11, $filter24, 0], - [$blob11, $filter25, 0], - [$blob11, $filter26, 1], - - [$blob12, $filter24, 1], - [$blob12, $filter25, 0], - [$blob12, $filter26, 0], - - [$blob13, $filter24, 1], - [$blob13, $filter25, 0], - [$blob13, $filter26, 1], - - [$blob14, $filter24, 1], - [$blob14, $filter25, 0], - [$blob14, $filter26, 0], - - [$blob15, $filter24, 1], - [$blob15, $filter25, 1], - [$blob15, $filter26, 1], - - [$blob16, $filter24, 1], - [$blob16, $filter25, 1], - [$blob16, $filter26, 1], - - // Time-range for journals (55) - [$blob17, $filter27, 0], - [$blob17, $filter28, 0], - [$blob18, $filter27, 0], - [$blob18, $filter28, 1], - [$blob19, $filter27, 1], - [$blob19, $filter28, 1], - - // Time-range for free-busy (61) - [$blob20, $filter29, -1], - - // Time-range on property (62) - [$blob5, $filter30, 1], - [$blob3, $filter37, -1], - [$blob3, $filter30, 0], - - // Time-range on alarm in vevent (65) - [$blob21, $filter31, 1], - [$blob21, $filter32, 0], - [$blob22, $filter31, 1], - [$blob22, $filter32, 0], - [$blob23, $filter31, 1], - [$blob23, $filter32, 0], - [$blob24, $filter31, 1], - [$blob24, $filter32, 0], - [$blob25, $filter31, 1], - [$blob25, $filter32, 0], - [$blob26, $filter31, 1], - [$blob26, $filter32, 0], - - // Time-range on alarm for vtodo (77) - [$blob27, $filter33, 1], - [$blob27, $filter34, 0], - - // Time-range on alarm for vjournal (79) - [$blob28, $filter35, -1], - [$blob28, $filter36, -1], - - // Time-range on alarm with duration (81) - [$blob29, $filter31, 1], - [$blob29, $filter32, 0], - [$blob30, $filter31, 0], - [$blob30, $filter32, 0], - - // Time-range with RRULE (85) - [$blob31, $filter20, 1], - [$blob32, $filter20, 0], - - // Bug reported on mailing list, related to all-day events (87) - //array($blob33, $filter38, 1), - - // Event in timerange, but filtered alarm is in the far future (88). - [$blob34, $filter39, 0], - ]; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php deleted file mode 100644 index 18c3ec126..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php +++ /dev/null @@ -1,229 +0,0 @@ -backend = TestUtil::getBackend(); - - $this->calendars = $this->backend->getCalendarsForUser('principals/user1'); - $this->assertEquals(2, count($this->calendars)); - $this->calendar = new Calendar($this->backend, $this->calendars[0]); - } - - public function teardown(): void - { - unset($this->backend); - } - - public function testSimple() - { - $this->assertEquals($this->calendars[0]['uri'], $this->calendar->getName()); - } - - /** - * @depends testSimple - */ - public function testUpdateProperties() - { - $propPatch = new PropPatch([ - '{DAV:}displayname' => 'NewName', - ]); - - $result = $this->calendar->propPatch($propPatch); - $result = $propPatch->commit(); - - $this->assertEquals(true, $result); - - $calendars2 = $this->backend->getCalendarsForUser('principals/user1'); - $this->assertEquals('NewName', $calendars2[0]['{DAV:}displayname']); - } - - /** - * @depends testSimple - */ - public function testGetProperties() - { - $question = [ - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set', - ]; - - $result = $this->calendar->getProperties($question); - - foreach ($question as $q) { - $this->assertArrayHasKey($q, $result); - } - - $this->assertEquals(['VEVENT', 'VTODO'], $result['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue()); - } - - /** - * @depends testSimple - */ - public function testGetChildNotFound() - { - $this->expectException('Sabre\DAV\Exception\NotFound'); - $this->calendar->getChild('randomname'); - } - - /** - * @depends testSimple - */ - public function testGetChildren() - { - $children = $this->calendar->getChildren(); - $this->assertEquals(1, count($children)); - - $this->assertTrue($children[0] instanceof CalendarObject); - } - - /** - * @depends testGetChildren - */ - public function testChildExists() - { - $this->assertFalse($this->calendar->childExists('foo')); - - $children = $this->calendar->getChildren(); - $this->assertTrue($this->calendar->childExists($children[0]->getName())); - } - - public function testCreateDirectory() - { - $this->expectException('Sabre\DAV\Exception\MethodNotAllowed'); - $this->calendar->createDirectory('hello'); - } - - public function testSetName() - { - $this->expectException('Sabre\DAV\Exception\MethodNotAllowed'); - $this->calendar->setName('hello'); - } - - public function testGetLastModified() - { - $this->assertNull($this->calendar->getLastModified()); - } - - public function testCreateFile() - { - $file = fopen('php://memory', 'r+'); - fwrite($file, TestUtil::getTestCalendarData()); - rewind($file); - - $this->calendar->createFile('hello', $file); - - $file = $this->calendar->getChild('hello'); - $this->assertTrue($file instanceof CalendarObject); - } - - public function testCreateFileNoSupportedComponents() - { - $file = fopen('php://memory', 'r+'); - fwrite($file, TestUtil::getTestCalendarData()); - rewind($file); - - $calendar = new Calendar($this->backend, $this->calendars[1]); - $calendar->createFile('hello', $file); - - $file = $calendar->getChild('hello'); - $this->assertTrue($file instanceof CalendarObject); - } - - public function testDelete() - { - $this->calendar->delete(); - - $calendars = $this->backend->getCalendarsForUser('principals/user1'); - $this->assertEquals(1, count($calendars)); - } - - public function testGetOwner() - { - $this->assertEquals('principals/user1', $this->calendar->getOwner()); - } - - public function testGetGroup() - { - $this->assertNull($this->calendar->getGroup()); - } - - public function testGetACL() - { - $expected = [ - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1/calendar-proxy-read', - 'protected' => true, - ], - [ - 'privilege' => '{'.Plugin::NS_CALDAV.'}read-free-busy', - 'principal' => '{DAV:}authenticated', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/user1', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/user1/calendar-proxy-write', - 'protected' => true, - ], - ]; - $this->assertEquals($expected, $this->calendar->getACL()); - } - - public function testSetACL() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $this->calendar->setACL([]); - } - - public function testGetSyncToken() - { - $this->assertNull($this->calendar->getSyncToken()); - } - - public function testGetSyncTokenNoSyncSupport() - { - $calendar = new Calendar(new Backend\Mock([], []), []); - $this->assertNull($calendar->getSyncToken()); - } - - public function testGetChanges() - { - $this->assertNull($this->calendar->getChanges(1, 1)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php deleted file mode 100644 index 93fc56dae..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php +++ /dev/null @@ -1,114 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -UID:foobar -DTEND;TZID=Europe/Berlin:20120207T191500 -RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3 -SUMMARY:RecurringEvents 3 times -DTSTART;TZID=Europe/Berlin:20120207T181500 -END:VEVENT -BEGIN:VEVENT -CREATED:20120207T111900Z -UID:foobar -DTEND;TZID=Europe/Berlin:20120208T191500 -SUMMARY:RecurringEvents 3 times OVERWRITTEN -DTSTART;TZID=Europe/Berlin:20120208T181500 -RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500 -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testExpand() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - $bodyAsString = $response->getBodyAsString(); - // Everts super awesome xml parser. - $body = substr( - $bodyAsString, - $start = strpos($bodyAsString, 'BEGIN:VCALENDAR'), - strpos($bodyAsString, 'END:VCALENDAR') - $start + 13 - ); - $body = str_replace(' ', '', $body); - - try { - $vObject = VObject\Reader::read($body); - } catch (VObject\ParseException $e) { - $this->fail('Could not parse object. Error:'.$e->getMessage().' full object: '.$response->getBodyAsString()); - } - - // check if DTSTARTs and DTENDs are correct - foreach ($vObject->VEVENT as $vevent) { - /** @var $vevent Sabre\VObject\Component\VEvent */ - foreach ($vevent->children() as $child) { - /** @var $child Sabre\VObject\Property */ - if ('DTSTART' == $child->name) { - // DTSTART has to be one of three valid values - $this->assertContains($child->getValue(), ['20120207T171500Z', '20120208T171500Z', '20120209T171500Z'], 'DTSTART is not a valid value: '.$child->getValue()); - } elseif ('DTEND' == $child->name) { - // DTEND has to be one of three valid values - $this->assertContains($child->getValue(), ['20120207T181500Z', '20120208T181500Z', '20120209T181500Z'], 'DTEND is not a valid value: '.$child->getValue()); - } - } - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php deleted file mode 100644 index 50fb6c03c..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php +++ /dev/null @@ -1,104 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -UID:foobar -DTEND;TZID=Europe/Berlin:20120207T191500 -RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH -SUMMARY:RecurringEvents on tuesday and thursday -DTSTART;TZID=Europe/Berlin:20120207T181500 -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testExpandRecurringByDayEvent() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - $bodyAsString = $response->getBodyAsString(); - // Everts super awesome xml parser. - $body = substr( - $bodyAsString, - $start = strpos($bodyAsString, 'BEGIN:VCALENDAR'), - strpos($bodyAsString, 'END:VCALENDAR') - $start + 13 - ); - $body = str_replace(' ', '', $body); - - $vObject = VObject\Reader::read($body); - - $this->assertEquals(2, count($vObject->VEVENT)); - - // check if DTSTARTs and DTENDs are correct - foreach ($vObject->VEVENT as $vevent) { - /** @var $vevent Sabre\VObject\Component\VEvent */ - foreach ($vevent->children() as $child) { - /** @var $child Sabre\VObject\Property */ - if ('DTSTART' == $child->name) { - // DTSTART has to be one of two valid values - $this->assertContains($child->getValue(), ['20120214T171500Z', '20120216T171500Z'], 'DTSTART is not a valid value: '.$child->getValue()); - } elseif ('DTEND' == $child->name) { - // DTEND has to be one of two valid values - $this->assertContains($child->getValue(), ['20120214T181500Z', '20120216T181500Z'], 'DTEND is not a valid value: '.$child->getValue()); - } - } - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php deleted file mode 100644 index 5e5c153e0..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php +++ /dev/null @@ -1,104 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -UID:foobar -DTEND;TZID=Europe/Berlin:20120207T191500 -RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3 -SUMMARY:RecurringEvents 3 times -DTSTART;TZID=Europe/Berlin:20120207T181500 -END:VEVENT -BEGIN:VEVENT -CREATED:20120207T111900Z -UID:foobar -DTEND;TZID=Europe/Berlin:20120208T191500 -SUMMARY:RecurringEvents 3 times OVERWRITTEN -DTSTART;TZID=Europe/Berlin:20120208T181500 -RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500 -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testExpand() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - $bodyAsString = $response->getBodyAsString(); - // Everts super awesome xml parser. - $body = substr( - $bodyAsString, - $start = strpos($bodyAsString, 'BEGIN:VCALENDAR'), - strpos($bodyAsString, 'END:VCALENDAR') - $start + 13 - ); - $body = str_replace(' ', '', $body); - - $vObject = VObject\Reader::read($body); - - // We only expect 3 events - $this->assertEquals(3, count($vObject->VEVENT), 'We got 6 events instead of 3. Output: '.$body); - - // TZID should be gone - $this->assertFalse(isset($vObject->VEVENT->DTSTART['TZID'])); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php deleted file mode 100644 index 44823edab..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php +++ /dev/null @@ -1,158 +0,0 @@ - [ - 'obj1' => [ - 'calendarid' => 1, - 'uri' => 'event1.ics', - 'calendardata' => $obj1, - ], - 'obj2' => [ - 'calendarid' => 1, - 'uri' => 'event2.ics', - 'calendardata' => $obj2, - ], - 'obj3' => [ - 'calendarid' => 1, - 'uri' => 'event3.ics', - 'calendardata' => $obj3, - ], - ], - ]; - - $caldavBackend = new Backend\Mock([], $calendarData); - - $calendar = new Calendar($caldavBackend, [ - 'id' => 1, - 'uri' => 'calendar', - 'principaluri' => 'principals/user1', - '{'.Plugin::NS_CALDAV.'}calendar-timezone' => "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nEND:VTIMEZONE\r\nEND:VCALENDAR", - ]); - - $this->server = new DAV\Server([$calendar]); - - $request = new HTTP\Request('GET', '/calendar'); - $this->server->httpRequest = $request; - $this->server->httpResponse = new HTTP\ResponseMock(); - - $this->plugin = new Plugin(); - $this->server->addPlugin($this->plugin); - } - - public function testFreeBusyReport() - { - $reportXML = << - - - -XML; - - $report = $this->server->xml->parse($reportXML, null, $rootElem); - $this->plugin->report($rootElem, $report, null); - - $this->assertEquals(200, $this->server->httpResponse->status); - $this->assertEquals('text/calendar', $this->server->httpResponse->getHeader('Content-Type')); - $this->assertTrue(false !== strpos($this->server->httpResponse->body, 'BEGIN:VFREEBUSY')); - $this->assertTrue(false !== strpos($this->server->httpResponse->body, '20111005T120000Z/20111005T130000Z')); - $this->assertTrue(false !== strpos($this->server->httpResponse->body, '20111006T100000Z/20111006T110000Z')); - } - - public function testFreeBusyReportNoTimeRange() - { - $this->expectException('Sabre\DAV\Exception\BadRequest'); - $reportXML = << - - -XML; - - $report = $this->server->xml->parse($reportXML, null, $rootElem); - } - - public function testFreeBusyReportWrongNode() - { - $this->expectException('Sabre\DAV\Exception\NotImplemented'); - $request = new HTTP\Request('REPORT', '/'); - $this->server->httpRequest = $request; - - $reportXML = << - - - -XML; - - $report = $this->server->xml->parse($reportXML, null, $rootElem); - $this->plugin->report($rootElem, $report, null); - } - - public function testFreeBusyReportNoACLPlugin() - { - $this->expectException('Sabre\DAV\Exception'); - $this->server = new DAV\Server(); - $this->server->httpRequest = new HTTP\Request('REPORT', '/'); - $this->plugin = new Plugin(); - $this->server->addPlugin($this->plugin); - - $reportXML = << - - - -XML; - - $report = $this->server->xml->parse($reportXML, null, $rootElem); - $this->plugin->report($rootElem, $report, null); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php deleted file mode 100644 index e82a85dd8..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php +++ /dev/null @@ -1,82 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -CREATED:20120313T142342Z -UID:171EBEFC-C951-499D-B234-7BA7D677B45D -DTEND;TZID=Europe/Berlin:20120227T010000 -TRANSP:OPAQUE -SUMMARY:Monday 0h -DTSTART;TZID=Europe/Berlin:20120227T000000 -DTSTAMP:20120313T142416Z -SEQUENCE:4 -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testQueryTimerange() - { - $request = new HTTP\Request( - 'REPORT', - '/calendars/user1/calendar1', - [ - 'Content-Type' => 'application/xml', - 'Depth' => '1', - ] - ); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - $this->assertTrue(false !== strpos($response->getBodyAsString(), 'BEGIN:VCALENDAR')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php deleted file mode 100644 index 8771f538b..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php +++ /dev/null @@ -1,366 +0,0 @@ -icsExportPlugin = new ICSExportPlugin(); - $this->server->addPlugin( - $this->icsExportPlugin - ); - - $id = $this->caldavBackend->createCalendar( - 'principals/admin', - 'UUID-123467', - [ - '{DAV:}displayname' => 'Hello!', - '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF', - ] - ); - - $this->caldavBackend->createCalendarObject( - $id, - 'event-1', - <<caldavBackend->createCalendarObject( - $id, - 'todo-1', - <<assertEquals( - $this->icsExportPlugin, - $this->server->getPlugin('ics-export') - ); - $this->assertEquals($this->icsExportPlugin, $this->server->getPlugin('ics-export')); - $this->assertEquals('ics-export', $this->icsExportPlugin->getPluginInfo()['name']); - } - - public function testBeforeMethod() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export' - ); - - $response = $this->request($request); - - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals('text/calendar', $response->getHeader('Content-Type')); - - $obj = VObject\Reader::read($response->getBodyAsString()); - - $this->assertEquals(8, count($obj->children())); - $this->assertEquals(1, count($obj->VERSION)); - $this->assertEquals(1, count($obj->CALSCALE)); - $this->assertEquals(1, count($obj->PRODID)); - $this->assertTrue(false !== strpos((string) $obj->PRODID, DAV\Version::VERSION)); - $this->assertEquals(1, count($obj->VTIMEZONE)); - $this->assertEquals(1, count($obj->VEVENT)); - $this->assertEquals('Hello!', $obj->{'X-WR-CALNAME'}); - $this->assertEquals('#AA0000FF', $obj->{'X-APPLE-CALENDAR-COLOR'}); - } - - public function testBeforeMethodNoVersion() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export' - ); - DAV\Server::$exposeVersion = false; - $response = $this->request($request); - DAV\Server::$exposeVersion = true; - - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals('text/calendar', $response->getHeader('Content-Type')); - - $obj = VObject\Reader::read($response->getBodyAsString()); - - $this->assertEquals(8, count($obj->children())); - $this->assertEquals(1, count($obj->VERSION)); - $this->assertEquals(1, count($obj->CALSCALE)); - $this->assertEquals(1, count($obj->PRODID)); - $this->assertFalse(false !== strpos((string) $obj->PRODID, DAV\Version::VERSION)); - $this->assertEquals(1, count($obj->VTIMEZONE)); - $this->assertEquals(1, count($obj->VEVENT)); - } - - public function testBeforeMethodNoExport() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467' - ); - $response = new HTTP\Response(); - $this->assertNull($this->icsExportPlugin->httpGet($request, $response)); - } - - public function testACLIntegrationBlocked() - { - $aclPlugin = new DAVACL\Plugin(); - $aclPlugin->allowUnauthenticatedAccess = false; - $this->server->addPlugin( - $aclPlugin - ); - - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export' - ); - - $this->request($request, 403); - } - - public function testACLIntegrationNotBlocked() - { - $aclPlugin = new DAVACL\Plugin(); - $aclPlugin->allowUnauthenticatedAccess = false; - $this->server->addPlugin( - $aclPlugin - ); - $this->server->addPlugin( - new Plugin() - ); - - $this->autoLogin('admin'); - - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export' - ); - - $response = $this->request($request, 200); - $this->assertEquals('text/calendar', $response->getHeader('Content-Type')); - - $obj = VObject\Reader::read($response->getBodyAsString()); - - $this->assertEquals(8, count($obj->children())); - $this->assertEquals(1, count($obj->VERSION)); - $this->assertEquals(1, count($obj->CALSCALE)); - $this->assertEquals(1, count($obj->PRODID)); - $this->assertTrue(false !== strpos((string) $obj->PRODID, DAV\Version::VERSION)); - $this->assertEquals(1, count($obj->VTIMEZONE)); - $this->assertEquals(1, count($obj->VEVENT)); - } - - public function testBadStartParam() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&start=foo' - ); - $this->request($request, 400); - } - - public function testBadEndParam() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&end=foo' - ); - $this->request($request, 400); - } - - public function testFilterStartEnd() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&start=1&end=2' - ); - $response = $this->request($request, 200); - - $obj = VObject\Reader::read($response->getBody()); - - $this->assertNull($obj->VTIMEZONE); - $this->assertNull($obj->VEVENT); - } - - public function testExpandNoStart() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&expand=1&end=2' - ); - $this->request($request, 400); - } - - public function testExpand() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&start=1&end=2000000000&expand=1' - ); - $response = $this->request($request, 200); - - $obj = VObject\Reader::read($response->getBody()); - - $this->assertNull($obj->VTIMEZONE); - $this->assertEquals(1, count($obj->VEVENT)); - } - - public function testJCal() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export', - ['Accept' => 'application/calendar+json'] - ); - - $response = $this->request($request, 200); - $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type')); - } - - public function testJCalInUrl() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&accept=jcal' - ); - - $response = $this->request($request, 200); - $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type')); - } - - public function testNegotiateDefault() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export', - ['Accept' => 'text/plain'] - ); - - $response = $this->request($request, 200); - $this->assertEquals('text/calendar', $response->getHeader('Content-Type')); - } - - public function testFilterComponentVEVENT() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&componentType=VEVENT' - ); - - $response = $this->request($request, 200); - - $obj = VObject\Reader::read($response->getBodyAsString()); - $this->assertEquals(1, count($obj->VTIMEZONE)); - $this->assertEquals(1, count($obj->VEVENT)); - $this->assertNull($obj->VTODO); - } - - public function testFilterComponentVTODO() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&componentType=VTODO' - ); - - $response = $this->request($request, 200); - - $obj = VObject\Reader::read($response->getBodyAsString()); - - $this->assertNull($obj->VTIMEZONE); - $this->assertNull($obj->VEVENT); - $this->assertEquals(1, count($obj->VTODO)); - } - - public function testFilterComponentBadComponent() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export&componentType=VVOODOO' - ); - - $response = $this->request($request, 400); - } - - public function testContentDisposition() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export' - ); - - $response = $this->request($request, 200); - $this->assertEquals('text/calendar', $response->getHeader('Content-Type')); - $this->assertEquals( - 'attachment; filename="UUID-123467-'.date('Y-m-d').'.ics"', - $response->getHeader('Content-Disposition') - ); - } - - public function testContentDispositionJson() - { - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-123467?export', - ['Accept' => 'application/calendar+json'] - ); - - $response = $this->request($request, 200); - $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type')); - $this->assertEquals( - 'attachment; filename="UUID-123467-'.date('Y-m-d').'.json"', - $response->getHeader('Content-Disposition') - ); - } - - public function testContentDispositionBadChars() - { - $this->caldavBackend->createCalendar( - 'principals/admin', - 'UUID-b_ad"(ch)ars', - [ - '{DAV:}displayname' => 'Test bad characters', - '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF', - ] - ); - - $request = new HTTP\Request( - 'GET', - '/calendars/admin/UUID-b_ad"(ch)ars?export', - ['Accept' => 'application/calendar+json'] - ); - - $response = $this->request($request, 200); - $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type')); - $this->assertEquals( - 'attachment; filename="UUID-b_adchars-'.date('Y-m-d').'.json"', - $response->getHeader('Content-Disposition') - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php deleted file mode 100644 index 02d39fe84..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php +++ /dev/null @@ -1,63 +0,0 @@ - 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2011-12-01'), - 'end' => new \DateTime('2012-02-01'), - ], - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]; - $input = VObject\Reader::read($input); - $this->assertTrue($validator->validate($input, $filters)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php deleted file mode 100644 index 83120fe6a..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php +++ /dev/null @@ -1,140 +0,0 @@ - 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'), - 'end' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'), - ], - ], - ], - 'prop-filters' => [], - ]; - $input = VObject\Reader::read($input); - $this->assertTrue($validator->validate($input, $filters)); - } - - // Pacific Standard Time, translates to America/Los_Angeles (GMT-8 in January) - public function testOutlookTimezoneName() - { - $input = << 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'), - 'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'), - ], - ], - ], - 'prop-filters' => [], - ]; - $input = VObject\Reader::read($input); - $this->assertTrue($validator->validate($input, $filters)); - } - - // X-LIC-LOCATION, translates to America/Los_Angeles (GMT-8 in January) - public function testLibICalLocationName() - { - $input = << 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'), - 'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'), - ], - ], - ], - 'prop-filters' => [], - ]; - $input = VObject\Reader::read($input); - $this->assertTrue($validator->validate($input, $filters)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php deleted file mode 100644 index 9a786c505..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue203Test.php +++ /dev/null @@ -1,138 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -UID:20120330T155305CEST-6585fBUVgV -DTSTAMP:20120330T135305Z -DTSTART;TZID=Europe/Berlin:20120326T155200 -DTEND;TZID=Europe/Berlin:20120326T165200 -RRULE:FREQ=DAILY;COUNT=2;INTERVAL=1 -SUMMARY:original summary -TRANSP:OPAQUE -END:VEVENT -BEGIN:VEVENT -UID:20120330T155305CEST-6585fBUVgV -DTSTAMP:20120330T135352Z -DESCRIPTION: -DTSTART;TZID=Europe/Berlin:20120328T155200 -DTEND;TZID=Europe/Berlin:20120328T165200 -RECURRENCE-ID;TZID=Europe/Berlin:20120327T155200 -SEQUENCE:1 -SUMMARY:overwritten summary -TRANSP:OPAQUE -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testIssue203() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - $bodyAsString = $response->getBodyAsString(); - // Everts super awesome xml parser. - $body = substr( - $bodyAsString, - $start = strpos($bodyAsString, 'BEGIN:VCALENDAR'), - strpos($bodyAsString, 'END:VCALENDAR') - $start + 13 - ); - $body = str_replace(' ', '', $body); - - $vObject = VObject\Reader::read($body); - - $this->assertEquals(2, count($vObject->VEVENT)); - - $expectedEvents = [ - [ - 'DTSTART' => '20120326T135200Z', - 'DTEND' => '20120326T145200Z', - 'SUMMARY' => 'original summary', - ], - [ - 'DTSTART' => '20120328T135200Z', - 'DTEND' => '20120328T145200Z', - 'SUMMARY' => 'overwritten summary', - 'RECURRENCE-ID' => '20120327T135200Z', - ], - ]; - - // try to match agains $expectedEvents array - foreach ($expectedEvents as $expectedEvent) { - $matching = false; - - foreach ($vObject->VEVENT as $vevent) { - /** @var $vevent Sabre\VObject\Component\VEvent */ - foreach ($vevent->children() as $child) { - /** @var $child Sabre\VObject\Property */ - if (isset($expectedEvent[$child->name])) { - if ($expectedEvent[$child->name] != $child->getValue()) { - continue 2; - } - } - } - - $matching = true; - break; - } - - $this->assertTrue($matching, 'Did not find the following event in the response: '.var_export($expectedEvent, true)); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php deleted file mode 100644 index b021634ba..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php +++ /dev/null @@ -1,99 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -UID:20120330T155305CEST-6585fBUVgV -DTSTAMP:20120330T135305Z -DTSTART;TZID=Europe/Berlin:20120326T155200 -DTEND;TZID=Europe/Berlin:20120326T165200 -SUMMARY:original summary -TRANSP:OPAQUE -BEGIN:VALARM -ACTION:AUDIO -ATTACH;VALUE=URI:Basso -TRIGGER:PT0S -END:VALARM -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testIssue205() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - $this->assertFalse(strpos($response->getBodyAsString(), 'Exception'), 'Exception occurred: '.$response->getBodyAsString()); - $this->assertFalse(strpos($response->getBodyAsString(), 'Unknown or bad format'), 'DateTime unknown format Exception: '.$response->getBodyAsString()); - - // Everts super awesome xml parser. - $body = substr( - $response->getBodyAsString(), - $start = strpos($response->getBodyAsString(), 'BEGIN:VCALENDAR'), - strpos($response->getBodyAsString(), 'END:VCALENDAR') - $start + 13 - ); - $body = str_replace(' ', '', $body); - - $vObject = VObject\Reader::read($body); - - $this->assertEquals(1, count($vObject->VEVENT)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php deleted file mode 100644 index d7fa18c09..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php +++ /dev/null @@ -1,90 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -UID:20120418T172519CEST-3510gh1hVw -DTSTAMP:20120418T152519Z -DTSTART;VALUE=DATE:20120330 -DTEND;VALUE=DATE:20120531 -EXDATE;TZID=Europe/Berlin:20120330T000000 -RRULE:FREQ=YEARLY;INTERVAL=1 -SEQUENCE:1 -SUMMARY:Birthday -TRANSP:TRANSPARENT -BEGIN:VALARM -ACTION:EMAIL -ATTENDEE:MAILTO:xxx@domain.de -DESCRIPTION:Dies ist eine Kalender Erinnerung -SUMMARY:Kalender Alarm Erinnerung -TRIGGER;VALUE=DATE-TIME:20120329T060000Z -END:VALARM -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testIssue211() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - // if this assert is reached, the endless loop is gone - // There should be no matching events - $this->assertFalse(strpos('BEGIN:VEVENT', $response->getBodyAsString())); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php deleted file mode 100644 index 8e51e49e2..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php +++ /dev/null @@ -1,101 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -DTSTART;TZID=Europe/Berlin:20120601T180000 -SUMMARY:Brot backen -RRULE:FREQ=DAILY;INTERVAL=1;WKST=MO -TRANSP:OPAQUE -DURATION:PT20M -LAST-MODIFIED:20120601T064634Z -CREATED:20120601T064634Z -DTSTAMP:20120601T064634Z -UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd -BEGIN:VALARM -TRIGGER;VALUE=DURATION:-PT5M -ACTION:DISPLAY -DESCRIPTION:Default Event Notification -X-WR-ALARMUID:cd952c1b-b3d6-41fb-b0a6-ec3a1a5bdd58 -END:VALARM -END:VEVENT -BEGIN:VEVENT -DTSTART;TZID=Europe/Berlin:20120606T180000 -SUMMARY:Brot backen -TRANSP:OPAQUE -STATUS:CANCELLED -DTEND;TZID=Europe/Berlin:20120606T182000 -LAST-MODIFIED:20120605T094310Z -SEQUENCE:1 -RECURRENCE-ID:20120606T160000Z -UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testIssue220() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - $this->assertFalse(strpos($response->getBodyAsString(), 'PHPUnit_Framework_Error_Warning'), 'Error Warning occurred: '.$response->getBodyAsString()); - $this->assertFalse(strpos($response->getBodyAsString(), 'Invalid argument supplied for foreach()'), 'Invalid argument supplied for foreach(): '.$response->getBodyAsString()); - - $this->assertEquals(207, $response->status); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php deleted file mode 100644 index 1f698e7dd..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php +++ /dev/null @@ -1,80 +0,0 @@ - 1, - 'name' => 'Calendar', - 'principaluri' => 'principals/user1', - 'uri' => 'calendar1', - ], - ]; - - protected $caldavCalendarObjects = [ - 1 => [ - 'event.ics' => [ - 'calendardata' => 'BEGIN:VCALENDAR -VERSION:2.0 -BEGIN:VEVENT -UID:20120730T113415CEST-6804EGphkd@xxxxxx.de -DTSTAMP:20120730T093415Z -DTSTART;VALUE=DATE:20120729 -DTEND;VALUE=DATE:20120730 -SUMMARY:sunday event -TRANSP:TRANSPARENT -END:VEVENT -END:VCALENDAR -', - ], - ], - ]; - - public function testIssue228() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'REQUEST_URI' => '/calendars/user1/calendar1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody(' - - - - - - - - - - - - - - -'); - - $response = $this->request($request); - - // We must check if absolutely nothing was returned from this query. - $this->assertFalse(strpos($response->getBodyAsString(), 'BEGIN:VCALENDAR')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php deleted file mode 100644 index 594241e0d..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php +++ /dev/null @@ -1,78 +0,0 @@ -principalUri = 'principals/user1'; - - $this->notification = new CalDAV\Xml\Notification\SystemStatus(1, '"1"'); - - $this->caldavBackend = new CalDAV\Backend\MockSharing([], [], [ - 'principals/user1' => [ - $this->notification, - ], - ]); - - return new Collection($this->caldavBackend, $this->principalUri); - } - - public function testGetChildren() - { - $col = $this->getInstance(); - $this->assertEquals('notifications', $col->getName()); - - $this->assertEquals([ - new Node($this->caldavBackend, $this->principalUri, $this->notification), - ], $col->getChildren()); - } - - public function testGetOwner() - { - $col = $this->getInstance(); - $this->assertEquals('principals/user1', $col->getOwner()); - } - - public function testGetGroup() - { - $col = $this->getInstance(); - $this->assertNull($col->getGroup()); - } - - public function testGetACL() - { - $col = $this->getInstance(); - $expected = [ - [ - 'privilege' => '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - ]; - - $this->assertEquals($expected, $col->getACL()); - } - - public function testSetACL() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $col = $this->getInstance(); - $col->setACL([]); - } - - public function testGetSupportedPrivilegeSet() - { - $col = $this->getInstance(); - $this->assertNull($col->getSupportedPrivilegeSet()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php deleted file mode 100644 index 623525e69..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php +++ /dev/null @@ -1,88 +0,0 @@ -systemStatus = new CalDAV\Xml\Notification\SystemStatus(1, '"1"'); - - $this->caldavBackend = new CalDAV\Backend\MockSharing([], [], [ - 'principals/user1' => [ - $this->systemStatus, - ], - ]); - - $node = new Node($this->caldavBackend, 'principals/user1', $this->systemStatus); - - return $node; - } - - public function testGetId() - { - $node = $this->getInstance(); - $this->assertEquals($this->systemStatus->getId().'.xml', $node->getName()); - } - - public function testGetEtag() - { - $node = $this->getInstance(); - $this->assertEquals('"1"', $node->getETag()); - } - - public function testGetNotificationType() - { - $node = $this->getInstance(); - $this->assertEquals($this->systemStatus, $node->getNotificationType()); - } - - public function testDelete() - { - $node = $this->getInstance(); - $node->delete(); - $this->assertEquals([], $this->caldavBackend->getNotificationsForPrincipal('principals/user1')); - } - - public function testGetGroup() - { - $node = $this->getInstance(); - $this->assertNull($node->getGroup()); - } - - public function testGetACL() - { - $node = $this->getInstance(); - $expected = [ - [ - 'privilege' => '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - ]; - - $this->assertEquals($expected, $node->getACL()); - } - - public function testSetACL() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $node = $this->getInstance(); - $node->setACL([]); - } - - public function testGetSupportedPrivilegeSet() - { - $node = $this->getInstance(); - $this->assertNull($node->getSupportedPrivilegeSet()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php deleted file mode 100644 index a4f08f7e5..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php +++ /dev/null @@ -1,1071 +0,0 @@ -caldavBackend = new Backend\Mock([ - [ - 'id' => 1, - 'uri' => 'UUID-123467', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'user1 calendar', - $caldavNS.'calendar-description' => 'Calendar description', - '{http://apple.com/ns/ical/}calendar-order' => '1', - '{http://apple.com/ns/ical/}calendar-color' => '#FF0000', - $caldavNS.'supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO']), - ], - [ - 'id' => 2, - 'uri' => 'UUID-123468', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'user1 calendar2', - $caldavNS.'calendar-description' => 'Calendar description', - '{http://apple.com/ns/ical/}calendar-order' => '1', - '{http://apple.com/ns/ical/}calendar-color' => '#FF0000', - $caldavNS.'supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO']), - ], - ], [ - 1 => [ - 'UUID-2345' => [ - 'calendardata' => TestUtil::getTestCalendarData(), - ], - ], - ]); - $principalBackend = new DAVACL\PrincipalBackend\Mock(); - $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-read', ['principals/user1']); - $principalBackend->setGroupMemberSet('principals/admin/calendar-proxy-write', ['principals/user1']); - $principalBackend->addPrincipal([ - 'uri' => 'principals/admin/calendar-proxy-read', - ]); - $principalBackend->addPrincipal([ - 'uri' => 'principals/admin/calendar-proxy-write', - ]); - - $calendars = new CalendarRoot($principalBackend, $this->caldavBackend); - $principals = new Principal\Collection($principalBackend); - - $root = new DAV\SimpleCollection('root'); - $root->addChild($calendars); - $root->addChild($principals); - - $this->server = new DAV\Server($root); - $this->server->sapi = new HTTP\SapiMock(); - $this->server->debugExceptions = true; - $this->server->setBaseUri('/'); - $this->plugin = new Plugin(); - $this->server->addPlugin($this->plugin); - - // Adding ACL plugin - $aclPlugin = new DAVACL\Plugin(); - $aclPlugin->allowUnauthenticatedAccess = false; - $this->server->addPlugin($aclPlugin); - - // Adding Auth plugin, and ensuring that we are logged in. - $authBackend = new DAV\Auth\Backend\Mock(); - $authBackend->setPrincipal('principals/user1'); - $authPlugin = new DAV\Auth\Plugin($authBackend); - $authPlugin->beforeMethod(new \Sabre\HTTP\Request('GET', '/'), new \Sabre\HTTP\Response()); - $this->server->addPlugin($authPlugin); - - // This forces a login - $authPlugin->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response()); - - $this->response = new HTTP\ResponseMock(); - $this->server->httpResponse = $this->response; - } - - public function testSimple() - { - $this->assertEquals(['MKCALENDAR'], $this->plugin->getHTTPMethods('calendars/user1/randomnewcalendar')); - $this->assertEquals(['calendar-access', 'calendar-proxy'], $this->plugin->getFeatures()); - $this->assertEquals( - 'caldav', - $this->plugin->getPluginInfo()['name'] - ); - } - - public function testUnknownMethodPassThrough() - { - $request = new HTTP\Request('MKBREAKFAST', '/'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(501, $this->response->status, 'Incorrect status returned. Full response body:'.$this->response->getBodyAsString()); - } - - public function testGetWithoutContentType() - { - $request = new HTTP\Request('GET', '/'); - $this->plugin->httpAfterGet($request, $this->response); - $this->assertTrue(true); - } - - public function testReportPassThrough() - { - $request = new HTTP\Request('REPORT', '/', ['Content-Type' => 'application/xml']); - $request->setBody(''); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(415, $this->response->status); - } - - public function testMkCalendarBadLocation() - { - $request = new HTTP\Request('MKCALENDAR', '/blabla'); - - $body = ' - - - - Lisa\'s Events - Calendar restricted to events. - - - - - - - '; - - $request->setBody($body); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(403, $this->response->status); - } - - public function testMkCalendarNoParentNode() - { - $request = new HTTP\Request('MKCALENDAR', '/doesntexist/calendar'); - - $body = ' - - - - Lisa\'s Events - Calendar restricted to events. - - - - - - - '; - - $request->setBody($body); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(409, $this->response->status); - } - - public function testMkCalendarExistingCalendar() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'MKCALENDAR', - 'REQUEST_URI' => '/calendars/user1/UUID-123467', - ]); - - $body = ' - - - - Lisa\'s Events - Calendar restricted to events. - - - - - - - '; - - $request->setBody($body); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(405, $this->response->status); - } - - public function testMkCalendarSucceed() - { - $request = new HTTP\Request('MKCALENDAR', '/calendars/user1/NEWCALENDAR'); - - $timezone = 'BEGIN:VCALENDAR -PRODID:-//Example Corp.//CalDAV Client//EN -VERSION:2.0 -BEGIN:VTIMEZONE -TZID:US-Eastern -LAST-MODIFIED:19870101T000000Z -BEGIN:STANDARD -DTSTART:19671029T020000 -RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:Eastern Standard Time (US & Canada) -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19870405T020000 -RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:Eastern Daylight Time (US & Canada) -END:DAYLIGHT -END:VTIMEZONE -END:VCALENDAR'; - - $body = ' - - - - Lisa\'s Events - Calendar restricted to events. - - - - - - - '; - - $request->setBody($body); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(201, $this->response->status, 'Invalid response code received. Full response body: '.$this->response->getBodyAsString()); - - $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1'); - $this->assertEquals(3, count($calendars)); - - $newCalendar = null; - foreach ($calendars as $calendar) { - if ('NEWCALENDAR' === $calendar['uri']) { - $newCalendar = $calendar; - break; - } - } - - $this->assertIsArray($newCalendar); - - $keys = [ - 'uri' => 'NEWCALENDAR', - 'id' => null, - '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar restricted to events.', - '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => $timezone, - '{DAV:}displayname' => 'Lisa\'s Events', - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null, - ]; - - foreach ($keys as $key => $value) { - $this->assertArrayHasKey($key, $newCalendar); - - if (is_null($value)) { - continue; - } - $this->assertEquals($value, $newCalendar[$key]); - } - $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'; - $this->assertTrue($newCalendar[$sccs] instanceof Xml\Property\SupportedCalendarComponentSet); - $this->assertEquals(['VEVENT'], $newCalendar[$sccs]->getValue()); - } - - public function testMkCalendarEmptyBodySucceed() - { - $request = new HTTP\Request('MKCALENDAR', '/calendars/user1/NEWCALENDAR'); - - $request->setBody(''); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(201, $this->response->status, 'Invalid response code received. Full response body: '.$this->response->getBodyAsString()); - - $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1'); - $this->assertEquals(3, count($calendars)); - - $newCalendar = null; - foreach ($calendars as $calendar) { - if ('NEWCALENDAR' === $calendar['uri']) { - $newCalendar = $calendar; - break; - } - } - - $this->assertIsArray($newCalendar); - - $keys = [ - 'uri' => 'NEWCALENDAR', - 'id' => null, - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null, - ]; - - foreach ($keys as $key => $value) { - $this->assertArrayHasKey($key, $newCalendar); - - if (is_null($value)) { - continue; - } - $this->assertEquals($value, $newCalendar[$key]); - } - $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'; - $this->assertTrue($newCalendar[$sccs] instanceof Xml\Property\SupportedCalendarComponentSet); - $this->assertEquals(['VEVENT', 'VTODO'], $newCalendar[$sccs]->getValue()); - } - - public function testMkCalendarBadXml() - { - $request = new HTTP\Request('MKCALENDAR', '/blabla'); - $body = 'This is not xml'; - - $request->setBody($body); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(400, $this->response->status); - } - - public function testPrincipalProperties() - { - $httpRequest = new HTTP\Request('FOO', '/blabla', ['Host' => 'sabredav.org']); - $this->server->httpRequest = $httpRequest; - - $props = $this->server->getPropertiesForPath('/principals/user1', [ - '{'.Plugin::NS_CALDAV.'}calendar-home-set', - '{'.Plugin::NS_CALENDARSERVER.'}calendar-proxy-read-for', - '{'.Plugin::NS_CALENDARSERVER.'}calendar-proxy-write-for', - '{'.Plugin::NS_CALENDARSERVER.'}notification-URL', - '{'.Plugin::NS_CALENDARSERVER.'}email-address-set', - ]); - - $this->assertArrayHasKey(0, $props); - $this->assertArrayHasKey(200, $props[0]); - - $this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-home-set', $props[0][200]); - $prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-home-set']; - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $prop); - $this->assertEquals('calendars/user1/', $prop->getHref()); - - $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-read-for', $props[0][200]); - $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-read-for']; - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $prop); - $this->assertEquals(['principals/admin/'], $prop->getHrefs()); - - $this->assertArrayHasKey('{http://calendarserver.org/ns/}calendar-proxy-write-for', $props[0][200]); - $prop = $props[0][200]['{http://calendarserver.org/ns/}calendar-proxy-write-for']; - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $prop); - $this->assertEquals(['principals/admin/'], $prop->getHrefs()); - - $this->assertArrayHasKey('{'.Plugin::NS_CALENDARSERVER.'}email-address-set', $props[0][200]); - $prop = $props[0][200]['{'.Plugin::NS_CALENDARSERVER.'}email-address-set']; - $this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\EmailAddressSet', $prop); - $this->assertEquals(['user1.sabredav@sabredav.org'], $prop->getValue()); - } - - public function testSupportedReportSetPropertyNonCalendar() - { - $props = $this->server->getPropertiesForPath('/calendars/user1', [ - '{DAV:}supported-report-set', - ]); - - $this->assertArrayHasKey(0, $props); - $this->assertArrayHasKey(200, $props[0]); - $this->assertArrayHasKey('{DAV:}supported-report-set', $props[0][200]); - - $prop = $props[0][200]['{DAV:}supported-report-set']; - - $this->assertInstanceOf('\\Sabre\\DAV\\Xml\\Property\\SupportedReportSet', $prop); - $value = [ - '{DAV:}expand-property', - '{DAV:}principal-match', - '{DAV:}principal-property-search', - '{DAV:}principal-search-property-set', - ]; - $this->assertEquals($value, $prop->getValue()); - } - - /** - * @depends testSupportedReportSetPropertyNonCalendar - */ - public function testSupportedReportSetProperty() - { - $props = $this->server->getPropertiesForPath('/calendars/user1/UUID-123467', [ - '{DAV:}supported-report-set', - ]); - - $this->assertArrayHasKey(0, $props); - $this->assertArrayHasKey(200, $props[0]); - $this->assertArrayHasKey('{DAV:}supported-report-set', $props[0][200]); - - $prop = $props[0][200]['{DAV:}supported-report-set']; - - $this->assertInstanceOf('\\Sabre\\DAV\\Xml\\Property\\SupportedReportSet', $prop); - $value = [ - '{urn:ietf:params:xml:ns:caldav}calendar-multiget', - '{urn:ietf:params:xml:ns:caldav}calendar-query', - '{urn:ietf:params:xml:ns:caldav}free-busy-query', - '{DAV:}expand-property', - '{DAV:}principal-match', - '{DAV:}principal-property-search', - '{DAV:}principal-search-property-set', - ]; - $this->assertEquals($value, $prop->getValue()); - } - - public function testSupportedReportSetUserCalendars() - { - $this->server->addPlugin(new \Sabre\DAV\Sync\Plugin()); - - $props = $this->server->getPropertiesForPath('/calendars/user1', [ - '{DAV:}supported-report-set', - ]); - - $this->assertArrayHasKey(0, $props); - $this->assertArrayHasKey(200, $props[0]); - $this->assertArrayHasKey('{DAV:}supported-report-set', $props[0][200]); - - $prop = $props[0][200]['{DAV:}supported-report-set']; - - $this->assertInstanceOf('\\Sabre\\DAV\\Xml\\Property\\SupportedReportSet', $prop); - $value = [ - '{DAV:}sync-collection', - '{DAV:}expand-property', - '{DAV:}principal-match', - '{DAV:}principal-property-search', - '{DAV:}principal-search-property-set', - ]; - $this->assertEquals($value, $prop->getValue()); - } - - /** - * @depends testSupportedReportSetProperty - */ - public function testCalendarMultiGetReport() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ''. - '/calendars/user1/UUID-123467/UUID-2345'. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(207, $this->response->status, 'Invalid HTTP status received. Full response body'); - - $expectedIcal = TestUtil::getTestCalendarData(); - - $expected = << - - - /calendars/user1/UUID-123467/UUID-2345 - - - $expectedIcal - "e207e33c10e5fb9c12cfb35b5d9116e1" - - HTTP/1.1 200 OK - - - -XML; - - $this->assertXmlStringEqualsXmlString($expected, $this->response->getBodyAsString()); - } - - /** - * @depends testCalendarMultiGetReport - */ - public function testCalendarMultiGetReportExpand() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - '/calendars/user1/UUID-123467/UUID-2345'. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $bodyAsString = $this->response->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Invalid HTTP status received. Full response body: '.$bodyAsString); - - $expectedIcal = TestUtil::getTestCalendarData(); - $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal); - $expectedIcal = $expectedIcal->expand( - new DateTime('2011-01-01 00:00:00', new DateTimeZone('UTC')), - new DateTime('2011-12-31 23:59:59', new DateTimeZone('UTC')) - ); - $expectedIcal = str_replace("\r\n", " \n", $expectedIcal->serialize()); - - $expected = << - - - /calendars/user1/UUID-123467/UUID-2345 - - - $expectedIcal - "e207e33c10e5fb9c12cfb35b5d9116e1" - - HTTP/1.1 200 OK - - - -XML; - - $this->assertXmlStringEqualsXmlString($expected, $bodyAsString); - } - - /** - * @depends testSupportedReportSetProperty - * @depends testCalendarMultiGetReport - */ - public function testCalendarQueryReport() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - ''. - ' '. - ' '. - ' '. - ''. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', ['Depth' => '1']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $bodyAsString = $this->response->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString); - - $expectedIcal = TestUtil::getTestCalendarData(); - $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal); - $expectedIcal = $expectedIcal->expand( - new DateTime('2000-01-01 00:00:00', new DateTimeZone('UTC')), - new DateTime('2010-12-31 23:59:59', new DateTimeZone('UTC')) - ); - $expectedIcal = str_replace("\r\n", " \n", $expectedIcal->serialize()); - - $expected = << - - - /calendars/user1/UUID-123467/UUID-2345 - - - $expectedIcal - "e207e33c10e5fb9c12cfb35b5d9116e1" - - HTTP/1.1 200 OK - - - -XML; - - $this->assertXmlStringEqualsXmlString($expected, $bodyAsString); - } - - /** - * @depends testSupportedReportSetProperty - * @depends testCalendarMultiGetReport - */ - public function testCalendarQueryReportWindowsPhone() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - ''. - ' '. - ' '. - ' '. - ''. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', [ - 'Depth' => '0', - 'User-Agent' => 'MSFT-WP/8.10.14219 (gzip)', - ]); - - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $bodyAsString = $this->response->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString); - - $expectedIcal = TestUtil::getTestCalendarData(); - $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal); - $expectedIcal = $expectedIcal->expand( - new DateTime('2000-01-01 00:00:00', new DateTimeZone('UTC')), - new DateTime('2010-12-31 23:59:59', new DateTimeZone('UTC')) - ); - $expectedIcal = str_replace("\r\n", " \n", $expectedIcal->serialize()); - - $expected = << - - - /calendars/user1/UUID-123467/UUID-2345 - - - $expectedIcal - "e207e33c10e5fb9c12cfb35b5d9116e1" - - HTTP/1.1 200 OK - - - -XML; - - $this->assertXmlStringEqualsXmlString($expected, $bodyAsString); - } - - /** - * @depends testSupportedReportSetProperty - * @depends testCalendarMultiGetReport - */ - public function testCalendarQueryReportBadDepth() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - ''. - ' '. - ' '. - ' '. - ''. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', [ - 'Depth' => '0', - ]); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(400, $this->response->status, 'Received an unexpected status. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testCalendarQueryReport - */ - public function testCalendarQueryReportNoCalData() - { - $body = - ''. - ''. - ''. - ' '. - ''. - ''. - ' '. - ' '. - ' '. - ''. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', [ - 'Depth' => '1', - ]); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $bodyAsString = $this->server->httpResponse->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString); - - $expected = << - - - /calendars/user1/UUID-123467/UUID-2345 - - - "e207e33c10e5fb9c12cfb35b5d9116e1" - - HTTP/1.1 200 OK - - - -XML; - - $this->assertXmlStringEqualsXmlString($expected, $bodyAsString); - } - - /** - * @depends testCalendarQueryReport - */ - public function testCalendarQueryReportNoFilters() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ''. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467'); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(400, $this->response->status, 'Received an unexpected status. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testSupportedReportSetProperty - * @depends testCalendarMultiGetReport - */ - public function testCalendarQueryReport1Object() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - ''. - ' '. - ' '. - ' '. - ''. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467/UUID-2345', ['Depth' => '0']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $bodyAsString = $this->server->httpResponse->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString); - - $expectedIcal = TestUtil::getTestCalendarData(); - $expectedIcal = \Sabre\VObject\Reader::read($expectedIcal); - $expectedIcal = $expectedIcal->expand( - new DateTime('2000-01-01 00:00:00', new DateTimeZone('UTC')), - new DateTime('2010-12-31 23:59:59', new DateTimeZone('UTC')) - ); - $expectedIcal = str_replace("\r\n", " \n", $expectedIcal->serialize()); - - $expected = << - - - /calendars/user1/UUID-123467/UUID-2345 - - - $expectedIcal - "e207e33c10e5fb9c12cfb35b5d9116e1" - - HTTP/1.1 200 OK - - - -XML; - - $this->assertXmlStringEqualsXmlString($expected, $bodyAsString); - } - - /** - * @depends testSupportedReportSetProperty - * @depends testCalendarMultiGetReport - */ - public function testCalendarQueryReport1ObjectNoCalData() - { - $body = - ''. - ''. - ''. - ' '. - ''. - ''. - ' '. - ' '. - ' '. - ''. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467/UUID-2345', ['Depth' => '0']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $bodyAsString = $this->server->httpResponse->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Received an unexpected status. Full response body: '.$bodyAsString); - - $expected = << - - - /calendars/user1/UUID-123467/UUID-2345 - - - "e207e33c10e5fb9c12cfb35b5d9116e1" - - HTTP/1.1 200 OK - - - -XML; - - $this->assertXmlStringEqualsXmlString($expected, $bodyAsString); - } - - public function testHTMLActionsPanel() - { - $output = ''; - $r = $this->server->emit('onHTMLActionsPanel', [$this->server->tree->getNodeForPath('calendars/user1'), &$output]); - $this->assertFalse($r); - - $this->assertTrue((bool) strpos($output, 'Display name')); - } - - /** - * @depends testCalendarMultiGetReport - */ - public function testCalendarMultiGetReportNoEnd() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - '/calendars/user1/UUID-123467/UUID-2345'. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(400, $this->response->status, 'Invalid HTTP status received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testCalendarMultiGetReport - */ - public function testCalendarMultiGetReportNoStart() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - '/calendars/user1/UUID-123467/UUID-2345'. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(400, $this->response->status, 'Invalid HTTP status received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testCalendarMultiGetReport - */ - public function testCalendarMultiGetReportEndBeforeStart() - { - $body = - ''. - ''. - ''. - ' '. - ' '. - ' '. - ' '. - ''. - '/calendars/user1/UUID-123467/UUID-2345'. - ''; - - $request = new HTTP\Request('REPORT', '/calendars/user1', ['Depth' => '1']); - $request->setBody($body); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(400, $this->response->status, 'Invalid HTTP status received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testSupportedReportSetPropertyNonCalendar - */ - public function testCalendarProperties() - { - $ns = '{urn:ietf:params:xml:ns:caldav}'; - $props = $this->server->getProperties('calendars/user1/UUID-123467', [ - $ns.'max-resource-size', - $ns.'supported-calendar-data', - $ns.'supported-collation-set', - ]); - - $this->assertEquals([ - $ns.'max-resource-size' => 10000000, - $ns.'supported-calendar-data' => new Xml\Property\SupportedCalendarData(), - $ns.'supported-collation-set' => new Xml\Property\SupportedCollationSet(), - ], $props); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php deleted file mode 100644 index 277de0664..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php +++ /dev/null @@ -1,20 +0,0 @@ -getChildForPrincipal([ - 'uri' => 'principals/admin', - ]); - $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\User', $r); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php deleted file mode 100644 index 95ff86fa1..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php +++ /dev/null @@ -1,91 +0,0 @@ - 'principal/user', - ]); - $this->backend = $backend; - - return $principal; - } - - public function testGetName() - { - $i = $this->getInstance(); - $this->assertEquals('calendar-proxy-read', $i->getName()); - } - - public function testGetDisplayName() - { - $i = $this->getInstance(); - $this->assertEquals('calendar-proxy-read', $i->getDisplayName()); - } - - public function testGetLastModified() - { - $i = $this->getInstance(); - $this->assertNull($i->getLastModified()); - } - - public function testDelete() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $i = $this->getInstance(); - $i->delete(); - } - - public function testSetName() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $i = $this->getInstance(); - $i->setName('foo'); - } - - public function testGetAlternateUriSet() - { - $i = $this->getInstance(); - $this->assertEquals([], $i->getAlternateUriSet()); - } - - public function testGetPrincipalUri() - { - $i = $this->getInstance(); - $this->assertEquals('principal/user/calendar-proxy-read', $i->getPrincipalUrl()); - } - - public function testGetGroupMemberSet() - { - $i = $this->getInstance(); - $this->assertEquals([], $i->getGroupMemberSet()); - } - - public function testGetGroupMembership() - { - $i = $this->getInstance(); - $this->assertEquals([], $i->getGroupMembership()); - } - - public function testSetGroupMemberSet() - { - $i = $this->getInstance(); - $i->setGroupMemberSet(['principals/foo']); - - $expected = [ - $i->getPrincipalUrl() => ['principals/foo'], - ]; - - $this->assertEquals($expected, $this->backend->groupMembers); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php deleted file mode 100644 index df1715ee5..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php +++ /dev/null @@ -1,39 +0,0 @@ - 'principal/user', - ]); - $this->backend = $backend; - - return $principal; - } - - public function testGetName() - { - $i = $this->getInstance(); - $this->assertEquals('calendar-proxy-write', $i->getName()); - } - - public function testGetDisplayName() - { - $i = $this->getInstance(); - $this->assertEquals('calendar-proxy-write', $i->getDisplayName()); - } - - public function testGetPrincipalUri() - { - $i = $this->getInstance(); - $this->assertEquals('principal/user/calendar-proxy-write', $i->getPrincipalUrl()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php deleted file mode 100644 index fd079acb2..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php +++ /dev/null @@ -1,111 +0,0 @@ -addPrincipal([ - 'uri' => 'principals/user/calendar-proxy-read', - ]); - $backend->addPrincipal([ - 'uri' => 'principals/user/calendar-proxy-write', - ]); - $backend->addPrincipal([ - 'uri' => 'principals/user/random', - ]); - - return new User($backend, [ - 'uri' => 'principals/user', - ]); - } - - public function testCreateFile() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $u = $this->getInstance(); - $u->createFile('test'); - } - - public function testCreateDirectory() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $u = $this->getInstance(); - $u->createDirectory('test'); - } - - public function testGetChildProxyRead() - { - $u = $this->getInstance(); - $child = $u->getChild('calendar-proxy-read'); - $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $child); - } - - public function testGetChildProxyWrite() - { - $u = $this->getInstance(); - $child = $u->getChild('calendar-proxy-write'); - $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $child); - } - - public function testGetChildNotFound() - { - $this->expectException('Sabre\DAV\Exception\NotFound'); - $u = $this->getInstance(); - $child = $u->getChild('foo'); - } - - public function testGetChildNotFound2() - { - $this->expectException('Sabre\DAV\Exception\NotFound'); - $u = $this->getInstance(); - $child = $u->getChild('random'); - } - - public function testGetChildren() - { - $u = $this->getInstance(); - $children = $u->getChildren(); - $this->assertEquals(2, count($children)); - $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $children[0]); - $this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $children[1]); - } - - public function testChildExist() - { - $u = $this->getInstance(); - $this->assertTrue($u->childExists('calendar-proxy-read')); - $this->assertTrue($u->childExists('calendar-proxy-write')); - $this->assertFalse($u->childExists('foo')); - } - - public function testGetACL() - { - $expected = [ - [ - 'privilege' => '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user/calendar-proxy-read', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user/calendar-proxy-write', - 'protected' => true, - ], - ]; - - $u = $this->getInstance(); - $this->assertEquals($expected, $u->getACL()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php deleted file mode 100644 index df70fe7ec..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php +++ /dev/null @@ -1,47 +0,0 @@ -assertEquals('outbox', $outbox->getName()); - $this->assertEquals([], $outbox->getChildren()); - $this->assertEquals('principals/user1', $outbox->getOwner()); - $this->assertEquals(null, $outbox->getGroup()); - - $this->assertEquals([ - [ - 'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-send', - 'principal' => 'principals/user1', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1', - 'protected' => true, - ], - [ - 'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-send', - 'principal' => 'principals/user1/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1/calendar-proxy-read', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1/calendar-proxy-write', - 'protected' => true, - ], - ], $outbox->getACL()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php deleted file mode 100644 index 735bbef41..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php +++ /dev/null @@ -1,172 +0,0 @@ - 1, - '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original', - '{http://sabredav.org/ns}owner-principal' => 'principals/owner', - '{http://sabredav.org/ns}read-only' => false, - 'share-access' => Sharing\Plugin::ACCESS_READWRITE, - 'principaluri' => 'principals/sharee', - ]; - } - - $this->backend = new Backend\MockSharing( - [$props], - [], - [] - ); - - $sharee = new Sharee(); - $sharee->href = 'mailto:removeme@example.org'; - $sharee->properties['{DAV:}displayname'] = 'To be removed'; - $sharee->access = Sharing\Plugin::ACCESS_READ; - $this->backend->updateInvites(1, [$sharee]); - - return new SharedCalendar($this->backend, $props); - } - - public function testGetInvites() - { - $sharee = new Sharee(); - $sharee->href = 'mailto:removeme@example.org'; - $sharee->properties['{DAV:}displayname'] = 'To be removed'; - $sharee->access = Sharing\Plugin::ACCESS_READ; - $sharee->inviteStatus = Sharing\Plugin::INVITE_NORESPONSE; - - $this->assertEquals( - [$sharee], - $this->getInstance()->getInvites() - ); - } - - public function testGetOwner() - { - $this->assertEquals('principals/sharee', $this->getInstance()->getOwner()); - } - - public function testGetACL() - { - $expected = [ - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/sharee', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/sharee/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write-properties', - 'principal' => 'principals/sharee', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write-properties', - 'principal' => 'principals/sharee/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/sharee', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/sharee/calendar-proxy-read', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/sharee/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{'.Plugin::NS_CALDAV.'}read-free-busy', - 'principal' => '{DAV:}authenticated', - 'protected' => true, - ], - ]; - - $this->assertEquals($expected, $this->getInstance()->getACL()); - } - - public function testGetChildACL() - { - $expected = [ - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/sharee', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => 'principals/sharee/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/sharee', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/sharee/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/sharee/calendar-proxy-read', - 'protected' => true, - ], - ]; - - $this->assertEquals($expected, $this->getInstance()->getChildACL()); - } - - public function testUpdateInvites() - { - $instance = $this->getInstance(); - $newSharees = [ - new Sharee(), - new Sharee(), - ]; - $newSharees[0]->href = 'mailto:test@example.org'; - $newSharees[0]->properties['{DAV:}displayname'] = 'Foo Bar'; - $newSharees[0]->comment = 'Booh'; - $newSharees[0]->access = Sharing\Plugin::ACCESS_READWRITE; - - $newSharees[1]->href = 'mailto:removeme@example.org'; - $newSharees[1]->access = Sharing\Plugin::ACCESS_NOACCESS; - - $instance->updateInvites($newSharees); - - $expected = [ - clone $newSharees[0], - ]; - $expected[0]->inviteStatus = Sharing\Plugin::INVITE_NORESPONSE; - $this->assertEquals($expected, $instance->getInvites()); - } - - public function testPublish() - { - $instance = $this->getInstance(); - $this->assertNull($instance->setPublishStatus(true)); - $this->assertNull($instance->setPublishStatus(false)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php deleted file mode 100644 index f11af8b95..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php +++ /dev/null @@ -1,383 +0,0 @@ -caldavCalendars = [ - [ - 'principaluri' => 'principals/user1', - 'id' => 1, - 'uri' => 'cal1', - ], - [ - 'principaluri' => 'principals/user1', - 'id' => 2, - 'uri' => 'cal2', - 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE, - ], - [ - 'principaluri' => 'principals/user1', - 'id' => 3, - 'uri' => 'cal3', - ], - ]; - - parent::setUp(); - - // Making the logged in user an admin, for full access: - $this->aclPlugin->adminPrincipals[] = 'principals/user2'; - } - - public function testSimple() - { - $this->assertInstanceOf('Sabre\\CalDAV\\SharingPlugin', $this->server->getPlugin('caldav-sharing')); - $this->assertEquals( - 'caldav-sharing', - $this->caldavSharingPlugin->getPluginInfo()['name'] - ); - } - - public function testSetupWithoutCoreSharingPlugin() - { - $this->expectException('LogicException'); - $server = new DAV\Server(); - $server->addPlugin( - new SharingPlugin() - ); - } - - public function testGetFeatures() - { - $this->assertEquals(['calendarserver-sharing'], $this->caldavSharingPlugin->getFeatures()); - } - - public function testBeforeGetShareableCalendar() - { - // Forcing the server to authenticate: - $this->authPlugin->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response()); - $props = $this->server->getProperties('calendars/user1/cal1', [ - '{'.Plugin::NS_CALENDARSERVER.'}invite', - '{'.Plugin::NS_CALENDARSERVER.'}allowed-sharing-modes', - ]); - - $this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\Invite', $props['{'.Plugin::NS_CALENDARSERVER.'}invite']); - $this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes', $props['{'.Plugin::NS_CALENDARSERVER.'}allowed-sharing-modes']); - } - - public function testBeforeGetSharedCalendar() - { - $props = $this->server->getProperties('calendars/user1/cal2', [ - '{'.Plugin::NS_CALENDARSERVER.'}shared-url', - '{'.Plugin::NS_CALENDARSERVER.'}invite', - ]); - - $this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\Invite', $props['{'.Plugin::NS_CALENDARSERVER.'}invite']); - //$this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $props['{' . Plugin::NS_CALENDARSERVER . '}shared-url']); - } - - public function testUpdateResourceType() - { - $this->caldavBackend->updateInvites(1, - [ - new Sharee([ - 'href' => 'mailto:joe@example.org', - ]), - ] - ); - $result = $this->server->updateProperties('calendars/user1/cal1', [ - '{DAV:}resourcetype' => new DAV\Xml\Property\ResourceType(['{DAV:}collection']), - ]); - - $this->assertEquals([ - '{DAV:}resourcetype' => 200, - ], $result); - - $this->assertEquals(0, count($this->caldavBackend->getInvites(1))); - } - - public function testUpdatePropertiesPassThru() - { - $result = $this->server->updateProperties('calendars/user1/cal3', [ - '{DAV:}foo' => 'bar', - ]); - - $this->assertEquals([ - '{DAV:}foo' => 200, - ], $result); - } - - public function testUnknownMethodNoPOST() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PATCH', - 'REQUEST_URI' => '/', - ]); - - $response = $this->request($request); - - $this->assertEquals(501, $response->status, $response->getBodyAsString()); - } - - public function testUnknownMethodNoXML() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'POST', - 'REQUEST_URI' => '/', - 'CONTENT_TYPE' => 'text/plain', - ]); - - $response = $this->request($request); - - $this->assertEquals(501, $response->status, $response->getBodyAsString()); - } - - public function testUnknownMethodNoNode() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'POST', - 'REQUEST_URI' => '/foo', - 'CONTENT_TYPE' => 'text/xml', - ]); - - $response = $this->request($request); - - $this->assertEquals(501, $response->status, $response->getBodyAsString()); - } - - public function testShareRequest() - { - $request = new HTTP\Request('POST', '/calendars/user1/cal1', ['Content-Type' => 'text/xml']); - - $xml = << - - - mailto:joe@example.org - Joe Shmoe - - - - mailto:nancy@example.org - - -RRR; - - $request->setBody($xml); - - $this->request($request, 200); - - $this->assertEquals( - [ - new Sharee([ - 'href' => 'mailto:joe@example.org', - 'properties' => [ - '{DAV:}displayname' => 'Joe Shmoe', - ], - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE, - 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE, - 'comment' => '', - ]), - ], - $this->caldavBackend->getInvites(1) - ); - - // Wiping out tree cache - $this->server->tree->markDirty(''); - - // Verifying that the calendar is now marked shared. - $props = $this->server->getProperties('calendars/user1/cal1', ['{DAV:}resourcetype']); - $this->assertTrue( - $props['{DAV:}resourcetype']->is('{http://calendarserver.org/ns/}shared-owner') - ); - } - - public function testShareRequestNoShareableCalendar() - { - $request = new HTTP\Request( - 'POST', - '/calendars/user1/cal2', - ['Content-Type' => 'text/xml'] - ); - - $xml = ' - - - mailto:joe@example.org - Joe Shmoe - - - - mailto:nancy@example.org - - -'; - - $request->setBody($xml); - - $this->request($request, 403); - } - - public function testInviteReply() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'POST', - 'REQUEST_URI' => '/calendars/user1', - 'CONTENT_TYPE' => 'text/xml', - ]); - - $xml = ' - - /principals/owner - - -'; - - $request->setBody($xml); - $response = $this->request($request); - $this->assertEquals(200, $response->status, $response->getBodyAsString()); - } - - public function testInviteBadXML() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'POST', - 'REQUEST_URI' => '/calendars/user1', - 'CONTENT_TYPE' => 'text/xml', - ]); - - $xml = ' - - -'; - $request->setBody($xml); - $response = $this->request($request); - $this->assertEquals(400, $response->status, $response->getBodyAsString()); - } - - public function testInviteWrongUrl() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'POST', - 'REQUEST_URI' => '/calendars/user1/cal1', - 'CONTENT_TYPE' => 'text/xml', - ]); - - $xml = ' - - /principals/owner - -'; - $request->setBody($xml); - $response = $this->request($request); - $this->assertEquals(501, $response->status, $response->getBodyAsString()); - - // If the plugin did not handle this request, it must ensure that the - // body is still accessible by other plugins. - $this->assertEquals($xml, $request->getBody()); - } - - public function testPostWithoutContentType() - { - $request = new HTTP\Request('POST', '/'); - $response = new HTTP\ResponseMock(); - - $this->caldavSharingPlugin->httpPost($request, $response); - $this->assertTrue(true); - } - - public function testPublish() - { - $request = new HTTP\Request('POST', '/calendars/user1/cal1', ['Content-Type' => 'text/xml']); - - $xml = ' - -'; - - $request->setBody($xml); - - $response = $this->request($request); - $this->assertEquals(202, $response->status, $response->getBodyAsString()); - } - - public function testUnpublish() - { - $request = new HTTP\Request( - 'POST', - '/calendars/user1/cal1', - ['Content-Type' => 'text/xml'] - ); - - $xml = ' - -'; - - $request->setBody($xml); - - $response = $this->request($request); - $this->assertEquals(200, $response->status, $response->getBodyAsString()); - } - - public function testPublishWrongUrl() - { - $request = new HTTP\Request( - 'POST', - '/calendars/user1', - ['Content-Type' => 'text/xml'] - ); - - $xml = ' - -'; - - $request->setBody($xml); - $this->request($request, 501); - } - - public function testUnpublishWrongUrl() - { - $request = new HTTP\Request( - 'POST', - '/calendars/user1', - ['Content-Type' => 'text/xml'] - ); - $xml = ' - -'; - - $request->setBody($xml); - - $this->request($request, 501); - } - - public function testUnknownXmlDoc() - { - $request = new HTTP\Request( - 'POST', - '/calendars/user1/cal2', - ['Content-Type' => 'text/xml'] - ); - - $xml = ' -'; - - $request->setBody($xml); - - $response = $this->request($request); - $this->assertEquals(501, $response->status, $response->getBodyAsString()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php b/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php deleted file mode 100644 index 5de11a31a..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php +++ /dev/null @@ -1,102 +0,0 @@ -createCalendar( - 'principals/user1', - 'UUID-123467', - [ - '{DAV:}displayname' => 'user1 calendar', - '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description', - '{http://apple.com/ns/ical/}calendar-order' => '1', - '{http://apple.com/ns/ical/}calendar-color' => '#FF0000', - ] - ); - $backend->createCalendar( - 'principals/user1', - 'UUID-123468', - [ - '{DAV:}displayname' => 'user1 calendar2', - '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description', - '{http://apple.com/ns/ical/}calendar-order' => '1', - '{http://apple.com/ns/ical/}calendar-color' => '#FF0000', - ] - ); - $backend->createCalendarObject($calendarId, 'UUID-2345', self::getTestCalendarData()); - - return $backend; - } - - public static function getTestCalendarData($type = 1) - { - $calendarData = 'BEGIN:VCALENDAR -VERSION:2.0 -PRODID:-//Apple Inc.//iCal 4.0.1//EN -CALSCALE:GREGORIAN -BEGIN:VTIMEZONE -TZID:Asia/Seoul -BEGIN:DAYLIGHT -TZOFFSETFROM:+0900 -RRULE:FREQ=YEARLY;UNTIL=19880507T150000Z;BYMONTH=5;BYDAY=2SU -DTSTART:19870510T000000 -TZNAME:GMT+09:00 -TZOFFSETTO:+1000 -END:DAYLIGHT -BEGIN:STANDARD -TZOFFSETFROM:+1000 -DTSTART:19881009T000000 -TZNAME:GMT+09:00 -TZOFFSETTO:+0900 -END:STANDARD -END:VTIMEZONE -BEGIN:VEVENT -CREATED:20100225T154229Z -UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627 -TRANSP:TRANSPARENT -SUMMARY:Something here -DTSTAMP:20100228T130202Z'; - - switch ($type) { - case 1: - $calendarData .= "\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDTEND;TZID=Asia/Seoul:20100223T070000\n"; - break; - case 2: - $calendarData .= "\nDTSTART:20100223T060000\nDTEND:20100223T070000\n"; - break; - case 3: - $calendarData .= "\nDTSTART;VALUE=DATE:20100223\nDTEND;VALUE=DATE:20100223\n"; - break; - case 4: - $calendarData .= "\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:PT1H\n"; - break; - case 5: - $calendarData .= "\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:-P5D\n"; - break; - case 6: - $calendarData .= "\nDTSTART;VALUE=DATE:20100223\n"; - break; - case 7: - $calendarData .= "\nDTSTART;VALUE=DATETIME:20100223T060000\n"; - break; - - // No DTSTART, so intentionally broken - case 'X': - $calendarData .= "\n"; - break; - } - - $calendarData .= 'ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com -SEQUENCE:2 -END:VEVENT -END:VCALENDAR'; - - return $calendarData; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php deleted file mode 100644 index 4e2411391..000000000 --- a/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php +++ /dev/null @@ -1,392 +0,0 @@ - 'calendar1', - 'principaluri' => 'principals/admin', - 'uri' => 'calendar1', - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO', 'VJOURNAL']), - ], - [ - 'id' => 'calendar2', - 'principaluri' => 'principals/admin', - 'uri' => 'calendar2', - '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VTODO', 'VJOURNAL']), - ], - ]; - - $this->calBackend = new Backend\Mock($calendars, []); - $principalBackend = new DAVACL\PrincipalBackend\Mock(); - - $tree = [ - new CalendarRoot($principalBackend, $this->calBackend), - ]; - - $this->server = new DAV\Server($tree); - $this->server->sapi = new HTTP\SapiMock(); - $this->server->debugExceptions = true; - - $plugin = new Plugin(); - $this->server->addPlugin($plugin); - - $response = new HTTP\ResponseMock(); - $this->server->httpResponse = $response; - } - - /** - * @return Sabre\HTTP\ResponseMock - */ - public function request(HTTP\Request $request) - { - $this->server->httpRequest = $request; - $this->server->exec(); - - return $this->server->httpResponse; - } - - public function testCreateFile() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics', - ]); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status); - } - - public function testCreateFileValid() - { - $request = new HTTP\Request( - 'PUT', - '/calendars/admin/calendar1/blabla.ics', - ['Prefer' => 'handling=strict'] - ); - - $ics = <<setBody($ics); - - $response = $this->request($request); - - $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.md5($ics).'"'], - ], $response->getHeaders()); - - $expected = [ - 'uri' => 'blabla.ics', - 'calendardata' => $ics, - 'calendarid' => 'calendar1', - 'lastmodified' => null, - ]; - - $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1', 'blabla.ics')); - } - - public function testCreateFileNoVersion() - { - $request = new HTTP\Request( - 'PUT', - '/calendars/admin/calendar1/blabla.ics', - ['Prefer' => 'handling=strict'] - ); - - $ics = <<setBody($ics); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testCreateFileNoVersionFixed() - { - $request = new HTTP\Request( - 'PUT', - '/calendars/admin/calendar1/blabla.ics', - ['Prefer' => 'handling=lenient'] - ); - - $ics = <<setBody($ics); - - $response = $this->request($request); - - $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - 'X-Sabre-Ew-Gross' => ['iCalendar validation warning: VERSION MUST appear exactly once in a VCALENDAR component'], - ], $response->getHeaders()); - - $ics = << 'blabla.ics', - 'calendardata' => $ics, - 'calendarid' => 'calendar1', - 'lastmodified' => null, - ]; - - $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1', 'blabla.ics')); - } - - public function testCreateFileNoComponents() - { - $request = new HTTP\Request( - 'PUT', - '/calendars/admin/calendar1/blabla.ics', - ['Prefer' => 'handling=strict'] - ); - $ics = <<setBody($ics); - - $response = $this->request($request); - $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testCreateFileNoUID() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics', - ]); - $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testCreateFileVCard() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics', - ]); - $request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n"); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testCreateFile2Components() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics', - ]); - $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VJOURNAL\r\nUID:foo\r\nEND:VJOURNAL\r\nEND:VCALENDAR\r\n"); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testCreateFile2UIDS() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics', - ]); - $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:bar\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testCreateFileWrongComponent() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics', - ]); - $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VFREEBUSY\r\nUID:foo\r\nEND:VFREEBUSY\r\nEND:VCALENDAR\r\n"); - - $response = $this->request($request); - - $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testUpdateFile() - { - $this->calBackend->createCalendarObject('calendar1', 'blabla.ics', 'foo'); - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics', - ]); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status); - } - - public function testUpdateFileParsableBody() - { - $this->calBackend->createCalendarObject('calendar1', 'blabla.ics', 'foo'); - $request = new HTTP\Request( - 'PUT', - '/calendars/admin/calendar1/blabla.ics' - ); - $ics = <<setBody($ics); - $response = $this->request($request); - - $this->assertEquals(204, $response->status); - - $expected = [ - 'uri' => 'blabla.ics', - 'calendardata' => $ics, - 'calendarid' => 'calendar1', - 'lastmodified' => null, - ]; - - $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1', 'blabla.ics')); - } - - public function testCreateFileInvalidComponent() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics', - ]); - $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $response = $this->request($request); - - $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testUpdateFileInvalidComponent() - { - $this->calBackend->createCalendarObject('calendar2', 'blabla.ics', 'foo'); - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics', - ]); - $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); - - $response = $this->request($request); - - $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - /** - * What we are testing here, is if we send in a latin1 character, the - * server should automatically transform this into UTF-8. - * - * More importantly. If any transformation happens, the etag must no longer - * be returned by the server. - */ - public function testCreateFileModified() - { - $request = new HTTP\Request( - 'PUT', - '/calendars/admin/calendar1/blabla.ics' - ); - $ics = <<setBody($ics); - - $response = $this->request($request); - - $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - $this->assertNull($response->getHeader('ETag')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php deleted file mode 100644 index 6565fc459..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php +++ /dev/null @@ -1,43 +0,0 @@ -backend = new Backend\Mock(); - $principalBackend = new DAVACL\PrincipalBackend\Mock(); - - $tree = [ - new AddressBookRoot($principalBackend, $this->backend), - new DAVACL\PrincipalCollection($principalBackend), - ]; - - $this->plugin = new Plugin(); - $this->plugin->directories = ['directory']; - $this->server = new DAV\Server($tree); - $this->server->sapi = new HTTP\SapiMock(); - $this->server->addPlugin($this->plugin); - $this->server->debugExceptions = true; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php deleted file mode 100644 index a86d85144..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php +++ /dev/null @@ -1,351 +0,0 @@ - '1'] - ); - - $request->setBody( -' - - - - - - - -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $this->assertEquals([ - '/addressbooks/user1/book1/card1' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD").'"', - ], - ], - '/addressbooks/user1/book1/card2' => [ - 404 => [ - '{DAV:}getetag' => null, - ], - ], - ], $result); - } - - public function testQueryDepth0() - { - $request = new HTTP\Request( - 'REPORT', - '/addressbooks/user1/book1/card1', - ['Depth' => '0'] - ); - - $request->setBody( -' - - - - - - - -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $this->assertEquals([ - '/addressbooks/user1/book1/card1' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD").'"', - ], - ], - ], $result); - } - - public function testQueryNoMatch() - { - $request = new HTTP\Request( - 'REPORT', - '/addressbooks/user1/book1', - ['Depth' => '1'] - ); - - $request->setBody( -' - - - - - - - -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $this->assertEquals([], $result); - } - - public function testQueryLimit() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'REQUEST_URI' => '/addressbooks/user1/book1', - 'HTTP_DEPTH' => '1', - ]); - - $request->setBody( -' - - - - - - - - 1 -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $this->assertEquals([ - '/addressbooks/user1/book1/card1' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD").'"', - ], - ], - ], $result); - } - - public function testJson() - { - $request = new HTTP\Request( - 'REPORT', - '/addressbooks/user1/book1/card1', - ['Depth' => '0'] - ); - - $request->setBody( -' - - - - - -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $vobjVersion = \Sabre\VObject\Version::VERSION; - - $this->assertEquals([ - '/addressbooks/user1/book1/card1' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD").'"', - '{urn:ietf:params:xml:ns:carddav}address-data' => '["vcard",[["version",{},"text","4.0"],["prodid",{},"text","-\/\/Sabre\/\/Sabre VObject '.$vobjVersion.'\/\/EN"],["uid",{},"text","12345"]]]', - ], - ], - ], $result); - } - - public function testVCard4() - { - $request = new HTTP\Request( - 'REPORT', - '/addressbooks/user1/book1/card1', - ['Depth' => '0'] - ); - - $request->setBody( -' - - - - - -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $vobjVersion = \Sabre\VObject\Version::VERSION; - - $this->assertEquals([ - '/addressbooks/user1/book1/card1' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD").'"', - '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\r\nVERSION:4.0\r\nPRODID:-//Sabre//Sabre VObject $vobjVersion//EN\r\nUID:12345\r\nEND:VCARD\r\n", - ], - ], - ], $result); - } - - public function testAddressBookDepth0() - { - $request = new HTTP\Request( - 'REPORT', - '/addressbooks/user1/book1', - ['Depth' => '0'] - ); - - $request->setBody( - ' - - - - - -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $this->assertEquals(415, $response->status, 'Incorrect status code. Full response body:'.$response->getBodyAsString()); - } - - public function testAddressBookProperties() - { - $request = new HTTP\Request( - 'REPORT', - '/addressbooks/user1/book3', - ['Depth' => '1'] - ); - - $request->setBody( - ' - - - - - - - - -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $this->assertEquals([ - '/addressbooks/user1/book3/card3' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nFN:Test-Card\nEMAIL;TYPE=home:bar@example.org\nEND:VCARD").'"', - '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\r\nVERSION:3.0\r\nUID:12345\r\nFN:Test-Card\r\nEND:VCARD\r\n", - ], - ], - ], $result); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php deleted file mode 100644 index c4aff2712..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookRootTest.php +++ /dev/null @@ -1,31 +0,0 @@ -assertEquals('addressbooks', $root->getName()); - } - - public function testGetChildForPrincipal() - { - $pBackend = new DAVACL\PrincipalBackend\Mock(); - $cBackend = new Backend\Mock(); - $root = new AddressBookRoot($pBackend, $cBackend); - - $children = $root->getChildren(); - $this->assertEquals(3, count($children)); - - $this->assertInstanceOf('Sabre\\CardDAV\\AddressBookHome', $children[0]); - $this->assertEquals('user1', $children[0]->getName()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php deleted file mode 100644 index e985c54ff..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php +++ /dev/null @@ -1,171 +0,0 @@ -backend = new Backend\Mock(); - $this->ab = new AddressBook( - $this->backend, - [ - 'uri' => 'book1', - 'id' => 'foo', - '{DAV:}displayname' => 'd-name', - 'principaluri' => 'principals/user1', - ] - ); - } - - public function testGetName() - { - $this->assertEquals('book1', $this->ab->getName()); - } - - public function testGetChild() - { - $card = $this->ab->getChild('card1'); - $this->assertInstanceOf('Sabre\\CardDAV\\Card', $card); - $this->assertEquals('card1', $card->getName()); - } - - public function testGetChildNotFound() - { - $this->expectException('Sabre\DAV\Exception\NotFound'); - $card = $this->ab->getChild('card3'); - } - - public function testGetChildren() - { - $cards = $this->ab->getChildren(); - $this->assertEquals(2, count($cards)); - - $this->assertEquals('card1', $cards[0]->getName()); - $this->assertEquals('card2', $cards[1]->getName()); - } - - public function testCreateDirectory() - { - $this->expectException('Sabre\DAV\Exception\MethodNotAllowed'); - $this->ab->createDirectory('name'); - } - - public function testCreateFile() - { - $file = fopen('php://memory', 'r+'); - fwrite($file, 'foo'); - rewind($file); - $this->ab->createFile('card2', $file); - - $this->assertEquals('foo', $this->backend->cards['foo']['card2']); - } - - public function testDelete() - { - $this->ab->delete(); - $this->assertEquals(1, count($this->backend->addressBooks)); - } - - public function testSetName() - { - $this->expectException('Sabre\DAV\Exception\MethodNotAllowed'); - $this->ab->setName('foo'); - } - - public function testGetLastModified() - { - $this->assertNull($this->ab->getLastModified()); - } - - public function testUpdateProperties() - { - $propPatch = new PropPatch([ - '{DAV:}displayname' => 'barrr', - ]); - $this->ab->propPatch($propPatch); - $this->assertTrue($propPatch->commit()); - - $this->assertEquals('barrr', $this->backend->addressBooks[0]['{DAV:}displayname']); - } - - public function testGetProperties() - { - $props = $this->ab->getProperties(['{DAV:}displayname']); - $this->assertEquals([ - '{DAV:}displayname' => 'd-name', - ], $props); - } - - public function testACLMethods() - { - $this->assertEquals('principals/user1', $this->ab->getOwner()); - $this->assertNull($this->ab->getGroup()); - $this->assertEquals([ - [ - 'privilege' => '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - ], $this->ab->getACL()); - } - - public function testSetACL() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $this->ab->setACL([]); - } - - public function testGetSupportedPrivilegeSet() - { - $this->assertNull( - $this->ab->getSupportedPrivilegeSet() - ); - } - - public function testGetSyncTokenNoSyncSupport() - { - $this->assertNull($this->ab->getSyncToken()); - } - - public function testGetChangesNoSyncSupport() - { - $this->assertNull($this->ab->getChanges(1, null)); - } - - public function testGetSyncToken() - { - $this->driver = 'sqlite'; - $this->dropTables(['addressbooks', 'cards', 'addressbookchanges']); - $this->createSchema('addressbooks'); - $backend = new Backend\PDO( - $this->getPDO() - ); - $ab = new AddressBook($backend, ['id' => 1, '{DAV:}sync-token' => 2]); - $this->assertEquals(2, $ab->getSyncToken()); - } - - public function testGetSyncToken2() - { - $this->driver = 'sqlite'; - $this->dropTables(['addressbooks', 'cards', 'addressbookchanges']); - $this->createSchema('addressbooks'); - $backend = new Backend\PDO( - $this->getPDO() - ); - $ab = new AddressBook($backend, ['id' => 1, '{http://sabredav.org/ns}sync-token' => 2]); - $this->assertEquals(2, $ab->getSyncToken()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php deleted file mode 100644 index bac3b2b22..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php +++ /dev/null @@ -1,351 +0,0 @@ -dropTables([ - 'addressbooks', - 'cards', - 'addressbookchanges', - ]); - $this->createSchema('addressbooks'); - $pdo = $this->getPDO(); - - $this->backend = new PDO($pdo); - $pdo->exec("INSERT INTO addressbooks (principaluri, displayname, uri, description, synctoken) VALUES ('principals/user1', 'book1', 'book1', 'addressbook 1', 1)"); - $pdo->exec("INSERT INTO cards (addressbookid, carddata, uri, lastmodified, etag, size) VALUES (1, 'card1', 'card1', 0, '".md5('card1')."', 5)"); - } - - public function testGetAddressBooksForUser() - { - $result = $this->backend->getAddressBooksForUser('principals/user1'); - - $expected = [ - [ - 'id' => 1, - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'book1', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'addressbook 1', - '{http://calendarserver.org/ns/}getctag' => 1, - '{http://sabredav.org/ns}sync-token' => 1, - ], - ]; - - $this->assertEquals($expected, $result); - } - - public function testUpdateAddressBookInvalidProp() - { - $propPatch = new PropPatch([ - '{DAV:}displayname' => 'updated', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'updated', - '{DAV:}foo' => 'bar', - ]); - - $this->backend->updateAddressBook(1, $propPatch); - $result = $propPatch->commit(); - - $this->assertFalse($result); - - $result = $this->backend->getAddressBooksForUser('principals/user1'); - - $expected = [ - [ - 'id' => 1, - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'book1', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'addressbook 1', - '{http://calendarserver.org/ns/}getctag' => 1, - '{http://sabredav.org/ns}sync-token' => 1, - ], - ]; - - $this->assertEquals($expected, $result); - } - - public function testUpdateAddressBookNoProps() - { - $propPatch = new PropPatch([ - ]); - - $this->backend->updateAddressBook(1, $propPatch); - $result = $propPatch->commit(); - $this->assertTrue($result); - - $result = $this->backend->getAddressBooksForUser('principals/user1'); - - $expected = [ - [ - 'id' => 1, - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'book1', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'addressbook 1', - '{http://calendarserver.org/ns/}getctag' => 1, - '{http://sabredav.org/ns}sync-token' => 1, - ], - ]; - - $this->assertEquals($expected, $result); - } - - public function testUpdateAddressBookSuccess() - { - $propPatch = new PropPatch([ - '{DAV:}displayname' => 'updated', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'updated', - ]); - - $this->backend->updateAddressBook(1, $propPatch); - $result = $propPatch->commit(); - - $this->assertTrue($result); - - $result = $this->backend->getAddressBooksForUser('principals/user1'); - - $expected = [ - [ - 'id' => 1, - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'updated', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'updated', - '{http://calendarserver.org/ns/}getctag' => 2, - '{http://sabredav.org/ns}sync-token' => 2, - ], - ]; - - $this->assertEquals($expected, $result); - } - - public function testDeleteAddressBook() - { - $this->backend->deleteAddressBook(1); - - $this->assertEquals([], $this->backend->getAddressBooksForUser('principals/user1')); - } - - public function testCreateAddressBookUnsupportedProp() - { - $this->expectException('Sabre\DAV\Exception\BadRequest'); - $this->backend->createAddressBook('principals/user1', 'book2', [ - '{DAV:}foo' => 'bar', - ]); - } - - public function testCreateAddressBookSuccess() - { - $this->backend->createAddressBook('principals/user1', 'book2', [ - '{DAV:}displayname' => 'book2', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'addressbook 2', - ]); - - $expected = [ - [ - 'id' => 1, - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'book1', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'addressbook 1', - '{http://calendarserver.org/ns/}getctag' => 1, - '{http://sabredav.org/ns}sync-token' => 1, - ], - [ - 'id' => 2, - 'uri' => 'book2', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'book2', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => 'addressbook 2', - '{http://calendarserver.org/ns/}getctag' => 1, - '{http://sabredav.org/ns}sync-token' => 1, - ], - ]; - $result = $this->backend->getAddressBooksForUser('principals/user1'); - $this->assertEquals($expected, $result); - } - - public function testGetCards() - { - $result = $this->backend->getCards(1); - - $expected = [ - [ - 'id' => 1, - 'uri' => 'card1', - 'lastmodified' => 0, - 'etag' => '"'.md5('card1').'"', - 'size' => 5, - ], - ]; - - $this->assertEquals($expected, $result); - } - - public function testGetCard() - { - $result = $this->backend->getCard(1, 'card1'); - - $expected = [ - 'id' => 1, - 'uri' => 'card1', - 'carddata' => 'card1', - 'lastmodified' => 0, - 'etag' => '"'.md5('card1').'"', - 'size' => 5, - ]; - - if (is_resource($result['carddata'])) { - $result['carddata'] = stream_get_contents($result['carddata']); - } - - $this->assertEquals($expected, $result); - } - - /** - * @depends testGetCard - */ - public function testCreateCard() - { - $result = $this->backend->createCard(1, 'card2', 'data2'); - $this->assertEquals('"'.md5('data2').'"', $result); - $result = $this->backend->getCard(1, 'card2'); - $this->assertEquals(2, $result['id']); - $this->assertEquals('card2', $result['uri']); - if (is_resource($result['carddata'])) { - $result['carddata'] = stream_get_contents($result['carddata']); - } - $this->assertEquals('data2', $result['carddata']); - } - - /** - * @depends testCreateCard - */ - public function testGetMultiple() - { - $result = $this->backend->createCard(1, 'card2', 'data2'); - $result = $this->backend->createCard(1, 'card3', 'data3'); - $check = [ - [ - 'id' => 1, - 'uri' => 'card1', - 'carddata' => 'card1', - 'lastmodified' => 0, - ], - [ - 'id' => 2, - 'uri' => 'card2', - 'carddata' => 'data2', - 'lastmodified' => time(), - ], - [ - 'id' => 3, - 'uri' => 'card3', - 'carddata' => 'data3', - 'lastmodified' => time(), - ], - ]; - - $result = $this->backend->getMultipleCards(1, ['card1', 'card2', 'card3']); - - foreach ($check as $index => $node) { - foreach ($node as $k => $v) { - $expected = $v; - $actual = $result[$index][$k]; - - switch ($k) { - case 'lastmodified': - $this->assertIsInt($actual); - break; - case 'carddata': - if (is_resource($actual)) { - $actual = stream_get_contents($actual); - } - // no break intended. - default: - $this->assertEquals($expected, $actual); - break; - } - } - } - } - - /** - * @depends testGetCard - */ - public function testUpdateCard() - { - $result = $this->backend->updateCard(1, 'card1', 'newdata'); - $this->assertEquals('"'.md5('newdata').'"', $result); - - $result = $this->backend->getCard(1, 'card1'); - $this->assertEquals(1, $result['id']); - if (is_resource($result['carddata'])) { - $result['carddata'] = stream_get_contents($result['carddata']); - } - $this->assertEquals('newdata', $result['carddata']); - } - - /** - * @depends testGetCard - */ - public function testDeleteCard() - { - $this->backend->deleteCard(1, 'card1'); - $result = $this->backend->getCard(1, 'card1'); - $this->assertFalse($result); - } - - public function testGetChanges() - { - $backend = $this->backend; - $id = $backend->createAddressBook( - 'principals/user1', - 'bla', - [] - ); - $result = $backend->getChangesForAddressBook($id, null, 1); - - $this->assertEquals([ - 'syncToken' => 1, - 'added' => [], - 'modified' => [], - 'deleted' => [], - ], $result); - - $currentToken = $result['syncToken']; - - $dummyCard = "BEGIN:VCARD\r\nEND:VCARD\r\n"; - - $backend->createCard($id, 'card1.ics', $dummyCard); - $backend->createCard($id, 'card2.ics', $dummyCard); - $backend->createCard($id, 'card3.ics', $dummyCard); - $backend->updateCard($id, 'card1.ics', $dummyCard); - $backend->deleteCard($id, 'card2.ics'); - - $result = $backend->getChangesForAddressBook($id, $currentToken, 1); - - $this->assertEquals([ - 'syncToken' => 6, - 'modified' => ['card1.ics'], - 'deleted' => ['card2.ics'], - 'added' => ['card3.ics'], - ], $result); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php deleted file mode 100644 index 630465cc8..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php +++ /dev/null @@ -1,257 +0,0 @@ -addressBooks = $addressBooks; - $this->cards = $cards; - - if (is_null($this->addressBooks)) { - $this->addressBooks = [ - [ - 'id' => 'foo', - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'd-name', - ], - [ - 'id' => 'bar', - 'uri' => 'book3', - 'principaluri' => 'principals/user1', - '{DAV:}displayname' => 'd-name', - ], - ]; - - $card2 = fopen('php://memory', 'r+'); - fwrite($card2, "BEGIN:VCARD\nVERSION:3.0\nUID:45678\nEND:VCARD"); - rewind($card2); - $this->cards = [ - 'foo' => [ - 'card1' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", - 'card2' => $card2, - ], - 'bar' => [ - 'card3' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nFN:Test-Card\nEMAIL;TYPE=home:bar@example.org\nEND:VCARD", - ], - ]; - } - } - - public function getAddressBooksForUser($principalUri) - { - $books = []; - foreach ($this->addressBooks as $book) { - if ($book['principaluri'] === $principalUri) { - $books[] = $book; - } - } - - return $books; - } - - /** - * Updates properties for an address book. - * - * The list of mutations is stored in a Sabre\DAV\PropPatch object. - * To do the actual updates, you must tell this object which properties - * you're going to process with the handle() method. - * - * Calling the handle method is like telling the PropPatch object "I - * promise I can handle updating this property". - * - * Read the PropPatch documentation for more info and examples. - * - * @param string $addressBookId - */ - public function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) - { - foreach ($this->addressBooks as &$book) { - if ($book['id'] !== $addressBookId) { - continue; - } - - $propPatch->handleRemaining(function ($mutations) use (&$book) { - foreach ($mutations as $key => $value) { - $book[$key] = $value; - } - - return true; - }); - } - } - - public function createAddressBook($principalUri, $url, array $properties) - { - $this->addressBooks[] = array_merge($properties, [ - 'id' => $url, - 'uri' => $url, - 'principaluri' => $principalUri, - ]); - } - - public function deleteAddressBook($addressBookId) - { - foreach ($this->addressBooks as $key => $value) { - if ($value['id'] === $addressBookId) { - unset($this->addressBooks[$key]); - } - } - unset($this->cards[$addressBookId]); - } - - /** - * Returns all cards for a specific addressbook id. - * - * This method should return the following properties for each card: - * * carddata - raw vcard data - * * uri - Some unique url - * * lastmodified - A unix timestamp - * - * It's recommended to also return the following properties: - * * etag - A unique etag. This must change every time the card changes. - * * size - The size of the card in bytes. - * - * If these last two properties are provided, less time will be spent - * calculating them. If they are specified, you can also ommit carddata. - * This may speed up certain requests, especially with large cards. - * - * @param mixed $addressBookId - * - * @return array - */ - public function getCards($addressBookId) - { - $cards = []; - foreach ($this->cards[$addressBookId] as $uri => $data) { - if (is_resource($data)) { - $cards[] = [ - 'uri' => $uri, - 'carddata' => $data, - ]; - } else { - $cards[] = [ - 'uri' => $uri, - 'carddata' => $data, - 'etag' => '"'.md5($data).'"', - 'size' => strlen($data), - ]; - } - } - - return $cards; - } - - /** - * Returns a specfic card. - * - * The same set of properties must be returned as with getCards. The only - * exception is that 'carddata' is absolutely required. - * - * If the card does not exist, you must return false. - * - * @param mixed $addressBookId - * @param string $cardUri - * - * @return array - */ - public function getCard($addressBookId, $cardUri) - { - if (!isset($this->cards[$addressBookId][$cardUri])) { - return false; - } - - $data = $this->cards[$addressBookId][$cardUri]; - - return [ - 'uri' => $cardUri, - 'carddata' => $data, - 'etag' => '"'.md5($data).'"', - 'size' => strlen($data), - ]; - } - - /** - * Creates a new card. - * - * The addressbook id will be passed as the first argument. This is the - * same id as it is returned from the getAddressBooksForUser method. - * - * The cardUri is a base uri, and doesn't include the full path. The - * cardData argument is the vcard body, and is passed as a string. - * - * It is possible to return an ETag from this method. This ETag is for the - * newly created resource, and must be enclosed with double quotes (that - * is, the string itself must contain the double quotes). - * - * You should only return the ETag if you store the carddata as-is. If a - * subsequent GET request on the same card does not have the same body, - * byte-by-byte and you did return an ETag here, clients tend to get - * confused. - * - * If you don't return an ETag, you can just return null. - * - * @param mixed $addressBookId - * @param string $cardUri - * @param string $cardData - * - * @return string|null - */ - public function createCard($addressBookId, $cardUri, $cardData) - { - if (is_resource($cardData)) { - $cardData = stream_get_contents($cardData); - } - $this->cards[$addressBookId][$cardUri] = $cardData; - - return '"'.md5($cardData).'"'; - } - - /** - * Updates a card. - * - * The addressbook id will be passed as the first argument. This is the - * same id as it is returned from the getAddressBooksForUser method. - * - * The cardUri is a base uri, and doesn't include the full path. The - * cardData argument is the vcard body, and is passed as a string. - * - * It is possible to return an ETag from this method. This ETag should - * match that of the updated resource, and must be enclosed with double - * quotes (that is: the string itself must contain the actual quotes). - * - * You should only return the ETag if you store the carddata as-is. If a - * subsequent GET request on the same card does not have the same body, - * byte-by-byte and you did return an ETag here, clients tend to get - * confused. - * - * If you don't return an ETag, you can just return null. - * - * @param mixed $addressBookId - * @param string $cardUri - * @param string $cardData - * - * @return string|null - */ - public function updateCard($addressBookId, $cardUri, $cardData) - { - if (is_resource($cardData)) { - $cardData = stream_get_contents($cardData); - } - $this->cards[$addressBookId][$cardUri] = $cardData; - - return '"'.md5($cardData).'"'; - } - - public function deleteCard($addressBookId, $cardUri) - { - unset($this->cards[$addressBookId][$cardUri]); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php deleted file mode 100644 index 718eec6be..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php +++ /dev/null @@ -1,10 +0,0 @@ -backend = new Backend\Mock(); - $this->card = new Card( - $this->backend, - [ - 'uri' => 'book1', - 'id' => 'foo', - 'principaluri' => 'principals/user1', - ], - [ - 'uri' => 'card1', - 'addressbookid' => 'foo', - 'carddata' => 'card', - ] - ); - } - - public function testGet() - { - $result = $this->card->get(); - $this->assertEquals('card', $result); - } - - public function testGet2() - { - $this->card = new Card( - $this->backend, - [ - 'uri' => 'book1', - 'id' => 'foo', - 'principaluri' => 'principals/user1', - ], - [ - 'uri' => 'card1', - 'addressbookid' => 'foo', - ] - ); - $result = $this->card->get(); - $this->assertEquals("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", $result); - } - - /** - * @depends testGet - */ - public function testPut() - { - $file = fopen('php://memory', 'r+'); - fwrite($file, 'newdata'); - rewind($file); - $this->card->put($file); - $result = $this->card->get(); - $this->assertEquals('newdata', $result); - } - - public function testDelete() - { - $this->card->delete(); - $this->assertEquals(1, count($this->backend->cards['foo'])); - } - - public function testGetContentType() - { - $this->assertEquals('text/vcard; charset=utf-8', $this->card->getContentType()); - } - - public function testGetETag() - { - $this->assertEquals('"'.md5('card').'"', $this->card->getETag()); - } - - public function testGetETag2() - { - $card = new Card( - $this->backend, - [ - 'uri' => 'book1', - 'id' => 'foo', - 'principaluri' => 'principals/user1', - ], - [ - 'uri' => 'card1', - 'addressbookid' => 'foo', - 'carddata' => 'card', - 'etag' => '"blabla"', - ] - ); - $this->assertEquals('"blabla"', $card->getETag()); - } - - public function testGetLastModified() - { - $this->assertEquals(null, $this->card->getLastModified()); - } - - public function testGetSize() - { - $this->assertEquals(4, $this->card->getSize()); - $this->assertEquals(4, $this->card->getSize()); - } - - public function testGetSize2() - { - $card = new Card( - $this->backend, - [ - 'uri' => 'book1', - 'id' => 'foo', - 'principaluri' => 'principals/user1', - ], - [ - 'uri' => 'card1', - 'addressbookid' => 'foo', - 'etag' => '"blabla"', - 'size' => 4, - ] - ); - $this->assertEquals(4, $card->getSize()); - } - - public function testACLMethods() - { - $this->assertEquals('principals/user1', $this->card->getOwner()); - $this->assertNull($this->card->getGroup()); - $this->assertEquals([ - [ - 'privilege' => '{DAV:}all', - 'principal' => 'principals/user1', - 'protected' => true, - ], - ], $this->card->getACL()); - } - - public function testOverrideACL() - { - $card = new Card( - $this->backend, - [ - 'uri' => 'book1', - 'id' => 'foo', - 'principaluri' => 'principals/user1', - ], - [ - 'uri' => 'card1', - 'addressbookid' => 'foo', - 'carddata' => 'card', - 'acl' => [ - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1', - 'protected' => true, - ], - ], - ] - ); - $this->assertEquals([ - [ - 'privilege' => '{DAV:}read', - 'principal' => 'principals/user1', - 'protected' => true, - ], - ], $card->getACL()); - } - - public function testSetACL() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $this->card->setACL([]); - } - - public function testGetSupportedPrivilegeSet() - { - $this->assertNull( - $this->card->getSupportedPrivilegeSet() - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php deleted file mode 100644 index 760749f6c..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php +++ /dev/null @@ -1,28 +0,0 @@ -addPlugin($plugin); - - $props = $server->getProperties('directory', ['{DAV:}resourcetype']); - $this->assertTrue($props['{DAV:}resourcetype']->is('{'.Plugin::NS_CARDDAV.'}directory')); - } -} - -class DirectoryMock extends DAV\SimpleCollection implements IDirectory -{ -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php deleted file mode 100644 index ac0cd5e91..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php +++ /dev/null @@ -1,99 +0,0 @@ - 'REPORT', - 'REQUEST_URI' => '/addressbooks/user1/book1', - ]); - - $request->setBody( -' - - - - - - /addressbooks/user1/book1/card1 -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $this->assertEquals([ - '/addressbooks/user1/book1/card1' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD").'"', - '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", - ], - ], - ], $result); - } - - public function testMultiGetVCard4() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'REPORT', - 'REQUEST_URI' => '/addressbooks/user1/book1', - ]); - - $request->setBody( -' - - - - - - /addressbooks/user1/book1/card1 -' - ); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $bodyAsString = $response->getBodyAsString(); - $this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:'.$bodyAsString); - - // using the client for parsing - $client = new DAV\Client(['baseUri' => '/']); - - $result = $client->parseMultiStatus($bodyAsString); - - $prodId = 'PRODID:-//Sabre//Sabre VObject '.\Sabre\VObject\Version::VERSION.'//EN'; - - $this->assertEquals([ - '/addressbooks/user1/book1/card1' => [ - 200 => [ - '{DAV:}getetag' => '"'.md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD").'"', - '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\r\nVERSION:4.0\r\n$prodId\r\nUID:12345\r\nEND:VCARD\r\n", - ], - ], - ], $result); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php deleted file mode 100644 index b5a68dc48..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php +++ /dev/null @@ -1,101 +0,0 @@ -assertEquals('{'.Plugin::NS_CARDDAV.'}addressbook', $this->server->resourceTypeMapping['Sabre\\CardDAV\\IAddressBook']); - - $this->assertTrue(in_array('addressbook', $this->plugin->getFeatures())); - $this->assertEquals('carddav', $this->plugin->getPluginInfo()['name']); - } - - public function testSupportedReportSet() - { - $this->assertEquals([ - '{'.Plugin::NS_CARDDAV.'}addressbook-multiget', - '{'.Plugin::NS_CARDDAV.'}addressbook-query', - ], $this->plugin->getSupportedReportSet('addressbooks/user1/book1')); - } - - public function testSupportedReportSetEmpty() - { - $this->assertEquals([ - ], $this->plugin->getSupportedReportSet('')); - } - - public function testAddressBookHomeSet() - { - $result = $this->server->getProperties('principals/user1', ['{'.Plugin::NS_CARDDAV.'}addressbook-home-set']); - - $this->assertEquals(1, count($result)); - $this->assertTrue(isset($result['{'.Plugin::NS_CARDDAV.'}addressbook-home-set'])); - $this->assertEquals('addressbooks/user1/', $result['{'.Plugin::NS_CARDDAV.'}addressbook-home-set']->getHref()); - } - - public function testDirectoryGateway() - { - $result = $this->server->getProperties('principals/user1', ['{'.Plugin::NS_CARDDAV.'}directory-gateway']); - - $this->assertEquals(1, count($result)); - $this->assertTrue(isset($result['{'.Plugin::NS_CARDDAV.'}directory-gateway'])); - $this->assertEquals(['directory'], $result['{'.Plugin::NS_CARDDAV.'}directory-gateway']->getHrefs()); - } - - public function testReportPassThrough() - { - $this->assertNull($this->plugin->report('{DAV:}foo', new \DomDocument(), '')); - } - - public function testHTMLActionsPanel() - { - $output = ''; - $r = $this->server->emit('onHTMLActionsPanel', [$this->server->tree->getNodeForPath('addressbooks/user1'), &$output]); - $this->assertFalse($r); - - $this->assertTrue((bool) strpos($output, 'Display name')); - } - - public function testAddressbookPluginProperties() - { - $ns = '{'.Plugin::NS_CARDDAV.'}'; - $propFind = new DAV\PropFind('addressbooks/user1/book1', [ - $ns.'supported-address-data', - $ns.'supported-collation-set', - ]); - $node = $this->server->tree->getNodeForPath('addressbooks/user1/book1'); - $this->plugin->propFindEarly($propFind, $node); - - $this->assertInstanceOf( - 'Sabre\\CardDAV\\Xml\\Property\\SupportedAddressData', - $propFind->get($ns.'supported-address-data') - ); - $this->assertInstanceOf( - 'Sabre\\CardDAV\\Xml\\Property\\SupportedCollationSet', - $propFind->get($ns.'supported-collation-set') - ); - } - - public function testGetTransform() - { - $request = new \Sabre\HTTP\Request('GET', '/addressbooks/user1/book1/card1', ['Accept' => 'application/vcard+json']); - $response = new \Sabre\HTTP\ResponseMock(); - $this->server->invokeMethod($request, $response); - - $this->assertEquals(200, $response->getStatus()); - } - - public function testGetWithoutContentType() - { - $request = new \Sabre\HTTP\Request('GET', '/'); - $response = new \Sabre\HTTP\ResponseMock(); - $this->plugin->httpAfterGet($request, $response); - $this->assertTrue(true); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php deleted file mode 100644 index 8d045569c..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php +++ /dev/null @@ -1,67 +0,0 @@ - 1, - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - ], - ]; - protected $carddavCards = [ - 1 => [ - 'card1.vcf' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", - ], - ]; - - public function testDontStrip() - { - $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf', ['{DAV:}getcontenttype']); - $this->assertEquals([ - '{DAV:}getcontenttype' => 'text/vcard; charset=utf-8', - ], $result); - } - - public function testStrip() - { - $this->server->httpRequest = new HTTP\Request('GET', '/', [ - 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 Lightning/1.2.1', - ]); - $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf', ['{DAV:}getcontenttype']); - $this->assertEquals([ - '{DAV:}getcontenttype' => 'text/x-vcard', - ], $result); - } - - public function testDontTouchOtherMimeTypes() - { - $this->server->httpRequest = new HTTP\Request('GET', '/addressbooks/user1/book1/card1.vcf', [ - 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 Lightning/1.2.1', - ]); - - $propFind = new PropFind('hello', ['{DAV:}getcontenttype']); - $propFind->set('{DAV:}getcontenttype', 'text/plain'); - $this->carddavPlugin->propFindLate($propFind, new \Sabre\DAV\SimpleCollection('foo')); - $this->assertEquals('text/plain', $propFind->get('{DAV:}getcontenttype')); - } - - public function testStripWithoutGetContentType() - { - $this->server->httpRequest = new HTTP\Request('GET', '/addressbooks/user1/book1/card1.vcf', [ - 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 Lightning/1.2.1', - ]); - - $propFind = new PropFind('hello', ['{DAV:}getcontenttype']); - $this->carddavPlugin->propFindLate($propFind, new \Sabre\DAV\SimpleCollection('foo')); - $this->assertEquals(null, $propFind->get('{DAV:}getcontenttype')); // Property not present - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php deleted file mode 100644 index 546a4ccfb..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php +++ /dev/null @@ -1,130 +0,0 @@ - 'book1', - 'uri' => 'book1', - 'principaluri' => 'principals/user1', - ], - ]; - protected $carddavCards = [ - 'book1' => [ - 'card1' => "BEGIN:VCARD\r\nFN:Person1\r\nEND:VCARD\r\n", - 'card2' => "BEGIN:VCARD\r\nFN:Person2\r\nEND:VCARD", - 'card3' => "BEGIN:VCARD\r\nFN:Person3\r\nEND:VCARD\r\n", - 'card4' => "BEGIN:VCARD\nFN:Person4\nEND:VCARD\n", - ], - ]; - - public function setup(): void - { - parent::setUp(); - $plugin = new VCFExportPlugin(); - $this->server->addPlugin( - $plugin - ); - } - - public function testSimple() - { - $plugin = $this->server->getPlugin('vcf-export'); - $this->assertInstanceOf('Sabre\\CardDAV\\VCFExportPlugin', $plugin); - - $this->assertEquals( - 'vcf-export', - $plugin->getPluginInfo()['name'] - ); - } - - public function testExport() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_URI' => '/addressbooks/user1/book1?export', - 'QUERY_STRING' => 'export', - 'REQUEST_METHOD' => 'GET', - ]); - - $response = $this->request($request); - $this->assertEquals(200, $response->status, $response->getBodyAsString()); - - $expected = 'BEGIN:VCARD -FN:Person1 -END:VCARD -BEGIN:VCARD -FN:Person2 -END:VCARD -BEGIN:VCARD -FN:Person3 -END:VCARD -BEGIN:VCARD -FN:Person4 -END:VCARD -'; - // We actually expected windows line endings - $expected = str_replace("\n", "\r\n", $expected); - - $this->assertEquals($expected, $response->getBodyAsString()); - } - - public function testBrowserIntegration() - { - $plugin = $this->server->getPlugin('vcf-export'); - $actions = ''; - $addressbook = new AddressBook($this->carddavBackend, []); - $this->server->emit('browserButtonActions', ['/foo', $addressbook, &$actions]); - $this->assertStringContainsString('/foo?export', $actions); - } - - public function testContentDisposition() - { - $request = new HTTP\Request( - 'GET', - '/addressbooks/user1/book1?export' - ); - - $response = $this->request($request, 200); - $this->assertEquals('text/directory', $response->getHeader('Content-Type')); - $this->assertEquals( - 'attachment; filename="book1-'.date('Y-m-d').'.vcf"', - $response->getHeader('Content-Disposition') - ); - } - - public function testContentDispositionBadChars() - { - $this->carddavBackend->createAddressBook( - 'principals/user1', - 'book-b_ad"(ch)ars', - [] - ); - $this->carddavBackend->createCard( - 'book-b_ad"(ch)ars', - 'card1', - "BEGIN:VCARD\r\nFN:Person1\r\nEND:VCARD\r\n" - ); - - $request = new HTTP\Request( - 'GET', - '/addressbooks/user1/book-b_ad"(ch)ars?export' - ); - - $response = $this->request($request, 200); - $this->assertEquals('text/directory', $response->getHeader('Content-Type')); - $this->assertEquals( - 'attachment; filename="book-b_adchars-'.date('Y-m-d').'.vcf"', - $response->getHeader('Content-Disposition') - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php deleted file mode 100644 index de7de19cd..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php +++ /dev/null @@ -1,204 +0,0 @@ -assertTrue($this->plugin->validateFilters($input, $filters, $test), $message); - } else { - $this->assertFalse($this->plugin->validateFilters($input, $filters, $test), $message); - } - } - - public function data() - { - $body1 = << 'title', 'is-not-defined' => false, 'param-filters' => [], 'text-matches' => []]; - - // Check if FOO is defined - $filter2 = - ['name' => 'foo', 'is-not-defined' => false, 'param-filters' => [], 'text-matches' => []]; - - // Check if TITLE is not defined - $filter3 = - ['name' => 'title', 'is-not-defined' => true, 'param-filters' => [], 'text-matches' => []]; - - // Check if FOO is not defined - $filter4 = - ['name' => 'foo', 'is-not-defined' => true, 'param-filters' => [], 'text-matches' => []]; - - // Check if TEL[TYPE] is defined - $filter5 = - [ - 'name' => 'tel', - 'is-not-defined' => false, - 'test' => 'anyof', - 'param-filters' => [ - [ - 'name' => 'type', - 'is-not-defined' => false, - 'text-match' => null, - ], - ], - 'text-matches' => [], - ]; - - // Check if TEL[FOO] is defined - $filter6 = $filter5; - $filter6['param-filters'][0]['name'] = 'FOO'; - - // Check if TEL[TYPE] is not defined - $filter7 = $filter5; - $filter7['param-filters'][0]['is-not-defined'] = true; - - // Check if TEL[FOO] is not defined - $filter8 = $filter5; - $filter8['param-filters'][0]['name'] = 'FOO'; - $filter8['param-filters'][0]['is-not-defined'] = true; - - // Combining property filters - $filter9 = $filter5; - $filter9['param-filters'][] = $filter6['param-filters'][0]; - - $filter10 = $filter5; - $filter10['param-filters'][] = $filter6['param-filters'][0]; - $filter10['test'] = 'allof'; - - // Check if URL contains 'google' - $filter11 = - [ - 'name' => 'url', - 'is-not-defined' => false, - 'test' => 'anyof', - 'param-filters' => [], - 'text-matches' => [ - [ - 'match-type' => 'contains', - 'value' => 'google', - 'negate-condition' => false, - 'collation' => 'i;octet', - ], - ], - ]; - - // Check if URL contains 'bing' - $filter12 = $filter11; - $filter12['text-matches'][0]['value'] = 'bing'; - - // Check if URL does not contain 'google' - $filter13 = $filter11; - $filter13['text-matches'][0]['negate-condition'] = true; - - // Check if URL does not contain 'bing' - $filter14 = $filter11; - $filter14['text-matches'][0]['value'] = 'bing'; - $filter14['text-matches'][0]['negate-condition'] = true; - - // Param filter with text - $filter15 = $filter5; - $filter15['param-filters'][0]['text-match'] = [ - 'match-type' => 'contains', - 'value' => 'WORK', - 'collation' => 'i;octet', - 'negate-condition' => false, - ]; - $filter16 = $filter15; - $filter16['param-filters'][0]['text-match']['negate-condition'] = true; - - // Param filter + text filter - $filter17 = $filter5; - $filter17['test'] = 'anyof'; - $filter17['text-matches'][] = [ - 'match-type' => 'contains', - 'value' => '444', - 'collation' => 'i;octet', - 'negate-condition' => false, - ]; - - $filter18 = $filter17; - $filter18['text-matches'][0]['negate-condition'] = true; - - $filter18['test'] = 'allof'; - - return [ - // Basic filters - [$body1, [$filter1], 'anyof', true], - [$body1, [$filter2], 'anyof', false], - [$body1, [$filter3], 'anyof', false], - [$body1, [$filter4], 'anyof', true], - - // Combinations - [$body1, [$filter1, $filter2], 'anyof', true], - [$body1, [$filter1, $filter2], 'allof', false], - [$body1, [$filter1, $filter4], 'anyof', true], - [$body1, [$filter1, $filter4], 'allof', true], - [$body1, [$filter2, $filter3], 'anyof', false], - [$body1, [$filter2, $filter3], 'allof', false], - - // Basic parameters - [$body1, [$filter5], 'anyof', true, 'TEL;TYPE is defined, so this should return true'], - [$body1, [$filter6], 'anyof', false, 'TEL;FOO is not defined, so this should return false'], - - [$body1, [$filter7], 'anyof', false, 'TEL;TYPE is defined, so this should return false'], - [$body1, [$filter8], 'anyof', true, 'TEL;TYPE is not defined, so this should return true'], - - // Combined parameters - [$body1, [$filter9], 'anyof', true], - [$body1, [$filter10], 'anyof', false], - - // Text-filters - [$body1, [$filter11], 'anyof', true], - [$body1, [$filter12], 'anyof', false], - [$body1, [$filter13], 'anyof', false], - [$body1, [$filter14], 'anyof', true], - - // Param filter with text-match - [$body1, [$filter15], 'anyof', true], - [$body1, [$filter16], 'anyof', false], - - // Param filter + text filter - [$body1, [$filter17], 'anyof', true], - [$body1, [$filter18], 'anyof', false], - [$body1, [$filter18], 'anyof', false], - ]; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php deleted file mode 100644 index 571cce3f0..000000000 --- a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php +++ /dev/null @@ -1,293 +0,0 @@ - 'addressbook1', - 'principaluri' => 'principals/admin', - 'uri' => 'addressbook1', - ], - ]; - - $this->cardBackend = new Backend\Mock($addressbooks, []); - $principalBackend = new DAVACL\PrincipalBackend\Mock(); - - $tree = [ - new AddressBookRoot($principalBackend, $this->cardBackend), - ]; - - $this->server = new DAV\Server($tree); - $this->server->sapi = new HTTP\SapiMock(); - $this->server->debugExceptions = true; - - $plugin = new Plugin(); - $this->server->addPlugin($plugin); - - $response = new HTTP\ResponseMock(); - $this->server->httpResponse = $response; - } - - public function request(HTTP\Request $request, $expectedStatus = null) - { - $this->server->httpRequest = $request; - $this->server->exec(); - - if ($expectedStatus) { - $realStatus = $this->server->httpResponse->getStatus(); - - $msg = ''; - if ($realStatus !== $expectedStatus) { - $msg = 'Response body: '.$this->server->httpResponse->getBodyAsString(); - } - $this->assertEquals( - $expectedStatus, - $realStatus, - $msg - ); - } - - return $this->server->httpResponse; - } - - public function testCreateFile() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf', - ]); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status); - } - - public function testCreateFileValid() - { - $request = new HTTP\Request( - 'PUT', - '/addressbooks/admin/addressbook1/blabla.vcf' - ); - - $vcard = <<setBody($vcard); - - $response = $this->request($request, 201); - - // The custom Ew header should not be set - $this->assertNull( - $response->getHeader('X-Sabre-Ew-Gross') - ); - // Valid, non-auto-fixed responses should contain an ETag. - $this->assertTrue( - null !== $response->getHeader('ETag'), - 'We did not receive an etag' - ); - - $expected = [ - 'uri' => 'blabla.vcf', - 'carddata' => $vcard, - 'size' => strlen($vcard), - 'etag' => '"'.md5($vcard).'"', - ]; - - $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1', 'blabla.vcf')); - } - - /** - * This test creates an intentionally broken vCard that vobject is able - * to automatically repair. - * - * @depends testCreateFileValid - */ - public function testCreateVCardAutoFix() - { - $request = new HTTP\Request( - 'PUT', - '/addressbooks/admin/addressbook1/blabla.vcf' - ); - - // The error in this vcard is that there's not enough semi-colons in N - $vcard = <<setBody($vcard); - - $response = $this->request($request, 201); - - // Auto-fixed vcards should NOT return an etag - $this->assertNull( - $response->getHeader('ETag') - ); - - // We should have gotten an Ew header - $this->assertNotNull( - $response->getHeader('X-Sabre-Ew-Gross') - ); - - $expectedVCard = << 'blabla.vcf', - 'carddata' => $expectedVCard, - 'size' => strlen($expectedVCard), - 'etag' => '"'.md5($expectedVCard).'"', - ]; - - $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1', 'blabla.vcf')); - } - - /** - * This test creates an intentionally broken vCard that vobject is able - * to automatically repair. - * - * However, we're supplying a heading asking the server to treat the - * request as strict, so the server should still let the request fail. - * - * @depends testCreateFileValid - */ - public function testCreateVCardStrictFail() - { - $request = new HTTP\Request( - 'PUT', - '/addressbooks/admin/addressbook1/blabla.vcf', - [ - 'Prefer' => 'handling=strict', - ] - ); - - // The error in this vcard is that there's not enough semi-colons in N - $vcard = <<setBody($vcard); - $this->request($request, 415); - } - - public function testCreateFileNoUID() - { - $request = new HTTP\Request( - 'PUT', - '/addressbooks/admin/addressbook1/blabla.vcf' - ); - $vcard = <<setBody($vcard); - - $response = $this->request($request, 201); - - $foo = $this->cardBackend->getCard('addressbook1', 'blabla.vcf'); - $this->assertTrue( - false !== strpos($foo['carddata'], 'UID'), - print_r($foo, true) - ); - } - - public function testCreateFileJson() - { - $request = new HTTP\Request( - 'PUT', - '/addressbooks/admin/addressbook1/blabla.vcf' - ); - $request->setBody('[ "vcard" , [ [ "VERSION", {}, "text", "4.0"], [ "UID" , {}, "text", "foo" ], [ "FN", {}, "text", "FirstName LastName"] ] ]'); - - $response = $this->request($request); - - $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - - $foo = $this->cardBackend->getCard('addressbook1', 'blabla.vcf'); - $this->assertEquals("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nFN:FirstName LastName\r\nEND:VCARD\r\n", $foo['carddata']); - } - - public function testCreateFileVCalendar() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf', - ]); - $request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n"); - - $response = $this->request($request); - - $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: '.$response->getBodyAsString()); - } - - public function testUpdateFile() - { - $this->cardBackend->createCard('addressbook1', 'blabla.vcf', 'foo'); - $request = new HTTP\Request( - 'PUT', - '/addressbooks/admin/addressbook1/blabla.vcf' - ); - - $response = $this->request($request, 415); - } - - public function testUpdateFileParsableBody() - { - $this->cardBackend->createCard('addressbook1', 'blabla.vcf', 'foo'); - $request = new HTTP\Request( - 'PUT', - '/addressbooks/admin/addressbook1/blabla.vcf' - ); - - $body = "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nFN:FirstName LastName\r\nEND:VCARD\r\n"; - $request->setBody($body); - - $response = $this->request($request, 204); - - $expected = [ - 'uri' => 'blabla.vcf', - 'carddata' => $body, - 'size' => strlen($body), - 'etag' => '"'.md5($body).'"', - ]; - - $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1', 'blabla.vcf')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php b/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php deleted file mode 100644 index 49fedf062..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php +++ /dev/null @@ -1,62 +0,0 @@ -response = new HTTP\ResponseMock(); - $this->server = new Server($this->getRootNode()); - $this->server->sapi = new HTTP\SapiMock(); - $this->server->httpResponse = $this->response; - $this->server->debugExceptions = true; - $this->deleteTree(SABRE_TEMPDIR, false); - file_put_contents(SABRE_TEMPDIR.'/test.txt', 'Test contents'); - mkdir(SABRE_TEMPDIR.'/dir'); - file_put_contents(SABRE_TEMPDIR.'/dir/child.txt', 'Child contents'); - } - - public function teardown(): void - { - $this->deleteTree(SABRE_TEMPDIR, false); - } - - protected function getRootNode() - { - return new FS\Directory(SABRE_TEMPDIR); - } - - private function deleteTree($path, $deleteRoot = true) - { - foreach (scandir($path) as $node) { - if ('.' == $node || '.svn' == $node || '..' == $node) { - continue; - } - $myPath = $path.'/'.$node; - if (is_file($myPath)) { - unlink($myPath); - } else { - $this->deleteTree($myPath); - } - } - if ($deleteRoot) { - rmdir($path); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php deleted file mode 100644 index ebc1e3f7b..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php +++ /dev/null @@ -1,90 +0,0 @@ -assertFalse( - $backend->check($request, $response)[0] - ); - } - - public function testCheckUnknownUser() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'PHP_AUTH_USER' => 'username', - 'PHP_AUTH_PW' => 'wrongpassword', - ]); - $response = new HTTP\Response(); - - $backend = new AbstractBasicMock(); - - $this->assertFalse( - $backend->check($request, $response)[0] - ); - } - - public function testCheckSuccess() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'PHP_AUTH_USER' => 'username', - 'PHP_AUTH_PW' => 'password', - ]); - $response = new HTTP\Response(); - - $backend = new AbstractBasicMock(); - $this->assertEquals( - [true, 'principals/username'], - $backend->check($request, $response) - ); - } - - public function testRequireAuth() - { - $request = new HTTP\Request('GET', '/'); - $response = new HTTP\Response(); - - $backend = new AbstractBasicMock(); - $backend->setRealm('writing unittests on a saturday night'); - $backend->challenge($request, $response); - - $this->assertEquals( - 'Basic realm="writing unittests on a saturday night", charset="UTF-8"', - $response->getHeader('WWW-Authenticate') - ); - } -} - -class AbstractBasicMock extends AbstractBasic -{ - /** - * Validates a username and password. - * - * This method should return true or false depending on if login - * succeeded. - * - * @param string $username - * @param string $password - * - * @return bool - */ - public function validateUserPass($username, $password) - { - return 'username' == $username && 'password' == $password; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php deleted file mode 100644 index a751efdc2..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php +++ /dev/null @@ -1,134 +0,0 @@ -assertFalse( - $backend->check($request, $response)[0] - ); - } - - public function testCheckBadGetUserInfoResponse() - { - $header = 'username=null, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'PHP_AUTH_DIGEST' => $header, - ]); - $response = new HTTP\Response(); - - $backend = new AbstractDigestMock(); - $this->assertFalse( - $backend->check($request, $response)[0] - ); - } - - public function testCheckBadGetUserInfoResponse2() - { - $this->expectException('Sabre\DAV\Exception'); - $header = 'username=array, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'PHP_AUTH_DIGEST' => $header, - ]); - - $response = new HTTP\Response(); - - $backend = new AbstractDigestMock(); - $backend->check($request, $response); - } - - public function testCheckUnknownUser() - { - $header = 'username=false, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'PHP_AUTH_DIGEST' => $header, - ]); - - $response = new HTTP\Response(); - - $backend = new AbstractDigestMock(); - $this->assertFalse( - $backend->check($request, $response)[0] - ); - } - - public function testCheckBadPassword() - { - $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response=HASH, opaque=1, qop=auth, nc=1, cnonce=1'; - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/', - 'PHP_AUTH_DIGEST' => $header, - ]); - - $response = new HTTP\Response(); - - $backend = new AbstractDigestMock(); - $this->assertFalse( - $backend->check($request, $response)[0] - ); - } - - public function testCheck() - { - $digestHash = md5('HELLO:12345:1:1:auth:'.md5('GET:/')); - $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response='.$digestHash.', opaque=1, qop=auth, nc=1, cnonce=1'; - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'PHP_AUTH_DIGEST' => $header, - ]); - - $response = new HTTP\Response(); - - $backend = new AbstractDigestMock(); - $this->assertEquals( - [true, 'principals/user'], - $backend->check($request, $response) - ); - } - - public function testRequireAuth() - { - $request = new HTTP\Request('GET', '/'); - $response = new HTTP\Response(); - - $backend = new AbstractDigestMock(); - $backend->setRealm('writing unittests on a saturday night'); - $backend->challenge($request, $response); - - $this->assertStringStartsWith( - 'Digest realm="writing unittests on a saturday night"', - $response->getHeader('WWW-Authenticate') - ); - } -} - -class AbstractDigestMock extends AbstractDigest -{ - public function getDigestHash($realm, $userName) - { - switch ($userName) { - case 'null': return null; - case 'false': return false; - case 'array': return []; - case 'user': return 'HELLO'; - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php deleted file mode 100644 index 8b874f884..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php +++ /dev/null @@ -1,42 +0,0 @@ -dropTables('users'); - $this->createSchema('users'); - - $this->getPDO()->query( - "INSERT INTO users (username,digesta1) VALUES ('user','hash')" - ); - } - - public function testConstruct() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $this->assertTrue($backend instanceof PDO); - } - - /** - * @depends testConstruct - */ - public function testUserInfo() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - - $this->assertNull($backend->getDigestHash('realm', 'blabla')); - - $expected = 'hash'; - - $this->assertEquals($expected, $backend->getDigestHash('realm', 'user')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php deleted file mode 100644 index a0086518f..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php +++ /dev/null @@ -1,72 +0,0 @@ -assertInstanceOf('Sabre\DAV\Auth\Backend\Apache', $backend); - } - - public function testNoHeader() - { - $request = new HTTP\Request('GET', '/'); - $response = new HTTP\Response(); - $backend = new Apache(); - - $this->assertFalse( - $backend->check($request, $response)[0] - ); - } - - public function testRemoteUser() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'REMOTE_USER' => 'username', - ]); - $response = new HTTP\Response(); - $backend = new Apache(); - - $this->assertEquals( - [true, 'principals/username'], - $backend->check($request, $response) - ); - } - - public function testRedirectRemoteUser() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/', - 'REDIRECT_REMOTE_USER' => 'username', - ]); - $response = new HTTP\Response(); - $backend = new Apache(); - - $this->assertEquals( - [true, 'principals/username'], - $backend->check($request, $response) - ); - } - - public function testRequireAuth() - { - $request = new HTTP\Request('GET', '/'); - $response = new HTTP\Response(); - - $backend = new Apache(); - $backend->challenge($request, $response); - - $this->assertNull( - $response->getHeader('WWW-Authenticate') - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php deleted file mode 100644 index 31a86f9ed..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php +++ /dev/null @@ -1,38 +0,0 @@ -assertTrue($file instanceof File); - } - - public function testLoadFileBroken() - { - $this->expectException('Sabre\DAV\Exception'); - file_put_contents(SABRE_TEMPDIR.'/backend', 'user:realm:hash'); - $file = new File(SABRE_TEMPDIR.'/backend'); - } - - public function testLoadFile() - { - file_put_contents(SABRE_TEMPDIR.'/backend', 'user:realm:'.md5('user:realm:password')); - $file = new File(); - $file->loadFile(SABRE_TEMPDIR.'/backend'); - - $this->assertFalse($file->getDigestHash('realm', 'blabla')); - $this->assertEquals(md5('user:realm:password'), $file->getDigestHash('realm', 'user')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php deleted file mode 100644 index fca7f722f..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php +++ /dev/null @@ -1,81 +0,0 @@ -principal = $principal; - } - - /** - * When this method is called, the backend must check if authentication was - * successful. - * - * The returned value must be one of the following - * - * [true, "principals/username"] - * [false, "reason for failure"] - * - * If authentication was successful, it's expected that the authentication - * backend returns a so-called principal url. - * - * Examples of a principal url: - * - * principals/admin - * principals/user1 - * principals/users/joe - * principals/uid/123457 - * - * If you don't use WebDAV ACL (RFC3744) we recommend that you simply - * return a string such as: - * - * principals/users/[username] - * - * @return array - */ - public function check(RequestInterface $request, ResponseInterface $response) - { - if ($this->invalidCheckResponse) { - return 'incorrect!'; - } - if ($this->fail) { - return [false, 'fail!']; - } - - return [true, $this->principal]; - } - - /** - * This method is called when a user could not be authenticated, and - * authentication was required for the current request. - * - * This gives you the oppurtunity to set authentication headers. The 401 - * status code will already be set. - * - * In this case of Basic Auth, this would for example mean that the - * following header needs to be set: - * - * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); - * - * Keep in mind that in the case of multiple authentication backends, other - * WWW-Authenticate headers may already have been set, and you'll want to - * append your own WWW-Authenticate header instead of overwriting the - * existing one. - */ - public function challenge(RequestInterface $request, ResponseInterface $response) - { - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php deleted file mode 100644 index 6ad7906c4..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php +++ /dev/null @@ -1,10 +0,0 @@ -assertTrue($plugin instanceof Plugin); - $fakeServer->addPlugin($plugin); - $this->assertEquals($plugin, $fakeServer->getPlugin('auth')); - $this->assertIsArray($plugin->getPluginInfo()); - } - - /** - * @depends testInit - */ - public function testAuthenticate() - { - $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); - $plugin = new Plugin(new Backend\Mock()); - $fakeServer->addPlugin($plugin); - $this->assertTrue( - $fakeServer->emit('beforeMethod:GET', [new HTTP\Request('GET', '/'), new HTTP\Response()]) - ); - } - - /** - * @depends testInit - */ - public function testAuthenticateFail() - { - $this->expectException('Sabre\DAV\Exception\NotAuthenticated'); - $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); - $backend = new Backend\Mock(); - $backend->fail = true; - - $plugin = new Plugin($backend); - $fakeServer->addPlugin($plugin); - $fakeServer->emit('beforeMethod:GET', [new HTTP\Request('GET', '/'), new HTTP\Response()]); - } - - /** - * @depends testAuthenticateFail - */ - public function testAuthenticateFailDontAutoRequire() - { - $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); - $backend = new Backend\Mock(); - $backend->fail = true; - - $plugin = new Plugin($backend); - $plugin->autoRequireLogin = false; - $fakeServer->addPlugin($plugin); - $this->assertTrue( - $fakeServer->emit('beforeMethod:GET', [new HTTP\Request('GET', '/'), new HTTP\Response()]) - ); - $this->assertEquals(1, count($plugin->getLoginFailedReasons())); - } - - /** - * @depends testAuthenticate - */ - public function testMultipleBackend() - { - $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); - $backend1 = new Backend\Mock(); - $backend2 = new Backend\Mock(); - $backend2->fail = true; - - $plugin = new Plugin(); - $plugin->addBackend($backend1); - $plugin->addBackend($backend2); - - $fakeServer->addPlugin($plugin); - $fakeServer->emit('beforeMethod:GET', [new HTTP\Request('GET', '/'), new HTTP\Response()]); - - $this->assertEquals('principals/admin', $plugin->getCurrentPrincipal()); - } - - /** - * @depends testInit - */ - public function testNoAuthBackend() - { - $this->expectException('Sabre\DAV\Exception'); - $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); - - $plugin = new Plugin(); - $fakeServer->addPlugin($plugin); - $fakeServer->emit('beforeMethod:GET', [new HTTP\Request('GET', '/'), new HTTP\Response()]); - } - - /** - * @depends testInit - */ - public function testInvalidCheckResponse() - { - $this->expectException('Sabre\DAV\Exception'); - $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); - $backend = new Backend\Mock(); - $backend->invalidCheckResponse = true; - - $plugin = new Plugin($backend); - $fakeServer->addPlugin($plugin); - $fakeServer->emit('beforeMethod:GET', [new HTTP\Request('GET', '/'), new HTTP\Response()]); - } - - /** - * @depends testAuthenticate - */ - public function testGetCurrentPrincipal() - { - $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla')); - $plugin = new Plugin(new Backend\Mock()); - $fakeServer->addPlugin($plugin); - $fakeServer->emit('beforeMethod:GET', [new HTTP\Request('GET', '/'), new HTTP\Response()]); - $this->assertEquals('principals/admin', $plugin->getCurrentPrincipal()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php deleted file mode 100644 index e9a8eddad..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php +++ /dev/null @@ -1,124 +0,0 @@ -expectException('Sabre\DAV\Exception\Forbidden'); - $file = new FileMock(); - $file->put('hi'); - } - - public function testGet() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $file = new FileMock(); - $file->get(); - } - - public function testGetSize() - { - $file = new FileMock(); - $this->assertEquals(0, $file->getSize()); - } - - public function testGetETag() - { - $file = new FileMock(); - $this->assertNull($file->getETag()); - } - - public function testGetContentType() - { - $file = new FileMock(); - $this->assertNull($file->getContentType()); - } - - public function testDelete() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $file = new FileMock(); - $file->delete(); - } - - public function testSetName() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $file = new FileMock(); - $file->setName('hi'); - } - - public function testGetLastModified() - { - $file = new FileMock(); - // checking if lastmod is within the range of a few seconds - $lastMod = $file->getLastModified(); - $compareTime = ($lastMod + 1) - time(); - $this->assertTrue($compareTime < 3); - } - - public function testGetChild() - { - $dir = new DirectoryMock(); - $file = $dir->getChild('mockfile'); - $this->assertTrue($file instanceof FileMock); - } - - public function testChildExists() - { - $dir = new DirectoryMock(); - $this->assertTrue($dir->childExists('mockfile')); - } - - public function testChildExistsFalse() - { - $dir = new DirectoryMock(); - $this->assertFalse($dir->childExists('mockfile2')); - } - - public function testGetChild404() - { - $this->expectException('Sabre\DAV\Exception\NotFound'); - $dir = new DirectoryMock(); - $file = $dir->getChild('blabla'); - } - - public function testCreateFile() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $dir = new DirectoryMock(); - $dir->createFile('hello', 'data'); - } - - public function testCreateDirectory() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $dir = new DirectoryMock(); - $dir->createDirectory('hello'); - } -} - -class DirectoryMock extends Collection -{ - public function getName() - { - return 'mockdir'; - } - - public function getChildren() - { - return [new FileMock()]; - } -} - -class FileMock extends File -{ - public function getName() - { - return 'mockfile'; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php deleted file mode 100644 index cb4d3ce03..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php +++ /dev/null @@ -1,67 +0,0 @@ -server->getPropertiesForPath('/somefile.jpg', $properties); - $this->assertArrayHasKey(0, $result); - $this->assertArrayHasKey(404, $result[0]); - $this->assertArrayHasKey('{DAV:}getcontenttype', $result[0][404]); - } - - /** - * @depends testGetProperties - */ - public function testGetPropertiesPluginEnabled() - { - $this->server->addPlugin(new GuessContentType()); - $properties = [ - '{DAV:}getcontenttype', - ]; - $result = $this->server->getPropertiesForPath('/somefile.jpg', $properties); - $this->assertArrayHasKey(0, $result); - $this->assertArrayHasKey(200, $result[0], 'We received: '.print_r($result, true)); - $this->assertArrayHasKey('{DAV:}getcontenttype', $result[0][200]); - $this->assertEquals('image/jpeg', $result[0][200]['{DAV:}getcontenttype']); - } - - /** - * @depends testGetPropertiesPluginEnabled - */ - public function testGetPropertiesUnknown() - { - $this->server->addPlugin(new GuessContentType()); - $properties = [ - '{DAV:}getcontenttype', - ]; - $result = $this->server->getPropertiesForPath('/somefile.hoi', $properties); - $this->assertArrayHasKey(0, $result); - $this->assertArrayHasKey(200, $result[0]); - $this->assertArrayHasKey('{DAV:}getcontenttype', $result[0][200]); - $this->assertEquals('application/octet-stream', $result[0][200]['{DAV:}getcontenttype']); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php deleted file mode 100644 index 00b2661ac..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php +++ /dev/null @@ -1,40 +0,0 @@ -server->addPlugin(new MapGetToPropFind()); - } - - public function testCollectionGet() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'GET', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody(''); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(207, $this->response->status, 'Incorrect status response received. Full response body: '.$this->response->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'DAV' => ['1, 3, extended-mkcol'], - 'Vary' => ['Brief,Prefer'], - ], - $this->response->getHeaders() - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php deleted file mode 100644 index a987525c0..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php +++ /dev/null @@ -1,176 +0,0 @@ -server->addPlugin($this->plugin = new Plugin()); - $this->server->tree->getNodeForPath('')->createDirectory('dir2'); - } - - public function testCollectionGet() - { - $request = new HTTP\Request('GET', '/dir'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(200, $this->response->getStatus(), 'Incorrect status received. Full response body: '.$this->response->getBodyAsString()); - $this->assertEquals( - [ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['text/html; charset=utf-8'], - 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"], - ], - $this->response->getHeaders() - ); - - $body = $this->response->getBodyAsString(); - $this->assertTrue(false !== strpos($body, 'dir'), $body); - $this->assertTrue(false !== strpos($body, '<a href="/dir/child.txt">')); - } - - /** - * Adding the If-None-Match should have 0 effect, but it threw an error. - */ - public function testCollectionGetIfNoneMatch() - { - $request = new HTTP\Request('GET', '/dir'); - $request->setHeader('If-None-Match', '"foo-bar"'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(200, $this->response->getStatus(), 'Incorrect status received. Full response body: '.$this->response->getBodyAsString()); - $this->assertEquals( - [ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['text/html; charset=utf-8'], - 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"], - ], - $this->response->getHeaders() - ); - - $body = $this->response->getBodyAsString(); - $this->assertTrue(false !== strpos($body, '<title>dir'), $body); - $this->assertTrue(false !== strpos($body, '<a href="/dir/child.txt">')); - } - - public function testCollectionGetRoot() - { - $request = new HTTP\Request('GET', '/'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(200, $this->response->status, 'Incorrect status received. Full response body: '.$this->response->getBodyAsString()); - $this->assertEquals( - [ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['text/html; charset=utf-8'], - 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"], - ], - $this->response->getHeaders() - ); - - $body = $this->response->getBodyAsString(); - $this->assertTrue(false !== strpos($body, '<title>/'), $body); - $this->assertTrue(false !== strpos($body, '<a href="/dir/">')); - $this->assertTrue(false !== strpos($body, '<span class="btn disabled">')); - } - - public function testGETPassthru() - { - $request = new HTTP\Request('GET', '/random'); - $response = new HTTP\Response(); - $this->assertNull( - $this->plugin->httpGet($request, $response) - ); - } - - public function testPostOtherContentType() - { - $request = new HTTP\Request('POST', '/', ['Content-Type' => 'text/xml']); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(501, $this->response->status); - } - - public function testPostNoSabreAction() - { - $request = new HTTP\Request('POST', '/', ['Content-Type' => 'application/x-www-form-urlencoded']); - $request->setPostData([]); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(501, $this->response->status); - } - - public function testPostMkCol() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'POST', - 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', - ]; - $postVars = [ - 'sabreAction' => 'mkcol', - 'name' => 'new_collection', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setPostData($postVars); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(302, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Location' => ['/'], - ], $this->response->getHeaders()); - - $this->assertTrue(is_dir(SABRE_TEMPDIR.'/new_collection')); - } - - public function testGetAsset() - { - $request = new HTTP\Request('GET', '/?sabreAction=asset&assetName=favicon.ico'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(200, $this->response->getStatus(), 'Error: '.$this->response->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['image/vnd.microsoft.icon'], - 'Content-Length' => ['4286'], - 'Cache-Control' => ['public, max-age=1209600'], - 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"], - ], $this->response->getHeaders()); - } - - public function testGetAsset404() - { - $request = new HTTP\Request('GET', '/?sabreAction=asset&assetName=flavicon.ico'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(404, $this->response->getStatus(), 'Error: '.$this->response->getBodyAsString()); - } - - public function testGetAssetEscapeBasePath() - { - $request = new HTTP\Request('GET', '/?sabreAction=asset&assetName=./../assets/favicon.ico'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(404, $this->response->getStatus(), 'Error: '.$this->response->getBodyAsString()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php b/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php deleted file mode 100644 index 7d787744a..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP\RequestInterface; -use Sabre\HTTP\ResponseInterface; - -class ClientMock extends Client -{ - public $request; - public $response; - - public $url; - public $curlSettings; - - /** - * Just making this method public. - * - * @param string $url - * - * @return string - */ - public function getAbsoluteUrl($url) - { - return parent::getAbsoluteUrl($url); - } - - public function doRequest(RequestInterface $request): ResponseInterface - { - $this->request = $request; - - return $this->response; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php deleted file mode 100644 index 85a95c90e..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php +++ /dev/null @@ -1,285 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP\Response; - -class ClientTest extends \PHPUnit\Framework\TestCase -{ - public function setup(): void - { - if (!function_exists('curl_init')) { - $this->markTestSkipped('CURL must be installed to test the client'); - } - } - - public function testConstruct() - { - $client = new ClientMock([ - 'baseUri' => '/', - ]); - $this->assertInstanceOf('Sabre\DAV\ClientMock', $client); - } - - public function testConstructNoBaseUri() - { - $this->expectException('InvalidArgumentException'); - $client = new ClientMock([]); - } - - public function testAuth() - { - $client = new ClientMock([ - 'baseUri' => '/', - 'userName' => 'foo', - 'password' => 'bar', - ]); - - $this->assertEquals('foo:bar', $client->curlSettings[CURLOPT_USERPWD]); - $this->assertEquals(CURLAUTH_BASIC | CURLAUTH_DIGEST, $client->curlSettings[CURLOPT_HTTPAUTH]); - } - - public function testBasicAuth() - { - $client = new ClientMock([ - 'baseUri' => '/', - 'userName' => 'foo', - 'password' => 'bar', - 'authType' => Client::AUTH_BASIC, - ]); - - $this->assertEquals('foo:bar', $client->curlSettings[CURLOPT_USERPWD]); - $this->assertEquals(CURLAUTH_BASIC, $client->curlSettings[CURLOPT_HTTPAUTH]); - } - - public function testDigestAuth() - { - $client = new ClientMock([ - 'baseUri' => '/', - 'userName' => 'foo', - 'password' => 'bar', - 'authType' => Client::AUTH_DIGEST, - ]); - - $this->assertEquals('foo:bar', $client->curlSettings[CURLOPT_USERPWD]); - $this->assertEquals(CURLAUTH_DIGEST, $client->curlSettings[CURLOPT_HTTPAUTH]); - } - - public function testNTLMAuth() - { - $client = new ClientMock([ - 'baseUri' => '/', - 'userName' => 'foo', - 'password' => 'bar', - 'authType' => Client::AUTH_NTLM, - ]); - - $this->assertEquals('foo:bar', $client->curlSettings[CURLOPT_USERPWD]); - $this->assertEquals(CURLAUTH_NTLM, $client->curlSettings[CURLOPT_HTTPAUTH]); - } - - public function testProxy() - { - $client = new ClientMock([ - 'baseUri' => '/', - 'proxy' => 'localhost:8888', - ]); - - $this->assertEquals('localhost:8888', $client->curlSettings[CURLOPT_PROXY]); - } - - public function testEncoding() - { - $client = new ClientMock([ - 'baseUri' => '/', - 'encoding' => Client::ENCODING_IDENTITY | Client::ENCODING_GZIP | Client::ENCODING_DEFLATE, - ]); - - $this->assertEquals('identity,deflate,gzip', $client->curlSettings[CURLOPT_ENCODING]); - } - - public function testPropFind() - { - $client = new ClientMock([ - 'baseUri' => '/', - ]); - - $responseBody = <<<XML -<?xml version="1.0"?> -<multistatus xmlns="DAV:"> - <response> - <href>/foo</href> - <propstat> - <prop> - <displayname>bar</displayname> - </prop> - <status>HTTP/1.1 200 OK</status> - </propstat> - </response> -</multistatus> -XML; - - $client->response = new Response(207, [], $responseBody); - $result = $client->propFind('foo', ['{DAV:}displayname', '{urn:zim}gir']); - - $this->assertEquals(['{DAV:}displayname' => 'bar'], $result); - - $request = $client->request; - $this->assertEquals('PROPFIND', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'Depth' => ['0'], - 'Content-Type' => ['application/xml'], - ], $request->getHeaders()); - } - - public function testPropFindError() - { - $this->expectException('Sabre\HTTP\ClientHttpException'); - $client = new ClientMock([ - 'baseUri' => '/', - ]); - - $client->response = new Response(405, []); - $client->propFind('foo', ['{DAV:}displayname', '{urn:zim}gir']); - } - - public function testPropFindDepth1() - { - $client = new ClientMock([ - 'baseUri' => '/', - ]); - - $responseBody = <<<XML -<?xml version="1.0"?> -<multistatus xmlns="DAV:"> - <response> - <href>/foo</href> - <propstat> - <prop> - <displayname>bar</displayname> - </prop> - <status>HTTP/1.1 200 OK</status> - </propstat> - </response> -</multistatus> -XML; - - $client->response = new Response(207, [], $responseBody); - $result = $client->propFind('foo', ['{DAV:}displayname', '{urn:zim}gir'], 1); - - $this->assertEquals([ - '/foo' => [ - '{DAV:}displayname' => 'bar', - ], - ], $result); - - $request = $client->request; - $this->assertEquals('PROPFIND', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'Depth' => ['1'], - 'Content-Type' => ['application/xml'], - ], $request->getHeaders()); - } - - public function testPropPatch() - { - $client = new ClientMock([ - 'baseUri' => '/', - ]); - - $responseBody = <<<XML -<?xml version="1.0"?> -<multistatus xmlns="DAV:"> - <response> - <href>/foo</href> - <propstat> - <prop> - <displayname>bar</displayname> - </prop> - <status>HTTP/1.1 200 OK</status> - </propstat> - </response> -</multistatus> -XML; - - $client->response = new Response(207, [], $responseBody); - $result = $client->propPatch('foo', ['{DAV:}displayname' => 'hi', '{urn:zim}gir' => null]); - $this->assertTrue($result); - $request = $client->request; - $this->assertEquals('PROPPATCH', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'Content-Type' => ['application/xml'], - ], $request->getHeaders()); - } - - /** - * @depends testPropPatch - */ - public function testPropPatchHTTPError() - { - $this->expectException('Sabre\HTTP\ClientHttpException'); - $client = new ClientMock([ - 'baseUri' => '/', - ]); - - $client->response = new Response(403, [], ''); - $client->propPatch('foo', ['{DAV:}displayname' => 'hi', '{urn:zim}gir' => null]); - } - - /** - * @depends testPropPatch - */ - public function testPropPatchMultiStatusError() - { - $this->expectException('Sabre\HTTP\ClientException'); - $client = new ClientMock([ - 'baseUri' => '/', - ]); - - $responseBody = <<<XML -<?xml version="1.0"?> -<multistatus xmlns="DAV:"> -<response> - <href>/foo</href> - <propstat> - <prop> - <displayname /> - </prop> - <status>HTTP/1.1 403 Forbidden</status> - </propstat> -</response> -</multistatus> -XML; - - $client->response = new Response(207, [], $responseBody); - $client->propPatch('foo', ['{DAV:}displayname' => 'hi', '{urn:zim}gir' => null]); - } - - public function testOPTIONS() - { - $client = new ClientMock([ - 'baseUri' => '/', - ]); - - $client->response = new Response(207, [ - 'DAV' => 'calendar-access, extended-mkcol', - ]); - $result = $client->options(); - - $this->assertEquals( - ['calendar-access', 'extended-mkcol'], - $result - ); - - $request = $client->request; - $this->assertEquals('OPTIONS', $request->getMethod()); - $this->assertEquals('/', $request->getUrl()); - $this->assertEquals([ - ], $request->getHeaders()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php deleted file mode 100644 index 5fc271587..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Exception; - -use DOMDocument; -use Sabre\DAV; - -class LockedTest extends \PHPUnit\Framework\TestCase -{ - public function testSerialize() - { - $dom = new DOMDocument('1.0'); - $dom->formatOutput = true; - $root = $dom->createElement('d:root'); - - $dom->appendChild($root); - $root->setAttribute('xmlns:d', 'DAV:'); - - $lockInfo = new DAV\Locks\LockInfo(); - $lockInfo->uri = '/foo'; - $locked = new Locked($lockInfo); - - $locked->serialize(new DAV\Server(), $root); - - $output = $dom->saveXML(); - - $expected = '<?xml version="1.0"?> -<d:root xmlns:d="DAV:"> - <d:lock-token-submitted xmlns:d="DAV:"> - <d:href>/foo</d:href> - </d:lock-token-submitted> -</d:root> -'; - - $this->assertEquals($expected, $output); - } - - public function testSerializeAmpersand() - { - $dom = new DOMDocument('1.0'); - $dom->formatOutput = true; - $root = $dom->createElement('d:root'); - - $dom->appendChild($root); - $root->setAttribute('xmlns:d', 'DAV:'); - - $lockInfo = new DAV\Locks\LockInfo(); - $lockInfo->uri = '/foo&bar'; - $locked = new Locked($lockInfo); - - $locked->serialize(new DAV\Server(), $root); - - $output = $dom->saveXML(); - - $expected = '<?xml version="1.0"?> -<d:root xmlns:d="DAV:"> - <d:lock-token-submitted xmlns:d="DAV:"> - <d:href>/foo&bar</d:href> - </d:lock-token-submitted> -</d:root> -'; - - $this->assertEquals($expected, $output); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php deleted file mode 100644 index 42775a313..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Exception/PaymentRequiredTest.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Exception; - -class PaymentRequiredTest extends \PHPUnit\Framework\TestCase -{ - public function testGetHTTPCode() - { - $ex = new PaymentRequired(); - $this->assertEquals(402, $ex->getHTTPCode()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php deleted file mode 100644 index 7237aea0d..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -class ExceptionTest extends \PHPUnit\Framework\TestCase -{ - public function testStatus() - { - $e = new Exception(); - $this->assertEquals(500, $e->getHTTPCode()); - } - - public function testExceptionStatuses() - { - $c = [ - 'Sabre\\DAV\\Exception\\NotAuthenticated' => 401, - 'Sabre\\DAV\\Exception\\InsufficientStorage' => 507, - ]; - - foreach ($c as $class => $status) { - $obj = new $class(); - $this->assertEquals($status, $obj->getHTTPCode()); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php deleted file mode 100644 index 2b759e5d0..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\FSExt; - -class FileTest extends \PHPUnit\Framework\TestCase -{ - public function setup(): void - { - file_put_contents(SABRE_TEMPDIR.'/file.txt', 'Contents'); - } - - public function teardown(): void - { - \Sabre\TestUtil::clearTempDir(); - } - - public function testPut() - { - $filename = SABRE_TEMPDIR.'/file.txt'; - $file = new File($filename); - $result = $file->put('New contents'); - - $this->assertEquals('New contents', file_get_contents(SABRE_TEMPDIR.'/file.txt')); - $this->assertEquals( - '"'. - sha1( - fileinode($filename). - filesize($filename). - filemtime($filename) - ).'"', - $result - ); - } - - public function testRange() - { - $file = new File(SABRE_TEMPDIR.'/file.txt'); - $file->put('0000000'); - $file->patch('111', 2, 3); - - $this->assertEquals('0001110', file_get_contents(SABRE_TEMPDIR.'/file.txt')); - } - - public function testRangeStream() - { - $stream = fopen('php://memory', 'r+'); - fwrite($stream, '222'); - rewind($stream); - - $file = new File(SABRE_TEMPDIR.'/file.txt'); - $file->put('0000000'); - $file->patch($stream, 2, 3); - - $this->assertEquals('0002220', file_get_contents(SABRE_TEMPDIR.'/file.txt')); - } - - public function testGet() - { - $file = new File(SABRE_TEMPDIR.'/file.txt'); - $this->assertEquals('Contents', stream_get_contents($file->get())); - } - - public function testDelete() - { - $file = new File(SABRE_TEMPDIR.'/file.txt'); - $file->delete(); - - $this->assertFalse(file_exists(SABRE_TEMPDIR.'/file.txt')); - } - - public function testGetETag() - { - $filename = SABRE_TEMPDIR.'/file.txt'; - $file = new File($filename); - $this->assertEquals( - '"'. - sha1( - fileinode($filename). - filesize($filename). - filemtime($filename) - ).'"', - $file->getETag() - ); - } - - public function testGetContentType() - { - $file = new File(SABRE_TEMPDIR.'/file.txt'); - $this->assertNull($file->getContentType()); - } - - public function testGetSize() - { - $file = new File(SABRE_TEMPDIR.'/file.txt'); - $this->assertEquals(8, $file->getSize()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php deleted file mode 100644 index 79ffb0186..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php +++ /dev/null @@ -1,252 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\FSExt; - -use Sabre\DAV; -use Sabre\HTTP; - -class ServerTest extends DAV\AbstractServer -{ - protected function getRootNode() - { - return new Directory($this->tempDir); - } - - public function testGet() - { - $request = new HTTP\Request('GET', '/test.txt'); - $filename = $this->tempDir.'/test.txt'; - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(200, $this->response->getStatus(), 'Invalid status code received.'); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [13], - 'Last-Modified' => [HTTP\toDate(new \DateTime('@'.filemtime($filename)))], - 'ETag' => ['"'.sha1(fileinode($filename).filesize($filename).filemtime($filename)).'"'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals('Test contents', $this->response->getBodyAsString()); - } - - public function testHEAD() - { - $request = new HTTP\Request('HEAD', '/test.txt'); - $filename = $this->tempDir.'/test.txt'; - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [13], - 'Last-Modified' => [HTTP\toDate(new \DateTime('@'.filemtime($this->tempDir.'/test.txt')))], - 'ETag' => ['"'.sha1(fileinode($filename).filesize($filename).filemtime($filename)).'"'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals(200, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - } - - public function testPut() - { - $request = new HTTP\Request('PUT', '/testput.txt'); - $filename = $this->tempDir.'/testput.txt'; - $request->setBody('Testing new file'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.sha1(fileinode($filename).filesize($filename).filemtime($filename)).'"'], - ], $this->response->getHeaders()); - - $this->assertEquals(201, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals('Testing new file', file_get_contents($filename)); - } - - public function testPutAlreadyExists() - { - $request = new HTTP\Request('PUT', '/test.txt', ['If-None-Match' => '*']); - $request->setBody('Testing new file'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(412, $this->response->status); - $this->assertNotEquals('Testing new file', file_get_contents($this->tempDir.'/test.txt')); - } - - public function testMkcol() - { - $request = new HTTP\Request('MKCOL', '/testcol'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - ], $this->response->getHeaders()); - - $this->assertEquals(201, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertTrue(is_dir($this->tempDir.'/testcol')); - } - - public function testPutUpdate() - { - $request = new HTTP\Request('PUT', '/test.txt'); - $request->setBody('Testing updated file'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals('0', $this->response->getHeader('Content-Length')); - - $this->assertEquals(204, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals('Testing updated file', file_get_contents($this->tempDir.'/test.txt')); - } - - public function testDelete() - { - $request = new HTTP\Request('DELETE', '/test.txt'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - ], $this->response->getHeaders()); - - $this->assertEquals(204, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertFalse(file_exists($this->tempDir.'/test.txt')); - } - - public function testDeleteDirectory() - { - mkdir($this->tempDir.'/testcol'); - file_put_contents($this->tempDir.'/testcol/test.txt', 'Hi! I\'m a file with a short lifespan'); - - $request = new HTTP\Request('DELETE', '/testcol'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - ], $this->response->getHeaders()); - $this->assertEquals(204, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertFalse(file_exists($this->tempDir.'/testcol')); - } - - public function testOptions() - { - $request = new HTTP\Request('OPTIONS', '/'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'DAV' => ['1, 3, extended-mkcol'], - 'MS-Author-Via' => ['DAV'], - 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT'], - 'Accept-Ranges' => ['bytes'], - 'Content-Length' => ['0'], - 'X-Sabre-Version' => [DAV\Version::VERSION], - ], $this->response->getHeaders()); - - $this->assertEquals(200, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - } - - public function testMove() - { - mkdir($this->tempDir.'/testcol'); - - $request = new HTTP\Request('MOVE', '/test.txt', ['Destination' => '/testcol/test2.txt']); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(201, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - - $this->assertEquals([ - 'Content-Length' => ['0'], - 'X-Sabre-Version' => [DAV\Version::VERSION], - ], $this->response->getHeaders()); - - $this->assertTrue( - is_file($this->tempDir.'/testcol/test2.txt') - ); - } - - /** - * This test checks if it's possible to move a non-FSExt collection into a - * FSExt collection. - * - * The moveInto function *should* ignore the object and let sabredav itself - * execute the slow move. - */ - public function testMoveOtherObject() - { - mkdir($this->tempDir.'/tree1'); - mkdir($this->tempDir.'/tree2'); - - $tree = new DAV\Tree(new DAV\SimpleCollection('root', [ - new DAV\FS\Directory($this->tempDir.'/tree1'), - new DAV\FSExt\Directory($this->tempDir.'/tree2'), - ])); - $this->server->tree = $tree; - - $request = new HTTP\Request('MOVE', '/tree1', ['Destination' => '/tree2/tree1']); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(201, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - - $this->assertEquals([ - 'Content-Length' => ['0'], - 'X-Sabre-Version' => [DAV\Version::VERSION], - ], $this->response->getHeaders()); - - $this->assertTrue( - is_dir($this->tempDir.'/tree2/tree1') - ); - } - - public function testCopy() - { - mkdir($this->tempDir.'/testcol'); - - $request = new HTTP\Request('COPY', '/test.txt', ['Destination' => '/testcol/test2.txt']); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(201, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - - $this->assertEquals([ - 'Content-Length' => ['0'], - 'X-Sabre-Version' => [DAV\Version::VERSION], - ], $this->response->getHeaders()); - - $this->assertTrue(is_file($this->tempDir.'/test.txt')); - $this->assertTrue(is_file($this->tempDir.'/testcol/test2.txt')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php b/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php deleted file mode 100644 index 7d6825612..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/HTTPPreferParsingTest.php +++ /dev/null @@ -1,175 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class HTTPPreferParsingTest extends \Sabre\DAVServerTest -{ - public function assertParseResult($input, $expected) - { - $httpRequest = new HTTP\Request('GET', '/foo', [ - 'Prefer' => $input, - ]); - - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals( - $expected, - $server->getHTTPPrefer() - ); - } - - public function testParseSimple() - { - $this->assertParseResult( - 'return-asynch', - [ - 'respond-async' => true, - 'return' => null, - 'handling' => null, - 'wait' => null, - ] - ); - } - - public function testParseValue() - { - $this->assertParseResult( - 'wait=10', - [ - 'respond-async' => false, - 'return' => null, - 'handling' => null, - 'wait' => '10', - ] - ); - } - - public function testParseMultiple() - { - $this->assertParseResult( - 'return-minimal, strict,lenient', - [ - 'respond-async' => false, - 'return' => 'minimal', - 'handling' => 'lenient', - 'wait' => null, - ] - ); - } - - public function testParseWeirdValue() - { - $this->assertParseResult( - 'BOOOH', - [ - 'respond-async' => false, - 'return' => null, - 'handling' => null, - 'wait' => null, - 'boooh' => true, - ] - ); - } - - public function testBrief() - { - $httpRequest = new HTTP\Request('GET', '/foo', [ - 'Brief' => 't', - ]); - - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals([ - 'respond-async' => false, - 'return' => 'minimal', - 'handling' => null, - 'wait' => null, - ], $server->getHTTPPrefer()); - } - - /** - * propfindMinimal. - */ - public function testpropfindMinimal() - { - $request = new HTTP\Request('PROPFIND', '/', [ - 'Prefer' => 'return-minimal', - ]); - $request->setBody(<<<BLA -<?xml version="1.0"?> -<d:propfind xmlns:d="DAV:"> - <d:prop> - <d:something /> - <d:resourcetype /> - </d:prop> -</d:propfind> -BLA - ); - - $response = $this->request($request); - - $body = $response->getBodyAsString(); - - $this->assertEquals(207, $response->getStatus(), $body); - - $this->assertTrue(false !== strpos($body, 'resourcetype'), $body); - $this->assertTrue(false === strpos($body, 'something'), $body); - } - - public function testproppatchMinimal() - { - $request = new HTTP\Request('PROPPATCH', '/', ['Prefer' => 'return-minimal']); - $request->setBody(<<<BLA -<?xml version="1.0"?> -<d:propertyupdate xmlns:d="DAV:"> - <d:set> - <d:prop> - <d:something>nope!</d:something> - </d:prop> - </d:set> -</d:propertyupdate> -BLA - ); - - $this->server->on('propPatch', function ($path, PropPatch $propPatch) { - $propPatch->handle('{DAV:}something', function ($props) { - return true; - }); - }); - - $response = $this->request($request); - - $this->assertEquals('', $response->getBodyAsString(), 'Expected empty body: '.$response->getBodyAsString()); - $this->assertEquals(204, $response->status); - } - - public function testproppatchMinimalError() - { - $request = new HTTP\Request('PROPPATCH', '/', ['Prefer' => 'return-minimal']); - $request->setBody(<<<BLA -<?xml version="1.0"?> -<d:propertyupdate xmlns:d="DAV:"> - <d:set> - <d:prop> - <d:something>nope!</d:something> - </d:prop> - </d:set> -</d:propertyupdate> -BLA - ); - - $response = $this->request($request); - - $body = $response->getBodyAsString(); - - $this->assertEquals(207, $response->status); - $this->assertTrue(false !== strpos($body, 'something')); - $this->assertTrue(false !== strpos($body, '403 Forbidden'), $body); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php b/vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php deleted file mode 100644 index f70febabd..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\DAVServerTest; -use Sabre\HTTP; - -/** - * Tests related to the PUT request. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class HttpDeleteTest extends DAVServerTest -{ - /** - * Sets up the DAV tree. - */ - public function setUpTree() - { - $this->tree = new Mock\Collection('root', [ - 'file1' => 'foo', - 'dir' => [ - 'subfile' => 'bar', - 'subfile2' => 'baz', - ], - ]); - } - - /** - * A successful DELETE. - */ - public function testDelete() - { - $request = new HTTP\Request('DELETE', '/file1'); - - $response = $this->request($request); - - $this->assertEquals( - 204, - $response->getStatus(), - 'Incorrect status code. Response body: '.$response->getBodyAsString() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - ], - $response->getHeaders() - ); - } - - /** - * Deleting a Directory. - */ - public function testDeleteDirectory() - { - $request = new HTTP\Request('DELETE', '/dir'); - - $response = $this->request($request); - - $this->assertEquals( - 204, - $response->getStatus(), - 'Incorrect status code. Response body: '.$response->getBodyAsString() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - ], - $response->getHeaders() - ); - } - - /** - * DELETE on a node that does not exist. - */ - public function testDeleteNotFound() - { - $request = new HTTP\Request('DELETE', '/file2'); - $response = $this->request($request); - - $this->assertEquals( - 404, - $response->getStatus(), - 'Incorrect status code. Response body: '.$response->getBodyAsString() - ); - } - - /** - * DELETE with preconditions. - */ - public function testDeletePreconditions() - { - $request = new HTTP\Request('DELETE', '/file1', [ - 'If-Match' => '"'.md5('foo').'"', - ]); - - $response = $this->request($request); - - $this->assertEquals( - 204, - $response->getStatus(), - 'Incorrect status code. Response body: '.$response->getBodyAsString() - ); - } - - /** - * DELETE with incorrect preconditions. - */ - public function testDeletePreconditionsFailed() - { - $request = new HTTP\Request('DELETE', '/file1', [ - 'If-Match' => '"'.md5('bar').'"', - ]); - - $response = $this->request($request); - - $this->assertEquals( - 412, - $response->getStatus(), - 'Incorrect status code. Response body: '.$response->getBodyAsString() - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php b/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php deleted file mode 100644 index 543ec652a..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php +++ /dev/null @@ -1,354 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\DAVServerTest; -use Sabre\HTTP; - -/** - * Tests related to the PUT request. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class HttpPutTest extends DAVServerTest -{ - /** - * Sets up the DAV tree. - */ - public function setUpTree() - { - $this->tree = new Mock\Collection('root', [ - 'file1' => 'foo', - ]); - } - - /** - * A successful PUT of a new file. - */ - public function testPut() - { - $request = new HTTP\Request('PUT', '/file2', [], 'hello'); - - $response = $this->request($request); - - $this->assertEquals(201, $response->getStatus(), 'Incorrect status code received. Full response body:'.$response->getBodyAsString()); - - $this->assertEquals( - 'hello', - $this->server->tree->getNodeForPath('file2')->get() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.md5('hello').'"'], - ], - $response->getHeaders() - ); - } - - /** - * A successful PUT on an existing file. - * - * @depends testPut - */ - public function testPutExisting() - { - $request = new HTTP\Request('PUT', '/file1', [], 'bar'); - - $response = $this->request($request); - - $this->assertEquals(204, $response->getStatus()); - - $this->assertEquals( - 'bar', - $this->server->tree->getNodeForPath('file1')->get() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.md5('bar').'"'], - ], - $response->getHeaders() - ); - } - - /** - * PUT on existing file with If-Match: *. - * - * @depends testPutExisting - */ - public function testPutExistingIfMatchStar() - { - $request = new HTTP\Request( - 'PUT', - '/file1', - ['If-Match' => '*'], - 'hello' - ); - - $response = $this->request($request); - - $this->assertEquals(204, $response->getStatus()); - - $this->assertEquals( - 'hello', - $this->server->tree->getNodeForPath('file1')->get() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.md5('hello').'"'], - ], - $response->getHeaders() - ); - } - - /** - * PUT on existing file with If-Match: with a correct etag. - * - * @depends testPutExisting - */ - public function testPutExistingIfMatchCorrect() - { - $request = new HTTP\Request( - 'PUT', - '/file1', - ['If-Match' => '"'.md5('foo').'"'], - 'hello' - ); - - $response = $this->request($request); - - $this->assertEquals(204, $response->status); - - $this->assertEquals( - 'hello', - $this->server->tree->getNodeForPath('file1')->get() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.md5('hello').'"'], - ], - $response->getHeaders() - ); - } - - /** - * PUT with Content-Range should be rejected. - * - * @depends testPut - */ - public function testPutContentRange() - { - $request = new HTTP\Request( - 'PUT', - '/file2', - ['Content-Range' => 'bytes/100-200'], - 'hello' - ); - - $response = $this->request($request); - $this->assertEquals(400, $response->getStatus()); - } - - /** - * PUT on non-existing file with If-None-Match: * should work. - * - * @depends testPut - */ - public function testPutIfNoneMatchStar() - { - $request = new HTTP\Request( - 'PUT', - '/file2', - ['If-None-Match' => '*'], - 'hello' - ); - - $response = $this->request($request); - - $this->assertEquals(201, $response->getStatus()); - - $this->assertEquals( - 'hello', - $this->server->tree->getNodeForPath('file2')->get() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.md5('hello').'"'], - ], - $response->getHeaders() - ); - } - - /** - * PUT on non-existing file with If-Match: * should fail. - * - * @depends testPut - */ - public function testPutIfMatchStar() - { - $request = new HTTP\Request( - 'PUT', - '/file2', - ['If-Match' => '*'], - 'hello' - ); - - $response = $this->request($request); - - $this->assertEquals(412, $response->getStatus()); - } - - /** - * PUT on existing file with If-None-Match: * should fail. - * - * @depends testPut - */ - public function testPutExistingIfNoneMatchStar() - { - $request = new HTTP\Request( - 'PUT', - '/file1', - ['If-None-Match' => '*'], - 'hello' - ); - $request->setBody('hello'); - - $response = $this->request($request); - - $this->assertEquals(412, $response->getStatus()); - } - - /** - * PUT thats created in a non-collection should be rejected. - * - * @depends testPut - */ - public function testPutParentIsNotCollection() - { - $request = new HTTP\Request( - 'PUT', - '/file1/file2', - [], - 'hello' - ); - - $response = $this->request($request); - $this->assertEquals(409, $response->getStatus()); - } - - /** - * PUT thats created in a non-existent collection should be rejected. - * - * @depends testPut - */ - public function testPutParentCollectionDoesNotExist() - { - $request = new HTTP\Request( - 'PUT', - '/non-existent-collection/file2', - [], - 'hello' - ); - - $response = $this->request($request); - $this->assertEquals(409, $response->getStatus()); - } - - /** - * Finder may sometimes make a request, which gets its content-body - * stripped. We can't always prevent this from happening, but in some cases - * we can detected this and return an error instead. - * - * @depends testPut - */ - public function testFinderPutSuccess() - { - $request = new HTTP\Request( - 'PUT', - '/file2', - ['X-Expected-Entity-Length' => '5'], - 'hello' - ); - $response = $this->request($request); - - $this->assertEquals(201, $response->getStatus()); - - $this->assertEquals( - 'hello', - $this->server->tree->getNodeForPath('file2')->get() - ); - - $this->assertEquals( - [ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - 'ETag' => ['"'.md5('hello').'"'], - ], - $response->getHeaders() - ); - } - - /** - * Same as the last one, but in this case we're mimicing a failed request. - * - * @depends testFinderPutSuccess - */ - public function testFinderPutFail() - { - $request = new HTTP\Request( - 'PUT', - '/file2', - ['X-Expected-Entity-Length' => '5'], - '' - ); - - $response = $this->request($request); - - $this->assertEquals(403, $response->getStatus()); - } - - /** - * Plugins can intercept PUT. We need to make sure that works. - * - * @depends testPut - */ - public function testPutIntercept() - { - $this->server->on('beforeBind', function ($uri) { - $this->server->httpResponse->setStatus(418); - - return false; - }); - - $request = new HTTP\Request('PUT', '/file2', [], 'hello'); - $response = $this->request($request); - - $this->assertEquals(418, $response->getStatus(), 'Incorrect status code received. Full response body: '.$response->getBodyAsString()); - - $this->assertFalse( - $this->server->tree->nodeExists('file2') - ); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - ], $response->getHeaders()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php b/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php deleted file mode 100644 index 36b182c44..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class Issue33Test extends \PHPUnit\Framework\TestCase -{ - public function setup(): void - { - \Sabre\TestUtil::clearTempDir(); - } - - public function testCopyMoveInfo() - { - $bar = new SimpleCollection('bar'); - $root = new SimpleCollection('webdav', [$bar]); - - $server = new Server($root); - $server->setBaseUri('/webdav/'); - - $request = new HTTP\Request('GET', '/webdav/bar', [ - 'Destination' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3', - 'Overwrite' => 'F', - ]); - - $server->httpRequest = $request; - - $info = $server->getCopyAndMoveInfo($request); - - $this->assertEquals('%C3%A0fo%C3%B3', urlencode($info['destination'])); - $this->assertFalse($info['destinationExists']); - $this->assertFalse($info['destinationNode']); - } - - public function testTreeMove() - { - mkdir(SABRE_TEMPDIR.'/issue33'); - $dir = new FS\Directory(SABRE_TEMPDIR.'/issue33'); - - $dir->createDirectory('bar'); - - $tree = new Tree($dir); - $tree->move('bar', urldecode('%C3%A0fo%C3%B3')); - - $node = $tree->getNodeForPath(urldecode('%C3%A0fo%C3%B3')); - $this->assertEquals(urldecode('%C3%A0fo%C3%B3'), $node->getName()); - } - - public function testDirName() - { - $dirname1 = 'bar'; - $dirname2 = urlencode('%C3%A0fo%C3%B3'); - - $this->assertTrue(dirname($dirname1) == dirname($dirname2)); - } - - /** - * @depends testTreeMove - * @depends testCopyMoveInfo - */ - public function testEverything() - { - $request = new HTTP\Request('MOVE', '/webdav/bar', [ - 'Destination' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3', - 'Overwrite' => 'F', - ]); - - $request->setBody(''); - - $response = new HTTP\ResponseMock(); - - // Server setup - mkdir(SABRE_TEMPDIR.'/issue33'); - $dir = new FS\Directory(SABRE_TEMPDIR.'/issue33'); - - $dir->createDirectory('bar'); - - $tree = new Tree($dir); - - $server = new Server($tree); - $server->setBaseUri('/webdav/'); - - $server->httpRequest = $request; - $server->httpResponse = $response; - $server->sapi = new HTTP\SapiMock(); - $server->exec(); - - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/issue33/'.urldecode('%C3%A0fo%C3%B3'))); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php deleted file mode 100644 index d1cd1799c..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php +++ /dev/null @@ -1,189 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Locks\Backend; - -use Sabre\DAV; - -abstract class AbstractTest extends \PHPUnit\Framework\TestCase -{ - /** - * @abstract - * - * @return AbstractBackend - */ - abstract public function getBackend(); - - public function testSetup() - { - $backend = $this->getBackend(); - $this->assertInstanceOf('Sabre\\DAV\\Locks\\Backend\\AbstractBackend', $backend); - } - - /** - * @depends testSetup - */ - public function testGetLocks() - { - $backend = $this->getBackend(); - - $lock = new DAV\Locks\LockInfo(); - $lock->owner = 'Sinterklaas'; - $lock->timeout = 60; - $lock->created = time(); - $lock->token = 'MY-UNIQUE-TOKEN'; - $lock->uri = 'someuri'; - - $this->assertTrue($backend->lock('someuri', $lock)); - - $locks = $backend->getLocks('someuri', false); - - $this->assertEquals(1, count($locks)); - $this->assertEquals('Sinterklaas', $locks[0]->owner); - $this->assertEquals('someuri', $locks[0]->uri); - } - - /** - * @depends testGetLocks - */ - public function testGetLocksParent() - { - $backend = $this->getBackend(); - - $lock = new DAV\Locks\LockInfo(); - $lock->owner = 'Sinterklaas'; - $lock->timeout = 60; - $lock->created = time(); - $lock->depth = DAV\Server::DEPTH_INFINITY; - $lock->token = 'MY-UNIQUE-TOKEN'; - - $this->assertTrue($backend->lock('someuri', $lock)); - - $locks = $backend->getLocks('someuri/child', false); - - $this->assertEquals(1, count($locks)); - $this->assertEquals('Sinterklaas', $locks[0]->owner); - $this->assertEquals('someuri', $locks[0]->uri); - } - - /** - * @depends testGetLocks - */ - public function testGetLocksParentDepth0() - { - $backend = $this->getBackend(); - - $lock = new DAV\Locks\LockInfo(); - $lock->owner = 'Sinterklaas'; - $lock->timeout = 60; - $lock->created = time(); - $lock->depth = 0; - $lock->token = 'MY-UNIQUE-TOKEN'; - - $this->assertTrue($backend->lock('someuri', $lock)); - - $locks = $backend->getLocks('someuri/child', false); - - $this->assertEquals(0, count($locks)); - } - - public function testGetLocksChildren() - { - $backend = $this->getBackend(); - - $lock = new DAV\Locks\LockInfo(); - $lock->owner = 'Sinterklaas'; - $lock->timeout = 60; - $lock->created = time(); - $lock->depth = 0; - $lock->token = 'MY-UNIQUE-TOKEN'; - - $this->assertTrue($backend->lock('someuri/child', $lock)); - - $locks = $backend->getLocks('someuri/child', false); - $this->assertEquals(1, count($locks)); - - $locks = $backend->getLocks('someuri', false); - $this->assertEquals(0, count($locks)); - - $locks = $backend->getLocks('someuri', true); - $this->assertEquals(1, count($locks)); - } - - /** - * @depends testGetLocks - */ - public function testLockRefresh() - { - $backend = $this->getBackend(); - - $lock = new DAV\Locks\LockInfo(); - $lock->owner = 'Sinterklaas'; - $lock->timeout = 60; - $lock->created = time(); - $lock->token = 'MY-UNIQUE-TOKEN'; - - $this->assertTrue($backend->lock('someuri', $lock)); - /* Second time */ - - $lock->owner = 'Santa Clause'; - $this->assertTrue($backend->lock('someuri', $lock)); - - $locks = $backend->getLocks('someuri', false); - - $this->assertEquals(1, count($locks)); - - $this->assertEquals('Santa Clause', $locks[0]->owner); - $this->assertEquals('someuri', $locks[0]->uri); - } - - /** - * @depends testGetLocks - */ - public function testUnlock() - { - $backend = $this->getBackend(); - - $lock = new DAV\Locks\LockInfo(); - $lock->owner = 'Sinterklaas'; - $lock->timeout = 60; - $lock->created = time(); - $lock->token = 'MY-UNIQUE-TOKEN'; - - $this->assertTrue($backend->lock('someuri', $lock)); - - $locks = $backend->getLocks('someuri', false); - $this->assertEquals(1, count($locks)); - - $this->assertTrue($backend->unlock('someuri', $lock)); - - $locks = $backend->getLocks('someuri', false); - $this->assertEquals(0, count($locks)); - } - - /** - * @depends testUnlock - */ - public function testUnlockUnknownToken() - { - $backend = $this->getBackend(); - - $lock = new DAV\Locks\LockInfo(); - $lock->owner = 'Sinterklaas'; - $lock->timeout = 60; - $lock->created = time(); - $lock->token = 'MY-UNIQUE-TOKEN'; - - $this->assertTrue($backend->lock('someuri', $lock)); - - $locks = $backend->getLocks('someuri', false); - $this->assertEquals(1, count($locks)); - - $lock->token = 'SOME-OTHER-TOKEN'; - $this->assertFalse($backend->unlock('someuri', $lock)); - - $locks = $backend->getLocks('someuri', false); - $this->assertEquals(1, count($locks)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php deleted file mode 100644 index 57a3255c7..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/FileTest.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Locks\Backend; - -class FileTest extends AbstractTest -{ - public function getBackend() - { - \Sabre\TestUtil::clearTempDir(); - $backend = new File(SABRE_TEMPDIR.'/lockdb'); - - return $backend; - } - - public function teardown(): void - { - \Sabre\TestUtil::clearTempDir(); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php deleted file mode 100644 index 86ffc0bb3..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Locks\Backend; - -class PDOMySQLTest extends PDOTest -{ - public $driver = 'mysql'; -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php deleted file mode 100644 index f5ed98f50..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Locks\Backend; - -abstract class PDOTest extends AbstractTest -{ - use \Sabre\DAV\DbTestHelperTrait; - - public function getBackend() - { - $this->dropTables('locks'); - $this->createSchema('locks'); - - $pdo = $this->getPDO(); - - return new PDO($pdo); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php deleted file mode 100644 index 02c3d39ba..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Locks; - -use Sabre\DAV; -use Sabre\HTTP; - -class MSWordTest extends \PHPUnit\Framework\TestCase -{ - public function teardown(): void - { - \Sabre\TestUtil::clearTempDir(); - } - - public function testLockEtc() - { - mkdir(SABRE_TEMPDIR.'/mstest'); - $tree = new DAV\FS\Directory(SABRE_TEMPDIR.'/mstest'); - - $server = new DAV\Server($tree); - $server->debugExceptions = true; - $locksBackend = new Backend\File(SABRE_TEMPDIR.'/locksdb'); - $locksPlugin = new Plugin($locksBackend); - $server->addPlugin($locksPlugin); - - $response1 = new HTTP\ResponseMock(); - - $server->httpRequest = $this->getLockRequest(); - $server->httpResponse = $response1; - $server->sapi = new HTTP\SapiMock(); - $server->exec(); - - $this->assertEquals(201, $server->httpResponse->getStatus(), 'Full response body:'.$response1->getBodyAsString()); - $this->assertTrue((bool) $server->httpResponse->getHeaders('Lock-Token')); - $lockToken = $server->httpResponse->getHeader('Lock-Token'); - - //sleep(10); - - $response2 = new HTTP\ResponseMock(); - - $server->httpRequest = $this->getLockRequest2(); - $server->httpResponse = $response2; - $server->exec(); - - $this->assertEquals(201, $server->httpResponse->status); - $this->assertTrue((bool) $server->httpResponse->getHeaders('Lock-Token')); - - //sleep(10); - - $response3 = new HTTP\ResponseMock(); - $server->httpRequest = $this->getPutRequest($lockToken); - $server->httpResponse = $response3; - $server->exec(); - - $this->assertEquals(204, $server->httpResponse->status); - } - - public function getLockRequest() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'LOCK', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'HTTP_TIMEOUT' => 'Second-3600', - 'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx', - ]); - - $request->setBody('<D:lockinfo xmlns:D="DAV:"> - <D:lockscope> - <D:exclusive /> - </D:lockscope> - <D:locktype> - <D:write /> - </D:locktype> - <D:owner> - <D:href>PC-Vista\User</D:href> - </D:owner> -</D:lockinfo>'); - - return $request; - } - - public function getLockRequest2() - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'LOCK', - 'HTTP_CONTENT_TYPE' => 'application/xml', - 'HTTP_TIMEOUT' => 'Second-3600', - 'REQUEST_URI' => '/~$Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx', - ]); - - $request->setBody('<D:lockinfo xmlns:D="DAV:"> - <D:lockscope> - <D:exclusive /> - </D:lockscope> - <D:locktype> - <D:write /> - </D:locktype> - <D:owner> - <D:href>PC-Vista\User</D:href> - </D:owner> -</D:lockinfo>'); - - return $request; - } - - public function getPutRequest($lockToken) - { - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx', - 'HTTP_IF' => 'If: ('.$lockToken.')', - ]); - $request->setBody('FAKE BODY'); - - return $request; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php deleted file mode 100644 index 9279afb5a..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php +++ /dev/null @@ -1,886 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Locks; - -use Sabre\DAV; -use Sabre\HTTP; - -class PluginTest extends DAV\AbstractServer -{ - /** - * @var Plugin - */ - protected $locksPlugin; - - public function setup(): void - { - parent::setUp(); - $locksBackend = new Backend\File(SABRE_TEMPDIR.'/locksdb'); - $locksPlugin = new Plugin($locksBackend); - $this->server->addPlugin($locksPlugin); - $this->locksPlugin = $locksPlugin; - } - - public function testGetInfo() - { - $this->assertArrayHasKey( - 'name', - $this->locksPlugin->getPluginInfo() - ); - } - - public function testGetFeatures() - { - $this->assertEquals([2], $this->locksPlugin->getFeatures()); - } - - public function testGetHTTPMethods() - { - $this->assertEquals(['LOCK', 'UNLOCK'], $this->locksPlugin->getHTTPMethods('')); - } - - public function testLockNoBody() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals(400, $this->response->status); - } - - public function testLock() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status, 'Got an incorrect status back. Response body: '.$this->response->getBodyAsString()); - - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $this->response->getBodyAsString()); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - - $elements = [ - '/d:prop', - '/d:prop/d:lockdiscovery', - '/d:prop/d:lockdiscovery/d:activelock', - '/d:prop/d:lockdiscovery/d:activelock/d:locktype', - '/d:prop/d:lockdiscovery/d:activelock/d:lockroot', - '/d:prop/d:lockdiscovery/d:activelock/d:lockroot/d:href', - '/d:prop/d:lockdiscovery/d:activelock/d:locktype/d:write', - '/d:prop/d:lockdiscovery/d:activelock/d:lockscope', - '/d:prop/d:lockdiscovery/d:activelock/d:lockscope/d:exclusive', - '/d:prop/d:lockdiscovery/d:activelock/d:depth', - '/d:prop/d:lockdiscovery/d:activelock/d:owner', - '/d:prop/d:lockdiscovery/d:activelock/d:timeout', - '/d:prop/d:lockdiscovery/d:activelock/d:locktoken', - '/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href', - ]; - - foreach ($elements as $elem) { - $data = $xml->xpath($elem); - $this->assertEquals(1, count($data), 'We expected 1 match for the xpath expression "'.$elem.'". '.count($data).' were found. Full response body: '.$this->response->getBodyAsString()); - } - - $depth = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:depth'); - $this->assertEquals('infinity', (string) $depth[0]); - - $token = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href'); - $this->assertEquals($this->response->getHeader('Lock-Token'), '<'.(string) $token[0].'>', 'Token in response body didn\'t match token in response header.'); - } - - public function testLockWithContext() - { - $request = new HTTP\Request('LOCK', '/baseuri/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->setBaseUri('baseuri'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(200, $this->response->status, 'Got an incorrect status back. Response body: '.$this->response->getBodyAsString()); - - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $this->response->getBodyAsString()); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - - $lockRoot = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:lockroot/d:href'); - $this->assertEquals('baseuri/test.txt', (string) $lockRoot[0]); - } - - /** - * @depends testLock - */ - public function testDoubleLock() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->response = new HTTP\ResponseMock(); - $this->server->httpResponse = $this->response; - - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - - $this->assertEquals(423, $this->response->status, 'Full response: '.$this->response->getBodyAsString()); - } - - /** - * @depends testLock - */ - public function testLockRefresh() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $lockToken = $this->response->getHeader('Lock-Token'); - - $this->response = new HTTP\ResponseMock(); - $this->server->httpResponse = $this->response; - - $request = new HTTP\Request('LOCK', '/test.txt', ['If' => '('.$lockToken.')']); - $request->setBody(''); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - - $this->assertEquals(200, $this->response->status, 'We received an incorrect status code. Full response body: '.$this->response->getBody()); - } - - /** - * @depends testLock - */ - public function testLockRefreshBadToken() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $lockToken = $this->response->getHeader('Lock-Token'); - - $this->response = new HTTP\ResponseMock(); - $this->server->httpResponse = $this->response; - - $request = new HTTP\Request('LOCK', '/test.txt', ['If' => '('.$lockToken.'foobar) (<opaquelocktoken:anotherbadtoken>)']); - $request->setBody(''); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - - $this->assertEquals(423, $this->response->getStatus(), 'We received an incorrect status code. Full response body: '.$this->response->getBody()); - } - - /** - * @depends testLock - */ - public function testLockNoFile() - { - $request = new HTTP\Request('LOCK', '/notfound.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(201, $this->response->status); - } - - /** - * @depends testLock - */ - public function testUnlockNoToken() - { - $request = new HTTP\Request('UNLOCK', '/test.txt'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals(400, $this->response->status); - } - - /** - * @depends testLock - */ - public function testUnlockBadToken() - { - $request = new HTTP\Request('UNLOCK', '/test.txt', ['Lock-Token' => '<opaquelocktoken:blablabla>']); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals(409, $this->response->status, 'Got an incorrect status code. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testLock - */ - public function testLockPutNoToken() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('PUT', '/test.txt'); - $request->setBody('newbody'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(423, $this->response->status); - } - - /** - * @depends testLock - */ - public function testUnlock() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $this->server->httpRequest = $request; - - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->invokeMethod($request, $this->server->httpResponse); - $lockToken = $this->server->httpResponse->getHeader('Lock-Token'); - - $request = new HTTP\Request('UNLOCK', '/test.txt', ['Lock-Token' => $lockToken]); - $this->server->httpRequest = $request; - $this->server->httpResponse = new HTTP\ResponseMock(); - $this->server->invokeMethod($request, $this->server->httpResponse); - - $this->assertEquals(204, $this->server->httpResponse->status, 'Got an incorrect status code. Full response body: '.$this->response->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - ], - $this->server->httpResponse->getHeaders() - ); - } - - /** - * @depends testLock - */ - public function testUnlockWindowsBug() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $this->server->httpRequest = $request; - - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->invokeMethod($request, $this->server->httpResponse); - $lockToken = $this->server->httpResponse->getHeader('Lock-Token'); - - // See Issue 123 - $lockToken = trim($lockToken, '<>'); - - $request = new HTTP\Request('UNLOCK', '/test.txt', ['Lock-Token' => $lockToken]); - $this->server->httpRequest = $request; - $this->server->httpResponse = new HTTP\ResponseMock(); - $this->server->invokeMethod($request, $this->server->httpResponse); - - $this->assertEquals(204, $this->server->httpResponse->status, 'Got an incorrect status code. Full response body: '.$this->response->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Length' => ['0'], - ], - $this->server->httpResponse->getHeaders() - ); - } - - /** - * @depends testLock - */ - public function testLockRetainOwner() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $this->server->httpRequest = $request; - - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner>Evert</D:owner> -</D:lockinfo>'); - - $this->server->invokeMethod($request, $this->server->httpResponse); - $lockToken = $this->server->httpResponse->getHeader('Lock-Token'); - - $locks = $this->locksPlugin->getLocks('test.txt'); - $this->assertEquals(1, count($locks)); - $this->assertEquals('Evert', $locks[0]->owner); - } - - /** - * @depends testLock - */ - public function testLockPutBadToken() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('PUT', '/test.txt', [ - 'If' => '(<opaquelocktoken:token1>)', - ]); - $request->setBody('newbody'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - // $this->assertEquals('412 Precondition failed',$this->response->status); - $this->assertEquals(423, $this->response->status); - } - - /** - * @depends testLock - */ - public function testLockDeleteParent() - { - $request = new HTTP\Request('LOCK', '/dir/child.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('DELETE', '/dir'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(423, $this->response->status); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - } - - /** - * @depends testLock - */ - public function testLockDeleteSucceed() - { - $request = new HTTP\Request('LOCK', '/dir/child.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('DELETE', '/dir/child.txt', [ - 'If' => '('.$this->response->getHeader('Lock-Token').')', - ]); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(204, $this->response->status); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - } - - /** - * @depends testLock - */ - public function testLockCopyLockSource() - { - $request = new HTTP\Request('LOCK', '/dir/child.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('COPY', '/dir/child.txt', [ - 'Destination' => '/dir/child2.txt', - ]); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(201, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination'); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - } - - /** - * @depends testLock - */ - public function testLockCopyLockDestination() - { - $request = new HTTP\Request('LOCK', '/dir/child2.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(201, $this->response->status); - - $request = new HTTP\Request('COPY', '/dir/child.txt', [ - 'Destination' => '/dir/child2.txt', - ]); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(423, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination'); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - } - - /** - * @depends testLock - */ - public function testLockMoveLockSourceLocked() - { - $request = new HTTP\Request('LOCK', '/dir/child.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('MOVE', '/dir/child.txt', [ - 'Destination' => '/dir/child2.txt', - ]); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(423, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination'); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - } - - /** - * @depends testLock - */ - public function testLockMoveLockSourceSucceed() - { - $request = new HTTP\Request('LOCK', '/dir/child.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('MOVE', '/dir/child.txt', [ - 'Destination' => '/dir/child2.txt', - 'If' => '('.$this->response->getHeader('Lock-Token').')', - ]); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(201, $this->response->status, 'A valid lock-token was provided for the source, so this MOVE operation must succeed. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testLock - */ - public function testLockMoveLockDestination() - { - $request = new HTTP\Request('LOCK', '/dir/child2.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(201, $this->response->status); - - $request = new HTTP\Request('MOVE', '/dir/child.txt', [ - 'Destination' => '/dir/child2.txt', - ]); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(423, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination'); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - } - - /** - * @depends testLock - */ - public function testLockMoveLockParent() - { - $request = new HTTP\Request('LOCK', '/dir', [ - 'Depth' => 'infinite', - ]); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('MOVE', '/dir/child.txt', [ - 'Destination' => '/dir/child2.txt', - 'If' => '</dir> ('.$this->response->getHeader('Lock-Token').')', - ]); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(201, $this->response->status, 'We locked the parent of both the source and destination, but the move didn\'t succeed.'); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - } - - /** - * @depends testLock - */ - public function testLockPutGoodToken() - { - $request = new HTTP\Request('LOCK', '/test.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(200, $this->response->status); - - $request = new HTTP\Request('PUT', '/test.txt', [ - 'If' => '('.$this->response->getHeader('Lock-Token').')', - ]); - $request->setBody('newbody'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(204, $this->response->status); - } - - /** - * @depends testLock - */ - public function testLockPutUnrelatedToken() - { - $request = new HTTP\Request('LOCK', '/unrelated.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(201, $this->response->getStatus()); - - $request = new HTTP\Request( - 'PUT', - '/test.txt', - ['If' => '</unrelated.txt> ('.$this->response->getHeader('Lock-Token').')'] - ); - $request->setBody('newbody'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - - $this->assertEquals(204, $this->response->status); - } - - public function testPutWithIncorrectETag() - { - $request = new HTTP\Request('PUT', '/test.txt', [ - 'If' => '(["etag1"])', - ]); - $request->setBody('newbody'); - $this->server->httpRequest = $request; - $this->server->exec(); - $this->assertEquals(412, $this->response->status); - } - - /** - * @depends testPutWithIncorrectETag - */ - public function testPutWithCorrectETag() - { - // We need an ETag-enabled file node. - $tree = new DAV\Tree(new DAV\FSExt\Directory(SABRE_TEMPDIR)); - $this->server->tree = $tree; - - $filename = SABRE_TEMPDIR.'/test.txt'; - $etag = sha1( - fileinode($filename). - filesize($filename). - filemtime($filename) - ); - - $request = new HTTP\Request('PUT', '/test.txt', [ - 'If' => '(["'.$etag.'"])', - ]); - $request->setBody('newbody'); - - $this->server->httpRequest = $request; - $this->server->exec(); - $this->assertEquals(204, $this->response->status, 'Incorrect status received. Full response body:'.$this->response->getBodyAsString()); - } - - public function testDeleteWithETagOnCollection() - { - $request = new HTTP\Request('DELETE', '/dir', [ - 'If' => '(["etag1"])', - ]); - - $this->server->httpRequest = $request; - $this->server->exec(); - $this->assertEquals(412, $this->response->status); - } - - public function testGetTimeoutHeader() - { - $request = new HTTP\Request('LOCK', '/foo/bar', [ - 'Timeout' => 'second-100', - ]); - - $this->server->httpRequest = $request; - $this->assertEquals(100, $this->locksPlugin->getTimeoutHeader()); - } - - public function testGetTimeoutHeaderTwoItems() - { - $request = new HTTP\Request('LOCK', '/foo/bar', [ - 'Timeout' => 'second-5, infinite', - ]); - $this->server->httpRequest = $request; - $this->assertEquals(5, $this->locksPlugin->getTimeoutHeader()); - } - - public function testGetTimeoutHeaderInfinite() - { - $request = new HTTP\Request('LOCK', '/foo/bar', [ - 'Timeout' => 'infinite, second-5', - ]); - $this->server->httpRequest = $request; - $this->assertEquals(LockInfo::TIMEOUT_INFINITE, $this->locksPlugin->getTimeoutHeader()); - } - - public function testGetTimeoutHeaderInvalid() - { - $this->expectException('Sabre\DAV\Exception\BadRequest'); - $request = new HTTP\Request('GET', '/', ['Timeout' => 'yourmom']); - - $this->server->httpRequest = $request; - $this->locksPlugin->getTimeoutHeader(); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Mock/Collection.php b/vendor/sabre/dav/tests/Sabre/DAV/Mock/Collection.php deleted file mode 100644 index 041274706..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Mock/Collection.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Mock; - -use Sabre\DAV; - -/** - * Mock Collection. - * - * This collection quickly allows you to create trees of nodes. - * Children are specified as an array. - * - * Every key a filename, every array value is either: - * * an array, for a sub-collection - * * a string, for a file - * * An instance of \Sabre\DAV\INode. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class Collection extends DAV\Collection -{ - protected $name; - protected $children; - protected $parent; - - /** - * Creates the object. - * - * @param string $name - * @param Collection $parent - */ - public function __construct($name, array $children = [], Collection $parent = null) - { - $this->name = $name; - foreach ($children as $key => $value) { - if (is_string($value)) { - $this->children[] = new File($key, $value, $this); - } elseif (is_array($value)) { - $this->children[] = new self($key, $value, $this); - } elseif ($value instanceof \Sabre\DAV\INode) { - $this->children[] = $value; - } else { - throw new \InvalidArgumentException('Unknown value passed in $children'); - } - } - $this->parent = $parent; - } - - /** - * Returns the name of the node. - * - * This is used to generate the url. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Creates a new file in the directory. - * - * Data will either be supplied as a stream resource, or in certain cases - * as a string. Keep in mind that you may have to support either. - * - * After successful creation of the file, you may choose to return the ETag - * of the new file here. - * - * The returned ETag must be surrounded by double-quotes (The quotes should - * be part of the actual string). - * - * If you cannot accurately determine the ETag, you should not return it. - * If you don't store the file exactly as-is (you're transforming it - * somehow) you should also not return an ETag. - * - * This means that if a subsequent GET to this new file does not exactly - * return the same contents of what was submitted here, you are strongly - * recommended to omit the ETag. - * - * @param string $name Name of the file - * @param resource|string $data Initial payload - * - * @return string|null - */ - public function createFile($name, $data = null) - { - if (null === $data) { - $data = ''; - } - if (is_resource($data)) { - $data = stream_get_contents($data); - } - $this->children[] = new File($name, $data, $this); - - return '"'.md5($data).'"'; - } - - /** - * Creates a new subdirectory. - * - * @param string $name - */ - public function createDirectory($name) - { - $this->children[] = new self($name); - } - - /** - * Returns an array with all the child nodes. - * - * @return \Sabre\DAV\INode[] - */ - public function getChildren() - { - return $this->children; - } - - /** - * Adds an already existing node to this collection. - */ - public function addNode(\Sabre\DAV\INode $node) - { - $this->children[] = $node; - } - - /** - * Removes a childnode from this node. - * - * @param string $name - */ - public function deleteChild($name) - { - foreach ($this->children as $key => $value) { - if ($value->getName() == $name) { - unset($this->children[$key]); - - return; - } - } - } - - /** - * Deletes this collection and all its children,. - */ - public function delete() - { - foreach ($this->getChildren() as $child) { - $this->deleteChild($child->getName()); - } - $this->parent->deleteChild($this->getName()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Mock/File.php b/vendor/sabre/dav/tests/Sabre/DAV/Mock/File.php deleted file mode 100644 index d48ddaa92..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Mock/File.php +++ /dev/null @@ -1,151 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Mock; - -use Sabre\DAV; - -/** - * Mock File. - * - * See the Collection in this directory for more details. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class File extends DAV\File -{ - protected $name; - protected $contents; - protected $parent; - protected $lastModified; - - /** - * Creates the object. - * - * @param string $name - * @param resource $contents - * @param Collection $parent - * @param int $lastModified - */ - public function __construct($name, $contents, Collection $parent = null, $lastModified = -1) - { - $this->name = $name; - $this->put($contents); - $this->parent = $parent; - - if (-1 === $lastModified) { - $lastModified = time(); - } - - $this->lastModified = $lastModified; - } - - /** - * Returns the name of the node. - * - * This is used to generate the url. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Changes the name of the node. - * - * @param string $name - */ - public function setName($name) - { - $this->name = $name; - } - - /** - * Updates the data. - * - * The data argument is a readable stream resource. - * - * After a successful put operation, you may choose to return an ETag. The - * etag must always be surrounded by double-quotes. These quotes must - * appear in the actual string you're returning. - * - * Clients may use the ETag from a PUT request to later on make sure that - * when they update the file, the contents haven't changed in the mean - * time. - * - * If you don't plan to store the file byte-by-byte, and you return a - * different object on a subsequent GET you are strongly recommended to not - * return an ETag, and just return null. - * - * @param resource $data - * - * @return string|null - */ - public function put($data) - { - if (is_resource($data)) { - $data = stream_get_contents($data); - } - $this->contents = $data; - - return '"'.md5($data).'"'; - } - - /** - * Returns the data. - * - * This method may either return a string or a readable stream resource - * - * @return mixed - */ - public function get() - { - return $this->contents; - } - - /** - * Returns the ETag for a file. - * - * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change. - * - * Return null if the ETag can not effectively be determined - */ - public function getETag() - { - return '"'.md5($this->contents).'"'; - } - - /** - * Returns the size of the node, in bytes. - * - * @return int - */ - public function getSize() - { - return strlen($this->contents); - } - - /** - * Delete the node. - */ - public function delete() - { - $this->parent->deleteChild($this->name); - } - - /** - * Returns the last modification time as a unix timestamp. - * If the information is not available, return null. - * - * @return int - */ - public function getLastModified() - { - return $this->lastModified; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php deleted file mode 100644 index 54f7e4cb4..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\Mount; - -use Sabre\DAV; -use Sabre\HTTP; - -class PluginTest extends DAV\AbstractServer -{ - public function setup(): void - { - parent::setUp(); - $this->server->addPlugin(new Plugin()); - } - - public function testPassThrough() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'GET', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(501, $this->response->status, 'We expected GET to not be implemented for Directories. Response body: '.$this->response->getBodyAsString()); - } - - public function testMountResponse() - { - $serverVars = [ - 'REQUEST_URI' => '/?mount', - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'mount', - 'HTTP_HOST' => 'example.org', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(200, $this->response->status); - - $xml = simplexml_load_string($this->response->getBodyAsString()); - $this->assertInstanceOf('SimpleXMLElement', $xml, 'Response was not a valid xml document. The list of errors:'.print_r(libxml_get_errors(), true).'. xml body: '.$this->response->getBodyAsString().'. What type we got: '.gettype($xml).' class, if object: '.get_class($xml)); - - $xml->registerXPathNamespace('dm', 'http://purl.org/NET/webdav/mount'); - $url = $xml->xpath('//dm:url'); - $this->assertEquals('http://example.org/', (string) $url[0]); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php deleted file mode 100644 index 7066c49fc..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -class ObjectTreeTest extends \PHPUnit\Framework\TestCase -{ - protected $tree; - - public function setup(): void - { - \Sabre\TestUtil::clearTempDir(); - mkdir(SABRE_TEMPDIR.'/root'); - mkdir(SABRE_TEMPDIR.'/root/subdir'); - file_put_contents(SABRE_TEMPDIR.'/root/file.txt', 'contents'); - file_put_contents(SABRE_TEMPDIR.'/root/subdir/subfile.txt', 'subcontents'); - $rootNode = new FSExt\Directory(SABRE_TEMPDIR.'/root'); - $this->tree = new Tree($rootNode); - } - - public function teardown(): void - { - \Sabre\TestUtil::clearTempDir(); - } - - public function testGetRootNode() - { - $root = $this->tree->getNodeForPath(''); - $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory', $root); - } - - public function testGetSubDir() - { - $root = $this->tree->getNodeForPath('subdir'); - $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory', $root); - } - - public function testCopyFile() - { - $this->tree->copy('file.txt', 'file2.txt'); - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt')); - $this->assertEquals('contents', file_get_contents(SABRE_TEMPDIR.'/root/file2.txt')); - } - - /** - * @depends testCopyFile - */ - public function testCopyDirectory() - { - $this->tree->copy('subdir', 'subdir2'); - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2')); - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); - $this->assertEquals('subcontents', file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); - } - - /** - * @depends testCopyFile - */ - public function testMoveFile() - { - $this->tree->move('file.txt', 'file2.txt'); - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt')); - $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt')); - $this->assertEquals('contents', file_get_contents(SABRE_TEMPDIR.'/root/file2.txt')); - } - - /** - * @depends testMoveFile - */ - public function testMoveFileNewParent() - { - $this->tree->move('file.txt', 'subdir/file2.txt'); - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir/file2.txt')); - $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt')); - $this->assertEquals('contents', file_get_contents(SABRE_TEMPDIR.'/root/subdir/file2.txt')); - } - - /** - * @depends testCopyDirectory - */ - public function testMoveDirectory() - { - $this->tree->move('subdir', 'subdir2'); - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2')); - $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); - $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/subdir')); - $this->assertEquals('subcontents', file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php deleted file mode 100644 index 72fdb5ec8..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\PartialUpdate; - -use Sabre\DAV; - -class FileMock implements IPatchSupport -{ - protected $data = ''; - - public function put($str) - { - if (is_resource($str)) { - $str = stream_get_contents($str); - } - $this->data = $str; - } - - /** - * Updates the file based on a range specification. - * - * The first argument is the data, which is either a readable stream - * resource or a string. - * - * The second argument is the type of update we're doing. - * This is either: - * * 1. append - * * 2. update based on a start byte - * * 3. update based on an end byte - *; - * The third argument is the start or end byte. - * - * After a successful put operation, you may choose to return an ETag. The - * etag must always be surrounded by double-quotes. These quotes must - * appear in the actual string you're returning. - * - * Clients may use the ETag from a PUT request to later on make sure that - * when they update the file, the contents haven't changed in the mean - * time. - * - * @param resource|string $data - * @param int $rangeType - * @param int $offset - * - * @return string|null - */ - public function patch($data, $rangeType, $offset = null) - { - if (is_resource($data)) { - $data = stream_get_contents($data); - } - - switch ($rangeType) { - case 1: - $this->data .= $data; - break; - case 3: - // Turn the offset into an offset-offset. - $offset = strlen($this->data) - $offset; - // no break is intentional - case 2: - $this->data = - substr($this->data, 0, $offset). - $data. - substr($this->data, $offset + strlen($data)); - break; - } - } - - public function get() - { - return $this->data; - } - - public function getContentType() - { - return 'text/plain'; - } - - public function getSize() - { - return strlen($this->data); - } - - public function getETag() - { - return '"'.$this->data.'"'; - } - - public function delete() - { - throw new DAV\Exception\MethodNotAllowed(); - } - - public function setName($name) - { - throw new DAV\Exception\MethodNotAllowed(); - } - - public function getName() - { - return 'partial'; - } - - public function getLastModified() - { - return null; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php deleted file mode 100644 index 4d99aee7d..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/PluginTest.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\PartialUpdate; - -use Sabre\HTTP; - -class PluginTest extends \Sabre\DAVServerTest -{ - protected $node; - protected $plugin; - - public function setup(): void - { - $this->node = new FileMock(); - $this->tree[] = $this->node; - - parent::setUp(); - - $this->plugin = new Plugin(); - $this->server->addPlugin($this->plugin); - } - - public function testInit() - { - $this->assertEquals('partialupdate', $this->plugin->getPluginName()); - $this->assertEquals(['sabredav-partialupdate'], $this->plugin->getFeatures()); - $this->assertEquals([ - 'PATCH', - ], $this->plugin->getHTTPMethods('partial')); - $this->assertEquals([ - ], $this->plugin->getHTTPMethods('')); - } - - public function testPatchNoRange() - { - $this->node->put('aaaaaaaa'); - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PATCH', - 'REQUEST_URI' => '/partial', - ]); - $response = $this->request($request); - - $this->assertEquals(400, $response->status, 'Full response body:'.$response->getBodyAsString()); - } - - public function testPatchNotSupported() - { - $this->node->put('aaaaaaaa'); - $request = new HTTP\Request('PATCH', '/', ['X-Update-Range' => '3-4']); - $request->setBody( - 'bbb' - ); - $response = $this->request($request); - - $this->assertEquals(405, $response->status, 'Full response body:'.$response->getBodyAsString()); - } - - public function testPatchNoContentType() - { - $this->node->put('aaaaaaaa'); - $request = new HTTP\Request('PATCH', '/partial', ['X-Update-Range' => 'bytes=3-4']); - $request->setBody( - 'bbb' - ); - $response = $this->request($request); - - $this->assertEquals(415, $response->status, 'Full response body:'.$response->getBodyAsString()); - } - - public function testPatchBadRange() - { - $this->node->put('aaaaaaaa'); - $request = new HTTP\Request('PATCH', '/partial', ['X-Update-Range' => 'bytes=3-4', 'Content-Type' => 'application/x-sabredav-partialupdate', 'Content-Length' => '3']); - $request->setBody( - 'bbb' - ); - $response = $this->request($request); - - $this->assertEquals(416, $response->status, 'Full response body:'.$response->getBodyAsString()); - } - - public function testPatchNoLength() - { - $this->node->put('aaaaaaaa'); - $request = new HTTP\Request('PATCH', '/partial', ['X-Update-Range' => 'bytes=3-5', 'Content-Type' => 'application/x-sabredav-partialupdate']); - $request->setBody( - 'bbb' - ); - $response = $this->request($request); - - $this->assertEquals(411, $response->status, 'Full response body:'.$response->getBodyAsString()); - } - - public function testPatchSuccess() - { - $this->node->put('aaaaaaaa'); - $request = new HTTP\Request('PATCH', '/partial', ['X-Update-Range' => 'bytes=3-5', 'Content-Type' => 'application/x-sabredav-partialupdate', 'Content-Length' => 3]); - $request->setBody( - 'bbb' - ); - $response = $this->request($request); - - $this->assertEquals(204, $response->status, 'Full response body:'.$response->getBodyAsString()); - $this->assertEquals('aaabbbaa', $this->node->get()); - } - - public function testPatchNoEndRange() - { - $this->node->put('aaaaa'); - $request = new HTTP\Request('PATCH', '/partial', ['X-Update-Range' => 'bytes=3-', 'Content-Type' => 'application/x-sabredav-partialupdate', 'Content-Length' => '3']); - $request->setBody( - 'bbb' - ); - - $response = $this->request($request); - - $this->assertEquals(204, $response->getStatus(), 'Full response body:'.$response->getBodyAsString()); - $this->assertEquals('aaabbb', $this->node->get()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php deleted file mode 100644 index a727a13e2..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV\PartialUpdate; - -use Sabre\DAV\FSExt\File; -use Sabre\DAV\Server; -use Sabre\HTTP; - -/** - * This test is an end-to-end sabredav test that goes through all - * the cases in the specification. - * - * See: http://sabre.io/dav/http-patch/ - */ -class SpecificationTest extends \PHPUnit\Framework\TestCase -{ - protected $server; - - public function setup(): void - { - $tree = [ - new File(SABRE_TEMPDIR.'/foobar.txt'), - ]; - $server = new Server($tree); - $server->debugExceptions = true; - $server->addPlugin(new Plugin()); - - $tree[0]->put('1234567890'); - - $this->server = $server; - } - - public function teardown(): void - { - \Sabre\TestUtil::clearTempDir(); - } - - /** - * @param string $headerValue - * @param string $httpStatus - * @param string $endResult - * @param int $contentLength - * - * @dataProvider data - */ - public function testUpdateRange($headerValue, $httpStatus, $endResult, $contentLength = 4) - { - $headers = [ - 'Content-Type' => 'application/x-sabredav-partialupdate', - 'X-Update-Range' => $headerValue, - ]; - - if ($contentLength) { - $headers['Content-Length'] = (string) $contentLength; - } - - $request = new HTTP\Request('PATCH', '/foobar.txt', $headers, '----'); - - $request->setBody('----'); - $this->server->httpRequest = $request; - $this->server->httpResponse = new HTTP\ResponseMock(); - $this->server->sapi = new HTTP\SapiMock(); - $this->server->exec(); - - $this->assertEquals($httpStatus, $this->server->httpResponse->status, 'Incorrect http status received: '.$this->server->httpResponse->body); - if (!is_null($endResult)) { - $this->assertEquals($endResult, file_get_contents(SABRE_TEMPDIR.'/foobar.txt')); - } - } - - public function data() - { - return [ - // Problems - ['foo', 400, null], - ['bytes=0-3', 411, null, 0], - ['bytes=4-1', 416, null], - - ['bytes=0-3', 204, '----567890'], - ['bytes=1-4', 204, '1----67890'], - ['bytes=0-', 204, '----567890'], - ['bytes=-4', 204, '123456----'], - ['bytes=-2', 204, '12345678----'], - ['bytes=2-', 204, '12----7890'], - ['append', 204, '1234567890----'], - ]; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php deleted file mode 100644 index b1f6754ea..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class ServerEventsTest extends AbstractServer -{ - private $tempPath; - - private $exception; - - public function testAfterBind() - { - $this->server->on('afterBind', [$this, 'afterBindHandler']); - $newPath = 'afterBind'; - - $this->tempPath = ''; - $this->server->createFile($newPath, 'body'); - $this->assertEquals($newPath, $this->tempPath); - } - - public function afterBindHandler($path) - { - $this->tempPath = $path; - } - - public function testAfterResponse() - { - $mock = $this->getMockBuilder('stdClass') - ->setMethods(['afterResponseCallback']) - ->getMock(); - $mock->expects($this->once())->method('afterResponseCallback'); - - $this->server->on('afterResponse', [$mock, 'afterResponseCallback']); - - $this->server->httpRequest = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/test.txt', - ]); - - $this->server->exec(); - } - - public function testBeforeBindCancel() - { - $this->server->on('beforeBind', [$this, 'beforeBindCancelHandler']); - $this->assertFalse($this->server->createFile('bla', 'body')); - - // Also testing put() - $req = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'PUT', - 'REQUEST_URI' => '/barbar', - ]); - - $this->server->httpRequest = $req; - $this->server->exec(); - - $this->assertEquals(500, $this->server->httpResponse->getStatus()); - } - - public function beforeBindCancelHandler($path) - { - return false; - } - - public function testException() - { - $this->server->on('exception', [$this, 'exceptionHandler']); - - $req = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/not/exisitng', - ]); - $this->server->httpRequest = $req; - $this->server->exec(); - - $this->assertInstanceOf('Sabre\\DAV\\Exception\\NotFound', $this->exception); - } - - public function exceptionHandler(Exception $exception) - { - $this->exception = $exception; - } - - public function testMethod() - { - $k = 1; - $this->server->on('method:*', function ($request, $response) use (&$k) { - ++$k; - - return false; - }); - $this->server->on('method:*', function ($request, $response) use (&$k) { - $k += 2; - - return false; - }); - - try { - $this->server->invokeMethod( - new HTTP\Request('BLABLA', '/'), - new HTTP\Response(), - false - ); - } catch (Exception $e) { - } - - // Fun fact, PHP 7.1 changes the order when sorting-by-callback. - $this->assertTrue($k >= 2 && $k <= 3); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php deleted file mode 100644 index 02c6a4633..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php +++ /dev/null @@ -1,354 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class ServerMKCOLTest extends AbstractServer -{ - public function testMkcol() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody(''); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - ], $this->response->getHeaders()); - - $this->assertEquals(201, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertTrue(is_dir($this->tempDir.'/testcol')); - } - - /** - * @depends testMkcol - */ - public function testMKCOLUnknownBody() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody('Hello'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(415, $this->response->status); - } - - /** - * @depends testMkcol - */ - public function testMKCOLBrokenXML() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - 'HTTP_CONTENT_TYPE' => 'application/xml', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody('Hello'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(400, $this->response->getStatus(), $this->response->getBodyAsString()); - } - - /** - * @depends testMkcol - */ - public function testMKCOLUnknownXML() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - 'HTTP_CONTENT_TYPE' => 'application/xml', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody('<?xml version="1.0"?><html></html>'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(400, $this->response->getStatus()); - } - - /** - * @depends testMkcol - */ - public function testMKCOLNoResourceType() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - 'HTTP_CONTENT_TYPE' => 'application/xml', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody('<?xml version="1.0"?> -<mkcol xmlns="DAV:"> - <set> - <prop> - <displayname>Evert</displayname> - </prop> - </set> -</mkcol>'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(400, $this->response->status, 'Wrong statuscode received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testMkcol - */ - public function testMKCOLIncorrectResourceType() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - 'HTTP_CONTENT_TYPE' => 'application/xml', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody('<?xml version="1.0"?> -<mkcol xmlns="DAV:"> - <set> - <prop> - <resourcetype><collection /><blabla /></resourcetype> - </prop> - </set> -</mkcol>'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(403, $this->response->status, 'Wrong statuscode received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testMKCOLIncorrectResourceType - */ - public function testMKCOLSuccess() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - 'HTTP_CONTENT_TYPE' => 'application/xml', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody('<?xml version="1.0"?> -<mkcol xmlns="DAV:"> - <set> - <prop> - <resourcetype><collection /></resourcetype> - </prop> - </set> -</mkcol>'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - ], $this->response->getHeaders()); - - $this->assertEquals(201, $this->response->status, 'Wrong statuscode received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testMKCOLIncorrectResourceType - */ - public function testMKCOLWhiteSpaceResourceType() - { - $serverVars = [ - 'REQUEST_URI' => '/testcol', - 'REQUEST_METHOD' => 'MKCOL', - 'HTTP_CONTENT_TYPE' => 'application/xml', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody('<?xml version="1.0"?> -<mkcol xmlns="DAV:"> - <set> - <prop> - <resourcetype> - <collection /> - </resourcetype> - </prop> - </set> -</mkcol>'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Length' => ['0'], - ], $this->response->getHeaders()); - - $this->assertEquals(201, $this->response->status, 'Wrong statuscode received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testMKCOLIncorrectResourceType - */ - public function testMKCOLNoParent() - { - $serverVars = [ - 'REQUEST_URI' => '/testnoparent/409me', - 'REQUEST_METHOD' => 'MKCOL', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody(''); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(409, $this->response->status, 'Wrong statuscode received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testMKCOLIncorrectResourceType - */ - public function testMKCOLParentIsNoCollection() - { - $serverVars = [ - 'REQUEST_URI' => '/test.txt/409me', - 'REQUEST_METHOD' => 'MKCOL', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody(''); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(409, $this->response->status, 'Wrong statuscode received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testMKCOLIncorrectResourceType - */ - public function testMKCOLAlreadyExists() - { - $serverVars = [ - 'REQUEST_URI' => '/test.txt', - 'REQUEST_METHOD' => 'MKCOL', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody(''); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT'], - ], $this->response->getHeaders()); - - $this->assertEquals(405, $this->response->status, 'Wrong statuscode received. Full response body: '.$this->response->getBodyAsString()); - } - - /** - * @depends testMKCOLSuccess - * @depends testMKCOLAlreadyExists - */ - public function testMKCOLAndProps() - { - $request = new HTTP\Request( - 'MKCOL', - '/testcol', - ['Content-Type' => 'application/xml'] - ); - $request->setBody('<?xml version="1.0"?> -<mkcol xmlns="DAV:"> - <set> - <prop> - <resourcetype><collection /></resourcetype> - <displayname>my new collection</displayname> - </prop> - </set> -</mkcol>'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $bodyAsString = $this->response->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Wrong statuscode received. Full response body: '.$bodyAsString); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $expected = <<<XML -<?xml version="1.0"?> -<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"> - <d:response> - <d:href>/testcol</d:href> - <d:propstat> - <d:prop> - <d:displayname /> - </d:prop> - <d:status>HTTP/1.1 403 Forbidden</d:status> - </d:propstat> - </d:response> -</d:multistatus> -XML; - - $this->assertXmlStringEqualsXmlString( - $expected, - $bodyAsString - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php deleted file mode 100644 index 47e1e6b4c..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class ServerPluginTest extends AbstractServer -{ - /** - * @var Sabre\DAV\TestPlugin - */ - protected $testPlugin; - - public function setup(): void - { - parent::setUp(); - - $testPlugin = new TestPlugin(); - $this->server->addPlugin($testPlugin); - $this->testPlugin = $testPlugin; - } - - public function testBaseClass() - { - $p = new ServerPluginMock(); - $this->assertEquals([], $p->getFeatures()); - $this->assertEquals([], $p->getHTTPMethods('')); - $this->assertEquals( - [ - 'name' => 'Sabre\DAV\ServerPluginMock', - 'description' => null, - 'link' => null, - ], $p->getPluginInfo() - ); - } - - public function testOptions() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'OPTIONS', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'DAV' => ['1, 3, extended-mkcol, drinking'], - 'MS-Author-Via' => ['DAV'], - 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT, BEER, WINE'], - 'Accept-Ranges' => ['bytes'], - 'Content-Length' => ['0'], - 'X-Sabre-Version' => [Version::VERSION], - ], $this->response->getHeaders()); - - $this->assertEquals(200, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals('OPTIONS', $this->testPlugin->beforeMethod); - } - - public function testGetPlugin() - { - $this->assertEquals($this->testPlugin, $this->server->getPlugin(get_class($this->testPlugin))); - } - - public function testUnknownPlugin() - { - $this->assertNull($this->server->getPlugin('SomeRandomClassName')); - } - - public function testGetSupportedReportSet() - { - $this->assertEquals([], $this->testPlugin->getSupportedReportSet('/')); - } - - public function testGetPlugins() - { - $this->assertEquals( - [ - get_class($this->testPlugin) => $this->testPlugin, - 'core' => $this->server->getPlugin('core'), - ], - $this->server->getPlugins() - ); - } -} - -class ServerPluginMock extends ServerPlugin -{ - public function initialize(Server $s) - { - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php deleted file mode 100644 index cd1ccfa53..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ServerPropsTest.php +++ /dev/null @@ -1,194 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class ServerPropsTest extends AbstractServer -{ - protected function getRootNode() - { - return new FSExt\Directory(SABRE_TEMPDIR); - } - - public function setup(): void - { - if (file_exists(SABRE_TEMPDIR.'../.sabredav')) { - unlink(SABRE_TEMPDIR.'../.sabredav'); - } - parent::setUp(); - file_put_contents(SABRE_TEMPDIR.'/test2.txt', 'Test contents2'); - mkdir(SABRE_TEMPDIR.'/col'); - file_put_contents(SABRE_TEMPDIR.'col/test.txt', 'Test contents'); - $this->server->addPlugin(new Locks\Plugin(new Locks\Backend\File(SABRE_TEMPDIR.'/.locksdb'))); - } - - public function teardown(): void - { - parent::tearDown(); - if (file_exists(SABRE_TEMPDIR.'../.locksdb')) { - unlink(SABRE_TEMPDIR.'../.locksdb'); - } - } - - private function sendRequest($body, $path = '/', $headers = ['Depth' => '0']) - { - $request = new HTTP\Request('PROPFIND', $path, $headers, $body); - - $this->server->httpRequest = $request; - $this->server->exec(); - } - - public function testPropFindEmptyBody() - { - $this->sendRequest(''); - $this->assertEquals(207, $this->response->status); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'DAV' => ['1, 3, extended-mkcol, 2'], - 'Vary' => ['Brief,Prefer'], - ], - $this->response->getHeaders() - ); - - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $this->response->getBodyAsString()); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - - list($data) = $xml->xpath('/d:multistatus/d:response/d:href'); - $this->assertEquals('/', (string) $data, 'href element should have been /'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype'); - $this->assertEquals(1, count($data)); - } - - public function testPropFindEmptyBodyFile() - { - $this->sendRequest('', '/test2.txt', []); - $this->assertEquals(207, $this->response->status); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'DAV' => ['1, 3, extended-mkcol, 2'], - 'Vary' => ['Brief,Prefer'], - ], - $this->response->getHeaders() - ); - - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $this->response->getBodyAsString()); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - - list($data) = $xml->xpath('/d:multistatus/d:response/d:href'); - $this->assertEquals('/test2.txt', (string) $data, 'href element should have been /test2.txt'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength'); - $this->assertEquals(1, count($data)); - } - - public function testSupportedLocks() - { - $xml = '<?xml version="1.0"?> -<d:propfind xmlns:d="DAV:"> - <d:prop> - <d:supportedlock /> - </d:prop> -</d:propfind>'; - - $this->sendRequest($xml); - - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $this->response->getBodyAsString()); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry'); - $this->assertEquals(2, count($data), 'We expected two \'d:lockentry\' tags'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope'); - $this->assertEquals(2, count($data), 'We expected two \'d:lockscope\' tags'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype'); - $this->assertEquals(2, count($data), 'We expected two \'d:locktype\' tags'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:shared'); - $this->assertEquals(1, count($data), 'We expected a \'d:shared\' tag'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:exclusive'); - $this->assertEquals(1, count($data), 'We expected a \'d:exclusive\' tag'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype/d:write'); - $this->assertEquals(2, count($data), 'We expected two \'d:write\' tags'); - } - - public function testLockDiscovery() - { - $xml = '<?xml version="1.0"?> -<d:propfind xmlns:d="DAV:"> - <d:prop> - <d:lockdiscovery /> - </d:prop> -</d:propfind>'; - - $this->sendRequest($xml); - - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $this->response->getBodyAsString()); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:lockdiscovery'); - $this->assertEquals(1, count($data), 'We expected a \'d:lockdiscovery\' tag'); - } - - public function testUnknownProperty() - { - $xml = '<?xml version="1.0"?> -<d:propfind xmlns:d="DAV:"> - <d:prop> - <d:macaroni /> - </d:prop> -</d:propfind>'; - - $this->sendRequest($xml); - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $this->response->getBodyAsString()); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - $pathTests = [ - '/d:multistatus', - '/d:multistatus/d:response', - '/d:multistatus/d:response/d:propstat', - '/d:multistatus/d:response/d:propstat/d:status', - '/d:multistatus/d:response/d:propstat/d:prop', - '/d:multistatus/d:response/d:propstat/d:prop/d:macaroni', - ]; - foreach ($pathTests as $test) { - $this->assertTrue(true == count($xml->xpath($test)), 'We expected the '.$test.' element to appear in the response, we got: '.$body); - } - - $val = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status'); - $this->assertEquals(1, count($val), $body); - $this->assertEquals('HTTP/1.1 404 Not Found', (string) $val[0]); - } - - public function testParsePropPatchRequest() - { - $body = '<?xml version="1.0"?> -<d:propertyupdate xmlns:d="DAV:" xmlns:s="http://sabredav.org/NS/test"> - <d:set><d:prop><s:someprop>somevalue</s:someprop></d:prop></d:set> - <d:remove><d:prop><s:someprop2 /></d:prop></d:remove> - <d:set><d:prop><s:someprop3>removeme</s:someprop3></d:prop></d:set> - <d:remove><d:prop><s:someprop3 /></d:prop></d:remove> -</d:propertyupdate>'; - - $result = $this->server->xml->parse($body); - $this->assertEquals([ - '{http://sabredav.org/NS/test}someprop' => 'somevalue', - '{http://sabredav.org/NS/test}someprop2' => null, - '{http://sabredav.org/NS/test}someprop3' => null, - ], $result->properties); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php deleted file mode 100644 index 6d5be4608..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ServerRangeTest.php +++ /dev/null @@ -1,252 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use DateTime; -use Sabre\HTTP; - -/** - * This file tests HTTP requests that use the Range: header. - * - * @copyright Copyright (C) fruux GmbH. (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class ServerRangeTest extends \Sabre\DAVServerTest -{ - protected $setupFiles = true; - - /** - * We need this string a lot. - */ - protected $lastModified; - - public function setup(): void - { - parent::setUp(); - $this->server->createFile('files/test.txt', 'Test contents'); - - $this->lastModified = HTTP\toDate( - new DateTime('@'.$this->server->tree->getNodeForPath('files/test.txt')->getLastModified()) - ); - - $stream = popen('echo "Test contents"', 'r'); - $streamingFile = new Mock\StreamingFile( - 'no-seeking.txt', - $stream - ); - $streamingFile->setSize(12); - $this->server->tree->getNodeForPath('files')->addNode($streamingFile); - } - - public function testRange() - { - $request = new HTTP\Request('GET', '/files/test.txt', ['Range' => 'bytes=2-5']); - $response = $this->request($request); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [4], - 'Content-Range' => ['bytes 2-5/13'], - 'ETag' => ['"'.md5('Test contents').'"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - $this->assertEquals(206, $response->getStatus()); - $this->assertEquals('st c', $response->getBodyAsString()); - } - - /** - * @depends testRange - */ - public function testStartRange() - { - $request = new HTTP\Request('GET', '/files/test.txt', ['Range' => 'bytes=2-']); - $response = $this->request($request); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [11], - 'Content-Range' => ['bytes 2-12/13'], - 'ETag' => ['"'.md5('Test contents').'"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - - $this->assertEquals(206, $response->getStatus()); - $this->assertEquals('st contents', $response->getBodyAsString()); - } - - /** - * @depends testRange - */ - public function testEndRange() - { - $request = new HTTP\Request('GET', '/files/test.txt', ['Range' => 'bytes=-8']); - $response = $this->request($request); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [8], - 'Content-Range' => ['bytes 5-12/13'], - 'ETag' => ['"'.md5('Test contents').'"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - - $this->assertEquals(206, $response->getStatus()); - $this->assertEquals('contents', $response->getBodyAsString()); - } - - /** - * @depends testRange - */ - public function testTooHighRange() - { - $request = new HTTP\Request('GET', '/files/test.txt', ['Range' => 'bytes=100-200']); - $response = $this->request($request); - - $this->assertEquals(416, $response->getStatus()); - } - - /** - * @depends testRange - */ - public function testCrazyRange() - { - $request = new HTTP\Request('GET', '/files/test.txt', ['Range' => 'bytes=8-4']); - $response = $this->request($request); - - $this->assertEquals(416, $response->getStatus()); - } - - public function testNonSeekableStream() - { - $request = new HTTP\Request('GET', '/files/no-seeking.txt', ['Range' => 'bytes=2-5']); - $response = $this->request($request); - - $this->assertEquals(206, $response->getStatus()); - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [4], - 'Content-Range' => ['bytes 2-5/12'], - // 'ETag' => ['"' . md5('Test contents') . '"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - - $this->assertEquals('st c', $response->getBodyAsString()); - } - - /** - * @depends testRange - */ - public function testIfRangeEtag() - { - $request = new HTTP\Request('GET', '/files/test.txt', [ - 'Range' => 'bytes=2-5', - 'If-Range' => '"'.md5('Test contents').'"', - ]); - $response = $this->request($request); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [4], - 'Content-Range' => ['bytes 2-5/13'], - 'ETag' => ['"'.md5('Test contents').'"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - - $this->assertEquals(206, $response->getStatus()); - $this->assertEquals('st c', $response->getBodyAsString()); - } - - /** - * @depends testIfRangeEtag - */ - public function testIfRangeEtagIncorrect() - { - $request = new HTTP\Request('GET', '/files/test.txt', [ - 'Range' => 'bytes=2-5', - 'If-Range' => '"foobar"', - ]); - $response = $this->request($request); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [13], - 'ETag' => ['"'.md5('Test contents').'"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals('Test contents', $response->getBodyAsString()); - } - - /** - * @depends testIfRangeEtag - */ - public function testIfRangeModificationDate() - { - $request = new HTTP\Request('GET', '/files/test.txt', [ - 'Range' => 'bytes=2-5', - 'If-Range' => 'tomorrow', - ]); - $response = $this->request($request); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [4], - 'Content-Range' => ['bytes 2-5/13'], - 'ETag' => ['"'.md5('Test contents').'"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - - $this->assertEquals(206, $response->getStatus()); - $this->assertEquals('st c', $response->getBodyAsString()); - } - - /** - * @depends testIfRangeModificationDate - */ - public function testIfRangeModificationDateModified() - { - $request = new HTTP\Request('GET', '/files/test.txt', [ - 'Range' => 'bytes=2-5', - 'If-Range' => '-2 years', - ]); - $response = $this->request($request); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [13], - 'ETag' => ['"'.md5('Test contents').'"'], - 'Last-Modified' => [$this->lastModified], - ], - $response->getHeaders() - ); - - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals('Test contents', $response->getBodyAsString()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php deleted file mode 100644 index e4dd3cdb6..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php +++ /dev/null @@ -1,433 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class ServerSimpleTest extends AbstractServer -{ - public function testConstructArray() - { - $nodes = [ - new SimpleCollection('hello'), - ]; - - $server = new Server($nodes); - $this->assertEquals($nodes[0], $server->tree->getNodeForPath('hello')); - } - - public function testConstructInvalidArg() - { - $this->expectException('Sabre\DAV\Exception'); - $server = new Server(1); - } - - public function testOptions() - { - $request = new HTTP\Request('OPTIONS', '/'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals([ - 'DAV' => ['1, 3, extended-mkcol'], - 'MS-Author-Via' => ['DAV'], - 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT'], - 'Accept-Ranges' => ['bytes'], - 'Content-Length' => ['0'], - 'X-Sabre-Version' => [Version::VERSION], - ], $this->response->getHeaders()); - - $this->assertEquals(200, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - } - - public function testOptionsUnmapped() - { - $request = new HTTP\Request('OPTIONS', '/unmapped'); - $this->server->httpRequest = $request; - - $this->server->exec(); - - $this->assertEquals([ - 'DAV' => ['1, 3, extended-mkcol'], - 'MS-Author-Via' => ['DAV'], - 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT, MKCOL'], - 'Accept-Ranges' => ['bytes'], - 'Content-Length' => ['0'], - 'X-Sabre-Version' => [Version::VERSION], - ], $this->response->getHeaders()); - - $this->assertEquals(200, $this->response->status); - $this->assertEquals('', $this->response->getBodyAsString()); - } - - public function testNonExistantMethod() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'BLABLA', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(501, $this->response->status); - } - - public function testBaseUri() - { - $serverVars = [ - 'REQUEST_URI' => '/blabla/test.txt', - 'REQUEST_METHOD' => 'GET', - ]; - $filename = $this->tempDir.'/test.txt'; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->setBaseUri('/blabla/'); - $this->assertEquals('/blabla/', $this->server->getBaseUri()); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/octet-stream'], - 'Content-Length' => [13], - 'Last-Modified' => [HTTP\toDate(new \DateTime('@'.filemtime($filename)))], - 'ETag' => ['"'.sha1(fileinode($filename).filesize($filename).filemtime($filename)).'"'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals(200, $this->response->status); - $this->assertEquals('Test contents', stream_get_contents($this->response->body)); - } - - public function testBaseUriAddSlash() - { - $tests = [ - '/' => '/', - '/foo' => '/foo/', - '/foo/' => '/foo/', - '/foo/bar' => '/foo/bar/', - '/foo/bar/' => '/foo/bar/', - ]; - - foreach ($tests as $test => $result) { - $this->server->setBaseUri($test); - - $this->assertEquals($result, $this->server->getBaseUri()); - } - } - - public function testCalculateUri() - { - $uris = [ - 'http://www.example.org/root/somepath', - '/root/somepath', - '/root/somepath/', - '//root/somepath/', - '///root///somepath///', - ]; - - $this->server->setBaseUri('/root/'); - - foreach ($uris as $uri) { - $this->assertEquals('somepath', $this->server->calculateUri($uri)); - } - - $this->server->setBaseUri('/root'); - - foreach ($uris as $uri) { - $this->assertEquals('somepath', $this->server->calculateUri($uri)); - } - - $this->assertEquals('', $this->server->calculateUri('/root')); - - $this->server->setBaseUri('/'); - - foreach ($uris as $uri) { - $this->assertEquals('root/somepath', $this->server->calculateUri($uri)); - } - - $this->assertEquals('', $this->server->calculateUri('')); - } - - public function testCalculateUriSpecialChars() - { - $uris = [ - 'http://www.example.org/root/%C3%A0fo%C3%B3', - '/root/%C3%A0fo%C3%B3', - '/root/%C3%A0fo%C3%B3/', - ]; - - $this->server->setBaseUri('/root/'); - - foreach ($uris as $uri) { - $this->assertEquals("\xc3\xa0fo\xc3\xb3", $this->server->calculateUri($uri)); - } - - $this->server->setBaseUri('/root'); - - foreach ($uris as $uri) { - $this->assertEquals("\xc3\xa0fo\xc3\xb3", $this->server->calculateUri($uri)); - } - - $this->server->setBaseUri('/'); - - foreach ($uris as $uri) { - $this->assertEquals("root/\xc3\xa0fo\xc3\xb3", $this->server->calculateUri($uri)); - } - } - - public function testCalculateUriBreakout() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $uri = '/path1/'; - - $this->server->setBaseUri('/path2/'); - $this->server->calculateUri($uri); - } - - public function testGuessBaseUri() - { - $serverVars = [ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/index.php/root', - 'PATH_INFO' => '/root', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals('/index.php/', $server->guessBaseUri()); - } - - /** - * @depends testGuessBaseUri - */ - public function testGuessBaseUriPercentEncoding() - { - $serverVars = [ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/index.php/dir/path2/path%20with%20spaces', - 'PATH_INFO' => '/dir/path2/path with spaces', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals('/index.php/', $server->guessBaseUri()); - } - - /** - * @depends testGuessBaseUri - */ - /* - function testGuessBaseUriPercentEncoding2() { - - $this->markTestIncomplete('This behaviour is not yet implemented'); - $serverVars = [ - 'REQUEST_URI' => '/some%20directory+mixed/index.php/dir/path2/path%20with%20spaces', - 'PATH_INFO' => '/dir/path2/path with spaces', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals('/some%20directory+mixed/index.php/', $server->guessBaseUri()); - - }*/ - - public function testGuessBaseUri2() - { - $serverVars = [ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/index.php/root/', - 'PATH_INFO' => '/root/', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals('/index.php/', $server->guessBaseUri()); - } - - public function testGuessBaseUriNoPathInfo() - { - $serverVars = [ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/index.php/root', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals('/', $server->guessBaseUri()); - } - - public function testGuessBaseUriNoPathInfo2() - { - $httpRequest = new HTTP\Request('GET', '/a/b/c/test.php'); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals('/', $server->guessBaseUri()); - } - - /** - * @depends testGuessBaseUri - */ - public function testGuessBaseUriQueryString() - { - $serverVars = [ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/index.php/root?query_string=blabla', - 'PATH_INFO' => '/root', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $this->assertEquals('/index.php/', $server->guessBaseUri()); - } - - /** - * @depends testGuessBaseUri - */ - public function testGuessBaseUriBadConfig() - { - $this->expectException('Sabre\DAV\Exception'); - $serverVars = [ - 'REQUEST_METHOD' => 'GET', - 'REQUEST_URI' => '/index.php/root/heyyy', - 'PATH_INFO' => '/root', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $server = new Server(); - $server->httpRequest = $httpRequest; - - $server->guessBaseUri(); - } - - public function testTriggerException() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'FOO', - ]; - - $httpRequest = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->httpRequest = $httpRequest; - $this->server->on('beforeMethod:*', [$this, 'exceptionTrigger']); - $this->server->exec(); - - $this->assertEquals([ - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $this->assertEquals(500, $this->response->status); - } - - public function exceptionTrigger($request, $response) - { - throw new Exception('Hola'); - } - - public function testReportNotFound() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'REPORT', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->httpRequest = ($request); - $this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>'); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals(415, $this->response->status, 'We got an incorrect status back. Full response body follows: '.$this->response->getBodyAsString()); - } - - public function testReportIntercepted() - { - $serverVars = [ - 'REQUEST_URI' => '/', - 'REQUEST_METHOD' => 'REPORT', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $this->server->httpRequest = ($request); - $this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>'); - $this->server->on('report', [$this, 'reportHandler']); - $this->server->exec(); - - $this->assertEquals([ - 'X-Sabre-Version' => [Version::VERSION], - 'testheader' => ['testvalue'], - ], - $this->response->getHeaders() - ); - - $this->assertEquals(418, $this->response->status, 'We got an incorrect status back. Full response body follows: '.$this->response->getBodyAsString()); - } - - public function reportHandler($reportName, $result, $path) - { - if ('{http://www.rooftopsolutions.nl/NS}myreport' == $reportName) { - $this->server->httpResponse->setStatus(418); - $this->server->httpResponse->setHeader('testheader', 'testvalue'); - - return false; - } else { - return; - } - } - - public function testGetPropertiesForChildren() - { - $result = $this->server->getPropertiesForChildren('', [ - '{DAV:}getcontentlength', - ]); - - $expected = [ - 'test.txt' => ['{DAV:}getcontentlength' => 13], - 'dir/' => [], - ]; - - $this->assertEquals($expected, $result); - } - - /** - * There are certain cases where no HTTP status may be set. We need to - * intercept these and set it to a default error message. - */ - public function testNoHTTPStatusSet() - { - $this->server->on('method:GET', function () { return false; }, 1); - $this->server->httpRequest = new HTTP\Request('GET', '/'); - $this->server->exec(); - $this->assertEquals(500, $this->response->getStatus()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php deleted file mode 100644 index cb8a4ab32..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php +++ /dev/null @@ -1,97 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -class ServerUpdatePropertiesTest extends \PHPUnit\Framework\TestCase -{ - public function testUpdatePropertiesFail() - { - $tree = [ - new SimpleCollection('foo'), - ]; - $server = new Server($tree); - - $result = $server->updateProperties('foo', [ - '{DAV:}foo' => 'bar', - ]); - - $expected = [ - '{DAV:}foo' => 403, - ]; - $this->assertEquals($expected, $result); - } - - public function testUpdatePropertiesProtected() - { - $tree = [ - new SimpleCollection('foo'), - ]; - $server = new Server($tree); - - $server->on('propPatch', function ($path, PropPatch $propPatch) { - $propPatch->handleRemaining(function () { return true; }); - }); - $result = $server->updateProperties('foo', [ - '{DAV:}getetag' => 'bla', - '{DAV:}foo' => 'bar', - ]); - - $expected = [ - '{DAV:}getetag' => 403, - '{DAV:}foo' => 424, - ]; - $this->assertEquals($expected, $result); - } - - public function testUpdatePropertiesEventFail() - { - $tree = [ - new SimpleCollection('foo'), - ]; - $server = new Server($tree); - $server->on('propPatch', function ($path, PropPatch $propPatch) { - $propPatch->setResultCode('{DAV:}foo', 404); - $propPatch->handleRemaining(function () { return true; }); - }); - - $result = $server->updateProperties('foo', [ - '{DAV:}foo' => 'bar', - '{DAV:}foo2' => 'bla', - ]); - - $expected = [ - '{DAV:}foo' => 404, - '{DAV:}foo2' => 424, - ]; - $this->assertEquals($expected, $result); - } - - public function testUpdatePropertiesEventSuccess() - { - $tree = [ - new SimpleCollection('foo'), - ]; - $server = new Server($tree); - $server->on('propPatch', function ($path, PropPatch $propPatch) { - $propPatch->handle(['{DAV:}foo', '{DAV:}foo2'], function () { - return [ - '{DAV:}foo' => 200, - '{DAV:}foo2' => 201, - ]; - }); - }); - - $result = $server->updateProperties('foo', [ - '{DAV:}foo' => 'bar', - '{DAV:}foo2' => 'bla', - ]); - - $expected = [ - '{DAV:}foo' => 200, - '{DAV:}foo2' => 201, - ]; - $this->assertEquals($expected, $result); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php deleted file mode 100644 index 6edca5ecc..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -class SimpleFileTest extends \PHPUnit\Framework\TestCase -{ - public function testAll() - { - $file = new SimpleFile('filename.txt', 'contents', 'text/plain'); - - $this->assertEquals('filename.txt', $file->getName()); - $this->assertEquals('contents', $file->get()); - $this->assertEquals(8, $file->getSize()); - $this->assertEquals('"'.sha1('contents').'"', $file->getETag()); - $this->assertEquals('text/plain', $file->getContentType()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php deleted file mode 100644 index bc36c6b78..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -class StringUtilTest extends \PHPUnit\Framework\TestCase -{ - /** - * @param string $haystack - * @param string $needle - * @param string $collation - * @param string $matchType - * @param string $result - * - * @throws Exception\BadRequest - * - * @dataProvider dataset - */ - public function testTextMatch($haystack, $needle, $collation, $matchType, $result) - { - $this->assertEquals($result, StringUtil::textMatch($haystack, $needle, $collation, $matchType)); - } - - public function dataset() - { - return [ - ['FOOBAR', 'FOO', 'i;octet', 'contains', true], - ['FOOBAR', 'foo', 'i;octet', 'contains', false], - ['FÖÖBAR', 'FÖÖ', 'i;octet', 'contains', true], - ['FÖÖBAR', 'föö', 'i;octet', 'contains', false], - ['FOOBAR', 'FOOBAR', 'i;octet', 'equals', true], - ['FOOBAR', 'fooBAR', 'i;octet', 'equals', false], - ['FOOBAR', 'FOO', 'i;octet', 'starts-with', true], - ['FOOBAR', 'foo', 'i;octet', 'starts-with', false], - ['FOOBAR', 'BAR', 'i;octet', 'starts-with', false], - ['FOOBAR', 'bar', 'i;octet', 'starts-with', false], - ['FOOBAR', 'FOO', 'i;octet', 'ends-with', false], - ['FOOBAR', 'foo', 'i;octet', 'ends-with', false], - ['FOOBAR', 'BAR', 'i;octet', 'ends-with', true], - ['FOOBAR', 'bar', 'i;octet', 'ends-with', false], - - ['FOOBAR', 'FOO', 'i;ascii-casemap', 'contains', true], - ['FOOBAR', 'foo', 'i;ascii-casemap', 'contains', true], - ['FÖÖBAR', 'FÖÖ', 'i;ascii-casemap', 'contains', true], - ['FÖÖBAR', 'föö', 'i;ascii-casemap', 'contains', false], - ['FOOBAR', 'FOOBAR', 'i;ascii-casemap', 'equals', true], - ['FOOBAR', 'fooBAR', 'i;ascii-casemap', 'equals', true], - ['FOOBAR', 'FOO', 'i;ascii-casemap', 'starts-with', true], - ['FOOBAR', 'foo', 'i;ascii-casemap', 'starts-with', true], - ['FOOBAR', 'BAR', 'i;ascii-casemap', 'starts-with', false], - ['FOOBAR', 'bar', 'i;ascii-casemap', 'starts-with', false], - ['FOOBAR', 'FOO', 'i;ascii-casemap', 'ends-with', false], - ['FOOBAR', 'foo', 'i;ascii-casemap', 'ends-with', false], - ['FOOBAR', 'BAR', 'i;ascii-casemap', 'ends-with', true], - ['FOOBAR', 'bar', 'i;ascii-casemap', 'ends-with', true], - - ['FOOBAR', 'FOO', 'i;unicode-casemap', 'contains', true], - ['FOOBAR', 'foo', 'i;unicode-casemap', 'contains', true], - ['FÖÖBAR', 'FÖÖ', 'i;unicode-casemap', 'contains', true], - ['FÖÖBAR', 'föö', 'i;unicode-casemap', 'contains', true], - ['FOOBAR', 'FOOBAR', 'i;unicode-casemap', 'equals', true], - ['FOOBAR', 'fooBAR', 'i;unicode-casemap', 'equals', true], - ['FOOBAR', 'FOO', 'i;unicode-casemap', 'starts-with', true], - ['FOOBAR', 'foo', 'i;unicode-casemap', 'starts-with', true], - ['FOOBAR', 'BAR', 'i;unicode-casemap', 'starts-with', false], - ['FOOBAR', 'bar', 'i;unicode-casemap', 'starts-with', false], - ['FOOBAR', 'FOO', 'i;unicode-casemap', 'ends-with', false], - ['FOOBAR', 'foo', 'i;unicode-casemap', 'ends-with', false], - ['FOOBAR', 'BAR', 'i;unicode-casemap', 'ends-with', true], - ['FOOBAR', 'bar', 'i;unicode-casemap', 'ends-with', true], - ]; - } - - public function testBadCollation() - { - $this->expectException('Sabre\DAV\Exception\BadRequest'); - StringUtil::textMatch('foobar', 'foo', 'blabla', 'contains'); - } - - public function testBadMatchType() - { - $this->expectException('Sabre\DAV\Exception\BadRequest'); - StringUtil::textMatch('foobar', 'foo', 'i;octet', 'booh'); - } - - public function testEnsureUTF8_ascii() - { - $inputString = 'harkema'; - $outputString = 'harkema'; - - $this->assertEquals( - $outputString, - StringUtil::ensureUTF8($inputString) - ); - } - - public function testEnsureUTF8_latin1() - { - $inputString = "m\xfcnster"; - $outputString = 'münster'; - - $this->assertEquals( - $outputString, - StringUtil::ensureUTF8($inputString) - ); - } - - public function testEnsureUTF8_utf8() - { - $inputString = "m\xc3\xbcnster"; - $outputString = 'münster'; - - $this->assertEquals( - $outputString, - StringUtil::ensureUTF8($inputString) - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php deleted file mode 100644 index 951078bf0..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php +++ /dev/null @@ -1,204 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP; - -class TemporaryFileFilterTest extends AbstractServer -{ - public function setup(): void - { - parent::setUp(); - $plugin = new TemporaryFileFilterPlugin(SABRE_TEMPDIR.'/tff'); - $this->server->addPlugin($plugin); - } - - public function testPutNormal() - { - $request = new HTTP\Request('PUT', '/testput.txt', [], 'Testing new file'); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals(201, $this->response->status); - $this->assertEquals('0', $this->response->getHeader('Content-Length')); - - $this->assertEquals('Testing new file', file_get_contents(SABRE_TEMPDIR.'/testput.txt')); - } - - public function testPutTemp() - { - // mimicking an OS/X resource fork - $request = new HTTP\Request('PUT', '/._testput.txt', [], 'Testing new file'); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals(201, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - ], $this->response->getHeaders()); - - $this->assertFalse(file_exists(SABRE_TEMPDIR.'/._testput.txt'), '._testput.txt should not exist in the regular file structure.'); - } - - public function testPutTempIfNoneMatch() - { - // mimicking an OS/X resource fork - $request = new HTTP\Request('PUT', '/._testput.txt', ['If-None-Match' => '*'], 'Testing new file'); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals(201, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - ], $this->response->getHeaders()); - - $this->assertFalse(file_exists(SABRE_TEMPDIR.'/._testput.txt'), '._testput.txt should not exist in the regular file structure.'); - - $this->server->exec(); - - $this->assertEquals(412, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - } - - public function testPutGet() - { - // mimicking an OS/X resource fork - $request = new HTTP\Request('PUT', '/._testput.txt', [], 'Testing new file'); - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals(201, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - ], $this->response->getHeaders()); - - $request = new HTTP\Request('GET', '/._testput.txt'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(200, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - 'Content-Length' => [16], - 'Content-Type' => ['application/octet-stream'], - ], $this->response->getHeaders()); - - $this->assertEquals('Testing new file', stream_get_contents($this->response->body)); - } - - public function testGetWithBrowserPlugin() - { - $this->server->addPlugin(new Browser\Plugin()); - $request = new HTTP\Request('GET', '/'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(200, $this->response->status); - } - - public function testLockNonExistant() - { - mkdir(SABRE_TEMPDIR.'/locksdir'); - $locksBackend = new Locks\Backend\File(SABRE_TEMPDIR.'/locks'); - $locksPlugin = new Locks\Plugin($locksBackend); - $this->server->addPlugin($locksPlugin); - - // mimicking an OS/X resource fork - $request = new HTTP\Request('LOCK', '/._testput.txt'); - $request->setBody('<?xml version="1.0"?> -<D:lockinfo xmlns:D="DAV:"> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - <D:owner> - <D:href>http://example.org/~ejw/contact.html</D:href> - </D:owner> -</D:lockinfo>'); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $this->assertEquals(201, $this->response->status); - $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type')); - $this->assertTrue(1 === preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')), 'We did not get a valid Locktoken back ('.$this->response->getHeader('Lock-Token').')'); - $this->assertEquals('true', $this->response->getHeader('X-Sabre-Temp')); - - $this->assertFalse(file_exists(SABRE_TEMPDIR.'/._testlock.txt'), '._testlock.txt should not exist in the regular file structure.'); - } - - public function testPutDelete() - { - // mimicking an OS/X resource fork - $request = new HTTP\Request('PUT', '/._testput.txt', [], 'Testing new file'); - - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals('', $this->response->getBodyAsString()); - $this->assertEquals(201, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - ], $this->response->getHeaders()); - - $request = new HTTP\Request('DELETE', '/._testput.txt'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $this->assertEquals(204, $this->response->status, "Incorrect status code received. Full body:\n".$this->response->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - ], $this->response->getHeaders()); - - $this->assertEquals('', $this->response->getBodyAsString()); - } - - public function testPutPropfind() - { - // mimicking an OS/X resource fork - $request = new HTTP\Request('PUT', '/._testput.txt', [], 'Testing new file'); - $this->server->httpRequest = $request; - $this->server->exec(); - - $bodyAsString = $this->response->getBodyAsString(); - $this->assertEquals('', $bodyAsString); - $this->assertEquals(201, $this->response->status); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - ], $this->response->getHeaders()); - - $request = new HTTP\Request('PROPFIND', '/._testput.txt'); - - $this->server->httpRequest = ($request); - $this->server->exec(); - - $bodyAsString = $this->response->getBodyAsString(); - $this->assertEquals(207, $this->response->status, 'Incorrect status code returned. Body: '.$bodyAsString); - $this->assertEquals([ - 'X-Sabre-Temp' => ['true'], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $this->response->getHeaders()); - - $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", 'xmlns\\1="urn:DAV"', $bodyAsString); - $xml = simplexml_load_string($body); - $xml->registerXPathNamespace('d', 'urn:DAV'); - - list($data) = $xml->xpath('/d:multistatus/d:response/d:href'); - $this->assertEquals('/._testput.txt', (string) $data, 'href element should have been /._testput.txt'); - - $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype'); - $this->assertEquals(1, count($data)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php b/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php deleted file mode 100644 index 3bfe3b3b0..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -use Sabre\HTTP\RequestInterface; -use Sabre\HTTP\ResponseInterface; - -class TestPlugin extends ServerPlugin -{ - public $beforeMethod; - - public function getFeatures() - { - return ['drinking']; - } - - public function getHTTPMethods($uri) - { - return ['BEER', 'WINE']; - } - - public function initialize(Server $server) - { - $server->on('beforeMethod:*', [$this, 'beforeMethod']); - } - - public function beforeMethod(RequestInterface $request, ResponseInterface $response) - { - $this->beforeMethod = $request->getMethod(); - - return true; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php deleted file mode 100644 index e3f04ea3a..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php +++ /dev/null @@ -1,238 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -class TreeTest extends \PHPUnit\Framework\TestCase -{ - public function testNodeExists() - { - $tree = new TreeMock(); - - $this->assertTrue($tree->nodeExists('hi')); - $this->assertFalse($tree->nodeExists('hello')); - } - - public function testCopy() - { - $tree = new TreeMock(); - $tree->copy('hi', 'hi2'); - - $this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories); - $this->assertEquals('foobar', $tree->getNodeForPath('hi/file')->get()); - $this->assertEquals(['test1' => 'value'], $tree->getNodeForPath('hi/file')->getProperties([])); - } - - public function testCopyFile() - { - $tree = new TreeMock(); - $tree->copy('hi/file', 'hi/newfile'); - - $this->assertArrayHasKey('newfile', $tree->getNodeForPath('hi')->newFiles); - } - - public function testCopyFile0() - { - $tree = new TreeMock(); - $tree->copy('hi/file', 'hi/0'); - - $this->assertArrayHasKey('0', $tree->getNodeForPath('hi')->newFiles); - } - - public function testMove() - { - $tree = new TreeMock(); - $tree->move('hi', 'hi2'); - - $this->assertEquals('hi2', $tree->getNodeForPath('hi')->getName()); - $this->assertTrue($tree->getNodeForPath('hi')->isRenamed); - } - - public function testDeepMove() - { - $tree = new TreeMock(); - $tree->move('hi/sub', 'hi2'); - - $this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories); - $this->assertTrue($tree->getNodeForPath('hi/sub')->isDeleted); - } - - public function testDelete() - { - $tree = new TreeMock(); - $tree->delete('hi'); - $this->assertTrue($tree->getNodeForPath('hi')->isDeleted); - } - - public function testGetChildren() - { - $tree = new TreeMock(); - $children = $tree->getChildren(''); - $firstChild = $children->current(); - $this->assertEquals('hi', $firstChild->getName()); - } - - public function testGetMultipleNodes() - { - $tree = new TreeMock(); - $result = $tree->getMultipleNodes(['hi/sub', 'hi/file']); - $this->assertArrayHasKey('hi/sub', $result); - $this->assertArrayHasKey('hi/file', $result); - - $this->assertEquals('sub', $result['hi/sub']->getName()); - $this->assertEquals('file', $result['hi/file']->getName()); - } - - public function testGetMultipleNodes2() - { - $tree = new TreeMock(); - $result = $tree->getMultipleNodes(['multi/1', 'multi/2']); - $this->assertArrayHasKey('multi/1', $result); - $this->assertArrayHasKey('multi/2', $result); - } -} - -class TreeMock extends Tree -{ - private $nodes = []; - - public function __construct() - { - $file = new TreeFileTester('file'); - $file->properties = ['test1' => 'value']; - $file->data = 'foobar'; - - parent::__construct( - new TreeDirectoryTester('root', [ - new TreeDirectoryTester('hi', [ - new TreeDirectoryTester('sub'), - $file, - ]), - new TreeMultiGetTester('multi', [ - new TreeFileTester('1'), - new TreeFileTester('2'), - new TreeFileTester('3'), - ]), - ]) - ); - } -} - -class TreeDirectoryTester extends SimpleCollection -{ - public $newDirectories = []; - public $newFiles = []; - public $isDeleted = false; - public $isRenamed = false; - - public function createDirectory($name) - { - $this->newDirectories[$name] = true; - } - - public function createFile($name, $data = null) - { - $this->newFiles[$name] = $data; - } - - public function getChild($name) - { - if (isset($this->newDirectories[$name])) { - return new self($name); - } - if (isset($this->newFiles[$name])) { - return new TreeFileTester($name, $this->newFiles[$name]); - } - - return parent::getChild($name); - } - - public function childExists($name) - { - return (bool) $this->getChild($name); - } - - public function delete() - { - $this->isDeleted = true; - } - - public function setName($name) - { - $this->isRenamed = true; - $this->name = $name; - } -} - -class TreeFileTester extends File implements IProperties -{ - public $name; - public $data; - public $properties; - - public function __construct($name, $data = null) - { - $this->name = $name; - if (is_null($data)) { - $data = 'bla'; - } - $this->data = $data; - } - - public function getName() - { - return $this->name; - } - - public function get() - { - return $this->data; - } - - public function getProperties($properties) - { - return $this->properties; - } - - /** - * Updates properties on this node. - * - * This method received a PropPatch object, which contains all the - * information about the update. - * - * To update specific properties, call the 'handle' method on this object. - * Read the PropPatch documentation for more information. - */ - public function propPatch(PropPatch $propPatch) - { - $this->properties = $propPatch->getMutations(); - $propPatch->setRemainingResultCode(200); - } -} - -class TreeMultiGetTester extends TreeDirectoryTester implements IMultiGet -{ - /** - * This method receives a list of paths in it's first argument. - * It must return an array with Node objects. - * - * If any children are not found, you do not have to return them. - * - * @return array - */ - public function getMultipleChildren(array $paths) - { - $result = []; - foreach ($paths as $path) { - try { - $child = $this->getChild($path); - $result[] = $child; - } catch (Exception\NotFound $e) { - // Do nothing - } - } - - return $result; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php deleted file mode 100644 index d7ef9bec9..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAV/UUIDUtilTest.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAV; - -class UUIDUtilTest extends \PHPUnit\Framework\TestCase -{ - public function testValidateUUID() - { - $this->assertTrue( - UUIDUtil::validateUUID('11111111-2222-3333-4444-555555555555') - ); - $this->assertFalse( - UUIDUtil::validateUUID(' 11111111-2222-3333-4444-555555555555') - ); - $this->assertTrue( - UUIDUtil::validateUUID('ffffffff-2222-3333-4444-555555555555') - ); - $this->assertFalse( - UUIDUtil::validateUUID('fffffffg-2222-3333-4444-555555555555') - ); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php deleted file mode 100644 index 715559df3..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php +++ /dev/null @@ -1,311 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; -use Sabre\HTTP; - -class ACLMethodTest extends \PHPUnit\Framework\TestCase -{ - public function testCallback() - { - $this->expectException('Sabre\DAV\Exception\BadRequest'); - $acl = new Plugin(); - $server = new DAV\Server(); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpAcl($server->httpRequest, $server->httpResponse); - } - - /** - /** - */ - public function testNotSupportedByNode() - { - $this->expectException('Sabre\DAV\Exception\MethodNotAllowed'); - $tree = [ - new DAV\SimpleCollection('test'), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('GET', '/'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testSuccessSimple() - { - $tree = [ - new MockACLNode('test', []), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('GET', '/'); - $server->httpRequest->setUrl('/test'); - - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $this->assertFalse($acl->httpACL($server->httpRequest, $server->httpResponse)); - } - - public function testUnrecognizedPrincipal() - { - $this->expectException('Sabre\DAVACL\Exception\NotRecognizedPrincipal'); - $tree = [ - new MockACLNode('test', []), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:read /></d:privilege></d:grant> - <d:principal><d:href>/principals/notfound</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testUnrecognizedPrincipal2() - { - $this->expectException('Sabre\DAVACL\Exception\NotRecognizedPrincipal'); - $tree = [ - new MockACLNode('test', []), - new DAV\SimpleCollection('principals', [ - new DAV\SimpleCollection('notaprincipal'), - ]), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:read /></d:privilege></d:grant> - <d:principal><d:href>/principals/notaprincipal</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testUnknownPrivilege() - { - $this->expectException('Sabre\DAVACL\Exception\NotSupportedPrivilege'); - $tree = [ - new MockACLNode('test', []), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:bananas /></d:privilege></d:grant> - <d:principal><d:href>/principals/notfound</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testAbstractPrivilege() - { - $this->expectException('Sabre\DAVACL\Exception\NoAbstract'); - $tree = [ - new MockACLNode('test', []), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->on('getSupportedPrivilegeSet', function ($node, &$supportedPrivilegeSet) { - $supportedPrivilegeSet['{DAV:}foo'] = ['abstract' => true]; - }); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:foo /></d:privilege></d:grant> - <d:principal><d:href>/principals/foo/</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testUpdateProtectedPrivilege() - { - $this->expectException('Sabre\DAVACL\Exception\AceConflict'); - $oldACL = [ - [ - 'principal' => 'principals/notfound', - 'privilege' => '{DAV:}write', - 'protected' => true, - ], - ]; - - $tree = [ - new MockACLNode('test', $oldACL), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:read /></d:privilege></d:grant> - <d:principal><d:href>/principals/notfound</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testUpdateProtectedPrivilege2() - { - $this->expectException('Sabre\DAVACL\Exception\AceConflict'); - $oldACL = [ - [ - 'principal' => 'principals/notfound', - 'privilege' => '{DAV:}write', - 'protected' => true, - ], - ]; - - $tree = [ - new MockACLNode('test', $oldACL), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:write /></d:privilege></d:grant> - <d:principal><d:href>/principals/foo</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testUpdateProtectedPrivilege3() - { - $this->expectException('Sabre\DAVACL\Exception\AceConflict'); - $oldACL = [ - [ - 'principal' => 'principals/notfound', - 'privilege' => '{DAV:}write', - 'protected' => true, - ], - ]; - - $tree = [ - new MockACLNode('test', $oldACL), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:write /></d:privilege></d:grant> - <d:principal><d:href>/principals/notfound</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $acl->httpACL($server->httpRequest, $server->httpResponse); - } - - public function testSuccessComplex() - { - $oldACL = [ - [ - 'principal' => 'principals/foo', - 'privilege' => '{DAV:}write', - 'protected' => true, - ], - [ - 'principal' => 'principals/bar', - 'privilege' => '{DAV:}read', - ], - ]; - - $tree = [ - $node = new MockACLNode('test', $oldACL), - new DAV\SimpleCollection('principals', [ - new MockPrincipal('foo', 'principals/foo'), - new MockPrincipal('baz', 'principals/baz'), - ]), - ]; - $acl = new Plugin(); - $server = new DAV\Server($tree); - $server->httpRequest = new HTTP\Request('ACL', '/test'); - $body = '<?xml version="1.0"?> -<d:acl xmlns:d="DAV:"> - <d:ace> - <d:grant><d:privilege><d:write /></d:privilege></d:grant> - <d:principal><d:href>/principals/foo</d:href></d:principal> - <d:protected /> - </d:ace> - <d:ace> - <d:grant><d:privilege><d:write /></d:privilege></d:grant> - <d:principal><d:href>/principals/baz</d:href></d:principal> - </d:ace> -</d:acl>'; - $server->httpRequest->setBody($body); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin($acl); - - $this->assertFalse($acl->httpAcl($server->httpRequest, $server->httpResponse)); - - $this->assertEquals([ - [ - 'principal' => 'principals/foo', - 'privilege' => '{DAV:}write', - 'protected' => true, - ], - [ - 'principal' => 'principals/baz', - 'privilege' => '{DAV:}write', - 'protected' => false, - ], - ], $node->getACL()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php deleted file mode 100644 index 04dd29c04..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; - -class AllowAccessTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var DAV\Server - */ - protected $server; - - public function setup(): void - { - $nodes = [ - new DAV\Mock\Collection('testdir', [ - 'file1.txt' => 'contents', - ]), - ]; - - $this->server = new DAV\Server($nodes); - $this->server->addPlugin( - new DAV\Auth\Plugin( - new DAV\Auth\Backend\Mock() - ) - ); - // Login - $this->server->getPlugin('auth')->beforeMethod( - new \Sabre\HTTP\Request('GET', '/'), - new \Sabre\HTTP\Response() - ); - $aclPlugin = new Plugin(); - $this->server->addPlugin($aclPlugin); - } - - public function testGet() - { - $this->server->httpRequest->setMethod('GET'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->assertTrue($this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testGetDoesntExist() - { - $this->server->httpRequest->setMethod('GET'); - $this->server->httpRequest->setUrl('/foo'); - - $this->assertTrue($this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testHEAD() - { - $this->server->httpRequest->setMethod('HEAD'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->assertTrue($this->server->emit('beforeMethod:HEAD', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testOPTIONS() - { - $this->server->httpRequest->setMethod('OPTIONS'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->assertTrue($this->server->emit('beforeMethod:OPTIONS', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testPUT() - { - $this->server->httpRequest->setMethod('PUT'); - $this->server->httpRequest->setUrl('/testdir/file1.txt'); - - $this->assertTrue($this->server->emit('beforeMethod:PUT', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testPROPPATCH() - { - $this->server->httpRequest->setMethod('PROPPATCH'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->assertTrue($this->server->emit('beforeMethod:PROPPATCH', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testCOPY() - { - $this->server->httpRequest->setMethod('COPY'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->assertTrue($this->server->emit('beforeMethod:COPY', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testMOVE() - { - $this->server->httpRequest->setMethod('MOVE'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->assertTrue($this->server->emit('beforeMethod:MOVE', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testLOCK() - { - $this->server->httpRequest->setMethod('LOCK'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->assertTrue($this->server->emit('beforeMethod:LOCK', [$this->server->httpRequest, $this->server->httpResponse])); - } - - public function testBeforeBind() - { - $this->assertTrue($this->server->emit('beforeBind', ['testdir/file'])); - } - - public function testBeforeUnbind() - { - $this->assertTrue($this->server->emit('beforeUnbind', ['testdir'])); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php deleted file mode 100644 index 566167ef0..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php +++ /dev/null @@ -1,180 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; - -class BlockAccessTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var DAV\Server - */ - protected $server; - protected $plugin; - - public function setup(): void - { - $nodes = [ - new DAV\SimpleCollection('testdir'), - ]; - - $this->server = new DAV\Server($nodes); - $this->plugin = new Plugin(); - $this->plugin->setDefaultAcl([]); - $this->server->addPlugin( - new DAV\Auth\Plugin( - new DAV\Auth\Backend\Mock() - ) - ); - // Login - $this->server->getPlugin('auth')->beforeMethod( - new \Sabre\HTTP\Request('GET', '/'), - new \Sabre\HTTP\Response() - ); - $this->server->addPlugin($this->plugin); - } - - public function testGet() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('GET'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testGetDoesntExist() - { - $this->server->httpRequest->setMethod('GET'); - $this->server->httpRequest->setUrl('/foo'); - - $r = $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - $this->assertTrue($r); - } - - public function testHEAD() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('HEAD'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testOPTIONS() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('OPTIONS'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testPUT() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('PUT'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testPROPPATCH() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('PROPPATCH'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testCOPY() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('COPY'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testMOVE() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('MOVE'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testACL() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('ACL'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testLOCK() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->httpRequest->setMethod('LOCK'); - $this->server->httpRequest->setUrl('/testdir'); - - $this->server->emit('beforeMethod:GET', [$this->server->httpRequest, $this->server->httpResponse]); - } - - public function testBeforeBind() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->emit('beforeBind', ['testdir/file']); - } - - public function testBeforeUnbind() - { - $this->expectException('Sabre\DAVACL\Exception\NeedPrivileges'); - $this->server->emit('beforeUnbind', ['testdir']); - } - - public function testPropFind() - { - $propFind = new DAV\PropFind('testdir', [ - '{DAV:}displayname', - '{DAV:}getcontentlength', - '{DAV:}bar', - '{DAV:}owner', - ]); - - $r = $this->server->emit('propFind', [$propFind, new DAV\SimpleCollection('testdir')]); - $this->assertTrue($r); - - $expected = [ - 200 => [], - 404 => [], - 403 => [ - '{DAV:}displayname' => null, - '{DAV:}getcontentlength' => null, - '{DAV:}bar' => null, - '{DAV:}owner' => null, - ], - ]; - - $this->assertEquals($expected, $propFind->getResultForMultiStatus()); - } - - public function testBeforeGetPropertiesNoListing() - { - $this->plugin->hideNodesFromListings = true; - $propFind = new DAV\PropFind('testdir', [ - '{DAV:}displayname', - '{DAV:}getcontentlength', - '{DAV:}bar', - '{DAV:}owner', - ]); - - $r = $this->server->emit('propFind', [$propFind, new DAV\SimpleCollection('testdir')]); - $this->assertFalse($r); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php deleted file mode 100644 index 60fb8f3e8..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\Exception; - -use Sabre\DAV; - -class AceConflictTest extends \PHPUnit\Framework\TestCase -{ - public function testSerialize() - { - $ex = new AceConflict('message'); - - $server = new DAV\Server(); - $dom = new \DOMDocument('1.0', 'utf-8'); - $root = $dom->createElementNS('DAV:', 'd:root'); - $dom->appendChild($root); - - $ex->serialize($server, $root); - - $xpaths = [ - '/d:root' => 1, - '/d:root/d:no-ace-conflict' => 1, - ]; - - // Reloading because PHP DOM sucks - $dom2 = new \DOMDocument('1.0', 'utf-8'); - $dom2->loadXML($dom->saveXML()); - - $dxpath = new \DOMXPath($dom2); - $dxpath->registerNamespace('d', 'DAV:'); - foreach ($xpaths as $xpath => $count) { - $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : '.$xpath.', we could only find '.$dxpath->query($xpath)->length.' elements, while we expected '.$count); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php deleted file mode 100644 index f08e536b5..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\Exception; - -use Sabre\DAV; - -class NeedPrivilegesExceptionTest extends \PHPUnit\Framework\TestCase -{ - public function testSerialize() - { - $uri = 'foo'; - $privileges = [ - '{DAV:}read', - '{DAV:}write', - ]; - $ex = new NeedPrivileges($uri, $privileges); - - $server = new DAV\Server(); - $dom = new \DOMDocument('1.0', 'utf-8'); - $root = $dom->createElementNS('DAV:', 'd:root'); - $dom->appendChild($root); - - $ex->serialize($server, $root); - - $xpaths = [ - '/d:root' => 1, - '/d:root/d:need-privileges' => 1, - '/d:root/d:need-privileges/d:resource' => 2, - '/d:root/d:need-privileges/d:resource/d:href' => 2, - '/d:root/d:need-privileges/d:resource/d:privilege' => 2, - '/d:root/d:need-privileges/d:resource/d:privilege/d:read' => 1, - '/d:root/d:need-privileges/d:resource/d:privilege/d:write' => 1, - ]; - - // Reloading because PHP DOM sucks - $dom2 = new \DOMDocument('1.0', 'utf-8'); - $dom2->loadXML($dom->saveXML()); - - $dxpath = new \DOMXPath($dom2); - $dxpath->registerNamespace('d', 'DAV:'); - foreach ($xpaths as $xpath => $count) { - $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : '.$xpath.', we could only find '.$dxpath->query($xpath)->length.' elements, while we expected '.$count); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php deleted file mode 100644 index 38e9d8b93..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\Exception; - -use Sabre\DAV; - -class NoAbstractTest extends \PHPUnit\Framework\TestCase -{ - public function testSerialize() - { - $ex = new NoAbstract('message'); - - $server = new DAV\Server(); - $dom = new \DOMDocument('1.0', 'utf-8'); - $root = $dom->createElementNS('DAV:', 'd:root'); - $dom->appendChild($root); - - $ex->serialize($server, $root); - - $xpaths = [ - '/d:root' => 1, - '/d:root/d:no-abstract' => 1, - ]; - - // Reloading because PHP DOM sucks - $dom2 = new \DOMDocument('1.0', 'utf-8'); - $dom2->loadXML($dom->saveXML()); - - $dxpath = new \DOMXPath($dom2); - $dxpath->registerNamespace('d', 'DAV:'); - foreach ($xpaths as $xpath => $count) { - $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : '.$xpath.', we could only find '.$dxpath->query($xpath)->length.' elements, while we expected '.$count); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php deleted file mode 100644 index 62915ea1d..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\Exception; - -use Sabre\DAV; - -class NotRecognizedPrincipalTest extends \PHPUnit\Framework\TestCase -{ - public function testSerialize() - { - $ex = new NotRecognizedPrincipal('message'); - - $server = new DAV\Server(); - $dom = new \DOMDocument('1.0', 'utf-8'); - $root = $dom->createElementNS('DAV:', 'd:root'); - $dom->appendChild($root); - - $ex->serialize($server, $root); - - $xpaths = [ - '/d:root' => 1, - '/d:root/d:recognized-principal' => 1, - ]; - - // Reloading because PHP DOM sucks - $dom2 = new \DOMDocument('1.0', 'utf-8'); - $dom2->loadXML($dom->saveXML()); - - $dxpath = new \DOMXPath($dom2); - $dxpath->registerNamespace('d', 'DAV:'); - foreach ($xpaths as $xpath => $count) { - $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : '.$xpath.', we could only find '.$dxpath->query($xpath)->length.' elements, while we expected '.$count); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php deleted file mode 100644 index 668c713d2..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\Exception; - -use Sabre\DAV; - -class NotSupportedPrivilegeTest extends \PHPUnit\Framework\TestCase -{ - public function testSerialize() - { - $ex = new NotSupportedPrivilege('message'); - - $server = new DAV\Server(); - $dom = new \DOMDocument('1.0', 'utf-8'); - $root = $dom->createElementNS('DAV:', 'd:root'); - $dom->appendChild($root); - - $ex->serialize($server, $root); - - $xpaths = [ - '/d:root' => 1, - '/d:root/d:not-supported-privilege' => 1, - ]; - - // Reloading because PHP DOM sucks - $dom2 = new \DOMDocument('1.0', 'utf-8'); - $dom2->loadXML($dom->saveXML()); - - $dxpath = new \DOMXPath($dom2); - $dxpath->registerNamespace('d', 'DAV:'); - foreach ($xpaths as $xpath => $count) { - $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : '.$xpath.', we could only find '.$dxpath->query($xpath)->length.' elements, while we expected '.$count); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php deleted file mode 100644 index 8afe6d30f..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php +++ /dev/null @@ -1,308 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; -use Sabre\HTTP; - -class ExpandPropertiesTest extends \PHPUnit\Framework\TestCase -{ - public function getServer() - { - $tree = [ - new DAV\Mock\PropertiesCollection('node1', [], [ - '{http://sabredav.org/ns}simple' => 'foo', - '{http://sabredav.org/ns}href' => new DAV\Xml\Property\Href('node2'), - '{DAV:}displayname' => 'Node 1', - ]), - new DAV\Mock\PropertiesCollection('node2', [], [ - '{http://sabredav.org/ns}simple' => 'simple', - '{http://sabredav.org/ns}hreflist' => new DAV\Xml\Property\Href(['node1', 'node3']), - '{DAV:}displayname' => 'Node 2', - ]), - new DAV\Mock\PropertiesCollection('node3', [], [ - '{http://sabredav.org/ns}simple' => 'simple', - '{DAV:}displayname' => 'Node 3', - ]), - ]; - - $fakeServer = new DAV\Server($tree); - $fakeServer->sapi = new HTTP\SapiMock(); - $fakeServer->debugExceptions = true; - $fakeServer->httpResponse = new HTTP\ResponseMock(); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - // Anyone can do anything - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - $this->assertTrue($plugin instanceof Plugin); - - $fakeServer->addPlugin($plugin); - $this->assertEquals($plugin, $fakeServer->getPlugin('acl')); - - return $fakeServer; - } - - public function testSimple() - { - $xml = '<?xml version="1.0"?> -<d:expand-property xmlns:d="DAV:"> - <d:property name="displayname" /> - <d:property name="foo" namespace="http://www.sabredav.org/NS/2010/nonexistant" /> - <d:property name="simple" namespace="http://sabredav.org/ns" /> - <d:property name="href" namespace="http://sabredav.org/ns" /> -</d:expand-property>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/node1', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(207, $server->httpResponse->status, 'Incorrect status code received. Full body: '.$server->httpResponse->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 1, - '/d:multistatus/d:response/d:href' => 1, - '/d:multistatus/d:response/d:propstat' => 2, - '/d:multistatus/d:response/d:propstat/d:prop' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:simple' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:href' => 1, - ]; - - $xml = simplexml_load_string($server->httpResponse->getBodyAsString()); - $xml->registerXPathNamespace('d', 'DAV:'); - $xml->registerXPathNamespace('s', 'http://sabredav.org/ns'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result).'. Full response: '.$server->httpResponse->getBodyAsString()); - } - } - - /** - * @depends testSimple - */ - public function testExpand() - { - $xml = '<?xml version="1.0"?> -<d:expand-property xmlns:d="DAV:"> - <d:property name="href" namespace="http://sabredav.org/ns"> - <d:property name="displayname" /> - </d:property> -</d:expand-property>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/node1', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(207, $server->httpResponse->status, 'Incorrect response status received. Full response body: '.$server->httpResponse->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 1, - '/d:multistatus/d:response/d:href' => 1, - '/d:multistatus/d:response/d:propstat' => 1, - '/d:multistatus/d:response/d:propstat/d:prop' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1, - ]; - - $xml = simplexml_load_string($server->httpResponse->getBodyAsString()); - $xml->registerXPathNamespace('d', 'DAV:'); - $xml->registerXPathNamespace('s', 'http://sabredav.org/ns'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result).' Full response body: '.$server->httpResponse->getBodyAsString()); - } - } - - /** - * @depends testSimple - */ - public function testExpandHrefList() - { - $xml = '<?xml version="1.0"?> -<d:expand-property xmlns:d="DAV:"> - <d:property name="hreflist" namespace="http://sabredav.org/ns"> - <d:property name="displayname" /> - </d:property> -</d:expand-property>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/node2', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(207, $server->httpResponse->status); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 1, - '/d:multistatus/d:response/d:href' => 1, - '/d:multistatus/d:response/d:propstat' => 1, - '/d:multistatus/d:response/d:propstat/d:prop' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2, - ]; - - $xml = simplexml_load_string($server->httpResponse->getBodyAsString()); - $xml->registerXPathNamespace('d', 'DAV:'); - $xml->registerXPathNamespace('s', 'http://sabredav.org/ns'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result)); - } - } - - /** - * @depends testExpand - */ - public function testExpandDeep() - { - $xml = '<?xml version="1.0"?> -<d:expand-property xmlns:d="DAV:"> - <d:property name="hreflist" namespace="http://sabredav.org/ns"> - <d:property name="href" namespace="http://sabredav.org/ns"> - <d:property name="displayname" /> - </d:property> - <d:property name="displayname" /> - </d:property> -</d:expand-property>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/node2', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(207, $server->httpResponse->status); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 1, - '/d:multistatus/d:response/d:href' => 1, - '/d:multistatus/d:response/d:propstat' => 1, - '/d:multistatus/d:response/d:propstat/d:prop' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 3, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 3, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1, - '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1, - ]; - - $xml = simplexml_load_string($server->httpResponse->getBodyAsString()); - $xml->registerXPathNamespace('d', 'DAV:'); - $xml->registerXPathNamespace('s', 'http://sabredav.org/ns'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result)); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php deleted file mode 100644 index 51411f304..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; - -class MockACLNode extends DAV\Node implements IACL -{ - public $name; - public $acl; - - public function __construct($name, array $acl = []) - { - $this->name = $name; - $this->acl = $acl; - } - - public function getName() - { - return $this->name; - } - - public function getOwner() - { - return null; - } - - public function getGroup() - { - return null; - } - - public function getACL() - { - return $this->acl; - } - - public function setACL(array $acl) - { - $this->acl = $acl; - } - - public function getSupportedPrivilegeSet() - { - return null; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php deleted file mode 100644 index f67025c5a..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; - -class MockPrincipal extends DAV\Node implements IPrincipal -{ - public $name; - public $principalUrl; - public $groupMembership = []; - public $groupMemberSet = []; - - public function __construct($name, $principalUrl, array $groupMembership = [], array $groupMemberSet = []) - { - $this->name = $name; - $this->principalUrl = $principalUrl; - $this->groupMembership = $groupMembership; - $this->groupMemberSet = $groupMemberSet; - } - - public function getName() - { - return $this->name; - } - - public function getDisplayName() - { - return $this->getName(); - } - - public function getAlternateUriSet() - { - return []; - } - - public function getPrincipalUrl() - { - return $this->principalUrl; - } - - public function getGroupMemberSet() - { - return $this->groupMemberSet; - } - - public function getGroupMemberShip() - { - return $this->groupMembership; - } - - public function setGroupMemberSet(array $groupMemberSet) - { - $this->groupMemberSet = $groupMemberSet; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php deleted file mode 100644 index 048b9f249..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; -use Sabre\HTTP; - -class PluginAdminTest extends \PHPUnit\Framework\TestCase -{ - public $server; - - public function setup(): void - { - $principalBackend = new PrincipalBackend\Mock(); - - $tree = [ - new MockACLNode('adminonly', []), - new PrincipalCollection($principalBackend), - ]; - - $this->server = new DAV\Server($tree); - $this->server->sapi = new HTTP\SapiMock(); - $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $this->server->addPlugin($plugin); - } - - public function testNoAdminAccess() - { - $plugin = new Plugin(); - $this->server->addPlugin($plugin); - - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'OPTIONS', - 'HTTP_DEPTH' => 1, - 'REQUEST_URI' => '/adminonly', - ]); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $this->assertEquals(403, $response->status); - } - - /** - * @depends testNoAdminAccess - */ - public function testAdminAccess() - { - $plugin = new Plugin(); - $plugin->adminPrincipals = [ - 'principals/admin', - ]; - $this->server->addPlugin($plugin); - - $request = HTTP\Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'OPTIONS', - 'HTTP_DEPTH' => 1, - 'REQUEST_URI' => '/adminonly', - ]); - - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - - $this->server->exec(); - - $this->assertEquals(200, $response->status); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php deleted file mode 100644 index 16d3e781e..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php +++ /dev/null @@ -1,399 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; -use Sabre\HTTP; - -class PluginPropertiesTest extends \PHPUnit\Framework\TestCase -{ - public function testPrincipalCollectionSet() - { - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - //Anyone can do anything - $plugin->principalCollectionSet = [ - 'principals1', - 'principals2', - ]; - - $requestedProperties = [ - '{DAV:}principal-collection-set', - ]; - - $server = new DAV\Server(new DAV\SimpleCollection('root')); - $server->addPlugin($plugin); - - $result = $server->getPropertiesForPath('', $requestedProperties); - $result = $result[0]; - - $this->assertEquals(1, count($result[200])); - $this->assertArrayHasKey('{DAV:}principal-collection-set', $result[200]); - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $result[200]['{DAV:}principal-collection-set']); - - $expected = [ - 'principals1/', - 'principals2/', - ]; - - $this->assertEquals($expected, $result[200]['{DAV:}principal-collection-set']->getHrefs()); - } - - public function testCurrentUserPrincipal() - { - $fakeServer = new DAV\Server(); - $plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $fakeServer->addPlugin($plugin); - $plugin = new Plugin(); - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - $fakeServer->addPlugin($plugin); - - $requestedProperties = [ - '{DAV:}current-user-principal', - ]; - - $result = $fakeServer->getPropertiesForPath('', $requestedProperties); - $result = $result[0]; - - $this->assertEquals(1, count($result[200])); - $this->assertArrayHasKey('{DAV:}current-user-principal', $result[200]); - $this->assertInstanceOf('Sabre\DAVACL\Xml\Property\Principal', $result[200]['{DAV:}current-user-principal']); - $this->assertEquals(Xml\Property\Principal::UNAUTHENTICATED, $result[200]['{DAV:}current-user-principal']->getType()); - - // This will force the login - $fakeServer->emit('beforeMethod:PROPFIND', [$fakeServer->httpRequest, $fakeServer->httpResponse]); - - $result = $fakeServer->getPropertiesForPath('', $requestedProperties); - $result = $result[0]; - - $this->assertEquals(1, count($result[200])); - $this->assertArrayHasKey('{DAV:}current-user-principal', $result[200]); - $this->assertInstanceOf('Sabre\DAVACL\Xml\Property\Principal', $result[200]['{DAV:}current-user-principal']); - $this->assertEquals(Xml\Property\Principal::HREF, $result[200]['{DAV:}current-user-principal']->getType()); - $this->assertEquals('principals/admin/', $result[200]['{DAV:}current-user-principal']->getHref()); - } - - public function testSupportedPrivilegeSet() - { - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - $server = new DAV\Server(); - $server->addPlugin($plugin); - - $requestedProperties = [ - '{DAV:}supported-privilege-set', - ]; - - $result = $server->getPropertiesForPath('', $requestedProperties); - $result = $result[0]; - - $this->assertEquals(1, count($result[200])); - $this->assertArrayHasKey('{DAV:}supported-privilege-set', $result[200]); - $this->assertInstanceOf('Sabre\\DAVACL\\Xml\\Property\\SupportedPrivilegeSet', $result[200]['{DAV:}supported-privilege-set']); - - $server = new DAV\Server(); - - $prop = $result[200]['{DAV:}supported-privilege-set']; - $result = $server->xml->write('{DAV:}root', $prop); - - $xpaths = [ - '/d:root' => 1, - '/d:root/d:supported-privilege' => 1, - '/d:root/d:supported-privilege/d:privilege' => 1, - '/d:root/d:supported-privilege/d:privilege/d:all' => 1, - '/d:root/d:supported-privilege/d:abstract' => 0, - '/d:root/d:supported-privilege/d:supported-privilege' => 2, - '/d:root/d:supported-privilege/d:supported-privilege/d:privilege' => 2, - '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:read' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:write' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege' => 7, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege' => 7, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-acl' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-current-user-privilege-set' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-content' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-properties' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:bind' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unbind' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unlock' => 1, - '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:abstract' => 0, - ]; - - // reloading because php dom sucks - $dom2 = new \DOMDocument('1.0', 'utf-8'); - $dom2->loadXML($result); - - $dxpath = new \DOMXPath($dom2); - $dxpath->registerNamespace('d', 'DAV:'); - foreach ($xpaths as $xpath => $count) { - $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : '.$xpath.', we could only find '.$dxpath->query($xpath)->length.' elements, while we expected '.$count.' Full XML: '.$result); - } - } - - public function testACL() - { - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - - $nodes = [ - new MockACLNode('foo', [ - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}read', - ], - ]), - new DAV\SimpleCollection('principals', [ - $principal = new MockPrincipal('admin', 'principals/admin'), - ]), - ]; - - $server = new DAV\Server($nodes); - $server->addPlugin($plugin); - $authPlugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $server->addPlugin($authPlugin); - - // Force login - $authPlugin->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response()); - - $requestedProperties = [ - '{DAV:}acl', - ]; - - $result = $server->getPropertiesForPath('foo', $requestedProperties); - $result = $result[0]; - - $this->assertEquals(1, count($result[200]), 'The {DAV:}acl property did not return from the list. Full list: '.print_r($result, true)); - $this->assertArrayHasKey('{DAV:}acl', $result[200]); - $this->assertInstanceOf('Sabre\\DAVACL\\Xml\Property\\Acl', $result[200]['{DAV:}acl']); - } - - public function testACLRestrictions() - { - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - - $nodes = [ - new MockACLNode('foo', [ - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}read', - ], - ]), - new DAV\SimpleCollection('principals', [ - $principal = new MockPrincipal('admin', 'principals/admin'), - ]), - ]; - - $server = new DAV\Server($nodes); - $server->addPlugin($plugin); - $authPlugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $server->addPlugin($authPlugin); - - // Force login - $authPlugin->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response()); - - $requestedProperties = [ - '{DAV:}acl-restrictions', - ]; - - $result = $server->getPropertiesForPath('foo', $requestedProperties); - $result = $result[0]; - - $this->assertEquals(1, count($result[200]), 'The {DAV:}acl-restrictions property did not return from the list. Full list: '.print_r($result, true)); - $this->assertArrayHasKey('{DAV:}acl-restrictions', $result[200]); - $this->assertInstanceOf('Sabre\\DAVACL\\Xml\\Property\\AclRestrictions', $result[200]['{DAV:}acl-restrictions']); - } - - public function testAlternateUriSet() - { - $tree = [ - new DAV\SimpleCollection('principals', [ - $principal = new MockPrincipal('user', 'principals/user'), - ]), - ]; - - $fakeServer = new DAV\Server($tree); - //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend()) - //$fakeServer->addPlugin($plugin); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - $fakeServer->addPlugin($plugin); - - $requestedProperties = [ - '{DAV:}alternate-URI-set', - ]; - $result = $fakeServer->getPropertiesForPath('principals/user', $requestedProperties); - $result = $result[0]; - - $this->assertTrue(isset($result[200])); - $this->assertTrue(isset($result[200]['{DAV:}alternate-URI-set'])); - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $result[200]['{DAV:}alternate-URI-set']); - - $this->assertEquals([], $result[200]['{DAV:}alternate-URI-set']->getHrefs()); - } - - public function testPrincipalURL() - { - $tree = [ - new DAV\SimpleCollection('principals', [ - $principal = new MockPrincipal('user', 'principals/user'), - ]), - ]; - - $fakeServer = new DAV\Server($tree); - //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend()); - //$fakeServer->addPlugin($plugin); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - $fakeServer->addPlugin($plugin); - - $requestedProperties = [ - '{DAV:}principal-URL', - ]; - - $result = $fakeServer->getPropertiesForPath('principals/user', $requestedProperties); - $result = $result[0]; - - $this->assertTrue(isset($result[200])); - $this->assertTrue(isset($result[200]['{DAV:}principal-URL'])); - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $result[200]['{DAV:}principal-URL']); - - $this->assertEquals('principals/user/', $result[200]['{DAV:}principal-URL']->getHref()); - } - - public function testGroupMemberSet() - { - $tree = [ - new DAV\SimpleCollection('principals', [ - $principal = new MockPrincipal('user', 'principals/user'), - ]), - ]; - - $fakeServer = new DAV\Server($tree); - //$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend()); - //$fakeServer->addPlugin($plugin); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - $fakeServer->addPlugin($plugin); - - $requestedProperties = [ - '{DAV:}group-member-set', - ]; - - $result = $fakeServer->getPropertiesForPath('principals/user', $requestedProperties); - $result = $result[0]; - - $this->assertTrue(isset($result[200])); - $this->assertTrue(isset($result[200]['{DAV:}group-member-set'])); - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $result[200]['{DAV:}group-member-set']); - - $this->assertEquals([], $result[200]['{DAV:}group-member-set']->getHrefs()); - } - - public function testGroupMemberShip() - { - $tree = [ - new DAV\SimpleCollection('principals', [ - $principal = new MockPrincipal('user', 'principals/user'), - ]), - ]; - - $fakeServer = new DAV\Server($tree); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $fakeServer->addPlugin($plugin); - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - - $requestedProperties = [ - '{DAV:}group-membership', - ]; - - $result = $fakeServer->getPropertiesForPath('principals/user', $requestedProperties); - $result = $result[0]; - - $this->assertTrue(isset($result[200])); - $this->assertTrue(isset($result[200]['{DAV:}group-membership'])); - $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $result[200]['{DAV:}group-membership']); - - $this->assertEquals([], $result[200]['{DAV:}group-membership']->getHrefs()); - } - - public function testGetDisplayName() - { - $tree = [ - new DAV\SimpleCollection('principals', [ - $principal = new MockPrincipal('user', 'principals/user'), - ]), - ]; - - $fakeServer = new DAV\Server($tree); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $fakeServer->addPlugin($plugin); - $plugin->setDefaultACL([ - [ - 'principal' => '{DAV:}all', - 'privilege' => '{DAV:}all', - ], - ]); - - $requestedProperties = [ - '{DAV:}displayname', - ]; - - $result = $fakeServer->getPropertiesForPath('principals/user', $requestedProperties); - $result = $result[0]; - - $this->assertTrue(isset($result[200])); - $this->assertTrue(isset($result[200]['{DAV:}displayname'])); - - $this->assertEquals('user', $result[200]['{DAV:}displayname']); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php deleted file mode 100644 index e6796e014..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; - -class PluginUpdatePropertiesTest extends \PHPUnit\Framework\TestCase -{ - public function testUpdatePropertiesPassthrough() - { - $tree = [ - new DAV\SimpleCollection('foo'), - ]; - $server = new DAV\Server($tree); - $server->addPlugin(new DAV\Auth\Plugin()); - $server->addPlugin(new Plugin()); - - $result = $server->updateProperties('foo', [ - '{DAV:}foo' => 'bar', - ]); - - $expected = [ - '{DAV:}foo' => 403, - ]; - - $this->assertEquals($expected, $result); - } - - public function testRemoveGroupMembers() - { - $tree = [ - new MockPrincipal('foo', 'foo'), - ]; - $server = new DAV\Server($tree); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $server->addPlugin($plugin); - - $result = $server->updateProperties('foo', [ - '{DAV:}group-member-set' => null, - ]); - - $expected = [ - '{DAV:}group-member-set' => 204, - ]; - - $this->assertEquals($expected, $result); - $this->assertEquals([], $tree[0]->getGroupMemberSet()); - } - - public function testSetGroupMembers() - { - $tree = [ - new MockPrincipal('foo', 'foo'), - ]; - $server = new DAV\Server($tree); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $server->addPlugin($plugin); - - $result = $server->updateProperties('foo', [ - '{DAV:}group-member-set' => new DAV\Xml\Property\Href(['/bar', '/baz'], true), - ]); - - $expected = [ - '{DAV:}group-member-set' => 200, - ]; - - $this->assertEquals($expected, $result); - $this->assertEquals(['bar', 'baz'], $tree[0]->getGroupMemberSet()); - } - - public function testSetBadValue() - { - $this->expectException('Sabre\DAV\Exception'); - $tree = [ - new MockPrincipal('foo', 'foo'), - ]; - $server = new DAV\Server($tree); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $server->addPlugin($plugin); - - $result = $server->updateProperties('foo', [ - '{DAV:}group-member-set' => new \StdClass(), - ]); - } - - public function testSetBadNode() - { - $tree = [ - new DAV\SimpleCollection('foo'), - ]; - $server = new DAV\Server($tree); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $server->addPlugin($plugin); - - $result = $server->updateProperties('foo', [ - '{DAV:}group-member-set' => new DAV\Xml\Property\Href(['/bar', '/baz'], false), - ]); - - $expected = [ - '{DAV:}group-member-set' => 403, - ]; - - $this->assertEquals($expected, $result); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php deleted file mode 100644 index b18ab9488..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php +++ /dev/null @@ -1,219 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\PrincipalBackend; - -use Sabre\DAV; - -abstract class AbstractPDOTest extends \PHPUnit\Framework\TestCase -{ - use DAV\DbTestHelperTrait; - - public function setup(): void - { - $this->dropTables(['principals', 'groupmembers']); - $this->createSchema('principals'); - - $pdo = $this->getPDO(); - - $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/user','user@example.org','User')"); - $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/group','group@example.org','Group')"); - - $pdo->query('INSERT INTO groupmembers (principal_id,member_id) VALUES (5,4)'); - } - - public function testConstruct() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $this->assertTrue($backend instanceof PDO); - } - - /** - * @depends testConstruct - */ - public function testGetPrincipalsByPrefix() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - - $expected = [ - [ - 'uri' => 'principals/admin', - '{http://sabredav.org/ns}email-address' => 'admin@example.org', - '{DAV:}displayname' => 'Administrator', - ], - [ - 'uri' => 'principals/user', - '{http://sabredav.org/ns}email-address' => 'user@example.org', - '{DAV:}displayname' => 'User', - ], - [ - 'uri' => 'principals/group', - '{http://sabredav.org/ns}email-address' => 'group@example.org', - '{DAV:}displayname' => 'Group', - ], - ]; - - $this->assertEquals($expected, $backend->getPrincipalsByPrefix('principals')); - $this->assertEquals([], $backend->getPrincipalsByPrefix('foo')); - } - - /** - * @depends testConstruct - */ - public function testGetPrincipalByPath() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - - $expected = [ - 'id' => 4, - 'uri' => 'principals/user', - '{http://sabredav.org/ns}email-address' => 'user@example.org', - '{DAV:}displayname' => 'User', - ]; - - $this->assertEquals($expected, $backend->getPrincipalByPath('principals/user')); - $this->assertEquals(null, $backend->getPrincipalByPath('foo')); - } - - public function testGetGroupMemberSet() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $expected = ['principals/user']; - - $this->assertEquals($expected, $backend->getGroupMemberSet('principals/group')); - } - - public function testGetGroupMembership() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $expected = ['principals/group']; - - $this->assertEquals($expected, $backend->getGroupMembership('principals/user')); - } - - public function testSetGroupMemberSet() - { - $pdo = $this->getPDO(); - - // Start situation - $backend = new PDO($pdo); - $this->assertEquals(['principals/user'], $backend->getGroupMemberSet('principals/group')); - - // Removing all principals - $backend->setGroupMemberSet('principals/group', []); - $this->assertEquals([], $backend->getGroupMemberSet('principals/group')); - - // Adding principals again - $backend->setGroupMemberSet('principals/group', ['principals/user']); - $this->assertEquals(['principals/user'], $backend->getGroupMemberSet('principals/group')); - } - - public function testSearchPrincipals() - { - $pdo = $this->getPDO(); - - $backend = new PDO($pdo); - - $result = $backend->searchPrincipals('principals', ['{DAV:}blabla' => 'foo']); - $this->assertEquals([], $result); - - $result = $backend->searchPrincipals('principals', ['{DAV:}displayname' => 'ou']); - $this->assertEquals(['principals/group'], $result); - - $result = $backend->searchPrincipals('principals', ['{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE']); - $this->assertEquals(['principals/user'], $result); - - $result = $backend->searchPrincipals('mom', ['{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE']); - $this->assertEquals([], $result); - } - - public function testUpdatePrincipal() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - - $propPatch = new DAV\PropPatch([ - '{DAV:}displayname' => 'pietje', - ]); - - $backend->updatePrincipal('principals/user', $propPatch); - $result = $propPatch->commit(); - - $this->assertTrue($result); - - $this->assertEquals([ - 'id' => 4, - 'uri' => 'principals/user', - '{DAV:}displayname' => 'pietje', - '{http://sabredav.org/ns}email-address' => 'user@example.org', - ], $backend->getPrincipalByPath('principals/user')); - } - - public function testUpdatePrincipalUnknownField() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - - $propPatch = new DAV\PropPatch([ - '{DAV:}displayname' => 'pietje', - '{DAV:}unknown' => 'foo', - ]); - - $backend->updatePrincipal('principals/user', $propPatch); - $result = $propPatch->commit(); - - $this->assertFalse($result); - - $this->assertEquals([ - '{DAV:}displayname' => 424, - '{DAV:}unknown' => 403, - ], $propPatch->getResult()); - - $this->assertEquals([ - 'id' => '4', - 'uri' => 'principals/user', - '{DAV:}displayname' => 'User', - '{http://sabredav.org/ns}email-address' => 'user@example.org', - ], $backend->getPrincipalByPath('principals/user')); - } - - public function testFindByUriUnknownScheme() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $this->assertNull($backend->findByUri('http://foo', 'principals')); - } - - public function testFindByUriWithMailtoAddress() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $this->assertEquals( - 'principals/user', - $backend->findByUri('mailto:user@example.org', 'principals') - ); - } - - public function testFindByUriWithUri() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $this->assertEquals( - 'principals/user', - $backend->findByUri('principals/user', 'principals') - ); - } - - public function testFindByUriWithUnknownUri() - { - $pdo = $this->getPDO(); - $backend = new PDO($pdo); - $this->assertNull($backend->findByUri('principals/other', 'principals')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php deleted file mode 100644 index 5f0434579..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/Mock.php +++ /dev/null @@ -1,158 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\PrincipalBackend; - -class Mock extends AbstractBackend -{ - public $groupMembers = []; - public $principals; - - public function __construct(array $principals = null) - { - $this->principals = $principals; - - if (is_null($principals)) { - $this->principals = [ - [ - 'uri' => 'principals/user1', - '{DAV:}displayname' => 'User 1', - '{http://sabredav.org/ns}email-address' => 'user1.sabredav@sabredav.org', - '{http://sabredav.org/ns}vcard-url' => 'addressbooks/user1/book1/vcard1.vcf', - ], - [ - 'uri' => 'principals/admin', - '{DAV:}displayname' => 'Admin', - ], - [ - 'uri' => 'principals/user2', - '{DAV:}displayname' => 'User 2', - '{http://sabredav.org/ns}email-address' => 'user2.sabredav@sabredav.org', - ], - ]; - } - } - - public function getPrincipalsByPrefix($prefix) - { - $prefix = trim($prefix, '/'); - if ($prefix) { - $prefix .= '/'; - } - $return = []; - - foreach ($this->principals as $principal) { - if ($prefix && 0 !== strpos($principal['uri'], $prefix)) { - continue; - } - - $return[] = $principal; - } - - return $return; - } - - public function addPrincipal(array $principal) - { - $this->principals[] = $principal; - } - - public function getPrincipalByPath($path) - { - foreach ($this->getPrincipalsByPrefix('principals') as $principal) { - if ($principal['uri'] === $path) { - return $principal; - } - } - } - - public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') - { - $matches = []; - foreach ($this->getPrincipalsByPrefix($prefixPath) as $principal) { - foreach ($searchProperties as $key => $value) { - if (!isset($principal[$key])) { - continue 2; - } - if (false === mb_stripos($principal[$key], $value, 0, 'UTF-8')) { - continue 2; - } - - // We have a match for this searchProperty! - if ('allof' === $test) { - continue; - } else { - break; - } - } - $matches[] = $principal['uri']; - } - - return $matches; - } - - public function getGroupMemberSet($path) - { - return isset($this->groupMembers[$path]) ? $this->groupMembers[$path] : []; - } - - public function getGroupMembership($path) - { - $membership = []; - foreach ($this->groupMembers as $group => $members) { - if (in_array($path, $members)) { - $membership[] = $group; - } - } - - return $membership; - } - - public function setGroupMemberSet($path, array $members) - { - $this->groupMembers[$path] = $members; - } - - /** - * Updates one ore more webdav properties on a principal. - * - * The list of mutations is stored in a Sabre\DAV\PropPatch object. - * To do the actual updates, you must tell this object which properties - * you're going to process with the handle() method. - * - * Calling the handle method is like telling the PropPatch object "I - * promise I can handle updating this property". - * - * Read the PropPatch documentation for more info and examples. - * - * @param string $path - */ - public function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch) - { - $value = null; - foreach ($this->principals as $principalIndex => $value) { - if ($value['uri'] === $path) { - $principal = $value; - break; - } - } - if (!$principal) { - return; - } - - $propPatch->handleRemaining(function ($mutations) use ($principal, $principalIndex) { - foreach ($mutations as $prop => $value) { - if (is_null($value) && isset($principal[$prop])) { - unset($principal[$prop]); - } else { - $principal[$prop] = $value; - } - } - - $this->principals[$principalIndex] = $principal; - - return true; - }); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php deleted file mode 100644 index 54795cf4d..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\PrincipalBackend; - -class PDOMySQLTest extends AbstractPDOTest -{ - public $driver = 'mysql'; -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php deleted file mode 100644 index 549e0bd60..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL\PrincipalBackend; - -class PDOSqliteTest extends AbstractPDOTest -{ - public $driver = 'sqlite'; -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php deleted file mode 100644 index 2777281a8..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -class PrincipalCollectionTest extends \PHPUnit\Framework\TestCase -{ - public function testBasic() - { - $backend = new PrincipalBackend\Mock(); - $pc = new PrincipalCollection($backend); - $this->assertTrue($pc instanceof PrincipalCollection); - - $this->assertEquals('principals', $pc->getName()); - } - - /** - * @depends testBasic - */ - public function testGetChildren() - { - $backend = new PrincipalBackend\Mock(); - $pc = new PrincipalCollection($backend); - - $children = $pc->getChildren(); - $this->assertTrue(is_array($children)); - - foreach ($children as $child) { - $this->assertTrue($child instanceof IPrincipal); - } - } - - /** - * @depends testBasic - */ - public function testGetChildrenDisable() - { - $this->expectException('Sabre\DAV\Exception\MethodNotAllowed'); - $backend = new PrincipalBackend\Mock(); - $pc = new PrincipalCollection($backend); - $pc->disableListing = true; - - $children = $pc->getChildren(); - } - - public function testFindByUri() - { - $backend = new PrincipalBackend\Mock(); - $pc = new PrincipalCollection($backend); - $this->assertEquals('principals/user1', $pc->findByUri('mailto:user1.sabredav@sabredav.org')); - $this->assertNull($pc->findByUri('mailto:fake.user.sabredav@sabredav.org')); - $this->assertNull($pc->findByUri('')); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php deleted file mode 100644 index 6883f25b4..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php +++ /dev/null @@ -1,389 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; -use Sabre\HTTP; - -class PrincipalPropertySearchTest extends \PHPUnit\Framework\TestCase -{ - public function getServer() - { - $backend = new PrincipalBackend\Mock(); - - $dir = new DAV\SimpleCollection('root'); - $principals = new PrincipalCollection($backend); - $dir->addChild($principals); - - $fakeServer = new DAV\Server($dir); - $fakeServer->sapi = new HTTP\SapiMock(); - $fakeServer->httpResponse = new HTTP\ResponseMock(); - $fakeServer->debugExceptions = true; - $plugin = new MockPlugin(); - $plugin->allowAccessToNodesWithoutACL = true; - $plugin->allowUnauthenticatedAccess = false; - - $this->assertTrue($plugin instanceof Plugin); - $fakeServer->addPlugin($plugin); - $this->assertEquals($plugin, $fakeServer->getPlugin('acl')); - - return $fakeServer; - } - - public function testDepth1() - { - $xml = '<?xml version="1.0"?> -<d:principal-property-search xmlns:d="DAV:"> - <d:property-search> - <d:prop> - <d:displayname /> - </d:prop> - <d:match>user</d:match> - </d:property-search> - <d:prop> - <d:displayname /> - <d:getcontentlength /> - </d:prop> -</d:principal-property-search>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '1', - 'REQUEST_URI' => '/principals', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(400, $server->httpResponse->getStatus(), $server->httpResponse->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - } - - public function testUnknownSearchField() - { - $xml = '<?xml version="1.0"?> -<d:principal-property-search xmlns:d="DAV:"> - <d:property-search> - <d:prop> - <d:yourmom /> - </d:prop> - <d:match>user</d:match> - </d:property-search> - <d:prop> - <d:displayname /> - <d:getcontentlength /> - </d:prop> -</d:principal-property-search>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/principals', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(207, $server->httpResponse->getStatus(), 'Full body: '.$server->httpResponse->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'Vary' => ['Brief,Prefer'], - ], $server->httpResponse->getHeaders()); - } - - public function testCorrect() - { - $xml = '<?xml version="1.0"?> -<d:principal-property-search xmlns:d="DAV:"> - <d:apply-to-principal-collection-set /> - <d:property-search> - <d:prop> - <d:displayname /> - </d:prop> - <d:match>user</d:match> - </d:property-search> - <d:prop> - <d:displayname /> - <d:getcontentlength /> - </d:prop> -</d:principal-property-search>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $bodyAsString = $server->httpResponse->getBodyAsString(); - $this->assertEquals(207, $server->httpResponse->status, $bodyAsString); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'Vary' => ['Brief,Prefer'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 2, - '/d:multistatus/d:response/d:href' => 2, - '/d:multistatus/d:response/d:propstat' => 4, - '/d:multistatus/d:response/d:propstat/d:prop' => 4, - '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 2, - '/d:multistatus/d:response/d:propstat/d:status' => 4, - ]; - - $xml = simplexml_load_string($bodyAsString); - $xml->registerXPathNamespace('d', 'DAV:'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result).'. Full response body: '.$server->httpResponse->getBodyAsString()); - } - } - - public function testAND() - { - $xml = '<?xml version="1.0"?> -<d:principal-property-search xmlns:d="DAV:"> - <d:apply-to-principal-collection-set /> - <d:property-search> - <d:prop> - <d:displayname /> - </d:prop> - <d:match>user</d:match> - </d:property-search> - <d:property-search> - <d:prop> - <d:foo /> - </d:prop> - <d:match>bar</d:match> - </d:property-search> - <d:prop> - <d:displayname /> - <d:getcontentlength /> - </d:prop> -</d:principal-property-search>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $bodyAsString = $server->httpResponse->getBodyAsString(); - $this->assertEquals(207, $server->httpResponse->status, $bodyAsString); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'Vary' => ['Brief,Prefer'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 0, - '/d:multistatus/d:response/d:href' => 0, - '/d:multistatus/d:response/d:propstat' => 0, - '/d:multistatus/d:response/d:propstat/d:prop' => 0, - '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 0, - '/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 0, - '/d:multistatus/d:response/d:propstat/d:status' => 0, - ]; - - $xml = simplexml_load_string($bodyAsString); - $xml->registerXPathNamespace('d', 'DAV:'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result).'. Full response body: '.$server->httpResponse->getBodyAsString()); - } - } - - public function testOR() - { - $xml = '<?xml version="1.0"?> -<d:principal-property-search xmlns:d="DAV:" test="anyof"> - <d:apply-to-principal-collection-set /> - <d:property-search> - <d:prop> - <d:displayname /> - </d:prop> - <d:match>user</d:match> - </d:property-search> - <d:property-search> - <d:prop> - <d:foo /> - </d:prop> - <d:match>bar</d:match> - </d:property-search> - <d:prop> - <d:displayname /> - <d:getcontentlength /> - </d:prop> -</d:principal-property-search>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $bodyAsString = $server->httpResponse->getBodyAsString(); - $this->assertEquals(207, $server->httpResponse->status, $bodyAsString); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'Vary' => ['Brief,Prefer'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 2, - '/d:multistatus/d:response/d:href' => 2, - '/d:multistatus/d:response/d:propstat' => 4, - '/d:multistatus/d:response/d:propstat/d:prop' => 4, - '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2, - '/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 2, - '/d:multistatus/d:response/d:propstat/d:status' => 4, - ]; - - $xml = simplexml_load_string($bodyAsString); - $xml->registerXPathNamespace('d', 'DAV:'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result).'. Full response body: '.$server->httpResponse->getBodyAsString()); - } - } - - public function testWrongUri() - { - $xml = '<?xml version="1.0"?> -<d:principal-property-search xmlns:d="DAV:"> - <d:property-search> - <d:prop> - <d:displayname /> - </d:prop> - <d:match>user</d:match> - </d:property-search> - <d:prop> - <d:displayname /> - <d:getcontentlength /> - </d:prop> -</d:principal-property-search>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $bodyAsString = $server->httpResponse->getBodyAsString(); - $this->assertEquals(207, $server->httpResponse->status, $bodyAsString); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - 'Vary' => ['Brief,Prefer'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:multistatus', - '/d:multistatus/d:response' => 0, - ]; - - $xml = simplexml_load_string($bodyAsString); - $xml->registerXPathNamespace('d', 'DAV:'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result).'. Full response body: '.$server->httpResponse->getBodyAsString()); - } - } -} - -class MockPlugin extends Plugin -{ - public function getCurrentUserPrivilegeSet($node) - { - return [ - '{DAV:}read', - '{DAV:}write', - ]; - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php deleted file mode 100644 index ec834fe1a..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php +++ /dev/null @@ -1,135 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; -use Sabre\HTTP; - -class PrincipalSearchPropertySetTest extends \PHPUnit\Framework\TestCase -{ - public function getServer() - { - $backend = new PrincipalBackend\Mock(); - - $dir = new DAV\SimpleCollection('root'); - $principals = new PrincipalCollection($backend); - $dir->addChild($principals); - - $fakeServer = new DAV\Server($dir); - $fakeServer->sapi = new HTTP\SapiMock(); - $fakeServer->httpResponse = new HTTP\ResponseMock(); - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $this->assertTrue($plugin instanceof Plugin); - $fakeServer->addPlugin($plugin); - $this->assertEquals($plugin, $fakeServer->getPlugin('acl')); - - return $fakeServer; - } - - public function testDepth1() - { - $xml = '<?xml version="1.0"?> -<d:principal-search-property-set xmlns:d="DAV:" />'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '1', - 'REQUEST_URI' => '/principals', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(400, $server->httpResponse->status); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - } - - public function testDepthIncorrectXML() - { - $xml = '<?xml version="1.0"?> -<d:principal-search-property-set xmlns:d="DAV:"><d:ohell /></d:principal-search-property-set>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/principals', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $this->assertEquals(400, $server->httpResponse->status, $server->httpResponse->getBodyAsString()); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - } - - public function testCorrect() - { - $xml = '<?xml version="1.0"?> -<d:principal-search-property-set xmlns:d="DAV:"/>'; - - $serverVars = [ - 'REQUEST_METHOD' => 'REPORT', - 'HTTP_DEPTH' => '0', - 'REQUEST_URI' => '/principals', - ]; - - $request = HTTP\Sapi::createFromServerArray($serverVars); - $request->setBody($xml); - - $server = $this->getServer(); - $server->httpRequest = $request; - - $server->exec(); - - $bodyAsString = $server->httpResponse->getBodyAsString(); - $this->assertEquals(200, $server->httpResponse->status, $bodyAsString); - $this->assertEquals([ - 'X-Sabre-Version' => [DAV\Version::VERSION], - 'Content-Type' => ['application/xml; charset=utf-8'], - ], $server->httpResponse->getHeaders()); - - $check = [ - '/d:principal-search-property-set', - '/d:principal-search-property-set/d:principal-search-property' => 2, - '/d:principal-search-property-set/d:principal-search-property/d:prop' => 2, - '/d:principal-search-property-set/d:principal-search-property/d:prop/d:displayname' => 1, - '/d:principal-search-property-set/d:principal-search-property/d:prop/s:email-address' => 1, - '/d:principal-search-property-set/d:principal-search-property/d:description' => 2, - ]; - - $xml = simplexml_load_string($bodyAsString); - $xml->registerXPathNamespace('d', 'DAV:'); - $xml->registerXPathNamespace('s', 'http://sabredav.org/ns'); - foreach ($check as $v1 => $v2) { - $xpath = is_int($v1) ? $v2 : $v1; - - $result = $xml->xpath($xpath); - - $count = 1; - if (!is_int($v1)) { - $count = $v2; - } - - $this->assertEquals($count, count($result), 'we expected '.$count.' appearances of '.$xpath.' . We found '.count($result).'. Full response body: '.$bodyAsString); - } - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php deleted file mode 100644 index 7e1656a15..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php +++ /dev/null @@ -1,192 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; - -class PrincipalTest extends \PHPUnit\Framework\TestCase -{ - public function testConstruct() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertTrue($principal instanceof Principal); - } - - public function testConstructNoUri() - { - $this->expectException('Sabre\DAV\Exception'); - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, []); - } - - public function testGetName() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertEquals('admin', $principal->getName()); - } - - public function testGetDisplayName() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertEquals('admin', $principal->getDisplayname()); - - $principal = new Principal($principalBackend, [ - 'uri' => 'principals/admin', - '{DAV:}displayname' => 'Mr. Admin', - ]); - $this->assertEquals('Mr. Admin', $principal->getDisplayname()); - } - - public function testGetProperties() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, [ - 'uri' => 'principals/admin', - '{DAV:}displayname' => 'Mr. Admin', - '{http://www.example.org/custom}custom' => 'Custom', - '{http://sabredav.org/ns}email-address' => 'admin@example.org', - ]); - - $keys = [ - '{DAV:}displayname', - '{http://www.example.org/custom}custom', - '{http://sabredav.org/ns}email-address', - ]; - $props = $principal->getProperties($keys); - - foreach ($keys as $key) { - $this->assertArrayHasKey($key, $props); - } - - $this->assertEquals('Mr. Admin', $props['{DAV:}displayname']); - - $this->assertEquals('admin@example.org', $props['{http://sabredav.org/ns}email-address']); - } - - public function testUpdateProperties() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - - $propPatch = new DAV\PropPatch(['{DAV:}yourmom' => 'test']); - - $result = $principal->propPatch($propPatch); - $result = $propPatch->commit(); - $this->assertTrue($result); - } - - public function testGetPrincipalUrl() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertEquals('principals/admin', $principal->getPrincipalUrl()); - } - - public function testGetAlternateUriSet() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, [ - 'uri' => 'principals/admin', - '{DAV:}displayname' => 'Mr. Admin', - '{http://www.example.org/custom}custom' => 'Custom', - '{http://sabredav.org/ns}email-address' => 'admin@example.org', - '{DAV:}alternate-URI-set' => [ - 'mailto:admin+1@example.org', - 'mailto:admin+2@example.org', - 'mailto:admin@example.org', - ], - ]); - - $expected = [ - 'mailto:admin+1@example.org', - 'mailto:admin+2@example.org', - 'mailto:admin@example.org', - ]; - - $this->assertEquals($expected, $principal->getAlternateUriSet()); - } - - public function testGetAlternateUriSetEmpty() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, [ - 'uri' => 'principals/admin', - ]); - - $expected = []; - - $this->assertEquals($expected, $principal->getAlternateUriSet()); - } - - public function testGetGroupMemberSet() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertEquals([], $principal->getGroupMemberSet()); - } - - public function testGetGroupMembership() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertEquals([], $principal->getGroupMembership()); - } - - public function testSetGroupMemberSet() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $principal->setGroupMemberSet(['principals/foo']); - - $this->assertEquals([ - 'principals/admin' => ['principals/foo'], - ], $principalBackend->groupMembers); - } - - public function testGetOwner() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertEquals('principals/admin', $principal->getOwner()); - } - - public function testGetGroup() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertNull($principal->getGroup()); - } - - public function testGetACl() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertEquals([ - [ - 'privilege' => '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - ], $principal->getACL()); - } - - public function testSetACl() - { - $this->expectException('Sabre\DAV\Exception\Forbidden'); - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $principal->setACL([]); - } - - public function testGetSupportedPrivilegeSet() - { - $principalBackend = new PrincipalBackend\Mock(); - $principal = new Principal($principalBackend, ['uri' => 'principals/admin']); - $this->assertNull($principal->getSupportedPrivilegeSet()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php deleted file mode 100644 index effa15838..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php +++ /dev/null @@ -1,302 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\DAVACL; - -use Sabre\DAV; -use Sabre\HTTP; - -class SimplePluginTest extends \PHPUnit\Framework\TestCase -{ - public function testValues() - { - $aclPlugin = new Plugin(); - $this->assertEquals('acl', $aclPlugin->getPluginName()); - $this->assertEquals( - ['access-control', 'calendarserver-principal-property-search'], - $aclPlugin->getFeatures() - ); - - $this->assertEquals( - [ - '{DAV:}expand-property', - '{DAV:}principal-match', - '{DAV:}principal-property-search', - '{DAV:}principal-search-property-set', - ], - $aclPlugin->getSupportedReportSet('')); - - $this->assertEquals(['ACL'], $aclPlugin->getMethods('')); - - $this->assertEquals( - 'acl', - $aclPlugin->getPluginInfo()['name'] - ); - } - - public function testGetFlatPrivilegeSet() - { - $expected = [ - '{DAV:}all' => [ - 'privilege' => '{DAV:}all', - 'abstract' => false, - 'aggregates' => [ - '{DAV:}read', - '{DAV:}write', - ], - 'concrete' => '{DAV:}all', - ], - '{DAV:}read' => [ - 'privilege' => '{DAV:}read', - 'abstract' => false, - 'aggregates' => [ - '{DAV:}read-acl', - '{DAV:}read-current-user-privilege-set', - ], - 'concrete' => '{DAV:}read', - ], - '{DAV:}read-acl' => [ - 'privilege' => '{DAV:}read-acl', - 'abstract' => false, - 'aggregates' => [], - 'concrete' => '{DAV:}read-acl', - ], - '{DAV:}read-current-user-privilege-set' => [ - 'privilege' => '{DAV:}read-current-user-privilege-set', - 'abstract' => false, - 'aggregates' => [], - 'concrete' => '{DAV:}read-current-user-privilege-set', - ], - '{DAV:}write' => [ - 'privilege' => '{DAV:}write', - 'abstract' => false, - 'aggregates' => [ - '{DAV:}write-properties', - '{DAV:}write-content', - '{DAV:}unlock', - '{DAV:}bind', - '{DAV:}unbind', - ], - 'concrete' => '{DAV:}write', - ], - '{DAV:}write-properties' => [ - 'privilege' => '{DAV:}write-properties', - 'abstract' => false, - 'aggregates' => [], - 'concrete' => '{DAV:}write-properties', - ], - '{DAV:}write-content' => [ - 'privilege' => '{DAV:}write-content', - 'abstract' => false, - 'aggregates' => [], - 'concrete' => '{DAV:}write-content', - ], - '{DAV:}unlock' => [ - 'privilege' => '{DAV:}unlock', - 'abstract' => false, - 'aggregates' => [], - 'concrete' => '{DAV:}unlock', - ], - '{DAV:}bind' => [ - 'privilege' => '{DAV:}bind', - 'abstract' => false, - 'aggregates' => [], - 'concrete' => '{DAV:}bind', - ], - '{DAV:}unbind' => [ - 'privilege' => '{DAV:}unbind', - 'abstract' => false, - 'aggregates' => [], - 'concrete' => '{DAV:}unbind', - ], - ]; - - $plugin = new Plugin(); - $plugin->allowUnauthenticatedAccess = false; - $server = new DAV\Server(); - $server->addPlugin($plugin); - $this->assertEquals($expected, $plugin->getFlatPrivilegeSet('')); - } - - public function testCurrentUserPrincipalsNotLoggedIn() - { - $acl = new Plugin(); - $acl->allowUnauthenticatedAccess = false; - $server = new DAV\Server(); - $server->addPlugin($acl); - - $this->assertEquals([], $acl->getCurrentUserPrincipals()); - } - - public function testCurrentUserPrincipalsSimple() - { - $tree = [ - new DAV\SimpleCollection('principals', [ - new MockPrincipal('admin', 'principals/admin'), - ]), - ]; - - $acl = new Plugin(); - $acl->allowUnauthenticatedAccess = false; - $server = new DAV\Server($tree); - $server->addPlugin($acl); - - $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $server->addPlugin($auth); - - //forcing login - $auth->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response()); - - $this->assertEquals(['principals/admin'], $acl->getCurrentUserPrincipals()); - } - - public function testCurrentUserPrincipalsGroups() - { - $tree = [ - new DAV\SimpleCollection('principals', [ - new MockPrincipal('admin', 'principals/admin', ['principals/administrators', 'principals/everyone']), - new MockPrincipal('administrators', 'principals/administrators', ['principals/groups'], ['principals/admin']), - new MockPrincipal('everyone', 'principals/everyone', [], ['principals/admin']), - new MockPrincipal('groups', 'principals/groups', [], ['principals/administrators']), - ]), - ]; - - $acl = new Plugin(); - $acl->allowUnauthenticatedAccess = false; - $server = new DAV\Server($tree); - $server->addPlugin($acl); - - $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $server->addPlugin($auth); - - //forcing login - $auth->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response()); - - $expected = [ - 'principals/admin', - 'principals/administrators', - 'principals/everyone', - 'principals/groups', - ]; - - $this->assertEquals($expected, $acl->getCurrentUserPrincipals()); - - // The second one should trigger the cache and be identical - $this->assertEquals($expected, $acl->getCurrentUserPrincipals()); - } - - public function testGetACL() - { - $acl = [ - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}read', - ], - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}write', - ], - ]; - - $tree = [ - new MockACLNode('foo', $acl), - ]; - - $server = new DAV\Server($tree); - $aclPlugin = new Plugin(); - $aclPlugin->allowUnauthenticatedAccess = false; - $server->addPlugin($aclPlugin); - - $this->assertEquals($acl, $aclPlugin->getACL('foo')); - } - - public function testGetCurrentUserPrivilegeSet() - { - $acl = [ - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}read', - ], - [ - 'principal' => 'principals/user1', - 'privilege' => '{DAV:}read', - ], - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}write', - ], - ]; - - $tree = [ - new MockACLNode('foo', $acl), - - new DAV\SimpleCollection('principals', [ - new MockPrincipal('admin', 'principals/admin'), - ]), - ]; - - $server = new DAV\Server($tree); - $aclPlugin = new Plugin(); - $aclPlugin->allowUnauthenticatedAccess = false; - $server->addPlugin($aclPlugin); - - $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $server->addPlugin($auth); - - //forcing login - $auth->beforeMethod(new HTTP\Request('GET', '/'), new HTTP\Response()); - - $expected = [ - '{DAV:}write', - '{DAV:}write-properties', - '{DAV:}write-content', - '{DAV:}unlock', - '{DAV:}write-acl', - '{DAV:}read', - '{DAV:}read-acl', - '{DAV:}read-current-user-privilege-set', - ]; - - $this->assertEquals($expected, $aclPlugin->getCurrentUserPrivilegeSet('foo')); - } - - public function testCheckPrivileges() - { - $acl = [ - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}read', - ], - [ - 'principal' => 'principals/user1', - 'privilege' => '{DAV:}read', - ], - [ - 'principal' => 'principals/admin', - 'privilege' => '{DAV:}write', - ], - ]; - - $tree = [ - new MockACLNode('foo', $acl), - - new DAV\SimpleCollection('principals', [ - new MockPrincipal('admin', 'principals/admin'), - ]), - ]; - - $server = new DAV\Server($tree); - $aclPlugin = new Plugin(); - $aclPlugin->allowUnauthenticatedAccess = false; - $server->addPlugin($aclPlugin); - - $auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock()); - $server->addPlugin($auth); - - //forcing login - //$auth->beforeMethod('GET','/'); - - $this->assertFalse($aclPlugin->checkPrivileges('foo', ['{DAV:}read'], Plugin::R_PARENT, false)); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/DAVServerTest.php b/vendor/sabre/dav/tests/Sabre/DAVServerTest.php deleted file mode 100644 index 2f64df08c..000000000 --- a/vendor/sabre/dav/tests/Sabre/DAVServerTest.php +++ /dev/null @@ -1,305 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre; - -use Sabre\HTTP\Request; -use Sabre\HTTP\Response; - -/** - * This class may be used as a basis for other webdav-related unittests. - * - * This class is supposed to provide a reasonably big framework to quickly get - * a testing environment running. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -abstract class DAVServerTest extends \PHPUnit\Framework\TestCase -{ - protected $setupCalDAV = false; - protected $setupCardDAV = false; - protected $setupACL = false; - protected $setupCalDAVSharing = false; - protected $setupCalDAVScheduling = false; - protected $setupCalDAVSubscriptions = false; - protected $setupCalDAVICSExport = false; - protected $setupLocks = false; - protected $setupFiles = false; - protected $setupSharing = false; - protected $setupPropertyStorage = false; - - /** - * An array with calendars. Every calendar should have - * - principaluri - * - uri. - */ - protected $caldavCalendars = []; - protected $caldavCalendarObjects = []; - - protected $carddavAddressBooks = []; - protected $carddavCards = []; - - /** - * @var \Sabre\DAV\Server - */ - protected $server; - protected $tree = []; - - protected $caldavBackend; - protected $carddavBackend; - protected $principalBackend; - protected $locksBackend; - protected $propertyStorageBackend; - - /** - * @var \Sabre\CalDAV\Plugin - */ - protected $caldavPlugin; - - /** - * @var \Sabre\CardDAV\Plugin - */ - protected $carddavPlugin; - - /** - * @var \Sabre\DAVACL\Plugin - */ - protected $aclPlugin; - - /** - * @var \Sabre\CalDAV\SharingPlugin - */ - protected $caldavSharingPlugin; - - /** - * CalDAV scheduling plugin. - * - * @var CalDAV\Schedule\Plugin - */ - protected $caldavSchedulePlugin; - - /** - * @var CalDAV\ICSExportPlugin - */ - protected $caldavICSExportPlugin; - - /** - * @var \Sabre\DAV\Auth\Plugin - */ - protected $authPlugin; - - /** - * @var \Sabre\DAV\Locks\Plugin - */ - protected $locksPlugin; - - /** - * Sharing plugin. - * - * @var \Sabre\DAV\Sharing\Plugin - */ - protected $sharingPlugin; - - /* - * @var Sabre\DAV\PropertyStorage\Plugin - */ - protected $propertyStoragePlugin; - - /** - * If this string is set, we will automatically log in the user with this - * name. - */ - protected $autoLogin = null; - - public function setup(): void - { - $this->initializeEverything(); - } - - public function initializeEverything() - { - $this->setUpBackends(); - $this->setUpTree(); - - $this->server = new DAV\Server($this->tree); - $this->server->sapi = new HTTP\SapiMock(); - $this->server->debugExceptions = true; - - if ($this->setupCalDAV) { - $this->caldavPlugin = new CalDAV\Plugin(); - $this->server->addPlugin($this->caldavPlugin); - } - if ($this->setupCalDAVSharing || $this->setupSharing) { - $this->sharingPlugin = new DAV\Sharing\Plugin(); - $this->server->addPlugin($this->sharingPlugin); - } - if ($this->setupCalDAVSharing) { - $this->caldavSharingPlugin = new CalDAV\SharingPlugin(); - $this->server->addPlugin($this->caldavSharingPlugin); - } - if ($this->setupCalDAVScheduling) { - $this->caldavSchedulePlugin = new CalDAV\Schedule\Plugin(); - $this->server->addPlugin($this->caldavSchedulePlugin); - } - if ($this->setupCalDAVSubscriptions) { - $this->server->addPlugin(new CalDAV\Subscriptions\Plugin()); - } - if ($this->setupCalDAVICSExport) { - $this->caldavICSExportPlugin = new CalDAV\ICSExportPlugin(); - $this->server->addPlugin($this->caldavICSExportPlugin); - } - if ($this->setupCardDAV) { - $this->carddavPlugin = new CardDAV\Plugin(); - $this->server->addPlugin($this->carddavPlugin); - } - if ($this->setupLocks) { - $this->locksPlugin = new DAV\Locks\Plugin( - $this->locksBackend - ); - $this->server->addPlugin($this->locksPlugin); - } - if ($this->setupPropertyStorage) { - $this->propertyStoragePlugin = new DAV\PropertyStorage\Plugin( - $this->propertyStorageBackend - ); - $this->server->addPlugin($this->propertyStoragePlugin); - } - if ($this->autoLogin) { - $this->autoLogin($this->autoLogin); - } - if ($this->setupACL) { - $this->aclPlugin = new DAVACL\Plugin(); - if (!$this->autoLogin) { - $this->aclPlugin->allowUnauthenticatedAccess = false; - } - $this->aclPlugin->adminPrincipals = ['principals/admin']; - $this->server->addPlugin($this->aclPlugin); - } - } - - /** - * Makes a request, and returns a response object. - * - * You can either pass an instance of Sabre\HTTP\Request, or an array, - * which will then be used as the _SERVER array. - * - * If $expectedStatus is set, we'll compare it with the HTTP status of - * the returned response. If it doesn't match, we'll immediately fail - * the test. - * - * @param array|\Sabre\HTTP\Request $request - * @param int $expectedStatus - * - * @return \Sabre\HTTP\Response - */ - public function request($request, $expectedStatus = null) - { - if (is_array($request)) { - $request = HTTP\Sapi::createFromServerArray($request); - } - $response = new HTTP\ResponseMock(); - - $this->server->httpRequest = $request; - $this->server->httpResponse = $response; - $this->server->exec(); - - if ($expectedStatus) { - $responseBody = $expectedStatus !== $response->getStatus() ? $response->getBodyAsString() : ''; - $this->assertEquals($expectedStatus, $response->getStatus(), 'Incorrect HTTP status received for request. Response body: '.$responseBody); - } - - return $this->server->httpResponse; - } - - /** - * This function takes a username and sets the server in a state where - * this user is logged in, and no longer requires an authentication check. - * - * @param string $userName - */ - public function autoLogin($userName) - { - $authBackend = new DAV\Auth\Backend\Mock(); - $authBackend->setPrincipal('principals/'.$userName); - $this->authPlugin = new DAV\Auth\Plugin($authBackend); - - // If the auth plugin already exists, we're removing its hooks: - if ($oldAuth = $this->server->getPlugin('auth')) { - $this->server->removeListener('beforeMethod', [$oldAuth, 'beforeMethod']); - } - $this->server->addPlugin($this->authPlugin); - - // This will trigger the actual login procedure - $this->authPlugin->beforeMethod(new Request('GET', '/'), new Response()); - } - - /** - * Override this to provide your own Tree for your test-case. - */ - public function setUpTree() - { - if ($this->setupCalDAV) { - $this->tree[] = new CalDAV\CalendarRoot( - $this->principalBackend, - $this->caldavBackend - ); - } - if ($this->setupCardDAV) { - $this->tree[] = new CardDAV\AddressBookRoot( - $this->principalBackend, - $this->carddavBackend - ); - } - - if ($this->setupCalDAV) { - $this->tree[] = new CalDAV\Principal\Collection( - $this->principalBackend - ); - } elseif ($this->setupCardDAV || $this->setupACL) { - $this->tree[] = new DAVACL\PrincipalCollection( - $this->principalBackend - ); - } - if ($this->setupFiles) { - $this->tree[] = new DAV\Mock\Collection('files'); - } - } - - public function setUpBackends() - { - if ($this->setupCalDAVSharing && is_null($this->caldavBackend)) { - $this->caldavBackend = new CalDAV\Backend\MockSharing($this->caldavCalendars, $this->caldavCalendarObjects); - } - if ($this->setupCalDAVSubscriptions && is_null($this->caldavBackend)) { - $this->caldavBackend = new CalDAV\Backend\MockSubscriptionSupport($this->caldavCalendars, $this->caldavCalendarObjects); - } - if ($this->setupCalDAV && is_null($this->caldavBackend)) { - if ($this->setupCalDAVScheduling) { - $this->caldavBackend = new CalDAV\Backend\MockScheduling($this->caldavCalendars, $this->caldavCalendarObjects); - } else { - $this->caldavBackend = new CalDAV\Backend\Mock($this->caldavCalendars, $this->caldavCalendarObjects); - } - } - if ($this->setupCardDAV && is_null($this->carddavBackend)) { - $this->carddavBackend = new CardDAV\Backend\Mock($this->carddavAddressBooks, $this->carddavCards); - } - if ($this->setupCardDAV || $this->setupCalDAV || $this->setupACL) { - $this->principalBackend = new DAVACL\PrincipalBackend\Mock(); - } - if ($this->setupLocks) { - $this->locksBackend = new DAV\Locks\Backend\Mock(); - } - if ($this->setupPropertyStorage) { - $this->propertyStorageBackend = new DAV\PropertyStorage\Backend\Mock(); - } - } - - public function assertHttpStatus($expectedStatus, HTTP\Request $req) - { - $resp = $this->request($req); - $this->assertEquals((int) $expectedStatus, (int) $resp->getStatus(), 'Incorrect HTTP status received: '.$resp->getStatus()); - } -} diff --git a/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php b/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php deleted file mode 100644 index c5357928a..000000000 --- a/vendor/sabre/dav/tests/Sabre/HTTP/ResponseMock.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre\HTTP; - -/** - * HTTP Response Mock object. - * - * This class exists to make the transition to sabre/http easier. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class ResponseMock extends Response -{ - /** - * Making these public. - */ - public $body; - public $status; -} diff --git a/vendor/sabre/dav/tests/Sabre/TestUtil.php b/vendor/sabre/dav/tests/Sabre/TestUtil.php deleted file mode 100644 index 4e7ca2fc4..000000000 --- a/vendor/sabre/dav/tests/Sabre/TestUtil.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Sabre; - -class TestUtil -{ - /** - * This function deletes all the contents of the temporary directory. - */ - public static function clearTempDir() - { - self::deleteTree(SABRE_TEMPDIR, false); - } - - private static function deleteTree($path, $deleteRoot = true) - { - foreach (scandir($path) as $node) { - if ('.' == $node || '..' == $node) { - continue; - } - $myPath = $path.'/'.$node; - if (is_file($myPath)) { - unlink($myPath); - } else { - self::deleteTree($myPath); - } - } - if ($deleteRoot) { - rmdir($path); - } - } - - public static function getMySQLDB() - { - try { - $pdo = new \PDO(SABRE_MYSQLDSN, SABRE_MYSQLUSER, SABRE_MYSQLPASS); - $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - - return $pdo; - } catch (\PDOException $e) { - return null; - } - } - - public static function getSQLiteDB() - { - $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend'); - $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - - return $pdo; - } - - public static function getPgSqlDB() - { - //try { - $pdo = new \PDO(SABRE_PGSQLDSN); - $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - - return $pdo; - //} catch (\PDOException $e) { - // return null; - //} - } -} diff --git a/vendor/sabre/dav/tests/bootstrap.php b/vendor/sabre/dav/tests/bootstrap.php deleted file mode 100644 index d15805382..000000000 --- a/vendor/sabre/dav/tests/bootstrap.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php - -declare(strict_types=1); - -set_include_path(__DIR__.'/../lib/'.PATH_SEPARATOR.__DIR__.PATH_SEPARATOR.get_include_path()); - -$autoLoader = include __DIR__.'/../vendor/autoload.php'; - -// SabreDAV tests auto loading -$autoLoader->add('Sabre\\', __DIR__); -// VObject tests auto loading -$autoLoader->addPsr4('Sabre\\VObject\\', __DIR__.'/../vendor/sabre/vobject/tests/VObject'); -$autoLoader->addPsr4('Sabre\\Xml\\', __DIR__.'/../vendor/sabre/xml/tests/Sabre/Xml'); - -date_default_timezone_set('UTC'); - -if ('TRUE' === getenv('RUN_TEST_WITH_STREAMING_PROPFIND')) { - echo 'Running unit tests with \Sabre\DAV\Server::$streamMultiStatus = true'; - \Sabre\DAV\Server::$streamMultiStatus = true; -} - -// List of variables that can be set by the environment -$environmentVars = [ - 'SABRE_MYSQLUSER', - 'SABRE_MYSQLPASS', - 'SABRE_MYSQLDSN', - 'SABRE_PGSQLDSN', -]; -foreach ($environmentVars as $var) { - if ($value = getenv($var)) { - define($var, $value); - } -} - -$config = [ - 'SABRE_TEMPDIR' => dirname(__FILE__).'/temp/', - 'SABRE_HASSQLITE' => in_array('sqlite', PDO::getAvailableDrivers()), - 'SABRE_HASMYSQL' => in_array('mysql', PDO::getAvailableDrivers()), - 'SABRE_HASPGSQL' => in_array('pgsql', PDO::getAvailableDrivers()), - 'SABRE_MYSQLDSN' => 'mysql:host=127.0.0.1;dbname=sabredav_test', - 'SABRE_MYSQLUSER' => 'sabredav', - 'SABRE_MYSQLPASS' => '', - 'SABRE_PGSQLDSN' => 'pgsql:host=localhost;dbname=sabredav_test;user=sabredav;password=sabredav', -]; - -if (file_exists(__DIR__.'/config.user.php')) { - $userConfig = []; - include __DIR__.'/config.user.php'; - foreach ($userConfig as $key => $value) { - $config[$key] = $value; - } -} - -foreach ($config as $key => $value) { - if (!defined($key)) { - define($key, $value); - } -} - -if (!file_exists(SABRE_TEMPDIR)) { - mkdir(SABRE_TEMPDIR); -} -if (file_exists('.sabredav')) { - unlink('.sabredav'); -} diff --git a/vendor/sabre/vobject/.gitignore b/vendor/sabre/vobject/.gitignore deleted file mode 100644 index 82b7dad3f..000000000 --- a/vendor/sabre/vobject/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Composer stuff -vendor/ -composer.lock -tests/cov/ -tests/temp -tests/.phpunit.result.cache - -# Development stuff -.php_cs.cache diff --git a/vendor/sabre/vobject/.php_cs.dist b/vendor/sabre/vobject/.php_cs.dist deleted file mode 100644 index c5c78a971..000000000 --- a/vendor/sabre/vobject/.php_cs.dist +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -$config = PhpCsFixer\Config::create(); -$config->getFinder() - ->exclude('vendor') - ->in(__DIR__); -$config->setRules([ - '@PSR1' => true, - '@Symfony' => true -]); - -return $config; \ No newline at end of file diff --git a/vendor/sabre/vobject/.travis.yml b/vendor/sabre/vobject/.travis.yml deleted file mode 100644 index 4f50e97fd..000000000 --- a/vendor/sabre/vobject/.travis.yml +++ /dev/null @@ -1,49 +0,0 @@ -language: php -php: - - 7.1 - - 7.2 - - 7.3 - - 7.4 - -env: - global: - - MEMCACHED_SERVER=127.0.0.1 - - RUN_PHPCSFIXER="TRUE" - - RUN_PHPUNIT="TRUE" - - RUN_PHPSTAN="FALSE" - matrix: - - PREFER_LOWEST="" REPORT_COVERAGE="TRUE" WITH_COVERAGE="--coverage-clover=coverage.xml" - - PREFER_LOWEST="--prefer-lowest" REPORT_COVERAGE="FALSE" WITH_COVERAGE="" - -matrix: - include: - - name: 'PHP8' - dist: focal - php: nightly - env: - - RUN_PHPCSFIXER="FALSE" - - REPORT_COVERAGE="FALSE" - - name: 'PHPStan' - php: 7.4 - env: - - RUN_PHPCSFIXER="FALSE" - - RUN_PHPUNIT="FALSE" - - RUN_PHPSTAN="TRUE" - - REPORT_COVERAGE="FALSE" - fast_finish: true - -before_script: - - if [ $RUN_PHPCSFIXER == "FALSE" ]; then composer remove --no-update --dev friendsofphp/php-cs-fixer; fi - - composer update $PREFER_LOWEST - -script: - - if [ $RUN_PHPCSFIXER == "TRUE" ]; then php vendor/bin/php-cs-fixer fix --dry-run --diff; fi - - if [ $RUN_PHPUNIT == "TRUE" ]; then php vendor/bin/phpunit --configuration tests/phpunit.xml $WITH_COVERAGE; fi - - if [ $RUN_PHPSTAN == "TRUE" ]; then composer phpstan; fi - -after_success: - - if [ $REPORT_COVERAGE == "TRUE" ]; then bash <(curl -s https://codecov.io/bash); fi - -cache: - directories: - - $HOME/.composer/cache diff --git a/vendor/sabre/vobject/CHANGELOG.md b/vendor/sabre/vobject/CHANGELOG.md deleted file mode 100644 index 7d6b096fd..000000000 --- a/vendor/sabre/vobject/CHANGELOG.md +++ /dev/null @@ -1,868 +0,0 @@ -ChangeLog -========= - -4.3.3 (2020-11-09) ------------------- - -* #519: Remove US/Pacific-New obsolete timezone (@phil-davis) - -4.3.2 (2020-10-03) ------------------- - -* #513: Added Support for PHP 8.0 (@phil-davis) - -4.3.1 (2020-07-13) ------------------- - -* #510: Fix an incomplete phpdoc type annotation (@mstilkerich) -* #505: Refactor unit test code for phpunit9 (@phil-davis) -* #500: Standardize CI (@phil-davis) -* #496: CI tooling changes (@JeroenVanOort) - -4.3.0 (2020-01-31) ------------------- - -* Added support for PHP 7.4, dropped support for PHP 7.0 (@phil-davis) -* #487: Added phpstan coverage, updated testsuite for phpunit8 (@phil-davis, @JeroenVanOort) -* #495: refactored maps to use ::class notation (@JeroenVanOort) - -4.2.2 (2020-01-14) ------------------- - -* #465: Add TZ in iTip REPLY iTip messages -* #486: Add PHONE-NUMBER value type (used for TEL in vCard 3.0) - -4.2.1 (2019-12-18) ------------------- - -* #469, #451: fix compat with php 7.4 -* #443: prevent running in indefinte loop -* #449: Preventing creating a component for a root document -* #450: Fix parse with option Forgiving with trailing equal -* #459: fixed typo in VCalendar which resulting in usage of the wrong TimeZone -* #462: Broker::parseEventForOrganizer copies DTSTAMP from $eventInfo that causes broken scheduling - -4.2.0 (2019-02-19) ------------------- - -* #432: DTSTAMP must be specified in UTC -* #435: ORGANIZER e-mail address are case-insensitive -* #441: Repairing BASE64 encoded vCard version 3 - -4.2.0-alpha1 (2018-09-26) -------------------------- - -* #412: Broker: add timezone to CANCEL messages -* #424: Support php7.3 - -4.1.6 (2018-04-20) ------------------- - -* #406, #407, #408, #409: Another round of performance improvements in serialization of properties (@gharlan, @staabm) -* #410: Fixes in iTip for handling `BYDAY=SA,SO` (@gharlan) -* #381: Fixes in iTip handling of `SCHEDULE-FORCE-SEND` (@alecpl) - -4.1.5 (2018-03-08) ------------------- - -* #404: Serialization: Performance boost for long properties (@gharlan) - -4.1.4 (2017-12-22) ------------------- - -* #383: Fix possible infinite loop in RRuleIterator, when the RRule FREQ - is YEARLY and it uses BYYEARDAY only (@mvdnes). -* #392: Improved significant change detection. This should reduce the number of - unneeded update emails in scheduling systems. (@alecpl). -* #395: Removed `Canada/East-Saskatchewan` timezone, as it got removed - from PHP as well. (@remicollet). - - -4.1.3 (2017-10-18) ------------------- - -* #363: Repair script and de-duplicate properties that are only allowed once, - but appear more than once. (@ddolcimascolo). -* #377: Added Pacific Time (US & Canada) as exchange timezone -* #384: Added fallback for VCards without `FN` - - -4.1.2 (2016-12-15) ------------------- - -* #340: Support for `BYYEARDAY` recurrence when `FREQ=YEARLY`. (@PHPGangsta) -* #341: Support for `BYWEEKNO` recurrence when `FREQ=YEARLY`. (@PHPGangsta) -* Updated to the latest windows timezone data mappings. -* #344: Auto-detecting more Outlook 365-generated timezone identifiers. - (@jpirkey) -* #348: `FreeBusyGenerator` can now accept streams. -* Support sabre/xml 1.5 and 2.0. -* #355: Support `DateTimeInterface` in more places where only `DateTime` was - supported. (@gharlan). -* #351: Fixing an inclusive/exclusive problem with `isInTimeRange` and - `fastForward` with all-day events. (@strokyl, thanks you are brilliant). - - -4.1.1 (2016-07-15) ------------------- - -* #327: Throwing `InvalidDataException` in more cases where invalid iCalendar - dates and times were provided. (@rsto) -* #331: Fix dealing with multiple overridden instances falling on the same - date/time (@afedyk-sugarcrm). -* #333: Fix endless loop on invalid `BYMONTH` values in recurrence. - (@PHPGangsta) -* #339: Fixed a few `validate()` results when repair is off. (@PHPGangsta) -* #338: Stripping invalid `BYMONTH=` rules during `validate()` (@PHPGangsta) -* #336: Fix incorrect `BYSECOND=` validation. (@PHPGangsta) - - -4.1.0 (2016-04-06) ------------------- - -* #309: When expanding recurring events, the first event should also have a - `RECURRENCE-ID` property. -* #306: iTip REPLYs to the first instance of a recurring event was not handled - correctly. -* Slightly better error message during validation of `N` and `ADR` properties. -* #312: Correctly extracing timezone in the iTip broker, even when we don't - have a master event. (@vkomrakov-sugar). -* When validating a component's property that must appear once and which could - automatically be repaired, make sure we report the change as 'repaired'. -* Added a PHPUnitAssertions trait. This trait makes it easy to compare two - vcards or iCalendar objects semantically. -* Better error message when parsing objects with an invalid `VALUE` parameter. - - -4.0.3 (2016-03-12) ------------------- - -* #300: Added `VCard::getByType()` to quickly get a property with a specific - `TYPE` parameter. (@kbond) -* #302: `UNTIL` was not encoded correctly when converting to jCal. - (@GrahamLinagora) -* #303: `COUNT` is now encoded as an int in jCal instead of a string. (@strokyl) -* #295: `RRULE` now has more validation and repair rules. - - -4.0.2 (2016-01-11) ------------------- - -* #288: Only decode `CHARSET` if we're reading vCard 2.1. If it appears - in any other document, we must ignore it. - - -4.0.1 (2016-01-04) ------------------- - -* #284: When generating `CANCEL` iTip messages, we now include `DTEND`. - (@kewisch) - - -4.0.0 (2015-12-11) ------------------- - -* #274: When creating new vCards, the default vCard version is now 4.0. -* #275: `VEVENT`, `VTODO` and `VCARD` now automatically get a `UID` and - `DTSTAMP` property if this was not already specified. -* `ParseException` now extends `\Exception`. -* `Sabre\VObject\Reader::read` now has a `$charset` argument. -* #272: `Sabre\VObject\Recur\EventIterator::$maxInstances` is now - `Sabre\VObject\Settings::$maxRecurrences` and is also honored by the - FreeBusyGenerator. -* #278: `expand()` did not work correctly on events with sub-components. - - -4.0.0-beta1 (2015-12-02) ------------------------- - -* #258: Support for expanding events that use `RDATE`. (@jabdoa2) -* #258: Correctly support TZID for events that use `RDATE`. (@jabdoa2) -* #240: `Component\VCalendar::expand()` now returns a new expanded `VCalendar` - object, instead of editing the existing `VCalendar` in-place. This is a BC - break. -* #265: Using the new `InvalidDataException` in place of - `InvalidArgumentException` and `LogicException` in all places where we fail - because there was something wrong with input data. -* #227: Always add `VALUE=URI` to `PHOTO` properties. -* #235: Always add `VALUE=URI` to `URL` properties. -* It's now possible to override which class is used instead of - `Component\VCalendar` or `Component\VCard` during parsing. -* #263: Lots of small cleanups. (@jakobsack) -* #220: Automatically stop recurring after 3500 recurrences. -* #41: Allow user to set different encoding than UTF-8 when decoding vCards. -* #41: Support the `ENCODING` parameter from vCard 2.1. - Both ISO-8859-1 and Windows-1252 are currently supported. -* #185: Fix encoding/decoding of `TIME` values in jCal/jCard. - - -4.0.0-alpha2 (2015-09-04) -------------------------- - -* Updated windows timezone file to support new mexican timezone. -* #239: Added a `BirthdayCalendarGenerator`. (@DominikTo) -* #250: `isInTimeRange()` now considers the timezone for floating dates and - times. (@armin-hackmann) -* Added a duplicate vcard merging tool for the command line. -* #253: `isInTimeRange()` now correctly handles events that throw the - `NoInstancesException` exception. (@migrax, @DominikTo) -* #254: The parser threw an `E_NOTICE` for certain invalid objects. It now - correctly throws a `ParseException`. - - -4.0.0-alpha1 (2015-07-17) -------------------------- - -* sabre/vobject now requires PHP 5.5. -* #244: PHP7 support. -* Lots of speedups and reduced memory usage! -* #160: Support for xCal a.k.a. RFC6321! (@Hywan) -* #192: Support for xCard a.k.a. RFC6351! (@Hywan) -* #139: We now accept `DateTimeInterface` wherever it accepted `DateTime` - before in arguments. This means that either `DateTime` or - `DateTimeImmutable` may be used everywhere. -* #242: Full support for the `VAVAILABILITY` component, and calculating - `VFREEBUSY` based on `VAVAILABILITY` data. -* #186: Fixing conversion of `UTC-OFFSET` properties when going back and - forward between jCal and iCalendar. -* Properties, Components and Parameters now implement PHP's `JsonSerializable` - interface. -* #139: We now _always_ return `DateTimeImmutable` from any method. This could - potentially have big implications if you manipulate Date objects anywhere. -* #161: Simplified `ElementList` by extending `ArrayIterator`. -* Removed `RecurrenceIterator` (use Recur\EventIterator instead). -* Now using php-cs-fixer to automatically enforce and correct CS. -* #233: The `+00:00` timezone is now recognized as UTC. (@c960657) -* #237: Added a `destroy()` method to all documents. This method breaks any - circular references, allowing PHP to free up memory. -* #197: Made accessing properties and objects by their name a lot faster. This - especially helps objects that have a lot of sub-components or properties, - such as large iCalendar objects. -* #197: The `$children` property on components has been changed from `public` - to `protected`. Use the `children()` method instead to get a flat list of - objects. -* #244: The `Float` and `Integer` classes have been renamed to `FloatValue` - and `IntegerValue` to allow PHP 7 compatibility. - - -3.5.3 (2016-10-06) ------------------- - -* #331: Fix dealing with multiple overridden instances falling on the same - date/time (@afedyk-sugarcrm). - - -3.5.2 (2016-04-24) ------------------ - -* #312: Backported a fix related to iTip processing of events with timezones, - without a master event. - - -3.5.1 (2016-04-06) ------------------- - -* #309: When expanding recurring events, the first event should also have a - `RECURRENCE-ID` property. -* #306: iTip REPLYs to the first instance of a recurring event was not handled - correctly. - - -3.5.0 (2016-01-11) ------------------- - -* This release supports PHP 7, contrary to 3.4.x versions. -* BC Break: `Sabre\VObject\Property\Float` has been renamed to - `Sabre\VObject\Property\FloatValue`. -* BC Break: `Sabre\VObject\Property\Integer` has been renamed to - `Sabre\VObject\Property\IntegerValue`. - - -3.4.9 (2016-01-11) ------------------- - -* This package now specifies in composer.json that it does not support PHP 7. - For PHP 7, use version 3.5.x or 4.x. - - -3.4.8 (2016-01-04) ------------------- - -* #284: When generating `CANCEL` iTip messages, we now include `DTEND`. - (@kewisch). - - -3.4.7 (2015-09-05) ------------------- - -* #253: Handle `isInTimeRange` for recurring events that have 0 valid - instances. (@DominikTo, @migrax). - - -3.4.6 (2015-08-06) ------------------- - -* #250: Recurring all-day events are incorrectly included in time range - requests when not using UTC in the time range. (@armin-hackmann) - - -3.4.5 (2015-06-02) ------------------- - -* #229: Converting vcards from 3.0 to 4.0 that contained a `LANG` property - would throw an error. - - -3.4.4 (2015-05-27) ------------------- - -* #228: Fixed a 'party crasher' bug in the iTip broker. This would break - scheduling in some cases. - - -3.4.3 (2015-05-19) ------------------- - -* #219: Corrected validation of `EXDATE` properties with more than one value. -* #212: `BYSETPOS` with values below `-1` was broken and could cause infinite - loops. -* #211: Fix `BYDAY=-5TH` in recurrence iterator. (@lindquist) -* #216: `ENCODING` parameter is now validated for all document types. -* #217: Initializing vCard `DATE` objects with a PHP DateTime object will now - work correctly. (@thomascube) - - -3.4.2 (2015-02-25) ------------------- - -* #210: iTip: Replying to an event without a master event was broken. - - -3.4.1 (2015-02-24) ------------------- - -* A minor change to ensure that unittests work correctly in the sabre/dav - test-suite. - - -3.4.0 (2015-02-23) ------------------- - -* #196: Made parsing recurrence rules a lot faster on big calendars. -* Updated windows timezone mappings to latest unicode version. -* #202: Support for parsing and validating `VAVAILABILITY` components. (@Hywan) -* #195: PHP 5.3 compatibility in 'generatevcards' script. (@rickdenhaan) -* #205: Improving handling of multiple `EXDATE` when processing iTip changes. - (@armin-hackmann) -* #187: Fixed validator rules for `LAST-MODIFIED` properties. -* #188: Retain floating times when generating instances using - `Recur\EventIterator`. -* #203: Skip tests for timezones that are not supported on older PHP versions, - instead of a hard fail. -* #204: Dealing a bit better with vCard date-time values that contained - milliseconds. (which is normally invalid). (@armin-hackmann) - - -3.3.5 (2015-01-09) ------------------- - -* #168: Expanding calendars now removes objects with recurrence rules that - don't have a valid recurrence instance. -* #177: SCHEDULE-STATUS should not contain a reason phrase, only a status - code. -* #175: Parser can now read and skip the UTF-8 BOM. -* #179: Added `isFloating` to `DATE-TIME` properties. -* #179: Fixed jCal serialization of floating `DATE-TIME` properties. -* #173: vCard converter failed for `X-ABDATE` properties that had no - `X-ABLABEL`. -* #180: Added `PROFILE_CALDAV` and `PROFILE_CARDDAV` to enable validation rules - specific for CalDAV/CardDAV servers. -* #176: A missing `UID` is no longer an error, but a warning for the vCard - validator, unless `PROFILE_CARDDAV` is specified. - - -3.3.4 (2014-11-19) ------------------- - -* #154: Converting `ANNIVERSARY` to `X-ANNIVERSARY` and `X-ABDATE` and - vice-versa when converting to/from vCard 4. -* #154: It's now possible to easily select all vCard properties belonging to - a single group with `$vcard->{'ITEM1.'}` syntax. (@armin-hackmann) -* #156: Simpler way to check if a string is UTF-8. (@Hywan) -* Unittest improvements. -* #159: The recurrence iterator, freebusy generator and iCalendar DATE and - DATE-TIME properties can now all accept a reference timezone when working - floating times or all-day events. -* #159: Master events will no longer get a `RECURRENCE-ID` when expanding. -* #159: `RECURRENCE-ID` for all-day events will now be correct when expanding. -* #163: Added a `getTimeZone()` method to `VTIMEZONE` components. - - -3.3.3 (2014-10-09) ------------------- - -* #142: `CANCEL` and `REPLY` messages now include the `DTSTART` from the - original event. -* #143: `SCHEDULE-AGENT` on the `ORGANIZER` property is respected. -* #144: `PARTSTAT=NEEDS-ACTION` is now set for new invites, if no `PARTSTAT` is - set to support the inbox feature of iOS. -* #147: Bugs related to scheduling all-day events. -* #148: Ignore events that have attendees but no organizer. -* #149: Avoiding logging errors during timezone detection. This is a workaround - for a PHP bug. -* Support for "Line Islands Standard Time" windows timezone. -* #154: Correctly work around vCard parameters that have a value but no name. - - -3.3.2 (2014-09-19) ------------------- - -* Changed: iTip broker now sets RSVP status to false when replies are received. -* #118: iTip Message now has a `getScheduleStatus()` method. -* #119: Support for detecting 'significant changes'. -* #120: Support for `SCHEDULE-FORCE-SEND`. -* #121: iCal demands parameters containing the + sign to be quoted. -* #122: Don't generate REPLY messages for events that have been cancelled. -* #123: Added `SUMMARY` to iTip messages. -* #130: Incorrect validation rules for `RELATED` (should be `RELATED-TO`). -* #128: `ATTACH` in iCalendar is `URI` by default, not `BINARY`. -* #131: RRULE that doesn't provide a single valid instance now throws an - exception. -* #136: Validator rejects *all* control characters. We were missing a few. -* #133: Splitter objects will throw exceptions when receiving incompatible - objects. -* #127: Attendees who delete recurring event instances events they had already - declined earlier will no longer generate another reply. -* #125: Send CANCEL messages when ORGANIZER property gets deleted. - - -3.3.1 (2014-08-18) ------------------- - -* Changed: It's now possible to pass DateTime objects when using the magic - setters on properties. (`$event->DTSTART = new DateTime('now')`). -* #111: iTip Broker does not process attendee adding events to EXDATE. -* #112: EventIterator now sets TZID on RECURRENCE-ID. -* #113: Timezone support during creation of iTip REPLY messages. -* #114: VTIMEZONE is retained when generating new REQUEST objects. -* #114: Support for 'MAILTO:' style email addresses (in uppercase) in the iTip - broker. This improves evolution support. -* #115: Using REQUEST-STATUS from REPLY messages and now propegating that into - SCHEDULE-STATUS. - - -3.3.0 (2014-08-07) ------------------- - -* We now use PSR-4 for the directory structure. This means that everything - that was used to be in the `lib/Sabre/VObject` directory is now moved to - `lib/`. If you use composer to load this library, you shouldn't have to do - anything about that though. -* VEVENT now get populated with a DTSTAMP and UID property by default. -* BC Break: Removed the 'includes.php' file. Use composer instead. -* #103: Added support for processing [iTip][iTip] messages. This allows a user - to parse incoming iTip messages and apply the result on existing calendars, - or automatically generate invites/replies/cancellations based on changes that - a user made on objects. -* #75, #58, #18: Fixes related to overriding the first event in recurrences. -* Added: VCalendar::getBaseComponent to find the 'master' component in a - calendar. -* #51: Support for iterating RDATE properties. -* Fixed: Issue #101: RecurrenceIterator::nextMonthly() shows events that are - excluded events with wrong time - - -3.2.4 (2014-07-14) ------------------- - -* Added: Issue #98. The VCardConverter now takes `X-APPLE-OMIT-YEAR` into - consideration when converting between vCard 3 and 4. -* Fixed: Issue #96. Some support for Yahoo's broken vcards. -* Fixed: PHP 5.3 support was broken in the cli tool. - - -3.2.3 (2014-06-12) ------------------- - -* Validator now checks if DUE and DTSTART are of the same type in VTODO, and - ensures that DUE is always after DTSTART. -* Removed documentation from source repository, to http://sabre.io/vobject/ -* Expanded the vobject cli tool validation output to make it easier to find - issues. -* Fixed: vobject repair. It was not working for iCalendar objects. - - -3.2.2 (2014-05-07) ------------------- - -* Minor tweak in unittests to make it run on PHP 5.5.12. Json-prettifying - slightly changed which caused the test to fail. - - -3.2.1 (2014-05-03) ------------------- - -* Minor tweak to make the unittests run with the latest hhvm on travis. -* Updated timezone definitions. -* Updated copyright links to point to http://sabre.io/ - - -3.2.0 (2014-04-02) ------------------- - -* Now hhvm compatible! -* The validator can now detect a _lot_ more problems. Many rules for both - iCalendar and vCard were added. -* Added: bin/generate_vcards, a utility to generate random vcards for testing - purposes. Patches are welcome to add more data. -* Updated: Windows timezone mapping to latest version from unicode.org -* Changed: The timezone maps are now loaded in from external files, in - lib/Sabre/VObject/timezonedata. -* Added: Fixing badly encoded URL's from google contacts vcards. -* Fixed: Issue #68. Couldn't decode properties ending in a colon. -* Fixed: Issue #72. RecurrenceIterator should respect timezone in the UNTIL - clause. -* Fixed: Issue #67. BYMONTH limit on DAILY recurrences. -* Fixed: Issue #26. Return a more descriptive error when coming across broken - BYDAY rules. -* Fixed: Issue #28. Incorrect timezone detection for some timezones. -* Fixed: Issue #70. Casting a parameter with a null value to string would fail. -* Added: Support for rfc6715 and rfc6474. -* Added: Support for DateTime objects in the VCard DATE-AND-OR-TIME property. -* Added: UUIDUtil, for easily creating unique identifiers. -* Fixed: Issue #83. Creating new VALUE=DATE objects using php's DateTime. -* Fixed: Issue #86. Don't go into an infinite loop when php errors are - disabled and an invalid file is read. - - -3.1.4 (2014-03-30) ------------------- - -* Fixed: Issue #87: Several compatibility fixes related to timezone handling - changes in PHP 5.5.10. - - -3.1.3 (2013-10-02) ------------------- - -* Fixed: Support from properties from draft-daboo-valarm-extensions-04. Issue - #56. -* Fixed: Issue #54. Parsing a stream of multiple vcards separated by more than - one newline. Thanks @Vedmak for the patch. -* Fixed: Serializing vcard 2.1 parameters with no name caused a literal '1' to - be inserted. -* Added: VCardConverter removed properties that are no longer supported in vCard - 4.0. -* Added: vCards with a minimum number of values (such as N), but don't have that - many, are now automatically padded with empty components. -* Added: The vCard validator now also checks for a minimum number of components, - and has the ability to repair these. -* Added: Some support for vCard 2.1 in the VCard converter, to upgrade to vCard - 3.0 or 4.0. -* Fixed: Issue 60 Use Document::$componentMap when instantiating the top-level - VCalendar and VCard components. -* Fixed: Issue 62: Parsing iCalendar parameters with no value. -* Added: --forgiving option to vobject utility. -* Fixed: Compound properties such as ADR were not correctly split up in vCard - 2.1 quoted printable-encoded properties. -* Fixed: Issue 64: Encoding of binary properties of converted vCards. Thanks - @DominikTo for the patch. - - -3.1.2 (2013-08-13) ------------------- - -* Fixed: Setting correct property group on VCard conversion - - -3.1.1 (2013-08-02) ------------------- - -* Fixed: Issue #53. A regression in RecurrenceIterator. - - -3.1.0 (2013-07-27) ------------------- - -* Added: bad-ass new cli debugging utility (in bin/vobject). -* Added: jCal and jCard parser. -* Fixed: URI properties should not escape ; and ,. -* Fixed: VCard 4 documents now correctly use URI as a default value-type for - PHOTO and others. BINARY no longer exists in vCard 4. -* Added: Utility to convert between 2.1, 3.0 and 4.0 vCards. -* Added: You can now add() multiple parameters to a property in one call. -* Added: Parameter::has() for easily checking if a parameter value exists. -* Added: VCard::preferred() to find a preferred email, phone number, etc for a - contact. -* Changed: All $duration properties are now public. -* Added: A few validators for iCalendar documents. -* Fixed: Issue #50. RecurrenceIterator gives incorrect result when exception - events are out of order in the iCalendar file. -* Fixed: Issue #48. Overridden events in the recurrence iterator that were past - the UNTIL date were ignored. -* Added: getDuration for DURATION values such as TRIGGER. Thanks to - @SimonSimCity. -* Fixed: Issue #52. vCard 2.1 parameters with no name may lose values if there's - more than 1. Thanks to @Vedmak. - - -3.0.0 (2013-06-21) ------------------- - -* Fixed: includes.php file was still broken. Our tool to generate it had some - bugs. - - -3.0.0-beta4 (2013-06-21) ------------------------- - -* Fixed: includes.php was no longer up to date. - - -3.0.0-beta3 (2013-06-17) ------------------------- - -* Added: OPTION_FORGIVING now also allows slashes in property names. -* Fixed: DateTimeParser no longer fails on dates with years < 1000 & > 4999 -* Fixed: Issue 36: Workaround for the recurrenceiterator and caldav events with - a missing base event. -* Fixed: jCard encoding of TIME properties. -* Fixed: jCal encoding of REQUEST-STATUS, GEO and PERIOD values. - - -3.0.0-beta2 (2013-06-10) ------------------------- - -* Fixed: Corrected includes.php file. -* Fixed: vCard date-time parser supported extended-format dates as well. -* Changed: Properties have been moved to an ICalendar or VCard directory. -* Fixed: Couldn't parse vCard 3 extended format dates and times. -* Fixed: Couldn't export jCard DATE values correctly. -* Fixed: Recursive loop in ICalendar\DateTime property. - - -3.0.0-beta1 (2013-06-07) ------------------------- - -* Added: jsonSerialize() for creating jCal and jCard documents. -* Added: helper method to parse vCard dates and times. -* Added: Specialized classes for FLOAT, LANGUAGE-TAG, TIME, TIMESTAMP, - DATE-AND-OR-TIME, CAL-ADDRESS, UNKNOWN and UTC-OFFSET properties. -* Removed: CommaSeparatedText property. Now included into Text. -* Fixed: Multiple parameters with the same name are now correctly encoded. -* Fixed: Parameter values containing a comma are now enclosed in double-quotes. -* Fixed: Iterating parameter values should now fully work as expected. -* Fixed: Support for vCard 2.1 nameless parameters. -* Changed: $valueMap, $componentMap and $propertyMap now all use fully-qualified - class names, so they are actually overridable. -* Fixed: Updating DATE-TIME to DATE values now behaves like expected. - - -3.0.0-alpha4 (2013-05-31) -------------------------- - -* Added: It's now possible to send parser options to the splitter classes. -* Added: A few tweaks to improve component and property creation. - - -3.0.0-alpha3 (2013-05-13) -------------------------- - -* Changed: propertyMap, valueMap and componentMap are now static properties. -* Changed: Component::remove() will throw an exception when trying to a node - that's not a child of said component. -* Added: Splitter objects are now faster, line numbers are accurately reported - and use less memory. -* Added: MimeDir parser can now continue parsing with the same stream buffer. -* Fixed: vobjectvalidate.php is operational again. -* Fixed: \r is properly stripped in text values. -* Fixed: QUOTED-PRINTABLE is now correctly encoded as well as encoded, for - vCards 2.1. -* Fixed: Parser assumes vCard 2.1, if no version was supplied. - - -3.0.0-alpha2 (2013-05-22) -------------------------- - -* Fixed: vCard URL properties were referencing a non-existant class. - - -3.0.0-alpha1 (2013-05-21) -------------------------- - -* Fixed: Now correctly dealing with escaping of properties. This solves the - problem with double-backslashes where they don't belong. -* Added: Easy support for properties with more than one value, using setParts - and getParts. -* Added: Support for broken 2.1 vCards produced by microsoft. -* Added: Automatically decoding quoted-printable values. -* Added: Automatically decoding base64 values. -* Added: Decoding RFC6868 parameter values (uses ^ as an escape character). -* Added: Fancy new MimeDir parser that can also parse streams. -* Added: Automatically mapping many, many properties to a property-class with - specialized API's. -* Added: remove() method for easily removing properties and sub-components - components. -* Changed: Components, Properties and Parameters can no longer be created with - Component::create, Property::create and Parameter::create. They must instead - be created through the root component. (A VCalendar or VCard object). -* Changed: API for DateTime properties has slightly changed. -* Changed: the ->value property is now protected everywhere. Use getParts() and - getValue() instead. -* BC Break: No support for mac newlines (\r). Never came across these anyway. -* Added: add() method to the Property class. -* Added: It's now possible to easy set multi-value properties as arrays. -* Added: When setting date-time properties you can just pass PHP's DateTime - object. -* Added: New components automatically get a bunch of default properties, such as - VERSION and CALSCALE. -* Added: You can add new sub-components much quicker with the magic setters, and - add() method. - - -2.1.7 (2015-01-21) ------------------- - -* Fixed: Issue #94, a workaround for bad escaping of ; and , in compound - properties. It's not a full solution, but it's an improvement for those - stuck in the 2.1 versions. - - -2.1.6 (2014-12-10) ------------------- - -* Fixed: Minor change to make sure that unittests succeed on every PHP version. - - -2.1.5 (2014-06-03) ------------------- - -* Fixed: #94: Better parameter escaping. -* Changed: Documentation cleanups. - - -2.1.4 (2014-03-30) ------------------- - -* Fixed: Issue #87: Several compatibility fixes related to timezone handling - changes in PHP 5.5.10. - - -2.1.3 (2013-10-02) ------------------- - -* Fixed: Issue #55. \r must be stripped from property values. -* Fixed: Issue #65. Putting quotes around parameter values that contain a colon. - - -2.1.2 (2013-08-02) ------------------- - -* Fixed: Issue #53. A regression in RecurrenceIterator. - - -2.1.1 (2013-07-27) ------------------- - -* Fixed: Issue #50. RecurrenceIterator gives incorrect result when exception - events are out of order in the iCalendar file. -* Fixed: Issue #48. Overridden events in the recurrence iterator that were past - the UNTIL date were ignored. - - -2.1.0 (2013-06-17) ------------------- - -* This version is fully backwards compatible with 2.0.\*. However, it contains a - few new API's that mimic the VObject 3 API. This allows it to be used a - 'bridge' version. Specifically, this new version exists so SabreDAV 1.7 and - 1.8 can run with both the 2 and 3 versions of this library. -* Added: Property\DateTime::hasTime(). -* Added: Property\MultiDateTime::hasTime(). -* Added: Property::getValue(). -* Added: Document class. -* Added: Document::createComponent and Document::createProperty. -* Added: Parameter::getValue(). - - -2.0.7 (2013-03-05) ------------------- - -* Fixed: Microsoft re-uses their magic numbers for different timezones, - specifically id 2 for both Sarajevo and Lisbon). A workaround was added to - deal with this. - - -2.0.6 (2013-02-17) ------------------- - -* Fixed: The reader now properly parses parameters without a value. - - -2.0.5 (2012-11-05) ------------------- - -* Fixed: The FreeBusyGenerator is now properly using the factory methods for - creation of components and properties. - - -2.0.4 (2012-11-02) ------------------- - -* Added: Known Lotus Notes / Domino timezone id's. - - -2.0.3 (2012-10-29) ------------------- - -* Added: Support for 'GMT+????' format in TZID's. -* Added: Support for formats like SystemV/EST5EDT in TZID's. -* Fixed: RecurrenceIterator now repairs recurrence rules where UNTIL < DTSTART. -* Added: Support for BYHOUR in FREQ=DAILY (@hollodk). -* Added: Support for BYHOUR and BYDAY in FREQ=WEEKLY. - - -2.0.2 (2012-10-06) ------------------- - -* Added: includes.php file, to load the entire library in one go. -* Fixed: A problem with determining alarm triggers for TODO's. - - -2.0.1 (2012-09-22) ------------------- - -* Removed: Element class. It wasn't used. -* Added: Basic validation and repair methods for broken input data. -* Fixed: RecurrenceIterator could infinitely loop when an INTERVAL of 0 was - specified. -* Added: A cli script that can validate and automatically repair vcards and - iCalendar objects. -* Added: A new 'Compound' property, that can automatically split up parts for - properties such as N, ADR, ORG and CATEGORIES. -* Added: Splitter classes, that can split up large objects (such as exports) - into individual objects (thanks @DominikTo and @armin-hackmann). -* Added: VFREEBUSY component, which allows easily checking wether timeslots are - available. -* Added: The Reader class now has a 'FORGIVING' option, which allows it to parse - properties with incorrect characters in the name (at this time, it just allows - underscores). -* Added: Also added the 'IGNORE_INVALID_LINES' option, to completely disregard - any invalid lines. -* Fixed: A bug in Windows timezone-id mappings for times created in Greenlands - timezone (sorry Greenlanders! I do care!). -* Fixed: DTEND was not generated correctly for VFREEBUSY reports. -* Fixed: Parser is at least 25% faster with real-world data. - - -2.0.0 (2012-08-08) ------------------- - -* VObject is now a separate project from SabreDAV. See the SabreDAV changelog - for version information before 2.0. -* New: VObject library now uses PHP 5.3 namespaces. -* New: It's possible to specify lists of parameters when constructing - properties. -* New: made it easier to construct the FreeBusyGenerator. - -[iTip]: http://tools.ietf.org/html/rfc5546 diff --git a/vendor/sabre/vobject/bin/bench.php b/vendor/sabre/vobject/bin/bench.php old mode 100644 new mode 100755 diff --git a/vendor/sabre/vobject/bin/bench_freebusygenerator.php b/vendor/sabre/vobject/bin/bench_freebusygenerator.php index 1299c14fb..963623d18 100644 --- a/vendor/sabre/vobject/bin/bench_freebusygenerator.php +++ b/vendor/sabre/vobject/bin/bench_freebusygenerator.php @@ -11,7 +11,7 @@ if ($argc < 2) { echo "The process will be repeated 100 times to get accurate stats\n"; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.ics\n"; - die(); + exit(); } list(, $inputFile) = $argv; diff --git a/vendor/sabre/vobject/bin/bench_manipulatevcard.php b/vendor/sabre/vobject/bin/bench_manipulatevcard.php index f229091db..df6d9f23d 100644 --- a/vendor/sabre/vobject/bin/bench_manipulatevcard.php +++ b/vendor/sabre/vobject/bin/bench_manipulatevcard.php @@ -10,7 +10,7 @@ if ($argc < 2) { echo 'system.'; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.vcf\n"; - die(); + exit(); } list(, $inputFile) = $argv; diff --git a/vendor/sabre/vobject/bin/fetch_windows_zones.php b/vendor/sabre/vobject/bin/fetch_windows_zones.php old mode 100644 new mode 100755 index 9c4e51abd..2361dc309 --- a/vendor/sabre/vobject/bin/fetch_windows_zones.php +++ b/vendor/sabre/vobject/bin/fetch_windows_zones.php @@ -1,13 +1,12 @@ #!/usr/bin/env php <?php -$windowsZonesUrl = 'http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml'; +$windowsZonesUrl = 'https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml'; $outputFile = __DIR__.'/../lib/timezonedata/windowszones.php'; echo 'Fetching timezone map from: '.$windowsZonesUrl, "\n"; $data = file_get_contents($windowsZonesUrl); - $xml = simplexml_load_string($data); $map = []; @@ -44,6 +43,6 @@ fclose($f); echo "Formatting\n"; -exec(__DIR__.'/sabre-cs-fixer fix '.escapeshellarg($outputFile)); +exec(__DIR__.'/../vendor/bin/php-cs-fixer fix '.escapeshellarg($outputFile)); echo "Done\n"; diff --git a/vendor/sabre/vobject/bin/generateicalendardata.php b/vendor/sabre/vobject/bin/generateicalendardata.php old mode 100644 new mode 100755 index 62b6107c5..019ed9745 --- a/vendor/sabre/vobject/bin/generateicalendardata.php +++ b/vendor/sabre/vobject/bin/generateicalendardata.php @@ -18,7 +18,7 @@ The iCalendar output goes to stdout. Other messages to stderr. HI ); - die(); + exit(); } $events = 100; @@ -77,7 +77,7 @@ $result = $calendar->validate(); if ($result) { fwrite(STDERR, "Errors!\n"); fwrite(STDERR, print_r($result, true)); - die(-1); + exit(-1); } fwrite(STDERR, "Serializing this beast\n"); diff --git a/vendor/sabre/vobject/bin/mergeduplicates.php b/vendor/sabre/vobject/bin/mergeduplicates.php old mode 100644 new mode 100755 index e6cde73dd..31b2c14ab --- a/vendor/sabre/vobject/bin/mergeduplicates.php +++ b/vendor/sabre/vobject/bin/mergeduplicates.php @@ -19,7 +19,7 @@ foreach ($paths as $path) { if (!class_exists('Sabre\\VObject\\Version')) { fwrite(STDERR, "Composer autoloader could not be loaded.\n"); - die(1); + exit(1); } echo 'sabre/vobject ', Version::VERSION, " duplicate contact merge tool\n"; @@ -27,7 +27,7 @@ echo 'sabre/vobject ', Version::VERSION, " duplicate contact merge tool\n"; if ($argc < 3) { echo "\n"; echo 'Usage: ', $argv[0], " input.vcf output.vcf [debug.log]\n"; - die(1); + exit(1); } $input = fopen($argv[1], 'r'); diff --git a/vendor/sabre/vobject/bin/rrulebench.php b/vendor/sabre/vobject/bin/rrulebench.php index 583da574c..69008002e 100644 --- a/vendor/sabre/vobject/bin/rrulebench.php +++ b/vendor/sabre/vobject/bin/rrulebench.php @@ -9,7 +9,7 @@ if ($argc < 4) { echo 'system.'; echo "\n"; echo 'Usage: '.$argv[0]." inputfile.ics startdate enddate\n"; - die(); + exit(); } list(, $inputFile, $startDate, $endDate) = $argv; diff --git a/vendor/sabre/vobject/composer.json b/vendor/sabre/vobject/composer.json index f26c0b5ec..b745b1fa6 100644 --- a/vendor/sabre/vobject/composer.json +++ b/vendor/sabre/vobject/composer.json @@ -37,8 +37,9 @@ "sabre/xml" : "^2.1" }, "require-dev" : { - "friendsofphp/php-cs-fixer": "~2.16.7", + "friendsofphp/php-cs-fixer": "~2.17.1", "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.0", + "phpunit/php-invoker" : "^2.0 || ^3.1", "phpstan/phpstan": "^0.12" }, "suggest" : { diff --git a/vendor/sabre/vobject/lib/Cli.php b/vendor/sabre/vobject/lib/Cli.php index f3e419b15..4984ac9b2 100644 --- a/vendor/sabre/vobject/lib/Cli.php +++ b/vendor/sabre/vobject/lib/Cli.php @@ -2,8 +2,7 @@ namespace Sabre\VObject; -use - InvalidArgumentException; +use InvalidArgumentException; /** * This is the CLI interface for sabre-vobject. @@ -137,17 +136,14 @@ class Cli // jcard/jcal documents case 'jcard': case 'jcal': - // specific document versions case 'vcard21': case 'vcard30': case 'vcard40': case 'icalendar20': - // specific formats case 'json': case 'mimedir': - // icalendar/vcad case 'icalendar': case 'vcard': @@ -183,7 +179,6 @@ class Cli case 'vcard30': case 'vcard40': case 'icalendar20': - $this->inputFormat = 'mimedir'; break; @@ -211,7 +206,7 @@ class Cli } if (!in_array($positional[0], ['validate', 'repair', 'convert', 'color'])) { - throw new InvalidArgumentException('Uknown command: '.$positional[0]); + throw new InvalidArgumentException('Unknown command: '.$positional[0]); } } catch (InvalidArgumentException $e) { $this->showHelp(); diff --git a/vendor/sabre/vobject/lib/Component.php b/vendor/sabre/vobject/lib/Component.php index da45eb29f..07f6a627f 100644 --- a/vendor/sabre/vobject/lib/Component.php +++ b/vendor/sabre/vobject/lib/Component.php @@ -160,9 +160,9 @@ class Component extends Node return; } } - } - throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component'); + throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component'); + } } /** diff --git a/vendor/sabre/vobject/lib/Component/VCalendar.php b/vendor/sabre/vobject/lib/Component/VCalendar.php index 40e09a1c0..4db318135 100644 --- a/vendor/sabre/vobject/lib/Component/VCalendar.php +++ b/vendor/sabre/vobject/lib/Component/VCalendar.php @@ -309,7 +309,7 @@ class VCalendar extends VObject\Document foreach ($this->children() as $child) { if ($child instanceof Property && 'PRODID' !== $child->name) { - // We explictly want to ignore PRODID, because we want to + // We explicitly want to ignore PRODID, because we want to // overwrite it with our own. $newChildren[] = clone $child; } elseif ($child instanceof Component && 'VTIMEZONE' !== $child->name) { diff --git a/vendor/sabre/vobject/lib/Component/VCard.php b/vendor/sabre/vobject/lib/Component/VCard.php index 51321949f..2430df621 100644 --- a/vendor/sabre/vobject/lib/Component/VCard.php +++ b/vendor/sabre/vobject/lib/Component/VCard.php @@ -373,7 +373,7 @@ class VCard extends VObject\Document /** * Returns a preferred field. * - * VCards can indicate wether a field such as ADR, TEL or EMAIL is + * VCards can indicate whether a field such as ADR, TEL or EMAIL is * preferred by specifying TYPE=PREF (vcard 2.1, 3) or PREF=x (vcard 4, x * being a number between 1 and 100). * diff --git a/vendor/sabre/vobject/lib/FreeBusyData.php b/vendor/sabre/vobject/lib/FreeBusyData.php index d05dfc799..4d9f441ce 100644 --- a/vendor/sabre/vobject/lib/FreeBusyData.php +++ b/vendor/sabre/vobject/lib/FreeBusyData.php @@ -84,7 +84,7 @@ class FreeBusyData 'type' => $type, ]; - $preceedingItem = $this->data[$insertStartIndex - 1]; + $precedingItem = $this->data[$insertStartIndex - 1]; if ($this->data[$insertStartIndex - 1]['start'] === $start) { // The old item starts at the exact same point as the new item. --$insertStartIndex; @@ -122,11 +122,11 @@ class FreeBusyData // between. if (-1 === $itemsToDelete) { $itemsToDelete = 0; - if ($newItem['end'] < $preceedingItem['end']) { + if ($newItem['end'] < $precedingItem['end']) { $newItems[] = [ 'start' => $newItem['end'] + 1, - 'end' => $preceedingItem['end'], - 'type' => $preceedingItem['type'], + 'end' => $precedingItem['end'], + 'type' => $precedingItem['type'], ]; } } diff --git a/vendor/sabre/vobject/lib/FreeBusyGenerator.php b/vendor/sabre/vobject/lib/FreeBusyGenerator.php index a1c24044c..81b8126d5 100644 --- a/vendor/sabre/vobject/lib/FreeBusyGenerator.php +++ b/vendor/sabre/vobject/lib/FreeBusyGenerator.php @@ -126,7 +126,7 @@ class FreeBusyGenerator /** * Sets the input objects. * - * You must either specify a valendar object as a string, or as the parse + * You must either specify a vcalendar object as a string, or as the parse * Component. * It's also possible to specify multiple objects as an array. * @@ -362,7 +362,6 @@ class FreeBusyGenerator foreach ($object->getBaseComponents() as $component) { switch ($component->name) { case 'VEVENT': - $FBTYPE = 'BUSY'; if (isset($component->TRANSP) && ('TRANSPARENT' === strtoupper($component->TRANSP))) { break; diff --git a/vendor/sabre/vobject/lib/Parameter.php b/vendor/sabre/vobject/lib/Parameter.php index e39d320a1..72f2ecbcb 100644 --- a/vendor/sabre/vobject/lib/Parameter.php +++ b/vendor/sabre/vobject/lib/Parameter.php @@ -95,13 +95,11 @@ class Parameter extends Node case 'WORK': case 'HOME': case 'PREF': - // Delivery Label Type case 'DOM': case 'INTL': case 'POSTAL': case 'PARCEL': - // Telephone types case 'VOICE': case 'FAX': @@ -113,7 +111,6 @@ class Parameter extends Node case 'CAR': case 'ISDN': case 'VIDEO': - // EMAIL types (lol) case 'AOL': case 'APPLELINK': @@ -127,7 +124,6 @@ class Parameter extends Node case 'PRODIGY': case 'TLX': case 'X400': - // Photo / Logo format types case 'GIF': case 'CGM': @@ -143,12 +139,10 @@ class Parameter extends Node case 'MPEG2': case 'AVI': case 'QTIME': - // Sound Digital Audio Type case 'WAVE': case 'PCM': case 'AIFF': - // Key types case 'X509': case 'PGP': @@ -299,7 +293,7 @@ class Parameter extends Node // https://tools.ietf.org/html/rfc6868 // // But we've found that iCal (7.0, shipped with OSX 10.9) - // severaly trips on + characters not being quoted, so we + // severely trips on + characters not being quoted, so we // added + as well. if (!preg_match('#(?: [\n":;\^,\+] )#x', $item)) { return $out.$item; diff --git a/vendor/sabre/vobject/lib/Parser/MimeDir.php b/vendor/sabre/vobject/lib/Parser/MimeDir.php index ea5ac0326..385d340d7 100644 --- a/vendor/sabre/vobject/lib/Parser/MimeDir.php +++ b/vendor/sabre/vobject/lib/Parser/MimeDir.php @@ -343,7 +343,7 @@ class MimeDir extends Parser ) (?=[;:,]) /xi"; - //echo $regex, "\n"; die(); + //echo $regex, "\n"; exit(); preg_match_all($regex, $line, $matches, PREG_SET_ORDER); $property = [ diff --git a/vendor/sabre/vobject/lib/Property/Boolean.php b/vendor/sabre/vobject/lib/Property/Boolean.php index 9fb2bce35..4bd6ffdfe 100644 --- a/vendor/sabre/vobject/lib/Property/Boolean.php +++ b/vendor/sabre/vobject/lib/Property/Boolean.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property; -use - Sabre\VObject\Property; +use Sabre\VObject\Property; /** * Boolean property. diff --git a/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php b/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php index e89bb31f9..86be66c15 100644 --- a/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php +++ b/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property\ICalendar; -use - Sabre\VObject\Property\Text; +use Sabre\VObject\Property\Text; /** * CalAddress property. diff --git a/vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php b/vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php index f2dbdeba3..d635e17ae 100644 --- a/vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php +++ b/vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php @@ -184,7 +184,7 @@ class DateTime extends Property * Sets the property as multiple date-time objects. * * The first value will be used as a reference for the timezones, and all - * the otehr values will be adjusted for that timezone + * the other values will be adjusted for that timezone * * @param DateTimeInterface[] $dt * @param bool isFloating If set to true, timezones will be ignored diff --git a/vendor/sabre/vobject/lib/Property/IntegerValue.php b/vendor/sabre/vobject/lib/Property/IntegerValue.php index 6f709bfff..3ae775214 100644 --- a/vendor/sabre/vobject/lib/Property/IntegerValue.php +++ b/vendor/sabre/vobject/lib/Property/IntegerValue.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property; -use - Sabre\VObject\Property; +use Sabre\VObject\Property; /** * Integer property. diff --git a/vendor/sabre/vobject/lib/Property/VCard/LanguageTag.php b/vendor/sabre/vobject/lib/Property/VCard/LanguageTag.php index 697273989..318ea0231 100644 --- a/vendor/sabre/vobject/lib/Property/VCard/LanguageTag.php +++ b/vendor/sabre/vobject/lib/Property/VCard/LanguageTag.php @@ -2,8 +2,7 @@ namespace Sabre\VObject\Property\VCard; -use - Sabre\VObject\Property; +use Sabre\VObject\Property; /** * LanguageTag property. diff --git a/vendor/sabre/vobject/lib/Recur/EventIterator.php b/vendor/sabre/vobject/lib/Recur/EventIterator.php index fd904b383..e42ca1360 100644 --- a/vendor/sabre/vobject/lib/Recur/EventIterator.php +++ b/vendor/sabre/vobject/lib/Recur/EventIterator.php @@ -83,7 +83,7 @@ class EventIterator implements \Iterator * 2. You can pass an array of VEVENTs (all UIDS should match). * 3. You can pass a single VEVENT component. * - * Only the second method is recomended. The other 1 and 3 will be removed + * Only the second method is recommended. The other 1 and 3 will be removed * at some point in the future. * * The $uid parameter is only required for the first method. diff --git a/vendor/sabre/vobject/lib/Recur/RRuleIterator.php b/vendor/sabre/vobject/lib/Recur/RRuleIterator.php index 55581e9ac..0511f0ade 100644 --- a/vendor/sabre/vobject/lib/Recur/RRuleIterator.php +++ b/vendor/sabre/vobject/lib/Recur/RRuleIterator.php @@ -468,6 +468,13 @@ class RRuleIterator implements Iterator // beginning. $currentDayOfMonth = 0; + // For some reason the "until" parameter was not being used here, + // that's why the workaround of the 10000 year bug was needed at all + // let's stop it before the "until" parameter date + if ($this->until && $this->currentDate->getTimestamp() >= $this->until->getTimestamp()) { + return; + } + // To prevent running this forever (better: until we hit the max date of DateTimeImmutable) we simply // stop at 9999-12-31. Looks like the year 10000 problem is not solved in php .... if ($this->currentDate->getTimestamp() > 253402300799) { @@ -536,7 +543,7 @@ class RRuleIterator implements Iterator foreach ($this->byWeekNo as $byWeekNo) { foreach ($dayOffsets as $dayOffset) { $date = clone $this->currentDate; - $date->setISODate($currentYear, $byWeekNo, $dayOffset); + $date = $date->setISODate($currentYear, $byWeekNo, $dayOffset); if ($date > $this->currentDate) { $checkDates[] = $date; @@ -717,7 +724,6 @@ class RRuleIterator implements Iterator break; case 'INTERVAL': - case 'COUNT': $val = (int) $value; if ($val < 1) { @@ -877,7 +883,7 @@ class RRuleIterator implements Iterator foreach ($this->byMonthDay as $monthDay) { // Removing values that are out of range for this month if ($monthDay > $startDate->format('t') || - $monthDay < 0 - $startDate->format('t')) { + $monthDay < 0 - $startDate->format('t')) { continue; } if ($monthDay > 0) { diff --git a/vendor/sabre/vobject/lib/Version.php b/vendor/sabre/vobject/lib/Version.php index 29ba84f88..63452400f 100644 --- a/vendor/sabre/vobject/lib/Version.php +++ b/vendor/sabre/vobject/lib/Version.php @@ -14,5 +14,5 @@ class Version /** * Full version number. */ - const VERSION = '4.3.3'; + const VERSION = '4.3.5'; } diff --git a/vendor/sabre/vobject/lib/timezonedata/windowszones.php b/vendor/sabre/vobject/lib/timezonedata/windowszones.php index af3904b12..2049a95c1 100644 --- a/vendor/sabre/vobject/lib/timezonedata/windowszones.php +++ b/vendor/sabre/vobject/lib/timezonedata/windowszones.php @@ -3,14 +3,14 @@ /** * Automatically generated timezone file. * - * Last update: 2016-08-24T17:35:38-04:00 - * Source: http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml + * Last update: 2020-12-13T17:38:12+05:45 + * Source: https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml * - * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/). + * @copyright Copyright (C) fruux GmbH (https://fruux.com/). * @license http://sabre.io/license/ Modified BSD License */ -return [ +return [ 'AUS Central Standard Time' => 'Australia/Darwin', 'AUS Eastern Standard Time' => 'Australia/Sydney', 'Afghanistan Standard Time' => 'Asia/Kabul', @@ -74,6 +74,7 @@ return [ 'Line Islands Standard Time' => 'Pacific/Kiritimati', 'Lord Howe Standard Time' => 'Australia/Lord_Howe', 'Magadan Standard Time' => 'Asia/Magadan', + 'Magallanes Standard Time' => 'America/Punta_Arenas', 'Marquesas Standard Time' => 'Pacific/Marquesas', 'Mauritius Standard Time' => 'Indian/Mauritius', 'Middle East Standard Time' => 'Asia/Beirut', @@ -91,11 +92,13 @@ return [ 'North Asia East Standard Time' => 'Asia/Irkutsk', 'North Asia Standard Time' => 'Asia/Krasnoyarsk', 'North Korea Standard Time' => 'Asia/Pyongyang', + 'Omsk Standard Time' => 'Asia/Omsk', 'Pacific SA Standard Time' => 'America/Santiago', 'Pacific Standard Time' => 'America/Los_Angeles', 'Pacific Standard Time (Mexico)' => 'America/Tijuana', 'Pakistan Standard Time' => 'Asia/Karachi', 'Paraguay Standard Time' => 'America/Asuncion', + 'Qyzylorda Standard Time' => 'Asia/Qyzylorda', 'Romance Standard Time' => 'Europe/Paris', 'Russia Time Zone 10' => 'Asia/Srednekolymsk', 'Russia Time Zone 11' => 'Asia/Kamchatka', @@ -108,9 +111,12 @@ return [ 'Saint Pierre Standard Time' => 'America/Miquelon', 'Sakhalin Standard Time' => 'Asia/Sakhalin', 'Samoa Standard Time' => 'Pacific/Apia', + 'Sao Tome Standard Time' => 'Africa/Sao_Tome', + 'Saratov Standard Time' => 'Europe/Saratov', 'Singapore Standard Time' => 'Asia/Singapore', 'South Africa Standard Time' => 'Africa/Johannesburg', 'Sri Lanka Standard Time' => 'Asia/Colombo', + 'Sudan Standard Time' => 'Africa/Khartoum', 'Syria Standard Time' => 'Asia/Damascus', 'Taipei Standard Time' => 'Asia/Taipei', 'Tasmania Standard Time' => 'Australia/Hobart', @@ -125,6 +131,7 @@ return [ 'US Mountain Standard Time' => 'America/Phoenix', 'UTC' => 'Etc/GMT', 'UTC+12' => 'Etc/GMT-12', + 'UTC+13' => 'Etc/GMT-13', 'UTC-02' => 'Etc/GMT+2', 'UTC-08' => 'Etc/GMT+8', 'UTC-09' => 'Etc/GMT+9', @@ -132,6 +139,7 @@ return [ 'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar', 'Venezuela Standard Time' => 'America/Caracas', 'Vladivostok Standard Time' => 'Asia/Vladivostok', + 'Volgograd Standard Time' => 'Europe/Volgograd', 'W. Australia Standard Time' => 'Australia/Perth', 'W. Central Africa Standard Time' => 'Africa/Lagos', 'W. Europe Standard Time' => 'Europe/Berlin', @@ -140,4 +148,5 @@ return [ 'West Bank Standard Time' => 'Asia/Hebron', 'West Pacific Standard Time' => 'Pacific/Port_Moresby', 'Yakutsk Standard Time' => 'Asia/Yakutsk', + 'Yukon Standard Time' => 'America/Whitehorse', ]; diff --git a/vendor/sabre/vobject/phpstan.neon b/vendor/sabre/vobject/phpstan.neon deleted file mode 100644 index c705178c9..000000000 --- a/vendor/sabre/vobject/phpstan.neon +++ /dev/null @@ -1,4 +0,0 @@ -parameters: - level: 1 - universalObjectCratesClasses: - - \Sabre\VObject\Component diff --git a/vendor/sabre/vobject/tests/bootstrap.php b/vendor/sabre/vobject/tests/bootstrap.php deleted file mode 100644 index 2496aa4ff..000000000 --- a/vendor/sabre/vobject/tests/bootstrap.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php - -date_default_timezone_set('UTC'); - -$try = [ - __DIR__.'/../vendor/autoload.php', - __DIR__.'/../../../autoload.php', -]; - -foreach ($try as $path) { - if (file_exists($path)) { - $autoLoader = include $path; - break; - } -} diff --git a/vendor/sabre/vobject/tests/phpunit.xml b/vendor/sabre/vobject/tests/phpunit.xml deleted file mode 100644 index c0588d460..000000000 --- a/vendor/sabre/vobject/tests/phpunit.xml +++ /dev/null @@ -1,21 +0,0 @@ -<phpunit - colors="true" - bootstrap="bootstrap.php" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - beStrictAboutTestsThatDoNotTestAnything="true" - beStrictAboutOutputDuringTests="true" - > - <testsuites> - <testsuite name="Sabre\VObject"> - <directory>.</directory> - </testsuite> - </testsuites> - - <filter> - <whitelist addUncoveredFilesFromWhitelist="true"> - <directory suffix=".php">../lib/</directory> - </whitelist> - </filter> -</phpunit> -- cgit v1.2.3 From 1e48be7ab7cfd0c7d16ed04e4ddc086dee01ee36 Mon Sep 17 00:00:00 2001 From: Mario <mario@mariovavti.com> Date: Mon, 15 Feb 2021 18:39:11 +0000 Subject: compser update symfony/polyfill-ctype --- composer.lock | 14 +++++++------- vendor/composer/InstalledVersions.php | 10 +++++----- vendor/composer/installed.json | 16 ++++++++-------- vendor/composer/installed.php | 10 +++++----- vendor/symfony/polyfill-ctype/bootstrap.php | 26 +++++++++++++++----------- vendor/symfony/polyfill-ctype/composer.json | 2 +- 6 files changed, 41 insertions(+), 37 deletions(-) diff --git a/composer.lock b/composer.lock index 18d2cd586..e3b3e2637 100644 --- a/composer.lock +++ b/composer.lock @@ -1474,16 +1474,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { @@ -1495,7 +1495,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1533,7 +1533,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" }, "funding": [ { @@ -1549,7 +1549,7 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "twbs/bootstrap", diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 88cdba06c..d73fdf6f4 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', + 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -241,12 +241,12 @@ private static $installed = array ( ), 'symfony/polyfill-ctype' => array ( - 'pretty_version' => 'v1.20.0', - 'version' => '1.20.0.0', + 'pretty_version' => 'v1.22.0', + 'version' => '1.22.0.0', 'aliases' => array ( ), - 'reference' => 'f4ba089a5b6366e453971d3aad5fe8e897b37f41', + 'reference' => 'c6c942b1ac76c82448322025e084cadc56048b4e', ), 'twbs/bootstrap' => array ( @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', + 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', ), ), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index ab8f9899a..62956251e 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1503,17 +1503,17 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", - "version_normalized": "1.20.0.0", + "version": "v1.22.0", + "version_normalized": "1.22.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { @@ -1522,11 +1522,11 @@ "suggest": { "ext-ctype": "For best performance" }, - "time": "2020-10-23T14:02:19+00:00", + "time": "2021-01-07T16:49:33+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1565,7 +1565,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 2b6305c54..aff338786 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', + 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -218,12 +218,12 @@ ), 'symfony/polyfill-ctype' => array ( - 'pretty_version' => 'v1.20.0', - 'version' => '1.20.0.0', + 'pretty_version' => 'v1.22.0', + 'version' => '1.22.0.0', 'aliases' => array ( ), - 'reference' => 'f4ba089a5b6366e453971d3aad5fe8e897b37f41', + 'reference' => 'c6c942b1ac76c82448322025e084cadc56048b4e', ), 'twbs/bootstrap' => array ( @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '02401ea9fd5d53f590305c0f9834685cda58723d', + 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', ), ), ); diff --git a/vendor/symfony/polyfill-ctype/bootstrap.php b/vendor/symfony/polyfill-ctype/bootstrap.php index 0bc45cfdf..d54524b31 100644 --- a/vendor/symfony/polyfill-ctype/bootstrap.php +++ b/vendor/symfony/polyfill-ctype/bootstrap.php @@ -11,36 +11,40 @@ use Symfony\Polyfill\Ctype as p; +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + if (!function_exists('ctype_alnum')) { - function ctype_alnum($input) { return p\Ctype::ctype_alnum($input); } + function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } } if (!function_exists('ctype_alpha')) { - function ctype_alpha($input) { return p\Ctype::ctype_alpha($input); } + function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } } if (!function_exists('ctype_cntrl')) { - function ctype_cntrl($input) { return p\Ctype::ctype_cntrl($input); } + function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } } if (!function_exists('ctype_digit')) { - function ctype_digit($input) { return p\Ctype::ctype_digit($input); } + function ctype_digit($text) { return p\Ctype::ctype_digit($text); } } if (!function_exists('ctype_graph')) { - function ctype_graph($input) { return p\Ctype::ctype_graph($input); } + function ctype_graph($text) { return p\Ctype::ctype_graph($text); } } if (!function_exists('ctype_lower')) { - function ctype_lower($input) { return p\Ctype::ctype_lower($input); } + function ctype_lower($text) { return p\Ctype::ctype_lower($text); } } if (!function_exists('ctype_print')) { - function ctype_print($input) { return p\Ctype::ctype_print($input); } + function ctype_print($text) { return p\Ctype::ctype_print($text); } } if (!function_exists('ctype_punct')) { - function ctype_punct($input) { return p\Ctype::ctype_punct($input); } + function ctype_punct($text) { return p\Ctype::ctype_punct($text); } } if (!function_exists('ctype_space')) { - function ctype_space($input) { return p\Ctype::ctype_space($input); } + function ctype_space($text) { return p\Ctype::ctype_space($text); } } if (!function_exists('ctype_upper')) { - function ctype_upper($input) { return p\Ctype::ctype_upper($input); } + function ctype_upper($text) { return p\Ctype::ctype_upper($text); } } if (!function_exists('ctype_xdigit')) { - function ctype_xdigit($input) { return p\Ctype::ctype_xdigit($input); } + function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } } diff --git a/vendor/symfony/polyfill-ctype/composer.json b/vendor/symfony/polyfill-ctype/composer.json index 2088bb9f6..995978c0a 100644 --- a/vendor/symfony/polyfill-ctype/composer.json +++ b/vendor/symfony/polyfill-ctype/composer.json @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", -- cgit v1.2.3 From 6fae291cc8ec69a74d0c1673186b3d8f319378d4 Mon Sep 17 00:00:00 2001 From: Mario <mario@mariovavti.com> Date: Mon, 15 Feb 2021 18:40:00 +0000 Subject: missing file --- vendor/symfony/polyfill-ctype/bootstrap80.php | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 vendor/symfony/polyfill-ctype/bootstrap80.php diff --git a/vendor/symfony/polyfill-ctype/bootstrap80.php b/vendor/symfony/polyfill-ctype/bootstrap80.php new file mode 100644 index 000000000..ab2f8611d --- /dev/null +++ b/vendor/symfony/polyfill-ctype/bootstrap80.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (!function_exists('ctype_alnum')) { + function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); } +} -- cgit v1.2.3 From e8c2e17bc901ab139377e759f5ef931f8649b8c1 Mon Sep 17 00:00:00 2001 From: Mario <mario@mariovavti.com> Date: Mon, 15 Feb 2021 18:41:44 +0000 Subject: compser update twbs/bootstrap --- composer.lock | 12 +- vendor/composer/InstalledVersions.php | 12 +- vendor/composer/installed.json | 14 +- vendor/composer/installed.php | 12 +- vendor/twbs/bootstrap/.bundlewatch.config.json | 2 +- vendor/twbs/bootstrap/.eslintignore | 3 +- vendor/twbs/bootstrap/.eslintrc.json | 16 +- vendor/twbs/bootstrap/.github/CONTRIBUTING.md | 26 +- .../bootstrap/.github/workflows/browserstack.yml | 20 +- .../bootstrap/.github/workflows/bundlewatch.yml | 20 +- vendor/twbs/bootstrap/.github/workflows/codeql.yml | 19 +- vendor/twbs/bootstrap/.github/workflows/css.yml | 20 +- .../twbs/bootstrap/.github/workflows/dart-sass.yml | 16 +- vendor/twbs/bootstrap/.github/workflows/docs.yml | 52 +- vendor/twbs/bootstrap/.github/workflows/js.yml | 22 +- vendor/twbs/bootstrap/.github/workflows/lint.yml | 20 +- vendor/twbs/bootstrap/.gitignore | 8 - vendor/twbs/bootstrap/.stylelintignore | 1 + vendor/twbs/bootstrap/.stylelintrc | 4 + vendor/twbs/bootstrap/CNAME | 1 - vendor/twbs/bootstrap/CODE_OF_CONDUCT.md | 5 +- vendor/twbs/bootstrap/Gemfile | 9 - vendor/twbs/bootstrap/LICENSE | 4 +- vendor/twbs/bootstrap/README.md | 26 +- vendor/twbs/bootstrap/_config.yml | 74 - vendor/twbs/bootstrap/build/build-plugins.js | 8 +- vendor/twbs/bootstrap/build/change-version.js | 4 +- vendor/twbs/bootstrap/build/generate-sri.js | 12 +- vendor/twbs/bootstrap/build/postcss.config.js | 24 +- vendor/twbs/bootstrap/build/rollup.config.js | 2 +- vendor/twbs/bootstrap/build/ship.sh | 0 vendor/twbs/bootstrap/build/vnu-jar.js | 4 +- vendor/twbs/bootstrap/build/zip-examples.js | 75 +- vendor/twbs/bootstrap/dist/css/bootstrap-grid.css | 6 +- .../twbs/bootstrap/dist/css/bootstrap-grid.css.map | 2 +- .../twbs/bootstrap/dist/css/bootstrap-grid.min.css | 6 +- .../bootstrap/dist/css/bootstrap-grid.min.css.map | 2 +- .../twbs/bootstrap/dist/css/bootstrap-reboot.css | 13 +- .../bootstrap/dist/css/bootstrap-reboot.css.map | 2 +- .../bootstrap/dist/css/bootstrap-reboot.min.css | 8 +- .../dist/css/bootstrap-reboot.min.css.map | 2 +- vendor/twbs/bootstrap/dist/css/bootstrap.css | 133 +- vendor/twbs/bootstrap/dist/css/bootstrap.css.map | 2 +- vendor/twbs/bootstrap/dist/css/bootstrap.min.css | 8 +- .../twbs/bootstrap/dist/css/bootstrap.min.css.map | 2 +- vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js | 124 +- .../twbs/bootstrap/dist/js/bootstrap.bundle.js.map | 2 +- .../twbs/bootstrap/dist/js/bootstrap.bundle.min.js | 6 +- .../bootstrap/dist/js/bootstrap.bundle.min.js.map | 2 +- vendor/twbs/bootstrap/dist/js/bootstrap.js | 124 +- vendor/twbs/bootstrap/dist/js/bootstrap.js.map | 2 +- vendor/twbs/bootstrap/dist/js/bootstrap.min.js | 6 +- vendor/twbs/bootstrap/dist/js/bootstrap.min.js.map | 2 +- vendor/twbs/bootstrap/js/dist/alert.js | 25 +- vendor/twbs/bootstrap/js/dist/alert.js.map | 2 +- vendor/twbs/bootstrap/js/dist/button.js | 23 +- vendor/twbs/bootstrap/js/dist/button.js.map | 2 +- vendor/twbs/bootstrap/js/dist/carousel.js | 72 +- vendor/twbs/bootstrap/js/dist/carousel.js.map | 2 +- vendor/twbs/bootstrap/js/dist/collapse.js | 43 +- vendor/twbs/bootstrap/js/dist/collapse.js.map | 2 +- vendor/twbs/bootstrap/js/dist/dropdown.js | 49 +- vendor/twbs/bootstrap/js/dist/dropdown.js.map | 2 +- vendor/twbs/bootstrap/js/dist/index.js | 2 +- vendor/twbs/bootstrap/js/dist/modal.js | 95 +- vendor/twbs/bootstrap/js/dist/modal.js.map | 2 +- vendor/twbs/bootstrap/js/dist/popover.js | 49 +- vendor/twbs/bootstrap/js/dist/popover.js.map | 2 +- vendor/twbs/bootstrap/js/dist/scrollspy.js | 43 +- vendor/twbs/bootstrap/js/dist/scrollspy.js.map | 2 +- vendor/twbs/bootstrap/js/dist/tab.js | 25 +- vendor/twbs/bootstrap/js/dist/tab.js.map | 2 +- vendor/twbs/bootstrap/js/dist/toast.js | 43 +- vendor/twbs/bootstrap/js/dist/toast.js.map | 2 +- vendor/twbs/bootstrap/js/dist/tooltip.js | 56 +- vendor/twbs/bootstrap/js/dist/tooltip.js.map | 2 +- vendor/twbs/bootstrap/js/dist/util.js | 6 +- vendor/twbs/bootstrap/js/dist/util.js.map | 2 +- vendor/twbs/bootstrap/js/src/alert.js | 4 +- vendor/twbs/bootstrap/js/src/button.js | 4 +- vendor/twbs/bootstrap/js/src/carousel.js | 32 +- vendor/twbs/bootstrap/js/src/collapse.js | 4 +- vendor/twbs/bootstrap/js/src/dropdown.js | 10 +- vendor/twbs/bootstrap/js/src/index.js | 34 - vendor/twbs/bootstrap/js/src/modal.js | 60 +- vendor/twbs/bootstrap/js/src/popover.js | 4 +- vendor/twbs/bootstrap/js/src/scrollspy.js | 4 +- vendor/twbs/bootstrap/js/src/tab.js | 4 +- vendor/twbs/bootstrap/js/src/toast.js | 4 +- vendor/twbs/bootstrap/js/src/tools/sanitizer.js | 2 +- vendor/twbs/bootstrap/js/src/tooltip.js | 9 +- vendor/twbs/bootstrap/js/src/util.js | 2 +- vendor/twbs/bootstrap/nuget/bootstrap.nuspec | 2 +- vendor/twbs/bootstrap/nuget/bootstrap.sass.nuspec | 2 +- vendor/twbs/bootstrap/package-lock.json | 5735 +++++++++++--------- vendor/twbs/bootstrap/package.js | 16 +- vendor/twbs/bootstrap/package.json | 119 +- vendor/twbs/bootstrap/scss/_breadcrumb.scss | 4 +- vendor/twbs/bootstrap/scss/_carousel.scss | 2 +- vendor/twbs/bootstrap/scss/_custom-forms.scss | 6 +- vendor/twbs/bootstrap/scss/_dropdown.scss | 2 +- vendor/twbs/bootstrap/scss/_input-group.scss | 24 +- vendor/twbs/bootstrap/scss/_nav.scss | 5 +- vendor/twbs/bootstrap/scss/_navbar.scss | 12 +- vendor/twbs/bootstrap/scss/_pagination.scss | 4 +- vendor/twbs/bootstrap/scss/_progress.scss | 2 +- vendor/twbs/bootstrap/scss/_reboot.scss | 16 +- vendor/twbs/bootstrap/scss/_root.scss | 1 - vendor/twbs/bootstrap/scss/_spinners.scss | 13 +- vendor/twbs/bootstrap/scss/_type.scss | 2 +- vendor/twbs/bootstrap/scss/_variables.scss | 12 +- vendor/twbs/bootstrap/scss/bootstrap-grid.scss | 7 +- vendor/twbs/bootstrap/scss/bootstrap-reboot.scss | 6 +- vendor/twbs/bootstrap/scss/bootstrap.scss | 6 +- vendor/twbs/bootstrap/scss/mixins/_forms.scss | 9 +- vendor/twbs/bootstrap/scss/mixins/_image.scss | 2 +- vendor/twbs/bootstrap/site/.eslintrc.json | 4 +- vendor/twbs/bootstrap/site/_data/breakpoints.yml | 29 - vendor/twbs/bootstrap/site/_data/browser-bugs.yml | 411 -- .../twbs/bootstrap/site/_data/browser-features.yml | 139 - vendor/twbs/bootstrap/site/_data/colors.yml | 26 - vendor/twbs/bootstrap/site/_data/core-team.yml | 32 - vendor/twbs/bootstrap/site/_data/docs-versions.yml | 46 - vendor/twbs/bootstrap/site/_data/examples.yml | 55 - vendor/twbs/bootstrap/site/_data/grays.yml | 18 - vendor/twbs/bootstrap/site/_data/nav.yml | 92 - vendor/twbs/bootstrap/site/_data/theme-colors.yml | 16 - vendor/twbs/bootstrap/site/_data/translations.yml | 29 - vendor/twbs/bootstrap/site/_includes/ads.html | 1 - .../twbs/bootstrap/site/_includes/analytics.html | 7 - vendor/twbs/bootstrap/site/_includes/bugify.html | 42 - .../site/_includes/callout-danger-async-methods.md | 8 - .../callout-info-mediaqueries-breakpoints.md | 4 - .../_includes/callout-info-prefersreducedmotion.md | 4 - ...callout-warning-color-assistive-technologies.md | 6 - vendor/twbs/bootstrap/site/_includes/callout.html | 9 - .../twbs/bootstrap/site/_includes/docs-navbar.html | 70 - .../bootstrap/site/_includes/docs-sidebar.html | 43 - vendor/twbs/bootstrap/site/_includes/example.html | 51 - vendor/twbs/bootstrap/site/_includes/favicons.html | 9 - vendor/twbs/bootstrap/site/_includes/footer.html | 12 - vendor/twbs/bootstrap/site/_includes/header.html | 23 - .../site/_includes/icons/bootstrap-stack.svg | 1 - .../bootstrap/site/_includes/icons/bootstrap.svg | 1 - .../site/_includes/icons/circle-square.svg | 4 - .../bootstrap/site/_includes/icons/cloud-fill.svg | 3 - .../twbs/bootstrap/site/_includes/icons/code.svg | 3 - .../site/_includes/icons/droplet-fill.svg | 3 - .../twbs/bootstrap/site/_includes/icons/github.svg | 1 - .../twbs/bootstrap/site/_includes/icons/menu.svg | 1 - .../site/_includes/icons/opencollective.svg | 1 - .../bootstrap/site/_includes/icons/placeholder.svg | 35 - .../twbs/bootstrap/site/_includes/icons/slack.svg | 1 - .../bootstrap/site/_includes/icons/twitter.svg | 1 - vendor/twbs/bootstrap/site/_includes/scripts.html | 23 - vendor/twbs/bootstrap/site/_includes/skippy.html | 8 - vendor/twbs/bootstrap/site/_includes/social.html | 17 - .../twbs/bootstrap/site/_includes/stylesheet.html | 16 - vendor/twbs/bootstrap/site/_layouts/default.html | 22 - vendor/twbs/bootstrap/site/_layouts/docs.html | 37 - vendor/twbs/bootstrap/site/_layouts/examples.html | 56 - vendor/twbs/bootstrap/site/_layouts/simple.html | 21 - vendor/twbs/bootstrap/site/docs/4.5/about/brand.md | 78 - .../twbs/bootstrap/site/docs/4.5/about/license.md | 34 - .../twbs/bootstrap/site/docs/4.5/about/overview.md | 27 - vendor/twbs/bootstrap/site/docs/4.5/about/team.md | 21 - .../bootstrap/site/docs/4.5/about/translations.md | 18 - .../docs/4.5/assets/brand/bootstrap-outline.svg | 5 - .../docs/4.5/assets/brand/bootstrap-punchout.svg | 5 - .../4.5/assets/brand/bootstrap-social-logo.png | Bin 23959 -> 0 bytes .../docs/4.5/assets/brand/bootstrap-social.png | Bin 231733 -> 0 bytes .../site/docs/4.5/assets/brand/bootstrap-solid.svg | 5 - .../site/docs/4.5/assets/css/docs.min.css | 8 - .../site/docs/4.5/assets/css/docs.min.css.map | 1 - .../site/docs/4.5/assets/img/bootstrap-icons.png | Bin 40798 -> 0 bytes .../docs/4.5/assets/img/bootstrap-icons@2x.png | Bin 125571 -> 0 bytes .../4.5/assets/img/bootstrap-themes-collage.png | Bin 74876 -> 0 bytes .../4.5/assets/img/bootstrap-themes-collage@2x.png | Bin 244640 -> 0 bytes .../site/docs/4.5/assets/img/bootstrap-themes.png | Bin 88695 -> 0 bytes .../docs/4.5/assets/img/bootstrap-themes@2x.png | Bin 278159 -> 0 bytes .../site/docs/4.5/assets/img/examples/album.png | Bin 21740 -> 0 bytes .../site/docs/4.5/assets/img/examples/album@2x.png | Bin 26370 -> 0 bytes .../site/docs/4.5/assets/img/examples/blog.png | Bin 32843 -> 0 bytes .../site/docs/4.5/assets/img/examples/blog@2x.png | Bin 36944 -> 0 bytes .../site/docs/4.5/assets/img/examples/carousel.png | Bin 21450 -> 0 bytes .../docs/4.5/assets/img/examples/carousel@2x.png | Bin 31465 -> 0 bytes .../site/docs/4.5/assets/img/examples/checkout.png | Bin 25151 -> 0 bytes .../docs/4.5/assets/img/examples/checkout@2x.png | Bin 28180 -> 0 bytes .../site/docs/4.5/assets/img/examples/cover.png | Bin 7240 -> 0 bytes .../site/docs/4.5/assets/img/examples/cover@2x.png | Bin 17953 -> 0 bytes .../docs/4.5/assets/img/examples/dashboard.png | Bin 24376 -> 0 bytes .../docs/4.5/assets/img/examples/dashboard@2x.png | Bin 26556 -> 0 bytes .../4.5/assets/img/examples/floating-labels.png | Bin 10516 -> 0 bytes .../4.5/assets/img/examples/floating-labels@2x.png | Bin 11053 -> 0 bytes .../site/docs/4.5/assets/img/examples/grid.png | Bin 37960 -> 0 bytes .../site/docs/4.5/assets/img/examples/grid@2x.png | Bin 34834 -> 0 bytes .../docs/4.5/assets/img/examples/jumbotron.png | Bin 31403 -> 0 bytes .../docs/4.5/assets/img/examples/jumbotron@2x.png | Bin 38408 -> 0 bytes .../docs/4.5/assets/img/examples/navbar-bottom.png | Bin 9774 -> 0 bytes .../4.5/assets/img/examples/navbar-bottom@2x.png | Bin 11316 -> 0 bytes .../docs/4.5/assets/img/examples/navbar-fixed.png | Bin 11569 -> 0 bytes .../4.5/assets/img/examples/navbar-fixed@2x.png | Bin 13616 -> 0 bytes .../docs/4.5/assets/img/examples/navbar-static.png | Bin 12523 -> 0 bytes .../4.5/assets/img/examples/navbar-static@2x.png | Bin 14893 -> 0 bytes .../site/docs/4.5/assets/img/examples/navbars.png | Bin 24748 -> 0 bytes .../docs/4.5/assets/img/examples/navbars@2x.png | Bin 27187 -> 0 bytes .../docs/4.5/assets/img/examples/offcanvas.png | Bin 20148 -> 0 bytes .../docs/4.5/assets/img/examples/offcanvas@2x.png | Bin 23975 -> 0 bytes .../site/docs/4.5/assets/img/examples/pricing.png | Bin 25033 -> 0 bytes .../docs/4.5/assets/img/examples/pricing@2x.png | Bin 29128 -> 0 bytes .../site/docs/4.5/assets/img/examples/product.png | Bin 24977 -> 0 bytes .../docs/4.5/assets/img/examples/product@2x.png | Bin 27953 -> 0 bytes .../site/docs/4.5/assets/img/examples/sign-in.png | Bin 5704 -> 0 bytes .../docs/4.5/assets/img/examples/sign-in@2x.png | Bin 5680 -> 0 bytes .../4.5/assets/img/examples/starter-template.png | Bin 9761 -> 0 bytes .../assets/img/examples/starter-template@2x.png | Bin 11334 -> 0 bytes .../assets/img/examples/sticky-footer-navbar.png | Bin 14167 -> 0 bytes .../img/examples/sticky-footer-navbar@2x.png | Bin 15836 -> 0 bytes .../docs/4.5/assets/img/examples/sticky-footer.png | Bin 8170 -> 0 bytes .../4.5/assets/img/examples/sticky-footer@2x.png | Bin 9665 -> 0 bytes .../assets/img/favicons/android-chrome-192x192.png | Bin 1935 -> 0 bytes .../assets/img/favicons/android-chrome-512x512.png | Bin 4269 -> 0 bytes .../4.5/assets/img/favicons/apple-touch-icon.png | Bin 1738 -> 0 bytes .../docs/4.5/assets/img/favicons/browserconfig.xml | 11 - .../docs/4.5/assets/img/favicons/favicon-16x16.png | Bin 310 -> 0 bytes .../docs/4.5/assets/img/favicons/favicon-32x32.png | Bin 491 -> 0 bytes .../docs/4.5/assets/img/favicons/manifest.json | 22 - .../4.5/assets/img/favicons/mstile-144x144.png | Bin 1479 -> 0 bytes .../4.5/assets/img/favicons/mstile-150x150.png | Bin 1428 -> 0 bytes .../4.5/assets/img/favicons/mstile-310x150.png | Bin 1746 -> 0 bytes .../4.5/assets/img/favicons/mstile-310x310.png | Bin 3085 -> 0 bytes .../docs/4.5/assets/img/favicons/mstile-70x70.png | Bin 1104 -> 0 bytes .../4.5/assets/img/favicons/safari-pinned-tab.svg | 4 - .../bootstrap/site/docs/4.5/assets/js/docs.min.js | 22 - .../site/docs/4.5/assets/js/src/application.js | 112 - .../assets/js/src/ie-emulation-modes-warning.js | 52 - .../site/docs/4.5/assets/js/src/search.js | 59 - .../site/docs/4.5/assets/js/vendor/anchor.min.js | 9 - .../assets/js/vendor/bs-custom-file-input.min.js | 7 - .../docs/4.5/assets/js/vendor/clipboard.min.js | 7 - .../docs/4.5/assets/js/vendor/jquery.slim.min.js | 2 - .../bootstrap/site/docs/4.5/assets/scss/_ads.scss | 39 - .../site/docs/4.5/assets/scss/_algolia.scss | 155 - .../site/docs/4.5/assets/scss/_anchor.scss | 10 - .../site/docs/4.5/assets/scss/_brand.scss | 88 - .../site/docs/4.5/assets/scss/_browser-bugs.scss | 12 - .../site/docs/4.5/assets/scss/_buttons.scss | 55 - .../site/docs/4.5/assets/scss/_callouts.scss | 40 - .../site/docs/4.5/assets/scss/_clipboard-js.scss | 36 - .../site/docs/4.5/assets/scss/_colors.scss | 17 - .../docs/4.5/assets/scss/_component-examples.scss | 378 -- .../site/docs/4.5/assets/scss/_content.scss | 127 - .../site/docs/4.5/assets/scss/_footer.scss | 40 - .../site/docs/4.5/assets/scss/_masthead.scss | 80 - .../bootstrap/site/docs/4.5/assets/scss/_nav.scss | 71 - .../docs/4.5/assets/scss/_placeholder-img.scss | 15 - .../site/docs/4.5/assets/scss/_sidebar.scss | 161 - .../site/docs/4.5/assets/scss/_skippy.scss | 20 - .../site/docs/4.5/assets/scss/_syntax.scss | 78 - .../site/docs/4.5/assets/scss/_variables.scss | 15 - .../bootstrap/site/docs/4.5/assets/scss/docs.scss | 52 - .../twbs/bootstrap/site/docs/4.5/browser-bugs.md | 72 - .../bootstrap/site/docs/4.5/components/alerts.md | 118 - .../bootstrap/site/docs/4.5/components/badge.md | 74 - .../site/docs/4.5/components/breadcrumb.md | 58 - .../site/docs/4.5/components/button-group.md | 207 - .../bootstrap/site/docs/4.5/components/buttons.md | 167 - .../bootstrap/site/docs/4.5/components/card.md | 875 --- .../bootstrap/site/docs/4.5/components/carousel.md | 370 -- .../bootstrap/site/docs/4.5/components/collapse.md | 251 - .../site/docs/4.5/components/dropdowns.md | 915 ---- .../bootstrap/site/docs/4.5/components/forms.md | 1457 ----- .../site/docs/4.5/components/input-group.md | 384 -- .../site/docs/4.5/components/jumbotron.md | 31 - .../site/docs/4.5/components/list-group.md | 393 -- .../site/docs/4.5/components/media-object.md | 144 - .../bootstrap/site/docs/4.5/components/modal.md | 815 --- .../bootstrap/site/docs/4.5/components/navbar.md | 581 -- .../bootstrap/site/docs/4.5/components/navs.md | 666 --- .../site/docs/4.5/components/pagination.md | 174 - .../bootstrap/site/docs/4.5/components/popovers.md | 409 -- .../bootstrap/site/docs/4.5/components/progress.md | 146 - .../site/docs/4.5/components/scrollspy.md | 345 -- .../bootstrap/site/docs/4.5/components/spinners.md | 185 - .../bootstrap/site/docs/4.5/components/toasts.md | 332 -- .../bootstrap/site/docs/4.5/components/tooltips.md | 388 -- .../twbs/bootstrap/site/docs/4.5/content/code.md | 55 - .../bootstrap/site/docs/4.5/content/figures.md | 28 - .../twbs/bootstrap/site/docs/4.5/content/images.md | 84 - .../twbs/bootstrap/site/docs/4.5/content/reboot.md | 380 -- .../twbs/bootstrap/site/docs/4.5/content/tables.md | 831 --- .../bootstrap/site/docs/4.5/content/typography.md | 301 - .../bootstrap/site/docs/4.5/examples/.stylelintrc | 15 - .../site/docs/4.5/examples/album/album.css | 33 - .../site/docs/4.5/examples/album/index.html | 207 - .../bootstrap/site/docs/4.5/examples/blog/blog.css | 106 - .../site/docs/4.5/examples/blog/index.html | 201 - .../site/docs/4.5/examples/carousel/carousel.css | 90 - .../site/docs/4.5/examples/carousel/index.html | 163 - .../docs/4.5/examples/checkout/form-validation.css | 5 - .../docs/4.5/examples/checkout/form-validation.js | 21 - .../site/docs/4.5/examples/checkout/index.html | 223 - .../site/docs/4.5/examples/cover/cover.css | 106 - .../site/docs/4.5/examples/cover/index.html | 34 - .../site/docs/4.5/examples/dashboard/dashboard.css | 103 - .../site/docs/4.5/examples/dashboard/dashboard.js | 53 - .../site/docs/4.5/examples/dashboard/index.html | 249 - .../examples/floating-labels/floating-labels.css | 123 - .../docs/4.5/examples/floating-labels/index.html | 32 - .../bootstrap/site/docs/4.5/examples/grid/grid.css | 13 - .../site/docs/4.5/examples/grid/index.html | 138 - .../bootstrap/site/docs/4.5/examples/index.html | 44 - .../site/docs/4.5/examples/jumbotron/index.html | 79 - .../site/docs/4.5/examples/jumbotron/jumbotron.css | 4 - .../docs/4.5/examples/navbar-bottom/index.html | 39 - .../site/docs/4.5/examples/navbar-fixed/index.html | 37 - .../4.5/examples/navbar-fixed/navbar-top-fixed.css | 5 - .../docs/4.5/examples/navbar-static/index.html | 37 - .../docs/4.5/examples/navbar-static/navbar-top.css | 4 - .../site/docs/4.5/examples/navbars/index.html | 361 -- .../site/docs/4.5/examples/navbars/navbar.css | 7 - .../site/docs/4.5/examples/offcanvas/index.html | 135 - .../site/docs/4.5/examples/offcanvas/offcanvas.css | 76 - .../site/docs/4.5/examples/offcanvas/offcanvas.js | 7 - .../site/docs/4.5/examples/pricing/index.html | 110 - .../site/docs/4.5/examples/pricing/pricing.css | 20 - .../site/docs/4.5/examples/product/index.html | 145 - .../site/docs/4.5/examples/product/product.css | 74 - .../site/docs/4.5/examples/sign-in/index.html | 23 - .../site/docs/4.5/examples/sign-in/signin.css | 44 - .../docs/4.5/examples/starter-template/index.html | 47 - .../examples/starter-template/starter-template.css | 7 - .../4.5/examples/sticky-footer-navbar/index.html | 49 - .../sticky-footer-navbar/sticky-footer-navbar.css | 20 - .../docs/4.5/examples/sticky-footer/index.html | 23 - .../4.5/examples/sticky-footer/sticky-footer.css | 13 - .../site/docs/4.5/getting-started/accessibility.md | 57 - .../docs/4.5/getting-started/best-practices.md | 21 - .../docs/4.5/getting-started/browsers-devices.md | 192 - .../site/docs/4.5/getting-started/build-tools.md | 58 - .../site/docs/4.5/getting-started/contents.md | 140 - .../site/docs/4.5/getting-started/download.md | 115 - .../site/docs/4.5/getting-started/introduction.md | 166 - .../site/docs/4.5/getting-started/javascript.md | 211 - .../site/docs/4.5/getting-started/theming.md | 488 -- .../site/docs/4.5/getting-started/webpack.md | 93 - vendor/twbs/bootstrap/site/docs/4.5/layout/grid.md | 904 --- .../bootstrap/site/docs/4.5/layout/overview.md | 275 - .../site/docs/4.5/layout/utilities-for-layout.md | 25 - vendor/twbs/bootstrap/site/docs/4.5/migration.md | 337 -- .../bootstrap/site/docs/4.5/utilities/borders.md | 91 - .../bootstrap/site/docs/4.5/utilities/clearfix.md | 38 - .../site/docs/4.5/utilities/close-icon.md | 15 - .../bootstrap/site/docs/4.5/utilities/colors.md | 58 - .../bootstrap/site/docs/4.5/utilities/display.md | 102 - .../bootstrap/site/docs/4.5/utilities/embed.md | 61 - .../twbs/bootstrap/site/docs/4.5/utilities/flex.md | 570 -- .../bootstrap/site/docs/4.5/utilities/float.md | 57 - .../site/docs/4.5/utilities/image-replacement.md | 36 - .../site/docs/4.5/utilities/interactions.md | 19 - .../bootstrap/site/docs/4.5/utilities/overflow.md | 24 - .../bootstrap/site/docs/4.5/utilities/position.md | 45 - .../site/docs/4.5/utilities/screen-readers.md | 25 - .../bootstrap/site/docs/4.5/utilities/shadows.md | 18 - .../bootstrap/site/docs/4.5/utilities/sizing.md | 56 - .../bootstrap/site/docs/4.5/utilities/spacing.md | 105 - .../site/docs/4.5/utilities/stretched-link.md | 80 - .../twbs/bootstrap/site/docs/4.5/utilities/text.md | 132 - .../site/docs/4.5/utilities/vertical-align.md | 40 - .../site/docs/4.5/utilities/visibility.md | 34 - vendor/twbs/bootstrap/site/docs/versions.html | 30 - vendor/twbs/bootstrap/site/index.html | 124 - vendor/twbs/bootstrap/site/robots.txt | 11 - vendor/twbs/bootstrap/site/sw.js | 27 - 374 files changed, 4467 insertions(+), 26155 deletions(-) delete mode 100644 vendor/twbs/bootstrap/CNAME delete mode 100644 vendor/twbs/bootstrap/Gemfile delete mode 100644 vendor/twbs/bootstrap/_config.yml mode change 100644 => 100755 vendor/twbs/bootstrap/build/change-version.js mode change 100644 => 100755 vendor/twbs/bootstrap/build/ship.sh delete mode 100644 vendor/twbs/bootstrap/js/src/index.js delete mode 100644 vendor/twbs/bootstrap/site/_data/breakpoints.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/browser-bugs.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/browser-features.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/colors.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/core-team.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/docs-versions.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/examples.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/grays.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/nav.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/theme-colors.yml delete mode 100644 vendor/twbs/bootstrap/site/_data/translations.yml delete mode 100644 vendor/twbs/bootstrap/site/_includes/ads.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/analytics.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/bugify.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/callout-danger-async-methods.md delete mode 100644 vendor/twbs/bootstrap/site/_includes/callout-info-mediaqueries-breakpoints.md delete mode 100644 vendor/twbs/bootstrap/site/_includes/callout-info-prefersreducedmotion.md delete mode 100644 vendor/twbs/bootstrap/site/_includes/callout-warning-color-assistive-technologies.md delete mode 100644 vendor/twbs/bootstrap/site/_includes/callout.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/docs-navbar.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/docs-sidebar.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/example.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/favicons.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/footer.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/header.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/bootstrap-stack.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/circle-square.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/cloud-fill.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/code.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/droplet-fill.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/github.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/menu.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/opencollective.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/placeholder.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/slack.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/icons/twitter.svg delete mode 100644 vendor/twbs/bootstrap/site/_includes/scripts.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/skippy.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/social.html delete mode 100644 vendor/twbs/bootstrap/site/_includes/stylesheet.html delete mode 100644 vendor/twbs/bootstrap/site/_layouts/default.html delete mode 100644 vendor/twbs/bootstrap/site/_layouts/docs.html delete mode 100644 vendor/twbs/bootstrap/site/_layouts/examples.html delete mode 100644 vendor/twbs/bootstrap/site/_layouts/simple.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/about/brand.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/about/license.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/about/overview.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/about/team.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/about/translations.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-outline.svg delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-punchout.svg delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social-logo.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-solid.svg delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css.map delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer@2x.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-192x192.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-512x512.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/apple-touch-icon.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/browserconfig.xml delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-16x16.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-32x32.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/manifest.json delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-144x144.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-150x150.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x150.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x310.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-70x70.png delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/safari-pinned-tab.svg delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/docs.min.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/application.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/search.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/anchor.min.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/bs-custom-file-input.min.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/clipboard.min.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/jquery.slim.min.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_ads.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_algolia.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_anchor.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_brand.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_browser-bugs.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_buttons.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_callouts.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_clipboard-js.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_colors.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_component-examples.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_content.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_footer.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_masthead.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_nav.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_placeholder-img.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_sidebar.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_skippy.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_syntax.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_variables.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/assets/scss/docs.scss delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/browser-bugs.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/alerts.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/badge.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/breadcrumb.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/button-group.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/buttons.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/card.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/carousel.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/collapse.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/dropdowns.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/forms.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/input-group.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/jumbotron.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/list-group.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/media-object.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/modal.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/navbar.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/navs.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/pagination.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/popovers.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/progress.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/scrollspy.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/spinners.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/toasts.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/components/tooltips.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/content/code.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/content/figures.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/content/images.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/content/reboot.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/content/tables.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/content/typography.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/.stylelintrc delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/album/album.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/album/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/blog/blog.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/blog/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/carousel/carousel.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/carousel/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/checkout/form-validation.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/checkout/form-validation.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/checkout/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/cover/cover.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/cover/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/dashboard/dashboard.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/dashboard/dashboard.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/dashboard/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/floating-labels/floating-labels.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/floating-labels/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/grid/grid.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/grid/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/jumbotron/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/jumbotron/jumbotron.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/navbar-bottom/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/navbar-fixed/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/navbar-fixed/navbar-top-fixed.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/navbar-static/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/navbar-static/navbar-top.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/navbars/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/navbars/navbar.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/offcanvas/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/offcanvas/offcanvas.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/offcanvas/offcanvas.js delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/pricing/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/pricing/pricing.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/product/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/product/product.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/sign-in/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/sign-in/signin.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/starter-template/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/starter-template/starter-template.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/sticky-footer-navbar/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/sticky-footer-navbar/sticky-footer-navbar.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/sticky-footer/index.html delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/examples/sticky-footer/sticky-footer.css delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/accessibility.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/best-practices.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/browsers-devices.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/build-tools.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/contents.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/download.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/introduction.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/javascript.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/theming.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/getting-started/webpack.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/layout/grid.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/layout/overview.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/layout/utilities-for-layout.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/migration.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/borders.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/clearfix.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/close-icon.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/colors.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/display.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/embed.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/flex.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/float.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/image-replacement.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/interactions.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/overflow.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/position.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/screen-readers.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/shadows.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/sizing.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/spacing.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/stretched-link.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/text.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/vertical-align.md delete mode 100644 vendor/twbs/bootstrap/site/docs/4.5/utilities/visibility.md delete mode 100644 vendor/twbs/bootstrap/site/docs/versions.html delete mode 100644 vendor/twbs/bootstrap/site/index.html delete mode 100644 vendor/twbs/bootstrap/site/robots.txt delete mode 100644 vendor/twbs/bootstrap/site/sw.js diff --git a/composer.lock b/composer.lock index e3b3e2637..8275ea0d5 100644 --- a/composer.lock +++ b/composer.lock @@ -1553,16 +1553,16 @@ }, { "name": "twbs/bootstrap", - "version": "v4.5.3", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/twbs/bootstrap.git", - "reference": "a716fb03f965dc0846df479e14388b1b4b93d7ce" + "reference": "6ffb0b48e455430f8a5359ed689ad64c1143fac2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twbs/bootstrap/zipball/a716fb03f965dc0846df479e14388b1b4b93d7ce", - "reference": "a716fb03f965dc0846df479e14388b1b4b93d7ce", + "url": "https://api.github.com/repos/twbs/bootstrap/zipball/6ffb0b48e455430f8a5359ed689ad64c1143fac2", + "reference": "6ffb0b48e455430f8a5359ed689ad64c1143fac2", "shasum": "" }, "replace": { @@ -1602,7 +1602,7 @@ ], "support": { "issues": "https://github.com/twbs/bootstrap/issues", - "source": "https://github.com/twbs/bootstrap/tree/v4.5.3" + "source": "https://github.com/twbs/bootstrap/tree/v4.6.0" }, "funding": [ { @@ -1610,7 +1610,7 @@ "type": "open_collective" } ], - "time": "2020-10-13T15:38:30+00:00" + "time": "2021-01-19T16:16:38+00:00" } ], "packages-dev": [ diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index d73fdf6f4..0e6b84d2a 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -29,7 +29,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', + 'reference' => '6fae291cc8ec69a74d0c1673186b3d8f319378d4', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -250,18 +250,18 @@ private static $installed = array ( ), 'twbs/bootstrap' => array ( - 'pretty_version' => 'v4.5.3', - 'version' => '4.5.3.0', + 'pretty_version' => 'v4.6.0', + 'version' => '4.6.0.0', 'aliases' => array ( ), - 'reference' => 'a716fb03f965dc0846df479e14388b1b4b93d7ce', + 'reference' => '6ffb0b48e455430f8a5359ed689ad64c1143fac2', ), 'twitter/bootstrap' => array ( 'replaced' => array ( - 0 => 'v4.5.3', + 0 => 'v4.6.0', ), ), 'zotlabs/hubzilla' => @@ -271,7 +271,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', + 'reference' => '6fae291cc8ec69a74d0c1673186b3d8f319378d4', ), ), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 62956251e..ce3eae708 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1585,23 +1585,23 @@ }, { "name": "twbs/bootstrap", - "version": "v4.5.3", - "version_normalized": "4.5.3.0", + "version": "v4.6.0", + "version_normalized": "4.6.0.0", "source": { "type": "git", "url": "https://github.com/twbs/bootstrap.git", - "reference": "a716fb03f965dc0846df479e14388b1b4b93d7ce" + "reference": "6ffb0b48e455430f8a5359ed689ad64c1143fac2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twbs/bootstrap/zipball/a716fb03f965dc0846df479e14388b1b4b93d7ce", - "reference": "a716fb03f965dc0846df479e14388b1b4b93d7ce", + "url": "https://api.github.com/repos/twbs/bootstrap/zipball/6ffb0b48e455430f8a5359ed689ad64c1143fac2", + "reference": "6ffb0b48e455430f8a5359ed689ad64c1143fac2", "shasum": "" }, "replace": { "twitter/bootstrap": "self.version" }, - "time": "2020-10-13T15:38:30+00:00", + "time": "2021-01-19T16:16:38+00:00", "type": "library", "extra": { "branch-alias": { @@ -1637,7 +1637,7 @@ ], "support": { "issues": "https://github.com/twbs/bootstrap/issues", - "source": "https://github.com/twbs/bootstrap/tree/v4.5.3" + "source": "https://github.com/twbs/bootstrap/tree/v4.6.0" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index aff338786..151f3da50 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', + 'reference' => '6fae291cc8ec69a74d0c1673186b3d8f319378d4', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -227,18 +227,18 @@ ), 'twbs/bootstrap' => array ( - 'pretty_version' => 'v4.5.3', - 'version' => '4.5.3.0', + 'pretty_version' => 'v4.6.0', + 'version' => '4.6.0.0', 'aliases' => array ( ), - 'reference' => 'a716fb03f965dc0846df479e14388b1b4b93d7ce', + 'reference' => '6ffb0b48e455430f8a5359ed689ad64c1143fac2', ), 'twitter/bootstrap' => array ( 'replaced' => array ( - 0 => 'v4.5.3', + 0 => 'v4.6.0', ), ), 'zotlabs/hubzilla' => @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '0cd4c3410121b9b584dc1b108e555832843b2576', + 'reference' => '6fae291cc8ec69a74d0c1673186b3d8f319378d4', ), ), ); diff --git a/vendor/twbs/bootstrap/.bundlewatch.config.json b/vendor/twbs/bootstrap/.bundlewatch.config.json index fb76d8dd8..1b4444728 100644 --- a/vendor/twbs/bootstrap/.bundlewatch.config.json +++ b/vendor/twbs/bootstrap/.bundlewatch.config.json @@ -26,7 +26,7 @@ }, { "path": "./dist/js/bootstrap.bundle.js", - "maxSize": "47.5 kB" + "maxSize": "48 kB" }, { "path": "./dist/js/bootstrap.bundle.min.js", diff --git a/vendor/twbs/bootstrap/.eslintignore b/vendor/twbs/bootstrap/.eslintignore index 10b147b83..ae6baae7e 100644 --- a/vendor/twbs/bootstrap/.eslintignore +++ b/vendor/twbs/bootstrap/.eslintignore @@ -3,5 +3,4 @@ **/vendor/ /_gh_pages/ /js/coverage/ -/site/sw.js -/package.js +/site/static/sw.js diff --git a/vendor/twbs/bootstrap/.eslintrc.json b/vendor/twbs/bootstrap/.eslintrc.json index f8e70335f..c5b351816 100644 --- a/vendor/twbs/bootstrap/.eslintrc.json +++ b/vendor/twbs/bootstrap/.eslintrc.json @@ -21,7 +21,12 @@ "warn", 5 ], - "new-cap": "off", + "new-cap": [ + "error", + { + "properties": false + } + ], "no-console": "error", "no-mixed-operators": "off", "no-negated-condition": "off", @@ -37,16 +42,17 @@ "unicorn/consistent-function-scoping": "off", "unicorn/explicit-length-check": "off", "unicorn/import-index": "off", - "unicorn/no-fn-reference-in-iterator": "off", + "unicorn/no-array-callback-reference": "off", "unicorn/no-for-loop": "off", "unicorn/no-null": "off", "unicorn/no-unused-properties": "error", "unicorn/no-useless-undefined": "off", "unicorn/prefer-array-find": "off", - "unicorn/prefer-dataset": "off", + "unicorn/prefer-dom-node-dataset": "off", "unicorn/prefer-includes": "off", - "unicorn/prefer-node-append": "off", - "unicorn/prefer-node-remove": "off", + "unicorn/prefer-math-trunc": "off", + "unicorn/prefer-dom-node-append": "off", + "unicorn/prefer-dom-node-remove": "off", "unicorn/prefer-number-properties": "off", "unicorn/prefer-optional-catch-binding": "off", "unicorn/prefer-query-selector": "off", diff --git a/vendor/twbs/bootstrap/.github/CONTRIBUTING.md b/vendor/twbs/bootstrap/.github/CONTRIBUTING.md index 0704e3b2f..296b13741 100644 --- a/vendor/twbs/bootstrap/.github/CONTRIBUTING.md +++ b/vendor/twbs/bootstrap/.github/CONTRIBUTING.md @@ -102,12 +102,12 @@ Example: Sometimes bugs reported to us are actually caused by bugs in the browser(s) themselves, not bugs in Bootstrap per se. When feasible, we aim to report such upstream bugs to the relevant browser vendor(s), and then list them on our [Wall of Browser Bugs](https://getbootstrap.com/browser-bugs/) and [document them in MDN](https://developer.mozilla.org/en-US/docs/Web). -| Vendor(s) | Browser(s) | Rendering engine | Bug reporting website(s) | Notes | -| ------------- | ---------------------------- | ---------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------- | -| Mozilla | Firefox | Gecko | https://bugzilla.mozilla.org/enter_bug.cgi | "Core" is normally the right product option to choose. | -| Apple | Safari | WebKit | https://bugs.webkit.org/enter_bug.cgi?product=WebKit <br> https://bugreport.apple.com/ | In Apple's bug reporter, choose "Safari" as the product. | -| Google, Opera | Chrome, Chromium, Opera v15+ | Blink | https://bugs.chromium.org/p/chromium/issues/list | Click the "New issue" button. | -| Microsoft | Edge | EdgeHTML | https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/ | | +| Vendor(s) | Browser(s) | Rendering engine | Bug reporting website(s) | Notes | +| ------------- | ---------------------------- | ---------------- | ------------------------------------------------------ | -------------------------------------------------------- | +| Mozilla | Firefox | Gecko | https://bugzilla.mozilla.org/enter_bug.cgi | "Core" is normally the right product option to choose. | +| Apple | Safari | WebKit | https://bugs.webkit.org/enter_bug.cgi?product=WebKit | In Apple's bug reporter, choose "Safari" as the product. | +| Google, Opera | Chrome, Chromium, Opera v15+ | Blink | https://bugs.chromium.org/p/chromium/issues/list | Click the "New issue" button. | +| Microsoft | Edge | Blink | https://developer.microsoft.com/en-us/microsoft-edge/ | Go to "Help > Send Feedback" from the browser | ## Feature requests @@ -124,23 +124,25 @@ Good pull requests—patches, improvements, new features—are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. -**Please ask first** before embarking on any significant pull request (e.g. +**Please ask first** before embarking on any **significant** pull request (e.g. implementing features, refactoring code, porting to a different language), otherwise you risk spending a lot of time working on something that the -project's developers might not want to merge into the project. +project's developers might not want to merge into the project. For trivial +things, or things that don't require a lot of your time, you can go ahead and +make a PR. Please adhere to the [coding guidelines](#code-guidelines) used throughout the project (indentation, accurate comments, etc.) and any other requirements (such as test coverage). -**Do not edit `bootstrap.css`, or `bootstrap.js` -directly!** Those files are automatically generated. You should edit the -source files in [`/bootstrap/scss/`](https://github.com/twbs/bootstrap/tree/v4-dev/scss) +**Do not edit `bootstrap.css` or `bootstrap.js`, and do not commit +any dist files (`dist/` or `js/dist`).** Those files are automatically generated by our build tools. You should +edit the source files in [`/bootstrap/scss/`](https://github.com/twbs/bootstrap/tree/v4-dev/scss) and/or [`/bootstrap/js/src/`](https://github.com/twbs/bootstrap/tree/v4-dev/js/src) instead. Similarly, when contributing to Bootstrap's documentation, you should edit the documentation source files in -[the `/bootstrap/site/docs/` directory of the `v4-dev` branch](https://github.com/twbs/bootstrap/tree/v4-dev/site/docs). +[the `/bootstrap/site/content/docs/` directory of the `v4-dev` branch](https://github.com/twbs/bootstrap/tree/v4-dev/site/content/docs). **Do not edit the `gh-pages` branch.** That branch is generated from the documentation source files and is managed separately by the Bootstrap Core Team. diff --git a/vendor/twbs/bootstrap/.github/workflows/browserstack.yml b/vendor/twbs/bootstrap/.github/workflows/browserstack.yml index f709b98da..a12bffcf7 100644 --- a/vendor/twbs/bootstrap/.github/workflows/browserstack.yml +++ b/vendor/twbs/bootstrap/.github/workflows/browserstack.yml @@ -1,20 +1,24 @@ name: BrowserStack -on: [push] + +on: + push: + env: - CI: true - NODE: 12.x + FORCE_COLOR: 2 + NODE: 14 jobs: browserstack: runs-on: ubuntu-latest - if: github.repository == 'twbs/bootstrap' + if: github.repository == 'twbs/bootstrap' && (!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')) + timeout-minutes: 30 steps: - name: Clone repository uses: actions/checkout@v2 - - name: Set Node.js version - uses: actions/setup-node@v1 + - name: Set up Node.js + uses: actions/setup-node@v2 with: node-version: "${{ env.NODE }}" @@ -24,8 +28,8 @@ jobs: path: ~/.npm key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} restore-keys: | - ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} - ${{ runner.OS }}-node-v${{ env.NODE }}- + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- - name: Install npm dependencies run: npm ci diff --git a/vendor/twbs/bootstrap/.github/workflows/bundlewatch.yml b/vendor/twbs/bootstrap/.github/workflows/bundlewatch.yml index 1e68223ba..16736b5cc 100644 --- a/vendor/twbs/bootstrap/.github/workflows/bundlewatch.yml +++ b/vendor/twbs/bootstrap/.github/workflows/bundlewatch.yml @@ -1,8 +1,14 @@ name: Bundlewatch -on: [push, pull_request] + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + env: - CI: true - NODE: 12.x + FORCE_COLOR: 2 + NODE: 14 jobs: bundlewatch: @@ -12,8 +18,8 @@ jobs: - name: Clone repository uses: actions/checkout@v2 - - name: Set Node.js version - uses: actions/setup-node@v1 + - name: Set up Node.js + uses: actions/setup-node@v2 with: node-version: "${{ env.NODE }}" @@ -23,8 +29,8 @@ jobs: path: ~/.npm key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} restore-keys: | - ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} - ${{ runner.OS }}-node-v${{ env.NODE }}- + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- - name: Install npm dependencies run: npm ci diff --git a/vendor/twbs/bootstrap/.github/workflows/codeql.yml b/vendor/twbs/bootstrap/.github/workflows/codeql.yml index 777d812d6..469a5a4fc 100644 --- a/vendor/twbs/bootstrap/.github/workflows/codeql.yml +++ b/vendor/twbs/bootstrap/.github/workflows/codeql.yml @@ -1,22 +1,33 @@ -name: "Code Scanning - Action" +name: "CodeQL" on: push: + branches: + - main + - v4-dev + - "!dependabot/**" + pull_request: + # The branches below must be a subset of the branches above + branches: + - main + - v4-dev schedule: - - cron: "0 0 * * 0" + - cron: "0 2 * * 5" jobs: - CodeQL-Build: + analyze: + name: Analyze runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 + # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 with: - languages: javascript + languages: "javascript" - name: Autobuild uses: github/codeql-action/autobuild@v1 diff --git a/vendor/twbs/bootstrap/.github/workflows/css.yml b/vendor/twbs/bootstrap/.github/workflows/css.yml index 390bffc96..a28059d79 100644 --- a/vendor/twbs/bootstrap/.github/workflows/css.yml +++ b/vendor/twbs/bootstrap/.github/workflows/css.yml @@ -1,8 +1,14 @@ name: CSS -on: [push, pull_request] + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + env: - CI: true - NODE: 12.x + FORCE_COLOR: 2 + NODE: 14 jobs: css: @@ -12,8 +18,8 @@ jobs: - name: Clone repository uses: actions/checkout@v2 - - name: Set Node.js version - uses: actions/setup-node@v1 + - name: Set up Node.js + uses: actions/setup-node@v2 with: node-version: "${{ env.NODE }}" @@ -23,8 +29,8 @@ jobs: path: ~/.npm key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} restore-keys: | - ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} - ${{ runner.OS }}-node-v${{ env.NODE }}- + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- - name: Install npm dependencies run: npm ci diff --git a/vendor/twbs/bootstrap/.github/workflows/dart-sass.yml b/vendor/twbs/bootstrap/.github/workflows/dart-sass.yml index 8482a152e..2b867d6bd 100644 --- a/vendor/twbs/bootstrap/.github/workflows/dart-sass.yml +++ b/vendor/twbs/bootstrap/.github/workflows/dart-sass.yml @@ -1,8 +1,14 @@ name: CSS (Dart Sass) -on: [push, pull_request] + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + env: - CI: true - NODE: 12.x + FORCE_COLOR: 2 + NODE: 14 jobs: css: @@ -12,8 +18,8 @@ jobs: - name: Clone repository uses: actions/checkout@v2 - - name: Set Node.js version - uses: actions/setup-node@v1 + - name: Set up Node.js + uses: actions/setup-node@v2 with: node-version: "${{ env.NODE }}" diff --git a/vendor/twbs/bootstrap/.github/workflows/docs.yml b/vendor/twbs/bootstrap/.github/workflows/docs.yml index ba16a9ad8..150e4d16c 100644 --- a/vendor/twbs/bootstrap/.github/workflows/docs.yml +++ b/vendor/twbs/bootstrap/.github/workflows/docs.yml @@ -1,9 +1,14 @@ name: Docs -on: [push, pull_request] + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + env: - CI: true - NODE: 12.x - RUBY: 2.7.x + FORCE_COLOR: 2 + NODE: 14 jobs: docs: @@ -13,30 +18,12 @@ jobs: - name: Clone repository uses: actions/checkout@v2 - - name: Set Node.js version - uses: actions/setup-node@v1 + - name: Set up Node.js + uses: actions/setup-node@v2 with: node-version: "${{ env.NODE }}" - - name: Set up Ruby - uses: actions/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY }} - - - name: Set up Ruby env - run: | - echo "gem: --no-document" > ~/.gemrc # Disable gem docs - bundle config set clean 'true' - bundle config set deployment 'true' - - - name: Set up Ruby cache - uses: actions/cache@v2 - with: - path: vendor/bundle - key: ${{ runner.os }}-ruby-v${{ env.RUBY }}-${{ hashFiles('Gemfile') }}-${{ hashFiles('Gemfile.lock') }} - restore-keys: | - ${{ runner.os }}-ruby-v${{ env.RUBY }}-${{ hashFiles('Gemfile') }}-${{ hashFiles('Gemfile.lock') }} - ${{ runner.os }}-ruby-v${{ env.RUBY }}- + - run: java -version - name: Set up npm cache uses: actions/cache@v2 @@ -44,22 +31,11 @@ jobs: path: ~/.npm key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} restore-keys: | - ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} - ${{ runner.OS }}-node-v${{ env.NODE }}- - - - run: ruby --version - - run: gem --version - - run: bundle --version - - run: java -version + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- - name: Install npm dependencies run: npm ci - - name: Install bundler dependencies - run: bundle install --deployment --jobs=4 --retry=3 --clean - - - name: Copy CSS and JS - run: npm run css-copy && npm run js-copy - - name: Test docs run: npm run docs diff --git a/vendor/twbs/bootstrap/.github/workflows/js.yml b/vendor/twbs/bootstrap/.github/workflows/js.yml index 543172ccb..c56a2dfdd 100644 --- a/vendor/twbs/bootstrap/.github/workflows/js.yml +++ b/vendor/twbs/bootstrap/.github/workflows/js.yml @@ -1,7 +1,13 @@ name: JS Tests -on: [push, pull_request] + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + env: - CI: true + FORCE_COLOR: 2 jobs: run: @@ -11,14 +17,14 @@ jobs: strategy: fail-fast: false matrix: - node: [10, 12] + node: [10, 12, 14] steps: - name: Clone repository uses: actions/checkout@v2 - - name: Set Node.js version - uses: actions/setup-node@v1 + - name: Set up Node.js + uses: actions/setup-node@v2 with: node-version: ${{ matrix.node }} @@ -28,8 +34,8 @@ jobs: path: ~/.npm key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}} restore-keys: | - ${{ runner.OS }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} - ${{ runner.OS }}-node-v${{ matrix.node }}- + ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ matrix.node }}- - name: Install npm dependencies run: npm ci @@ -42,7 +48,7 @@ jobs: - name: Run Coveralls uses: coverallsapp/github-action@master - if: matrix.node == 12 + if: matrix.node == 14 with: github-token: "${{ secrets.GITHUB_TOKEN }}" path-to-lcov: "./js/coverage/lcov.info" diff --git a/vendor/twbs/bootstrap/.github/workflows/lint.yml b/vendor/twbs/bootstrap/.github/workflows/lint.yml index f3d00d69f..369aaced3 100644 --- a/vendor/twbs/bootstrap/.github/workflows/lint.yml +++ b/vendor/twbs/bootstrap/.github/workflows/lint.yml @@ -1,8 +1,14 @@ name: Lint -on: [push, pull_request] + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + env: - CI: true - NODE: 12.x + FORCE_COLOR: 2 + NODE: 14 jobs: lint: @@ -12,8 +18,8 @@ jobs: - name: Clone repository uses: actions/checkout@v2 - - name: Set Node.js version - uses: actions/setup-node@v1 + - name: Set up Node.js + uses: actions/setup-node@v2 with: node-version: "${{ env.NODE }}" @@ -23,8 +29,8 @@ jobs: path: ~/.npm key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} restore-keys: | - ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} - ${{ runner.OS }}-node-v${{ env.NODE }}- + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- - name: Install npm dependencies run: npm ci diff --git a/vendor/twbs/bootstrap/.gitignore b/vendor/twbs/bootstrap/.gitignore index a3437b8a5..ef7b47d4b 100644 --- a/vendor/twbs/bootstrap/.gitignore +++ b/vendor/twbs/bootstrap/.gitignore @@ -1,16 +1,8 @@ # Ignore docs files /_gh_pages/ -/site/.jekyll-cache -/site/.jekyll-metadata -/site/docs/**/dist/ # Hugo folders /resources/ -# Ignore ruby/bundler files -/.bundle/ -/vendor/ -/.ruby-version - # Numerous always-ignore extensions *.diff *.err diff --git a/vendor/twbs/bootstrap/.stylelintignore b/vendor/twbs/bootstrap/.stylelintignore index 7bc488e5f..e42e88938 100644 --- a/vendor/twbs/bootstrap/.stylelintignore +++ b/vendor/twbs/bootstrap/.stylelintignore @@ -2,3 +2,4 @@ **/dist/ **/vendor/ /_gh_pages/ +/js/coverage/ diff --git a/vendor/twbs/bootstrap/.stylelintrc b/vendor/twbs/bootstrap/.stylelintrc index 47dd3e5d9..b9bde72db 100644 --- a/vendor/twbs/bootstrap/.stylelintrc +++ b/vendor/twbs/bootstrap/.stylelintrc @@ -3,6 +3,10 @@ "stylelint-config-twbs-bootstrap/scss" ], "rules": { + "declaration-property-value-disallowed-list": { + "border": "none", + "outline": "none" + }, "function-disallowed-list": [ "calc" ], diff --git a/vendor/twbs/bootstrap/CNAME b/vendor/twbs/bootstrap/CNAME deleted file mode 100644 index 52c853392..000000000 --- a/vendor/twbs/bootstrap/CNAME +++ /dev/null @@ -1 +0,0 @@ -getbootstrap.com diff --git a/vendor/twbs/bootstrap/CODE_OF_CONDUCT.md b/vendor/twbs/bootstrap/CODE_OF_CONDUCT.md index 9d9922f25..0d2e52695 100644 --- a/vendor/twbs/bootstrap/CODE_OF_CONDUCT.md +++ b/vendor/twbs/bootstrap/CODE_OF_CONDUCT.md @@ -40,7 +40,4 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html][version] - -[homepage]: https://www.contributor-covenant.org/ -[version]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct/> diff --git a/vendor/twbs/bootstrap/Gemfile b/vendor/twbs/bootstrap/Gemfile deleted file mode 100644 index 70ac52c40..000000000 --- a/vendor/twbs/bootstrap/Gemfile +++ /dev/null @@ -1,9 +0,0 @@ -source 'https://rubygems.org' - -group :development, :test do - gem 'jekyll', '~> 4.1.1' - gem 'jekyll-redirect-from', '~> 0.16.0' - gem 'jekyll-sitemap', '~> 1.4.0' - gem 'jekyll-toc', '~> 0.14.0' - gem 'wdm', '~> 0.1.1', :install_if => Gem.win_platform? -end diff --git a/vendor/twbs/bootstrap/LICENSE b/vendor/twbs/bootstrap/LICENSE index 173a9ebbb..72dda234e 100644 --- a/vendor/twbs/bootstrap/LICENSE +++ b/vendor/twbs/bootstrap/LICENSE @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2011-2020 Twitter, Inc. -Copyright (c) 2011-2020 The Bootstrap Authors +Copyright (c) 2011-2021 Twitter, Inc. +Copyright (c) 2011-2021 The Bootstrap Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/twbs/bootstrap/README.md b/vendor/twbs/bootstrap/README.md index 35ce9feaa..6a29ebcd7 100644 --- a/vendor/twbs/bootstrap/README.md +++ b/vendor/twbs/bootstrap/README.md @@ -1,6 +1,6 @@ <p align="center"> <a href="https://getbootstrap.com/"> - <img src="https://getbootstrap.com/docs/4.5/assets/brand/bootstrap-solid.svg" alt="Bootstrap logo" width="72" height="72"> + <img src="https://getbootstrap.com/docs/4.6/assets/brand/bootstrap-solid.svg" alt="Bootstrap logo" width="72" height="72"> </a> </p> @@ -9,7 +9,7 @@ <p align="center"> Sleek, intuitive, and powerful front-end framework for faster and easier web development. <br> - <a href="https://getbootstrap.com/docs/4.5/"><strong>Explore Bootstrap docs »</strong></a> + <a href="https://getbootstrap.com/docs/4.6/"><strong>Explore Bootstrap docs »</strong></a> <br> <br> <a href="https://github.com/twbs/bootstrap/issues/new?template=bug_report.md">Report bug</a> @@ -41,14 +41,14 @@ Several quick start options are available: -- [Download the latest release.](https://github.com/twbs/bootstrap/archive/v4.5.3.zip) +- [Download the latest release.](https://github.com/twbs/bootstrap/archive/v4.6.0.zip) - Clone the repo: `git clone https://github.com/twbs/bootstrap.git` - Install with [npm](https://www.npmjs.com/): `npm install bootstrap` -- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@4.5.3` -- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:4.5.3` +- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@4.6.0` +- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:4.6.0` - Install with [NuGet](https://www.nuget.org/): CSS: `Install-Package bootstrap` Sass: `Install-Package bootstrap.sass` -Read the [Getting started page](https://getbootstrap.com/docs/4.5/getting-started/introduction/) for information on the framework contents, templates and examples, and more. +Read the [Getting started page](https://getbootstrap.com/docs/4.6/getting-started/introduction/) for information on the framework contents, templates and examples, and more. ## Status @@ -111,18 +111,18 @@ Have a bug or a feature request? Please first read the [issue guidelines](https: ## Documentation -Bootstrap's documentation, included in this repo in the root directory, is built with [Jekyll](https://jekyllrb.com/) and publicly hosted on GitHub Pages at <https://getbootstrap.com/>. The docs may also be run locally. +Bootstrap's documentation, included in this repo in the root directory, is built with [Hugo](https://gohugo.io/) and publicly hosted on GitHub Pages at <https://getbootstrap.com/>. The docs may also be run locally. -Documentation search is powered by [Algolia's DocSearch](https://community.algolia.com/docsearch/). Working on our search? Be sure to set `debug: true` in `site/docs/4.5/assets/js/src/search.js` file. +Documentation search is powered by [Algolia's DocSearch](https://community.algolia.com/docsearch/). Working on our search? Be sure to set `debug: true` in `site/assets/js/search.js`. ### Running documentation locally -1. Run through the [tooling setup](https://getbootstrap.com/docs/4.5/getting-started/build-tools/#tooling-setup) to install Jekyll (the site builder) and other Ruby dependencies with `bundle install`. -2. Run `npm install` to install Node.js dependencies. +1. Run `npm install` to install the Node.js dependencies, including Hugo (the site builder). +2. Run `npm run test` (or a specific npm script) to rebuild distributed CSS and JavaScript files, as well as our docs assets. 3. Run `npm start` to compile CSS and JavaScript files, generate our docs, and watch for changes. -4. Open `http://localhost:9001` in your browser, and voilà. +4. Open `http://localhost:9001/` in your browser, and voilà. -Learn more about using Jekyll by reading its [documentation](https://jekyllrb.com/docs/). +Learn more about using Hugo by reading its [documentation](https://gohugo.io/documentation/). ### Documentation for previous releases @@ -206,4 +206,4 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com ## Copyright and license -Code and documentation copyright 2011-2020 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/). +Code and documentation copyright 2011-2021 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/). diff --git a/vendor/twbs/bootstrap/_config.yml b/vendor/twbs/bootstrap/_config.yml deleted file mode 100644 index 58e8937c3..000000000 --- a/vendor/twbs/bootstrap/_config.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Dependencies -markdown: kramdown -highlighter: rouge - -kramdown: - auto_ids: true - -# Permalinks -permalink: pretty - -# Server -source: "site" -destination: ./_gh_pages -host: "localhost" -port: 9001 -baseurl: "" -url: "https://getbootstrap.com" -encoding: UTF-8 -exclude: - - docs/4.5/assets/scss/ - -plugins: - - jekyll-redirect-from - - jekyll-sitemap - - jekyll-toc - -redirect_from: - json: false - -# Social -title: Bootstrap -description: "The most popular HTML, CSS, and JS library in the world." -twitter: getbootstrap -authors: "Mark Otto, Jacob Thornton, and Bootstrap contributors" -social_image_path: /docs/4.5/assets/brand/bootstrap-social.png -social_logo_path: /docs/4.5/assets/brand/bootstrap-social-logo.png - -# Custom variables -current_version: 4.5.3 -current_ruby_version: 4.5.3 -docs_version: 4.5 -github_org: "https://github.com/twbs" -repo: "https://github.com/twbs/bootstrap" -slack: "https://bootstrap-slack.herokuapp.com" -opencollective: "https://opencollective.com/bootstrap" -blog: "https://blog.getbootstrap.com" -expo: "https://expo.getbootstrap.com" -themes: "https://themes.getbootstrap.com" -icons: "https://icons.getbootstrap.com" - -download: - source: "https://github.com/twbs/bootstrap/archive/v4.5.3.zip" - dist: "https://github.com/twbs/bootstrap/releases/download/v4.5.3/bootstrap-4.5.3-dist.zip" - dist_examples: "https://github.com/twbs/bootstrap/releases/download/v4.5.3/bootstrap-4.5.3-examples.zip" - -cdn: - # See https://www.srihash.org for info on how to generate the hashes - css: "https://stackpath.bootstrapcdn.com/bootstrap/4.5.3/css/bootstrap.min.css" - css_hash: "sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" - js: "https://stackpath.bootstrapcdn.com/bootstrap/4.5.3/js/bootstrap.min.js" - js_hash: "sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" - js_bundle: "https://stackpath.bootstrapcdn.com/bootstrap/4.5.3/js/bootstrap.bundle.min.js" - js_bundle_hash: "sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" - jquery: "https://code.jquery.com/jquery-3.5.1.slim.min.js" - jquery_hash: "sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" - popper: "https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" - popper_hash: "sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" - -toc: - min_level: 2 - max_level: 4 - no_toc_section_class: - - "bd-callout" - - "bd-example" diff --git a/vendor/twbs/bootstrap/build/build-plugins.js b/vendor/twbs/bootstrap/build/build-plugins.js index 521450f85..ffdf0d1e9 100644 --- a/vendor/twbs/bootstrap/build/build-plugins.js +++ b/vendor/twbs/bootstrap/build/build-plugins.js @@ -2,8 +2,8 @@ /*! * Script to build our plugins to use them separately. - * Copyright 2020 The Bootstrap Authors - * Copyright 2020 Twitter, Inc. + * Copyright 2020-2021 The Bootstrap Authors + * Copyright 2020-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -19,8 +19,8 @@ const plugins = [ babel({ // Only transpile our source code exclude: 'node_modules/**', - // Inline the required helpers in each file - babelHelpers: 'inline' + // Include the helpers in each file, at most one copy of each + babelHelpers: 'bundled' }) ] const bsPlugins = { diff --git a/vendor/twbs/bootstrap/build/change-version.js b/vendor/twbs/bootstrap/build/change-version.js old mode 100644 new mode 100755 index e2de874d7..78bc8464b --- a/vendor/twbs/bootstrap/build/change-version.js +++ b/vendor/twbs/bootstrap/build/change-version.js @@ -2,8 +2,8 @@ /*! * Script to update version number references in the project. - * Copyright 2017-2020 The Bootstrap Authors - * Copyright 2017-2020 Twitter, Inc. + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ diff --git a/vendor/twbs/bootstrap/build/generate-sri.js b/vendor/twbs/bootstrap/build/generate-sri.js index 972f8622e..f0aa7340b 100644 --- a/vendor/twbs/bootstrap/build/generate-sri.js +++ b/vendor/twbs/bootstrap/build/generate-sri.js @@ -5,8 +5,8 @@ * Remember to use the same vendor files as the CDN ones, * otherwise the hashes won't match! * - * Copyright 2017-2020 The Bootstrap Authors - * Copyright 2017-2020 Twitter, Inc. + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -21,11 +21,11 @@ const pkg = require('../package.json') sh.config.fatal = true -const configFile = path.join(__dirname, '../_config.yml') +const configFile = path.join(__dirname, '../config.yml') // Array of objects which holds the files to generate SRI hashes for. // `file` is the path from the root folder -// `configPropertyName` is the _config.yml variable's name of the file +// `configPropertyName` is the config.yml variable's name of the file const files = [ { file: 'dist/css/bootstrap.min.css', @@ -40,7 +40,7 @@ const files = [ configPropertyName: 'js_bundle_hash' }, { - file: `site/docs/${pkg.version_short}/assets/js/vendor/jquery.slim.min.js`, + file: `site/static/docs/${pkg.config.version_short}/assets/js/vendor/jquery.slim.min.js`, configPropertyName: 'jquery_hash' }, { @@ -61,6 +61,6 @@ files.forEach(file => { console.log(`${file.configPropertyName}: ${integrity}`) - sh.sed('-i', new RegExp(`(\\s${file.configPropertyName}:\\s+"|')(\\S+)("|')`), `$1${integrity}$3`, configFile) + sh.sed('-i', new RegExp(`^(\\s+${file.configPropertyName}:\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile) }) }) diff --git a/vendor/twbs/bootstrap/build/postcss.config.js b/vendor/twbs/bootstrap/build/postcss.config.js index bd307fa35..ef416258f 100644 --- a/vendor/twbs/bootstrap/build/postcss.config.js +++ b/vendor/twbs/bootstrap/build/postcss.config.js @@ -1,14 +1,18 @@ 'use strict' -module.exports = ctx => ({ - map: ctx.file.dirname.includes('examples') ? false : { - inline: false, - annotation: true, - sourcesContent: true - }, - plugins: { - autoprefixer: { - cascade: false +module.exports = ctx => { + return { + map: ctx.file.dirname.includes('examples') ? + false : + { + inline: false, + annotation: true, + sourcesContent: true + }, + plugins: { + autoprefixer: { + cascade: false + } } } -}) +} diff --git a/vendor/twbs/bootstrap/build/rollup.config.js b/vendor/twbs/bootstrap/build/rollup.config.js index 6294204cd..e2d2b125e 100644 --- a/vendor/twbs/bootstrap/build/rollup.config.js +++ b/vendor/twbs/bootstrap/build/rollup.config.js @@ -31,7 +31,7 @@ if (BUNDLE) { } module.exports = { - input: path.resolve(__dirname, '../js/src/index.js'), + input: path.resolve(__dirname, '../js/index.js'), output: { banner, file: path.resolve(__dirname, `../dist/js/${fileDest}`), diff --git a/vendor/twbs/bootstrap/build/ship.sh b/vendor/twbs/bootstrap/build/ship.sh old mode 100644 new mode 100755 diff --git a/vendor/twbs/bootstrap/build/vnu-jar.js b/vendor/twbs/bootstrap/build/vnu-jar.js index f4a4141c1..d211ce577 100644 --- a/vendor/twbs/bootstrap/build/vnu-jar.js +++ b/vendor/twbs/bootstrap/build/vnu-jar.js @@ -2,8 +2,8 @@ /*! * Script to run vnu-jar if Java is available. - * Copyright 2017-2020 The Bootstrap Authors - * Copyright 2017-2020 Twitter, Inc. + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ diff --git a/vendor/twbs/bootstrap/build/zip-examples.js b/vendor/twbs/bootstrap/build/zip-examples.js index 778d75f05..f976c3bc5 100644 --- a/vendor/twbs/bootstrap/build/zip-examples.js +++ b/vendor/twbs/bootstrap/build/zip-examples.js @@ -3,7 +3,7 @@ /*! * Script to create the built examples zip archive; * requires the `zip` command to be present! - * Copyright 2020 The Bootstrap Authors + * Copyright 2020-2021 The Bootstrap Authors * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -12,38 +12,65 @@ const path = require('path') const sh = require('shelljs') -const { - version, version_short: versionShort -} = require('../package.json') +const pkg = require('../package.json') -const folderName = `bootstrap-${version}-examples` +const versionShort = pkg.config.version_short +const distFolder = `bootstrap-${pkg.version}-examples` +const rootDocsDir = '_gh_pages' +const docsDir = `${rootDocsDir}/docs/${versionShort}/` + +// these are the files we need in the examples +const cssFiles = [ + 'bootstrap.min.css', + 'bootstrap.min.css.map' +] +const jsFiles = [ + 'bootstrap.bundle.min.js', + 'bootstrap.bundle.min.js.map' +] +const imgFiles = [ + 'bootstrap-outline.svg', + 'bootstrap-solid.svg' +] sh.config.fatal = true -if (!sh.test('-d', '_gh_pages')) { - throw new Error('The "_gh_pages" folder does not exist, did you forget building the docs?') +if (!sh.test('-d', rootDocsDir)) { + throw new Error(`The "${rootDocsDir}" folder does not exist, did you forget building the docs?`) } // switch to the root dir sh.cd(path.join(__dirname, '..')) -// remove any previously created folder with the same name -sh.rm('-rf', folderName) +// remove any previously created folder/zip with the same name +sh.rm('-rf', [distFolder, `${distFolder}.zip`]) + // create any folders so that `cp` works -sh.mkdir('-p', folderName) -sh.mkdir('-p', `${folderName}/assets/brand/`) - -sh.cp('-Rf', `_gh_pages/docs/${versionShort}/examples/*`, folderName) -sh.cp('-Rf', `_gh_pages/docs/${versionShort}/dist/`, `${folderName}/assets/`) -// also copy the two brand images we use in the examples -sh.cp('-f', [ - `_gh_pages/docs/${versionShort}/assets/brand/bootstrap-outline.svg`, - `_gh_pages/docs/${versionShort}/assets/brand/bootstrap-solid.svg` -], `${folderName}/assets/brand/`) -sh.rm(`${folderName}/index.html`) +sh.mkdir('-p', [ + distFolder, + `${distFolder}/assets/brand/`, + `${distFolder}/assets/dist/css/`, + `${distFolder}/assets/dist/js/` +]) + +sh.cp('-Rf', `${docsDir}/examples/*`, distFolder) + +cssFiles.forEach(file => { + sh.cp('-f', `${docsDir}/dist/css/${file}`, `${distFolder}/assets/dist/css/`) +}) + +jsFiles.forEach(file => { + sh.cp('-f', `${docsDir}/dist/js/${file}`, `${distFolder}/assets/dist/js/`) +}) + +imgFiles.forEach(file => { + sh.cp('-f', `${docsDir}/assets/brand/${file}`, `${distFolder}/assets/brand/`) +}) + +sh.rm(`${distFolder}/index.html`) // get all examples' HTML files -sh.find(`${folderName}/**/*.html`).forEach(file => { +sh.find(`${distFolder}/**/*.html`).forEach(file => { const fileContents = sh.cat(file) .toString() .replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../') @@ -55,9 +82,7 @@ sh.find(`${folderName}/**/*.html`).forEach(file => { }) // create the zip file -sh.exec(`zip -r9 "${folderName}.zip" "${folderName}"`, { - fatal: true -}) +sh.exec(`zip -r9 "${distFolder}.zip" "${distFolder}"`) // remove the folder we created -sh.rm('-rf', folderName) +sh.rm('-rf', distFolder) diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css index 9cfa07ac5..468530f77 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css @@ -1,7 +1,7 @@ /*! - * Bootstrap Grid v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap Grid v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ html { diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css.map b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css.map index a664f9803..34902bafe 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css.map +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../scss/bootstrap-grid.scss","bootstrap-grid.css","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/_variables.scss","../../scss/mixins/_grid-framework.scss","../../scss/utilities/_display.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_spacing.scss"],"names":[],"mappings":"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EKp0BM;IAAwB,iBADZ;IACY,QADZ;ELw0BlB;EKv0BM;IAAwB,iBADZ;IACY,QADZ;EL20BlB;EK10BM;IAAwB,kBADZ;IACY,SADZ;EL80BlB;EK70BM;IAAwB,kBADZ;IACY,SADZ;ELi1BlB;EKh1BM;IAAwB,kBADZ;IACY,SADZ;ELo1BlB;EK50BU;IHhBV,cAA4B;EF+1B5B;EK/0BU;IHhBV,sBAA8C;EFk2B9C;EKl1BU;IHhBV,uBAA8C;EFq2B9C;EKr1BU;IHhBV,gBAA8C;EFw2B9C;EKx1BU;IHhBV,uBAA8C;EF22B9C;EK31BU;IHhBV,uBAA8C;EF82B9C;EK91BU;IHhBV,gBAA8C;EFi3B9C;EKj2BU;IHhBV,uBAA8C;EFo3B9C;EKp2BU;IHhBV,uBAA8C;EFu3B9C;EKv2BU;IHhBV,gBAA8C;EF03B9C;EK12BU;IHhBV,uBAA8C;EF63B9C;EK72BU;IHhBV,uBAA8C;EFg4B9C;AACF;;AM76BM;EAAwB,wBAA0B;ANi7BxD;;AMj7BM;EAAwB,0BAA0B;ANq7BxD;;AMr7BM;EAAwB,gCAA0B;ANy7BxD;;AMz7BM;EAAwB,yBAA0B;AN67BxD;;AM77BM;EAAwB,yBAA0B;ANi8BxD;;AMj8BM;EAAwB,6BAA0B;ANq8BxD;;AMr8BM;EAAwB,8BAA0B;ANy8BxD;;AMz8BM;EAAwB,+BAA0B;EAA1B,wBAA0B;AN68BxD;;AM78BM;EAAwB,sCAA0B;EAA1B,+BAA0B;ANi9BxD;;AGh6BI;EGjDE;IAAwB,wBAA0B;ENs9BtD;EMt9BI;IAAwB,0BAA0B;ENy9BtD;EMz9BI;IAAwB,gCAA0B;EN49BtD;EM59BI;IAAwB,yBAA0B;EN+9BtD;EM/9BI;IAAwB,yBAA0B;ENk+BtD;EMl+BI;IAAwB,6BAA0B;ENq+BtD;EMr+BI;IAAwB,8BAA0B;ENw+BtD;EMx+BI;IAAwB,+BAA0B;IAA1B,wBAA0B;EN2+BtD;EM3+BI;IAAwB,sCAA0B;IAA1B,+BAA0B;EN8+BtD;AACF;;AG97BI;EGjDE;IAAwB,wBAA0B;ENo/BtD;EMp/BI;IAAwB,0BAA0B;ENu/BtD;EMv/BI;IAAwB,gCAA0B;EN0/BtD;EM1/BI;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hD;;AQpsDQ;EAAgC,yBAA4B;ARwsDpE;;AQvsDQ;;EAEE,6BAAoC;AR0sD9C;;AQxsDQ;;EAEE,+BAAwC;AR2sDlD;;AQzsDQ;;EAEE,gCAA0C;AR4sDpD;;AQ1sDQ;;EAEE,8BAAsC;AR6sDhD;;AQ5tDQ;EAAgC,uBAA4B;ARguDpE;;AQ/tDQ;;EAEE,2BAAoC;ARkuD9C;;AQhuDQ;;EAEE,6BAAwC;ARmuDlD;;AQjuDQ;;EAEE,8BAA0C;ARouDpD;;AQluDQ;;EAEE,4BAAsC;ARquDhD;;AQpvDQ;EAAgC,yBAA4B;ARwvDpE;;AQvvDQ;;EAEE,6BAAoC;AR0vD9C;;AQxvDQ;;EAEE,+BAAwC;AR2vDlD;;AQzvDQ;;EAEE,gCAA0C;AR4vDpD;;AQ1vDQ;;EAEE,8BAAsC;AR6vDhD;;AQ5wDQ;EAAgC,uBAA4B;ARgxDpE;;AQ/wDQ;;EAEE,2BAAoC;ARkxD9C;;AQhxDQ;;EAEE,6BAAwC;ARmxDlD;;AQjxDQ;;EAEE,8BAA0C;ARoxDpD;;AQlxDQ;;EAEE,4BAAsC;ARqxDhD;;AQpyDQ;EAAgC,qBAA4B;ARwyDpE;;AQvyDQ;;EAEE,yBAAoC;AR0yD9C;;AQxyDQ;;EAEE,2BAAwC;AR2yDlD;;AQzyDQ;;EAEE,4BAA0C;AR4yDpD;;AQ1yDQ;;EAEE,0BAAsC;AR6yDhD;;AQ5zDQ;EAAgC,2BAA4B;ARg0DpE;;AQ/zDQ;;EAEE,+BAAoC;ARk0D9C;;AQh0DQ;;EAEE,iCAAwC;ARm0DlD;;AQj0DQ;;EAEE,kCAA0C;ARo0DpD;;AQl0DQ;;EAEE,gCAAsC;ARq0DhD;;AQp1DQ;EAAgC,0BAA4B;ARw1DpE;;AQv1DQ;;EAEE,8BAAoC;AR01D9C;;AQx1DQ;;EAEE,gCAAwC;AR21DlD;;AQz1DQ;;EAEE,iCAA0C;AR41DpD;;AQ11DQ;;EAEE,+BAAsC;AR61DhD;;AQ52DQ;EAAgC,wBAA4B;ARg3DpE;;AQ/2DQ;;EAEE,4BAAoC;ARk3D9C;;AQh3DQ;;EAEE,8BAAwC;ARm3DlD;;AQj3DQ;;EAEE,+BAA0C;ARo3DpD;;AQl3DQ;;EAEE,6BAAsC;ARq3DhD;;AQp4DQ;EAAgC,0BAA4B;ARw4DpE;;AQv4DQ;;EAEE,8BAAoC;AR04D9C;;AQx4DQ;;EAEE,gCAAwC;AR24DlD;;AQz4DQ;;EAEE,iCAA0C;AR44DpD;;AQ14DQ;;EAEE,+BAAsC;AR64DhD;;AQ55DQ;EAAgC,wBAA4B;ARg6DpE;;AQ/5DQ;;EAEE,4BAAoC;ARk6D9C;;AQh6DQ;;EAEE,8BAAwC;ARm6DlD;;AQj6DQ;;EAEE,+BAA0C;ARo6DpD;;AQl6DQ;;EAEE,6BAAsC;ARq6DhD;;AQ75DQ;EAAwB,2BAA2B;ARi6D3D;;AQh6DQ;;EAEE,+BAA+B;ARm6DzC;;AQj6DQ;;EAEE,iCAAiC;ARo6D3C;;AQl6DQ;;EAEE,kCAAkC;ARq6D5C;;AQn6DQ;;EAEE,gCAAgC;ARs6D1C;;AQr7DQ;EAAwB,0BAA2B;ARy7D3D;;AQx7DQ;;EAEE,8BAA+B;AR27DzC;;AQz7DQ;;EAEE,gCAAiC;AR47D3C;;AQ17DQ;;EAEE,iCAAkC;AR67D5C;;AQ37DQ;;EAEE,+BAAgC;AR87D1C;;AQ78DQ;EAAwB,wBAA2B;ARi9D3D;;AQh9DQ;;EAEE,4BAA+B;ARm9DzC;;AQj9DQ;;EAEE,8BAAiC;ARo9D3C;;AQl9DQ;;EAEE,+BAAkC;ARq9D5C;;AQn9DQ;;EAEE,6BAAgC;ARs9D1C;;AQr+DQ;EAAwB,0BAA2B;ARy+D3D;;AQx+DQ;;EAEE,8BAA+B;AR2+DzC;;AQz+DQ;;EAEE,gCAAiC;AR4+D3C;;AQ1+DQ;;EAEE,iCAAkC;AR6+D5C;;AQ3+DQ;;EAEE,+BAAgC;AR8+D1C;;AQ7/DQ;EAAwB,wBAA2B;ARigE3D;;AQhgEQ;;EAEE,4BAA+B;ARmgEzC;;AQjgEQ;;EAEE,8BAAiC;ARogE3C;;AQlgEQ;;EAEE,+BAAkC;ARqgE5C;;AQngEQ;;EAEE,6BAAgC;ARsgE1C;;AQhgEI;EAAmB,uBAAuB;ARogE9C;;AQngEI;;EAEE,2BAA2B;ARsgEjC;;AQpgEI;;EAEE,6BAA6B;ARugEnC;;AQrgEI;;EAEE,8BAA8B;ARwgEpC;;AQtgEI;;EAEE,4BAA4B;ARygElC;;AGlhEI;EKlDI;IAAgC,oBAA4B;ERykElE;EQxkEM;;IAEE,wBAAoC;ER0kE5C;EQxkEM;;IAEE,0BAAwC;ER0kEhD;EQxkEM;;IAEE,2BAA0C;ER0kElD;EQxkEM;;IAEE,yBAAsC;ER0kE9C;EQzlEM;IAAgC,0BAA4B;ER4lElE;EQ3lEM;;IAEE,8BAAoC;ER6lE5C;EQ3lEM;;IAEE,gCAAwC;ER6lEhD;EQ3lEM;;IAEE,iCAA0C;ER6lElD;EQ3lEM;;IAEE,+BAAsC;ER6lE9C;EQ5mEM;IAAgC,yBAA4B;ER+mElE;EQ9mEM;;IAEE,6BAAoC;ERgnE5C;EQ9mEM;;IAEE,+BAAwC;ERgnEhD;EQ9mEM;;IAEE,gCAA0C;ERgnElD;EQ9mEM;;IAEE,8BAAsC;ERgnE9C;EQ/nEM;IAAgC,uBAA4B;ERkoElE;EQjoEM;;IAEE,2BAAoC;ERmoE5C;EQjoEM;;IAEE,6BAAwC;ERmoEhD;EQjoEM;;IAEE,8BAA0C;ERmoElD;EQjoEM;;IAEE,4BAAsC;ERmoE9C;EQlpEM;IAAgC,yBAA4B;ERqpElE;EQppEM;;IAEE,6BAAoC;ERspE5C;EQppEM;;IAEE,+BAAwC;ERspEhD;EQppEM;;IAEE,gCAA0C;ERspElD;EQppEM;;IAEE,8BAAsC;ERspE9C;EQrqEM;IAAgC,uBAA4B;ERwqElE;EQvqEM;;IAEE,2BAAoC;ERyqE5C;EQvqEM;;IAEE,6BAAwC;ERyqEhD;EQvqEM;;IAEE,8BAA0C;ERyqElD;EQvqEM;;IAEE,4BAAsC;ERyqE9C;EQxrEM;IAAgC,qBAA4B;ER2rElE;EQ1rEM;;IAEE,yBAAoC;ER4rE5C;EQ1rEM;;IAEE,2BAAwC;ER4rEhD;EQ1rEM;;IAEE,4BAA0C;ER4rElD;EQ1rEM;;IAEE,0BAAsC;ER4rE9C;EQ3sEM;IAAgC,2BAA4B;ER8sElE;EQ7sEM;;IAEE,+BAAoC;ER+sE5C;EQ7sEM;;IAEE,iCAAwC;ER+sEhD;EQ7sEM;;IAEE,kCAA0C;ER+sElD;EQ7sEM;;IAEE,gCAAsC;ER+sE9C;EQ9tEM;IAAgC,0BAA4B;ERiuElE;EQhuEM;;IAEE,8BAAoC;ERkuE5C;EQhuEM;;IAEE,gCAAwC;ERkuEhD;EQhuEM;;IAEE,iCAA0C;ERkuElD;EQhuEM;;IAEE,+BAAsC;ERkuE9C;EQjvEM;IAAgC,wBAA4B;ERovElE;EQnvEM;;IAEE,4BAAoC;ERqvE5C;EQnvEM;;IAEE,8BAAwC;ERqvEhD;EQnvEM;;IAEE,+BAA0C;ERqvElD;EQnvEM;;IAEE,6BAAsC;ERqvE9C;EQpwEM;IAAgC,0BAA4B;ERuwElE;EQtwEM;;IAEE,8BAAoC;ERwwE5C;EQtwEM;;IAEE,gCAAwC;ERwwEhD;EQtwEM;;IAEE,iCAA0C;ERwwElD;EQtwEM;;IAEE,+BAAsC;ERwwE9C;EQvxEM;IAAgC,wBAA4B;ER0xElE;EQzxEM;;IAEE,4BAAoC;ER2xE5C;EQzxEM;;IAEE,8BAAwC;ER2xEhD;EQzxEM;;IAEE,+BAA0C;ER2xElD;EQzxEM;;IAEE,6BAAsC;ER2xE9C;EQnxEM;IAAwB,2BAA2B;ERsxEzD;EQrxEM;;IAEE,+BAA+B;ERuxEvC;EQrxEM;;IAEE,iCAAiC;ERuxEzC;EQrxEM;;IAEE,kCAAkC;ERuxE1C;EQrxEM;;IAEE,gCAAgC;ERuxExC;EQtyEM;IAAwB,0BAA2B;ERyyEzD;EQxyEM;;IAEE,8BAA+B;ER0yEvC;EQxyEM;;IAEE,gCAAiC;ER0yEzC;EQxyEM;;IAEE,iCAAkC;ER0yE1C;EQxyEM;;IAEE,+BAAgC;ER0yExC;EQzzEM;IAAwB,wBAA2B;ER4zEzD;EQ3zEM;;IAEE,4BAA+B;ER6zEvC;EQ3zEM;;IAEE,8BAAiC;ER6zEzC;EQ3zEM;;IAEE,+BAAkC;ER6zE1C;EQ3zEM;;IAEE,6BAAgC;ER6zExC;EQ50EM;IAAwB,0BAA2B;ER+0EzD;EQ90EM;;IAEE,8BAA+B;ERg1EvC;EQ90EM;;IAEE,gCAAiC;ERg1EzC;EQ90EM;;IAEE,iCAAkC;ERg1E1C;EQ90EM;;IAEE,+BAAgC;ERg1ExC;EQ/1EM;IAAwB,wBAA2B;ERk2EzD;EQj2EM;;IAEE,4BAA+B;ERm2EvC;EQj2EM;;IAEE,8BAAiC;ERm2EzC;EQj2EM;;IAEE,+BAAkC;ERm2E1C;EQj2EM;;IAEE,6BAAgC;ERm2ExC;EQ71EE;IAAmB,uBAAuB;ERg2E5C;EQ/1EE;;IAEE,2BAA2B;ERi2E/B;EQ/1EE;;IAEE,6BAA6B;ERi2EjC;EQ/1EE;;IAEE,8BAA8B;ERi2ElC;EQ/1EE;;IAEE,4BAA4B;ERi2EhC;AACF;;AG32EI;EKlDI;IAAgC,oBAA4B;ERk6ElE;EQj6EM;;IAEE,wBAAoC;ERm6E5C;EQj6EM;;IAEE,0BAAwC;ERm6EhD;EQj6EM;;IAEE,2BAA0C;ERm6ElD;EQj6EM;;IAEE,yBAAsC;ERm6E9C;EQl7EM;IAAgC,0BAA4B;ERq7ElE;EQp7EM;;IAEE,8BAAoC;ERs7E5C;EQp7EM;;IAEE,gCAAwC;ERs7EhD;EQp7EM;;IAEE,iCAA0C;ERs7ElD;EQp7EM;;IAEE,+BAAsC;ERs7E9C;EQr8EM;IAAgC,yBAA4B;ERw8ElE;EQv8EM;;IAEE,6BAAoC;ERy8E5C;EQv8EM;;IAEE,+BAAwC;ERy8EhD;EQv8EM;;IAEE,gCAA0C;ERy8ElD;EQv8EM;;IAEE,8BAAsC;ERy8E9C;EQx9EM;IAAgC,uBAA4B;ER29ElE;EQ19EM;;IAEE,2BAAoC;ER49E5C;EQ19EM;;IAEE,6BAAwC;ER49EhD;EQ19EM;;IAEE,8BAA0C;ER49ElD;EQ19EM;;IAEE,4BAAsC;ER49E9C;EQ3+EM;IAAgC,yBAA4B;ER8+ElE;EQ7+EM;;IAEE,6BAAoC;ER++E5C;EQ7+EM;;IAEE,+BAAwC;ER++EhD;EQ7+EM;;IAEE,gCAA0C;ER++ElD;EQ7+EM;;IAEE,8BAAsC;ER++E9C;EQ9/EM;IAAgC,uBAA4B;ERigFlE;EQhgFM;;IAEE,2BAAoC;ERkgF5C;EQhgFM;;IAEE,6BAAwC;ERkgFhD;EQhgFM;;IAEE,8BAA0C;ERkgFlD;EQhgFM;;IAEE,4BAAsC;ERkgF9C;EQjhFM;IAAgC,qBAA4B;ERohFlE;EQnhFM;;IAEE,yBAAoC;ERqhF5C;EQnhFM;;IAEE,2BAAwC;ERqhFhD;EQnhFM;;IAEE,4BAA0C;ERqhFlD;EQnhFM;;IAEE,0BAAsC;ERqhF9C;EQpiFM;IAAgC,2BAA4B;ERuiFlE;EQtiFM;;IAEE,+BAAoC;ERwiF5C;EQtiFM;;IAEE,iCAAwC;ERwiFhD;EQtiFM;;IAEE,kCAA0C;ERwiFlD;EQtiFM;;IAEE,gCAAsC;ERwiF9C;EQvjFM;IAAgC,0BAA4B;ER0jFlE;EQzjFM;;IAEE,8BAAoC;ER2jF5C;EQzjFM;;IAEE,gCAAwC;ER2jFhD;EQzjFM;;IAEE,iCAA0C;ER2jFlD;EQzjFM;;IAEE,+BAAsC;ER2jF9C;EQ1kFM;IAAgC,wBAA4B;ER6kFlE;EQ5kFM;;IAEE,4BAAoC;ER8kF5C;EQ5kFM;;IAEE,8BAAwC;ER8kFhD;EQ5kFM;;IAEE,+BAA0C;ER8kFlD;EQ5kFM;;IAEE,6BAAsC;ER8kF9C;EQ7lFM;IAAgC,0BAA4B;ERgmFlE;EQ/lFM;;IAEE,8BAAoC;ERimF5C;EQ/lFM;;IAEE,gCAAwC;ERimFhD;EQ/lFM;;IAEE,iCAA0C;ERimFlD;EQ/lFM;;IAEE,+BAAsC;ERimF9C;EQhnFM;IAAgC,wBAA4B;ERmnFlE;EQlnFM;;IAEE,4BAAoC;ERonF5C;EQlnFM;;IAEE,8BAAwC;ERonFhD;EQlnFM;;IAEE,+BAA0C;ERonFlD;EQlnFM;;IAEE,6BAAsC;ERonF9C;EQ5mFM;IAAwB,2BAA2B;ER+mFzD;EQ9mFM;;IAEE,+BAA+B;ERgnFvC;EQ9mFM;;IAEE,iCAAiC;ERgnFzC;EQ9mFM;;IAEE,kCAAkC;ERgnF1C;EQ9mFM;;IAEE,gCAAgC;ERgnFxC;EQ/nFM;IAAwB,0BAA2B;ERkoFzD;EQjoFM;;IAEE,8BAA+B;ERmoFvC;EQjoFM;;IAEE,gCAAiC;ERmoFzC;EQjoFM;;IAEE,iCAAkC;ERmoF1C;EQjoFM;;IAEE,+BAAgC;ERmoFxC;EQlpFM;IAAwB,wBAA2B;ERqpFzD;EQppFM;;IAEE,4BAA+B;ERspFvC;EQppFM;;IAEE,8BAAiC;ERspFzC;EQppFM;;IAEE,+BAAkC;ERspF1C;EQppFM;;IAEE,6BAAgC;ERspFxC;EQrqFM;IAAwB,0BAA2B;ERwqFzD;EQvqFM;;IAEE,8BAA+B;ERyqFvC;EQvqFM;;IAEE,gCAAiC;ERyqFzC;EQvqFM;;IAEE,iCAAkC;ERyqF1C;EQvqFM;;IAEE,+BAAgC;ERyqFxC;EQxrFM;IAAwB,wBAA2B;ER2rFzD;EQ1rFM;;IAEE,4BAA+B;ER4rFvC;EQ1rFM;;IAEE,8BAAiC;ER4rFzC;EQ1rFM;;IAEE,+BAAkC;ER4rF1C;EQ1rFM;;IAEE,6BAAgC;ER4rFxC;EQtrFE;IAAmB,uBAAuB;ERyrF5C;EQxrFE;;IAEE,2BAA2B;ER0rF/B;EQxrFE;;IAEE,6BAA6B;ER0rFjC;EQxrFE;;IAEE,8BAA8B;ER0rFlC;EQxrFE;;IAEE,4BAA4B;ER0rFhC;AACF;;AGpsFI;EKlDI;IAAgC,oBAA4B;ER2vFlE;EQ1vFM;;IAEE,wBAAoC;ER4vF5C;EQ1vFM;;IAEE,0BAAwC;ER4vFhD;EQ1vFM;;IAEE,2BAA0C;ER4vFlD;EQ1vFM;;IAEE,yBAAsC;ER4vF9C;EQ3wFM;IAAgC,0BAA4B;ER8wFlE;EQ7wFM;;IAEE,8BAAoC;ER+wF5C;EQ7wFM;;IAEE,gCAAwC;ER+wFhD;EQ7wFM;;IAEE,iCAA0C;ER+wFlD;EQ7wFM;;IAEE,+BAAsC;ER+wF9C;EQ9xFM;IAAgC,yBAA4B;ERiyFlE;EQhyFM;;IAEE,6BAAoC;ERkyF5C;EQhyFM;;IAEE,+BAAwC;ERkyFhD;EQhyFM;;IAEE,gCAA0C;ERkyFlD;EQhyFM;;IAEE,8BAAsC;ERkyF9C;EQjzFM;IAAgC,uBAA4B;ERozFlE;EQnzFM;;IAEE,2BAAoC;ERqzF5C;EQnzFM;;IAEE,6BAAwC;ERqzFhD;EQnzFM;;IAEE,8BAA0C;ERqzFlD;EQnzFM;;IAEE,4BAAsC;ERqzF9C;EQp0FM;IAAgC,yBAA4B;ERu0FlE;EQt0FM;;IAEE,6BAAoC;ERw0F5C;EQt0FM;;IAEE,+BAAwC;ERw0FhD;EQt0FM;;IAEE,gCAA0C;ERw0FlD;EQt0FM;;IAEE,8BAAsC;ERw0F9C;EQv1FM;IAAgC,uBAA4B;ER01FlE;EQz1FM;;IAEE,2BAAoC;ER21F5C;EQz1FM;;IAEE,6BAAwC;ER21FhD;EQz1FM;;IAEE,8BAA0C;ER21FlD;EQz1FM;;IAEE,4BAAsC;ER21F9C;EQ12FM;IAAgC,qBAA4B;ER62FlE;EQ52FM;;IAEE,yBAAoC;ER82F5C;EQ52FM;;IAEE,2BAAwC;ER82FhD;EQ52FM;;IAEE,4BAA0C;ER82FlD;EQ52FM;;IAEE,0BAAsC;ER82F9C;EQ73FM;IAAgC,2BAA4B;ERg4FlE;EQ/3FM;;IAEE,+BAAoC;ERi4F5C;EQ/3FM;;IAEE,iCAAwC;ERi4FhD;EQ/3FM;;IAEE,kCAA0C;ERi4FlD;EQ/3FM;;IAEE,gCAAsC;ERi4F9C;EQh5FM;IAAgC,0BAA4B;ERm5FlE;EQl5FM;;IAEE,8BAAoC;ERo5F5C;EQl5FM;;IAEE,gCAAwC;ERo5FhD;EQl5FM;;IAEE,iCAA0C;ERo5FlD;EQl5FM;;IAEE,+BAAsC;ERo5F9C;EQn6FM;IAAgC,wBAA4B;ERs6FlE;EQr6FM;;IAEE,4BAAoC;ERu6F5C;EQr6FM;;IAEE,8BAAwC;ERu6FhD;EQr6FM;;IAEE,+BAA0C;ERu6FlD;EQr6FM;;IAEE,6BAAsC;ERu6F9C;EQt7FM;IAAgC,0BAA4B;ERy7FlE;EQx7FM;;IAEE,8BAAoC;ER07F5C;EQx7FM;;IAEE,gCAAwC;ER07FhD;EQx7FM;;IAEE,iCAA0C;ER07FlD;EQx7FM;;IAEE,+BAAsC;ER07F9C;EQz8FM;IAAgC,wBAA4B;ER48FlE;EQ38FM;;IAEE,4BAAoC;ER68F5C;EQ38FM;;IAEE,8BAAwC;ER68FhD;EQ38FM;;IAEE,+BAA0C;ER68FlD;EQ38FM;;IAEE,6BAAsC;ER68F9C;EQr8FM;IAAwB,2BAA2B;ERw8FzD;EQv8FM;;IAEE,+BAA+B;ERy8FvC;EQv8FM;;IAEE,iCAAiC;ERy8FzC;EQv8FM;;IAEE,kCAAkC;ERy8F1C;EQv8FM;;IAEE,gCAAgC;ERy8FxC;EQx9FM;IAAwB,0BAA2B;ER29FzD;EQ19FM;;IAEE,8BAA+B;ER49FvC;EQ19FM;;IAEE,gCAAiC;ER49FzC;EQ19FM;;IAEE,iCAAkC;ER49F1C;EQ19FM;;IAEE,+BAAgC;ER49FxC;EQ3+FM;IAAwB,wBAA2B;ER8+FzD;EQ7+FM;;IAEE,4BAA+B;ER++FvC;EQ7+FM;;IAEE,8BAAiC;ER++FzC;EQ7+FM;;IAEE,+BAAkC;ER++F1C;EQ7+FM;;IAEE,6BAAgC;ER++FxC;EQ9/FM;IAAwB,0BAA2B;ERigGzD;EQhgGM;;IAEE,8BAA+B;ERkgGvC;EQhgGM;;IAEE,gCAAiC;ERkgGzC;EQhgGM;;IAEE,iCAAkC;ERkgG1C;EQhgGM;;IAEE,+BAAgC;ERkgGxC;EQjhGM;IAAwB,wBAA2B;ERohGzD;EQnhGM;;IAEE,4BAA+B;ERqhGvC;EQnhGM;;IAEE,8BAAiC;ERqhGzC;EQnhGM;;IAEE,+BAAkC;ERqhG1C;EQnhGM;;IAEE,6BAAgC;ERqhGxC;EQ/gGE;IAAmB,uBAAuB;ERkhG5C;EQjhGE;;IAEE,2BAA2B;ERmhG/B;EQjhGE;;IAEE,6BAA6B;ERmhGjC;EQjhGE;;IAEE,8BAA8B;ERmhGlC;EQjhGE;;IAEE,4BAA4B;ERmhGhC;AACF;;AG7hGI;EKlDI;IAAgC,oBAA4B;ERolGlE;EQnlGM;;IAEE,wBAAoC;ERqlG5C;EQnlGM;;IAEE,0BAAwC;ERqlGhD;EQnlGM;;IAEE,2BAA0C;ERqlGlD;EQnlGM;;IAEE,yBAAsC;ERqlG9C;EQpmGM;IAAgC,0BAA4B;ERumGlE;EQtmGM;;IAEE,8BAAoC;ERwmG5C;EQtmGM;;IAEE,gCAAwC;ERwmGhD;EQtmGM;;IAEE,iCAA0C;ERwmGlD;EQtmGM;;IAEE,+BAAsC;ERwmG9C;EQvnGM;IAAgC,yBAA4B;ER0nGlE;EQznGM;;IAEE,6BAAoC;ER2nG5C;EQznGM;;IAEE,+BAAwC;ER2nGhD;EQznGM;;IAEE,gCAA0C;ER2nGlD;EQznGM;;IAEE,8BAAsC;ER2nG9C;EQ1oGM;IAAgC,uBAA4B;ER6oGlE;EQ5oGM;;IAEE,2BAAoC;ER8oG5C;EQ5oGM;;IAEE,6BAAwC;ER8oGhD;EQ5oGM;;IAEE,8BAA0C;ER8oGlD;EQ5oGM;;IAEE,4BAAsC;ER8oG9C;EQ7pGM;IAAgC,yBAA4B;ERgqGlE;EQ/pGM;;IAEE,6BAAoC;ERiqG5C;EQ/pGM;;IAEE,+BAAwC;ERiqGhD;EQ/pGM;;IAEE,gCAA0C;ERiqGlD;EQ/pGM;;IAEE,8BAAsC;ERiqG9C;EQhrGM;IAAgC,uBAA4B;ERmrGlE;EQlrGM;;IAEE,2BAAoC;ERorG5C;EQlrGM;;IAEE,6BAAwC;ERorGhD;EQlrGM;;IAEE,8BAA0C;ERorGlD;EQlrGM;;IAEE,4BAAsC;ERorG9C;EQnsGM;IAAgC,qBAA4B;ERssGlE;EQrsGM;;IAEE,yBAAoC;ERusG5C;EQrsGM;;IAEE,2BAAwC;ERusGhD;EQrsGM;;IAEE,4BAA0C;ERusGlD;EQrsGM;;IAEE,0BAAsC;ERusG9C;EQttGM;IAAgC,2BAA4B;ERytGlE;EQxtGM;;IAEE,+BAAoC;ER0tG5C;EQxtGM;;IAEE,iCAAwC;ER0tGhD;EQxtGM;;IAEE,kCAA0C;ER0tGlD;EQxtGM;;IAEE,gCAAsC;ER0tG9C;EQzuGM;IAAgC,0BAA4B;ER4uGlE;EQ3uGM;;IAEE,8BAAoC;ER6uG5C;EQ3uGM;;IAEE,gCAAwC;ER6uGhD;EQ3uGM;;IAEE,iCAA0C;ER6uGlD;EQ3uGM;;IAEE,+BAAsC;ER6uG9C;EQ5vGM;IAAgC,wBAA4B;ER+vGlE;EQ9vGM;;IAEE,4BAAoC;ERgwG5C;EQ9vGM;;IAEE,8BAAwC;ERgwGhD;EQ9vGM;;IAEE,+BAA0C;ERgwGlD;EQ9vGM;;IAEE,6BAAsC;ERgwG9C;EQ/wGM;IAAgC,0BAA4B;ERkxGlE;EQjxGM;;IAEE,8BAAoC;ERmxG5C;EQjxGM;;IAEE,gCAAwC;ERmxGhD;EQjxGM;;IAEE,iCAA0C;ERmxGlD;EQjxGM;;IAEE,+BAAsC;ERmxG9C;EQlyGM;IAAgC,wBAA4B;ERqyGlE;EQpyGM;;IAEE,4BAAoC;ERsyG5C;EQpyGM;;IAEE,8BAAwC;ERsyGhD;EQpyGM;;IAEE,+BAA0C;ERsyGlD;EQpyGM;;IAEE,6BAAsC;ERsyG9C;EQ9xGM;IAAwB,2BAA2B;ERiyGzD;EQhyGM;;IAEE,+BAA+B;ERkyGvC;EQhyGM;;IAEE,iCAAiC;ERkyGzC;EQhyGM;;IAEE,kCAAkC;ERkyG1C;EQhyGM;;IAEE,gCAAgC;ERkyGxC;EQjzGM;IAAwB,0BAA2B;ERozGzD;EQnzGM;;IAEE,8BAA+B;ERqzGvC;EQnzGM;;IAEE,gCAAiC;ERqzGzC;EQnzGM;;IAEE,iCAAkC;ERqzG1C;EQnzGM;;IAEE,+BAAgC;ERqzGxC;EQp0GM;IAAwB,wBAA2B;ERu0GzD;EQt0GM;;IAEE,4BAA+B;ERw0GvC;EQt0GM;;IAEE,8BAAiC;ERw0GzC;EQt0GM;;IAEE,+BAAkC;ERw0G1C;EQt0GM;;IAEE,6BAAgC;ERw0GxC;EQv1GM;IAAwB,0BAA2B;ER01GzD;EQz1GM;;IAEE,8BAA+B;ER21GvC;EQz1GM;;IAEE,gCAAiC;ER21GzC;EQz1GM;;IAEE,iCAAkC;ER21G1C;EQz1GM;;IAEE,+BAAgC;ER21GxC;EQ12GM;IAAwB,wBAA2B;ER62GzD;EQ52GM;;IAEE,4BAA+B;ER82GvC;EQ52GM;;IAEE,8BAAiC;ER82GzC;EQ52GM;;IAEE,+BAAkC;ER82G1C;EQ52GM;;IAEE,6BAAgC;ER82GxC;EQx2GE;IAAmB,uBAAuB;ER22G5C;EQ12GE;;IAEE,2BAA2B;ER42G/B;EQ12GE;;IAEE,6BAA6B;ER42GjC;EQ12GE;;IAEE,8BAA8B;ER42GlC;EQ12GE;;IAEE,4BAA4B;ER42GhC;AACF","file":"bootstrap-grid.css","sourcesContent":["/*!\n * Bootstrap Grid v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@import \"functions\";\n@import \"variables\";\n\n@import \"mixins/breakpoints\";\n@import \"mixins/grid-framework\";\n@import \"mixins/grid\";\n\n@import \"grid\";\n@import \"utilities/display\";\n@import \"utilities/flex\";\n@import \"utilities/spacing\";\n","/*!\n * Bootstrap Grid v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap-grid.css.map */","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n$grid-row-columns: 6 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n$table-th-font-weight: null !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height-lg * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n$custom-control-cursor: null !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-label-color: null !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: null !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: null !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/></svg>\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'><path stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/></svg>\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: null !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'><circle r='3' fill='#{$custom-control-indicator-checked-color}'/></svg>\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>\") !default;\n$custom-select-background: escape-svg($custom-select-indicator) no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n\n$form-validation-states: () !default;\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-100 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-600 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-font-size: null !default;\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n$user-selects: all, auto, none !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../scss/bootstrap-grid.scss","bootstrap-grid.css","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/_variables.scss","../../scss/mixins/_grid-framework.scss","../../scss/utilities/_display.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_spacing.scss"],"names":[],"mappings":"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EKp0BM;IAAwB,iBADZ;IACY,QADZ;ELw0BlB;EKv0BM;IAAwB,iBADZ;IACY,QADZ;EL20BlB;EK10BM;IAAwB,kBADZ;IACY,SADZ;EL80BlB;EK70BM;IAAwB,kBADZ;IACY,SADZ;ELi1BlB;EKh1BM;IAAwB,kBADZ;IACY,SADZ;ELo1BlB;EK50BU;IHhBV,cAA4B;EF+1B5B;EK/0BU;IHhBV,sBAA8C;EFk2B9C;EKl1BU;IHhBV,uBAA8C;EFq2B9C;EKr1BU;IHhBV,gBAA8C;EFw2B9C;EKx1BU;IHhBV,uBAA8C;EF22B9C;EK31BU;IHhBV,uBAA8C;EF82B9C;EK91BU;IHhBV,gBAA8C;EFi3B9C;EKj2BU;IHhBV,uBAA8C;EFo3B9C;EKp2BU;IHhBV,uBAA8C;EFu3B9C;EKv2BU;IHhBV,gBAA8C;EF03B9C;EK12BU;IHhBV,uBAA8C;EF63B9C;EK72BU;IHhBV,uBAA8C;EFg4B9C;AACF;;AM76BM;EAAwB,wBAA0B;ANi7BxD;;AMj7BM;EAAwB,0BAA0B;ANq7BxD;;AMr7BM;EAAwB,gCAA0B;ANy7BxD;;AMz7BM;EAAwB,yBAA0B;AN67BxD;;AM77BM;EAAwB,yBAA0B;ANi8BxD;;AMj8BM;EAAwB,6BAA0B;ANq8BxD;;AMr8BM;EAAwB,8BAA0B;ANy8BxD;;AMz8BM;EAAwB,+BAA0B;EAA1B,wBAA0B;AN68BxD;;AM78BM;EAAwB,sCAA0B;EAA1B,+BAA0B;ANi9BxD;;AGh6BI;EGjDE;IAAwB,wBAA0B;ENs9BtD;EMt9BI;IAAwB,0BAA0B;ENy9BtD;EMz9BI;IAAwB,gCAA0B;EN49BtD;EM59BI;IAAwB,yBAA0B;EN+9BtD;EM/9BI;IAAwB,yBAA0B;ENk+BtD;EMl+BI;IAAwB,6BAA0B;ENq+BtD;EMr+BI;IAAwB,8BAA0B;ENw+BtD;EMx+BI;IAAwB,+BAA0B;IAA1B,wBAA0B;EN2+BtD;EM3+BI;IAAwB,sCAA0B;IAA1B,+BAA0B;EN8+BtD;AACF;;AG97BI;EGjDE;IAAwB,wBAA0B;ENo/BtD;EMp/BI;IAAwB,0BAA0B;ENu/BtD;EMv/BI;IAAwB,gCAA0B;EN0/BtD;EM1/BI;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hD;;AQpsDQ;EAAgC,yBAA4B;ARwsDpE;;AQvsDQ;;EAEE,6BAAoC;AR0sD9C;;AQxsDQ;;EAEE,+BAAwC;AR2sDlD;;AQzsDQ;;EAEE,gCAA0C;AR4sDpD;;AQ1sDQ;;EAEE,8BAAsC;AR6sDhD;;AQ5tDQ;EAAgC,uBAA4B;ARguDpE;;AQ/tDQ;;EAEE,2BAAoC;ARkuD9C;;AQhuDQ;;EAEE,6BAAwC;ARmuDlD;;AQjuDQ;;EAEE,8BAA0C;ARouDpD;;AQluDQ;;EAEE,4BAAsC;ARquDhD;;AQpvDQ;EAAgC,yBAA4B;ARwvDpE;;AQvvDQ;;EAEE,6BAAoC;AR0vD9C;;AQxvDQ;;EAEE,+BAAwC;AR2vDlD;;AQzvDQ;;EAEE,gCAA0C;AR4vDpD;;AQ1vDQ;;EAEE,8BAAsC;AR6vDhD;;AQ5wDQ;EAAgC,uBAA4B;ARgxDpE;;AQ/wDQ;;EAEE,2BAAoC;ARkxD9C;;AQhxDQ;;EAEE,6BAAwC;ARmxDlD;;AQjxDQ;;EAEE,8BAA0C;ARoxDpD;;AQlxDQ;;EAEE,4BAAsC;ARqxDhD;;AQpyDQ;EAAgC,qBAA4B;ARwyDpE;;AQvyDQ;;EAEE,yBAAoC;AR0yD9C;;AQxyDQ;;EAEE,2BAAwC;AR2yDlD;;AQzyDQ;;EAEE,4BAA0C;AR4yDpD;;AQ1yDQ;;EAEE,0BAAsC;AR6yDhD;;AQ5zDQ;EAAgC,2BAA4B;ARg0DpE;;AQ/zDQ;;EAEE,+BAAoC;ARk0D9C;;AQh0DQ;;EAEE,iCAAwC;ARm0DlD;;AQj0DQ;;EAEE,kCAA0C;ARo0DpD;;AQl0DQ;;EAEE,gCAAsC;ARq0DhD;;AQp1DQ;EAAgC,0BAA4B;ARw1DpE;;AQv1DQ;;EAEE,8BAAoC;AR01D9C;;AQx1DQ;;EAEE,gCAAwC;AR21DlD;;AQz1DQ;;EAEE,iCAA0C;AR41DpD;;AQ11DQ;;EAEE,+BAAsC;AR61DhD;;AQ52DQ;EAAgC,wBAA4B;ARg3DpE;;AQ/2DQ;;EAEE,4BAAoC;ARk3D9C;;AQh3DQ;;EAEE,8BAAwC;ARm3DlD;;AQj3DQ;;EAEE,+BAA0C;ARo3DpD;;AQl3DQ;;EAEE,6BAAsC;ARq3DhD;;AQp4DQ;EAAgC,0BAA4B;ARw4DpE;;AQv4DQ;;EAEE,8BAAoC;AR04D9C;;AQx4DQ;;EAEE,gCAAwC;AR24DlD;;AQz4DQ;;EAEE,iCAA0C;AR44DpD;;AQ14DQ;;EAEE,+BAAsC;AR64DhD;;AQ55DQ;EAAgC,wBAA4B;ARg6DpE;;AQ/5DQ;;EAEE,4BAAoC;ARk6D9C;;AQh6DQ;;EAEE,8BAAwC;ARm6DlD;;AQj6DQ;;EAEE,+BAA0C;ARo6DpD;;AQl6DQ;;EAEE,6BAAsC;ARq6DhD;;AQ75DQ;EAAwB,2BAA2B;ARi6D3D;;AQh6DQ;;EAEE,+BAA+B;ARm6DzC;;AQj6DQ;;EAEE,iCAAiC;ARo6D3C;;AQl6DQ;;EAEE,kCAAkC;ARq6D5C;;AQn6DQ;;EAEE,gCAAgC;ARs6D1C;;AQr7DQ;EAAwB,0BAA2B;ARy7D3D;;AQx7DQ;;EAEE,8BAA+B;AR27DzC;;AQz7DQ;;EAEE,gCAAiC;AR47D3C;;AQ17DQ;;EAEE,iCAAkC;AR67D5C;;AQ37DQ;;EAEE,+BAAgC;AR87D1C;;AQ78DQ;EAAwB,wBAA2B;ARi9D3D;;AQh9DQ;;EAEE,4BAA+B;ARm9DzC;;AQj9DQ;;EAEE,8BAAiC;ARo9D3C;;AQl9DQ;;EAEE,+BAAkC;ARq9D5C;;AQn9DQ;;EAEE,6BAAgC;ARs9D1C;;AQr+DQ;EAAwB,0BAA2B;ARy+D3D;;AQx+DQ;;EAEE,8BAA+B;AR2+DzC;;AQz+DQ;;EAEE,gCAAiC;AR4+D3C;;AQ1+DQ;;EAEE,iCAAkC;AR6+D5C;;AQ3+DQ;;EAEE,+BAAgC;AR8+D1C;;AQ7/DQ;EAAwB,wBAA2B;ARigE3D;;AQhgEQ;;EAEE,4BAA+B;ARmgEzC;;AQjgEQ;;EAEE,8BAAiC;ARogE3C;;AQlgEQ;;EAEE,+BAAkC;ARqgE5C;;AQngEQ;;EAEE,6BAAgC;ARsgE1C;;AQhgEI;EAAmB,uBAAuB;ARogE9C;;AQngEI;;EAEE,2BAA2B;ARsgEjC;;AQpgEI;;EAEE,6BAA6B;ARugEnC;;AQrgEI;;EAEE,8BAA8B;ARwgEpC;;AQtgEI;;EAEE,4BAA4B;ARygElC;;AGlhEI;EKlDI;IAAgC,oBAA4B;ERykElE;EQxkEM;;IAEE,wBAAoC;ER0kE5C;EQxkEM;;IAEE,0BAAwC;ER0kEhD;EQxkEM;;IAEE,2BAA0C;ER0kElD;EQxkEM;;IAEE,yBAAsC;ER0kE9C;EQzlEM;IAAgC,0BAA4B;ER4lElE;EQ3lEM;;IAEE,8BAAoC;ER6lE5C;EQ3lEM;;IAEE,gCAAwC;ER6lEhD;EQ3lEM;;IAEE,iCAA0C;ER6lElD;EQ3lEM;;IAEE,+BAAsC;ER6lE9C;EQ5mEM;IAAgC,yBAA4B;ER+mElE;EQ9mEM;;IAEE,6BAAoC;ERgnE5C;EQ9mEM;;IAEE,+BAAwC;ERgnEhD;EQ9mEM;;IAEE,gCAA0C;ERgnElD;EQ9mEM;;IAEE,8BAAsC;ERgnE9C;EQ/nEM;IAAgC,uBAA4B;ERkoElE;EQjoEM;;IAEE,2BAAoC;ERmoE5C;EQjoEM;;IAEE,6BAAwC;ERmoEhD;EQjoEM;;IAEE,8BAA0C;ERmoElD;EQjoEM;;IAEE,4BAAsC;ERmoE9C;EQlpEM;IAAgC,yBAA4B;ERqpElE;EQppEM;;IAEE,6BAAoC;ERspE5C;EQppEM;;IAEE,+BAAwC;ERspEhD;EQppEM;;IAEE,gCAA0C;ERspElD;EQppEM;;IAEE,8BAAsC;ERspE9C;EQrqEM;IAAgC,uBAA4B;ERwqElE;EQvqEM;;IAEE,2BAAoC;ERyqE5C;EQvqEM;;IAEE,6BAAwC;ERyqEhD;EQvqEM;;IAEE,8BAA0C;ERyqElD;EQvqEM;;IAEE,4BAAsC;ERyqE9C;EQxrEM;IAAgC,qBAA4B;ER2rElE;EQ1rEM;;IAEE,yBAAoC;ER4rE5C;EQ1rEM;;IAEE,2BAAwC;ER4rEhD;EQ1rEM;;IAEE,4BAA0C;ER4rElD;EQ1rEM;;IAEE,0BAAsC;ER4rE9C;EQ3sEM;IAAgC,2BAA4B;ER8sElE;EQ7sEM;;IAEE,+BAAoC;ER+sE5C;EQ7sEM;;IAEE,iCAAwC;ER+sEhD;EQ7sEM;;IAEE,kCAA0C;ER+sElD;EQ7sEM;;IAEE,gCAAsC;ER+sE9C;EQ9tEM;IAAgC,0BAA4B;ERiuElE;EQhuEM;;IAEE,8BAAoC;ERkuE5C;EQhuEM;;IAEE,gCAAwC;ERkuEhD;EQhuEM;;IAEE,iCAA0C;ERkuElD;EQhuEM;;IAEE,+BAAsC;ERkuE9C;EQjvEM;IAAgC,wBAA4B;ERovElE;EQnvEM;;IAEE,4BAAoC;ERqvE5C;EQnvEM;;IAEE,8BAAwC;ERqvEhD;EQnvEM;;IAEE,+BAA0C;ERqvElD;EQnvEM;;IAEE,6BAAsC;ERqvE9C;EQpwEM;IAAgC,0BAA4B;ERuwElE;EQtwEM;;IAEE,8BAAoC;ERwwE5C;EQtwEM;;IAEE,gCAAwC;ERwwEhD;EQtwEM;;IAEE,iCAA0C;ERwwElD;EQtwEM;;IAEE,+BAAsC;ERwwE9C;EQvxEM;IAAgC,wBAA4B;ER0xElE;EQzxEM;;IAEE,4BAAoC;ER2xE5C;EQzxEM;;IAEE,8BAAwC;ER2xEhD;EQzxEM;;IAEE,+BAA0C;ER2xElD;EQzxEM;;IAEE,6BAAsC;ER2xE9C;EQnxEM;IAAwB,2BAA2B;ERsxEzD;EQrxEM;;IAEE,+BAA+B;ERuxEvC;EQrxEM;;IAEE,iCAAiC;ERuxEzC;EQrxEM;;IAEE,kCAAkC;ERuxE1C;EQrxEM;;IAEE,gCAAgC;ERuxExC;EQtyEM;IAAwB,0BAA2B;ERyyEzD;EQxyEM;;IAEE,8BAA+B;ER0yEvC;EQxyEM;;IAEE,gCAAiC;ER0yEzC;EQxyEM;;IAEE,iCAAkC;ER0yE1C;EQxyEM;;IAEE,+BAAgC;ER0yExC;EQzzEM;IAAwB,wBAA2B;ER4zEzD;EQ3zEM;;IAEE,4BAA+B;ER6zEvC;EQ3zEM;;IAEE,8BAAiC;ER6zEzC;EQ3zEM;;IAEE,+BAAkC;ER6zE1C;EQ3zEM;;IAEE,6BAAgC;ER6zExC;EQ50EM;IAAwB,0BAA2B;ER+0EzD;EQ90EM;;IAEE,8BAA+B;ERg1EvC;EQ90EM;;IAEE,gCAAiC;ERg1EzC;EQ90EM;;IAEE,iCAAkC;ERg1E1C;EQ90EM;;IAEE,+BAAgC;ERg1ExC;EQ/1EM;IAAwB,wBAA2B;ERk2EzD;EQj2EM;;IAEE,4BAA+B;ERm2EvC;EQj2EM;;IAEE,8BAAiC;ERm2EzC;EQj2EM;;IAEE,+BAAkC;ERm2E1C;EQj2EM;;IAEE,6BAAgC;ERm2ExC;EQ71EE;IAAmB,uBAAuB;ERg2E5C;EQ/1EE;;IAEE,2BAA2B;ERi2E/B;EQ/1EE;;IAEE,6BAA6B;ERi2EjC;EQ/1EE;;IAEE,8BAA8B;ERi2ElC;EQ/1EE;;IAEE,4BAA4B;ERi2EhC;AACF;;AG32EI;EKlDI;IAAgC,oBAA4B;ERk6ElE;EQj6EM;;IAEE,wBAAoC;ERm6E5C;EQj6EM;;IAEE,0BAAwC;ERm6EhD;EQj6EM;;IAEE,2BAA0C;ERm6ElD;EQj6EM;;IAEE,yBAAsC;ERm6E9C;EQl7EM;IAAgC,0BAA4B;ERq7ElE;EQp7EM;;IAEE,8BAAoC;ERs7E5C;EQp7EM;;IAEE,gCAAwC;ERs7EhD;EQp7EM;;IAEE,iCAA0C;ERs7ElD;EQp7EM;;IAEE,+BAAsC;ERs7E9C;EQr8EM;IAAgC,yBAA4B;ERw8ElE;EQv8EM;;IAEE,6BAAoC;ERy8E5C;EQv8EM;;IAEE,+BAAwC;ERy8EhD;EQv8EM;;IAEE,gCAA0C;ERy8ElD;EQv8EM;;IAEE,8BAAsC;ERy8E9C;EQx9EM;IAAgC,uBAA4B;ER29ElE;EQ19EM;;IAEE,2BAAoC;ER49E5C;EQ19EM;;IAEE,6BAAwC;ER49EhD;EQ19EM;;IAEE,8BAA0C;ER49ElD;EQ19EM;;IAEE,4BAAsC;ER49E9C;EQ3+EM;IAAgC,yBAA4B;ER8+ElE;EQ7+EM;;IAEE,6BAAoC;ER++E5C;EQ7+EM;;IAEE,+BAAwC;ER++EhD;EQ7+EM;;IAEE,gCAA0C;ER++ElD;EQ7+EM;;IAEE,8BAAsC;ER++E9C;EQ9/EM;IAAgC,uBAA4B;ERigFlE;EQhgFM;;IAEE,2BAAoC;ERkgF5C;EQhgFM;;IAEE,6BAAwC;ERkgFhD;EQhgFM;;IAEE,8BAA0C;ERkgFlD;EQhgFM;;IAEE,4BAAsC;ERkgF9C;EQjhFM;IAAgC,qBAA4B;ERohFlE;EQnhFM;;IAEE,yBAAoC;ERqhF5C;EQnhFM;;IAEE,2BAAwC;ERqhFhD;EQnhFM;;IAEE,4BAA0C;ERqhFlD;EQnhFM;;IAEE,0BAAsC;ERqhF9C;EQpiFM;IAAgC,2BAA4B;ERuiFlE;EQtiFM;;IAEE,+BAAoC;ERwiF5C;EQtiFM;;IAEE,iCAAwC;ERwiFhD;EQtiFM;;IAEE,kCAA0C;ERwiFlD;EQtiFM;;IAEE,gCAAsC;ERwiF9C;EQvjFM;IAAgC,0BAA4B;ER0jFlE;EQzjFM;;IAEE,8BAAoC;ER2jF5C;EQzjFM;;IAEE,gCAAwC;ER2jFhD;EQzjFM;;IAEE,iCAA0C;ER2jFlD;EQzjFM;;IAEE,+BAAsC;ER2jF9C;EQ1kFM;IAAgC,wBAA4B;ER6kFlE;EQ5kFM;;IAEE,4BAAoC;ER8kF5C;EQ5kFM;;IAEE,8BAAwC;ER8kFhD;EQ5kFM;;IAEE,+BAA0C;ER8kFlD;EQ5kFM;;IAEE,6BAAsC;ER8kF9C;EQ7lFM;IAAgC,0BAA4B;ERgmFlE;EQ/lFM;;IAEE,8BAAoC;ERimF5C;EQ/lFM;;IAEE,gCAAwC;ERimFhD;EQ/lFM;;IAEE,iCAA0C;ERimFlD;EQ/lFM;;IAEE,+BAAsC;ERimF9C;EQhnFM;IAAgC,wBAA4B;ERmnFlE;EQlnFM;;IAEE,4BAAoC;ERonF5C;EQlnFM;;IAEE,8BAAwC;ERonFhD;EQlnFM;;IAEE,+BAA0C;ERonFlD;EQlnFM;;IAEE,6BAAsC;ERonF9C;EQ5mFM;IAAwB,2BAA2B;ER+mFzD;EQ9mFM;;IAEE,+BAA+B;ERgnFvC;EQ9mFM;;IAEE,iCAAiC;ERgnFzC;EQ9mFM;;IAEE,kCAAkC;ERgnF1C;EQ9mFM;;IAEE,gCAAgC;ERgnFxC;EQ/nFM;IAAwB,0BAA2B;ERkoFzD;EQjoFM;;IAEE,8BAA+B;ERmoFvC;EQjoFM;;IAEE,gCAAiC;ERmoFzC;EQjoFM;;IAEE,iCAAkC;ERmoF1C;EQjoFM;;IAEE,+BAAgC;ERmoFxC;EQlpFM;IAAwB,wBAA2B;ERqpFzD;EQppFM;;IAEE,4BAA+B;ERspFvC;EQppFM;;IAEE,8BAAiC;ERspFzC;EQppFM;;IAEE,+BAAkC;ERspF1C;EQppFM;;IAEE,6BAAgC;ERspFxC;EQrqFM;IAAwB,0BAA2B;ERwqFzD;EQvqFM;;IAEE,8BAA+B;ERyqFvC;EQvqFM;;IAEE,gCAAiC;ERyqFzC;EQvqFM;;IAEE,iCAAkC;ERyqF1C;EQvqFM;;IAEE,+BAAgC;ERyqFxC;EQxrFM;IAAwB,wBAA2B;ER2rFzD;EQ1rFM;;IAEE,4BAA+B;ER4rFvC;EQ1rFM;;IAEE,8BAAiC;ER4rFzC;EQ1rFM;;IAEE,+BAAkC;ER4rF1C;EQ1rFM;;IAEE,6BAAgC;ER4rFxC;EQtrFE;IAAmB,uBAAuB;ERyrF5C;EQxrFE;;IAEE,2BAA2B;ER0rF/B;EQxrFE;;IAEE,6BAA6B;ER0rFjC;EQxrFE;;IAEE,8BAA8B;ER0rFlC;EQxrFE;;IAEE,4BAA4B;ER0rFhC;AACF;;AGpsFI;EKlDI;IAAgC,oBAA4B;ER2vFlE;EQ1vFM;;IAEE,wBAAoC;ER4vF5C;EQ1vFM;;IAEE,0BAAwC;ER4vFhD;EQ1vFM;;IAEE,2BAA0C;ER4vFlD;EQ1vFM;;IAEE,yBAAsC;ER4vF9C;EQ3wFM;IAAgC,0BAA4B;ER8wFlE;EQ7wFM;;IAEE,8BAAoC;ER+wF5C;EQ7wFM;;IAEE,gCAAwC;ER+wFhD;EQ7wFM;;IAEE,iCAA0C;ER+wFlD;EQ7wFM;;IAEE,+BAAsC;ER+wF9C;EQ9xFM;IAAgC,yBAA4B;ERiyFlE;EQhyFM;;IAEE,6BAAoC;ERkyF5C;EQhyFM;;IAEE,+BAAwC;ERkyFhD;EQhyFM;;IAEE,gCAA0C;ERkyFlD;EQhyFM;;IAEE,8BAAsC;ERkyF9C;EQjzFM;IAAgC,uBAA4B;ERozFlE;EQnzFM;;IAEE,2BAAoC;ERqzF5C;EQnzFM;;IAEE,6BAAwC;ERqzFhD;EQnzFM;;IAEE,8BAA0C;ERqzFlD;EQnzFM;;IAEE,4BAAsC;ERqzF9C;EQp0FM;IAAgC,yBAA4B;ERu0FlE;EQt0FM;;IAEE,6BAAoC;ERw0F5C;EQt0FM;;IAEE,+BAAwC;ERw0FhD;EQt0FM;;IAEE,gCAA0C;ERw0FlD;EQt0FM;;IAEE,8BAAsC;ERw0F9C;EQv1FM;IAAgC,uBAA4B;ER01FlE;EQz1FM;;IAEE,2BAAoC;ER21F5C;EQz1FM;;IAEE,6BAAwC;ER21FhD;EQz1FM;;IAEE,8BAA0C;ER21FlD;EQz1FM;;IAEE,4BAAsC;ER21F9C;EQ12FM;IAAgC,qBAA4B;ER62FlE;EQ52FM;;IAEE,yBAAoC;ER82F5C;EQ52FM;;IAEE,2BAAwC;ER82FhD;EQ52FM;;IAEE,4BAA0C;ER82FlD;EQ52FM;;IAEE,0BAAsC;ER82F9C;EQ73FM;IAAgC,2BAA4B;ERg4FlE;EQ/3FM;;IAEE,+BAAoC;ERi4F5C;EQ/3FM;;IAEE,iCAAwC;ERi4FhD;EQ/3FM;;IAEE,kCAA0C;ERi4FlD;EQ/3FM;;IAEE,gCAAsC;ERi4F9C;EQh5FM;IAAgC,0BAA4B;ERm5FlE;EQl5FM;;IAEE,8BAAoC;ERo5F5C;EQl5FM;;IAEE,gCAAwC;ERo5FhD;EQl5FM;;IAEE,iCAA0C;ERo5FlD;EQl5FM;;IAEE,+BAAsC;ERo5F9C;EQn6FM;IAAgC,wBAA4B;ERs6FlE;EQr6FM;;IAEE,4BAAoC;ERu6F5C;EQr6FM;;IAEE,8BAAwC;ERu6FhD;EQr6FM;;IAEE,+BAA0C;ERu6FlD;EQr6FM;;IAEE,6BAAsC;ERu6F9C;EQt7FM;IAAgC,0BAA4B;ERy7FlE;EQx7FM;;IAEE,8BAAoC;ER07F5C;EQx7FM;;IAEE,gCAAwC;ER07FhD;EQx7FM;;IAEE,iCAA0C;ER07FlD;EQx7FM;;IAEE,+BAAsC;ER07F9C;EQz8FM;IAAgC,wBAA4B;ER48FlE;EQ38FM;;IAEE,4BAAoC;ER68F5C;EQ38FM;;IAEE,8BAAwC;ER68FhD;EQ38FM;;IAEE,+BAA0C;ER68FlD;EQ38FM;;IAEE,6BAAsC;ER68F9C;EQr8FM;IAAwB,2BAA2B;ERw8FzD;EQv8FM;;IAEE,+BAA+B;ERy8FvC;EQv8FM;;IAEE,iCAAiC;ERy8FzC;EQv8FM;;IAEE,kCAAkC;ERy8F1C;EQv8FM;;IAEE,gCAAgC;ERy8FxC;EQx9FM;IAAwB,0BAA2B;ER29FzD;EQ19FM;;IAEE,8BAA+B;ER49FvC;EQ19FM;;IAEE,gCAAiC;ER49FzC;EQ19FM;;IAEE,iCAAkC;ER49F1C;EQ19FM;;IAEE,+BAAgC;ER49FxC;EQ3+FM;IAAwB,wBAA2B;ER8+FzD;EQ7+FM;;IAEE,4BAA+B;ER++FvC;EQ7+FM;;IAEE,8BAAiC;ER++FzC;EQ7+FM;;IAEE,+BAAkC;ER++F1C;EQ7+FM;;IAEE,6BAAgC;ER++FxC;EQ9/FM;IAAwB,0BAA2B;ERigGzD;EQhgGM;;IAEE,8BAA+B;ERkgGvC;EQhgGM;;IAEE,gCAAiC;ERkgGzC;EQhgGM;;IAEE,iCAAkC;ERkgG1C;EQhgGM;;IAEE,+BAAgC;ERkgGxC;EQjhGM;IAAwB,wBAA2B;ERohGzD;EQnhGM;;IAEE,4BAA+B;ERqhGvC;EQnhGM;;IAEE,8BAAiC;ERqhGzC;EQnhGM;;IAEE,+BAAkC;ERqhG1C;EQnhGM;;IAEE,6BAAgC;ERqhGxC;EQ/gGE;IAAmB,uBAAuB;ERkhG5C;EQjhGE;;IAEE,2BAA2B;ERmhG/B;EQjhGE;;IAEE,6BAA6B;ERmhGjC;EQjhGE;;IAEE,8BAA8B;ERmhGlC;EQjhGE;;IAEE,4BAA4B;ERmhGhC;AACF;;AG7hGI;EKlDI;IAAgC,oBAA4B;ERolGlE;EQnlGM;;IAEE,wBAAoC;ERqlG5C;EQnlGM;;IAEE,0BAAwC;ERqlGhD;EQnlGM;;IAEE,2BAA0C;ERqlGlD;EQnlGM;;IAEE,yBAAsC;ERqlG9C;EQpmGM;IAAgC,0BAA4B;ERumGlE;EQtmGM;;IAEE,8BAAoC;ERwmG5C;EQtmGM;;IAEE,gCAAwC;ERwmGhD;EQtmGM;;IAEE,iCAA0C;ERwmGlD;EQtmGM;;IAEE,+BAAsC;ERwmG9C;EQvnGM;IAAgC,yBAA4B;ER0nGlE;EQznGM;;IAEE,6BAAoC;ER2nG5C;EQznGM;;IAEE,+BAAwC;ER2nGhD;EQznGM;;IAEE,gCAA0C;ER2nGlD;EQznGM;;IAEE,8BAAsC;ER2nG9C;EQ1oGM;IAAgC,uBAA4B;ER6oGlE;EQ5oGM;;IAEE,2BAAoC;ER8oG5C;EQ5oGM;;IAEE,6BAAwC;ER8oGhD;EQ5oGM;;IAEE,8BAA0C;ER8oGlD;EQ5oGM;;IAEE,4BAAsC;ER8oG9C;EQ7pGM;IAAgC,yBAA4B;ERgqGlE;EQ/pGM;;IAEE,6BAAoC;ERiqG5C;EQ/pGM;;IAEE,+BAAwC;ERiqGhD;EQ/pGM;;IAEE,gCAA0C;ERiqGlD;EQ/pGM;;IAEE,8BAAsC;ERiqG9C;EQhrGM;IAAgC,uBAA4B;ERmrGlE;EQlrGM;;IAEE,2BAAoC;ERorG5C;EQlrGM;;IAEE,6BAAwC;ERorGhD;EQlrGM;;IAEE,8BAA0C;ERorGlD;EQlrGM;;IAEE,4BAAsC;ERorG9C;EQnsGM;IAAgC,qBAA4B;ERssGlE;EQrsGM;;IAEE,yBAAoC;ERusG5C;EQrsGM;;IAEE,2BAAwC;ERusGhD;EQrsGM;;IAEE,4BAA0C;ERusGlD;EQrsGM;;IAEE,0BAAsC;ERusG9C;EQttGM;IAAgC,2BAA4B;ERytGlE;EQxtGM;;IAEE,+BAAoC;ER0tG5C;EQxtGM;;IAEE,iCAAwC;ER0tGhD;EQxtGM;;IAEE,kCAA0C;ER0tGlD;EQxtGM;;IAEE,gCAAsC;ER0tG9C;EQzuGM;IAAgC,0BAA4B;ER4uGlE;EQ3uGM;;IAEE,8BAAoC;ER6uG5C;EQ3uGM;;IAEE,gCAAwC;ER6uGhD;EQ3uGM;;IAEE,iCAA0C;ER6uGlD;EQ3uGM;;IAEE,+BAAsC;ER6uG9C;EQ5vGM;IAAgC,wBAA4B;ER+vGlE;EQ9vGM;;IAEE,4BAAoC;ERgwG5C;EQ9vGM;;IAEE,8BAAwC;ERgwGhD;EQ9vGM;;IAEE,+BAA0C;ERgwGlD;EQ9vGM;;IAEE,6BAAsC;ERgwG9C;EQ/wGM;IAAgC,0BAA4B;ERkxGlE;EQjxGM;;IAEE,8BAAoC;ERmxG5C;EQjxGM;;IAEE,gCAAwC;ERmxGhD;EQjxGM;;IAEE,iCAA0C;ERmxGlD;EQjxGM;;IAEE,+BAAsC;ERmxG9C;EQlyGM;IAAgC,wBAA4B;ERqyGlE;EQpyGM;;IAEE,4BAAoC;ERsyG5C;EQpyGM;;IAEE,8BAAwC;ERsyGhD;EQpyGM;;IAEE,+BAA0C;ERsyGlD;EQpyGM;;IAEE,6BAAsC;ERsyG9C;EQ9xGM;IAAwB,2BAA2B;ERiyGzD;EQhyGM;;IAEE,+BAA+B;ERkyGvC;EQhyGM;;IAEE,iCAAiC;ERkyGzC;EQhyGM;;IAEE,kCAAkC;ERkyG1C;EQhyGM;;IAEE,gCAAgC;ERkyGxC;EQjzGM;IAAwB,0BAA2B;ERozGzD;EQnzGM;;IAEE,8BAA+B;ERqzGvC;EQnzGM;;IAEE,gCAAiC;ERqzGzC;EQnzGM;;IAEE,iCAAkC;ERqzG1C;EQnzGM;;IAEE,+BAAgC;ERqzGxC;EQp0GM;IAAwB,wBAA2B;ERu0GzD;EQt0GM;;IAEE,4BAA+B;ERw0GvC;EQt0GM;;IAEE,8BAAiC;ERw0GzC;EQt0GM;;IAEE,+BAAkC;ERw0G1C;EQt0GM;;IAEE,6BAAgC;ERw0GxC;EQv1GM;IAAwB,0BAA2B;ER01GzD;EQz1GM;;IAEE,8BAA+B;ER21GvC;EQz1GM;;IAEE,gCAAiC;ER21GzC;EQz1GM;;IAEE,iCAAkC;ER21G1C;EQz1GM;;IAEE,+BAAgC;ER21GxC;EQ12GM;IAAwB,wBAA2B;ER62GzD;EQ52GM;;IAEE,4BAA+B;ER82GvC;EQ52GM;;IAEE,8BAAiC;ER82GzC;EQ52GM;;IAEE,+BAAkC;ER82G1C;EQ52GM;;IAEE,6BAAgC;ER82GxC;EQx2GE;IAAmB,uBAAuB;ER22G5C;EQ12GE;;IAEE,2BAA2B;ER42G/B;EQ12GE;;IAEE,6BAA6B;ER42GjC;EQ12GE;;IAEE,8BAA8B;ER42GlC;EQ12GE;;IAEE,4BAA4B;ER42GhC;AACF","file":"bootstrap-grid.css","sourcesContent":["/*!\n * Bootstrap Grid v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@import \"functions\";\n@import \"variables\";\n\n@import \"mixins/deprecate\";\n@import \"mixins/breakpoints\";\n@import \"mixins/grid-framework\";\n@import \"mixins/grid\";\n\n@import \"grid\";\n@import \"utilities/display\";\n@import \"utilities/flex\";\n@import \"utilities/spacing\";\n","/*!\n * Bootstrap Grid v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap-grid.css.map */","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n$grid-row-columns: 6 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n$table-th-font-weight: null !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height-lg * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n$custom-control-cursor: null !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-label-color: null !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: null !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: null !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/></svg>\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'><path stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/></svg>\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: null !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'><circle r='3' fill='#{$custom-control-indicator-checked-color}'/></svg>\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>\") !default;\n$custom-select-background: escape-svg($custom-select-indicator) right $custom-select-padding-x center / $custom-select-bg-size no-repeat !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n\n$form-validation-states: () !default;\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-nav-scroll-max-height: 75vh !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-200 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-500 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n$pagination-border-radius-sm: $border-radius-sm !default;\n$pagination-border-radius-lg: $border-radius-lg !default;\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-font-size: null !default;\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n$user-selects: all, auto, none !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css index d323f93fd..f0a3258fd 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css @@ -1,7 +1,7 @@ /*! - * Bootstrap Grid v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap Grid v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */html{box-sizing:border-box;-ms-overflow-style:scrollbar}*,::after,::before{box-sizing:inherit}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}} /*# sourceMappingURL=bootstrap-grid.min.css.map */ \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css.map b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css.map index 9c96ff302..12e4889fc 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css.map +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../scss/bootstrap-grid.scss","dist/css/bootstrap-grid.css","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/utilities/_display.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_spacing.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap Grid v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@import \"functions\";\n@import \"variables\";\n\n@import \"mixins/breakpoints\";\n@import \"mixins/grid-framework\";\n@import \"mixins/grid\";\n\n@import \"grid\";\n@import \"utilities/display\";\n@import \"utilities/flex\";\n@import \"utilities/spacing\";\n","/*!\n * Bootstrap Grid v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.flex-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n/*# sourceMappingURL=bootstrap-grid.css.map */","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../scss/bootstrap-grid.scss","dist/css/bootstrap-grid.css","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/utilities/_display.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_spacing.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap Grid v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@import \"functions\";\n@import \"variables\";\n\n@import \"mixins/deprecate\";\n@import \"mixins/breakpoints\";\n@import \"mixins/grid-framework\";\n@import \"mixins/grid\";\n\n@import \"grid\";\n@import \"utilities/display\";\n@import \"utilities/flex\";\n@import \"utilities/spacing\";\n","/*!\n * Bootstrap Grid v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nhtml {\n box-sizing: border-box;\n -ms-overflow-style: scrollbar;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.flex-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n/*# sourceMappingURL=bootstrap-grid.css.map */","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css index 4c642187d..604149678 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css @@ -1,7 +1,7 @@ /*! - * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) */ @@ -24,7 +24,7 @@ article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 1rem; font-weight: 400; line-height: 1.5; @@ -198,9 +198,8 @@ button { border-radius: 0; } -button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; +button:focus:not(:focus-visible) { + outline: 0; } input, diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css.map b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css.map index e79cab0cf..42a71d215 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css.map +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../scss/bootstrap-reboot.scss","bootstrap-reboot.css","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/vendor/_rfs.scss","../../scss/mixins/_hover.scss"],"names":[],"mappings":"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","file":"bootstrap-reboot.css","sourcesContent":["/*!\n * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"reboot\";\n","/*!\n * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n$grid-row-columns: 6 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n$table-th-font-weight: null !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height-lg * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n$custom-control-cursor: null !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-label-color: null !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: null !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: null !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/></svg>\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'><path stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/></svg>\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: null !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'><circle r='3' fill='#{$custom-control-indicator-checked-color}'/></svg>\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>\") !default;\n$custom-select-background: escape-svg($custom-select-indicator) no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n\n$form-validation-states: () !default;\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-100 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-600 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-font-size: null !default;\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n$user-selects: all, auto, none !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../scss/bootstrap-reboot.scss","bootstrap-reboot.css","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/vendor/_rfs.scss","../../scss/mixins/_hover.scss"],"names":[],"mappings":"AAAA;;;;;;ECME;ACYF;;;EAGE,sBAAsB;ADVxB;;ACaA;EACE,uBAAuB;EACvB,iBAAiB;EACjB,8BAA8B;EAC9B,6CCXa;AFCf;;ACgBA;EACE,cAAc;ADbhB;;ACuBA;EACE,SAAS;EACT,qNCqOoO;ECrJhO,eAtCY;EFxChB,gBC8O+B;ED7O/B,gBCkP+B;EDjP/B,cCnCgB;EDoChB,gBAAgB;EAChB,sBC9Ca;AF0Bf;;AAEA;EC+BE,qBAAqB;AD7BvB;;ACsCA;EACE,uBAAuB;EACvB,SAAS;EACT,iBAAiB;ADnCnB;;ACgDA;EACE,aAAa;EACb,qBCgNuC;AF7PzC;;ACoDA;EACE,aAAa;EACb,mBCoF8B;AFrIhC;;AC4DA;;EAEE,0BAA0B;EAC1B,yCAAiC;EAAjC,iCAAiC;EACjC,YAAY;EACZ,gBAAgB;EAChB,sCAA8B;EAA9B,8BAA8B;ADzDhC;;AC4DA;EACE,mBAAmB;EACnB,kBAAkB;EAClB,oBAAoB;ADzDtB;;AC4DA;;;EAGE,aAAa;EACb,mBAAmB;ADzDrB;;AC4DA;;;;EAIE,gBAAgB;ADzDlB;;AC4DA;EACE,gBCiJ+B;AF1MjC;;AC4DA;EACE,oBAAoB;EACpB,cAAc;ADzDhB;;AC4DA;EACE,gBAAgB;ADzDlB;;AC4DA;;EAEE,mBCoIkC;AF7LpC;;AC4DA;EExFI,cAAW;AHgCf;;ACiEA;;EAEE,kBAAkB;EEnGhB,cAAW;EFqGb,cAAc;EACd,wBAAwB;AD9D1B;;ACiEA;EAAM,cAAc;AD7DpB;;AC8DA;EAAM,UAAU;AD1DhB;;ACiEA;EACE,cCvJe;EDwJf,qBCX4C;EDY5C,6BAA6B;AD9D/B;;AIlHE;EHmLE,cCd8D;EDe9D,0BCd+C;AF/CnD;;ACsEA;EACE,cAAc;EACd,qBAAqB;ADnEvB;;AI5HE;EHkME,cAAc;EACd,qBAAqB;ADlEzB;;AC2EA;;;;EAIE,iGCyDgH;EC7M9G,cAAW;AH6Ef;;AC2EA;EAEE,aAAa;EAEb,mBAAmB;EAEnB,cAAc;EAGd,6BAA6B;AD7E/B;;ACqFA;EAEE,gBAAgB;ADnFlB;;AC2FA;EACE,sBAAsB;EACtB,kBAAkB;ADxFpB;;AC2FA;EAGE,gBAAgB;EAChB,sBAAsB;AD1FxB;;ACkGA;EACE,yBAAyB;AD/F3B;;ACkGA;EACE,oBC6EkC;ED5ElC,uBC4EkC;ED3ElC,cCtQgB;EDuQhB,gBAAgB;EAChB,oBAAoB;AD/FtB;;ACsGA;EAEE,mBAAmB;EACnB,gCAAgC;ADpGlC;;AC4GA;EAEE,qBAAqB;EACrB,qBC2J2C;AFrQ7C;;ACgHA;EAEE,gBAAgB;AD9GlB;;ACsHA;EACE,UAAU;ADnHZ;;ACsHA;;;;;EAKE,SAAS;EACT,oBAAoB;EE5PlB,kBAAW;EF8Pb,oBAAoB;ADnHtB;;ACsHA;;EAEE,iBAAiB;ADnHnB;;ACsHA;;EAEE,oBAAoB;ADnHtB;;AAEA;ECwHE,eAAe;ADtHjB;;AC4HA;EACE,iBAAiB;ADzHnB;;ACgIA;;;;EAIE,0BAA0B;AD7H5B;;ACkIE;;;;EAKI,eAAe;ADhIrB;;ACsIA;;;;EAIE,UAAU;EACV,kBAAkB;ADnIpB;;ACsIA;;EAEE,sBAAsB;EACtB,UAAU;ADnIZ;;ACuIA;EACE,cAAc;EAEd,gBAAgB;ADrIlB;;ACwIA;EAME,YAAY;EAEZ,UAAU;EACV,SAAS;EACT,SAAS;AD3IX;;ACgJA;EACE,cAAc;EACd,WAAW;EACX,eAAe;EACf,UAAU;EACV,oBAAoB;EEnShB,iBAtCY;EF2UhB,oBAAoB;EACpB,cAAc;EACd,mBAAmB;AD7IrB;;ACgJA;EACE,wBAAwB;AD7I1B;;AAEA;;ECiJE,YAAY;AD9Id;;AAEA;ECoJE,oBAAoB;EACpB,wBAAwB;ADlJ1B;;AAEA;ECwJE,wBAAwB;ADtJ1B;;AC8JA;EACE,aAAa;EACb,0BAA0B;AD3J5B;;ACkKA;EACE,qBAAqB;AD/JvB;;ACkKA;EACE,kBAAkB;EAClB,eAAe;AD/JjB;;ACkKA;EACE,aAAa;AD/Jf;;AAEA;ECmKE,wBAAwB;ADjK1B","file":"bootstrap-reboot.css","sourcesContent":["/*!\n * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"reboot\";\n","/*!\n * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n$grid-row-columns: 6 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n$table-th-font-weight: null !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height-lg * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n$custom-control-cursor: null !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-label-color: null !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: null !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: null !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/></svg>\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'><path stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/></svg>\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: null !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'><circle r='3' fill='#{$custom-control-indicator-checked-color}'/></svg>\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>\") !default;\n$custom-select-background: escape-svg($custom-select-indicator) right $custom-select-padding-x center / $custom-select-bg-size no-repeat !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n\n$form-validation-states: () !default;\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-nav-scroll-max-height: 75vh !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-200 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-500 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n$pagination-border-radius-sm: $border-radius-sm !default;\n$pagination-border-radius-lg: $border-radius-lg !default;\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-font-size: null !default;\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n$user-selects: all, auto, none !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css index 04512ed53..83c70bba6 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css @@ -1,8 +1,8 @@ /*! - * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) - */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} + */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} /*# sourceMappingURL=bootstrap-reboot.min.css.map */ \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css.map b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css.map index bfaee258d..72ec346d0 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css.map +++ b/vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../scss/bootstrap-reboot.scss","../../scss/_reboot.scss","dist/css/bootstrap-reboot.css","../../scss/vendor/_rfs.scss","bootstrap-reboot.css","../../scss/mixins/_hover.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"reboot\";\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n -webkit-text-decoration-skip-ink: none;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","/*!\n * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../scss/bootstrap-reboot.scss","../../scss/_reboot.scss","dist/css/bootstrap-reboot.css","../../scss/vendor/_rfs.scss","bootstrap-reboot.css","../../scss/mixins/_hover.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"reboot\";\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n -webkit-text-decoration-skip-ink: none;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","/*!\n * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap.css b/vendor/twbs/bootstrap/dist/css/bootstrap.css index a3171bef4..2282e0a06 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap.css +++ b/vendor/twbs/bootstrap/dist/css/bootstrap.css @@ -1,7 +1,7 @@ /*! - * Bootstrap v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ :root { @@ -31,7 +31,7 @@ --breakpoint-md: 768px; --breakpoint-lg: 992px; --breakpoint-xl: 1200px; - --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; } @@ -54,7 +54,7 @@ article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 1rem; font-weight: 400; line-height: 1.5; @@ -228,9 +228,8 @@ button { border-radius: 0; } -button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; +button:focus:not(:focus-visible) { + outline: 0; } input, @@ -2241,6 +2240,11 @@ textarea.form-control { border-radius: 0.25rem; } +.form-row > .col > .valid-tooltip, +.form-row > [class*="col-"] > .valid-tooltip { + left: 5px; +} + .was-validated :valid ~ .valid-feedback, .was-validated :valid ~ .valid-tooltip, .is-valid ~ .valid-feedback, @@ -2270,7 +2274,7 @@ textarea.form-control { .was-validated .custom-select:valid, .custom-select.is-valid { border-color: #28a745; padding-right: calc(0.75em + 2.3125rem); - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat, #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat; } .was-validated .custom-select:valid:focus, .custom-select.is-valid:focus { @@ -2342,6 +2346,11 @@ textarea.form-control { border-radius: 0.25rem; } +.form-row > .col > .invalid-tooltip, +.form-row > [class*="col-"] > .invalid-tooltip { + left: 5px; +} + .was-validated :invalid ~ .invalid-feedback, .was-validated :invalid ~ .invalid-tooltip, .is-invalid ~ .invalid-feedback, @@ -2371,7 +2380,7 @@ textarea.form-control { .was-validated .custom-select:invalid, .custom-select.is-invalid { border-color: #dc3545; padding-right: calc(0.75em + 2.3125rem); - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat, #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat; } .was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus { @@ -3388,7 +3397,7 @@ input[type="button"].btn-block { .dropdown-item:hover, .dropdown-item:focus { color: #16181b; text-decoration: none; - background-color: #f8f9fa; + background-color: #e9ecef; } .dropdown-item.active, .dropdown-item:active { @@ -3398,7 +3407,7 @@ input[type="button"].btn-block { } .dropdown-item.disabled, .dropdown-item:disabled { - color: #6c757d; + color: #adb5bd; pointer-events: none; background-color: transparent; } @@ -3597,12 +3606,6 @@ input[type="button"].btn-block { z-index: 4; } -.input-group > .form-control:not(:last-child), -.input-group > .custom-select:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - .input-group > .form-control:not(:first-child), .input-group > .custom-select:not(:first-child) { border-top-left-radius: 0; @@ -3617,14 +3620,23 @@ input[type="button"].btn-block { } .input-group > .custom-file:not(:last-child) .custom-file-label, -.input-group > .custom-file:not(:last-child) .custom-file-label::after { +.input-group > .custom-file:not(:first-child) .custom-file-label { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group:not(.has-validation) > .form-control:not(:last-child), +.input-group:not(.has-validation) > .custom-select:not(:last-child), +.input-group:not(.has-validation) > .custom-file:not(:last-child) .custom-file-label::after { border-top-right-radius: 0; border-bottom-right-radius: 0; } -.input-group > .custom-file:not(:first-child) .custom-file-label { - border-top-left-radius: 0; - border-bottom-left-radius: 0; +.input-group.has-validation > .form-control:nth-last-child(n + 3), +.input-group.has-validation > .custom-select:nth-last-child(n + 3), +.input-group.has-validation > .custom-file:nth-last-child(n + 3) .custom-file-label::after { + border-top-right-radius: 0; + border-bottom-right-radius: 0; } .input-group-prepend, @@ -3727,8 +3739,10 @@ input[type="button"].btn-block { .input-group > .input-group-prepend > .btn, .input-group > .input-group-prepend > .input-group-text, -.input-group > .input-group-append:not(:last-child) > .btn, -.input-group > .input-group-append:not(:last-child) > .input-group-text, +.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn, +.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text, +.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn, +.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text, .input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { border-top-right-radius: 0; @@ -3825,7 +3839,7 @@ input[type="button"].btn-block { width: 1rem; height: 1rem; content: ""; - background: no-repeat 50% / 50% 50%; + background: 50% / 50% 50% no-repeat; } .custom-checkbox .custom-control-label::before { @@ -3914,7 +3928,7 @@ input[type="button"].btn-block { line-height: 1.5; color: #495057; vertical-align: middle; - background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px; + background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat; border: 1px solid #ced4da; border-radius: 0.25rem; -webkit-appearance: none; @@ -3983,6 +3997,7 @@ input[type="button"].btn-block { width: 100%; height: calc(1.5em + 0.75rem + 2px); margin: 0; + overflow: hidden; opacity: 0; } @@ -4012,6 +4027,7 @@ input[type="button"].btn-block { z-index: 1; height: calc(1.5em + 0.75rem + 2px); padding: 0.375rem 0.75rem; + overflow: hidden; font-weight: 400; line-height: 1.5; color: #495057; @@ -4048,7 +4064,7 @@ input[type="button"].btn-block { } .custom-range:focus { - outline: none; + outline: 0; } .custom-range:focus::-webkit-slider-thumb { @@ -4243,11 +4259,8 @@ input[type="button"].btn-block { border-bottom: 1px solid #dee2e6; } -.nav-tabs .nav-item { - margin-bottom: -1px; -} - .nav-tabs .nav-link { + margin-bottom: -1px; border: 1px solid transparent; border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; @@ -4403,8 +4416,12 @@ input[type="button"].btn-block { height: 1.5em; vertical-align: middle; content: ""; - background: no-repeat center center; - background-size: 100% 100%; + background: 50% / 100% 100% no-repeat; +} + +.navbar-nav-scroll { + max-height: 75vh; + overflow-y: auto; } @media (max-width: 575.98px) { @@ -4438,6 +4455,9 @@ input[type="button"].btn-block { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible; + } .navbar-expand-sm .navbar-collapse { display: -ms-flexbox !important; display: flex !important; @@ -4480,6 +4500,9 @@ input[type="button"].btn-block { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .navbar-expand-md .navbar-nav-scroll { + overflow: visible; + } .navbar-expand-md .navbar-collapse { display: -ms-flexbox !important; display: flex !important; @@ -4522,6 +4545,9 @@ input[type="button"].btn-block { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible; + } .navbar-expand-lg .navbar-collapse { display: -ms-flexbox !important; display: flex !important; @@ -4564,6 +4590,9 @@ input[type="button"].btn-block { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible; + } .navbar-expand-xl .navbar-collapse { display: -ms-flexbox !important; display: flex !important; @@ -4608,6 +4637,10 @@ input[type="button"].btn-block { flex-wrap: nowrap; } +.navbar-expand .navbar-nav-scroll { + overflow: visible; +} + .navbar-expand .navbar-collapse { display: -ms-flexbox !important; display: flex !important; @@ -4972,17 +5005,12 @@ input[type="button"].btn-block { border-radius: 0.25rem; } -.breadcrumb-item { - display: -ms-flexbox; - display: flex; -} - .breadcrumb-item + .breadcrumb-item { padding-left: 0.5rem; } .breadcrumb-item + .breadcrumb-item::before { - display: inline-block; + float: left; padding-right: 0.5rem; color: #6c757d; content: "/"; @@ -5465,8 +5493,8 @@ a.badge-dark:focus, a.badge-dark.focus { } .progress-bar-animated { - -webkit-animation: progress-bar-stripes 1s linear infinite; - animation: progress-bar-stripes 1s linear infinite; + -webkit-animation: 1s linear infinite progress-bar-stripes; + animation: 1s linear infinite progress-bar-stripes; } @media (prefers-reduced-motion: reduce) { @@ -6145,7 +6173,7 @@ a.close.disabled { z-index: 1070; display: block; margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-style: normal; font-weight: 400; line-height: 1.5; @@ -6258,7 +6286,7 @@ a.close.disabled { z-index: 1060; display: block; max-width: 276px; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-style: normal; font-weight: 400; line-height: 1.5; @@ -6546,7 +6574,7 @@ a.close.disabled { display: inline-block; width: 20px; height: 20px; - background: no-repeat 50% / 100% 100%; + background: 50% / 100% 100% no-repeat; } .carousel-control-prev-icon { @@ -6635,8 +6663,8 @@ a.close.disabled { border: 0.25em solid currentColor; border-right-color: transparent; border-radius: 50%; - -webkit-animation: spinner-border .75s linear infinite; - animation: spinner-border .75s linear infinite; + -webkit-animation: .75s linear infinite spinner-border; + animation: .75s linear infinite spinner-border; } .spinner-border-sm { @@ -6677,8 +6705,8 @@ a.close.disabled { background-color: currentColor; border-radius: 50%; opacity: 0; - -webkit-animation: spinner-grow .75s linear infinite; - animation: spinner-grow .75s linear infinite; + -webkit-animation: .75s linear infinite spinner-grow; + animation: .75s linear infinite spinner-grow; } .spinner-grow-sm { @@ -6686,6 +6714,14 @@ a.close.disabled { height: 1rem; } +@media (prefers-reduced-motion: reduce) { + .spinner-border, + .spinner-grow { + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s; + } +} + .align-baseline { vertical-align: baseline !important; } @@ -7954,7 +7990,6 @@ button.bg-dark:focus { .user-select-all { -webkit-user-select: all !important; -moz-user-select: all !important; - -ms-user-select: all !important; user-select: all !important; } diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap.css.map b/vendor/twbs/bootstrap/dist/css/bootstrap.css.map index 549dbb45e..e6e765662 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap.css.map +++ b/vendor/twbs/bootstrap/dist/css/bootstrap.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../scss/bootstrap.scss","bootstrap.css","../../scss/_root.scss","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/vendor/_rfs.scss","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_functions.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/utilities/_interactions.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_stretched-link.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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FnH1B;;AAEA;EEyHE,wBAAwB;AFvH1B;;AE+HA;EACE,aAAa;EACb,0BAA0B;AF5H5B;;AEmIA;EACE,qBAAqB;AFhIvB;;AEmIA;EACE,kBAAkB;EAClB,eAAe;AFhIjB;;AEmIA;EACE,aAAa;AFhIf;;AAEA;EEoIE,wBAAwB;AFlI1B;;AM1VA;;EAEE,qBHqSuC;EGnSvC,gBHqS+B;EGpS/B,gBHqS+B;AHuDjC;;AMxVA;EFgHM,iBAtCY;AJkRlB;;AM3VA;EF+GM,eAtCY;AJsRlB;;AM9VA;EF8GM,kBAtCY;AJ0RlB;;AMjWA;EF6GM,iBAtCY;AJ8RlB;;AMpWA;EF4GM,kBAtCY;AJkSlB;;AMvWA;EF2GM,eAtCY;AJsSlB;;AMzWA;EFyGM,kBAtCY;EEjEhB,gBHuS+B;AHqEjC;;AMxWA;EFmGM,eAtCY;EE3DhB,gBH0R+B;EGzR/B,gBHiR+B;AH0FjC;;AMzWA;EF8FM,iBAtCY;EEtDhB,gBHsR+B;EGrR/B,gBH4Q+B;AHgGjC;;AM1WA;EFyFM,iBAtCY;EEjDhB,gBHkR+B;EGjR/B,gBHuQ+B;AHsGjC;;AM3WA;EFoFM,iBAtCY;EE5ChB,gBH8Q+B;EG7Q/B,gBHkQ+B;AH4GjC;;AEjVA;EIpBE,gBHgFW;EG/EX,mBH+EW;EG9EX,SAAS;EACT,wCHzCa;AHkZf;;AMjWA;;EFMI,cAAW;EEHb,gBH0N+B;AH0IjC;;AMjWA;;EAEE,cHkQgC;EGjQhC,yBH0QmC;AH0FrC;;AM5VA;EC/EE,eAAe;EACf,gBAAgB;AP+alB;;AM5VA;ECpFE,eAAe;EACf,gBAAgB;APoblB;;AM9VA;EACE,qBAAqB;ANiWvB;;AMlWA;EAII,oBHoP+B;AH8GnC;;AMxVA;EFjCI,cAAW;EEmCb,yBAAyB;AN2V3B;;AMvVA;EACE,mBHuBW;ECRP,kBAtCY;AJkXlB;;AMvVA;EACE,cAAc;EF7CZ,cAAW;EE+Cb,cH1GgB;AHoclB;;AM7VA;EAMI,qBAAqB;AN2VzB;;AQ9cA;ECIE,eAAe;EAGf,YAAY;AT4cd;;AQ7cA;EACE,gBL+/BwC;EK9/BxC,sBLRa;EKSb,yBLNgB;EOQd,sBP6NgC;EMpOlC,eAAe;EAGf,YAAY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EahIX,cbSgB;AHy7ClB;;AgBr8CA;;EAQI,gBbkVgC;EajVhC,mBAAmB;EACnB,6BbJc;AHs8ClB;;AgB58CA;EAcI,sBAAsB;EACtB,gCbTc;AH28ClB;;AgBj9CA;EAmBI,6Bbbc;AH+8ClB;;AgBz7CA;;EAGI,eb4T+B;AH+nCnC;;AgBl7CA;EACE,yBbnCgB;AHw9ClB;;AgBt7CA;;EAKI,yBbvCc;AH69ClB;;AgB37CA;;EAWM,wBAA4C;AhBq7ClD;;AgBh7CA;;;;EAKI,SAAS;AhBk7Cb;;AgB16CA;EAEI,qCb1DW;AHs+Cf;;AK3+CE;EW2EI,cbvEY;EawEZ,sCbvES;AH2+Cf;;AiBv/CE;;;EAII,yBCgG4D;AlBy5ClE;;AiB7/CE;;;;EAYM,qBCwF0D;AlBg6ClE;;AK7/CE;EYiBM,yBAJsC;AjBo/C9C;;AiBr/CE;;EASQ,yBARoC;AjBy/C9C;;AiB7gDE;;;EAII,yBCgG4D;AlB+6ClE;;AiBnhDE;;;;EAYM,qBCwF0D;AlBs7ClE;;AKnhDE;EYiBM,yBAJsC;AjB0gD9C;;AiB3gDE;;EASQ,yBARoC;AjB+gD9C;;AiBniDE;;;EAII,yBCgG4D;AlBq8ClE;;AiBziDE;;;;EAYM,qBCwF0D;AlB48ClE;;AKziDE;EYiBM,yBAJsC;AjBgiD9C;;AiBjiDE;;EASQ,yBARoC;AjBqiD9C;;AiBzjDE;;;EAII,yBCgG4D;AlB29ClE;;AiB/jDE;;;;EAYM,qBCwF0D;AlBk+ClE;;AK/jDE;EYiBM,yBAJsC;AjBsjD9C;;AiBvjDE;;EASQ,yBARoC;AjB2jD9C;;AiB/kDE;;;EAII,yBCgG4D;AlBi/ClE;;AiBrlDE;;;;EAYM,qBCwF0D;AlBw/ClE;;AKrlDE;EYiBM,yBAJsC;AjB4kD9C;;AiB7kDE;;EASQ,yBARoC;AjBilD9C;;AiBrmDE;;;EAII,yBCgG4D;AlBugDlE;;AiB3mDE;;;;EAYM,qBCwF0D;AlB8gDlE;;AK3mDE;EYiBM,yBAJsC;AjBkmD9C;;AiBnmDE;;EASQ,yBARoC;AjBumD9C;;AiB3nDE;;;EAII,yBCgG4D;AlB6hDlE;;AiBjoDE;;;;EAYM,qBCwF0D;AlBoiDlE;;AKjoDE;EYiBM,yBAJsC;AjBwnD9C;;AiBznDE;;EASQ,yBARoC;AjB6nD9C;;AiBjpDE;;;EAII,yBCgG4D;AlBmjDlE;;AiBvpDE;;;;EAYM,qBCwF0D;AlB0jDlE;;AKvpDE;EYiBM,yBAJsC;AjB8oD9C;;AiB/oDE;;EASQ,yBARoC;AjBmpD9C;;AiBvqDE;;;EAII,sCdQS;AHiqDf;;AKtqDE;EYiBM,sCAJsC;AjB6pD9C;;AiB9pDE;;EASQ,sCARoC;AjBkqD9C;;AgB5kDA;EAGM,Wb3GS;Ea4GT,yBbpGY;EaqGZ,qBbgQqD;AH60C3D;;AgBllDA;EAWM,cb5GY;Ea6GZ,yBblHY;EamHZ,qBblHY;AH6rDlB;;AgBtkDA;EACE,Wb3Ha;Ea4Hb,yBbpHgB;AH6rDlB;;AgB3kDA;;;EAOI,qBb4OuD;AH81C3D;;AgBjlDA;EAWI,SAAS;AhB0kDb;;AgBrlDA;EAgBM,2Cb1IS;AHmtDf;;AK9sDE;EW4IM,WbjJO;EakJP,4CblJO;AHwtDf;;ActpDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhBwjDvC;EgB7jDG;IASK,SAAS;EhBujDjB;AACF;;AclqDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhBokDvC;EgBzkDG;IASK,SAAS;EhBmkDjB;AACF;;Ac9qDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhBglDvC;EgBrlDG;IASK,SAAS;EhB+kDjB;AACF;;Ac1rDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhB4lDvC;EgBjmDG;IASK,SAAS;EhB2lDjB;AACF;;AgB1mDA;EAOQ,cAAc;EACd,WAAW;EACX,gBAAgB;EAChB,iCAAiC;AhBumDzC;;AgBjnDA;EAcU,SAAS;AhBumDnB;;AmBpxDA;EACE,cAAc;EACd,WAAW;EACX,mCDiH8D;EChH9D,yBhByXkC;ECpQ9B,eAtCY;Ee5EhB,gBhBkR+B;EgBjR/B,gBhBsR+B;EgBrR/B,chBDgB;EgBEhB,sBhBTa;EgBUb,4BAA4B;EAC5B,yBhBPgB;EOOd,sBP6NgC;EiB/N9B,wEjBue4F;AHmzClG;;AoBtxDM;EDdN;ICeQ,gBAAgB;EpB0xDtB;AACF;;AmB1yDA;EAsBI,6BAA6B;EAC7B,SAAS;AnBwxDb;;AmB/yDA;EA4BI,kBAAkB;EAClB,0BhBrBc;AH4yDlB;;AqB7yDE;EACE,clBAc;EkBCd,sBlBRW;EkBSX,qBlBqdsE;EkBpdtE,UAAU;EAKR,gDlBaW;AH+xDjB;;AmB5zDA;EAqCI,chB9Bc;EgBgCd,UAAU;AnB0xDd;;AmBj0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnB0xDd;;AmBj0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnB0xDd;;AmBj0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnB0xDd;;AmBj0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnB0xDd;;AmBj0DA;EAiDI,yBhB9Cc;EgBgDd,UAAU;AnBmxDd;;AmB/wDA;;;;EAKI,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;AnBixDpB;;AmB7wDA;EAOI,chB/Dc;EgBgEd,sBhBvEW;AHi1Df;;AmBrwDA;;EAEE,cAAc;EACd,WAAW;AnBwwDb;;AmB9vDA;EACE,iCDyB8D;ECxB9D,oCDwB8D;ECvB9D,gBAAgB;Ef3Bd,kBAAW;Ee6Bb,gBhB+L+B;AHkkDjC;;AmB9vDA;EACE,+BDiB8D;EChB9D,kCDgB8D;EdK1D,kBAtCY;EemBhB,gBhB6H+B;AHooDjC;;AmB9vDA;EACE,gCDU8D;ECT9D,mCDS8D;EdK1D,mBAtCY;Ee0BhB,gBhBuH+B;AH0oDjC;;AmBxvDA;EACE,cAAc;EACd,WAAW;EACX,mBAA2B;EAC3B,gBAAgB;EfDZ,eAtCY;EeyChB,gBhBkK+B;EgBjK/B,chBnHgB;EgBoHhB,6BAA6B;EAC7B,yBAAyB;EACzB,mBAAmC;AnB2vDrC;;AmBrwDA;EAcI,gBAAgB;EAChB,eAAe;AnB2vDnB;;AmB/uDA;EACE,kCD9B8D;EC+B9D,uBhBoPiC;EC9Q7B,mBAtCY;EekEhB,gBhB+E+B;EOxN7B,qBP+N+B;AH6pDnC;;AmB/uDA;EACE,gCDtC8D;ECuC9D,oBhBiPgC;ECnR5B,kBAtCY;Ee0EhB,gBhBsE+B;EOvN7B,qBP8N+B;AHsqDnC;;AmB9uDA;EAGI,YAAY;AnB+uDhB;;AmB3uDA;EACE,YAAY;AnB8uDd;;AmBtuDA;EACE,mBhB0U0C;AH+5C5C;;AmBtuDA;EACE,cAAc;EACd,mBhB2T4C;AH86C9C;;AmBjuDA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,kBAA0C;EAC1C,iBAAyC;AnBouD3C;;AmBxuDA;;EAQI,kBAA0C;EAC1C,iBAAyC;AnBquD7C;;AmB5tDA;EACE,kBAAkB;EAClB,cAAc;EACd,qBhBgS6C;AH+7C/C;;AmB5tDA;EACE,kBAAkB;EAClB,kBhB4R2C;EgB3R3C,qBhB0R6C;AHq8C/C;;AmBluDA;;EAQI,chBzNc;AHw7DlB;;AmB3tDA;EACE,gBAAgB;AnB8tDlB;;AmB3tDA;EACE,2BAAoB;EAApB,oBAAoB;EACpB,sBAAmB;EAAnB,mBAAmB;EACnB,eAAe;EACf,qBhB6Q4C;AHi9C9C;;AmBluDA;EAQI,gBAAgB;EAChB,aAAa;EACb,uBhBwQ4C;EgBvQ5C,cAAc;AnB8tDlB;;AqB36DE;EACE,aAAa;EACb,WAAW;EACX,mBlB0c0C;ECjb1C,cAAW;EiBvBX,clBPa;AHq7DjB;;AqB36DE;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,UAAU;EACV,aAAa;EACb,eAAe;EACf,uBlBgyBqC;EkB/xBrC,iBAAiB;EjBmEf,mBAtCY;EiB3Bd,gBlBsO6B;EkBrO7B,WlBxDW;EkByDX,wClBtBa;EOxBb,sBP6NgC;AHgwDpC;;AqB/8DI;;;;EAuCE,cAAc;ArB+6DpB;;AqBt9DI;EA6CE,qBlBnCW;EkBsCT,oCH0CwD;EGzCxD,iRHpB0E;EGqB1E,4BAA4B;EAC5B,2DAA6D;EAC7D,gEHsCwD;AlBq4DhE;;AqB/9DI;EAwDI,qBlB9CS;EkB+CT,gDlB/CS;AH09DjB;;AqBp+DI;EAkEI,oCHwBwD;EGvBxD,kFHuBwD;AlB+4DhE;;AqBz+DI;EA0EE,qBlBhEW;EkBmET,uCHawD;EGZxD,ujBAA8J;ArBi6DtK;;AqB/+DI;EAkFI,qBlBxES;EkByET,gDlBzES;AH0+DjB;;AqBp/DI;EA2FI,clBjFS;AH8+DjB;;AqBx/DI;;;EAgGI,cAAc;ArB85DtB;;AqB9/DI;EAwGI,clB9FS;AHw/DjB;;AqBlgEI;EA2GM,qBlBjGO;AH4/DjB;;AqBtgEI;EAiHM,qBAAkC;EC3IxC,yBD4I+C;ArBy5DnD;;AqB3gEI;EAwHM,gDlB9GO;AHqgEjB;;AqB/gEI;EA4HM,qBlBlHO;AHygEjB;;AqBnhEI;EAsII,qBlB5HS;AH6gEjB;;AqBvhEI;EA2IM,qBlBjIO;EkBkIP,gDlBlIO;AHkhEjB;;AqBhhEE;EACE,aAAa;EACb,WAAW;EACX,mBlB0c0C;ECjb1C,cAAW;EiBvBX,clBVa;AH6hEjB;;AqBhhEE;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,UAAU;EACV,aAAa;EACb,eAAe;EACf,uBlBgyBqC;EkB/xBrC,iBAAiB;EjBmEf,mBAtCY;EiB3Bd,gBlBsO6B;EkBrO7B,WlBxDW;EkByDX,wClBzBa;EOrBb,sBP6NgC;AHq2DpC;;AqBpjEI;;;;EAuCE,cAAc;ArBohEpB;;AqB3jEI;EA6CE,qBlBtCW;EkByCT,oCH0CwD;EGzCxD,4UHpB0E;EGqB1E,4BAA4B;EAC5B,2DAA6D;EAC7D,gEHsCwD;AlB0+DhE;;AqBpkEI;EAwDI,qBlBjDS;EkBkDT,gDlBlDS;AHkkEjB;;AqBzkEI;EAkEI,oCHwBwD;EGvBxD,kFHuBwD;AlBo/DhE;;AqB9kEI;EA0EE,qBlBnEW;EkBsET,uCHawD;EGZxD,knBAA8J;ArBsgEtK;;AqBplEI;EAkFI,qBlB3ES;EkB4ET,gDlB5ES;AHklEjB;;AqBzlEI;EA2FI,clBpFS;AHslEjB;;AqB7lEI;;;EAgGI,cAAc;ArBmgEtB;;AqBnmEI;EAwGI,clBjGS;AHgmEjB;;AqBvmEI;EA2GM,qBlBpGO;AHomEjB;;AqB3mEI;EAiHM,qBAAkC;EC3IxC,yBD4I+C;ArB8/DnD;;AqBhnEI;EAwHM,gDlBjHO;AH6mEjB;;AqBpnEI;EA4HM,qBlBrHO;AHinEjB;;AqBxnEI;EAsII,qBlB/HS;AHqnEjB;;AqB5nEI;EA2IM,qBlBpIO;EkBqIP,gDlBrIO;AH0nEjB;;AmB/4DA;EACE,oBAAa;EAAb,aAAa;EACb,uBAAmB;EAAnB,mBAAmB;EACnB,sBAAmB;EAAnB,mBAAmB;AnBk5DrB;;AmBr5DA;EASI,WAAW;AnBg5Df;;Ac/mEI;EKsNJ;IAeM,oBAAa;IAAb,aAAa;IACb,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;IACvB,gBAAgB;EnB+4DpB;EmBj6DF;IAuBM,oBAAa;IAAb,aAAa;IACb,kBAAc;IAAd,cAAc;IACd,uBAAmB;IAAnB,mBAAmB;IACnB,sBAAmB;IAAnB,mBAAmB;IACnB,gBAAgB;EnB64DpB;EmBx6DF;IAgCM,qBAAqB;IACrB,WAAW;IACX,sBAAsB;EnB24D1B;EmB76DF;IAuCM,qBAAqB;EnBy4DzB;EmBh7DF;;IA4CM,WAAW;EnBw4Df;EmBp7DF;IAkDM,oBAAa;IAAb,aAAa;IACb,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;IACvB,WAAW;IACX,eAAe;EnBq4DnB;EmB37DF;IAyDM,kBAAkB;IAClB,oBAAc;IAAd,cAAc;IACd,aAAa;IACb,qBhB+KwC;IgB9KxC,cAAc;EnBq4DlB;EmBl8DF;IAiEM,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;EnBo4D3B;EmBt8DF;IAqEM,gBAAgB;EnBo4DpB;AACF;;AuBttEA;EACE,qBAAqB;EAErB,gBpBsR+B;EoBrR/B,cpBMgB;EoBLhB,kBAAkB;EAGlB,sBAAsB;EACtB,yBAAiB;EAAjB,sBAAiB;EAAjB,qBAAiB;EAAjB,iBAAiB;EACjB,6BAA6B;EAC7B,6BAA2C;ECuF3C,yBrB2RkC;ECpQ9B,eAtCY;EoBiBhB,gBrB0L+B;EOlR7B,sBP6NgC;EiB/N9B,qIjBgb6I;AH4yDnJ;;AoBxtEM;EGdN;IHeQ,gBAAgB;EpB4tEtB;AACF;;AKtuEE;EkBUE,cpBNc;EoBOd,qBAAqB;AvBguEzB;;AuBjvEA;EAsBI,UAAU;EACV,gDpBMa;AHytEjB;;AuBtvEA;EA6BI,apBiZ6B;AH40DjC;;AuB1vEA;EAkCI,eAAsD;AvB4tE1D;;AuB9sEA;;EAEE,oBAAoB;AvBitEtB;;AuBxsEE;EC3DA,WrBCa;EmBDX,yBnB6Ba;EqB3Bf,qBrB2Be;AH4uEjB;;AKnwEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBgxE7H;;AwBpwEE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,gDAAiF;AxBkwEvF;;AwB7vEE;EAEE,WrB1BW;EqB2BX,yBrBCa;EqBAb,qBrBAa;AH+vEjB;;AwBxvEE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBoyEnN;;AwBrvEI;;EAKI,gDAAiF;AxBqvEzF;;AuB7uEE;EC3DA,WrBCa;EmBDX,yBnBOc;EqBLhB,qBrBKgB;AHuyElB;;AKxyEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBqzE7H;;AwBzyEE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,iDAAiF;AxBuyEvF;;AwBlyEE;EAEE,WrB1BW;EqB2BX,yBrBrBc;EqBsBd,qBrBtBc;AH0zElB;;AwB7xEE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBy0EnN;;AwB1xEI;;EAKI,iDAAiF;AxB0xEzF;;AuBlxEE;EC3DA,WrBCa;EmBDX,yBnBoCa;EqBlCf,qBrBkCe;AH+yEjB;;AK70EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxB01E7H;;AwB90EE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,+CAAiF;AxB40EvF;;AwBv0EE;EAEE,WrB1BW;EqB2BX,yBrBQa;EqBPb,qBrBOa;AHk0EjB;;AwBl0EE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxB82EnN;;AwB/zEI;;EAKI,+CAAiF;AxB+zEzF;;AuBvzEE;EC3DA,WrBCa;EmBDX,yBnBsCa;EqBpCf,qBrBoCe;AHk1EjB;;AKl3EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxB+3E7H;;AwBn3EE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,gDAAiF;AxBi3EvF;;AwB52EE;EAEE,WrB1BW;EqB2BX,yBrBUa;EqBTb,qBrBSa;AHq2EjB;;AwBv2EE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBm5EnN;;AwBp2EI;;EAKI,gDAAiF;AxBo2EzF;;AuB51EE;EC3DA,crBUgB;EmBVd,yBnBmCa;EqBjCf,qBrBiCe;AH03EjB;;AKv5EE;EmBAE,crBIc;EmBVd,yBEDoF;EASpF,qBATyH;AxBo6E7H;;AwBx5EE;EAEE,crBHc;EmBVd,yBEDoF;EAgBpF,qBAhByH;EAqBvH,gDAAiF;AxBs5EvF;;AwBj5EE;EAEE,crBjBc;EqBkBd,yBrBOa;EqBNb,qBrBMa;AH64EjB;;AwB54EE;;EAGE,crB7Bc;EqB8Bd,yBAzCuK;EA6CvK,qBA7C+M;AxBw7EnN;;AwBz4EI;;EAKI,gDAAiF;AxBy4EzF;;AuBj4EE;EC3DA,WrBCa;EmBDX,yBnBiCa;EqB/Bf,qBrB+Be;AHi6EjB;;AK57EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBy8E7H;;AwB77EE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,+CAAiF;AxB27EvF;;AwBt7EE;EAEE,WrB1BW;EqB2BX,yBrBKa;EqBJb,qBrBIa;AHo7EjB;;AwBj7EE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxB69EnN;;AwB96EI;;EAKI,+CAAiF;AxB86EzF;;AuBt6EE;EC3DA,crBUgB;EmBVd,yBnBEc;EqBAhB,qBrBAgB;AHq+ElB;;AKj+EE;EmBAE,crBIc;EmBVd,yBEDoF;EASpF,qBATyH;AxB8+E7H;;AwBl+EE;EAEE,crBHc;EmBVd,yBEDoF;EAgBpF,qBAhByH;EAqBvH,iDAAiF;AxBg+EvF;;AwB39EE;EAEE,crBjBc;EqBkBd,yBrB1Bc;EqB2Bd,qBrB3Bc;AHw/ElB;;AwBt9EE;;EAGE,crB7Bc;EqB8Bd,yBAzCuK;EA6CvK,qBA7C+M;AxBkgFnN;;AwBn9EI;;EAKI,iDAAiF;AxBm9EzF;;AuB38EE;EC3DA,WrBCa;EmBDX,yBnBSc;EqBPhB,qBrBOgB;AHmgFlB;;AKtgFE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBmhF7H;;AwBvgFE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,8CAAiF;AxBqgFvF;;AwBhgFE;EAEE,WrB1BW;EqB2BX,yBrBnBc;EqBoBd,qBrBpBc;AHshFlB;;AwB3/EE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBuiFnN;;AwBx/EI;;EAKI,8CAAiF;AxBw/EzF;;AuB1+EE;ECPA,crB7Be;EqB8Bf,qBrB9Be;AHmhFjB;;AK1iFE;EmBwDE,WrB7DW;EqB8DX,yBrBlCa;EqBmCb,qBrBnCa;AHyhFjB;;AwBn/EE;EAEE,+CrBxCa;AH6hFjB;;AwBl/EE;EAEE,crB7Ca;EqB8Cb,6BAA6B;AxBo/EjC;;AwBj/EE;;EAGE,WrBhFW;EqBiFX,yBrBrDa;EqBsDb,qBrBtDa;AHyiFjB;;AwBj/EI;;EAKI,+CrB7DS;AH8iFjB;;AuB1gFE;ECPA,crBnDgB;EqBoDhB,qBrBpDgB;AHykFlB;;AK1kFE;EmBwDE,WrB7DW;EqB8DX,yBrBxDc;EqByDd,qBrBzDc;AH+kFlB;;AwBnhFE;EAEE,iDrB9Dc;AHmlFlB;;AwBlhFE;EAEE,crBnEc;EqBoEd,6BAA6B;AxBohFjC;;AwBjhFE;;EAGE,WrBhFW;EqBiFX,yBrB3Ec;EqB4Ed,qBrB5Ec;AH+lFlB;;AwBjhFI;;EAKI,iDrBnFU;AHomFlB;;AuB1iFE;ECPA,crBtBe;EqBuBf,qBrBvBe;AH4kFjB;;AK1mFE;EmBwDE,WrB7DW;EqB8DX,yBrB3Ba;EqB4Bb,qBrB5Ba;AHklFjB;;AwBnjFE;EAEE,+CrBjCa;AHslFjB;;AwBljFE;EAEE,crBtCa;EqBuCb,6BAA6B;AxBojFjC;;AwBjjFE;;EAGE,WrBhFW;EqBiFX,yBrB9Ca;EqB+Cb,qBrB/Ca;AHkmFjB;;AwBjjFI;;EAKI,+CrBtDS;AHumFjB;;AuB1kFE;ECPA,crBpBe;EqBqBf,qBrBrBe;AH0mFjB;;AK1oFE;EmBwDE,WrB7DW;EqB8DX,yBrBzBa;EqB0Bb,qBrB1Ba;AHgnFjB;;AwBnlFE;EAEE,gDrB/Ba;AHonFjB;;AwBllFE;EAEE,crBpCa;EqBqCb,6BAA6B;AxBolFjC;;AwBjlFE;;EAGE,WrBhFW;EqBiFX,yBrB5Ca;EqB6Cb,qBrB7Ca;AHgoFjB;;AwBjlFI;;EAKI,gDrBpDS;AHqoFjB;;AuB1mFE;ECPA,crBvBe;EqBwBf,qBrBxBe;AH6oFjB;;AK1qFE;EmBwDE,crBpDc;EqBqDd,yBrB5Ba;EqB6Bb,qBrB7Ba;AHmpFjB;;AwBnnFE;EAEE,+CrBlCa;AHupFjB;;AwBlnFE;EAEE,crBvCa;EqBwCb,6BAA6B;AxBonFjC;;AwBjnFE;;EAGE,crBvEc;EqBwEd,yBrB/Ca;EqBgDb,qBrBhDa;AHmqFjB;;AwBjnFI;;EAKI,+CrBvDS;AHwqFjB;;AuB1oFE;ECPA,crBzBe;EqB0Bf,qBrB1Be;AH+qFjB;;AK1sFE;EmBwDE,WrB7DW;EqB8DX,yBrB9Ba;EqB+Bb,qBrB/Ba;AHqrFjB;;AwBnpFE;EAEE,+CrBpCa;AHyrFjB;;AwBlpFE;EAEE,crBzCa;EqB0Cb,6BAA6B;AxBopFjC;;AwBjpFE;;EAGE,WrBhFW;EqBiFX,yBrBjDa;EqBkDb,qBrBlDa;AHqsFjB;;AwBjpFI;;EAKI,+CrBzDS;AH0sFjB;;AuB1qFE;ECPA,crBxDgB;EqByDhB,qBrBzDgB;AH8uFlB;;AK1uFE;EmBwDE,crBpDc;EqBqDd,yBrB7Dc;EqB8Dd,qBrB9Dc;AHovFlB;;AwBnrFE;EAEE,iDrBnEc;AHwvFlB;;AwBlrFE;EAEE,crBxEc;EqByEd,6BAA6B;AxBorFjC;;AwBjrFE;;EAGE,crBvEc;EqBwEd,yBrBhFc;EqBiFd,qBrBjFc;AHowFlB;;AwBjrFI;;EAKI,iDrBxFU;AHywFlB;;AuB1sFE;ECPA,crBjDgB;EqBkDhB,qBrBlDgB;AHuwFlB;;AK1wFE;EmBwDE,WrB7DW;EqB8DX,yBrBtDc;EqBuDd,qBrBvDc;AH6wFlB;;AwBntFE;EAEE,8CrB5Dc;AHixFlB;;AwBltFE;EAEE,crBjEc;EqBkEd,6BAA6B;AxBotFjC;;AwBjtFE;;EAGE,WrBhFW;EqBiFX,yBrBzEc;EqB0Ed,qBrB1Ec;AH6xFlB;;AwBjtFI;;EAKI,8CrBjFU;AHkyFlB;;AuB/tFA;EACE,gBpB4M+B;EoB3M/B,cpBjDe;EoBkDf,qBpB2F4C;AHuoF9C;;AK3yFE;EkB4EE,cpByF8D;EoBxF9D,0BpByF+C;AH0oFnD;;AuB1uFA;EAYI,0BpBoF+C;AH8oFnD;;AuB9uFA;EAiBI,cpBtFc;EoBuFd,oBAAoB;AvBiuFxB;;AuBttFA;ECPE,oBrB0SgC;ECnR5B,kBAtCY;EoBiBhB,gBrB+H+B;EOvN7B,qBP8N+B;AH4lFnC;;AuBztFA;ECXE,uBrBqSiC;EC9Q7B,mBAtCY;EoBiBhB,gBrBgI+B;EOxN7B,qBP+N+B;AHkmFnC;;AuBvtFA;EACE,cAAc;EACd,WAAW;AvB0tFb;;AuB5tFA;EAMI,kBpBuT+B;AHm6EnC;;AuBrtFA;;;EAII,WAAW;AvButFf;;AyBl2FA;ELgBM,gCjBiP2C;AHqmFjD;;AoBl1FM;EKpBN;ILqBQ,gBAAgB;EpBs1FtB;AACF;;AyB52FA;EAII,UAAU;AzB42Fd;;AyBx2FA;EAEI,aAAa;AzB02FjB;;AyBt2FA;EACE,kBAAkB;EAClB,SAAS;EACT,gBAAgB;ELDZ,6BjBkPwC;AHynF9C;;AoBv2FM;EKNN;ILOQ,gBAAgB;EpB22FtB;AACF;;A0Bh4FA;;;;EAIE,kBAAkB;A1Bm4FpB;;A0Bh4FA;EACE,mBAAmB;A1Bm4FrB;;A2B/2FI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;EAhCf,uBAA8B;EAC9B,qCAA4C;EAC5C,gBAAgB;EAChB,oCAA2C;A3Bm5F7C;;A2B91FI;EACE,cAAc;A3Bi2FpB;;A0B34FA;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,avBwpBsC;EuBvpBtC,aAAa;EACb,WAAW;EACX,gBvB8tBuC;EuB7tBvC,iBvB8tBmC;EuB7tBnC,oBAA4B;EtBsGxB,eAtCY;EsB9DhB,cvBXgB;EuBYhB,gBAAgB;EAChB,gBAAgB;EAChB,sBvBvBa;EuBwBb,4BAA4B;EAC5B,qCvBfa;EOCX,sBP6NgC;AHgsFpC;;A0Bt4FI;EACE,WAAW;EACX,OAAO;A1By4Fb;;A0Bt4FI;EACE,QAAQ;EACR,UAAU;A1By4FhB;;Ac73FI;EYnBA;IACE,WAAW;IACX,OAAO;E1Bo5FX;E0Bj5FE;IACE,QAAQ;IACR,UAAU;E1Bm5Fd;AACF;;Acx4FI;EYnBA;IACE,WAAW;IACX,OAAO;E1B+5FX;E0B55FE;IACE,QAAQ;IACR,UAAU;E1B85Fd;AACF;;Acn5FI;EYnBA;IACE,WAAW;IACX,OAAO;E1B06FX;E0Bv6FE;IACE,QAAQ;IACR,UAAU;E1By6Fd;AACF;;Ac95FI;EYnBA;IACE,WAAW;IACX,OAAO;E1Bq7FX;E0Bl7FE;IACE,QAAQ;IACR,UAAU;E1Bo7Fd;AACF;;A0B96FA;EAEI,SAAS;EACT,YAAY;EACZ,aAAa;EACb,uBvB4rBuC;AHovE3C;;A2B/8FI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;EAzBf,aAAa;EACb,qCAA4C;EAC5C,0BAAiC;EACjC,oCAA2C;A3B4+F7C;;A2B97FI;EACE,cAAc;A3Bi8FpB;;A0Bv7FA;EAEI,MAAM;EACN,WAAW;EACX,UAAU;EACV,aAAa;EACb,qBvB8qBuC;AH2wE3C;;A2Bt+FI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;EAlBf,mCAA0C;EAC1C,eAAe;EACf,sCAA6C;EAC7C,wBAA+B;A3B4/FjC;;A2Br9FI;EACE,cAAc;A3Bw9FpB;;A2Br/FI;EDmDE,iBAAiB;A1Bs8FvB;;A0Bj8FA;EAEI,MAAM;EACN,WAAW;EACX,UAAU;EACV,aAAa;EACb,sBvB6pBuC;AHsyE3C;;A2BjgGI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;A3BogGjB;;A2BxgGI;EAgBI,aAAa;A3B4/FrB;;A2Bz/FM;EACE,qBAAqB;EACrB,qBxB4MwC;EwB3MxC,uBxB0MwC;EwBzMxC,WAAW;EA9BjB,mCAA0C;EAC1C,yBAAgC;EAChC,sCAA6C;A3B2hG/C;;A2B1/FI;EACE,cAAc;A3B6/FpB;;A2BvgGM;EDiDA,iBAAiB;A1B09FvB;;A0Bn9FA;EAKI,WAAW;EACX,YAAY;A1Bk9FhB;;A0B78FA;EE9GE,SAAS;EACT,gBAAmB;EACnB,gBAAgB;EAChB,6BzBCgB;AH8jGlB;;A0B78FA;EACE,cAAc;EACd,WAAW;EACX,uBvBipBwC;EuBhpBxC,WAAW;EACX,gBvBgK+B;EuB/J/B,cvBhHgB;EuBiHhB,mBAAmB;EAEnB,mBAAmB;EACnB,6BAA6B;EAC7B,SAAS;A1B+8FX;;AKpkGE;EqBoIE,cvBinBqD;EuBhnBrD,qBAAqB;EJ/IrB,yBnBEc;AHklGlB;;A0Bh+FA;EAiCI,WvBpJW;EuBqJX,qBAAqB;EJtJrB,yBnB6Ba;AH6jGjB;;A0Bt+FA;EAwCI,cvBrJc;EuBsJd,oBAAoB;EACpB,6BAA6B;A1Bk8FjC;;A0B17FA;EACE,cAAc;A1B67FhB;;A0Bz7FA;EACE,cAAc;EACd,sBvB2lBwC;EuB1lBxC,gBAAgB;EtBrDZ,mBAtCY;EsB6FhB,cvBzKgB;EuB0KhB,mBAAmB;A1B47FrB;;A0Bx7FA;EACE,cAAc;EACd,uBvBilBwC;EuBhlBxC,cvB9KgB;AHymGlB;;A6BtnGA;;EAEE,kBAAkB;EAClB,2BAAoB;EAApB,oBAAoB;EACpB,sBAAsB;A7BynGxB;;A6B7nGA;;EAOI,kBAAkB;EAClB,kBAAc;EAAd,cAAc;A7B2nGlB;;AK1nGE;;EwBII,UAAU;A7B2nGhB;;A6BxoGA;;;;EAkBM,UAAU;A7B6nGhB;;A6BvnGA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,oBAA2B;EAA3B,2BAA2B;A7B0nG7B;;A6B7nGA;EAMI,WAAW;A7B2nGf;;A6BvnGA;;EAII,iB1BmM6B;AHq7FjC;;A6B5nGA;;EnBHI,0BmBa8B;EnBZ9B,6BmBY8B;A7BwnGlC;;A6BloGA;;EnBWI,yBmBI6B;EnBH7B,4BmBG6B;A7BynGjC;;A6BzmGA;EACE,wBAAmC;EACnC,uBAAkC;A7B4mGpC;;A6B9mGA;;;EAOI,cAAc;A7B6mGlB;;A6B1mGE;EACE,eAAe;A7B6mGnB;;A6BzmGA;EACE,uBAAsC;EACtC,sBAAqC;A7B4mGvC;;A6BzmGA;EACE,sBAAsC;EACtC,qBAAqC;A7B4mGvC;;A6BxlGA;EACE,0BAAsB;EAAtB,sBAAsB;EACtB,qBAAuB;EAAvB,uBAAuB;EACvB,qBAAuB;EAAvB,uBAAuB;A7B2lGzB;;A6B9lGA;;EAOI,WAAW;A7B4lGf;;A6BnmGA;;EAYI,gB1BkH6B;AH0+FjC;;A6BxmGA;;EnBrEI,6BmBuF+B;EnBtF/B,4BmBsF+B;A7B4lGnC;;A6B9mGA;;EnBnFI,yBmB0G4B;EnBzG5B,0BmByG4B;A7B6lGhC;;A6B5kGA;;EAGI,gBAAgB;A7B8kGpB;;A6BjlGA;;;;EAOM,kBAAkB;EAClB,sBAAsB;EACtB,oBAAoB;A7BilG1B;;A8B1uGA;EACE,kBAAkB;EAClB,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,uBAAoB;EAApB,oBAAoB;EACpB,WAAW;A9B6uGb;;A8BlvGA;;;;EAWI,kBAAkB;EAClB,kBAAc;EAAd,cAAc;EACd,SAAS;EACT,YAAY;EACZ,gBAAgB;A9B8uGpB;;A8B7vGA;;;;;;;;;;;;EAoBM,iB3BkN2B;AHsiGjC;;A8B5wGA;;;EA4BI,UAAU;A9BsvGd;;A8BlxGA;EAiCI,UAAU;A9BqvGd;;A8BtxGA;;EpB4BI,0BoBUmD;EpBTnD,6BoBSmD;A9BsvGvD;;A8B5xGA;;EpB0CI,yBoBHmD;EpBInD,4BoBJmD;A9B2vGvD;;A8BlyGA;EA6CI,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;A9ByvGvB;;A8BvyGA;;EpB4BI,0BoBqB6E;EpBpB7E,6BoBoB6E;A9B4vGjF;;A8B7yGA;EpB0CI,yBoBQsE;EpBPtE,4BoBOsE;A9BgwG1E;;A8BrvGA;;EAEE,oBAAa;EAAb,aAAa;A9BwvGf;;A8B1vGA;;EAQI,kBAAkB;EAClB,UAAU;A9BuvGd;;A8BhwGA;;EAYM,UAAU;A9ByvGhB;;A8BrwGA;;;;;;;;EAoBI,iB3BqJ6B;AHumGjC;;A8BxvGA;EAAuB,kB3BiJU;AH2mGjC;;A8B3vGA;EAAsB,iB3BgJW;AH+mGjC;;A8BvvGA;EACE,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,yB3B4RkC;E2B3RlC,gBAAgB;E1BuBZ,eAtCY;E0BiBhB,gB3BqL+B;E2BpL/B,gB3ByL+B;E2BxL/B,c3B9FgB;E2B+FhB,kBAAkB;EAClB,mBAAmB;EACnB,yB3BtGgB;E2BuGhB,yB3BrGgB;EOOd,sBP6NgC;AH4nGpC;;A8BvwGA;;EAkBI,aAAa;A9B0vGjB;;A8BhvGA;;EAEE,gCZR8D;AlB2vGhE;;A8BhvGA;;;;;;EAME,oB3BuQgC;ECnR5B,kBAtCY;E0BoDhB,gB3B4F+B;EOvN7B,qBP8N+B;AHipGnC;;A8BhvGA;;EAEE,kCZzB8D;AlB4wGhE;;A8BhvGA;;;;;;EAME,uB3BiPiC;EC9Q7B,mBAtCY;E0BqEhB,gB3B4E+B;EOxN7B,qBP+N+B;AHiqGnC;;A8BhvGA;;EAEE,sBAA0E;A9BmvG5E;;A8BxuGA;;;;;;EpB7II,0BoBmJ4B;EpBlJ5B,6BoBkJ4B;A9B4uGhC;;A8BzuGA;;;;;;EpBxII,yBoB8I2B;EpB7I3B,4BoB6I2B;A9B6uG/B;;A+Bl6GA;EACE,kBAAkB;EAClB,UAAU;EACV,cAAc;EACd,kBAA+C;EAC/C,oBAAqE;EACrE,iCAAmB;EAAnB,mBAAmB;A/Bq6GrB;;A+Bl6GA;EACE,2BAAoB;EAApB,oBAAoB;EACpB,kB5Bwf0C;AH66F5C;;A+Bl6GA;EACE,kBAAkB;EAClB,OAAO;EACP,WAAW;EACX,W5Bof0C;E4Bnf1C,eAAkF;EAClF,UAAU;A/Bq6GZ;;A+B36GA;EASI,W5BzBW;E4B0BX,qB5BEa;EmB7Bb,yBnB6Ba;AHq6GjB;;A+Bj7GA;EAoBM,gD5BRW;AHy6GjB;;A+Br7GA;EAyBI,qB5BqbsE;AH2+F1E;;A+Bz7GA;EA6BI,W5B7CW;E4B8CX,yB5Bif8E;E4Bhf9E,qB5Bgf8E;AHg7FlF;;A+B/7GA;EAuCM,c5BjDY;AH68GlB;;A+Bn8GA;EA0CQ,yB5BxDU;AHq9GlB;;A+Bn5GA;EACE,kBAAkB;EAClB,gBAAgB;EAEhB,mBAAmB;A/Bq5GrB;;A+Bz5GA;EASI,kBAAkB;EAClB,YAA+E;EAC/E,aAA+D;EAC/D,cAAc;EACd,W5BubwC;E4BtbxC,Y5BsbwC;E4BrbxC,oBAAoB;EACpB,WAAW;EACX,sB5BrFW;E4BsFX,yB5B+I6B;AHqwGjC;;A+Bt6GA;EAwBI,kBAAkB;EAClB,YAA+E;EAC/E,aAA+D;EAC/D,cAAc;EACd,W5BwawC;E4BvaxC,Y5BuawC;E4BtaxC,WAAW;EACX,mCAAgE;A/Bk5GpE;;A+Bz4GA;ErBjGI,sBP6NgC;AHixGpC;;A+B74GA;EAOM,kOb7D4E;AlBu8GlF;;A+Bj5GA;EAaM,qB5B7FW;EmB7Bb,yBnB6Ba;AHs+GjB;;A+Bt5GA;EAkBM,+KbxE4E;AlBg9GlF;;A+B15GA;ET7GI,wCnB6Ba;AH8+GjB;;A+B95GA;ET7GI,wCnB6Ba;AHk/GjB;;A+B93GA;EAGI,kB5ByZ+C;AHs+FnD;;A+Bl4GA;EAQM,8KblG4E;AlBg+GlF;;A+Bt4GA;ETjJI,wCnB6Ba;AH8/GjB;;A+Bl3GA;EACE,qBAA2D;A/Bq3G7D;;A+Bt3GA;EAKM,cAAqD;EACrD,c5BiY+E;E4BhY/E,mBAAmB;EAEnB,qB5B+X4E;AHq/FlF;;A+B73GA;EAaM,wBblE0D;EamE1D,0BbnE0D;EaoE1D,uBbhD0D;EaiD1D,wBbjD0D;EakD1D,yB5BpLY;E4BsLZ,qB5BqX4E;EiBviB5E,iJjByf+H;EiBzf/H,yIjByf+H;EiBzf/H,8KjByf+H;AH6iGrI;;AoBliHM;EW2JN;IX1JQ,gBAAgB;EpBsiHtB;AACF;;A+B74GA;EA0BM,sB5BlMS;E4BmMT,sCAA4E;EAA5E,8BAA4E;A/Bu3GlF;;A+Bl5GA;ETzKI,wCnB6Ba;AHkiHjB;;A+Bz2GA;EACE,qBAAqB;EACrB,WAAW;EACX,mCbrG8D;EasG9D,0C5BmKkC;ECpQ9B,eAtCY;E2B0IhB,gB5B4D+B;E4B3D/B,gB5BgE+B;E4B/D/B,c5BvNgB;E4BwNhB,sBAAsB;EACtB,uO5BkW+I;E4BjW/I,yB5B7NgB;EOOd,sBP6NgC;E4BJlC,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;A/B02GlB;;A+Bz3GA;EAkBI,qB5BuPsE;E4BtPtE,UAAU;EAKR,gD5BjNW;AHwjHjB;;A+B/3GA;EAiCM,c5B/OY;E4BgPZ,sB5BvPS;AHylHf;;A+Bp4GA;EAwCI,YAAY;EACZ,sB5B8HgC;E4B7HhC,sBAAsB;A/Bg2G1B;;A+B14GA;EA8CI,c5B7Pc;E4B8Pd,yB5BlQc;AHkmHlB;;A+B/4GA;EAoDI,aAAa;A/B+1GjB;;A+Bn5GA;EAyDI,kBAAkB;EAClB,0B5BxQc;AHsmHlB;;A+B11GA;EACE,kCbjK8D;EakK9D,oB5BgHkC;E4B/GlC,uB5B+GkC;E4B9GlC,oB5B+GiC;EC9Q7B,mBAtCY;AJmiHlB;;A+B11GA;EACE,gCbzK8D;Ea0K9D,mB5B6GiC;E4B5GjC,sB5B4GiC;E4B3GjC,kB5B4GgC;ECnR5B,kBAtCY;AJ2iHlB;;A+Br1GA;EACE,kBAAkB;EAClB,qBAAqB;EACrB,WAAW;EACX,mCbzL8D;Ea0L9D,gBAAgB;A/Bw1GlB;;A+Br1GA;EACE,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,mCbjM8D;EakM9D,SAAS;EACT,UAAU;A/Bw1GZ;;A+B91GA;EASI,qB5BqKsE;E4BpKtE,gD5B9Ra;AHunHjB;;A+Bn2GA;;EAgBI,yB5B9Tc;AHspHlB;;A+Bx2GA;EAqBM,iB5B4TQ;AH2hGd;;A+B52GA;EA0BI,0BAA0B;A/Bs1G9B;;A+Bl1GA;EACE,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,OAAO;EACP,UAAU;EACV,mCbjO8D;EakO9D,yB5BuCkC;E4BrClC,gB5B/D+B;E4BgE/B,gB5B3D+B;E4B4D/B,c5BlVgB;E4BmVhB,sB5B1Va;E4B2Vb,yB5BvVgB;EOOd,sBP6NgC;AHw8GpC;;A+Bl2GA;EAkBI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,UAAU;EACV,cAAc;EACd,6BbnP4D;EaoP5D,yB5BqBgC;E4BpBhC,gB5B3E6B;E4B4E7B,c5BlWc;E4BmWd,iBAAiB;ET3WjB,yBnBGc;E4B0Wd,oBAAoB;ErBjWpB,kCqBkWgF;A/Bo1GpF;;A+B10GA;EACE,WAAW;EACX,cbzQ2B;Ea0Q3B,UAAU;EACV,6BAA6B;EAC7B,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;A/B60GlB;;A+Bl1GA;EAQI,aAAa;A/B80GjB;;A+Bt1GA;EAY8B,gE5BvWb;AHqrHjB;;A+B11GA;EAa8B,gE5BxWb;AHyrHjB;;A+B91GA;EAc8B,gE5BzWb;AH6rHjB;;A+Bl2GA;EAkBI,SAAS;A/Bo1Gb;;A+Bt2GA;EAsBI,W5BqN6C;E4BpN7C,Y5BoN6C;E4BnN7C,oBAAyE;EThZzE,yBnB6Ba;E4BqXb,S5BoN0C;EO1lB1C,mBP2lB6C;EiB7lB3C,oHjByf+H;EiBzf/H,4GjByf+H;E4B7GjI,wBAAgB;EAAhB,gBAAgB;A/Bm1GpB;;AoB3tHM;EW0WN;IXzWQ,wBAAgB;IAAhB,gBAAgB;EpB+tHtB;AACF;;A+Bv3GA;ETxXI,yBnB2mB2E;AHwoG/E;;A+B33GA;EAsCI,W5B8LoC;E4B7LpC,c5B8LqC;E4B7LrC,kBAAkB;EAClB,e5B6LuC;E4B5LvC,yB5B9Zc;E4B+Zd,yBAAyB;ErBvZzB,mBPolBoC;AH6pGxC;;A+Br4GA;EAiDI,W5B0L6C;E4BzL7C,Y5ByL6C;EmBnmB7C,yBnB6Ba;E4B+Yb,S5B0L0C;EO1lB1C,mBP2lB6C;EiB7lB3C,iHjByf+H;EiBzf/H,4GjByf+H;E4BnFjI,qBAAgB;EAAhB,gBAAgB;A/Bu1GpB;;AoBzvHM;EW0WN;IXzWQ,qBAAgB;IAAhB,gBAAgB;EpB6vHtB;AACF;;A+Br5GA;ETxXI,yBnB2mB2E;AHsqG/E;;A+Bz5GA;EAgEI,W5BoKoC;E4BnKpC,c5BoKqC;E4BnKrC,kBAAkB;EAClB,e5BmKuC;E4BlKvC,yB5Bxbc;E4Bybd,yBAAyB;ErBjbzB,mBPolBoC;AH2rGxC;;A+Bn6GA;EA2EI,W5BgK6C;E4B/J7C,Y5B+J6C;E4B9J7C,aAAa;EACb,oB5BpE+B;E4BqE/B,mB5BrE+B;EmBlY/B,yBnB6Ba;E4B4ab,S5B6J0C;EO1lB1C,mBP2lB6C;EiB7lB3C,gHjByf+H;EiBzf/H,4GjByf+H;E4BtDjI,gBAAgB;A/B21GpB;;AoB1xHM;EW0WN;IXzWQ,oBAAgB;IAAhB,gBAAgB;EpB8xHtB;AACF;;A+Bt7GA;ETxXI,yBnB2mB2E;AHusG/E;;A+B17GA;EA6FI,W5BuIoC;E4BtIpC,c5BuIqC;E4BtIrC,kBAAkB;EAClB,e5BsIuC;E4BrIvC,6BAA6B;EAC7B,yBAAyB;EACzB,oBAA4C;A/Bi2GhD;;A+Bp8GA;EAwGI,yB5B5dc;EOQd,mBPolBoC;AHiuGxC;;A+Bz8GA;EA6GI,kBAAkB;EAClB,yB5Blec;EOQd,mBPolBoC;AHuuGxC;;A+B/8GA;EAoHM,yB5BteY;AHq0HlB;;A+Bn9GA;EAwHM,eAAe;A/B+1GrB;;A+Bv9GA;EA4HM,yB5B9eY;AH60HlB;;A+B39GA;EAgIM,eAAe;A/B+1GrB;;A+B/9GA;EAoIM,yB5BtfY;AHq1HlB;;A+B11GA;;;EXvfM,4GjByf+H;AH81GrI;;AoBn1HM;EWmfN;;;IXlfQ,gBAAgB;EpBy1HtB;AACF;;AgC12HA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,eAAe;EACf,gBAAgB;EAChB,gBAAgB;AhC62HlB;;AgC12HA;EACE,cAAc;EACd,oB7ByqBsC;AHosGxC;;AK52HE;E2BGE,qBAAqB;AhC62HzB;;AgCn3HA;EAWI,c7BXc;E6BYd,oBAAoB;EACpB,eAAe;AhC42HnB;;AgCp2HA;EACE,gC7BzBgB;AHg4HlB;;AgCx2HA;EAII,mB7BsM6B;AHkqHjC;;AgC52HA;EAQI,6BAAgD;EtBfhD,+BPoNgC;EOnNhC,gCPmNgC;AHqqHpC;;AKp4HE;E2B8BI,qC7BpCY;AH84HlB;;AgCt3HA;EAgBM,c7BrCY;E6BsCZ,6BAA6B;EAC7B,yBAAyB;AhC02H/B;;AgC53HA;;EAwBI,c7B5Cc;E6B6Cd,sB7BpDW;E6BqDX,kC7BrDW;AH85Hf;;AgCn4HA;EA+BI,gB7B2K6B;EOjN7B,yBsBwC4B;EtBvC5B,0BsBuC4B;AhCw2HhC;;AgC/1HA;EtB1DI,sBP6NgC;AHgsHpC;;AgCn2HA;;EAOI,W7B5EW;E6B6EX,yB7BjDa;AHk5HjB;;AgCx1HA;;EAGI,kBAAc;EAAd,cAAc;EACd,kBAAkB;AhC01HtB;;AgCt1HA;;EAGI,0BAAa;EAAb,aAAa;EACb,oBAAY;E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IAAnB,mBAAmB;EjC8+H3B;EiCtgIG;IA2BO,kBAAkB;EjC8+H5B;EiCzgIG;IA+BO,qB9B4hB6B;I8B3hB7B,oB9B2hB6B;EHk9GvC;EiC7gIG;;IAsCK,qBAAiB;IAAjB,iBAAiB;EjC2+HzB;EiCjhIG;IAqDK,+BAAwB;IAAxB,wBAAwB;IAGxB,6BAAgB;IAAhB,gBAAgB;EjC69HxB;EiCrhIG;IA4DK,aAAa;EjC49HrB;AACF;;AiC9hIA;EAyBQ,yBAAqB;EAArB,qBAAqB;EACrB,oBAA2B;EAA3B,2BAA2B;AjCygInC;;AiCniIA;;EAQU,gBAAgB;EAChB,eAAe;AjCgiIzB;;AiCziIA;EA6BU,uBAAmB;EAAnB,mBAAmB;AjCghI7B;;AiC7iIA;EAgCY,kBAAkB;AjCihI9B;;AiCjjIA;EAoCY,qB9B4hB6B;E8B3hB7B,oB9B2hB6B;AHs/GzC;;AiCtjIA;;EA2CU,qBAAiB;EAAjB,iBAAiB;AjCghI3B;;AiC3jIA;EA0DU,+BAAwB;EAAxB,wBAAwB;EAGxB,6BAAgB;EAAhB,gBAAgB;AjCmgI1B;;AiChkIA;EAiEU,aAAa;AjCmgIvB;;AiCt/HA;EAEI,yB9B/MW;AHusIf;;AKxsIE;E4BmNI,yB9BlNS;AH2sIf;;AiC9/HA;EAWM,yB9BxNS;AH+sIf;;AKhtIE;E4B4NM,yB9B3NO;AHmtIf;;AiCtgIA;EAkBQ,yB9B/NO;AHutIf;;AiC1gIA;;;;EA0BM,yB9BvOS;AH8tIf;;AiCjhIA;EA+BI,yB9B5OW;E8B6OX,gC9B7OW;AHmuIf;;AiCthIA;EAoCI,mRfrM8E;AlB2rIlF;;AiC1hIA;EAwCI,yB9BrPW;AH2uIf;;AiC9hIA;EA0CM,yB9BvPS;AH+uIf;;AKhvIE;E4B2PM,yB9B1PO;AHmvIf;;AiCl/HA;EAEI,W9B7QW;AHiwIf;;AKxvIE;E4BuQI,W9BhRS;AHqwIf;;AiC1/HA;EAWM,+B9BtRS;AHywIf;;AKhwIE;E4BgRM,gC9BzRO;AH6wIf;;AiClgIA;EAkBQ,gC9B7RO;AHixIf;;AiCtgIA;;;;EA0BM,W9BrSS;AHwxIf;;AiC7gIA;EA+BI,+B9B1SW;E8B2SX,sC9B3SW;AH6xIf;;AiClhIA;EAoCI,yRfzP8E;AlB2uIlF;;AiCthIA;EAwCI,+B9BnTW;AHqyIf;;AiC1hIA;EA0CM,W9BrTS;AHyyIf;;AKhyIE;E4B+SM,W9BxTO;AH6yIf;;AkChzIA;EACE,kBAAkB;EAClB,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,YAAY;EAEZ,qBAAqB;EACrB,sB/BJa;E+BKb,2BAA2B;EAC3B,sC/BIa;EOCX,sBP6NgC;AHilIpC;;AkC5zIA;EAaI,eAAe;EACf,cAAc;AlCmzIlB;;AkCj0IA;EAkBI,mBAAmB;EACnB,sBAAsB;AlCmzI1B;;AkCt0IA;EAsBM,mBAAmB;ExBCrB,2CQmH4D;ERlH5D,4CQkH4D;AlBksIhE;;AkC50IA;EA2BM,sBAAsB;ExBUxB,+CQqG4D;ERpG5D,8CQoG4D;AlBwsIhE;;AkCl1IA;;EAoCI,aAAa;AlCmzIjB;;AkC/yIA;EAGE,kBAAc;EAAd,cAAc;EAGd,eAAe;EACf,gB/B0wByC;AHoiH3C;;AkC1yIA;EACE,sB/BowBwC;AHyiH1C;;AkC1yIA;EACE,qBAA+B;EAC/B,gBAAgB;AlC6yIlB;;AkC1yIA;EACE,gBAAgB;AlC6yIlB;;AKl2IE;E6B0DE,qBAAqB;AlC4yIzB;;AkC9yIA;EAMI,oB/BmvBuC;AHyjH3C;;AkCpyIA;EACE,wB/B0uByC;E+BzuBzC,gBAAgB;EAEhB,qC/BrEa;E+BsEb,6C/BtEa;AH42If;;AkC3yIA;ExBhEI,0DwBwE8E;AlCuyIlF;;AkCnyIA;EACE,wB/B8tByC;E+B5tBzC,qC/BhFa;E+BiFb,0C/BjFa;AHs3If;;AkCzyIA;ExB5EI,0DQ4H4D;AlB6vIhE;;AkC7xIA;EACE,uBAAiC;EACjC,uB/B4sBwC;E+B3sBxC,sBAAgC;EAChC,gBAAgB;AlCgyIlB;;AkC7xIA;EACE,uBAAiC;EACjC,sBAAgC;AlCgyIlC;;AkC5xIA;EACE,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,OAAO;EACP,gB/BusByC;EOtzBvC,kCQ4H4D;AlBmxIhE;;AkC5xIA;;;EAGE,oBAAc;EAAd,cAAc;EACd,WAAW;AlC+xIb;;AkC5xIA;;ExBjHI,2CQmH4D;ERlH5D,4CQkH4D;AlBgyIhE;;AkC7xIA;;ExBxGI,+CQqG4D;ERpG5D,8CQoG4D;AlBsyIhE;;AkC3xIA;EAEI,mB/B+qBsD;AH8mH1D;;Ac53II;EoB6FJ;IAMI,oBAAa;IAAb,aAAa;IACb,uBAAmB;IAAnB,mBAAmB;IACnB,mB/ByqBsD;I+BxqBtD,kB/BwqBsD;EHsnHxD;EkCvyIF;IAaM,gBAAY;IAAZ,YAAY;IACZ,kB/BmqBoD;I+BlqBpD,gBAAgB;IAChB,iB/BiqBoD;EH4nHxD;AACF;;AkCpxIA;EAII,mB/BmpBsD;AHioH1D;;Ac/4II;EoBuHJ;IAQI,oBAAa;IAAb,aAAa;IACb,uBAAmB;IAAnB,mBAAmB;ElCqxIrB;EkC9xIF;IAcM,gBAAY;IAAZ,YAAY;IACZ,gBAAgB;ElCmxIpB;EkClyIF;IAkBQ,cAAc;IACd,cAAc;ElCmxIpB;EkCtyIF;IxBjJI,0BwB0KoC;IxBzKpC,6BwByKoC;ElCixItC;EkC1yIF;;IA8BY,0BAA0B;ElCgxIpC;EkC9yIF;;IAmCY,6BAA6B;ElC+wIvC;EkClzIF;IxBnII,yBwB2KmC;IxB1KnC,4BwB0KmC;ElC8wIrC;EkCtzIF;;IA6CY,yBAAyB;ElC6wInC;EkC1zIF;;IAkDY,4BAA4B;ElC4wItC;AACF;;AkChwIA;EAEI,sB/BwkBsC;AH0rH1C;;Ac17II;EoBsLJ;IAMI,uB/BqlBiC;I+BrlBjC,oB/BqlBiC;I+BrlBjC,e/BqlBiC;I+BplBjC,2B/BqlBuC;I+BrlBvC,wB/BqlBuC;I+BrlBvC,mB/BqlBuC;I+BplBvC,UAAU;IACV,SAAS;ElCmwIX;EkC5wIF;IAYM,qBAAqB;IACrB,WAAW;ElCmwIf;AACF;;AkC1vIA;EACE,qBAAqB;AlC6vIvB;;AkC9vIA;EAII,gBAAgB;AlC8vIpB;;AkClwIA;EAOM,gBAAgB;ExBvOlB,6BwBwOiC;ExBvOjC,4BwBuOiC;AlCgwIrC;;AkCxwIA;ExB9OI,yBwB0P8B;ExBzP9B,0BwByP8B;AlCiwIlC;;AkC7wIA;ExBvPI,gBwBuQ0B;EACxB,mB/B9C2B;AH+yIjC;;AmC3hJA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,qBhC6hCsC;EgC5hCtC,mBhC+hCsC;EgC7hCtC,gBAAgB;EAChB,yBhCEgB;EOSd,sBP6NgC;AHszIpC;;AmC1hJA;EACE,oBAAa;EAAb,aAAa;AnC6hJf;;AmC9hJA;EAKI,oBhCihCqC;AH4gHzC;;AmCliJA;EAQM,qBAAqB;EACrB,qBhC6gCmC;EgC5gCnC,chCRY;EgCSZ,YhCkhCuC;AH4gH7C;;AmCziJA;EAsBI,0BAA0B;AnCuhJ9B;;AmC7iJA;EA0BI,qBAAqB;AnCuhJzB;;AmCjjJA;EA8BI,chC5Bc;AHmjJlB;;AoChkJA;EACE,oBAAa;EAAb,aAAa;E7BGb,eAAe;EACf,gBAAgB;EGad,sBP6NgC;AHw1IpC;;AoCjkJA;EACE,kBAAkB;EAClB,cAAc;EACd,uBjC8wBwC;EiC7wBxC,iBjCkO+B;EiCjO/B,iBjCixBsC;EiChxBtC,cjCuBe;EiCrBf,sBjCPa;EiCQb,yBjCLgB;AHwkJlB;;AoC5kJA;EAYI,UAAU;EACV,cjC8J8D;EiC7J9D,qBAAqB;EACrB,yBjCZc;EiCad,qBjCZc;AHglJlB;;AoCplJA;EAoBI,UAAU;EACV,UjCywBiC;EiCxwBjC,gDjCOa;AH6jJjB;;AoChkJA;EAGM,cAAc;E1BahB,+BP+LgC;EO9LhC,kCP8LgC;AHu3IpC;;AoCtkJA;E1BEI,gCP6MgC;EO5MhC,mCP4MgC;AH43IpC;;AoC3kJA;EAcI,UAAU;EACV,WjCxCW;EiCyCX,yBjCba;EiCcb,qBjCda;AH+kJjB;;AoCllJA;EAqBI,cjCxCc;EiCyCd,oBAAoB;EAEpB,YAAY;EACZ,sBjClDW;EiCmDX,qBjChDc;AHgnJlB;;AqCvnJE;EACE,uBlCuxBsC;EC5pBpC,kBAtCY;EiCnFd,gBlCmO6B;AHu5IjC;;AqCrnJM;E3BqCF,8BPgM+B;EO/L/B,iCP+L+B;AHq5InC;;AqCrnJM;E3BkBF,+BP8M+B;EO7M/B,kCP6M+B;AH05InC;;AqCvoJE;EACE,uBlCqxBqC;EC1pBnC,mBAtCY;EiCnFd,gBlCoO6B;AHs6IjC;;AqCroJM;E3BqCF,8BPiM+B;EOhM/B,iCPgM+B;AHo6InC;;AqCroJM;E3BkBF,+BP+M+B;EO9M/B,kCP8M+B;AHy6InC;;AsCrpJA;EACE,qBAAqB;EACrB,qBnCs5BsC;ECr1BpC,cAAW;EkC/Db,gBnCuR+B;EmCtR/B,cAAc;EACd,kBAAkB;EAClB,mBAAmB;EACnB,wBAAwB;E5BKtB,sBP6NgC;EiB/N9B,qIjBgb6I;AHuuInJ;;AoBnpJM;EkBfN;IlBgBQ,gBAAgB;EpBupJtB;AACF;;AK7pJE;EiCGI,qBAAqB;AtC8pJ3B;;AsC5qJA;EAoBI,aAAa;AtC4pJjB;;AsCvpJA;EACE,kBAAkB;EAClB,SAAS;AtC0pJX;;AsCnpJA;EACE,oBnC23BsC;EmC13BtC,mBnC03BsC;EOj5BpC,oBPo5BqC;AH0xHzC;;AsC9oJE;ECjDA,WpCMa;EoCLb,yBpCiCe;AHkqJjB;;AKrrJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCmsJxC;;AuCtsJU;EAQJ,UAAU;EACV,+CpCsBW;AH4qJjB;;AsC7pJE;ECjDA,WpCMa;EoCLb,yBpCWgB;AHusJlB;;AKpsJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCktJxC;;AuCrtJU;EAQJ,UAAU;EACV,iDpCAY;AHitJlB;;AsC5qJE;ECjDA,WpCMa;EoCLb,yBpCwCe;AHyrJjB;;AKntJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCiuJxC;;AuCpuJU;EAQJ,UAAU;EACV,+CpC6BW;AHmsJjB;;AsC3rJE;ECjDA,WpCMa;EoCLb,yBpC0Ce;AHssJjB;;AKluJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCgvJxC;;AuCnvJU;EAQJ,UAAU;EACV,gDpC+BW;AHgtJjB;;AsC1sJE;ECjDA,cpCegB;EoCdhB,yBpCuCe;AHwtJjB;;AKjvJE;EkCVI,cpCUY;EoCTZ,yBAAkC;AvC+vJxC;;AuClwJU;EAQJ,UAAU;EACV,+CpC4BW;AHkuJjB;;AsCztJE;ECjDA,WpCMa;EoCLb,yBpCqCe;AHyuJjB;;AKhwJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC8wJxC;;AuCjxJU;EAQJ,UAAU;EACV,+CpC0BW;AHmvJjB;;AsCxuJE;ECjDA,cpCegB;EoCdhB,yBpCMgB;AHuxJlB;;AK/wJE;EkCVI,cpCUY;EoCTZ,yBAAkC;AvC6xJxC;;AuChyJU;EAQJ,UAAU;EACV,iDpCLY;AHiyJlB;;AsCvvJE;ECjDA,WpCMa;EoCLb,yBpCagB;AH+xJlB;;AK9xJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC4yJxC;;AuC/yJU;EAQJ,UAAU;EACV,8CpCEY;AHyyJlB;;AwCxzJA;EACE,kBAAoD;EACpD,mBrCmzBsC;EqCjzBtC,yBrCKgB;EOSd,qBP8N+B;AH+kJnC;;AcnwJI;E0B5DJ;IAQI,kBrC6yBoC;EH+gItC;AACF;;AwCzzJA;EACE,gBAAgB;EAChB,eAAe;E9BIb,gB8BHsB;AxC4zJ1B;;AyCv0JA;EACE,kBAAkB;EAClB,wBtCm9ByC;EsCl9BzC,mBtCm9BsC;EsCl9BtC,6BAA6C;E/BU3C,sBP6NgC;AHomJpC;;AyCt0JA;EAEE,cAAc;AzCw0JhB;;AyCp0JA;EACE,gBtC4Q+B;AH2jJjC;;AyC/zJA;EACE,mBAAsD;AzCk0JxD;;AyCn0JA;EAKI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,UAAU;EACV,wBtCo7BuC;EsCn7BvC,cAAc;AzCk0JlB;;AyCxzJE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBqwJlE;;A0Cz2JE;EACE,yBAAqC;A1C42JzC;;A0Cz2JE;EACE,cAA0B;A1C42J9B;;AyCt0JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBmxJlE;;A0Cv3JE;EACE,yBAAqC;A1C03JzC;;A0Cv3JE;EACE,cAA0B;A1C03J9B;;AyCp1JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBiyJlE;;A0Cr4JE;EACE,yBAAqC;A1Cw4JzC;;A0Cr4JE;EACE,cAA0B;A1Cw4J9B;;AyCl2JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlB+yJlE;;A0Cn5JE;EACE,yBAAqC;A1Cs5JzC;;A0Cn5JE;EACE,cAA0B;A1Cs5J9B;;AyCh3JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlB6zJlE;;A0Cj6JE;EACE,yBAAqC;A1Co6JzC;;A0Cj6JE;EACE,cAA0B;A1Co6J9B;;AyC93JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlB20JlE;;A0C/6JE;EACE,yBAAqC;A1Ck7JzC;;A0C/6JE;EACE,cAA0B;A1Ck7J9B;;AyC54JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBy1JlE;;A0C77JE;EACE,yBAAqC;A1Cg8JzC;;A0C77JE;EACE,cAA0B;A1Cg8J9B;;AyC15JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBu2JlE;;A0C38JE;EACE,yBAAqC;A1C88JzC;;A0C38JE;EACE,cAA0B;A1C88J9B;;A2Ct9JE;EACE;IAAO,2BAAuC;E3C09JhD;E2Cz9JE;IAAK,wBAAwB;E3C49J/B;AACF;;A2C/9JE;EACE;IAAO,2BAAuC;E3C09JhD;E2Cz9JE;IAAK,wBAAwB;E3C49J/B;AACF;;A2Cz9JA;EACE,oBAAa;EAAb,aAAa;EACb,YxC49BsC;EwC39BtC,gBAAgB;EAChB,cAAc;EvCmHV,kBAtCY;EuC3EhB,yBxCLgB;EOSd,sBP6NgC;AH4vJpC;;A2Cx9JA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,qBAAuB;EAAvB,uBAAuB;EACvB,gBAAgB;EAChB,WxCjBa;EwCkBb,kBAAkB;EAClB,mBAAmB;EACnB,yBxCQe;EiBnBX,2BjB89B4C;AHygIlD;;AoBn+JM;EuBDN;IvBEQ,gBAAgB;EpBu+JtB;AACF;;A2C99JA;ErBYE,qMAA6I;EqBV7I,0BxCq8BsC;AH4hIxC;;A2C79JE;EACE,0DxCu8BkD;EwCv8BlD,kDxCu8BkD;AHyhItD;;A2C79JM;EAJJ;IAKM,uBAAe;IAAf,eAAe;E3Ci+JrB;AACF;;A4C5gKA;EACE,oBAAa;EAAb,aAAa;EACb,qBAAuB;EAAvB,uBAAuB;A5C+gKzB;;A4C5gKA;EACE,WAAO;EAAP,OAAO;A5C+gKT;;A6CjhKA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EAGtB,eAAe;EACf,gBAAgB;EnCQd,sBP6NgC;AH8yJpC;;A6CzgKA;EACE,WAAW;EACX,c1CRgB;E0CShB,mBAAmB;A7C4gKrB;;AKnhKE;EwCWE,UAAU;EACV,c1Cdc;E0Ced,qBAAqB;EACrB,yB1CtBc;AHkiKlB;;A6CthKA;EAcI,c1ClBc;E0CmBd,yB1C1Bc;AHsiKlB;;A6CngKA;EACE,kBAAkB;EAClB,cAAc;EACd,wB1C28ByC;E0Cx8BzC,sB1C3Ca;E0C4Cb,sC1ClCa;AHsiKf;;A6C3gKA;EnCjBI,+BmC2BkC;EnC1BlC,gCmC0BkC;A7CsgKtC;;A6ChhKA;EnCHI,mCmCiBqC;EnChBrC,kCmCgBqC;A7CugKzC;;A6CrhKA;EAmBI,c1ClDc;E0CmDd,oBAAoB;EACpB,sB1C1DW;AHgkKf;;A6C3hKA;EA0BI,UAAU;EACV,W1ChEW;E0CiEX,yB1CrCa;E0CsCb,qB1CtCa;AH2iKjB;;A6CliKA;EAiCI,mBAAmB;A7CqgKvB;;A6CtiKA;EAoCM,gB1C4J2B;E0C3J3B,qB1C2J2B;AH22JjC;;A6Cx/JI;EACE,uBAAmB;EAAnB,mBAAmB;A7C2/JzB;;A6C5/JI;EnCtBA,kCPsKgC;EOlLhC,0BmCwCwC;A7C2/J5C;;A6CjgKI;EnClCA,gCPkLgC;EOtKhC,4BmCiC0C;A7C2/J9C;;A6CtgKI;EAeM,aAAa;A7C2/JvB;;A6C1gKI;EAmBM,qB1C0HuB;E0CzHvB,oBAAoB;A7C2/J9B;;A6C/gKI;EAuBQ,iB1CsHqB;E0CrHrB,sB1CqHqB;AHu4JjC;;AcvjKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7CwhKvB;E6CzhKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7CuhK1C;E6C7hKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7CshK5C;E6CjiKE;IAeM,aAAa;E7CqhKrB;E6CpiKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7CohK5B;E6CxiKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EH+5J/B;AACF;;AchlKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7CijKvB;E6CljKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7CgjK1C;E6CtjKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7C+iK5C;E6C1jKE;IAeM,aAAa;E7C8iKrB;E6C7jKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7C6iK5B;E6CjkKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EHw7J/B;AACF;;AczmKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7C0kKvB;E6C3kKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7CykK1C;E6C/kKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7CwkK5C;E6CnlKE;IAeM,aAAa;E7CukKrB;E6CtlKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7CskK5B;E6C1lKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EHi9J/B;AACF;;AcloKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7CmmKvB;E6CpmKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7CkmK1C;E6CxmKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7CimK5C;E6C5mKE;IAeM,aAAa;E7CgmKrB;E6C/mKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7C+lK5B;E6CnnKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EH0+J/B;AACF;;A6CllKA;EnCnHI,gBmCoHsB;A7CqlK1B;;A6CtlKA;EAII,qB1CmG6B;AHm/JjC;;A6C1lKA;EAOM,sBAAsB;A7CulK5B;;A8ChuKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+nKlE;;AKxtKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CmuKjD;;A8C1uKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0oKlE;;A8ChvKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+oKlE;;AKxuKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CmvKjD;;A8C1vKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0pKlE;;A8ChwKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+pKlE;;AKxvKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CmwKjD;;A8C1wKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0qKlE;;A8ChxKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+qKlE;;AKxwKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CmxKjD;;A8C1xKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0rKlE;;A8ChyKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+rKlE;;AKxxKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CmyKjD;;A8C1yKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0sKlE;;A8ChzKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+sKlE;;AKxyKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CmzKjD;;A8C1zKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0tKlE;;A8Ch0KE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+tKlE;;AKxzKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9Cm0KjD;;A8C10KE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0uKlE;;A8Ch1KE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB+uKlE;;AKx0KE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9Cm1KjD;;A8C11KE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlB0vKlE;;A+Cn2KA;EACE,YAAY;E3C8HR,iBAtCY;E2CtFhB,gB5C6R+B;E4C5R/B,cAAc;EACd,W5CYa;E4CXb,yB5CCa;E4CAb,WAAW;A/Cs2Kb;;AKj2KE;E0CDE,W5CMW;E4CLX,qBAAqB;A/Cs2KzB;;AKl2KE;E0CCI,YAAY;A/Cq2KlB;;A+C11KA;EACE,UAAU;EACV,6BAA6B;EAC7B,SAAS;A/C61KX;;A+Cv1KA;EACE,oBAAoB;A/C01KtB;;AgDh4KA;EAGE,8B7Cq4BuC;E6Cr4BvC,iB7Cq4BuC;E6Cp4BvC,gB7Co4BuC;ECzwBnC,mBAtCY;E4ClFhB,2C7CAa;E6CCb,4BAA4B;EAC5B,oC7Cs4BmD;E6Cr4BnD,gD7COa;E6CNb,UAAU;EtCOR,sBP83BsC;AH4/I1C;;AgD54KA;EAeI,sB7C03BsC;AHugJ1C;;AgDh5KA;EAmBI,UAAU;AhDi4Kd;;AgDp5KA;EAuBI,cAAc;EACd,UAAU;AhDi4Kd;;AgDz5KA;EA4BI,aAAa;AhDi4KjB;;AgD73KA;EACE,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,wB7Cs2BwC;E6Cr2BxC,c7CvBgB;E6CwBhB,2C7C9Ba;E6C+Bb,4BAA4B;EAC5B,4C7C82BoD;EO13BlD,2CQmH4D;ERlH5D,4CQkH4D;AlB2xKhE;;AgD93KA;EACE,gB7C61BwC;AHoiJ1C;;AiDv6KA;EAEE,gBAAgB;AjDy6KlB;;AiD36KA;EAKI,kBAAkB;EAClB,gBAAgB;AjD06KpB;;AiDr6KA;EACE,eAAe;EACf,MAAM;EACN,OAAO;EACP,a9C2pBsC;E8C1pBtC,aAAa;EACb,WAAW;EACX,YAAY;EACZ,gBAAgB;EAGhB,UAAU;AjDs6KZ;;AiD/5KA;EACE,kBAAkB;EAClB,WAAW;EACX,c9C24BuC;E8Cz4BvC,oBAAoB;AjDi6KtB;;AiD95KE;E7B3BI,2CjBg8BoD;EiBh8BpD,mCjBg8BoD;EiBh8BpD,oEjBg8BoD;E8Cn6BtD,sC9Ci6BmD;E8Cj6BnD,8B9Ci6BmD;AHggJvD;;AoB17KM;E6BuBJ;I7BtBM,gBAAgB;EpB87KtB;AACF;;AiDr6KE;EACE,uB9C+5BoC;E8C/5BpC,e9C+5BoC;AHygJxC;;AiDp6KE;EACE,8B9C45B2C;E8C55B3C,sB9C45B2C;AH2gJ/C;;AiDn6KA;EACE,oBAAa;EAAb,aAAa;EACb,6B/BmF8D;AlBm1KhE;;AiDx6KA;EAKI,8B/BgF4D;E+B/E5D,gBAAgB;AjDu6KpB;;AiD76KA;;EAWI,oBAAc;EAAd,cAAc;AjDu6KlB;;AiDl7KA;EAeI,gBA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E+CzxBnC,yB/CrDS;AHmsLf;;AkDzoLA;EACE,iB/CmxBuC;AHy3JzC;;AkD7oLA;EAII,QAAQ;EACR,a/C+wBqC;E+C9wBrC,c/C6wBqC;AHg4JzC;;AkDnpLA;EASM,OAAO;EACP,oC/C0wBmC;E+CzwBnC,uB/CrES;AHmtLf;;AkDznLA;EACE,gB/CyuBuC;E+CxuBvC,uB/C8uBuC;E+C7uBvC,W/CvGa;E+CwGb,kBAAkB;EAClB,sB/C/Fa;EOCX,sBP6NgC;AH8/KpC;;AoD7uLA;EACE,kBAAkB;EAClB,MAAM;EACN,OAAO;EACP,ajD6qBsC;EiD5qBtC,cAAc;EACd,gBjDy2BuC;EgD92BvC,kMhDmRiN;EgDjRjN,kBAAkB;EAClB,gBhD2R+B;EgD1R/B,gBhD+R+B;EgD9R/B,gBAAgB;EAChB,iBAAiB;EACjB,qBAAqB;EACrB,iBAAiB;EACjB,oBAAoB;EACpB,sBAAsB;EACtB,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,gBAAgB;E/CgHZ,mBAtCY;EgD7EhB,qBAAqB;EACrB,sBjDNa;EiDOb,4BAA4B;EAC5B,oCjDEa;EOCX,qBP8N+B;AH0hLnC;;AoD1wLA;EAoBI,kBAAkB;EAClB,cAAc;EACd,WjDy2BoC;EiDx2BpC,cjDy2BqC;EiDx2BrC,gBjDwN+B;AHkiLnC;;AoDlxLA;EA4BM,kBAAkB;EAClB,cAAc;EACd,WAAW;EACX,yBAAyB;EACzB,mBAAmB;ApD0vLzB;;AoDrvLA;EACE,qBjD01BuC;AH85JzC;;AoDzvLA;EAII,2BlCqG4D;AlBopLhE;;AoD7vLA;EAOM,SAAS;EACT,6BAAgE;EAChE,qCjDq1BiE;AHq6JvE;;AoDnwLA;EAaM,WjD0L2B;EiDzL3B,6BAAgE;EAChE,sBjD7CS;AHuyLf;;AoDrvLA;EACE,mBjDs0BuC;AHk7JzC;;AoDzvLA;EAII,yBlCiF4D;EkChF5D,ajDk0BqC;EiDj0BrC,YjDg0BoC;EiD/zBpC,gBAAgC;ApDyvLpC;;AoDhwLA;EAUM,OAAO;EACP,oCAA2F;EAC3F,uCjD8zBiE;AH47JvE;;AoDtwLA;EAgBM,SjDmK2B;EiDlK3B,oCAA2F;EAC3F,wBjDpES;AH8zLf;;AoDrvLA;EACE,kBjD+yBuC;AHy8JzC;;AoDzvLA;EAII,wBlC0D4D;AlB+rLhE;;AoD7vLA;EAOM,MAAM;EACN,oCAA2F;EAC3F,wCjD0yBiE;AHg9JvE;;AoDnwLA;EAaM,QjD+I2B;EiD9I3B,oCAA2F;EAC3F,yBjDxFS;AHk1Lf;;AoDzwLA;EAqBI,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,cAAc;EACd,WjDsxBoC;EiDrxBpC,oBAAsC;EACtC,WAAW;EACX,gCjD0wBuD;AH8+J3D;;AoDpvLA;EACE,oBjD+wBuC;AHw+JzC;;AoDxvLA;EAII,0BlC0B4D;EkCzB5D,ajD2wBqC;EiD1wBrC,YjDywBoC;EiDxwBpC,gBAAgC;ApDwvLpC;;AoD/vLA;EAUM,QAAQ;EACR,oCjDqwBmC;EiDpwBnC,sCjDuwBiE;AHk/JvE;;AoDrwLA;EAgBM,UjD4G2B;EiD3G3B,oCjD+vBmC;EiD9vBnC,uBjD3HS;AHo3Lf;;AoDnuLA;EACE,uBjDguBwC;EiD/tBxC,gBAAgB;EhD3BZ,eAtCY;EgDoEhB,yBjDytByD;EiDxtBzD,gCAAyE;E1CnIvE,0CQmH4D;ERlH5D,2CQkH4D;AlBuvLhE;;AoD7uLA;EAUI,aAAa;ApDuuLjB;;AoDnuLA;EACE,uBjDktBwC;EiDjtBxC,cjDxJgB;AH83LlB;;AqDj4LA;EACE,kBAAkB;ArDo4LpB;;AqDj4LA;EACE,uBAAmB;EAAnB,mBAAmB;ArDo4LrB;;AqDj4LA;EACE,kBAAkB;EAClB,WAAW;EACX,gBAAgB;ArDo4LlB;;AsD35LE;EACE,cAAc;EACd,WAAW;EACX,WAAW;AtD85Lf;;AqDt4LA;EACE,kBAAkB;EAClB,aAAa;EACb,WAAW;EACX,WAAW;EACX,mBAAmB;EACnB,mCAA2B;EAA3B,2BAA2B;EjClBvB,8CjBqjCkF;EiBrjClF,sCjBqjCkF;EiBrjClF,0EjBqjCkF;AHu2JxF;;AoBx5LM;EiCQN;IjCPQ,gBAAgB;EpB45LtB;AACF;;AqD54LA;;;EAGE,cAAc;ArD+4LhB;;AqD54LA;;EAEE,mCAA2B;EAA3B,2BAA2B;A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4pMtD;;AyDlqME;EACE,oCAAmC;AzDqqMvC;;AK3pME;;;EoDLI,oCAAgD;AzDsqMtD;;AyD5qME;EACE,oCAAmC;AzD+qMvC;;AKrqME;;;EoDLI,oCAAgD;AzDgrMtD;;AyDtrME;EACE,oCAAmC;AzDyrMvC;;AK/qME;;;EoDLI,oCAAgD;AzD0rMtD;;AyDhsME;EACE,oCAAmC;AzDmsMvC;;AKzrME;;;EoDLI,oCAAgD;AzDosMtD;;AyD1sME;EACE,oCAAmC;AzD6sMvC;;AKnsME;;;EoDLI,oCAAgD;AzD8sMtD;;AyDptME;EACE,oCAAmC;AzDutMvC;;AK7sME;;;EoDLI,oCAAgD;AzDwtMtD;;A0DvtMA;EACE,iCAAmC;A1D0tMrC;;A0DvtMA;EACE,wCAAwC;A1D0tM1C;;A2DruMA;EAAkB,oCAAoD;A3DyuMtE;;A2DxuMA;EAAkB,wCAAwD;A3D4uM1E;;A2D3uMA;EAAkB,0CAA0D;A3D+uM5E;;A2D9uMA;EAAkB,2CAA2D;A3DkvM7E;;A2DjvMA;EAAkB,yCAAyD;A3DqvM3E;;A2DnvMA;EAAmB,oBAAoB;A3DuvMvC;;A2DtvMA;EAAmB,wBAAwB;A3D0vM3C;;A2DzvMA;EAAmB,0BAA0B;A3D6vM7C;;A2D5vMA;EAAmB,2BAA2B;A3DgwM9C;;A2D/vMA;EAAmB,yBAAyB;A3DmwM5C;;A2DhwME;EACE,gCAA+B;A3DmwMnC;;A2DpwME;EACE,gCAA+B;A3DuwMnC;;A2DxwME;EACE,gCAA+B;A3D2wMnC;;A2D5wME;EACE,gCAA+B;A3D+wMnC;;A2DhxME;EACE,gCAA+B;A3DmxMnC;;A2DpxME;EACE,gCAA+B;A3DuxMnC;;A2DxxME;EACE,gCAA+B;A3D2xMnC;;A2D5xME;EACE,gCAA+B;A3D+xMnC;;A2D3xMA;EACE,6BAA+B;A3D8xMjC;;A2DvxMA;EACE,gCAA2C;A3D0xM7C;;A2DvxMA;EACE,iCAAwC;A3D0xM1C;;A2DvxMA;EACE,0CAAiD;EACjD,2CAAkD;A3D0xMpD;;A2DvxMA;EACE,2CAAkD;EAClD,8CAAqD;A3D0xMvD;;A2DvxMA;EACE,8CAAqD;EACrD,6CAAoD;A3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lD;;AuE92OQ;;EAEE,iCAA0C;AvEi3OpD;;AuE/2OQ;;EAEE,+BAAsC;AvEk3OhD;;AuEj4OQ;EAAgC,yBAA4B;AvEq4OpE;;AuEp4OQ;;EAEE,6BAAoC;AvEu4O9C;;AuEr4OQ;;EAEE,+BAAwC;AvEw4OlD;;AuEt4OQ;;EAEE,gCAA0C;AvEy4OpD;;AuEv4OQ;;EAEE,8BAAsC;AvE04OhD;;AuEz5OQ;EAAgC,uBAA4B;AvE65OpE;;AuE55OQ;;EAEE,2BAAoC;AvE+5O9C;;AuE75OQ;;EAEE,6BAAwC;AvEg6OlD;;AuE95OQ;;EAEE,8BAA0C;AvEi6OpD;;AuE/5OQ;;EAEE,4BAAsC;AvEk6OhD;;AuEj7OQ;EAAgC,yBAA4B;AvEq7OpE;;AuEp7OQ;;EAEE,6BAAoC;AvEu7O9C;;AuEr7OQ;;EAEE,+BAAwC;AvEw7OlD;;AuEt7OQ;;EAEE,gCAA0C;AvEy7OpD;;AuEv7OQ;;EAEE,8BAAsC;AvE07OhD;;AuEz8OQ;EAAgC,uBAA4B;AvE68OpE;;AuE58OQ;;EAEE,2BAAoC;AvE+8O9C;;AuE78OQ;;EAEE,6BAAwC;AvEg9OlD;;AuE98OQ;;EAEE,8BAA0C;AvEi9OpD;;AuE/8OQ;;EAEE,4BAAsC;AvEk9OhD;;AuEj+OQ;EAAgC,qBAA4B;AvEq+OpE;;AuEp+OQ;;EAEE,yBAAoC;AvEu+O9C;;AuEr+OQ;;EAEE,2BAAwC;AvEw+OlD;;AuEt+OQ;;EAEE,4BAA0C;AvEy+OpD;;AuEv+OQ;;EAEE,0BAAsC;AvE0+OhD;;AuEz/OQ;EAAgC,2BAA4B;AvE6/OpE;;AuE5/OQ;;EAEE,+BAAoC;AvE+/O9C;;AuE7/OQ;;EAEE,iCAAwC;AvEggPlD;;AuE9/OQ;;EAEE,kCAA0C;AvEigPpD;;AuE//OQ;;EAEE,gCAAsC;AvEkgPhD;;AuEjhPQ;EAAgC,0BAA4B;AvEqhPpE;;AuEphPQ;;EAEE,8BAAoC;AvEuhP9C;;AuErhPQ;;EAEE,gCAAwC;AvEwhPlD;;AuEthPQ;;EAEE,iCAA0C;AvEyhPpD;;AuEvhPQ;;EAEE,+BAAsC;AvE0hPhD;;AuEziPQ;EAAgC,wBAA4B;AvE6iPpE;;AuE5iPQ;;EAEE,4BAAoC;AvE+iP9C;;AuE7iPQ;;EAEE,8BAAwC;AvEgjPlD;;AuE9iPQ;;EAEE,+BAA0C;AvEijPpD;;AuE/iPQ;;EAEE,6BAAsC;AvEkjPhD;;AuEjkPQ;EAAgC,0BAA4B;AvEqkPpE;;AuEpkPQ;;EAEE,8BAAoC;AvEukP9C;;AuErkPQ;;EAEE,gCAAwC;AvEwkPlD;;AuEtkPQ;;EAEE,iCAA0C;AvEykPpD;;AuEvkPQ;;EAEE,+BAAsC;AvE0kPhD;;AuEzlPQ;EAAgC,wBAA4B;AvE6lPpE;;AuE5lPQ;;EAEE,4BAAoC;AvE+lP9C;;AuE7lPQ;;EAEE,8BAAwC;AvEgmPlD;;AuE9lPQ;;EAEE,+BAA0C;AvEimPpD;;AuE/lPQ;;EAEE,6BAAsC;AvEkmPhD;;AuE1lPQ;EAAwB,2BAA2B;AvE8lP3D;;AuE7lPQ;;EAEE,+BAA+B;AvEgmPzC;;AuE9lPQ;;EAEE,iCAAiC;AvEimP3C;;AuE/lPQ;;EAEE,kCAAkC;AvEkmP5C;;AuEhmPQ;;EAEE,gCAAgC;AvEmmP1C;;AuElnPQ;EAAwB,0BAA2B;AvEsnP3D;;AuErnPQ;;EAEE,8BAA+B;AvEwnPzC;;AuEtnPQ;;EAEE,gCAAiC;AvEynP3C;;AuEvnPQ;;EAEE,iCAAkC;AvE0nP5C;;AuExnPQ;;EAEE,+BAAgC;AvE2nP1C;;AuE1oPQ;EAAwB,wBAA2B;AvE8oP3D;;AuE7oPQ;;EAEE,4BAA+B;AvEgpPzC;;AuE9oPQ;;EAEE,8BAAiC;AvEipP3C;;AuE/oPQ;;EAEE,+BAAkC;AvEkpP5C;;AuEhpPQ;;EAEE,6BAAgC;AvEmpP1C;;AuElqPQ;EAAwB,0BAA2B;AvEsqP3D;;AuErqPQ;;EAEE,8BAA+B;AvEwqPzC;;AuEtqPQ;;EAEE,gCAAiC;AvEyqP3C;;AuEvqPQ;;EAEE,iCAAkC;AvE0qP5C;;AuExqPQ;;EAEE,+BAAgC;AvE2qP1C;;AuE1rPQ;EAAwB,wBAA2B;AvE8rP3D;;AuE7rPQ;;EAEE,4BAA+B;AvEgsPzC;;AuE9rPQ;;EAEE,8BAAiC;AvEisP3C;;AuE/rPQ;;EAEE,+BAAkC;AvEksP5C;;AuEhsPQ;;EAEE,6BAAgC;AvEmsP1C;;AuE7rPI;EAAmB,uBAAuB;AvEisP9C;;AuEhsPI;;EAEE,2BAA2B;AvEmsPjC;;AuEjsPI;;EAEE,6BAA6B;AvEosPnC;;AuElsPI;;EAEE,8BAA8B;AvEqsPpC;;AuEnsPI;;EAEE,4BAA4B;AvEssPlC;;Ac/sPI;EyDlDI;IAAgC,oBAA4B;EvEswPlE;EuErwPM;;IAEE,wBAAoC;EvEuwP5C;EuErwPM;;IAEE,0BAAwC;EvEuwPhD;EuErwPM;;IAEE,2BAA0C;EvEuwPlD;EuErwPM;;IAEE,yBAAsC;EvEuwP9C;EuEtxPM;IAAgC,0BAA4B;EvEyxPlE;EuExxPM;;IAEE,8BAAoC;EvE0xP5C;EuExxPM;;IAEE,gCAAwC;EvE0xPhD;EuExxPM;;IAEE,iCAA0C;EvE0xPlD;EuExxPM;;IAEE,+BAAsC;EvE0xP9C;EuEzyPM;IAAgC,yBAA4B;EvE4yPlE;EuE3yPM;;IAEE,6BAAoC;EvE6yP5C;EuE3yPM;;IAEE,+BAAwC;EvE6yPhD;EuE3yPM;;IAEE,gCAA0C;EvE6yPlD;EuE3yPM;;IAEE,8BAAsC;EvE6yP9C;EuE5zPM;IAAgC,uBAA4B;EvE+zPlE;EuE9zPM;;IAEE,2BAAoC;EvEg0P5C;EuE9zPM;;IAEE,6BAAwC;EvEg0PhD;EuE9zPM;;IAEE,8BAA0C;EvEg0PlD;EuE9zPM;;IAEE,4BAAsC;EvEg0P9C;EuE/0PM;IAAgC,yBAA4B;EvEk1PlE;EuEj1PM;;IAEE,6BAAoC;EvEm1P5C;EuEj1PM;;IAEE,+BAAwC;EvEm1PhD;EuEj1PM;;IAEE,gCAA0C;EvEm1PlD;EuEj1PM;;IAEE,8BAAsC;EvEm1P9C;EuEl2PM;IAAgC,uBAA4B;EvEq2PlE;EuEp2PM;;IAEE,2BAAoC;EvEs2P5C;EuEp2PM;;IAEE,6BAAwC;EvEs2PhD;EuEp2PM;;IAEE,8BAA0C;EvEs2PlD;EuEp2PM;;IAEE,4BAAsC;EvEs2P9C;EuEr3PM;IAAgC,qBAA4B;EvEw3PlE;EuEv3PM;;IAEE,yBAAoC;EvEy3P5C;EuEv3PM;;IAEE,2BAAwC;EvEy3PhD;EuEv3PM;;IAEE,4BAA0C;EvEy3PlD;EuEv3PM;;IAEE,0BAAsC;EvEy3P9C;EuEx4PM;IAAgC,2BAA4B;EvE24PlE;EuE14PM;;IAEE,+BAAoC;EvE44P5C;EuE14PM;;IAEE,iCAAwC;EvE44PhD;EuE14PM;;IAEE,kCAA0C;EvE44PlD;EuE14PM;;IAEE,gCAAsC;EvE44P9C;EuE35PM;IAAgC,0BAA4B;EvE85PlE;EuE75PM;;IAEE,8BAAoC;EvE+5P5C;EuE75PM;;IAEE,gCAAwC;EvE+5PhD;EuE75PM;;IAEE,iCAA0C;EvE+5PlD;EuE75PM;;IAEE,+BAAsC;EvE+5P9C;EuE96PM;IAAgC,wBAA4B;EvEi7PlE;EuEh7PM;;IAEE,4BAAoC;EvEk7P5C;EuEh7PM;;IAEE,8BAAwC;EvEk7PhD;EuEh7PM;;IAEE,+BAA0C;EvEk7PlD;EuEh7PM;;IAEE,6BAAsC;EvEk7P9C;EuEj8PM;IAAgC,0BAA4B;EvEo8PlE;EuEn8PM;;IAEE,8BAAoC;EvEq8P5C;EuEn8PM;;IAEE,gCAAwC;EvEq8PhD;EuEn8PM;;IAEE,iCAA0C;EvEq8PlD;EuEn8PM;;IAEE,+BAAsC;EvEq8P9C;EuEp9PM;IAAgC,wBAA4B;EvEu9PlE;EuEt9PM;;IAEE,4BAAoC;EvEw9P5C;EuEt9PM;;IAEE,8BAAwC;EvEw9PhD;EuEt9PM;;IAEE,+BAA0C;EvEw9PlD;EuEt9PM;;IAEE,6BAAsC;EvEw9P9C;EuEh9PM;IAAwB,2BAA2B;EvEm9PzD;EuEl9PM;;IAEE,+BAA+B;EvEo9PvC;EuEl9PM;;IAEE,iCAAiC;EvEo9PzC;EuEl9PM;;IAEE,kCAAkC;EvEo9P1C;EuEl9PM;;IAEE,gCAAgC;EvEo9PxC;EuEn+PM;IAAwB,0BAA2B;EvEs+PzD;EuEr+PM;;IAEE,8BAA+B;EvEu+PvC;EuEr+PM;;IAEE,gCAAiC;EvEu+PzC;EuEr+PM;;IAEE,iCAAkC;EvEu+P1C;EuEr+PM;;IAEE,+BAAgC;EvEu+PxC;EuEt/PM;IAAwB,wBAA2B;EvEy/PzD;EuEx/PM;;IAEE,4BAA+B;EvE0/PvC;EuEx/PM;;IAEE,8BAAiC;EvE0/PzC;EuEx/PM;;IAEE,+BAAkC;EvE0/P1C;EuEx/PM;;IAEE,6BAAgC;EvE0/PxC;EuEzgQM;IAAwB,0BAA2B;EvE4gQzD;EuE3gQM;;IAEE,8BAA+B;EvE6gQvC;EuE3gQM;;IAEE,gCAAiC;EvE6gQzC;EuE3gQM;;IAEE,iCAAkC;EvE6gQ1C;EuE3gQM;;IAEE,+BAAgC;EvE6gQxC;EuE5hQM;IAAwB,wBAA2B;EvE+hQzD;EuE9hQM;;IAEE,4BAA+B;EvEgiQvC;EuE9hQM;;IAEE,8BAAiC;EvEgiQzC;EuE9hQM;;IAEE,+BAAkC;EvEgiQ1C;EuE9hQM;;IAEE,6BAAgC;EvEgiQxC;EuE1hQE;IAAmB,uBAAuB;EvE6hQ5C;EuE5hQE;;IAEE,2BAA2B;EvE8hQ/B;EuE5hQE;;IAEE,6BAA6B;EvE8hQjC;EuE5hQE;;IAEE,8BAA8B;EvE8hQlC;EuE5hQE;;IAEE,4BAA4B;EvE8hQhC;AACF;;AcxiQI;EyDlDI;IAAgC,oBAA4B;EvE+lQlE;EuE9lQM;;IAEE,wBAAoC;EvEgmQ5C;EuE9lQM;;IAEE,0BAAwC;EvEgmQhD;EuE9lQM;;IAEE,2BAA0C;EvEgmQlD;EuE9lQM;;IAEE,yBAAsC;EvEgmQ9C;EuE/mQM;IAAgC,0BAA4B;EvEknQlE;EuEjnQM;;IAEE,8BAAoC;EvEmnQ5C;EuEjnQM;;IAEE,gCAAwC;EvEmnQhD;EuEjnQM;;IAEE,iCAA0C;EvEmnQlD;EuEjnQM;;IAEE,+BAAsC;EvEmnQ9C;EuEloQM;IAAgC,yBAA4B;EvEqoQlE;EuEpoQM;;IAEE,6BAAoC;EvEsoQ5C;EuEpoQM;;IAEE,+BAAwC;EvEsoQhD;EuEpoQM;;IAEE,gCAA0C;EvEsoQlD;EuEpoQM;;IAEE,8BAAsC;EvEsoQ9C;EuErpQM;IAAgC,uBAA4B;EvEwpQlE;EuEvpQM;;IAEE,2BAAoC;EvEypQ5C;EuEvpQM;;IAEE,6BAAwC;EvEypQhD;EuEvpQM;;IAEE,8BAA0C;EvEypQlD;EuEvpQM;;IAEE,4BAAsC;EvEypQ9C;EuExqQM;IAAgC,yBAA4B;EvE2qQlE;EuE1qQM;;IAEE,6BAAoC;EvE4qQ5C;EuE1qQM;;IAEE,+BAAwC;EvE4qQhD;EuE1qQM;;IAEE,gCAA0C;EvE4qQlD;EuE1qQM;;IAEE,8BAAsC;EvE4qQ9C;EuE3rQM;IAAgC,uBAA4B;EvE8rQlE;EuE7rQM;;IAEE,2BAAoC;EvE+rQ5C;EuE7rQM;;IAEE,6BAAwC;EvE+rQhD;EuE7rQM;;IAEE,8BAA0C;EvE+rQlD;EuE7rQM;;IAEE,4BAAsC;EvE+rQ9C;EuE9sQM;IAAgC,qBAA4B;EvEitQlE;EuEhtQM;;IAEE,yBAAoC;EvEktQ5C;EuEhtQM;;IAEE,2BAAwC;EvEktQhD;EuEhtQM;;IAEE,4BAA0C;EvEktQlD;EuEhtQM;;IAEE,0BAAsC;EvEktQ9C;EuEjuQM;IAAgC,2BAA4B;EvEouQlE;EuEnuQM;;IAEE,+BAAoC;EvEquQ5C;EuEnuQM;;IAEE,iCAAwC;EvEquQhD;EuEnuQM;;IAEE,kCAA0C;EvEquQlD;EuEnuQM;;IAEE,gCAAsC;EvEquQ9C;EuEpvQM;IAAgC,0BAA4B;EvEuvQlE;EuEtvQM;;IAEE,8BAAoC;EvEwvQ5C;EuEtvQM;;IAEE,gCAAwC;EvEwvQhD;EuEtvQM;;IAEE,iCAA0C;EvEwvQlD;EuEtvQM;;IAEE,+BAAsC;EvEwvQ9C;EuEvwQM;IAAgC,wBAA4B;EvE0wQlE;EuEzwQM;;IAEE,4BAAoC;EvE2wQ5C;EuEzwQM;;IAEE,8BAAwC;EvE2wQhD;EuEzwQM;;IAEE,+BAA0C;EvE2wQlD;EuEzwQM;;IAEE,6BAAsC;EvE2wQ9C;EuE1xQM;IAAgC,0BAA4B;EvE6xQlE;EuE5xQM;;IAEE,8BAAoC;EvE8xQ5C;EuE5xQM;;IAEE,gCAAwC;EvE8xQhD;EuE5xQM;;IAEE,iCAA0C;EvE8xQlD;EuE5xQM;;IAEE,+BAAsC;EvE8xQ9C;EuE7yQM;IAAgC,wBAA4B;EvEgzQlE;EuE/yQM;;IAEE,4BAAoC;EvEizQ5C;EuE/yQM;;IAEE,8BAAwC;EvEizQhD;EuE/yQM;;IAEE,+BAA0C;EvEizQlD;EuE/yQM;;IAEE,6BAAsC;EvEizQ9C;EuEzyQM;IAAwB,2BAA2B;EvE4yQzD;EuE3yQM;;IAEE,+BAA+B;EvE6yQvC;EuE3yQM;;IAEE,iCAAiC;EvE6yQzC;EuE3yQM;;IAEE,kCAAkC;EvE6yQ1C;EuE3yQM;;IAEE,gCAAgC;EvE6yQxC;EuE5zQM;IAAwB,0BAA2B;EvE+zQzD;EuE9zQM;;IAEE,8BAA+B;EvEg0QvC;EuE9zQM;;IAEE,gCAAiC;EvEg0QzC;EuE9zQM;;IAEE,iCAAkC;EvEg0Q1C;EuE9zQM;;IAEE,+BAAgC;EvEg0QxC;EuE/0QM;IAAwB,wBAA2B;EvEk1QzD;EuEj1QM;;IAEE,4BAA+B;EvEm1QvC;EuEj1QM;;IAEE,8BAAiC;EvEm1QzC;EuEj1QM;;IAEE,+BAAkC;EvEm1Q1C;EuEj1QM;;IAEE,6BAAgC;EvEm1QxC;EuEl2QM;IAAwB,0BAA2B;EvEq2QzD;EuEp2QM;;IAEE,8BAA+B;EvEs2QvC;EuEp2QM;;IAEE,gCAAiC;EvEs2QzC;EuEp2QM;;IAEE,iCAAkC;EvEs2Q1C;EuEp2QM;;IAEE,+BAAgC;EvEs2QxC;EuEr3QM;IAAwB,wBAA2B;EvEw3QzD;EuEv3QM;;IAEE,4BAA+B;EvEy3QvC;EuEv3QM;;IAEE,8BAAiC;EvEy3QzC;EuEv3QM;;IAEE,+BAAkC;EvEy3Q1C;EuEv3QM;;IAEE,6BAAgC;EvEy3QxC;EuEn3QE;IAAmB,uBAAuB;EvEs3Q5C;EuEr3QE;;IAEE,2BAA2B;EvEu3Q/B;EuEr3QE;;IAEE,6BAA6B;EvEu3QjC;EuEr3QE;;IAEE,8BAA8B;EvEu3QlC;EuEr3QE;;IAEE,4BAA4B;EvEu3QhC;AACF;;Acj4QI;EyDlDI;IAAgC,oBAA4B;EvEw7QlE;EuEv7QM;;IAEE,wBAAoC;EvEy7Q5C;EuEv7QM;;IAEE,0BAAwC;EvEy7QhD;EuEv7QM;;IAEE,2BAA0C;EvEy7QlD;EuEv7QM;;IAEE,yBAAsC;EvEy7Q9C;EuEx8QM;IAAgC,0BAA4B;EvE28QlE;EuE18QM;;IAEE,8BAAoC;EvE48Q5C;EuE18QM;;IAEE,gCAAwC;EvE48QhD;EuE18QM;;IAEE,iCAA0C;EvE48QlD;EuE18QM;;IAEE,+BAAsC;EvE48Q9C;EuE39QM;IAAgC,yBAA4B;EvE89QlE;EuE79QM;;IAEE,6BAAoC;EvE+9Q5C;EuE79QM;;IAEE,+BAAwC;EvE+9QhD;EuE79QM;;IAEE,gCAA0C;EvE+9QlD;EuE79QM;;IAEE,8BAAsC;EvE+9Q9C;EuE9+QM;IAAgC,uBAA4B;EvEi/QlE;EuEh/QM;;IAEE,2BAAoC;EvEk/Q5C;EuEh/QM;;IAEE,6BAAwC;EvEk/QhD;EuEh/QM;;IAEE,8BAA0C;EvEk/QlD;EuEh/QM;;IAEE,4BAAsC;EvEk/Q9C;EuEjgRM;IAAgC,yBAA4B;EvEogRlE;EuEngRM;;IAEE,6BAAoC;EvEqgR5C;EuEngRM;;IAEE,+BAAwC;EvEqgRhD;EuEngRM;;IAEE,gCAA0C;EvEqgRlD;EuEngRM;;IAEE,8BAAsC;EvEqgR9C;EuEphRM;IAAgC,uBAA4B;EvEuhRlE;EuEthRM;;IAEE,2BAAoC;EvEwhR5C;EuEthRM;;IAEE,6BAAwC;EvEwhRhD;EuEthRM;;IAEE,8BAA0C;EvEwhRlD;EuEthRM;;IAEE,4BAAsC;EvEwhR9C;EuEviRM;IAAgC,qBAA4B;EvE0iRlE;EuEziRM;;IAEE,yBAAoC;EvE2iR5C;EuEziRM;;IAEE,2BAAwC;EvE2iRhD;EuEziRM;;IAEE,4BAA0C;EvE2iRlD;EuEziRM;;IAEE,0BAAsC;EvE2iR9C;EuE1jRM;IAAgC,2BAA4B;EvE6jRlE;EuE5jRM;;IAEE,+BAAoC;EvE8jR5C;EuE5jRM;;IAEE,iCAAwC;EvE8jRhD;EuE5jRM;;IAEE,kCAA0C;EvE8jRlD;EuE5jRM;;IAEE,gCAAsC;EvE8jR9C;EuE7kRM;IAAgC,0BAA4B;EvEglRlE;EuE/kRM;;IAEE,8BAAoC;EvEilR5C;EuE/kRM;;IAEE,gCAAwC;EvEilRhD;EuE/kRM;;IAEE,iCAA0C;EvEilRlD;EuE/kRM;;IAEE,+BAAsC;EvEilR9C;EuEhmRM;IAAgC,wBAA4B;EvEmmRlE;EuElmRM;;IAEE,4BAAoC;EvEomR5C;EuElmRM;;IAEE,8BAAwC;EvEomRhD;EuElmRM;;IAEE,+BAA0C;EvEomRlD;EuElmRM;;IAEE,6BAAsC;EvEomR9C;EuEnnRM;IAAgC,0BAA4B;EvEsnRlE;EuErnRM;;IAEE,8BAAoC;EvEunR5C;EuErnRM;;IAEE,gCAAwC;EvEunRhD;EuErnRM;;IAEE,iCAA0C;EvEunRlD;EuErnRM;;IAEE,+BAAsC;EvEunR9C;EuEtoRM;IAAgC,wBAA4B;EvEyoRlE;EuExoRM;;IAEE,4BAAoC;EvE0oR5C;EuExoRM;;IAEE,8BAAwC;EvE0oRhD;EuExoRM;;IAEE,+BAA0C;EvE0oRlD;EuExoRM;;IAEE,6BAAsC;EvE0oR9C;EuEloRM;IAAwB,2BAA2B;EvEqoRzD;EuEpoRM;;IAEE,+BAA+B;EvEsoRvC;EuEpoRM;;IAEE,iCAAiC;EvEsoRzC;EuEpoRM;;IAEE,kCAAkC;EvEsoR1C;EuEpoRM;;IAEE,gCAAgC;EvEsoRxC;EuErpRM;IAAwB,0BAA2B;EvEwpRzD;EuEvpRM;;IAEE,8BAA+B;EvEypRvC;EuEvpRM;;IAEE,gCAAiC;EvEypRzC;EuEvpRM;;IAEE,iCAAkC;EvEypR1C;EuEvpRM;;IAEE,+BAAgC;EvEypRxC;EuExqRM;IAAwB,wBAA2B;EvE2qRzD;EuE1qRM;;IAEE,4BAA+B;EvE4qRvC;EuE1qRM;;IAEE,8BAAiC;EvE4qRzC;EuE1qRM;;IAEE,+BAAkC;EvE4qR1C;EuE1qRM;;IAEE,6BAAgC;EvE4qRxC;EuE3rRM;IAAwB,0BAA2B;EvE8rRzD;EuE7rRM;;IAEE,8BAA+B;EvE+rRvC;EuE7rRM;;IAEE,gCAAiC;EvE+rRzC;EuE7rRM;;IAEE,iCAAkC;EvE+rR1C;EuE7rRM;;IAEE,+BAAgC;EvE+rRxC;EuE9sRM;IAAwB,wBAA2B;EvEitRzD;EuEhtRM;;IAEE,4BAA+B;EvEktRvC;EuEhtRM;;IAEE,8BAAiC;EvEktRzC;EuEhtRM;;IAEE,+BAAkC;EvEktR1C;EuEhtRM;;IAEE,6BAAgC;EvEktRxC;EuE5sRE;IAAmB,uBAAuB;EvE+sR5C;EuE9sRE;;IAEE,2BAA2B;EvEgtR/B;EuE9sRE;;IAEE,6BAA6B;EvEgtRjC;EuE9sRE;;IAEE,8BAA8B;EvEgtRlC;EuE9sRE;;IAEE,4BAA4B;EvEgtRhC;AACF;;Ac1tRI;EyDlDI;IAAgC,oBAA4B;EvEixRlE;EuEhxRM;;IAEE,wBAAoC;EvEkxR5C;EuEhxRM;;IAEE,0BAAwC;EvEkxRhD;EuEhxRM;;IAEE,2BAA0C;EvEkxRlD;EuEhxRM;;IAEE,yBAAsC;EvEkxR9C;EuEjyRM;IAAgC,0BAA4B;EvEoyRlE;EuEnyRM;;IAEE,8BAAoC;EvEqyR5C;EuEnyRM;;IAEE,gCAAwC;EvEqyRhD;EuEnyRM;;IAEE,iCAA0C;EvEqyRlD;EuEnyRM;;IAEE,+BAAsC;EvEqyR9C;EuEpzRM;IAAgC,yBAA4B;EvEuzRlE;EuEtzRM;;IAEE,6BAAoC;EvEwzR5C;EuEtzRM;;IAEE,+BAAwC;EvEwzRhD;EuEtzRM;;IAEE,gCAA0C;EvEwzRlD;EuEtzRM;;IAEE,8BAAsC;EvEwzR9C;EuEv0RM;IAAgC,uBAA4B;EvE00RlE;EuEz0RM;;IAEE,2BAAoC;EvE20R5C;EuEz0RM;;IAEE,6BAAwC;EvE20RhD;EuEz0RM;;IAEE,8BAA0C;EvE20RlD;EuEz0RM;;IAEE,4BAAsC;EvE20R9C;EuE11RM;IAAgC,yBAA4B;EvE61RlE;EuE51RM;;IAEE,6BAAoC;EvE81R5C;EuE51RM;;IAEE,+BAAwC;EvE81RhD;EuE51RM;;IAEE,gCAA0C;EvE81RlD;EuE51RM;;IAEE,8BAAsC;EvE81R9C;EuE72RM;IAAgC,uBAA4B;EvEg3RlE;EuE/2RM;;IAEE,2BAAoC;EvEi3R5C;EuE/2RM;;IAEE,6BAAwC;EvEi3RhD;EuE/2RM;;IAEE,8BAA0C;EvEi3RlD;EuE/2RM;;IAEE,4BAAsC;EvEi3R9C;EuEh4RM;IAAgC,qBAA4B;EvEm4RlE;EuEl4RM;;IAEE,yBAAoC;EvEo4R5C;EuEl4RM;;IAEE,2BAAwC;EvEo4RhD;EuEl4RM;;IAEE,4BAA0C;EvEo4RlD;EuEl4RM;;IAEE,0BAAsC;EvEo4R9C;EuEn5RM;IAAgC,2BAA4B;EvEs5RlE;EuEr5RM;;IAEE,+BAAoC;EvEu5R5C;EuEr5RM;;IAEE,iCAAwC;EvEu5RhD;EuEr5RM;;IAEE,kCAA0C;EvEu5RlD;EuEr5RM;;IAEE,gCAAsC;EvEu5R9C;EuEt6RM;IAAgC,0BAA4B;EvEy6RlE;EuEx6RM;;IAEE,8BAAoC;EvE06R5C;EuEx6RM;;IAEE,gCAAwC;EvE06RhD;EuEx6RM;;IAEE,iCAA0C;EvE06RlD;EuEx6RM;;IAEE,+BAAsC;EvE06R9C;EuEz7RM;IAAgC,wBAA4B;EvE47RlE;EuE37RM;;IAEE,4BAAoC;EvE67R5C;EuE37RM;;IAEE,8BAAwC;EvE67RhD;EuE37RM;;IAEE,+BAA0C;EvE67RlD;EuE37RM;;IAEE,6BAAsC;EvE67R9C;EuE58RM;IAAgC,0BAA4B;EvE+8RlE;EuE98RM;;IAEE,8BAAoC;EvEg9R5C;EuE98RM;;IAEE,gCAAwC;EvEg9RhD;EuE98RM;;IAEE,iCAA0C;EvEg9RlD;EuE98RM;;IAEE,+BAAsC;EvEg9R9C;EuE/9RM;IAAgC,wBAA4B;EvEk+RlE;EuEj+RM;;IAEE,4BAAoC;EvEm+R5C;EuEj+RM;;IAEE,8BAAwC;EvEm+RhD;EuEj+RM;;IAEE,+BAA0C;EvEm+RlD;EuEj+RM;;IAEE,6BAAsC;EvEm+R9C;EuE39RM;IAAwB,2BAA2B;EvE89RzD;EuE79RM;;IAEE,+BAA+B;EvE+9RvC;EuE79RM;;IAEE,iCAAiC;EvE+9RzC;EuE79RM;;IAEE,kCAAkC;EvE+9R1C;EuE79RM;;IAEE,gCAAgC;EvE+9RxC;EuE9+RM;IAAwB,0BAA2B;EvEi/RzD;EuEh/RM;;IAEE,8BAA+B;EvEk/RvC;EuEh/RM;;IAEE,gCAAiC;EvEk/RzC;EuEh/RM;;IAEE,iCAAkC;EvEk/R1C;EuEh/RM;;IAEE,+BAAgC;EvEk/RxC;EuEjgSM;IAAwB,wBAA2B;EvEogSzD;EuEngSM;;IAEE,4BAA+B;EvEqgSvC;EuEngSM;;IAEE,8BAAiC;EvEqgSzC;EuEngSM;;IAEE,+BAAkC;EvEqgS1C;EuEngSM;;IAEE,6BAAgC;EvEqgSxC;EuEphSM;IAAwB,0BAA2B;EvEuhSzD;EuEthSM;;IAEE,8BAA+B;EvEwhSvC;EuEthSM;;IAEE,gCAAiC;EvEwhSzC;EuEthSM;;IAEE,iCAAkC;EvEwhS1C;EuEthSM;;IAEE,+BAAgC;EvEwhSxC;EuEviSM;IAAwB,wBAA2B;EvE0iSzD;EuEziSM;;IAEE,4BAA+B;EvE2iSvC;EuEziSM;;IAEE,8BAAiC;EvE2iSzC;EuEziSM;;IAEE,+BAAkC;EvE2iS1C;EuEziSM;;IAEE,6BAAgC;EvE2iSxC;EuEriSE;IAAmB,uBAAuB;EvEwiS5C;EuEviSE;;IAEE,2BAA2B;EvEyiS/B;EuEviSE;;IAEE,6BAA6B;EvEyiSjC;EuEviSE;;IAEE,8BAA8B;EvEyiSlC;EuEviSE;;IAEE,4BAA4B;EvEyiShC;AACF;;AwE3mSA;EAEI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,OAAO;EACP,UAAU;EAEV,oBAAoB;EACpB,WAAW;EAEX,kCAAkC;AxE2mStC;;AyErnSA;EAAkB,4GAA8C;AzEynShE;;AyErnSA;EAAiB,8BAA8B;AzEynS/C;;AyExnSA;EAAiB,8BAA8B;AzE4nS/C;;AyE3nSA;EAAiB,8BAA8B;AzE+nS/C;;AyE9nSA;ECTE,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;A1E2oSrB;;AyE5nSI;EAAwB,2BAA2B;AzEgoSvD;;AyE/nSI;EAAwB,4BAA4B;AzEmoSxD;;AyEloSI;EAAwB,6BAA6B;AzEsoSzD;;AcjmSI;E2DvCA;IAAwB,2BAA2B;EzE6oSrD;EyE5oSE;IAAwB,4BAA4B;EzE+oStD;EyE9oSE;IAAwB,6BAA6B;EzEipSvD;AACF;;Ac7mSI;E2DvCA;IAAwB,2BAA2B;EzEypSrD;EyExpSE;IAAwB,4BAA4B;EzE2pStD;EyE1pSE;IAAwB,6BAA6B;EzE6pSvD;AACF;;AcznSI;E2DvCA;IAAwB,2BAA2B;EzEqqSrD;EyEpqSE;IAAwB,4BAA4B;EzEuqStD;EyEtqSE;IAAwB,6BAA6B;EzEyqSvD;AACF;;AcroSI;E2DvCA;IAAwB,2BAA2B;EzEirSrD;EyEhrSE;IAAwB,4BAA4B;EzEmrStD;EyElrSE;IAAwB,6BAA6B;EzEqrSvD;AACF;;AyEhrSA;EAAmB,oCAAoC;AzEorSvD;;AyEnrSA;EAAmB,oCAAoC;AzEurSvD;;AyEtrSA;EAAmB,qCAAqC;AzE0rSxD;;AyEtrSA;EAAuB,2BAA0C;AzE0rSjE;;AyEzrSA;EAAuB,+BAA4C;AzE6rSnE;;AyE5rSA;EAAuB,2BAA2C;AzEgsSlE;;AyE/rSA;EAAuB,2BAAyC;AzEmsShE;;AyElsSA;EAAuB,8BAA2C;AzEssSlE;;AyErsSA;EAAuB,6BAA6B;AzEysSpD;;AyErsSA;EAAc,sBAAwB;AzEysStC;;A2EhvSE;EACE,yBAAwB;A3EmvS5B;;AKzuSE;EsELM,yBAA0E;A3EkvSlF;;A2ExvSE;EACE,yBAAwB;A3E2vS5B;;AKjvSE;EsELM,yBAA0E;A3E0vSlF;;A2EhwSE;EACE,yBAAwB;A3EmwS5B;;AKzvSE;EsELM,yBAA0E;A3EkwSlF;;A2ExwSE;EACE,yBAAwB;A3E2wS5B;;AKjwSE;EsELM,yBAA0E;A3E0wSlF;;A2EhxSE;EACE,yBAAwB;A3EmxS5B;;AKzwSE;EsELM,yBAA0E;A3EkxSlF;;A2ExxSE;EACE,yBAAwB;A3E2xS5B;;AKjxSE;EsELM,yBAA0E;A3E0xSlF;;A2EhySE;EACE,yBAAwB;A3EmyS5B;;AKzxSE;EsELM,yBAA0E;A3EkySlF;;A2ExySE;EACE,yBAAwB;A3E2yS5B;;AKjySE;EsELM,yBAA0E;A3E0ySlF;;AyEnwSA;EAAa,yBAA6B;AzEuwS1C;;AyEtwSA;EAAc,yBAA6B;AzE0wS3C;;AyExwSA;EAAiB,oCAAkC;AzE4wSnD;;AyE3wSA;EAAiB,0CAAkC;AzE+wSnD;;AyE3wSA;EGvDE,WAAW;EACX,kBAAkB;EAClB,iBAAiB;EACjB,6BAA6B;EAC7B,SAAS;A5Es0SX;;AyE/wSA;EAAwB,gCAAgC;AzEmxSxD;;AyEjxSA;EACE,iCAAiC;EACjC,gCAAgC;AzEoxSlC;;AyE/wSA;EAAc,yBAAyB;AzEmxSvC;;A6Ep1SA;EACE,8BAA8B;A7Eu1ShC;;A6Ep1SA;EACE,6BAA6B;A7Eu1S/B;;A8Ev1SE;E5EOF;;;I4EDM,4BAA4B;IAE5B,2BAA2B;E9Eu1S/B;E8Ep1SE;IAEI,0BAA0B;E9Eq1ShC;E8E50SE;IACE,6BAA6B;E9E80SjC;EEhpSF;I4E/KM,gCAAgC;E9Ek0SpC;E8Eh0SE;;IAEE,yB3EzCY;I2E0CZ,wBAAwB;E9Ek0S5B;E8E1zSE;IACE,2BAA2B;E9E4zS/B;E8EzzSE;;IAEE,wBAAwB;E9E2zS5B;E8ExzSE;;;IAGE,UAAU;IACV,SAAS;E9E0zSb;E8EvzSE;;IAEE,uBAAuB;E9EyzS3B;E8EjzSE;IACE,Q3E2hCgC;EHwxQpC;EE/1SF;I4E+CM,2BAA2C;E9EmzS/C;E8EjzSE;IACE,2BAA2C;E9EmzS/C;EiCj4SF;I6CmFM,aAAa;E9EizSjB;EsCh5SF;IwCkGM,sB3EtFS;EHu4Sb;EgBp5SF;I8DuGM,oCAAoC;E9EgzSxC;E8EjzSE;;IAKI,iCAAmC;E9EgzSzC;EgBn3SF;;I8D0EQ,oCAAsC;E9E6yS5C;EgBlySF;I8DNM,cAAc;E9E2ySlB;EiBj6SA;;;;I6D4HM,qB3EvHU;EHk6ShB;EgB7zSF;I8DuBM,cAAc;IACd,qB3E7HY;EHs6ShB;AACF","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"code\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"input-group\";\n@import \"custom-forms\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"jumbotron\";\n@import \"alert\";\n@import \"progress\";\n@import \"media\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"utilities\";\n@import \"print\";\n","/*!\n * Bootstrap v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-wrap: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n color: #212529;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n color: #212529;\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #343a40;\n border-color: #454d55;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #454d55;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\ninput[type=\"date\"].form-control,\ninput[type=\"time\"].form-control,\ninput[type=\"datetime-local\"].form-control,\ninput[type=\"month\"].form-control {\n appearance: none;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: 0.375rem 0;\n margin-bottom: 0;\n font-size: 1rem;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(1.5em + 1rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input[disabled] ~ .form-check-label,\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n text-decoration: none;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n min-width: 0;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(1.5em + 1rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.5em + 0.5rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n color-adjust: exact;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1;\n width: 1rem;\n height: 1.25rem;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background: no-repeat 50% / 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n display: none;\n}\n\n.custom-select:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.custom-select-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(1.5em + 1rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input[disabled] ~ .custom-file-label,\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(1.5em + 0.75rem);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: 1.4rem;\n padding: 0;\n background-color: transparent;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: none;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar .container,\n.navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n}\n\n.card > .list-group:first-child {\n border-top-width: 0;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card > .list-group:last-child {\n border-bottom-width: 0;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n border-top: 0;\n}\n\n.card-body {\n flex: 1 1 auto;\n min-height: 1px;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0;\n width: 100%;\n}\n\n.card-img,\n.card-img-top {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n display: flex;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n flex: 1 0 0%;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n display: flex;\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion {\n overflow-anchor: none;\n}\n\n.accordion > .card {\n overflow: hidden;\n}\n\n.accordion > .card:not(:last-of-type) {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion > .card:not(:first-of-type) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion > .card > .card-header {\n border-radius: 0;\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item {\n display: flex;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 3;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 3;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .badge {\n transition: none;\n }\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\na.badge-primary:focus, a.badge-primary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\na.badge-secondary:focus, a.badge-secondary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\na.badge-success:focus, a.badge-success.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\na.badge-info:focus, a.badge-info.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\na.badge-warning:focus, a.badge-warning.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\na.badge-danger:focus, a.badge-danger.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\na.badge-light:focus, a.badge-light.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\na.badge-dark:focus, a.badge-dark.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n line-height: 0;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n animation: none;\n }\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n border-radius: 0.25rem;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n\n.list-group-item:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-item + .list-group-item {\n border-top-width: 0;\n}\n\n.list-group-item + .list-group-item.active {\n margin-top: -1px;\n border-top-width: 1px;\n}\n\n.list-group-horizontal {\n flex-direction: row;\n}\n\n.list-group-horizontal > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item.active {\n margin-top: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n flex-direction: row;\n }\n .list-group-horizontal-sm > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n flex-direction: row;\n }\n .list-group-horizontal-md > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n flex-direction: row;\n }\n .list-group-horizontal-lg > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n flex-direction: row;\n }\n .list-group-horizontal-xl > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n.list-group-flush {\n border-radius: 0;\n}\n\n.list-group-flush > .list-group-item {\n border-width: 0 0 1px;\n}\n\n.list-group-flush > .list-group-item:last-child {\n border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n flex-basis: 350px;\n max-width: 350px;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n opacity: 0;\n border-radius: 0.25rem;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -50px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n transform: none;\n}\n\n.modal.modal-static .modal-dialog {\n transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n display: flex;\n max-height: calc(100% - 1rem);\n}\n\n.modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 1rem);\n overflow: hidden;\n}\n\n.modal-dialog-scrollable .modal-header,\n.modal-dialog-scrollable .modal-footer {\n flex-shrink: 0;\n}\n\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - 1rem);\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - 1rem);\n height: min-content;\n content: \"\";\n}\n\n.modal-dialog-centered.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable .modal-content {\n max-height: none;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable::before {\n content: none;\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #dee2e6;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n padding: 0.75rem;\n border-top: 1px solid #dee2e6;\n border-bottom-right-radius: calc(0.3rem - 1px);\n border-bottom-left-radius: calc(0.3rem - 1px);\n}\n\n.modal-footer > * {\n margin: 0.25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-scrollable {\n max-height: calc(100% - 3.5rem);\n }\n .modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 3.5rem);\n }\n .modal-dialog-centered {\n min-height: calc(100% - 3.5rem);\n }\n .modal-dialog-centered::before {\n height: calc(100vh - 3.5rem);\n height: min-content;\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=\"top\"] > .arrow {\n bottom: calc(-0.5rem - 1px);\n}\n\n.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=\"top\"] > .arrow::before {\n bottom: 0;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=\"top\"] > .arrow::after {\n bottom: 1px;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=\"right\"] > .arrow {\n left: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=\"right\"] > .arrow::before {\n left: 0;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=\"right\"] > .arrow::after {\n left: 1px;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow {\n top: calc(-0.5rem - 1px);\n}\n\n.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::before {\n top: 0;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::after {\n top: 1px;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=\"left\"] > .arrow {\n right: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=\"left\"] > .arrow::before {\n right: 0;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=\"left\"] > .arrow::after {\n right: 1px;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n transition: transform 0.6s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: opacity 0s 0.6s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: no-repeat 50% / 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@keyframes spinner-border {\n to {\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded-sm {\n border-radius: 0.2rem !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-lg {\n border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.user-select-all {\n user-select: all !important;\n}\n\n.user-select-auto {\n user-select: auto !important;\n}\n\n.user-select-none {\n user-select: none !important;\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n pointer-events: auto;\n content: \"\";\n background-color: rgba(0, 0, 0, 0);\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !important;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-break {\n word-break: break-word !important;\n word-wrap: break-word !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// Do not forget to update getting-started/theming.md!\n:root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n$grid-row-columns: 6 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n$table-th-font-weight: null !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height-lg * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n$custom-control-cursor: null !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-label-color: null !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: null !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: null !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/></svg>\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'><path stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/></svg>\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: null !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'><circle r='3' fill='#{$custom-control-indicator-checked-color}'/></svg>\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>\") !default;\n$custom-select-background: escape-svg($custom-select-indicator) no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n\n$form-validation-states: () !default;\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-100 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-600 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-font-size: null !default;\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n$user-selects: all, auto, none !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable declaration-no-important, selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { @include font-size($h1-font-size); }\nh2, .h2 { @include font-size($h2-font-size); }\nh3, .h3 { @include font-size($h3-font-size); }\nh4, .h4 { @include font-size($h4-font-size); }\nh5, .h5 { @include font-size($h5-font-size); }\nh6, .h6 { @include font-size($h6-font-size); }\n\n.lead {\n @include font-size($lead-font-size);\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n @include font-size($display1-size);\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n @include font-size($display2-size);\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n @include font-size($display3-size);\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n @include font-size($display4-size);\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n @include font-size($small-font-size);\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled();\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled();\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n @include font-size(90%);\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n @include font-size($blockquote-font-size);\n}\n\n.blockquote-footer {\n display: block;\n @include font-size($blockquote-small-font-size);\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014\\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled() {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid();\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid();\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: $spacer / 2;\n line-height: 1;\n}\n\n.figure-caption {\n @include font-size($figure-caption-font-size);\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid() {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/#feat=css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n @include deprecate(\"`img-retina()`\", \"v4.3.0\", \"v5\");\n}\n","// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n $return: ();\n @each $value in $radius {\n @if type-of($value) == number {\n $return: append($return, max($value, 0));\n } @else {\n $return: append($return, $value);\n }\n }\n @return $return;\n}\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: valid-radius($radius);\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n","// Inline code\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n @include font-size(100%);\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n margin-bottom: $spacer;\n color: $table-color;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: 2 * $table-border-width;\n }\n }\n}\n\n.table-borderless {\n th,\n td,\n thead th,\n tbody + tbody {\n border: 0;\n }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover() {\n color: $table-hover-color;\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover() {\n color: $table-dark-hover-color;\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background, $border: null) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n\n @if $border != null {\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $border;\n }\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover() {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// Bootstrap functions\n//\n// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.\n\n// Ascending\n// Used to evaluate Sass maps like our grid breakpoints.\n@mixin _assert-ascending($map, $map-name) {\n $prev-key: null;\n $prev-num: null;\n @each $key, $num in $map {\n @if $prev-num == null or unit($num) == \"%\" or unit($prev-num) == \"%\" {\n // Do nothing\n } @else if not comparable($prev-num, $num) {\n @warn \"Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n } @else if $prev-num >= $num {\n @warn \"Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n }\n $prev-key: $key;\n $prev-num: $num;\n }\n}\n\n// Starts at zero\n// Used to ensure the min-width of the lowest breakpoint starts at 0.\n@mixin _assert-starts-at-zero($map, $map-name: \"$grid-breakpoints\") {\n @if length($map) > 0 {\n $values: map-values($map);\n $first-value: nth($values, 1);\n @if $first-value != 0 {\n @warn \"First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.\";\n }\n }\n}\n\n// Replace `$search` with `$replace` in `$string`\n// Used on our SVG icon backgrounds for custom forms.\n//\n// @author Hugo Giraudel\n// @param {String} $string - Initial string\n// @param {String} $search - Substring to replace\n// @param {String} $replace ('') - New value\n// @return {String} - Updated string\n@function str-replace($string, $search, $replace: \"\") {\n $index: str-index($string, $search);\n\n @if $index {\n @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);\n }\n\n @return $string;\n}\n\n// See https://codepen.io/kevinweber/pen/dXWoRw\n//\n// Requires the use of quotes around data URIs.\n\n@function escape-svg($string) {\n @if str-index($string, \"data:image/svg+xml\") {\n @each $char, $encoded in $escaped-characters {\n // Do not escape the url brackets\n @if str-index($string, \"url(\") == 1 {\n $string: url(\"#{str-replace(str-slice($string, 6, -3), $char, $encoded)}\");\n } @else {\n $string: str-replace($string, $char, $encoded);\n }\n }\n }\n\n @return $string;\n}\n\n// Color contrast\n@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {\n $r: red($color);\n $g: green($color);\n $b: blue($color);\n\n $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;\n\n @if ($yiq >= $yiq-contrasted-threshold) {\n @return $dark;\n } @else {\n @return $light;\n }\n}\n\n// Retrieve color Sass maps\n@function color($key: \"blue\") {\n @return map-get($colors, $key);\n}\n\n@function theme-color($key: \"primary\") {\n @return map-get($theme-colors, $key);\n}\n\n@function gray($key: \"100\") {\n @return map-get($grays, $key);\n}\n\n// Request a theme color level\n@function theme-color-level($color-name: \"primary\", $level: 0) {\n $color: theme-color($color-name);\n $color-base: if($level > 0, $black, $white);\n $level: abs($level);\n\n @return mix($color-base, $color, $level * $theme-color-interval);\n}\n\n// Return valid calc\n@function add($value1, $value2, $return-calc: true) {\n @if $value1 == null {\n @return $value2;\n }\n\n @if $value2 == null {\n @return $value1;\n }\n\n @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n @return $value1 + $value2;\n }\n\n @return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(\" + \") + $value2);\n}\n\n@function subtract($value1, $value2, $return-calc: true) {\n @if $value1 == null and $value2 == null {\n @return null;\n }\n\n @if $value1 == null {\n @return -$value2;\n }\n\n @if $value2 == null {\n @return $value1;\n }\n\n @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n @return $value1 - $value2;\n }\n\n @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(\" - \") + $value2);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n height: $input-height;\n padding: $input-padding-y $input-padding-x;\n font-family: $input-font-family;\n @include font-size($input-font-size);\n font-weight: $input-font-weight;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n @include border-radius($input-border-radius, 0);\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n background-color: transparent;\n border: 0;\n }\n\n // Remove select outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $input-color;\n }\n\n // Customize the `:focus` state to imitate native WebKit styles.\n @include form-control-focus($ignore-warning: true);\n\n // Placeholder\n &::placeholder {\n color: $input-placeholder-color;\n // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n opacity: 1;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &:disabled,\n &[readonly] {\n background-color: $input-disabled-bg;\n // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n opacity: 1;\n }\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n &.form-control {\n appearance: none; // Fix appearance for date inputs in Safari\n }\n}\n\nselect.form-control {\n &:focus::-ms-value {\n // Suppress the nested default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: add($input-padding-y, $input-border-width);\n padding-bottom: add($input-padding-y, $input-border-width);\n margin-bottom: 0; // Override the `<label>/<legend>` default\n @include font-size(inherit); // Override the `<legend>` default\n line-height: $input-line-height;\n}\n\n.col-form-label-lg {\n padding-top: add($input-padding-y-lg, $input-border-width);\n padding-bottom: add($input-padding-y-lg, $input-border-width);\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n}\n\n.col-form-label-sm {\n padding-top: add($input-padding-y-sm, $input-border-width);\n padding-bottom: add($input-padding-y-sm, $input-border-width);\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n}\n\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: $input-padding-y 0;\n margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n @include font-size($input-font-size);\n line-height: $input-line-height;\n color: $input-plaintext-color;\n background-color: transparent;\n border: solid transparent;\n border-width: $input-border-width 0;\n\n &.form-control-sm,\n &.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n height: $input-height-sm;\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.form-control-lg {\n height: $input-height-lg;\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n// stylelint-disable-next-line no-duplicate-selectors\nselect.form-control {\n &[size],\n &[multiple] {\n height: auto;\n }\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: $form-group-margin-bottom;\n}\n\n.form-text {\n display: block;\n margin-top: $form-text-margin-top;\n}\n\n\n// Form grid\n//\n// Special replacement for our grid system's `.row` for tighter form layouts.\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$form-grid-gutter-width / 2;\n margin-left: -$form-grid-gutter-width / 2;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: $form-grid-gutter-width / 2;\n padding-left: $form-grid-gutter-width / 2;\n }\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.form-check {\n position: relative;\n display: block;\n padding-left: $form-check-input-gutter;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: $form-check-input-margin-y;\n margin-left: -$form-check-input-gutter;\n\n // Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .form-check-label,\n &:disabled ~ .form-check-label {\n color: $text-muted;\n }\n}\n\n.form-check-label {\n margin-bottom: 0; // Override default `<label>` bottom margin\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0; // Override base .form-check\n margin-right: $form-check-inline-margin-x;\n\n // Undo .form-check-input defaults and add some `margin-right`.\n .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: $form-check-inline-input-margin-x;\n margin-left: 0;\n }\n}\n\n\n// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server side validation.\n\n@each $state, $data in $form-validation-states {\n @include form-validation-state($state, map-get($data, color), map-get($data, icon));\n}\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)\n\n // Because we use flex, the initial sizing of checkboxes is collapsed and\n // doesn't occupy the full-width (which is what we want for xs grid tier),\n // so we force that here.\n .form-check {\n width: 100%;\n }\n\n // Kick in the inline\n @include media-breakpoint-up(sm) {\n label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n\n // Inline-block all the things for \"inline\"\n .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n\n // Allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-plaintext {\n display: inline-block;\n }\n\n .input-group,\n .custom-select {\n width: auto;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: $form-check-input-margin-x;\n margin-left: 0;\n }\n\n .custom-control {\n align-items: center;\n justify-content: center;\n }\n .custom-control-label {\n margin-bottom: 0;\n }\n }\n}\n","// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n @if length($transition) == 0 {\n $transition: $transition-base;\n }\n\n @if length($transition) > 1 {\n @each $value in $transition {\n @if $value == null or $value == none {\n @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n }\n }\n }\n\n @if $enable-transitions {\n @if nth($transition, 1) != null {\n transition: $transition;\n }\n\n @if $enable-prefers-reduced-motion-media-query and nth($transition, 1) != null and nth($transition, 1) != none {\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n }\n}\n","// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `$input-focus-border-color` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n@mixin form-control-focus($ignore-warning: false) {\n &:focus {\n color: $input-focus-color;\n background-color: $input-focus-bg;\n border-color: $input-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($input-box-shadow, $input-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $input-focus-box-shadow;\n }\n }\n @include deprecate(\"The `form-control-focus()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n// This mixin uses an `if()` technique to be compatible with Dart Sass\n// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details\n@mixin form-validation-state-selector($state) {\n @if ($state == \"valid\" or $state == \"invalid\") {\n .was-validated #{if(&, \"&\", \"\")}:#{$state},\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n } @else {\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n }\n}\n\n@mixin form-validation-state($state, $color, $icon) {\n .#{$state}-feedback {\n display: none;\n width: 100%;\n margin-top: $form-feedback-margin-top;\n @include font-size($form-feedback-font-size);\n color: $color;\n }\n\n .#{$state}-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%; // Contain to parent when possible\n padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n margin-top: .1rem;\n @include font-size($form-feedback-tooltip-font-size);\n line-height: $form-feedback-tooltip-line-height;\n color: color-yiq($color);\n background-color: rgba($color, $form-feedback-tooltip-opacity);\n @include border-radius($form-feedback-tooltip-border-radius);\n }\n\n @include form-validation-state-selector($state) {\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n\n .form-control {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-image: escape-svg($icon);\n background-repeat: no-repeat;\n background-position: right $input-height-inner-quarter center;\n background-size: $input-height-inner-half $input-height-inner-half;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n // stylelint-disable-next-line selector-no-qualifying-type\n textarea.form-control {\n @include form-validation-state-selector($state) {\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n }\n }\n }\n\n .custom-select {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $custom-select-feedback-icon-padding-right;\n background: $custom-select-background, escape-svg($icon) $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n .form-check-input {\n @include form-validation-state-selector($state) {\n ~ .form-check-label {\n color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .custom-control-input {\n @include form-validation-state-selector($state) {\n ~ .custom-control-label {\n color: $color;\n\n &::before {\n border-color: $color;\n }\n }\n\n &:checked {\n ~ .custom-control-label::before {\n border-color: lighten($color, 10%);\n @include gradient-bg(lighten($color, 10%));\n }\n }\n\n &:focus {\n ~ .custom-control-label::before {\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n &:not(:checked) ~ .custom-control-label::before {\n border-color: $color;\n }\n }\n }\n }\n\n // custom file\n .custom-file-input {\n @include form-validation-state-selector($state) {\n ~ .custom-file-label {\n border-color: $color;\n }\n\n &:focus {\n ~ .custom-file-label {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.btn {\n display: inline-block;\n font-family: $btn-font-family;\n font-weight: $btn-font-weight;\n color: $body-color;\n text-align: center;\n text-decoration: if($link-decoration == none, null, none);\n white-space: $btn-white-space;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: $btn-border-width solid transparent;\n @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);\n @include transition($btn-transition);\n\n @include hover() {\n color: $body-color;\n text-decoration: none;\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: $btn-focus-box-shadow;\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n opacity: $btn-disabled-opacity;\n @include box-shadow(none);\n }\n\n &:not(:disabled):not(.disabled) {\n cursor: if($enable-pointer-cursor-for-buttons, pointer, null);\n\n &:active,\n &.active {\n @include box-shadow($btn-active-box-shadow);\n\n &:focus {\n @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n }\n }\n }\n}\n\n// Future-proof disabling of clicks on `<a>` elements\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n\n//\n// Alternate buttons\n//\n\n@each $color, $value in $theme-colors {\n .btn-#{$color} {\n @include button-variant($value, $value);\n }\n}\n\n@each $color, $value in $theme-colors {\n .btn-outline-#{$color} {\n @include button-outline-variant($value);\n }\n}\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n font-weight: $font-weight-normal;\n color: $link-color;\n text-decoration: $link-decoration;\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n\n &:focus,\n &.focus {\n text-decoration: $link-hover-decoration;\n }\n\n &:disabled,\n &.disabled {\n color: $btn-link-disabled-color;\n pointer-events: none;\n }\n\n // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);\n}\n\n\n//\n// Block button\n//\n\n.btn-block {\n display: block;\n width: 100%;\n\n // Vertically space out multiple block buttons\n + .btn-block {\n margin-top: $btn-block-spacing-y;\n }\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {\n color: color-yiq($background);\n @include gradient-bg($background);\n border-color: $border;\n @include box-shadow($btn-box-shadow);\n\n @include hover() {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n }\n\n &:focus,\n &.focus {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n @if $enable-shadows {\n @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n color: color-yiq($background);\n background-color: $background;\n border-color: $border;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n @if $enable-gradients {\n background-image: none; // Remove the gradient for the pressed/active state\n }\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n }\n}\n\n@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {\n color: $color;\n border-color: $color;\n\n @include hover() {\n color: $color-hover;\n background-color: $active-background;\n border-color: $active-border;\n }\n\n &:focus,\n &.focus {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n\n &.disabled,\n &:disabled {\n color: $color;\n background-color: transparent;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n }\n }\n}\n\n// Button sizes\n@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n // Manually declare to provide an override to the browser default\n @include border-radius($border-radius, 0);\n}\n",".fade {\n @include transition($transition-fade);\n\n &:not(.show) {\n opacity: 0;\n }\n}\n\n.collapse {\n &:not(.show) {\n display: none;\n }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n @include transition($transition-collapse);\n}\n","// The dropdown wrapper (`<div>`)\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n\n // Generate the caret automatically\n @include caret();\n}\n\n// The dropdown menu\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: $zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: $dropdown-min-width;\n padding: $dropdown-padding-y $dropdown-padding-x;\n margin: $dropdown-spacer 0 0; // override default ul\n @include font-size($dropdown-font-size);\n color: $dropdown-color;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n list-style: none;\n background-color: $dropdown-bg;\n background-clip: padding-box;\n border: $dropdown-border-width solid $dropdown-border-color;\n @include border-radius($dropdown-border-radius);\n @include box-shadow($dropdown-box-shadow);\n}\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .dropdown-menu#{$infix}-left {\n right: auto;\n left: 0;\n }\n\n .dropdown-menu#{$infix}-right {\n right: 0;\n left: auto;\n }\n }\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(up);\n }\n}\n\n.dropright {\n .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(right);\n &::after {\n vertical-align: 0;\n }\n }\n}\n\n.dropleft {\n .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(left);\n &::before {\n vertical-align: 0;\n }\n }\n}\n\n// When enabled Popper.js, reset basic dropdown position\n// stylelint-disable-next-line no-duplicate-selectors\n.dropdown-menu {\n &[x-placement^=\"top\"],\n &[x-placement^=\"right\"],\n &[x-placement^=\"bottom\"],\n &[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n }\n}\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n @include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n display: block;\n width: 100%; // For `<button>`s\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n clear: both;\n font-weight: $font-weight-normal;\n color: $dropdown-link-color;\n text-align: inherit; // For `<button>`s\n text-decoration: if($link-decoration == none, null, none);\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n background-color: transparent; // For `<button>`s\n border: 0; // For `<button>`s\n\n // Prevent dropdown overflow if there's no padding\n // See https://github.com/twbs/bootstrap/pull/27703\n @if $dropdown-padding-y == 0 {\n &:first-child {\n @include border-top-radius($dropdown-inner-border-radius);\n }\n\n &:last-child {\n @include border-bottom-radius($dropdown-inner-border-radius);\n }\n }\n\n @include hover-focus() {\n color: $dropdown-link-hover-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-hover-bg);\n }\n\n &.active,\n &:active {\n color: $dropdown-link-active-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-active-bg);\n }\n\n &.disabled,\n &:disabled {\n color: $dropdown-link-disabled-color;\n pointer-events: none;\n background-color: transparent;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: $dropdown-header-padding;\n margin-bottom: 0; // for use with heading elements\n @include font-size($font-size-sm);\n color: $dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n display: block;\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n color: $dropdown-link-color;\n}\n","@mixin caret-down() {\n border-top: $caret-width solid;\n border-right: $caret-width solid transparent;\n border-bottom: 0;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up() {\n border-top: 0;\n border-right: $caret-width solid transparent;\n border-bottom: $caret-width solid;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-right() {\n border-top: $caret-width solid transparent;\n border-right: 0;\n border-bottom: $caret-width solid transparent;\n border-left: $caret-width solid;\n}\n\n@mixin caret-left() {\n border-top: $caret-width solid transparent;\n border-right: $caret-width solid;\n border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n @if $enable-caret {\n &::after {\n display: inline-block;\n margin-left: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @if $direction == down {\n @include caret-down();\n } @else if $direction == up {\n @include caret-up();\n } @else if $direction == right {\n @include caret-right();\n }\n }\n\n @if $direction == left {\n &::after {\n display: none;\n }\n\n &::before {\n display: inline-block;\n margin-right: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @include caret-left();\n }\n }\n\n &:empty::after {\n margin-left: 0;\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y, $ignore-warning: false) {\n height: 0;\n margin: $margin-y 0;\n overflow: hidden;\n border-top: 1px solid $color;\n @include deprecate(\"The `nav-divider()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle; // match .btn alignment given font-size hack above\n\n > .btn {\n position: relative;\n flex: 1 1 auto;\n\n // Bring the hover, focused, and \"active\" buttons to the front to overlay\n // the borders properly\n @include hover() {\n z-index: 1;\n }\n &:focus,\n &:active,\n &.active {\n z-index: 1;\n }\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n\n .input-group {\n width: auto;\n }\n}\n\n.btn-group {\n // Prevent double borders when buttons are next to each other\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-left: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-right-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-left-radius(0);\n }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n padding-right: $btn-padding-x * .75;\n padding-left: $btn-padding-x * .75;\n\n &::after,\n .dropup &::after,\n .dropright &::after {\n margin-left: 0;\n }\n\n .dropleft &::before {\n margin-right: 0;\n }\n}\n\n.btn-sm + .dropdown-toggle-split {\n padding-right: $btn-padding-x-sm * .75;\n padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n padding-right: $btn-padding-x-lg * .75;\n padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n @include box-shadow($btn-active-box-shadow);\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n @include box-shadow(none);\n }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n\n > .btn,\n > .btn-group {\n width: 100%;\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-top: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-bottom-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-top-radius(0);\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n.btn-group-toggle {\n > .btn,\n > .btn-group > .btn {\n margin-bottom: 0; // Override default `<label>` value\n\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap; // For form validation feedback\n align-items: stretch;\n width: 100%;\n\n > .form-control,\n > .form-control-plaintext,\n > .custom-select,\n > .custom-file {\n position: relative; // For focus state's z-index\n flex: 1 1 auto;\n width: 1%;\n min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size\n margin-bottom: 0;\n\n + .form-control,\n + .custom-select,\n + .custom-file {\n margin-left: -$input-border-width;\n }\n }\n\n // Bring the \"active\" form control to the top of surrounding elements\n > .form-control:focus,\n > .custom-select:focus,\n > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n }\n\n // Bring the custom file input above the label\n > .custom-file .custom-file-input:focus {\n z-index: 4;\n }\n\n > .form-control,\n > .custom-select {\n &:not(:last-child) { @include border-right-radius(0); }\n &:not(:first-child) { @include border-left-radius(0); }\n }\n\n // Custom file inputs have more complex markup, thus requiring different\n // border-radius overrides.\n > .custom-file {\n display: flex;\n align-items: center;\n\n &:not(:last-child) .custom-file-label,\n &:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }\n &:not(:first-child) .custom-file-label { @include border-left-radius(0); }\n }\n}\n\n\n// Prepend and append\n//\n// While it requires one extra layer of HTML for each, dedicated prepend and\n// append elements allow us to 1) be less clever, 2) simplify our selectors, and\n// 3) support HTML5 form validation.\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n\n // Ensure buttons are always above inputs for more visually pleasing borders.\n // This isn't needed for `.input-group-text` since it shares the same border-color\n // as our inputs.\n .btn {\n position: relative;\n z-index: 2;\n\n &:focus {\n z-index: 3;\n }\n }\n\n .btn + .btn,\n .btn + .input-group-text,\n .input-group-text + .input-group-text,\n .input-group-text + .btn {\n margin-left: -$input-border-width;\n }\n}\n\n.input-group-prepend { margin-right: -$input-border-width; }\n.input-group-append { margin-left: -$input-border-width; }\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: $input-padding-y $input-padding-x;\n margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom\n @include font-size($input-font-size); // Match inputs\n font-weight: $font-weight-normal;\n line-height: $input-line-height;\n color: $input-group-addon-color;\n text-align: center;\n white-space: nowrap;\n background-color: $input-group-addon-bg;\n border: $input-border-width solid $input-group-addon-border-color;\n @include border-radius($input-border-radius);\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: $input-height-lg;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: $input-height-sm;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: $custom-select-padding-x + $custom-select-indicator-padding;\n}\n\n\n// Prepend and append rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n @include border-right-radius(0);\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n @include border-left-radius(0);\n}\n","// Embedded icons from Open Iconic.\n// Released under MIT and copyright 2014 Waybury.\n// https://useiconic.com/open\n\n\n// Checkboxes and radios\n//\n// Base class takes care of all the key behavioral aspects.\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: $font-size-base * $line-height-base;\n padding-left: $custom-control-gutter + $custom-control-indicator-size;\n color-adjust: exact; // Keep themed appearance for print\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: $custom-control-spacer-x;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1; // Put the input behind the label so it doesn't overlay text\n width: $custom-control-indicator-size;\n height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;\n opacity: 0;\n\n &:checked ~ .custom-control-label::before {\n color: $custom-control-indicator-checked-color;\n border-color: $custom-control-indicator-checked-border-color;\n @include gradient-bg($custom-control-indicator-checked-bg);\n @include box-shadow($custom-control-indicator-checked-box-shadow);\n }\n\n &:focus ~ .custom-control-label::before {\n // the mixin is not used here to make sure there is feedback\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $custom-control-indicator-focus-box-shadow;\n } @else {\n box-shadow: $custom-control-indicator-focus-box-shadow;\n }\n }\n\n &:focus:not(:checked) ~ .custom-control-label::before {\n border-color: $custom-control-indicator-focus-border-color;\n }\n\n &:not(:disabled):active ~ .custom-control-label::before {\n color: $custom-control-indicator-active-color;\n background-color: $custom-control-indicator-active-bg;\n border-color: $custom-control-indicator-active-border-color;\n @include box-shadow($custom-control-indicator-active-box-shadow);\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled],\n &:disabled {\n ~ .custom-control-label {\n color: $custom-control-label-disabled-color;\n\n &::before {\n background-color: $custom-control-indicator-disabled-bg;\n }\n }\n }\n}\n\n// Custom control indicators\n//\n// Build the custom controls out of pseudo-elements.\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n color: $custom-control-label-color;\n vertical-align: top;\n cursor: $custom-control-cursor;\n\n // Background-color and (when enabled) gradient\n &::before {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n pointer-events: none;\n content: \"\";\n background-color: $custom-control-indicator-bg;\n border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;\n @include box-shadow($custom-control-indicator-box-shadow);\n }\n\n // Foreground (icon)\n &::after {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n content: \"\";\n background: no-repeat 50% / #{$custom-control-indicator-bg-size};\n }\n}\n\n\n// Checkboxes\n//\n// Tweak just a few things for checkboxes.\n\n.custom-checkbox {\n .custom-control-label::before {\n @include border-radius($custom-checkbox-indicator-border-radius);\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-checked);\n }\n }\n\n .custom-control-input:indeterminate ~ .custom-control-label {\n &::before {\n border-color: $custom-checkbox-indicator-indeterminate-border-color;\n @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);\n @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);\n }\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n &:indeterminate ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n// Radios\n//\n// Tweak just a few things for radios.\n\n.custom-radio {\n .custom-control-label::before {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-radio-indicator-border-radius;\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-radio-indicator-icon-checked);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// switches\n//\n// Tweak a few things for switches\n\n.custom-switch {\n padding-left: $custom-switch-width + $custom-control-gutter;\n\n .custom-control-label {\n &::before {\n left: -($custom-switch-width + $custom-control-gutter);\n width: $custom-switch-width;\n pointer-events: all;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n }\n\n &::after {\n top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);\n left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);\n width: $custom-switch-indicator-size;\n height: $custom-switch-indicator-size;\n background-color: $custom-control-indicator-border-color;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n @include transition(transform .15s ease-in-out, $custom-forms-transition);\n }\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-color: $custom-control-indicator-bg;\n transform: translateX($custom-switch-width - $custom-control-indicator-size);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n//\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: $custom-select-height;\n padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;\n font-family: $custom-select-font-family;\n @include font-size($custom-select-font-size);\n font-weight: $custom-select-font-weight;\n line-height: $custom-select-line-height;\n color: $custom-select-color;\n vertical-align: middle;\n background: $custom-select-bg $custom-select-background;\n border: $custom-select-border-width solid $custom-select-border-color;\n @include border-radius($custom-select-border-radius, 0);\n @include box-shadow($custom-select-box-shadow);\n appearance: none;\n\n &:focus {\n border-color: $custom-select-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $custom-select-focus-box-shadow;\n }\n\n &::-ms-value {\n // For visual consistency with other platforms/browsers,\n // suppress the default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n }\n\n &[multiple],\n &[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: $custom-select-padding-x;\n background-image: none;\n }\n\n &:disabled {\n color: $custom-select-disabled-color;\n background-color: $custom-select-disabled-bg;\n }\n\n // Hides the default caret in IE11\n &::-ms-expand {\n display: none;\n }\n\n // Remove outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $custom-select-color;\n }\n}\n\n.custom-select-sm {\n height: $custom-select-height-sm;\n padding-top: $custom-select-padding-y-sm;\n padding-bottom: $custom-select-padding-y-sm;\n padding-left: $custom-select-padding-x-sm;\n @include font-size($custom-select-font-size-sm);\n}\n\n.custom-select-lg {\n height: $custom-select-height-lg;\n padding-top: $custom-select-padding-y-lg;\n padding-bottom: $custom-select-padding-y-lg;\n padding-left: $custom-select-padding-x-lg;\n @include font-size($custom-select-font-size-lg);\n}\n\n\n// File\n//\n// Custom file input.\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: $custom-file-height;\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: $custom-file-height;\n margin: 0;\n opacity: 0;\n\n &:focus ~ .custom-file-label {\n border-color: $custom-file-focus-border-color;\n box-shadow: $custom-file-focus-box-shadow;\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .custom-file-label,\n &:disabled ~ .custom-file-label {\n background-color: $custom-file-disabled-bg;\n }\n\n @each $lang, $value in $custom-file-text {\n &:lang(#{$lang}) ~ .custom-file-label::after {\n content: $value;\n }\n }\n\n ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n }\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: $custom-file-height;\n padding: $custom-file-padding-y $custom-file-padding-x;\n font-family: $custom-file-font-family;\n font-weight: $custom-file-font-weight;\n line-height: $custom-file-line-height;\n color: $custom-file-color;\n background-color: $custom-file-bg;\n border: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius($custom-file-border-radius);\n @include box-shadow($custom-file-box-shadow);\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: $custom-file-height-inner;\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-button-color;\n content: \"Browse\";\n @include gradient-bg($custom-file-button-bg);\n border-left: inherit;\n @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);\n }\n}\n\n// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.custom-range {\n width: 100%;\n height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);\n padding: 0; // Need to reset padding\n background-color: transparent;\n appearance: none;\n\n &:focus {\n outline: none;\n\n // Pseudo-elements must be split across multiple rulesets to have an effect.\n // No box-shadow() mixin for focus accessibility.\n &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n }\n\n &::-moz-focus-outer {\n border: 0;\n }\n\n &::-webkit-slider-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-webkit-slider-runnable-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent; // Why?\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent;\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-moz-range-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-moz-range-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent; // Firefox specific?\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: 0; // Edge specific\n margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-ms-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: transparent;\n border-color: transparent;\n border-width: $custom-range-thumb-height / 2;\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-fill-lower {\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &::-ms-fill-upper {\n margin-right: 15px; // arbitrary?\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &:disabled {\n &::-webkit-slider-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-webkit-slider-runnable-track {\n cursor: default;\n }\n\n &::-moz-range-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-moz-range-track {\n cursor: default;\n }\n\n &::-ms-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n }\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n @include transition($custom-forms-transition);\n}\n","// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s, `<ul>`s or `<ol>`s.\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: $nav-link-padding-y $nav-link-padding-x;\n text-decoration: if($link-decoration == none, null, none);\n\n @include hover-focus() {\n text-decoration: none;\n }\n\n // Disabled state lightens text\n &.disabled {\n color: $nav-link-disabled-color;\n pointer-events: none;\n cursor: default;\n }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n .nav-item {\n margin-bottom: -$nav-tabs-border-width;\n }\n\n .nav-link {\n border: $nav-tabs-border-width solid transparent;\n @include border-top-radius($nav-tabs-border-radius);\n\n @include hover-focus() {\n border-color: $nav-tabs-link-hover-border-color;\n }\n\n &.disabled {\n color: $nav-link-disabled-color;\n background-color: transparent;\n border-color: transparent;\n }\n }\n\n .nav-link.active,\n .nav-item.show .nav-link {\n color: $nav-tabs-link-active-color;\n background-color: $nav-tabs-link-active-bg;\n border-color: $nav-tabs-link-active-border-color;\n }\n\n .dropdown-menu {\n // Make dropdown border overlap tab border\n margin-top: -$nav-tabs-border-width;\n // Remove the top rounded corners here since there is a hard edge above the menu\n @include border-top-radius(0);\n }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n .nav-link {\n @include border-radius($nav-pills-border-radius);\n }\n\n .nav-link.active,\n .show > .nav-link {\n color: $nav-pills-link-active-color;\n background-color: $nav-pills-link-active-bg;\n }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n > .nav-link,\n .nav-item {\n flex: 1 1 auto;\n text-align: center;\n }\n}\n\n.nav-justified {\n > .nav-link,\n .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n","// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Navbar divider\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap; // allow us to do the line break for collapsing content\n align-items: center;\n justify-content: space-between; // space out brand from logo\n padding: $navbar-padding-y $navbar-padding-x;\n\n // Because flex properties aren't inherited, we need to redeclare these first\n // few properties so that content nested within behave properly.\n %container-flex-properties {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n }\n\n .container,\n .container-fluid {\n @extend %container-flex-properties;\n }\n\n @each $breakpoint, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {\n @extend %container-flex-properties;\n }\n }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n display: inline-block;\n padding-top: $navbar-brand-padding-y;\n padding-bottom: $navbar-brand-padding-y;\n margin-right: $navbar-padding-x;\n @include font-size($navbar-brand-font-size);\n line-height: inherit;\n white-space: nowrap;\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n display: flex;\n flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n\n .nav-link {\n padding-right: 0;\n padding-left: 0;\n }\n\n .dropdown-menu {\n position: static;\n float: none;\n }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n display: inline-block;\n padding-top: $nav-link-padding-y;\n padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n // For always expanded or extra full navbars, ensure content aligns itself\n // properly vertically. Can be easily overridden with flex utilities.\n align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n @include font-size($navbar-toggler-font-size);\n line-height: 1;\n background-color: transparent; // remove default button style\n border: $border-width solid transparent; // remove default button style\n @include border-radius($navbar-toggler-border-radius);\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n %container-navbar-expand-#{$breakpoint} {\n padding-right: 0;\n padding-left: 0;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n }\n }\n\n @include media-breakpoint-up($next) {\n flex-flow: row nowrap;\n justify-content: flex-start;\n\n .navbar-nav {\n flex-direction: row;\n\n .dropdown-menu {\n position: absolute;\n }\n\n .nav-link {\n padding-right: $navbar-nav-link-padding-x;\n padding-left: $navbar-nav-link-padding-x;\n }\n }\n\n // For nesting containers, have to redeclare for alignment purposes\n %container-nesting-#{$breakpoint} {\n flex-wrap: nowrap;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-nesting-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-nesting-#{$breakpoint};\n }\n }\n\n .navbar-collapse {\n display: flex !important; // stylelint-disable-line declaration-no-important\n\n // Changes flex-bases to auto because of an IE10 bug\n flex-basis: auto;\n }\n\n .navbar-toggler {\n display: none;\n }\n }\n }\n }\n}\n\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n .navbar-brand {\n color: $navbar-light-brand-color;\n\n @include hover-focus() {\n color: $navbar-light-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-light-color;\n\n @include hover-focus() {\n color: $navbar-light-hover-color;\n }\n\n &.disabled {\n color: $navbar-light-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-light-color;\n border-color: $navbar-light-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-light-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-light-color;\n a {\n color: $navbar-light-active-color;\n\n @include hover-focus() {\n color: $navbar-light-active-color;\n }\n }\n }\n}\n\n// White links against a dark background\n.navbar-dark {\n .navbar-brand {\n color: $navbar-dark-brand-color;\n\n @include hover-focus() {\n color: $navbar-dark-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-dark-color;\n\n @include hover-focus() {\n color: $navbar-dark-hover-color;\n }\n\n &.disabled {\n color: $navbar-dark-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-dark-color;\n border-color: $navbar-dark-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-dark-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-dark-color;\n a {\n color: $navbar-dark-active-color;\n\n @include hover-focus() {\n color: $navbar-dark-active-color;\n }\n }\n }\n}\n","//\n// Base styles\n//\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106\n height: $card-height;\n word-wrap: break-word;\n background-color: $card-bg;\n background-clip: border-box;\n border: $card-border-width solid $card-border-color;\n @include border-radius($card-border-radius);\n\n > hr {\n margin-right: 0;\n margin-left: 0;\n }\n\n > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n\n &:first-child {\n border-top-width: 0;\n @include border-top-radius($card-inner-border-radius);\n }\n\n &:last-child {\n border-bottom-width: 0;\n @include border-bottom-radius($card-inner-border-radius);\n }\n }\n\n // Due to specificity of the above selector (`.card > .list-group`), we must\n // use a child selector here to prevent double borders.\n > .card-header + .list-group,\n > .list-group + .card-footer {\n border-top: 0;\n }\n}\n\n.card-body {\n // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n // as much space as possible, ensuring footers are aligned to the bottom.\n flex: 1 1 auto;\n // Workaround for the image size bug in IE\n // See: https://github.com/twbs/bootstrap/pull/28855\n min-height: 1px;\n padding: $card-spacer-x;\n color: $card-color;\n}\n\n.card-title {\n margin-bottom: $card-spacer-y;\n}\n\n.card-subtitle {\n margin-top: -$card-spacer-y / 2;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link {\n @include hover() {\n text-decoration: none;\n }\n\n + .card-link {\n margin-left: $card-spacer-x;\n }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n padding: $card-spacer-y $card-spacer-x;\n margin-bottom: 0; // Removes the default margin-bottom of <hN>\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-bottom: $card-border-width solid $card-border-color;\n\n &:first-child {\n @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n }\n}\n\n.card-footer {\n padding: $card-spacer-y $card-spacer-x;\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-top: $card-border-width solid $card-border-color;\n\n &:last-child {\n @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n margin-right: -$card-spacer-x / 2;\n margin-bottom: -$card-spacer-y;\n margin-left: -$card-spacer-x / 2;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -$card-spacer-x / 2;\n margin-left: -$card-spacer-x / 2;\n}\n\n// Card image\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: $card-img-overlay-padding;\n @include border-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n}\n\n.card-img,\n.card-img-top {\n @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n// Card deck\n\n.card-deck {\n .card {\n margin-bottom: $card-deck-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n margin-right: -$card-deck-margin;\n margin-left: -$card-deck-margin;\n\n .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-right: $card-deck-margin;\n margin-bottom: 0; // Override the default\n margin-left: $card-deck-margin;\n }\n }\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n margin-bottom: $card-group-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-bottom: 0;\n\n + .card {\n margin-left: 0;\n border-left: 0;\n }\n\n // Handle rounded corners\n @if $enable-rounded {\n &:not(:last-child) {\n @include border-right-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-right-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-right-radius: 0;\n }\n }\n\n &:not(:first-child) {\n @include border-left-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-left-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-left-radius: 0;\n }\n }\n }\n }\n }\n}\n\n\n//\n// Columns\n//\n\n.card-columns {\n .card {\n margin-bottom: $card-columns-margin;\n }\n\n @include media-breakpoint-up(sm) {\n column-count: $card-columns-count;\n column-gap: $card-columns-gap;\n orphans: 1;\n widows: 1;\n\n .card {\n display: inline-block; // Don't let them vertically span multiple columns\n width: 100%; // Don't let their width change\n }\n }\n}\n\n\n//\n// Accordion\n//\n\n.accordion {\n overflow-anchor: none;\n\n > .card {\n overflow: hidden;\n\n &:not(:last-of-type) {\n border-bottom: 0;\n @include border-bottom-radius(0);\n }\n\n &:not(:first-of-type) {\n @include border-top-radius(0);\n }\n\n > .card-header {\n @include border-radius(0);\n margin-bottom: -$card-border-width;\n }\n }\n}\n",".breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n margin-bottom: $breadcrumb-margin-bottom;\n @include font-size($breadcrumb-font-size);\n list-style: none;\n background-color: $breadcrumb-bg;\n @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n display: flex;\n\n // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n + .breadcrumb-item {\n padding-left: $breadcrumb-item-padding;\n\n &::before {\n display: inline-block; // Suppress underlining of the separator in modern browsers\n padding-right: $breadcrumb-item-padding;\n color: $breadcrumb-divider-color;\n content: escape-svg($breadcrumb-divider);\n }\n }\n\n // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built\n // without `<ul>`s. The `::before` pseudo-element generates an element\n // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.\n //\n // To trick IE into suppressing the underline, we give the pseudo-element an\n // underline and then immediately remove it.\n + .breadcrumb-item:hover::before {\n text-decoration: underline;\n }\n // stylelint-disable-next-line no-duplicate-selectors\n + .breadcrumb-item:hover::before {\n text-decoration: none;\n }\n\n &.active {\n color: $breadcrumb-active-color;\n }\n}\n",".pagination {\n display: flex;\n @include list-unstyled();\n @include border-radius();\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: $pagination-padding-y $pagination-padding-x;\n margin-left: -$pagination-border-width;\n line-height: $pagination-line-height;\n color: $pagination-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $pagination-bg;\n border: $pagination-border-width solid $pagination-border-color;\n\n &:hover {\n z-index: 2;\n color: $pagination-hover-color;\n text-decoration: none;\n background-color: $pagination-hover-bg;\n border-color: $pagination-hover-border-color;\n }\n\n &:focus {\n z-index: 3;\n outline: $pagination-focus-outline;\n box-shadow: $pagination-focus-box-shadow;\n }\n}\n\n.page-item {\n &:first-child {\n .page-link {\n margin-left: 0;\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n\n &.active .page-link {\n z-index: 3;\n color: $pagination-active-color;\n background-color: $pagination-active-bg;\n border-color: $pagination-active-border-color;\n }\n\n &.disabled .page-link {\n color: $pagination-disabled-color;\n pointer-events: none;\n // Opinionated: remove the \"hand\" cursor set previously for .page-link\n cursor: auto;\n background-color: $pagination-disabled-bg;\n border-color: $pagination-disabled-border-color;\n }\n}\n\n\n//\n// Sizing\n//\n\n.pagination-lg {\n @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);\n}\n\n.pagination-sm {\n @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);\n}\n","// Pagination\n\n@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n .page-link {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n }\n\n .page-item {\n &:first-child {\n .page-link {\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n }\n}\n","// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n display: inline-block;\n padding: $badge-padding-y $badge-padding-x;\n @include font-size($badge-font-size);\n font-weight: $badge-font-weight;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n @include border-radius($badge-border-radius);\n @include transition($badge-transition);\n\n @at-root a#{&} {\n @include hover-focus() {\n text-decoration: none;\n }\n }\n\n // Empty badges collapse automatically\n &:empty {\n display: none;\n }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Pill badges\n//\n// Make them extra rounded with a modifier to replace v3's badges.\n\n.badge-pill {\n padding-right: $badge-pill-padding-x;\n padding-left: $badge-pill-padding-x;\n @include border-radius($badge-pill-border-radius);\n}\n\n// Colors\n//\n// Contextual variations (linked badges get darker on :hover).\n\n@each $color, $value in $theme-colors {\n .badge-#{$color} {\n @include badge-variant($value);\n }\n}\n","@mixin badge-variant($bg) {\n color: color-yiq($bg);\n background-color: $bg;\n\n @at-root a#{&} {\n @include hover-focus() {\n color: color-yiq($bg);\n background-color: darken($bg, 10%);\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);\n }\n }\n}\n",".jumbotron {\n padding: $jumbotron-padding ($jumbotron-padding / 2);\n margin-bottom: $jumbotron-padding;\n color: $jumbotron-color;\n background-color: $jumbotron-bg;\n @include border-radius($border-radius-lg);\n\n @include media-breakpoint-up(sm) {\n padding: ($jumbotron-padding * 2) $jumbotron-padding;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n @include border-radius(0);\n}\n","//\n// Base styles\n//\n\n.alert {\n position: relative;\n padding: $alert-padding-y $alert-padding-x;\n margin-bottom: $alert-margin-bottom;\n border: $alert-border-width solid transparent;\n @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n // Specified to prevent conflicts of changing $headings-color\n color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n padding-right: $close-font-size + $alert-padding-x * 2;\n\n // Adjust close link position\n .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: $alert-padding-y $alert-padding-x;\n color: inherit;\n }\n}\n\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $color, $value in $theme-colors {\n .alert-#{$color} {\n @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));\n }\n}\n","@mixin alert-variant($background, $border, $color) {\n color: $color;\n @include gradient-bg($background);\n border-color: $border;\n\n hr {\n border-top-color: darken($border, 5%);\n }\n\n .alert-link {\n color: darken($color, 10%);\n }\n}\n","// Disable animation if transitions are disabled\n@if $enable-transitions {\n @keyframes progress-bar-stripes {\n from { background-position: $progress-height 0; }\n to { background-position: 0 0; }\n }\n}\n\n.progress {\n display: flex;\n height: $progress-height;\n overflow: hidden; // force rounded corners by cropping it\n line-height: 0;\n @include font-size($progress-font-size);\n background-color: $progress-bg;\n @include border-radius($progress-border-radius);\n @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: $progress-bar-color;\n text-align: center;\n white-space: nowrap;\n background-color: $progress-bar-bg;\n @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n @include gradient-striped();\n background-size: $progress-height $progress-height;\n}\n\n@if $enable-transitions {\n .progress-bar-animated {\n animation: progress-bar-stripes $progress-bar-animation-timing;\n\n @if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n}\n",".media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n","// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n display: flex;\n flex-direction: column;\n\n // No need to set list-style: none; since .list-group-item is block level\n padding-left: 0; // reset padding because ul and ol\n margin-bottom: 0;\n @include border-radius($list-group-border-radius);\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n width: 100%; // For `<button>`s (anchors become 100% by default though)\n color: $list-group-action-color;\n text-align: inherit; // For `<button>`s (anchors inherit)\n\n // Hover state\n @include hover-focus() {\n z-index: 1; // Place hover/focus items above their siblings for proper border styling\n color: $list-group-action-hover-color;\n text-decoration: none;\n background-color: $list-group-hover-bg;\n }\n\n &:active {\n color: $list-group-action-active-color;\n background-color: $list-group-action-active-bg;\n }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: $list-group-item-padding-y $list-group-item-padding-x;\n color: $list-group-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $list-group-bg;\n border: $list-group-border-width solid $list-group-border-color;\n\n &:first-child {\n @include border-top-radius(inherit);\n }\n\n &:last-child {\n @include border-bottom-radius(inherit);\n }\n\n &.disabled,\n &:disabled {\n color: $list-group-disabled-color;\n pointer-events: none;\n background-color: $list-group-disabled-bg;\n }\n\n // Include both here for `<a>`s and `<button>`s\n &.active {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: $list-group-active-color;\n background-color: $list-group-active-bg;\n border-color: $list-group-active-border-color;\n }\n\n & + & {\n border-top-width: 0;\n\n &.active {\n margin-top: -$list-group-border-width;\n border-top-width: $list-group-border-width;\n }\n }\n}\n\n\n// Horizontal\n//\n// Change the layout of list group items from vertical (default) to horizontal.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .list-group-horizontal#{$infix} {\n flex-direction: row;\n\n > .list-group-item {\n &:first-child {\n @include border-bottom-left-radius($list-group-border-radius);\n @include border-top-right-radius(0);\n }\n\n &:last-child {\n @include border-top-right-radius($list-group-border-radius);\n @include border-bottom-left-radius(0);\n }\n\n &.active {\n margin-top: 0;\n }\n\n + .list-group-item {\n border-top-width: $list-group-border-width;\n border-left-width: 0;\n\n &.active {\n margin-left: -$list-group-border-width;\n border-left-width: $list-group-border-width;\n }\n }\n }\n }\n }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n @include border-radius(0);\n\n > .list-group-item {\n border-width: 0 0 $list-group-border-width;\n\n &:last-child {\n border-bottom-width: 0;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $color, $value in $theme-colors {\n @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));\n}\n","// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n .list-group-item-#{$state} {\n color: $color;\n background-color: $background;\n\n &.list-group-item-action {\n @include hover-focus() {\n color: $color;\n background-color: darken($background, 5%);\n }\n\n &.active {\n color: $white;\n background-color: $color;\n border-color: $color;\n }\n }\n }\n}\n",".close {\n float: right;\n @include font-size($close-font-size);\n font-weight: $close-font-weight;\n line-height: 1;\n color: $close-color;\n text-shadow: $close-text-shadow;\n opacity: .5;\n\n // Override <a>'s hover style\n @include hover() {\n color: $close-color;\n text-decoration: none;\n }\n\n &:not(:disabled):not(.disabled) {\n @include hover-focus() {\n opacity: .75;\n }\n }\n}\n\n// Additional properties for button version\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n// stylelint-disable-next-line selector-no-qualifying-type\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\n// Future-proof disabling of clicks on `<a>` elements\n\n// stylelint-disable-next-line selector-no-qualifying-type\na.close.disabled {\n pointer-events: none;\n}\n",".toast {\n // Prevents from shrinking in IE11, when in a flex container\n // See https://github.com/twbs/bootstrap/issues/28341\n flex-basis: $toast-max-width;\n max-width: $toast-max-width;\n @include font-size($toast-font-size);\n color: $toast-color;\n background-color: $toast-background-color;\n background-clip: padding-box;\n border: $toast-border-width solid $toast-border-color;\n box-shadow: $toast-box-shadow;\n opacity: 0;\n @include border-radius($toast-border-radius);\n\n &:not(:last-child) {\n margin-bottom: $toast-padding-x;\n }\n\n &.showing {\n opacity: 1;\n }\n\n &.show {\n display: block;\n opacity: 1;\n }\n\n &.hide {\n display: none;\n }\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: $toast-padding-y $toast-padding-x;\n color: $toast-header-color;\n background-color: $toast-header-background-color;\n background-clip: padding-box;\n border-bottom: $toast-border-width solid $toast-header-border-color;\n @include border-top-radius(subtract($toast-border-radius, $toast-border-width));\n}\n\n.toast-body {\n padding: $toast-padding-x; // apply to both vertical and horizontal\n}\n","// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and stuff\n\n\n.modal-open {\n // Kill the scroll on the body\n overflow: hidden;\n\n .modal {\n overflow-x: hidden;\n overflow-y: auto;\n }\n}\n\n// Container that the modal scrolls within\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: $modal-dialog-margin;\n // allow clicks to pass through for custom click handling to close modal\n pointer-events: none;\n\n // When fading in the modal, animate it to slide down\n .modal.fade & {\n @include transition($modal-transition);\n transform: $modal-fade-transform;\n }\n .modal.show & {\n transform: $modal-show-transform;\n }\n\n // When trying to close, animate focus to scale\n .modal.modal-static & {\n transform: $modal-scale-transform;\n }\n}\n\n.modal-dialog-scrollable {\n display: flex; // IE10/11\n max-height: subtract(100%, $modal-dialog-margin * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11\n overflow: hidden;\n }\n\n .modal-header,\n .modal-footer {\n flex-shrink: 0;\n }\n\n .modal-body {\n overflow-y: auto;\n }\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: subtract(100%, $modal-dialog-margin * 2);\n\n // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)\n &::before {\n display: block; // IE10\n height: subtract(100vh, $modal-dialog-margin * 2);\n height: min-content; // Reset height to 0 except on IE\n content: \"\";\n }\n\n // Ensure `.modal-body` shows scrollbar (IE10/11)\n &.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n\n .modal-content {\n max-height: none;\n }\n\n &::before {\n content: none;\n }\n }\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n // counteract the pointer-events: none; in the .modal-dialog\n color: $modal-content-color;\n pointer-events: auto;\n background-color: $modal-content-bg;\n background-clip: padding-box;\n border: $modal-content-border-width solid $modal-content-border-color;\n @include border-radius($modal-content-border-radius);\n @include box-shadow($modal-content-box-shadow-xs);\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal-backdrop;\n width: 100vw;\n height: 100vh;\n background-color: $modal-backdrop-bg;\n\n // Fade for backdrop\n &.fade { opacity: 0; }\n &.show { opacity: $modal-backdrop-opacity; }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n display: flex;\n align-items: flex-start; // so the close btn always stays on the upper right corner\n justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n padding: $modal-header-padding;\n border-bottom: $modal-header-border-width solid $modal-header-border-color;\n @include border-top-radius($modal-content-inner-border-radius);\n\n .close {\n padding: $modal-header-padding;\n // auto on the left force icon to the right even when there is no .modal-title\n margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;\n }\n}\n\n// Title text within header\n.modal-title {\n margin-bottom: 0;\n line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n // Enable `flex-grow: 1` so that the body take up as much space as possible\n // when there should be a fixed height on `.modal-dialog`.\n flex: 1 1 auto;\n padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center; // vertically center\n justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n padding: $modal-inner-padding - $modal-footer-margin-between / 2;\n border-top: $modal-footer-border-width solid $modal-footer-border-color;\n @include border-bottom-radius($modal-content-inner-border-radius);\n\n // Place margin between footer elements\n // This solution is far from ideal because of the universal selector usage,\n // but is needed to fix https://github.com/twbs/bootstrap/issues/24800\n > * {\n margin: $modal-footer-margin-between / 2;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n max-width: $modal-md;\n margin: $modal-dialog-margin-y-sm-up auto;\n }\n\n .modal-dialog-scrollable {\n max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n }\n }\n\n .modal-dialog-centered {\n min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n &::before {\n height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n height: min-content;\n }\n }\n\n .modal-content {\n @include box-shadow($modal-content-box-shadow-sm-up);\n }\n\n .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n .modal-lg,\n .modal-xl {\n max-width: $modal-lg;\n }\n}\n\n@include media-breakpoint-up(xl) {\n .modal-xl { max-width: $modal-xl; }\n}\n","// Base class\n.tooltip {\n position: absolute;\n z-index: $zindex-tooltip;\n display: block;\n margin: $tooltip-margin;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($tooltip-font-size);\n // Allow breaking very long words so they don't overflow the tooltip's bounds\n word-wrap: break-word;\n opacity: 0;\n\n &.show { opacity: $tooltip-opacity; }\n\n .arrow {\n position: absolute;\n display: block;\n width: $tooltip-arrow-width;\n height: $tooltip-arrow-height;\n\n &::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-tooltip-top {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n bottom: 0;\n\n &::before {\n top: 0;\n border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-top-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-right {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n left: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n right: 0;\n border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-right-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-bottom {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n top: 0;\n\n &::before {\n bottom: 0;\n border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-bottom-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-left {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n right: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n left: 0;\n border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-left-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-tooltip-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-tooltip-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-tooltip-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-tooltip-left;\n }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: $tooltip-max-width;\n padding: $tooltip-padding-y $tooltip-padding-x;\n color: $tooltip-color;\n text-align: center;\n background-color: $tooltip-bg;\n @include border-radius($tooltip-border-radius);\n}\n","@mixin reset-text() {\n font-family: $font-family-base;\n // We deliberately do NOT reset font-size or word-wrap.\n font-style: normal;\n font-weight: $font-weight-normal;\n line-height: $line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n}\n",".popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: $zindex-popover;\n display: block;\n max-width: $popover-max-width;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($popover-font-size);\n // Allow breaking very long words so they don't overflow the popover's bounds\n word-wrap: break-word;\n background-color: $popover-bg;\n background-clip: padding-box;\n border: $popover-border-width solid $popover-border-color;\n @include border-radius($popover-border-radius);\n @include box-shadow($popover-box-shadow);\n\n .arrow {\n position: absolute;\n display: block;\n width: $popover-arrow-width;\n height: $popover-arrow-height;\n margin: 0 $popover-border-radius;\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-popover-top {\n margin-bottom: $popover-arrow-height;\n\n > .arrow {\n bottom: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n bottom: 0;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-outer-color;\n }\n\n &::after {\n bottom: $popover-border-width;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-right {\n margin-left: $popover-arrow-height;\n\n > .arrow {\n left: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n left: 0;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-outer-color;\n }\n\n &::after {\n left: $popover-border-width;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-bottom {\n margin-top: $popover-arrow-height;\n\n > .arrow {\n top: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n top: 0;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-outer-color;\n }\n\n &::after {\n top: $popover-border-width;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-color;\n }\n }\n\n // This will remove the popover-header's border just below the arrow\n .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: $popover-arrow-width;\n margin-left: -$popover-arrow-width / 2;\n content: \"\";\n border-bottom: $popover-border-width solid $popover-header-bg;\n }\n}\n\n.bs-popover-left {\n margin-right: $popover-arrow-height;\n\n > .arrow {\n right: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n right: 0;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-outer-color;\n }\n\n &::after {\n right: $popover-border-width;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-popover-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-popover-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-popover-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-popover-left;\n }\n}\n\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n padding: $popover-header-padding-y $popover-header-padding-x;\n margin-bottom: 0; // Reset the default from Reboot\n @include font-size($font-size-base);\n color: $popover-header-color;\n background-color: $popover-header-bg;\n border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);\n @include border-top-radius($popover-inner-border-radius);\n\n &:empty {\n display: none;\n }\n}\n\n.popover-body {\n padding: $popover-body-padding-y $popover-body-padding-x;\n color: $popover-body-color;\n}\n","// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n// even when their scroll action started on a carousel, but for compatibility (with Firefox)\n// we're preventing all actions instead\n// 2. The .carousel-item-left and .carousel-item-right is used to indicate where\n// the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-left and .active.carousel-item-right is the current\n// slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right\n// is the upcoming slide in transition.\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n @include clearfix();\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n }\n\n .carousel-item.active,\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n }\n\n .active.carousel-item-left,\n .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n @include transition(opacity 0s $carousel-transition-duration);\n }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n // Use flex for alignment (1-3)\n display: flex; // 1. allow flex styles\n align-items: center; // 2. vertically center contents\n justify-content: center; // 3. horizontally center contents\n width: $carousel-control-width;\n color: $carousel-control-color;\n text-align: center;\n opacity: $carousel-control-opacity;\n @include transition($carousel-control-transition);\n\n // Hover/focus state\n @include hover-focus() {\n color: $carousel-control-color;\n text-decoration: none;\n outline: 0;\n opacity: $carousel-control-hover-opacity;\n }\n}\n.carousel-control-prev {\n left: 0;\n @if $enable-gradients {\n background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));\n }\n}\n.carousel-control-next {\n right: 0;\n @if $enable-gradients {\n background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));\n }\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: $carousel-control-icon-width;\n height: $carousel-control-icon-width;\n background: no-repeat 50% / 100% 100%;\n}\n.carousel-control-prev-icon {\n background-image: escape-svg($carousel-control-prev-icon-bg);\n}\n.carousel-control-next-icon {\n background-image: escape-svg($carousel-control-next-icon-bg);\n}\n\n\n// Optional indicator pips\n//\n// Add an ordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0; // override <ol> default\n // Use the .carousel-control's width as margin so we don't overlay those\n margin-right: $carousel-control-width;\n margin-left: $carousel-control-width;\n list-style: none;\n\n li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: $carousel-indicator-width;\n height: $carousel-indicator-height;\n margin-right: $carousel-indicator-spacer;\n margin-left: $carousel-indicator-spacer;\n text-indent: -999px;\n cursor: pointer;\n background-color: $carousel-indicator-active-bg;\n background-clip: padding-box;\n // Use transparent borders to increase the hit area by 10px on top and bottom.\n border-top: $carousel-indicator-hit-area-height solid transparent;\n border-bottom: $carousel-indicator-hit-area-height solid transparent;\n opacity: .5;\n @include transition($carousel-indicator-transition);\n }\n\n .active {\n opacity: 1;\n }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n position: absolute;\n right: (100% - $carousel-caption-width) / 2;\n bottom: 20px;\n left: (100% - $carousel-caption-width) / 2;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: $carousel-caption-color;\n text-align: center;\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","//\n// Rotating border\n//\n\n@keyframes spinner-border {\n to { transform: rotate(360deg); }\n}\n\n.spinner-border {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n border: $spinner-border-width solid currentColor;\n border-right-color: transparent;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n background-color: currentColor;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n}\n","// stylelint-disable declaration-no-important\n\n.align-baseline { vertical-align: baseline !important; } // Browser default\n.align-top { vertical-align: top !important; }\n.align-middle { vertical-align: middle !important; }\n.align-bottom { vertical-align: bottom !important; }\n.align-text-bottom { vertical-align: text-bottom !important; }\n.align-text-top { vertical-align: text-top !important; }\n","// stylelint-disable declaration-no-important\n\n// Contextual backgrounds\n\n@mixin bg-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background-color: $color !important;\n }\n a#{$parent},\n button#{$parent} {\n @include hover-focus() {\n background-color: darken($color, 10%) !important;\n }\n }\n @include deprecate(\"The `bg-variant` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n@mixin bg-gradient-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;\n }\n @include deprecate(\"The `bg-gradient-variant` mixin\", \"v4.5.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n@each $color, $value in $theme-colors {\n @include bg-variant(\".bg-#{$color}\", $value, true);\n}\n\n@if $enable-gradients {\n @each $color, $value in $theme-colors {\n @include bg-gradient-variant(\".bg-gradient-#{$color}\", $value, true);\n }\n}\n\n.bg-white {\n background-color: $white !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n","// stylelint-disable property-disallowed-list, declaration-no-important\n\n//\n// Border\n//\n\n.border { border: $border-width solid $border-color !important; }\n.border-top { border-top: $border-width solid $border-color !important; }\n.border-right { border-right: $border-width solid $border-color !important; }\n.border-bottom { border-bottom: $border-width solid $border-color !important; }\n.border-left { border-left: $border-width solid $border-color !important; }\n\n.border-0 { border: 0 !important; }\n.border-top-0 { border-top: 0 !important; }\n.border-right-0 { border-right: 0 !important; }\n.border-bottom-0 { border-bottom: 0 !important; }\n.border-left-0 { border-left: 0 !important; }\n\n@each $color, $value in $theme-colors {\n .border-#{$color} {\n border-color: $value !important;\n }\n}\n\n.border-white {\n border-color: $white !important;\n}\n\n//\n// Border-radius\n//\n\n.rounded-sm {\n border-radius: $border-radius-sm !important;\n}\n\n.rounded {\n border-radius: $border-radius !important;\n}\n\n.rounded-top {\n border-top-left-radius: $border-radius !important;\n border-top-right-radius: $border-radius !important;\n}\n\n.rounded-right {\n border-top-right-radius: $border-radius !important;\n border-bottom-right-radius: $border-radius !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-left {\n border-top-left-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-lg {\n border-radius: $border-radius-lg !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: $rounded-pill !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n\n &::before {\n display: block;\n content: \"\";\n }\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n }\n}\n\n@each $embed-responsive-aspect-ratio in $embed-responsive-aspect-ratios {\n $embed-responsive-aspect-ratio-x: nth($embed-responsive-aspect-ratio, 1);\n $embed-responsive-aspect-ratio-y: nth($embed-responsive-aspect-ratio, 2);\n\n .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} {\n &::before {\n padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x);\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .float#{$infix}-left { float: left !important; }\n .float#{$infix}-right { float: right !important; }\n .float#{$infix}-none { float: none !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $user-selects {\n .user-select-#{$value} { user-select: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $overflows {\n .overflow-#{$value} { overflow: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Common values\n@each $position in $positions {\n .position-#{$position} { position: $position !important; }\n}\n\n// Shorthand\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.sticky-top {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: $zindex-sticky;\n }\n}\n","//\n// Screenreaders\n//\n\n.sr-only {\n @include sr-only();\n}\n\n.sr-only-focusable {\n @include sr-only-focusable();\n}\n","// Only display content to screen readers\n//\n// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/\n// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin sr-only() {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px; // Fix for https://github.com/twbs/bootstrap/issues/25686\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable() {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n }\n}\n","// stylelint-disable declaration-no-important\n\n.shadow-sm { box-shadow: $box-shadow-sm !important; }\n.shadow { box-shadow: $box-shadow !important; }\n.shadow-lg { box-shadow: $box-shadow-lg !important; }\n.shadow-none { box-shadow: none !important; }\n","// stylelint-disable declaration-no-important\n\n// Width and height\n\n@each $prop, $abbrev in (width: w, height: h) {\n @each $size, $length in $sizes {\n .#{$abbrev}-#{$size} { #{$prop}: $length !important; }\n }\n}\n\n.mw-100 { max-width: 100% !important; }\n.mh-100 { max-height: 100% !important; }\n\n// Viewport additional helpers\n\n.min-vw-100 { min-width: 100vw !important; }\n.min-vh-100 { min-height: 100vh !important; }\n\n.vw-100 { width: 100vw !important; }\n.vh-100 { height: 100vh !important; }\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n","//\n// Stretched link\n//\n\n.stretched-link {\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n // Just in case `pointer-events: none` is set on a parent\n pointer-events: auto;\n content: \"\";\n // IE10 bugfix, see https://stackoverflow.com/questions/16947967/ie10-hover-pseudo-class-doesnt-work-without-background-color\n background-color: rgba(0, 0, 0, 0);\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Text\n//\n\n.text-monospace { font-family: $font-family-monospace !important; }\n\n// Alignment\n\n.text-justify { text-align: justify !important; }\n.text-wrap { white-space: normal !important; }\n.text-nowrap { white-space: nowrap !important; }\n.text-truncate { @include text-truncate(); }\n\n// Responsive alignment\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .text#{$infix}-left { text-align: left !important; }\n .text#{$infix}-right { text-align: right !important; }\n .text#{$infix}-center { text-align: center !important; }\n }\n}\n\n// Transformation\n\n.text-lowercase { text-transform: lowercase !important; }\n.text-uppercase { text-transform: uppercase !important; }\n.text-capitalize { text-transform: capitalize !important; }\n\n// Weight and italics\n\n.font-weight-light { font-weight: $font-weight-light !important; }\n.font-weight-lighter { font-weight: $font-weight-lighter !important; }\n.font-weight-normal { font-weight: $font-weight-normal !important; }\n.font-weight-bold { font-weight: $font-weight-bold !important; }\n.font-weight-bolder { font-weight: $font-weight-bolder !important; }\n.font-italic { font-style: italic !important; }\n\n// Contextual colors\n\n.text-white { color: $white !important; }\n\n@each $color, $value in $theme-colors {\n @include text-emphasis-variant(\".text-#{$color}\", $value, true);\n}\n\n.text-body { color: $body-color !important; }\n.text-muted { color: $text-muted !important; }\n\n.text-black-50 { color: rgba($black, .5) !important; }\n.text-white-50 { color: rgba($white, .5) !important; }\n\n// Misc\n\n.text-hide {\n @include text-hide($ignore-warning: true);\n}\n\n.text-decoration-none { text-decoration: none !important; }\n\n.text-break {\n word-break: break-word !important; // Deprecated, but avoids issues with flex containers\n word-wrap: break-word !important; // Used instead of `overflow-wrap` for IE & Edge Legacy\n}\n\n// Reset\n\n.text-reset { color: inherit !important; }\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// stylelint-disable declaration-no-important\n\n// Typography\n\n@mixin text-emphasis-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n color: $color !important;\n }\n @if $emphasized-link-hover-darken-percentage != 0 {\n a#{$parent} {\n @include hover-focus() {\n color: darken($color, $emphasized-link-hover-darken-percentage) !important;\n }\n }\n }\n @include deprecate(\"`text-emphasis-variant()`\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// CSS image replacement\n@mixin text-hide($ignore-warning: false) {\n // stylelint-disable-next-line font-family-no-missing-generic-family-keyword\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n\n @include deprecate(\"`text-hide()`\", \"v4.1.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Visibility utilities\n//\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n// Source: https://github.com/h5bp/main.css/blob/master/src/_print.css\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request:\n// https://www.phpied.com/delay-loading-your-print-css/\n// ==========================================================================\n\n@if $enable-print-styles {\n @media print {\n *,\n *::before,\n *::after {\n // Bootstrap specific; comment out `color` and `background`\n //color: $black !important; // Black prints faster\n text-shadow: none !important;\n //background: transparent !important;\n box-shadow: none !important;\n }\n\n a {\n &:not(.btn) {\n text-decoration: underline;\n }\n }\n\n // Bootstrap specific; comment the following selector out\n //a[href]::after {\n // content: \" (\" attr(href) \")\";\n //}\n\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n // Bootstrap specific; comment the following selector out\n //\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n //\n\n //a[href^=\"#\"]::after,\n //a[href^=\"javascript:\"]::after {\n // content: \"\";\n //}\n\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px\n page-break-inside: avoid;\n }\n\n //\n // Printing Tables:\n // https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables\n //\n\n thead {\n display: table-header-group;\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Specify a size and min-width to make printing closer across browsers.\n // We don't set margin here because it breaks `size` in Chrome. We also\n // don't use `!important` on `size` as it breaks in Chrome.\n @page {\n size: $print-page-size;\n }\n body {\n min-width: $print-body-min-width !important;\n }\n .container {\n min-width: $print-body-min-width !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .badge {\n border: $border-width solid $black;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: $white !important;\n }\n }\n\n .table-bordered {\n th,\n td {\n border: 1px solid $gray-300 !important;\n }\n }\n\n .table-dark {\n color: inherit;\n\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $table-border-color;\n }\n }\n\n .table .thead-dark th {\n color: inherit;\n border-color: $table-border-color;\n }\n\n // Bootstrap specific changes end\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../scss/bootstrap.scss","bootstrap.css","../../scss/_root.scss","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/vendor/_rfs.scss","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_functions.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/utilities/_interactions.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_stretched-link.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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E,wBAAwB;AFxH1B;;AEgIA;EACE,aAAa;EACb,0BAA0B;AF7H5B;;AEoIA;EACE,qBAAqB;AFjIvB;;AEoIA;EACE,kBAAkB;EAClB,eAAe;AFjIjB;;AEoIA;EACE,aAAa;AFjIf;;AAEA;EEqIE,wBAAwB;AFnI1B;;AMzVA;;EAEE,qBHqSuC;EGnSvC,gBHqS+B;EGpS/B,gBHqS+B;AHsDjC;;AMvVA;EFgHM,iBAtCY;AJiRlB;;AM1VA;EF+GM,eAtCY;AJqRlB;;AM7VA;EF8GM,kBAtCY;AJyRlB;;AMhWA;EF6GM,iBAtCY;AJ6RlB;;AMnWA;EF4GM,kBAtCY;AJiSlB;;AMtWA;EF2GM,eAtCY;AJqSlB;;AMxWA;EFyGM,kBAtCY;EEjEhB,gBHuS+B;AHoEjC;;AMvWA;EFmGM,eAtCY;EE3DhB,gBH0R+B;EGzR/B,gBHiR+B;AHyFjC;;AMxWA;EF8FM,iBAtCY;EEtDhB,gBHsR+B;EGrR/B,gBH4Q+B;AH+FjC;;AMzWA;EFyFM,iBAtCY;EEjDhB,gBHkR+B;EGjR/B,gBHuQ+B;AHqGjC;;AM1WA;EFoFM,iBAtCY;EE5ChB,gBH8Q+B;EG7Q/B,gBHkQ+B;AH2GjC;;AEhVA;EIpBE,gBHgFW;EG/EX,mBH+EW;EG9EX,SAAS;EACT,wCHzCa;AHiZf;;AMhWA;;EFMI,cAAW;EEHb,gBH0N+B;AHyIjC;;AMhWA;;EAEE,cHkQgC;EGjQhC,yBH0QmC;AHyFrC;;AM3VA;EC/EE,eAAe;EACf,gBAAgB;AP8alB;;AM3VA;ECpFE,eAAe;EACf,gBAAgB;APmblB;;AM7VA;EACE,qBAAqB;ANgWvB;;AMjWA;EAII,oBHoP+B;AH6GnC;;AMvVA;EFjCI,cAAW;EEmCb,yBAAyB;AN0V3B;;AMtVA;EACE,mBHuBW;ECRP,kBAtCY;AJiXlB;;AMtVA;EACE,cAAc;EF7CZ,cAAW;EE+Cb,cH1GgB;AHmclB;;AM5VA;EAMI,qBAAqB;AN0VzB;;AQ7cA;ECIE,eAAe;EAGf,YAAY;AT2cd;;AQ5cA;EACE,gBLmgCwC;EKlgCxC,sBLRa;EKSb,yBLNgB;EOQd,sBP6NgC;EMpOlC,eAAe;EAGf,YAAY;ATodd;;AQtcA;EA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ClB;;AgBp8CA;;EAQI,gBbkVgC;EajVhC,mBAAmB;EACnB,6BbJc;AHq8ClB;;AgB38CA;EAcI,sBAAsB;EACtB,gCbTc;AH08ClB;;AgBh9CA;EAmBI,6Bbbc;AH88ClB;;AgBx7CA;;EAGI,eb4T+B;AH8nCnC;;AgBj7CA;EACE,yBbnCgB;AHu9ClB;;AgBr7CA;;EAKI,yBbvCc;AH49ClB;;AgB17CA;;EAWM,wBAA4C;AhBo7ClD;;AgB/6CA;;;;EAKI,SAAS;AhBi7Cb;;AgBz6CA;EAEI,qCb1DW;AHq+Cf;;AK1+CE;EW2EI,cbvEY;EawEZ,sCbvES;AH0+Cf;;AiBt/CE;;;EAII,yBCgG4D;AlBw5ClE;;AiB5/CE;;;;EAYM,qBCwF0D;AlB+5ClE;;AK5/CE;EYiBM,yBAJsC;AjBm/C9C;;AiBp/CE;;EASQ,yBARoC;AjBw/C9C;;AiB5gDE;;;EAII,yBCgG4D;AlB86ClE;;AiBlhDE;;;;EAYM,qBCwF0D;AlBq7ClE;;AKlhDE;EYiBM,yBAJsC;AjBygD9C;;AiB1gDE;;EASQ,yBARoC;AjB8gD9C;;AiBliDE;;;EAII,yBCgG4D;AlBo8ClE;;AiBxiDE;;;;EAYM,qBCwF0D;AlB28ClE;;AKxiDE;EYiBM,yBAJsC;AjB+hD9C;;AiBhiDE;;EASQ,yBARoC;AjBoiD9C;;AiBxjDE;;;EAII,yBCgG4D;AlB09ClE;;AiB9jDE;;;;EAYM,qBCwF0D;AlBi+ClE;;AK9jDE;EYiBM,yBAJsC;AjBqjD9C;;AiBtjDE;;EASQ,yBARoC;AjB0jD9C;;AiB9kDE;;;EAII,yBCgG4D;AlBg/ClE;;AiBplDE;;;;EAYM,qBCwF0D;AlBu/ClE;;AKplDE;EYiBM,yBAJsC;AjB2kD9C;;AiB5kDE;;EASQ,yBARoC;AjBglD9C;;AiBpmDE;;;EAII,yBCgG4D;AlBsgDlE;;AiB1mDE;;;;EAYM,qBCwF0D;AlB6gDlE;;AK1mDE;EYiBM,yBAJsC;AjBimD9C;;AiBlmDE;;EASQ,yBARoC;AjBsmD9C;;AiB1nDE;;;EAII,yBCgG4D;AlB4hDlE;;AiBhoDE;;;;EAYM,qBCwF0D;AlBmiDlE;;AKhoDE;EYiBM,yBAJsC;AjBunD9C;;AiBxnDE;;EASQ,yBARoC;AjB4nD9C;;AiBhpDE;;;EAII,yBCgG4D;AlBkjDlE;;AiBtpDE;;;;EAYM,qBCwF0D;AlByjDlE;;AKtpDE;EYiBM,yBAJsC;AjB6oD9C;;AiB9oDE;;EASQ,yBARoC;AjBkpD9C;;AiBtqDE;;;EAII,sCdQS;AHgqDf;;AKrqDE;EYiBM,sCAJsC;AjB4pD9C;;AiB7pDE;;EASQ,sCARoC;AjBiqD9C;;AgB3kDA;EAGM,Wb3GS;Ea4GT,yBbpGY;EaqGZ,qBbgQqD;AH40C3D;;AgBjlDA;EAWM,cb5GY;Ea6GZ,yBblHY;EamHZ,qBblHY;AH4rDlB;;AgBrkDA;EACE,Wb3Ha;Ea4Hb,yBbpHgB;AH4rDlB;;AgB1kDA;;;EAOI,qBb4OuD;AH61C3D;;AgBhlDA;EAWI,SAAS;AhBykDb;;AgBplDA;EAgBM,2Cb1IS;AHktDf;;AK7sDE;EW4IM,WbjJO;EakJP,4CblJO;AHutDf;;AcrpDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhBujDvC;EgB5jDG;IASK,SAAS;EhBsjDjB;AACF;;AcjqDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhBmkDvC;EgBxkDG;IASK,SAAS;EhBkkDjB;AACF;;Ac7qDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhB+kDvC;EgBplDG;IASK,SAAS;EhB8kDjB;AACF;;AczrDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhB2lDvC;EgBhmDG;IASK,SAAS;EhB0lDjB;AACF;;AgBzmDA;EAOQ,cAAc;EACd,WAAW;EACX,gBAAgB;EAChB,iCAAiC;AhBsmDzC;;AgBhnDA;EAcU,SAAS;AhBsmDnB;;AmBnxDA;EACE,cAAc;EACd,WAAW;EACX,mCDiH8D;EChH9D,yBhByXkC;ECpQ9B,eAtCY;Ee5EhB,gBhBkR+B;EgBjR/B,gBhBsR+B;EgBrR/B,chBDgB;EgBEhB,sBhBTa;EgBUb,4BAA4B;EAC5B,yBhBPgB;EOOd,sBP6NgC;EiB/N9B,wEjBue4F;AHkzClG;;AoBrxDM;EDdN;ICeQ,gBAAgB;EpByxDtB;AACF;;AmBzyDA;EAsBI,6BAA6B;EAC7B,SAAS;AnBuxDb;;AmB9yDA;EA4BI,kBAAkB;EAClB,0BhBrBc;AH2yDlB;;AqB5yDE;EACE,clBAc;EkBCd,sBlBRW;EkBSX,qBlBqdsE;EkBpdtE,UAAU;EAKR,gDlBaW;AH8xDjB;;AmB3zDA;EAqCI,chB9Bc;EgBgCd,UAAU;AnByxDd;;AmBh0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnByxDd;;AmBh0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnByxDd;;AmBh0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnByxDd;;AmBh0DA;EAqCI,chB9Bc;EgBgCd,UAAU;AnByxDd;;AmBh0DA;EAiDI,yBhB9Cc;EgBgDd,UAAU;AnBkxDd;;AmB9wDA;;;;EAKI,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;AnBgxDpB;;AmB5wDA;EAOI,chB/Dc;EgBgEd,sBhBvEW;AHg1Df;;AmBpwDA;;EAEE,cAAc;EACd,WAAW;AnBuwDb;;AmB7vDA;EACE,iCDyB8D;ECxB9D,oCDwB8D;ECvB9D,gBAAgB;Ef3Bd,kBAAW;Ee6Bb,gBhB+L+B;AHikDjC;;AmB7vDA;EACE,+BDiB8D;EChB9D,kCDgB8D;EdK1D,kBAtCY;EemBhB,gBhB6H+B;AHmoDjC;;AmB7vDA;EACE,gCDU8D;ECT9D,mCDS8D;EdK1D,mBAtCY;Ee0BhB,gBhBuH+B;AHyoDjC;;AmBvvDA;EACE,cAAc;EACd,WAAW;EACX,mBAA2B;EAC3B,gBAAgB;EfDZ,eAtCY;EeyChB,gBhBkK+B;EgBjK/B,chBnHgB;EgBoHhB,6BAA6B;EAC7B,yBAAyB;EACzB,mBAAmC;AnB0vDrC;;AmBpwDA;EAcI,gBAAgB;EAChB,eAAe;AnB0vDnB;;AmB9uDA;EACE,kCD9B8D;EC+B9D,uBhBoPiC;EC9Q7B,mBAtCY;EekEhB,gBhB+E+B;EOxN7B,qBP+N+B;AH4pDnC;;AmB9uDA;EACE,gCDtC8D;ECuC9D,oBhBiPgC;ECnR5B,kBAtCY;Ee0EhB,gBhBsE+B;EOvN7B,qBP8N+B;AHqqDnC;;AmB7uDA;EAGI,YAAY;AnB8uDhB;;AmB1uDA;EACE,YAAY;AnB6uDd;;AmBruDA;EACE,mBhB0U0C;AH85C5C;;AmBruDA;EACE,cAAc;EACd,mBhB2T4C;AH66C9C;;AmBhuDA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,kBAA0C;EAC1C,iBAAyC;AnBmuD3C;;AmBvuDA;;EAQI,kBAA0C;EAC1C,iBAAyC;AnBouD7C;;AmB3tDA;EACE,kBAAkB;EAClB,cAAc;EACd,qBhBgS6C;AH87C/C;;AmB3tDA;EACE,kBAAkB;EAClB,kBhB4R2C;EgB3R3C,qBhB0R6C;AHo8C/C;;AmBjuDA;;EAQI,chBzNc;AHu7DlB;;AmB1tDA;EACE,gBAAgB;AnB6tDlB;;AmB1tDA;EACE,2BAAoB;EAApB,oBAAoB;EACpB,sBAAmB;EAAnB,mBAAmB;EACnB,eAAe;EACf,qBhB6Q4C;AHg9C9C;;AmBjuDA;EAQI,gBAAgB;EAChB,aAAa;EACb,uBhBwQ4C;EgBvQ5C,cAAc;AnB6tDlB;;AqB16DE;EACE,aAAa;EACb,WAAW;EACX,mBlB0c0C;ECjb1C,cAAW;EiBvBX,clBPa;AHo7DjB;;AqB16DE;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,UAAU;EACV,aAAa;EACb,eAAe;EACf,uBlBoyBqC;EkBnyBrC,iBAAiB;EjBmEf,mBAtCY;EiB3Bd,gBlBsO6B;EkBrO7B,WlBxDW;EkByDX,wClBtBa;EOxBb,sBP6NgC;AH+vDpC;;AqBz6DI;;EAEE,SAAiC;ArB46DvC;;AqBn9DI;;;;EA8CE,cAAc;ArB46DpB;;AqB19DI;EAoDE,qBlB1CW;EkB6CT,oCHmCwD;EGlCxD,iRH3B0E;EG4B1E,4BAA4B;EAC5B,2DAA6D;EAC7D,gEH+BwD;AlBy4DhE;;AqBn+DI;EA+DI,qBlBrDS;EkBsDT,gDlBtDS;AH89DjB;;AqBx+DI;EAyEI,oCHiBwD;EGhBxD,kFHgBwD;AlBm5DhE;;AqB7+DI;EAiFE,qBlBvEW;EkB0ET,uCHMwD;EGLxD,ujBAA8J;ArB85DtK;;AqBn/DI;EAyFI,qBlB/ES;EkBgFT,gDlBhFS;AH8+DjB;;AqBx/DI;EAkGI,clBxFS;AHk/DjB;;AqB5/DI;;;EAuGI,cAAc;ArB25DtB;;AqBlgEI;EA+GI,clBrGS;AH4/DjB;;AqBtgEI;EAkHM,qBlBxGO;AHggEjB;;AqB1gEI;EAwHM,qBAAkC;EClJxC,yBDmJ+C;ArBs5DnD;;AqB/gEI;EA+HM,gDlBrHO;AHygEjB;;AqBnhEI;EAmIM,qBlBzHO;AH6gEjB;;AqBvhEI;EA6II,qBlBnIS;AHihEjB;;AqB3hEI;EAkJM,qBlBxIO;EkByIP,gDlBzIO;AHshEjB;;AqBphEE;EACE,aAAa;EACb,WAAW;EACX,mBlB0c0C;ECjb1C,cAAW;EiBvBX,clBVa;AHiiEjB;;AqBphEE;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,UAAU;EACV,aAAa;EACb,eAAe;EACf,uBlBoyBqC;EkBnyBrC,iBAAiB;EjBmEf,mBAtCY;EiB3Bd,gBlBsO6B;EkBrO7B,WlBxDW;EkByDX,wClBzBa;EOrBb,sBP6NgC;AHy2DpC;;AqBnhEI;;EAEE,SAAiC;ArBshEvC;;AqB7jEI;;;;EA8CE,cAAc;ArBshEpB;;AqBpkEI;EAoDE,qBlB7CW;EkBgDT,oCHmCwD;EGlCxD,4UH3B0E;EG4B1E,4BAA4B;EAC5B,2DAA6D;EAC7D,gEH+BwD;AlBm/DhE;;AqB7kEI;EA+DI,qBlBxDS;EkByDT,gDlBzDS;AH2kEjB;;AqBllEI;EAyEI,oCHiBwD;EGhBxD,kFHgBwD;AlB6/DhE;;AqBvlEI;EAiFE,qBlB1EW;EkB6ET,uCHMwD;EGLxD,knBAA8J;ArBwgEtK;;AqB7lEI;EAyFI,qBlBlFS;EkBmFT,gDlBnFS;AH2lEjB;;AqBlmEI;EAkGI,clB3FS;AH+lEjB;;AqBtmEI;;;EAuGI,cAAc;ArBqgEtB;;AqB5mEI;EA+GI,clBxGS;AHymEjB;;AqBhnEI;EAkHM,qBlB3GO;AH6mEjB;;AqBpnEI;EAwHM,qBAAkC;EClJxC,yBDmJ+C;ArBggEnD;;AqBznEI;EA+HM,gDlBxHO;AHsnEjB;;AqB7nEI;EAmIM,qBlB5HO;AH0nEjB;;AqBjoEI;EA6II,qBlBtIS;AH8nEjB;;AqBroEI;EAkJM,qBlB3IO;EkB4IP,gDlB5IO;AHmoEjB;;AmBx5DA;EACE,oBAAa;EAAb,aAAa;EACb,uBAAmB;EAAnB,mBAAmB;EACnB,sBAAmB;EAAnB,mBAAmB;AnB25DrB;;AmB95DA;EASI,WAAW;AnBy5Df;;AcxnEI;EKsNJ;IAeM,oBAAa;IAAb,aAAa;IACb,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;IACvB,gBAAgB;EnBw5DpB;EmB16DF;IAuBM,oBAAa;IAAb,aAAa;IACb,kBAAc;IAAd,cAAc;IACd,uBAAmB;IAAnB,mBAAmB;IACnB,sBAAmB;IAAnB,mBAAmB;IACnB,gBAAgB;EnBs5DpB;EmBj7DF;IAgCM,qBAAqB;IACrB,WAAW;IACX,sBAAsB;EnBo5D1B;EmBt7DF;IAuCM,qBAAqB;EnBk5DzB;EmBz7DF;;IA4CM,WAAW;EnBi5Df;EmB77DF;IAkDM,oBAAa;IAAb,aAAa;IACb,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;IACvB,WAAW;IACX,eAAe;EnB84DnB;EmBp8DF;IAyDM,kBAAkB;IAClB,oBAAc;IAAd,cAAc;IACd,aAAa;IACb,qBhB+KwC;IgB9KxC,cAAc;EnB84DlB;EmB38DF;IAiEM,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;EnB64D3B;EmB/8DF;IAqEM,gBAAgB;EnB64DpB;AACF;;AuB/tEA;EACE,qBAAqB;EAErB,gBpBsR+B;EoBrR/B,cpBMgB;EoBLhB,kBAAkB;EAGlB,sBAAsB;EACtB,yBAAiB;EAAjB,sBAAiB;EAAjB,qBAAiB;EAAjB,iBAAiB;EACjB,6BAA6B;EAC7B,6BAA2C;ECuF3C,yBrB2RkC;ECpQ9B,eAtCY;EoBiBhB,gBrB0L+B;EOlR7B,sBP6NgC;EiB/N9B,qIjBgb6I;AHqzDnJ;;AoBjuEM;EGdN;IHeQ,gBAAgB;EpBquEtB;AACF;;AK/uEE;EkBUE,cpBNc;EoBOd,qBAAqB;AvByuEzB;;AuB1vEA;EAsBI,UAAU;EACV,gDpBMa;AHkuEjB;;AuB/vEA;EA6BI,apBiZ6B;AHq1DjC;;AuBnwEA;EAkCI,eAAsD;AvBquE1D;;AuBvtEA;;EAEE,oBAAoB;AvB0tEtB;;AuBjtEE;EC3DA,WrBCa;EmBDX,yBnB6Ba;EqB3Bf,qBrB2Be;AHqvEjB;;AK5wEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxByxE7H;;AwB7wEE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,gDAAiF;AxB2wEvF;;AwBtwEE;EAEE,WrB1BW;EqB2BX,yBrBCa;EqBAb,qBrBAa;AHwwEjB;;AwBjwEE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxB6yEnN;;AwB9vEI;;EAKI,gDAAiF;AxB8vEzF;;AuBtvEE;EC3DA,WrBCa;EmBDX,yBnBOc;EqBLhB,qBrBKgB;AHgzElB;;AKjzEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxB8zE7H;;AwBlzEE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,iDAAiF;AxBgzEvF;;AwB3yEE;EAEE,WrB1BW;EqB2BX,yBrBrBc;EqBsBd,qBrBtBc;AHm0ElB;;AwBtyEE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBk1EnN;;AwBnyEI;;EAKI,iDAAiF;AxBmyEzF;;AuB3xEE;EC3DA,WrBCa;EmBDX,yBnBoCa;EqBlCf,qBrBkCe;AHwzEjB;;AKt1EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBm2E7H;;AwBv1EE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,+CAAiF;AxBq1EvF;;AwBh1EE;EAEE,WrB1BW;EqB2BX,yBrBQa;EqBPb,qBrBOa;AH20EjB;;AwB30EE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBu3EnN;;AwBx0EI;;EAKI,+CAAiF;AxBw0EzF;;AuBh0EE;EC3DA,WrBCa;EmBDX,yBnBsCa;EqBpCf,qBrBoCe;AH21EjB;;AK33EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBw4E7H;;AwB53EE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,gDAAiF;AxB03EvF;;AwBr3EE;EAEE,WrB1BW;EqB2BX,yBrBUa;EqBTb,qBrBSa;AH82EjB;;AwBh3EE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxB45EnN;;AwB72EI;;EAKI,gDAAiF;AxB62EzF;;AuBr2EE;EC3DA,crBUgB;EmBVd,yBnBmCa;EqBjCf,qBrBiCe;AHm4EjB;;AKh6EE;EmBAE,crBIc;EmBVd,yBEDoF;EASpF,qBATyH;AxB66E7H;;AwBj6EE;EAEE,crBHc;EmBVd,yBEDoF;EAgBpF,qBAhByH;EAqBvH,gDAAiF;AxB+5EvF;;AwB15EE;EAEE,crBjBc;EqBkBd,yBrBOa;EqBNb,qBrBMa;AHs5EjB;;AwBr5EE;;EAGE,crB7Bc;EqB8Bd,yBAzCuK;EA6CvK,qBA7C+M;AxBi8EnN;;AwBl5EI;;EAKI,gDAAiF;AxBk5EzF;;AuB14EE;EC3DA,WrBCa;EmBDX,yBnBiCa;EqB/Bf,qBrB+Be;AH06EjB;;AKr8EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBk9E7H;;AwBt8EE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,+CAAiF;AxBo8EvF;;AwB/7EE;EAEE,WrB1BW;EqB2BX,yBrBKa;EqBJb,qBrBIa;AH67EjB;;AwB17EE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBs+EnN;;AwBv7EI;;EAKI,+CAAiF;AxBu7EzF;;AuB/6EE;EC3DA,crBUgB;EmBVd,yBnBEc;EqBAhB,qBrBAgB;AH8+ElB;;AK1+EE;EmBAE,crBIc;EmBVd,yBEDoF;EASpF,qBATyH;AxBu/E7H;;AwB3+EE;EAEE,crBHc;EmBVd,yBEDoF;EAgBpF,qBAhByH;EAqBvH,iDAAiF;AxBy+EvF;;AwBp+EE;EAEE,crBjBc;EqBkBd,yBrB1Bc;EqB2Bd,qBrB3Bc;AHigFlB;;AwB/9EE;;EAGE,crB7Bc;EqB8Bd,yBAzCuK;EA6CvK,qBA7C+M;AxB2gFnN;;AwB59EI;;EAKI,iDAAiF;AxB49EzF;;AuBp9EE;EC3DA,WrBCa;EmBDX,yBnBSc;EqBPhB,qBrBOgB;AH4gFlB;;AK/gFE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxB4hF7H;;AwBhhFE;EAEE,WrBZW;EmBDX,yBEDoF;EAgBpF,qBAhByH;EAqBvH,8CAAiF;AxB8gFvF;;AwBzgFE;EAEE,WrB1BW;EqB2BX,yBrBnBc;EqBoBd,qBrBpBc;AH+hFlB;;AwBpgFE;;EAGE,WrBtCW;EqBuCX,yBAzCuK;EA6CvK,qBA7C+M;AxBgjFnN;;AwBjgFI;;EAKI,8CAAiF;AxBigFzF;;AuBn/EE;ECPA,crB7Be;EqB8Bf,qBrB9Be;AH4hFjB;;AKnjFE;EmBwDE,WrB7DW;EqB8DX,yBrBlCa;EqBmCb,qBrBnCa;AHkiFjB;;AwB5/EE;EAEE,+CrBxCa;AHsiFjB;;AwB3/EE;EAEE,crB7Ca;EqB8Cb,6BAA6B;AxB6/EjC;;AwB1/EE;;EAGE,WrBhFW;EqBiFX,yBrBrDa;EqBsDb,qBrBtDa;AHkjFjB;;AwB1/EI;;EAKI,+CrB7DS;AHujFjB;;AuBnhFE;ECPA,crBnDgB;EqBoDhB,qBrBpDgB;AHklFlB;;AKnlFE;EmBwDE,WrB7DW;EqB8DX,yBrBxDc;EqByDd,qBrBzDc;AHwlFlB;;AwB5hFE;EAEE,iDrB9Dc;AH4lFlB;;AwB3hFE;EAEE,crBnEc;EqBoEd,6BAA6B;AxB6hFjC;;AwB1hFE;;EAGE,WrBhFW;EqBiFX,yBrB3Ec;EqB4Ed,qBrB5Ec;AHwmFlB;;AwB1hFI;;EAKI,iDrBnFU;AH6mFlB;;AuBnjFE;ECPA,crBtBe;EqBuBf,qBrBvBe;AHqlFjB;;AKnnFE;EmBwDE,WrB7DW;EqB8DX,yBrB3Ba;EqB4Bb,qBrB5Ba;AH2lFjB;;AwB5jFE;EAEE,+CrBjCa;AH+lFjB;;AwB3jFE;EAEE,crBtCa;EqBuCb,6BAA6B;AxB6jFjC;;AwB1jFE;;EAGE,WrBhFW;EqBiFX,yBrB9Ca;EqB+Cb,qBrB/Ca;AH2mFjB;;AwB1jFI;;EAKI,+CrBtDS;AHgnFjB;;AuBnlFE;ECPA,crBpBe;EqBqBf,qBrBrBe;AHmnFjB;;AKnpFE;EmBwDE,WrB7DW;EqB8DX,yBrBzBa;EqB0Bb,qBrB1Ba;AHynFjB;;AwB5lFE;EAEE,gDrB/Ba;AH6nFjB;;AwB3lFE;EAEE,crBpCa;EqBqCb,6BAA6B;AxB6lFjC;;AwB1lFE;;EAGE,WrBhFW;EqBiFX,yBrB5Ca;EqB6Cb,qBrB7Ca;AHyoFjB;;AwB1lFI;;EAKI,gDrBpDS;AH8oFjB;;AuBnnFE;ECPA,crBvBe;EqBwBf,qBrBxBe;AHspFjB;;AKnrFE;EmBwDE,crBpDc;EqBqDd,yBrB5Ba;EqB6Bb,qBrB7Ba;AH4pFjB;;AwB5nFE;EAEE,+CrBlCa;AHgqFjB;;AwB3nFE;EAEE,crBvCa;EqBwCb,6BAA6B;AxB6nFjC;;AwB1nFE;;EAGE,crBvEc;EqBwEd,yBrB/Ca;EqBgDb,qBrBhDa;AH4qFjB;;AwB1nFI;;EAKI,+CrBvDS;AHirFjB;;AuBnpFE;ECPA,crBzBe;EqB0Bf,qBrB1Be;AHwrFjB;;AKntFE;EmBwDE,WrB7DW;EqB8DX,yBrB9Ba;EqB+Bb,qBrB/Ba;AH8rFjB;;AwB5pFE;EAEE,+CrBpCa;AHksFjB;;AwB3pFE;EAEE,crBzCa;EqB0Cb,6BAA6B;AxB6pFjC;;AwB1pFE;;EAGE,WrBhFW;EqBiFX,yBrBjDa;EqBkDb,qBrBlDa;AH8sFjB;;AwB1pFI;;EAKI,+CrBzDS;AHmtFjB;;AuBnrFE;ECPA,crBxDgB;EqByDhB,qBrBzDgB;AHuvFlB;;AKnvFE;EmBwDE,crBpDc;EqBqDd,yBrB7Dc;EqB8Dd,qBrB9Dc;AH6vFlB;;AwB5rFE;EAEE,iDrBnEc;AHiwFlB;;AwB3rFE;EAEE,crBxEc;EqByEd,6BAA6B;AxB6rFjC;;AwB1rFE;;EAGE,crBvEc;EqBwEd,yBrBhFc;EqBiFd,qBrBjFc;AH6wFlB;;AwB1rFI;;EAKI,iDrBxFU;AHkxFlB;;AuBntFE;ECPA,crBjDgB;EqBkDhB,qBrBlDgB;AHgxFlB;;AKnxFE;EmBwDE,WrB7DW;EqB8DX,yBrBtDc;EqBuDd,qBrBvDc;AHsxFlB;;AwB5tFE;EAEE,8CrB5Dc;AH0xFlB;;AwB3tFE;EAEE,crBjEc;EqBkEd,6BAA6B;AxB6tFjC;;AwB1tFE;;EAGE,WrBhFW;EqBiFX,yBrBzEc;EqB0Ed,qBrB1Ec;AHsyFlB;;AwB1tFI;;EAKI,8CrBjFU;AH2yFlB;;AuBxuFA;EACE,gBpB4M+B;EoB3M/B,cpBjDe;EoBkDf,qBpB2F4C;AHgpF9C;;AKpzFE;EkB4EE,cpByF8D;EoBxF9D,0BpByF+C;AHmpFnD;;AuBnvFA;EAYI,0BpBoF+C;AHupFnD;;AuBvvFA;EAiBI,cpBtFc;EoBuFd,oBAAoB;AvB0uFxB;;AuB/tFA;ECPE,oBrB0SgC;ECnR5B,kBAtCY;EoBiBhB,gBrB+H+B;EOvN7B,qBP8N+B;AHqmFnC;;AuBluFA;ECXE,uBrBqSiC;EC9Q7B,mBAtCY;EoBiBhB,gBrBgI+B;EOxN7B,qBP+N+B;AH2mFnC;;AuBhuFA;EACE,cAAc;EACd,WAAW;AvBmuFb;;AuBruFA;EAMI,kBpBuT+B;AH46EnC;;AuB9tFA;;;EAII,WAAW;AvBguFf;;AyB32FA;ELgBM,gCjBiP2C;AH8mFjD;;AoB31FM;EKpBN;ILqBQ,gBAAgB;EpB+1FtB;AACF;;AyBr3FA;EAII,UAAU;AzBq3Fd;;AyBj3FA;EAEI,aAAa;AzBm3FjB;;AyB/2FA;EACE,kBAAkB;EAClB,SAAS;EACT,gBAAgB;ELDZ,6BjBkPwC;AHkoF9C;;AoBh3FM;EKNN;ILOQ,gBAAgB;EpBo3FtB;AACF;;A0Bz4FA;;;;EAIE,kBAAkB;A1B44FpB;;A0Bz4FA;EACE,mBAAmB;A1B44FrB;;A2Bx3FI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;EAhCf,uBAA8B;EAC9B,qCAA4C;EAC5C,gBAAgB;EAChB,oCAA2C;A3B45F7C;;A2Bv2FI;EACE,cAAc;A3B02FpB;;A0Bp5FA;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,avBwpBsC;EuBvpBtC,aAAa;EACb,WAAW;EACX,gBvBguBuC;EuB/tBvC,iBvBguBmC;EuB/tBnC,oBAA4B;EtBsGxB,eAtCY;EsB9DhB,cvBXgB;EuBYhB,gBAAgB;EAChB,gBAAgB;EAChB,sBvBvBa;EuBwBb,4BAA4B;EAC5B,qCvBfa;EOCX,sBP6NgC;AHysFpC;;A0B/4FI;EACE,WAAW;EACX,OAAO;A1Bk5Fb;;A0B/4FI;EACE,QAAQ;EACR,UAAU;A1Bk5FhB;;Act4FI;EYnBA;IACE,WAAW;IACX,OAAO;E1B65FX;E0B15FE;IACE,QAAQ;IACR,UAAU;E1B45Fd;AACF;;Acj5FI;EYnBA;IACE,WAAW;IACX,OAAO;E1Bw6FX;E0Br6FE;IACE,QAAQ;IACR,UAAU;E1Bu6Fd;AACF;;Ac55FI;EYnBA;IACE,WAAW;IACX,OAAO;E1Bm7FX;E0Bh7FE;IACE,QAAQ;IACR,UAAU;E1Bk7Fd;AACF;;Acv6FI;EYnBA;IACE,WAAW;IACX,OAAO;E1B87FX;E0B37FE;IACE,QAAQ;IACR,UAAU;E1B67Fd;AACF;;A0Bv7FA;EAEI,SAAS;EACT,YAAY;EACZ,aAAa;EACb,uBvB8rBuC;AH2vE3C;;A2Bx9FI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;EAzBf,aAAa;EACb,qCAA4C;EAC5C,0BAAiC;EACjC,oCAA2C;A3Bq/F7C;;A2Bv8FI;EACE,cAAc;A3B08FpB;;A0Bh8FA;EAEI,MAAM;EACN,WAAW;EACX,UAAU;EACV,aAAa;EACb,qBvBgrBuC;AHkxE3C;;A2B/+FI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;EAlBf,mCAA0C;EAC1C,eAAe;EACf,sCAA6C;EAC7C,wBAA+B;A3BqgGjC;;A2B99FI;EACE,cAAc;A3Bi+FpB;;A2B9/FI;EDmDE,iBAAiB;A1B+8FvB;;A0B18FA;EAEI,MAAM;EACN,WAAW;EACX,UAAU;EACV,aAAa;EACb,sBvB+pBuC;AH6yE3C;;A2B1gGI;EACE,qBAAqB;EACrB,oBxB+N0C;EwB9N1C,uBxB6N0C;EwB5N1C,WAAW;A3B6gGjB;;A2BjhGI;EAgBI,aAAa;A3BqgGrB;;A2BlgGM;EACE,qBAAqB;EACrB,qBxB4MwC;EwB3MxC,uBxB0MwC;EwBzMxC,WAAW;EA9BjB,mCAA0C;EAC1C,yBAAgC;EAChC,sCAA6C;A3BoiG/C;;A2BngGI;EACE,cAAc;A3BsgGpB;;A2BhhGM;EDiDA,iBAAiB;A1Bm+FvB;;A0B59FA;EAKI,WAAW;EACX,YAAY;A1B29FhB;;A0Bt9FA;EE9GE,SAAS;EACT,gBAAmB;EACnB,gBAAgB;EAChB,6BzBCgB;AHukGlB;;A0Bt9FA;EACE,cAAc;EACd,WAAW;EACX,uBvBmpBwC;EuBlpBxC,WAAW;EACX,gBvBgK+B;EuB/J/B,cvBhHgB;EuBiHhB,mBAAmB;EAEnB,mBAAmB;EACnB,6BAA6B;EAC7B,SAAS;A1Bw9FX;;AK7kGE;EqBoIE,cvBmnBqD;EuBlnBrD,qBAAqB;EJ/IrB,yBnBGc;AH0lGlB;;A0Bz+FA;EAiCI,WvBpJW;EuBqJX,qBAAqB;EJtJrB,yBnB6Ba;AHskGjB;;A0B/+FA;EAwCI,cvBtJc;EuBuJd,oBAAoB;EACpB,6BAA6B;A1B28FjC;;A0Bn8FA;EACE,cAAc;A1Bs8FhB;;A0Bl8FA;EACE,cAAc;EACd,sBvB6lBwC;EuB5lBxC,gBAAgB;EtBrDZ,mBAtCY;EsB6FhB,cvBzKgB;EuB0KhB,mBAAmB;A1Bq8FrB;;A0Bj8FA;EACE,cAAc;EACd,uBvBmlBwC;EuBllBxC,cvB9KgB;AHknGlB;;A6B/nGA;;EAEE,kBAAkB;EAClB,2BAAoB;EAApB,oBAAoB;EACpB,sBAAsB;A7BkoGxB;;A6BtoGA;;EAOI,kBAAkB;EAClB,kBAAc;EAAd,cAAc;A7BooGlB;;AKnoGE;;EwBII,UAAU;A7BooGhB;;A6BjpGA;;;;EAkBM,UAAU;A7BsoGhB;;A6BhoGA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,oBAA2B;EAA3B,2BAA2B;A7BmoG7B;;A6BtoGA;EAMI,WAAW;A7BooGf;;A6BhoGA;;EAII,iB1BmM6B;AH87FjC;;A6BroGA;;EnBHI,0BmBa8B;EnBZ9B,6BmBY8B;A7BioGlC;;A6B3oGA;;EnBWI,yBmBI6B;EnBH7B,4BmBG6B;A7BkoGjC;;A6BlnGA;EACE,wBAAmC;EACnC,uBAAkC;A7BqnGpC;;A6BvnGA;;;EAOI,cAAc;A7BsnGlB;;A6BnnGE;EACE,eAAe;A7BsnGnB;;A6BlnGA;EACE,uBAAsC;EACtC,sBAAqC;A7BqnGvC;;A6BlnGA;EACE,sBAAsC;EACtC,qBAAqC;A7BqnGvC;;A6BjmGA;EACE,0BAAsB;EAAtB,sBAAsB;EACtB,qBAAuB;EAAvB,uBAAuB;EACvB,qBAAuB;EAAvB,uBAAuB;A7BomGzB;;A6BvmGA;;EAOI,WAAW;A7BqmGf;;A6B5mGA;;EAYI,gB1BkH6B;AHm/FjC;;A6BjnGA;;EnBrEI,6BmBuF+B;EnBtF/B,4BmBsF+B;A7BqmGnC;;A6BvnGA;;EnBnFI,yBmB0G4B;EnBzG5B,0BmByG4B;A7BsmGhC;;A6BrlGA;;EAGI,gBAAgB;A7BulGpB;;A6B1lGA;;;;EAOM,kBAAkB;EAClB,sBAAsB;EACtB,oBAAoB;A7B0lG1B;;A8BnvGA;EACE,kBAAkB;EAClB,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,uBAAoB;EAApB,oBAAoB;EACpB,WAAW;A9BsvGb;;A8B3vGA;;;;EAWI,kBAAkB;EAClB,kBAAc;EAAd,cAAc;EACd,SAAS;EACT,YAAY;EACZ,gBAAgB;A9BuvGpB;;A8BtwGA;;;;;;;;;;;;EAoBM,iB3BkN2B;AH+iGjC;;A8BrxGA;;;EA4BI,UAAU;A9B+vGd;;A8B3xGA;EAiCI,UAAU;A9B8vGd;;A8B/xGA;;EpB0CI,yBoBJmD;EpBKnD,4BoBLmD;A9B+vGvD;;A8BryGA;EA4CI,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;A9B6vGvB;;A8B1yGA;;EpB0CI,yBoBMsE;EpBLtE,4BoBKsE;A9BgwG1E;;A8BhzGA;;;EpB4BI,0BoB2BgC;EpB1BhC,6BoB0BgC;A9BgwGpC;;A8BvzGA;;;EpB4BI,0BoBmCgC;EpBlChC,6BoBkCgC;A9B+vGpC;;A8BnvGA;;EAEE,oBAAa;EAAb,aAAa;A9BsvGf;;A8BxvGA;;EAQI,kBAAkB;EAClB,UAAU;A9BqvGd;;A8B9vGA;;EAYM,UAAU;A9BuvGhB;;A8BnwGA;;;;;;;;EAoBI,iB3BuI6B;AHmnGjC;;A8BtvGA;EAAuB,kB3BmIU;AHunGjC;;A8BzvGA;EAAsB,iB3BkIW;AH2nGjC;;A8BrvGA;EACE,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,yB3B8QkC;E2B7QlC,gBAAgB;E1BSZ,eAtCY;E0B+BhB,gB3BuK+B;E2BtK/B,gB3B2K+B;E2B1K/B,c3B5GgB;E2B6GhB,kBAAkB;EAClB,mBAAmB;EACnB,yB3BpHgB;E2BqHhB,yB3BnHgB;EOOd,sBP6NgC;AHwoGpC;;A8BrwGA;;EAkBI,aAAa;A9BwvGjB;;A8B9uGA;;EAEE,gCZtB8D;AlBuwGhE;;A8B9uGA;;;;;;EAME,oB3ByPgC;ECnR5B,kBAtCY;E0BkEhB,gB3B8E+B;EOvN7B,qBP8N+B;AH6pGnC;;A8B9uGA;;EAEE,kCZvC8D;AlBwxGhE;;A8B9uGA;;;;;;EAME,uB3BmOiC;EC9Q7B,mBAtCY;E0BmFhB,gB3B8D+B;EOxN7B,qBP+N+B;AH6qGnC;;A8B9uGA;;EAEE,sBAA0E;A9BivG5E;;A8BtuGA;;;;;;;;EpB3JI,0BoBmK4B;EpBlK5B,6BoBkK4B;A9B0uGhC;;A8BvuGA;;;;;;EpBxJI,yBoB8J2B;EpB7J3B,4BoB6J2B;A9B2uG/B;;A+Bh7GA;EACE,kBAAkB;EAClB,UAAU;EACV,cAAc;EACd,kBAA+C;EAC/C,oBAAqE;EACrE,iCAAmB;EAAnB,mBAAmB;A/Bm7GrB;;A+Bh7GA;EACE,2BAAoB;EAApB,oBAAoB;EACpB,kB5Bwf0C;AH27F5C;;A+Bh7GA;EACE,kBAAkB;EAClB,OAAO;EACP,WAAW;EACX,W5Bof0C;E4Bnf1C,eAAkF;EAClF,UAAU;A/Bm7GZ;;A+Bz7GA;EASI,W5BzBW;E4B0BX,qB5BEa;EmB7Bb,yBnB6Ba;AHm7GjB;;A+B/7GA;EAoBM,gD5BRW;AHu7GjB;;A+Bn8GA;EAyBI,qB5BqbsE;AHy/F1E;;A+Bv8GA;EA6BI,W5B7CW;E4B8CX,yB5Bif8E;E4Bhf9E,qB5Bgf8E;AH87FlF;;A+B78GA;EAuCM,c5BjDY;AH29GlB;;A+Bj9GA;EA0CQ,yB5BxDU;AHm+GlB;;A+Bj6GA;EACE,kBAAkB;EAClB,gBAAgB;EAEhB,mBAAmB;A/Bm6GrB;;A+Bv6GA;EASI,kBAAkB;EAClB,YAA+E;EAC/E,aAA+D;EAC/D,cAAc;EACd,W5BubwC;E4BtbxC,Y5BsbwC;E4BrbxC,oBAAoB;EACpB,WAAW;EACX,sB5BrFW;E4BsFX,yB5B+I6B;AHmxGjC;;A+Bp7GA;EAwBI,kBAAkB;EAClB,YAA+E;EAC/E,aAA+D;EAC/D,cAAc;EACd,W5BwawC;E4BvaxC,Y5BuawC;E4BtaxC,WAAW;EACX,mCAAgE;A/Bg6GpE;;A+Bv5GA;ErBjGI,sBP6NgC;AH+xGpC;;A+B35GA;EAOM,kOb7D4E;AlBq9GlF;;A+B/5GA;EAaM,qB5B7FW;EmB7Bb,yBnB6Ba;AHo/GjB;;A+Bp6GA;EAkBM,+KbxE4E;AlB89GlF;;A+Bx6GA;ET7GI,wCnB6Ba;AH4/GjB;;A+B56GA;ET7GI,wCnB6Ba;AHggHjB;;A+B54GA;EAGI,kB5ByZ+C;AHo/FnD;;A+Bh5GA;EAQM,8KblG4E;AlB8+GlF;;A+Bp5GA;ETjJI,wCnB6Ba;AH4gHjB;;A+Bh4GA;EACE,qBAA2D;A/Bm4G7D;;A+Bp4GA;EAKM,cAAqD;EACrD,c5BiY+E;E4BhY/E,mBAAmB;EAEnB,qB5B+X4E;AHmgGlF;;A+B34GA;EAaM,wBblE0D;EamE1D,0BbnE0D;EaoE1D,uBbhD0D;EaiD1D,wBbjD0D;EakD1D,yB5BpLY;E4BsLZ,qB5BqX4E;EiBviB5E,iJjByf+H;EiBzf/H,yIjByf+H;EiBzf/H,8KjByf+H;AH2jGrI;;AoBhjHM;EW2JN;IX1JQ,gBAAgB;EpBojHtB;AACF;;A+B35GA;EA0BM,sB5BlMS;E4BmMT,sCAA4E;EAA5E,8BAA4E;A/Bq4GlF;;A+Bh6GA;ETzKI,wCnB6Ba;AHgjHjB;;A+Bv3GA;EACE,qBAAqB;EACrB,WAAW;EACX,mCbrG8D;EasG9D,0C5BmKkC;ECpQ9B,eAtCY;E2B0IhB,gB5B4D+B;E4B3D/B,gB5BgE+B;E4B/D/B,c5BvNgB;E4BwNhB,sBAAsB;EACtB,uO5BkW+I;E4BjW/I,yB5B7NgB;EOOd,sBP6NgC;E4BJlC,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;A/Bw3GlB;;A+Bv4GA;EAkBI,qB5BuPsE;E4BtPtE,UAAU;EAKR,gD5BjNW;AHskHjB;;A+B74GA;EAiCM,c5B/OY;E4BgPZ,sB5BvPS;AHumHf;;A+Bl5GA;EAwCI,YAAY;EACZ,sB5B8HgC;E4B7HhC,sBAAsB;A/B82G1B;;A+Bx5GA;EA8CI,c5B7Pc;E4B8Pd,yB5BlQc;AHgnHlB;;A+B75GA;EAoDI,aAAa;A/B62GjB;;A+Bj6GA;EAyDI,kBAAkB;EAClB,0B5BxQc;AHonHlB;;A+Bx2GA;EACE,kCbjK8D;EakK9D,oB5BgHkC;E4B/GlC,uB5B+GkC;E4B9GlC,oB5B+GiC;EC9Q7B,mBAtCY;AJijHlB;;A+Bx2GA;EACE,gCbzK8D;Ea0K9D,mB5B6GiC;E4B5GjC,sB5B4GiC;E4B3GjC,kB5B4GgC;ECnR5B,kBAtCY;AJyjHlB;;A+Bn2GA;EACE,kBAAkB;EAClB,qBAAqB;EACrB,WAAW;EACX,mCbzL8D;Ea0L9D,gBAAgB;A/Bs2GlB;;A+Bn2GA;EACE,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,mCbjM8D;EakM9D,SAAS;EACT,gBAAgB;EAChB,UAAU;A/Bs2GZ;;A+B72GA;EAUI,qB5BoKsE;E4BnKtE,gD5B/Ra;AHsoHjB;;A+Bl3GA;;EAiBI,yB5B/Tc;AHqqHlB;;A+Bv3GA;EAsBM,iB5B2TQ;AH0iGd;;A+B33GA;EA2BI,0BAA0B;A/Bo2G9B;;A+Bh2GA;EACE,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,OAAO;EACP,UAAU;EACV,mCblO8D;EamO9D,yB5BsCkC;E4BrClC,gBAAgB;EAEhB,gB5BjE+B;E4BkE/B,gB5B7D+B;E4B8D/B,c5BpVgB;E4BqVhB,sB5B5Va;E4B6Vb,yB5BzVgB;EOOd,sBP6NgC;AHw9GpC;;A+Bj3GA;EAmBI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,UAAU;EACV,cAAc;EACd,6BbrP4D;EasP5D,yB5BmBgC;E4BlBhC,gB5B7E6B;E4B8E7B,c5BpWc;E4BqWd,iBAAiB;ET7WjB,yBnBGc;E4B4Wd,oBAAoB;ErBnWpB,kCqBoWgF;A/Bk2GpF;;A+Bx1GA;EACE,WAAW;EACX,cb3Q2B;Ea4Q3B,UAAU;EACV,6BAA6B;EAC7B,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;A/B21GlB;;A+Bh2GA;EAQI,UAAU;A/B41Gd;;A+Bp2GA;EAY8B,gE5BzWb;AHqsHjB;;A+Bx2GA;EAa8B,gE5B1Wb;AHysHjB;;A+B52GA;EAc8B,gE5B3Wb;AH6sHjB;;A+Bh3GA;EAkBI,SAAS;A/Bk2Gb;;A+Bp3GA;EAsBI,W5BmN6C;E4BlN7C,Y5BkN6C;E4BjN7C,oBAAyE;ETlZzE,yBnB6Ba;E4BuXb,S5BkN0C;EO1lB1C,mBP2lB6C;EiB7lB3C,oHjByf+H;EiBzf/H,4GjByf+H;E4B3GjI,wBAAgB;EAAhB,gBAAgB;A/Bi2GpB;;AoB3uHM;EW4WN;IX3WQ,wBAAgB;IAAhB,gBAAgB;EpB+uHtB;AACF;;A+Br4GA;ET1XI,yBnB2mB2E;AHwpG/E;;A+Bz4GA;EAsCI,W5B4LoC;E4B3LpC,c5B4LqC;E4B3LrC,kBAAkB;EAClB,e5B2LuC;E4B1LvC,yB5Bhac;E4Biad,yBAAyB;ErBzZzB,mBPolBoC;AH6qGxC;;A+Bn5GA;EAiDI,W5BwL6C;E4BvL7C,Y5BuL6C;EmBnmB7C,yBnB6Ba;E4BiZb,S5BwL0C;EO1lB1C,mBP2lB6C;EiB7lB3C,iHjByf+H;EiBzf/H,4GjByf+H;E4BjFjI,qBAAgB;EAAhB,gBAAgB;A/Bq2GpB;;AoBzwHM;EW4WN;IX3WQ,qBAAgB;IAAhB,gBAAgB;EpB6wHtB;AACF;;A+Bn6GA;ET1XI,yBnB2mB2E;AHsrG/E;;A+Bv6GA;EAgEI,W5BkKoC;E4BjKpC,c5BkKqC;E4BjKrC,kBAAkB;EAClB,e5BiKuC;E4BhKvC,yB5B1bc;E4B2bd,yBAAyB;ErBnbzB,mBPolBoC;AH2sGxC;;A+Bj7GA;EA2EI,W5B8J6C;E4B7J7C,Y5B6J6C;E4B5J7C,aAAa;EACb,oB5BtE+B;E4BuE/B,mB5BvE+B;EmBlY/B,yBnB6Ba;E4B8ab,S5B2J0C;EO1lB1C,mBP2lB6C;EiB7lB3C,gHjByf+H;EiBzf/H,4GjByf+H;E4BpDjI,gBAAgB;A/By2GpB;;AoB1yHM;EW4WN;IX3WQ,oBAAgB;IAAhB,gBAAgB;EpB8yHtB;AACF;;A+Bp8GA;ET1XI,yBnB2mB2E;AHutG/E;;A+Bx8GA;EA6FI,W5BqIoC;E4BpIpC,c5BqIqC;E4BpIrC,kBAAkB;EAClB,e5BoIuC;E4BnIvC,6BAA6B;EAC7B,yBAAyB;EACzB,oBAA4C;A/B+2GhD;;A+Bl9GA;EAwGI,yB5B9dc;EOQd,mBPolBoC;AHivGxC;;A+Bv9GA;EA6GI,kBAAkB;EAClB,yB5Bpec;EOQd,mBPolBoC;AHuvGxC;;A+B79GA;EAoHM,yB5BxeY;AHq1HlB;;A+Bj+GA;EAwHM,eAAe;A/B62GrB;;A+Br+GA;EA4HM,yB5BhfY;AH61HlB;;A+Bz+GA;EAgIM,eAAe;A/B62GrB;;A+B7+GA;EAoIM,yB5BxfY;AHq2HlB;;A+Bx2GA;;;EXzfM,4GjByf+H;AH82GrI;;AoBn2HM;EWqfN;;;IXpfQ,gBAAgB;EpBy2HtB;AACF;;AgC13HA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,eAAe;EACf,gBAAgB;EAChB,gBAAgB;AhC63HlB;;AgC13HA;EACE,cAAc;EACd,oB7ByqBsC;AHotGxC;;AK53HE;E2BGE,qBAAqB;AhC63HzB;;AgCn4HA;EAWI,c7BXc;E6BYd,oBAAoB;EACpB,eAAe;AhC43HnB;;AgCp3HA;EACE,gC7BzBgB;AHg5HlB;;AgCx3HA;EAII,mB7BsM6B;E6BrM7B,6BAAgD;EtBZhD,+BPoNgC;EOnNhC,gCPmNgC;AHkrHpC;;AKj5HE;E2B2BI,qC7BjCY;AH25HlB;;AgCn4HA;EAaM,c7BlCY;E6BmCZ,6BAA6B;EAC7B,yBAAyB;AhC03H/B;;AgCz4HA;;EAqBI,c7BzCc;E6B0Cd,sB7BjDW;E6BkDX,kC7BlDW;AH26Hf;;AgCh5HA;EA4BI,gB7B8K6B;EOjN7B,yBsBqC4B;EtBpC5B,0BsBoC4B;AhCw3HhC;;AgC/2HA;EtBvDI,sBP6NgC;AH6sHpC;;AgCn3HA;;EAOI,W7BzEW;E6B0EX,yB7B9Ca;AH+5HjB;;AgCx2HA;;EAGI,kBAAc;EAAd,cAAc;EA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AKjxIE;E4BmQM,yB9BlQO;AHoxIf;;AiC3gIA;EAEI,W9BrRW;AHkyIf;;AKzxIE;E4B+QI,W9BxRS;AHsyIf;;AiCnhIA;EAWM,+B9B9RS;AH0yIf;;AKjyIE;E4BwRM,gC9BjSO;AH8yIf;;AiC3hIA;EAkBQ,gC9BrSO;AHkzIf;;AiC/hIA;;;;EA0BM,W9B7SS;AHyzIf;;AiCtiIA;EA+BI,+B9BlTW;E8BmTX,sC9BnTW;AH8zIf;;AiC3iIA;EAoCI,yRfjQ8E;AlB4wIlF;;AiC/iIA;EAwCI,+B9B3TW;AHs0If;;AiCnjIA;EA0CM,W9B7TS;AH00If;;AKj0IE;E4BuTM,W9BhUO;AH80If;;AkCj1IA;EACE,kBAAkB;EAClB,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,YAAY;EAEZ,qBAAqB;EACrB,sB/BJa;E+BKb,2BAA2B;EAC3B,sC/BIa;EOCX,sBP6NgC;AHknIpC;;AkC71IA;EAaI,eAAe;EACf,cAAc;AlCo1IlB;;AkCl2IA;EAkBI,mBAAmB;EACnB,sBAAsB;AlCo1I1B;;AkCv2IA;EAsBM,mBAAmB;ExBCrB,2CQmH4D;ERlH5D,4CQkH4D;AlBmuIhE;;AkC72IA;EA2BM,sBAAsB;ExBUxB,+CQqG4D;ERpG5D,8CQoG4D;AlByuIhE;;AkCn3IA;;EAoCI,aAAa;AlCo1IjB;;AkCh1IA;EAGE,kBAAc;EAAd,cAAc;EAGd,eAAe;EACf,gB/B8wByC;AHikH3C;;AkC30IA;EACE,sB/BwwBwC;AHskH1C;;AkC30IA;EACE,qBAA+B;EAC/B,gBAAgB;AlC80IlB;;AkC30IA;EACE,gBAAgB;AlC80IlB;;AKn4IE;E6B0DE,qBAAqB;AlC60IzB;;AkC/0IA;EAMI,oB/BuvBuC;AHslH3C;;AkCr0IA;EACE,wB/B8uByC;E+B7uBzC,gBAAgB;EAEhB,qC/BrEa;E+BsEb,6C/BtEa;AH64If;;AkC50IA;ExBhEI,0DwBwE8E;AlCw0IlF;;AkCp0IA;EACE,wB/BkuByC;E+BhuBzC,qC/BhFa;E+BiFb,0C/BjFa;AHu5If;;AkC10IA;ExB5EI,0DQ4H4D;AlB8xIhE;;AkC9zIA;EACE,uBAAiC;EACjC,uB/BgtBwC;E+B/sBxC,sBAAgC;EAChC,gBAAgB;AlCi0IlB;;AkC9zIA;EACE,uBAAiC;EACjC,sBAAgC;AlCi0IlC;;AkC7zIA;EACE,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,OAAO;EACP,gB/B2sByC;EO1zBvC,kCQ4H4D;AlBozIhE;;AkC7zIA;;;EAGE,oBAAc;EAAd,cAAc;EACd,WAAW;AlCg0Ib;;AkC7zIA;;ExBjHI,2CQmH4D;ERlH5D,4CQkH4D;AlBi0IhE;;AkC9zIA;;ExBxGI,+CQqG4D;ERpG5D,8CQoG4D;AlBu0IhE;;AkC5zIA;EAEI,mB/BmrBsD;AH2oH1D;;Ac75II;EoB6FJ;IAMI,oBAAa;IAAb,aAAa;IACb,uBAAmB;IAAnB,mBAAmB;IACnB,mB/B6qBsD;I+B5qBtD,kB/B4qBsD;EHmpHxD;EkCx0IF;IAaM,gBAAY;IAAZ,YAAY;IACZ,kB/BuqBoD;I+BtqBpD,gBAAgB;IAChB,iB/BqqBoD;EHypHxD;AACF;;AkCrzIA;EAII,mB/BupBsD;AH8pH1D;;Ach7II;EoBuHJ;IAQI,oBAAa;IAAb,aAAa;IACb,uBAAmB;IAAnB,mBAAmB;ElCszIrB;EkC/zIF;IAcM,gBAAY;IAAZ,YAAY;IACZ,gBAAgB;ElCozIpB;EkCn0IF;IAkBQ,cAAc;IACd,cAAc;ElCozIpB;EkCv0IF;IxBjJI,0BwB0KoC;IxBzKpC,6BwByKoC;ElCkzItC;EkC30IF;;IA8BY,0BAA0B;ElCizIpC;EkC/0IF;;IAmCY,6BAA6B;ElCgzIvC;EkCn1IF;IxBnII,yBwB2KmC;IxB1KnC,4BwB0KmC;ElC+yIrC;EkCv1IF;;IA6CY,yBAAyB;ElC8yInC;EkC31IF;;IAkDY,4BAA4B;ElC6yItC;AACF;;AkCjyIA;EAEI,sB/B4kBsC;AHutH1C;;Ac39II;EoBsLJ;IAMI,uB/BylBiC;I+BzlBjC,oB/BylBiC;I+BzlBjC,e/BylBiC;I+BxlBjC,2B/BylBuC;I+BzlBvC,wB/BylBuC;I+BzlBvC,mB/BylBuC;I+BxlBvC,UAAU;IACV,SAAS;ElCoyIX;EkC7yIF;IAYM,qBAAqB;IACrB,WAAW;ElCoyIf;AACF;;AkC3xIA;EACE,qBAAqB;AlC8xIvB;;AkC/xIA;EAII,gBAAgB;AlC+xIpB;;AkCnyIA;EAOM,gBAAgB;ExBvOlB,6BwBwOiC;ExBvOjC,4BwBuOiC;AlCiyIrC;;AkCzyIA;ExB9OI,yBwB0P8B;ExBzP9B,0BwByP8B;AlCkyIlC;;AkC9yIA;ExBvPI,gBwBuQ0B;EACxB,mB/B9C2B;AHg1IjC;;AmC5jJA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,qBhCiiCsC;EgChiCtC,mBhCmiCsC;EgCjiCtC,gBAAgB;EAChB,yBhCEgB;EOSd,sBP6NgC;AHu1IpC;;AmC3jJA;EAGI,oBhCuhCqC;AHqiHzC;;AmC/jJA;EAMM,WAAW;EACX,qBhCmhCmC;EgClhCnC,chCNY;EgCOZ,YhCwhCuC;AHqiH7C;;AmCtkJA;EAoBI,0BAA0B;AnCsjJ9B;;AmC1kJA;EAwBI,qBAAqB;AnCsjJzB;;AmC9kJA;EA4BI,chC1Bc;AHglJlB;;AoC7lJA;EACE,oBAAa;EAAb,aAAa;E7BGb,eAAe;EACf,gBAAgB;EGad,sBP6NgC;AHq3IpC;;AoC9lJA;EACE,kBAAkB;EAClB,cAAc;EACd,uBjCgxBwC;EiC/wBxC,iBjCkO+B;EiCjO/B,iBjCmxBsC;EiClxBtC,cjCuBe;EiCrBf,sBjCPa;EiCQb,yBjCLgB;AHqmJlB;;AoCzmJA;EAYI,UAAU;EACV,cjC8J8D;EiC7J9D,qBAAqB;EACrB,yBjCZc;EiCad,qBjCZc;AH6mJlB;;AoCjnJA;EAoBI,UAAU;EACV,UjC2wBiC;EiC1wBjC,gDjCOa;AH0lJjB;;AoC7lJA;EAGM,cAAc;E1BahB,+BP+LgC;EO9LhC,kCP8LgC;AHo5IpC;;AoCnmJA;E1BEI,gCP6MgC;EO5MhC,mCP4MgC;AHy5IpC;;AoCxmJA;EAcI,UAAU;EACV,WjCxCW;EiCyCX,yBjCba;EiCcb,qBjCda;AH4mJjB;;AoC/mJA;EAqBI,cjCxCc;EiCyCd,oBAAoB;EAEpB,YAAY;EACZ,sBjClDW;EiCmDX,qBjChDc;AH6oJlB;;AqCppJE;EACE,uBlCyxBsC;EC9pBpC,kBAtCY;EiCnFd,gBlCmO6B;AHo7IjC;;AqClpJM;E3BqCF,8BPgM+B;EO/L/B,iCP+L+B;AHk7InC;;AqClpJM;E3BkBF,+BP8M+B;EO7M/B,kCP6M+B;AHu7InC;;AqCpqJE;EACE,uBlCuxBqC;EC5pBnC,mBAtCY;EiCnFd,gBlCoO6B;AHm8IjC;;AqClqJM;E3BqCF,8BPiM+B;EOhM/B,iCPgM+B;AHi8InC;;AqClqJM;E3BkBF,+BP+M+B;EO9M/B,kCP8M+B;AHs8InC;;AsClrJA;EACE,qBAAqB;EACrB,qBnC05BsC;ECz1BpC,cAAW;EkC/Db,gBnCuR+B;EmCtR/B,cAAc;EACd,kBAAkB;EAClB,mBAAmB;EACnB,wBAAwB;E5BKtB,sBP6NgC;EiB/N9B,qIjBgb6I;AHowInJ;;AoBhrJM;EkBfN;IlBgBQ,gBAAgB;EpBorJtB;AACF;;AK1rJE;EiCGI,qBAAqB;AtC2rJ3B;;AsCzsJA;EAoBI,aAAa;AtCyrJjB;;AsCprJA;EACE,kBAAkB;EAClB,SAAS;AtCurJX;;AsChrJA;EACE,oBnC+3BsC;EmC93BtC,mBnC83BsC;EOr5BpC,oBPw5BqC;AHmzHzC;;AsC3qJE;ECjDA,WpCMa;EoCLb,yBpCiCe;AH+rJjB;;AKltJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCguJxC;;AuCnuJU;EAQJ,UAAU;EACV,+CpCsBW;AHysJjB;;AsC1rJE;ECjDA,WpCMa;EoCLb,yBpCWgB;AHouJlB;;AKjuJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC+uJxC;;AuClvJU;EAQJ,UAAU;EACV,iDpCAY;AH8uJlB;;AsCzsJE;ECjDA,WpCMa;EoCLb,yBpCwCe;AHstJjB;;AKhvJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC8vJxC;;AuCjwJU;EAQJ,UAAU;EACV,+CpC6BW;AHguJjB;;AsCxtJE;ECjDA,WpCMa;EoCLb,yBpC0Ce;AHmuJjB;;AK/vJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC6wJxC;;AuChxJU;EAQJ,UAAU;EACV,gDpC+BW;AH6uJjB;;AsCvuJE;ECjDA,cpCegB;EoCdhB,yBpCuCe;AHqvJjB;;AK9wJE;EkCVI,cpCUY;EoCTZ,yBAAkC;AvC4xJxC;;AuC/xJU;EAQJ,UAAU;EACV,+CpC4BW;AH+vJjB;;AsCtvJE;ECjDA,WpCMa;EoCLb,yBpCqCe;AHswJjB;;AK7xJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC2yJxC;;AuC9yJU;EAQJ,UAAU;EACV,+CpC0BW;AHgxJjB;;AsCrwJE;ECjDA,cpCegB;EoCdhB,yBpCMgB;AHozJlB;;AK5yJE;EkCVI,cpCUY;EoCTZ,yBAAkC;AvC0zJxC;;AuC7zJU;EAQJ,UAAU;EACV,iDpCLY;AH8zJlB;;AsCpxJE;ECjDA,WpCMa;EoCLb,yBpCagB;AH4zJlB;;AK3zJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCy0JxC;;AuC50JU;EAQJ,UAAU;EACV,8CpCEY;AHs0JlB;;AwCr1JA;EACE,kBAAoD;EACpD,mBrCuzBsC;EqCrzBtC,yBrCKgB;EOSd,qBP8N+B;AH4mJnC;;AchyJI;E0B5DJ;IAQI,kBrCizBoC;EHwiItC;AACF;;AwCt1JA;EACE,gBAAgB;EAChB,eAAe;E9BIb,gB8BHsB;AxCy1J1B;;AyCp2JA;EACE,kBAAkB;EAClB,wBtCu9ByC;EsCt9BzC,mBtCu9BsC;EsCt9BtC,6BAA6C;E/BU3C,sBP6NgC;AHioJpC;;AyCn2JA;EAEE,cAAc;AzCq2JhB;;AyCj2JA;EACE,gBtC4Q+B;AHwlJjC;;AyC51JA;EACE,mBAAsD;AzC+1JxD;;AyCh2JA;EAKI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,UAAU;EACV,wBtCw7BuC;EsCv7BvC,cAAc;AzC+1JlB;;AyCr1JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBkyJlE;;A0Ct4JE;EACE,yBAAqC;A1Cy4JzC;;A0Ct4JE;EACE,cAA0B;A1Cy4J9B;;AyCn2JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBgzJlE;;A0Cp5JE;EACE,yBAAqC;A1Cu5JzC;;A0Cp5JE;EACE,cAA0B;A1Cu5J9B;;AyCj3JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlB8zJlE;;A0Cl6JE;EACE,yBAAqC;A1Cq6JzC;;A0Cl6JE;EACE,cAA0B;A1Cq6J9B;;AyC/3JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlB40JlE;;A0Ch7JE;EACE,yBAAqC;A1Cm7JzC;;A0Ch7JE;EACE,cAA0B;A1Cm7J9B;;AyC74JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlB01JlE;;A0C97JE;EACE,yBAAqC;A1Ci8JzC;;A0C97JE;EACE,cAA0B;A1Ci8J9B;;AyC35JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBw2JlE;;A0C58JE;EACE,yBAAqC;A1C+8JzC;;A0C58JE;EACE,cAA0B;A1C+8J9B;;AyCz6JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBs3JlE;;A0C19JE;EACE,yBAAqC;A1C69JzC;;A0C19JE;EACE,cAA0B;A1C69J9B;;AyCv7JE;EC/CA,cxBwGgE;EInG9D,yBJmG8D;EwBtGhE,qBxBsGgE;AlBo4JlE;;A0Cx+JE;EACE,yBAAqC;A1C2+JzC;;A0Cx+JE;EACE,cAA0B;A1C2+J9B;;A2Cn/JE;EACE;IAAO,2BAAuC;E3Cu/JhD;E2Ct/JE;IAAK,wBAAwB;E3Cy/J/B;AACF;;A2C5/JE;EACE;IAAO,2BAAuC;E3Cu/JhD;E2Ct/JE;IAAK,wBAAwB;E3Cy/J/B;AACF;;A2Ct/JA;EACE,oBAAa;EAAb,aAAa;EACb,YxCg+BsC;EwC/9BtC,gBAAgB;EAChB,cAAc;EvCmHV,kBAtCY;EuC3EhB,yBxCLgB;EOSd,sBP6NgC;AHyxJpC;;A2Cr/JA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,qBAAuB;EAAvB,uBAAuB;EACvB,gBAAgB;EAChB,WxCjBa;EwCkBb,kBAAkB;EAClB,mBAAmB;EACnB,yBxCQe;EiBnBX,2BjBk+B4C;AHkiIlD;;AoBhgKM;EuBDN;IvBEQ,gBAAgB;EpBogKtB;AACF;;A2C3/JA;ErBYE,qMAA6I;EqBV7I,0BxCy8BsC;AHqjIxC;;A2C1/JE;EACE,0DAA8D;EAA9D,kDAA8D;A3C6/JlE;;A2C1/JM;EAJJ;IAKM,uBAAe;IAAf,eAAe;E3C8/JrB;AACF;;A4CziKA;EACE,oBAAa;EAAb,aAAa;EACb,qBAAuB;EAAvB,uBAAuB;A5C4iKzB;;A4CziKA;EACE,WAAO;EAAP,OAAO;A5C4iKT;;A6C9iKA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EAGtB,eAAe;EACf,gBAAgB;EnCQd,sBP6NgC;AH20JpC;;A6CtiKA;EACE,WAAW;EACX,c1CRgB;E0CShB,mBAAmB;A7CyiKrB;;AKhjKE;EwCWE,UAAU;EACV,c1Cdc;E0Ced,qBAAqB;EACrB,yB1CtBc;AH+jKlB;;A6CnjKA;EAcI,c1ClBc;E0CmBd,yB1C1Bc;AHmkKlB;;A6ChiKA;EACE,kBAAkB;EAClB,cAAc;EACd,wB1C+8ByC;E0C58BzC,sB1C3Ca;E0C4Cb,sC1ClCa;AHmkKf;;A6CxiKA;EnCjBI,+BmC2BkC;EnC1BlC,gCmC0BkC;A7CmiKtC;;A6C7iKA;EnCHI,mCmCiBqC;EnChBrC,kCmCgBqC;A7CoiKzC;;A6CljKA;EAmBI,c1ClDc;E0CmDd,oBAAoB;EACpB,sB1C1DW;AH6lKf;;A6CxjKA;EA0BI,UAAU;EACV,W1ChEW;E0CiEX,yB1CrCa;E0CsCb,qB1CtCa;AHwkKjB;;A6C/jKA;EAiCI,mBAAmB;A7CkiKvB;;A6CnkKA;EAoCM,gB1C4J2B;E0C3J3B,qB1C2J2B;AHw4JjC;;A6CrhKI;EACE,uBAAmB;EAAnB,mBAAmB;A7CwhKzB;;A6CzhKI;EnCtBA,kCPsKgC;EOlLhC,0BmCwCwC;A7CwhK5C;;A6C9hKI;EnClCA,gCPkLgC;EOtKhC,4BmCiC0C;A7CwhK9C;;A6CniKI;EAeM,aAAa;A7CwhKvB;;A6CviKI;EAmBM,qB1C0HuB;E0CzHvB,oBAAoB;A7CwhK9B;;A6C5iKI;EAuBQ,iB1CsHqB;E0CrHrB,sB1CqHqB;AHo6JjC;;AcplKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7CqjKvB;E6CtjKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7CojK1C;E6C1jKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7CmjK5C;E6C9jKE;IAeM,aAAa;E7CkjKrB;E6CjkKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7CijK5B;E6CrkKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EH47J/B;AACF;;Ac7mKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7C8kKvB;E6C/kKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7C6kK1C;E6CnlKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7C4kK5C;E6CvlKE;IAeM,aAAa;E7C2kKrB;E6C1lKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7C0kK5B;E6C9lKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EHq9J/B;AACF;;ActoKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7CumKvB;E6CxmKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7CsmK1C;E6C5mKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7CqmK5C;E6ChnKE;IAeM,aAAa;E7ComKrB;E6CnnKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7CmmK5B;E6CvnKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EH8+J/B;AACF;;Ac/pKI;E+BmCA;IACE,uBAAmB;IAAnB,mBAAmB;E7CgoKvB;E6CjoKE;InCtBA,kCPsKgC;IOlLhC,0BmCwCwC;E7C+nK1C;E6CroKE;InClCA,gCPkLgC;IOtKhC,4BmCiC0C;E7C8nK5C;E6CzoKE;IAeM,aAAa;E7C6nKrB;E6C5oKE;IAmBM,qB1C0HuB;I0CzHvB,oBAAoB;E7C4nK5B;E6ChpKE;IAuBQ,iB1CsHqB;I0CrHrB,sB1CqHqB;EHugK/B;AACF;;A6C/mKA;EnCnHI,gBmCoHsB;A7CknK1B;;A6CnnKA;EAII,qB1CmG6B;AHghKjC;;A6CvnKA;EAOM,sBAAsB;A7ConK5B;;A8C7vKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4pKlE;;AKrvKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CgwKjD;;A8CvwKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlBuqKlE;;A8C7wKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4qKlE;;AKrwKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CgxKjD;;A8CvxKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlBurKlE;;A8C7xKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4rKlE;;AKrxKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CgyKjD;;A8CvyKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlBusKlE;;A8C7yKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4sKlE;;AKryKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9CgzKjD;;A8CvzKE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlButKlE;;A8C7zKE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4tKlE;;AKrzKE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9Cg0KjD;;A8Cv0KE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlBuuKlE;;A8C70KE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4uKlE;;AKr0KE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9Cg1KjD;;A8Cv1KE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlBuvKlE;;A8C71KE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4vKlE;;AKr1KE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9Cg2KjD;;A8Cv2KE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlBuwKlE;;A8C72KE;EACE,c5BqG8D;E4BpG9D,yB5BoG8D;AlB4wKlE;;AKr2KE;EyCPM,c5BgG0D;E4B/F1D,yBAAyC;A9Cg3KjD;;A8Cv3KE;EAWM,W3CPO;E2CQP,yB5B0F0D;E4BzF1D,qB5ByF0D;AlBuxKlE;;A+Ch4KA;EACE,YAAY;E3C8HR,iBAtCY;E2CtFhB,gB5C6R+B;E4C5R/B,cAAc;EACd,W5CYa;E4CXb,yB5CCa;E4CAb,WAAW;A/Cm4Kb;;AK93KE;E0CDE,W5CMW;E4CLX,qBAAqB;A/Cm4KzB;;AK/3KE;E0CCI,YAAY;A/Ck4KlB;;A+Cv3KA;EACE,UAAU;EACV,6BAA6B;EAC7B,SAAS;A/C03KX;;A+Cp3KA;EACE,oBAAoB;A/Cu3KtB;;AgD75KA;EAGE,8B7Cy4BuC;E6Cz4BvC,iB7Cy4BuC;E6Cx4BvC,gB7Cw4BuC;EC7wBnC,mBAtCY;E4ClFhB,2C7CAa;E6CCb,4BAA4B;EAC5B,oC7C04BmD;E6Cz4BnD,gD7COa;E6CNb,UAAU;EtCOR,sBPk4BsC;AHqhJ1C;;AgDz6KA;EAeI,sB7C83BsC;AHgiJ1C;;AgD76KA;EAmBI,UAAU;AhD85Kd;;AgDj7KA;EAuBI,cAAc;EACd,UAAU;AhD85Kd;;AgDt7KA;EA4BI,aAAa;AhD85KjB;;AgD15KA;EACE,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,wB7C02BwC;E6Cz2BxC,c7CvBgB;E6CwBhB,2C7C9Ba;E6C+Bb,4BAA4B;EAC5B,4C7Ck3BoD;EO93BlD,2CQmH4D;ERlH5D,4CQkH4D;AlBwzKhE;;AgD35KA;EACE,gB7Ci2BwC;AH6jJ1C;;AiDp8KA;EAEE,gBAAgB;AjDs8KlB;;AiDx8KA;EAKI,kBAAkB;EAClB,gBAAgB;AjDu8KpB;;AiDl8KA;EACE,eAAe;EACf,MAAM;EACN,OAAO;EACP,a9C2pBsC;E8C1pBtC,aAAa;EACb,WAAW;EACX,YAAY;EACZ,gBAAgB;EAGhB,UAAU;AjDm8KZ;;AiD57KA;EACE,kBAAkB;EAClB,WAAW;EACX,c9C+4BuC;E8C74BvC,oBAAoB;AjD87KtB;;AiD37KE;E7B3BI,2CjBo8BoD;EiBp8BpD,mCjBo8BoD;EiBp8BpD,oEjBo8BoD;E8Cv6BtD,sC9Cq6BmD;E8Cr6BnD,8B9Cq6BmD;AHyhJvD;;AoBv9KM;E6BuBJ;I7BtBM,gBAAgB;EpB29KtB;AACF;;AiDl8KE;EACE,uB9Cm6BoC;E8Cn6BpC,e9Cm6BoC;AHkiJxC;;AiDj8KE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DlxLA;EACE,mBjD00BuC;AH28JzC;;AoDtxLA;EAII,yBlCiF4D;EkChF5D,ajDs0BqC;EiDr0BrC,YjDo0BoC;EiDn0BpC,gBAAgC;ApDsxLpC;;AoD7xLA;EAUM,OAAO;EACP,oCAA2F;EAC3F,uCjDk0BiE;AHq9JvE;;AoDnyLA;EAgBM,SjDmK2B;EiDlK3B,oCAA2F;EAC3F,wBjDpES;AH21Lf;;AoDlxLA;EACE,kBjDmzBuC;AHk+JzC;;AoDtxLA;EAII,wBlC0D4D;AlB4tLhE;;AoD1xLA;EAOM,MAAM;EACN,oCAA2F;EAC3F,wCjD8yBiE;AHy+JvE;;AoDhyLA;EAaM,QjD+I2B;EiD9I3B,oCAA2F;EAC3F,yBjDxFS;AH+2Lf;;AoDtyLA;EAqBI,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,cAAc;EACd,WjD0xBoC;EiDzxBpC,oBAAsC;EACtC,WAAW;EACX,gCjD8wBuD;AHugK3D;;AoDjxLA;EACE,oBjDmxBuC;AHigKzC;;AoDrxLA;EAII,0BlC0B4D;EkCzB5D,ajD+wBqC;EiD9wBrC,YjD6wBoC;EiD5wBpC,gBAAgC;ApDqxLpC;;AoD5xLA;EAUM,QAAQ;EACR,oCjDywBmC;EiDxwBnC,sCjD2wBiE;AH2gKvE;;AoDlyLA;EAgBM,UjD4G2B;EiD3G3B,oCjDmwBmC;EiDlwBnC,uBjD3HS;AHi5Lf;;AoDhwLA;EACE,uBjDouBwC;EiDnuBxC,gBAAgB;EhD3BZ,eAtCY;EgDoEhB,yBjD6tByD;EiD5tBzD,gCAAyE;E1CnIvE,0CQmH4D;ERlH5D,2CQkH4D;AlBoxLhE;;AoD1wLA;EAUI,aAAa;ApDowLjB;;AoDhwLA;EACE,uBjDstBwC;EiDrtBxC,cjDxJgB;AH25LlB;;AqD95LA;EACE,kBAAkB;ArDi6LpB;;AqD95LA;EACE,uBAAmB;EAAnB,mBAAmB;ArDi6LrB;;AqD95LA;EACE,kBAAkB;EAClB,WAAW;EACX,gBAAgB;ArDi6LlB;;AsDx7LE;EACE,cAAc;EACd,WAAW;EACX,WAAW;AtD27Lf;;AqDn6LA;EACE,kBAAkB;EAClB,aAAa;EACb,WAAW;EACX,WAAW;EACX,mBAAm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8B;AxDoqMnD;;AwDnqMA;EAAqB,iCAAiC;AxDuqMtD;;AwDtqMA;EAAqB,iCAAiC;AxD0qMtD;;AwDzqMA;EAAqB,sCAAsC;AxD6qM3D;;AwD5qMA;EAAqB,mCAAmC;AxDgrMxD;;AyDlrME;EACE,oCAAmC;AzDqrMvC;;AK3qME;;;EoDLI,oCAAgD;AzDsrMtD;;AyD5rME;EACE,oCAAmC;AzD+rMvC;;AKrrME;;;EoDLI,oCAAgD;AzDgsMtD;;AyDtsME;EACE,oCAAmC;AzDysMvC;;AK/rME;;;EoDLI,oCAAgD;AzD0sMtD;;AyDhtME;EACE,oCAAmC;AzDmtMvC;;AKzsME;;;EoDLI,oCAAgD;AzDotMtD;;AyD1tME;EACE,oCAAmC;AzD6tMvC;;AKntME;;;EoDLI,oCAAgD;AzD8tMtD;;AyDpuME;EACE,oCAAmC;AzDuuMvC;;AK7tME;;;EoDLI,oCAAgD;AzDwuMtD;;AyD9uME;EACE,oCAAmC;AzDivMvC;;AKvuME;;;EoDLI,oCAAgD;AzDkvMtD;;AyDxvME;EACE,oCAAmC;AzD2vMvC;;AKjvME;;;EoDLI,oCAAgD;AzD4vMtD;;A0D3vMA;EACE,iCAAmC;A1D8vMrC;;A0D3vMA;EACE,wCAAwC;A1D8vM1C;;A2DzwMA;EAAkB,oCAAoD;A3D6wMtE;;A2D5wMA;EAAkB,wCAAwD;A3DgxM1E;;A2D/wMA;EAAkB,0CAA0D;A3DmxM5E;;A2DlxMA;EAAkB,2CAA2D;A3DsxM7E;;A2DrxMA;EAAkB,yCAAyD;A3DyxM3E;;A2DvxMA;EAAmB,oBAAoB;A3D2xMvC;;A2D1xMA;EAAmB,wBAAwB;A3D8xM3C;;A2D7xMA;EAAmB,0BAA0B;A3DiyM7C;;A2DhyMA;EAAmB,2BAA2B;A3DoyM9C;;A2DnyMA;EAAmB,yBAAyB;A3DuyM5C;;A2DpyME;EACE,gCAA+B;A3DuyMnC;;A2DxyME;EACE,gCAA+B;A3D2yMnC;;A2D5yME;EACE,gCAA+B;A3D+yMnC;;A2DhzME;EACE,gCAA+B;A3DmzMnC;;A2DpzME;EACE,gCAA+B;A3DuzMnC;;A2DxzME;EACE,gCAA+B;A3D2zMnC;;A2D5zME;EACE,gCAA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r3OQ;EAAgC,oBAA4B;AvEy3OpE;;AuEx3OQ;;EAEE,wBAAoC;AvE23O9C;;AuEz3OQ;;EAEE,0BAAwC;AvE43OlD;;AuE13OQ;;EAEE,2BAA0C;AvE63OpD;;AuE33OQ;;EAEE,yBAAsC;AvE83OhD;;AuE74OQ;EAAgC,0BAA4B;AvEi5OpE;;AuEh5OQ;;EAEE,8BAAoC;AvEm5O9C;;AuEj5OQ;;EAEE,gCAAwC;AvEo5OlD;;AuEl5OQ;;EAEE,iCAA0C;AvEq5OpD;;AuEn5OQ;;EAEE,+BAAsC;AvEs5OhD;;AuEr6OQ;EAAgC,yBAA4B;AvEy6OpE;;AuEx6OQ;;EAEE,6BAAoC;AvE26O9C;;AuEz6OQ;;EAEE,+BAAwC;AvE46OlD;;AuE16OQ;;EAEE,gCAA0C;AvE66OpD;;AuE36OQ;;EAEE,8BAAsC;AvE86OhD;;AuE77OQ;EAAgC,uBAA4B;AvEi8OpE;;AuEh8OQ;;EAEE,2BAAoC;AvEm8O9C;;AuEj8OQ;;EAEE,6BAAwC;AvEo8OlD;;AuEl8OQ;;EAEE,8BAA0C;AvEq8OpD;;AuEn8OQ;;EAEE,4BAAsC;AvEs8OhD;;AuEr9OQ;EAAgC,yBAA4B;AvEy9OpE;;AuEx9OQ;;EAEE,6BAAoC;AvE29O9C;;AuEz9OQ;;EAEE,+BAAwC;AvE49OlD;;AuE19OQ;;EAEE,gCAA0C;AvE69OpD;;AuE39OQ;;EAEE,8BAAsC;AvE89OhD;;AuE7+OQ;EAAgC,uBAA4B;AvEi/OpE;;AuEh/OQ;;EAEE,2BAAoC;AvEm/O9C;;AuEj/OQ;;EAEE,6BAAwC;AvEo/OlD;;AuEl/OQ;;EAEE,8BAA0C;AvEq/OpD;;AuEn/OQ;;EAEE,4BAAsC;AvEs/OhD;;AuErgPQ;EAAgC,qBAA4B;AvEygPpE;;AuExgPQ;;EAEE,yBAAoC;AvE2gP9C;;AuEzgPQ;;EAEE,2BAAwC;AvE4gPlD;;AuE1gPQ;;EAEE,4BAA0C;AvE6gPpD;;AuE3gPQ;;EAEE,0BAAsC;AvE8gPhD;;AuE7hPQ;EAAgC,2BAA4B;AvEiiPpE;;AuEhiPQ;;EAEE,+BAAoC;AvEmiP9C;;AuEjiPQ;;EAEE,iCAAwC;AvEoiPlD;;AuEliPQ;;EAEE,kCAA0C;AvEqiPpD;;AuEniPQ;;EAEE,gCAAsC;AvEsiPhD;;AuErjPQ;EAAgC,0BAA4B;AvEyjPpE;;AuExjPQ;;EAEE,8BAAoC;AvE2jP9C;;AuEzjPQ;;EAEE,gCAAwC;AvE4jPlD;;AuE1jPQ;;EAEE,iCAA0C;AvE6jPpD;;AuE3jPQ;;EAEE,+BAAsC;AvE8jPhD;;AuE7kPQ;EAAgC,wBAA4B;AvEilPpE;;AuEhlPQ;;EAEE,4BAAoC;AvEmlP9C;;AuEjlPQ;;EAEE,8BAAwC;AvEolPlD;;AuEllPQ;;EAEE,+BAA0C;AvEqlPpD;;AuEnlPQ;;EAEE,6BAAsC;AvEslPhD;;AuErmPQ;EAAgC,0BAA4B;AvEymPpE;;AuExmPQ;;EAEE,8BAAoC;AvE2mP9C;;AuEzmPQ;;EAEE,gCAAwC;AvE4mPlD;;AuE1mPQ;;EAEE,iCAA0C;AvE6mPpD;;AuE3mPQ;;EAEE,+BAAsC;AvE8mPhD;;AuE7nPQ;EAAgC,wBAA4B;AvEioPpE;;AuEhoPQ;;EAEE,4BAAoC;AvEmoP9C;;AuEjoPQ;;EAEE,8BAAwC;AvEooPlD;;AuEloPQ;;EAEE,+BAA0C;AvEqoPpD;;AuEnoPQ;;EAEE,6BAAsC;AvEsoPhD;;AuE9nPQ;EAAwB,2BAA2B;AvEkoP3D;;AuEjoPQ;;EAEE,+BAA+B;AvEooPzC;;AuEloPQ;;EAEE,iCAAiC;AvEqoP3C;;AuEnoPQ;;EAEE,kCAAkC;AvEsoP5C;;AuEpoPQ;;EAEE,gCAAgC;AvEuoP1C;;AuEtpPQ;EAAwB,0BAA2B;AvE0pP3D;;AuEzpPQ;;EAEE,8BAA+B;AvE4pPzC;;AuE1pPQ;;EAEE,gCAAiC;AvE6pP3C;;AuE3pPQ;;EAEE,iCAAkC;AvE8pP5C;;AuE5pPQ;;EAEE,+BAAgC;AvE+pP1C;;AuE9qPQ;EAAwB,wBAA2B;AvEkrP3D;;AuEjrPQ;;EAEE,4BAA+B;AvEorPzC;;AuElrPQ;;EAEE,8BAAiC;AvEqrP3C;;AuEnrPQ;;EAEE,+BAAkC;AvEsrP5C;;AuEprPQ;;EAEE,6BAAgC;AvEurP1C;;AuEtsPQ;EAAwB,0BAA2B;AvE0sP3D;;AuEzsPQ;;EAEE,8BAA+B;AvE4sPzC;;AuE1sPQ;;EAEE,gCAAiC;AvE6sP3C;;AuE3sPQ;;EAEE,iCAAkC;AvE8sP5C;;AuE5sPQ;;EAEE,+BAAgC;AvE+sP1C;;AuE9tPQ;EAAwB,wBAA2B;AvEkuP3D;;AuEjuPQ;;EAEE,4BAA+B;AvEouPzC;;AuEluPQ;;EAEE,8BAAiC;AvEquP3C;;AuEnuPQ;;EAEE,+BAAkC;AvEsuP5C;;AuEpuPQ;;EAEE,6BAAgC;AvEuuP1C;;AuEjuPI;EAAmB,uBAAuB;AvEquP9C;;AuEpuPI;;EAEE,2BAA2B;AvEuuPjC;;AuEruPI;;EAEE,6BAA6B;AvEwuPnC;;AuEtuPI;;EAEE,8BAA8B;AvEyuPpC;;AuEvuPI;;EAEE,4BAA4B;AvE0uPlC;;AcnvPI;EyDlDI;IAAgC,oBAA4B;EvE0yPlE;EuEzyPM;;IAEE,wBAAoC;EvE2yP5C;EuEzyPM;;IAEE,0BAAwC;EvE2yPhD;EuEzyPM;;IAEE,2BAA0C;EvE2yPlD;EuEzyPM;;IAEE,yBAAsC;EvE2yP9C;EuE1zPM;IAAgC,0BAA4B;EvE6zPlE;EuE5zPM;;IAEE,8BAAoC;EvE8zP5C;EuE5zPM;;IAEE,gCAAwC;EvE8zPhD;EuE5zPM;;IAEE,iCAA0C;EvE8zPlD;EuE5zPM;;IAEE,+BAAsC;EvE8zP9C;EuE70PM;IAAgC,yBAA4B;EvEg1PlE;EuE/0PM;;IAEE,6BAAoC;EvEi1P5C;EuE/0PM;;IAEE,+BAAwC;EvEi1PhD;EuE/0PM;;IAEE,gCAA0C;EvEi1PlD;EuE/0PM;;IAEE,8BAAsC;EvEi1P9C;EuEh2PM;IAAgC,uBAA4B;EvEm2PlE;EuEl2PM;;IAEE,2BAAoC;EvEo2P5C;EuEl2PM;;IAEE,6BAAwC;EvEo2PhD;EuEl2PM;;IAEE,8BAA0C;EvEo2PlD;EuEl2PM;;IAEE,4BAAsC;EvEo2P9C;EuEn3PM;IAAgC,yBAA4B;EvEs3PlE;EuEr3PM;;IAEE,6BAAoC;EvEu3P5C;EuEr3PM;;IAEE,+BAAwC;EvEu3PhD;EuEr3PM;;IAEE,gCAA0C;EvEu3PlD;EuEr3PM;;IAEE,8BAAsC;EvEu3P9C;EuEt4PM;IAAgC,uBAA4B;EvEy4PlE;EuEx4PM;;IAEE,2BAAoC;EvE04P5C;EuEx4PM;;IAEE,6BAAwC;EvE04PhD;EuEx4PM;;IAEE,8BAA0C;EvE04PlD;EuEx4PM;;IAEE,4BAAsC;EvE04P9C;EuEz5PM;IAAgC,qBAA4B;EvE45PlE;EuE35PM;;IAEE,yBAAoC;EvE65P5C;EuE35PM;;IAEE,2BAAwC;EvE65PhD;EuE35PM;;IAEE,4BAA0C;EvE65PlD;EuE35PM;;IAEE,0BAAsC;EvE65P9C;EuE56PM;IAAgC,2BAA4B;EvE+6PlE;EuE96PM;;IAEE,+BAAoC;EvEg7P5C;EuE96PM;;IAEE,iCAAwC;EvEg7PhD;EuE96PM;;IAEE,kCAA0C;EvEg7PlD;EuE96PM;;IAEE,gCAAsC;EvEg7P9C;EuE/7PM;IAAgC,0BAA4B;EvEk8PlE;EuEj8PM;;IAEE,8BAAoC;EvEm8P5C;EuEj8PM;;IAEE,gCAAwC;EvEm8PhD;EuEj8PM;;IAEE,iCAA0C;EvEm8PlD;EuEj8PM;;IAEE,+BAAsC;EvEm8P9C;EuEl9PM;IAAgC,wBAA4B;EvEq9PlE;EuEp9PM;;IAEE,4BAAoC;EvEs9P5C;EuEp9PM;;IAEE,8BAAwC;EvEs9PhD;EuEp9PM;;IAEE,+BAA0C;EvEs9PlD;EuEp9PM;;IAEE,6BAAsC;EvEs9P9C;EuEr+PM;IAAgC,0BAA4B;EvEw+PlE;EuEv+PM;;IAEE,8BAAoC;EvEy+P5C;EuEv+PM;;IAEE,gCAAwC;EvEy+PhD;EuEv+PM;;IAEE,iCAA0C;EvEy+PlD;EuEv+PM;;IAEE,+BAAsC;EvEy+P9C;EuEx/PM;IAAgC,wBAA4B;EvE2/PlE;EuE1/PM;;IAEE,4BAAoC;EvE4/P5C;EuE1/PM;;IAEE,8BAAwC;EvE4/PhD;EuE1/PM;;IAEE,+BAA0C;EvE4/PlD;EuE1/PM;;IAEE,6BAAsC;EvE4/P9C;EuEp/PM;IAAwB,2BAA2B;EvEu/PzD;EuEt/PM;;IAEE,+BAA+B;EvEw/PvC;EuEt/PM;;IAEE,iCAAiC;EvEw/PzC;EuEt/PM;;IAEE,kCAAkC;EvEw/P1C;EuEt/PM;;IAEE,gCAAgC;EvEw/PxC;EuEvgQM;IAAwB,0BAA2B;EvE0gQzD;EuEzgQM;;IAEE,8BAA+B;EvE2gQvC;EuEzgQM;;IAEE,gCAAiC;EvE2gQzC;EuEzgQM;;IAEE,iCAAkC;EvE2gQ1C;EuEzgQM;;IAEE,+BAAgC;EvE2gQxC;EuE1hQM;IAAwB,wBAA2B;EvE6hQzD;EuE5hQM;;IAEE,4BAA+B;EvE8hQvC;EuE5hQM;;IAEE,8BAAiC;EvE8hQzC;EuE5hQM;;IAEE,+BAAkC;EvE8hQ1C;EuE5hQM;;IAEE,6BAAgC;EvE8hQxC;EuE7iQM;IAAwB,0BAA2B;EvEgjQzD;EuE/iQM;;IAEE,8BAA+B;EvEijQvC;EuE/iQM;;IAEE,gCAAiC;EvEijQzC;EuE/iQM;;IAEE,iCAAkC;EvEijQ1C;EuE/iQM;;IAEE,+BAAgC;EvEijQxC;EuEhkQM;IAAwB,wBAA2B;EvEmkQzD;EuElkQM;;IAEE,4BAA+B;EvEokQvC;EuElkQM;;IAEE,8BAAiC;EvEokQzC;EuElkQM;;IAEE,+BAAkC;EvEokQ1C;EuElkQM;;IAEE,6BAAgC;EvEokQxC;EuE9jQE;IAAmB,uBAAuB;EvEikQ5C;EuEhkQE;;IAEE,2BAA2B;EvEkkQ/B;EuEhkQE;;IAEE,6BAA6B;EvEkkQjC;EuEhkQE;;IAEE,8BAA8B;EvEkkQlC;EuEhkQE;;IAEE,4BAA4B;EvEkkQhC;AACF;;Ac5kQI;EyDlDI;IAAgC,oBAA4B;EvEmoQlE;EuEloQM;;IAEE,wBAAoC;EvEooQ5C;EuEloQM;;IAEE,0BAAwC;EvEooQhD;EuEloQM;;IAEE,2BAA0C;EvEooQlD;EuEloQM;;IAEE,yBAAsC;EvEooQ9C;EuEnpQM;IAAgC,0BAA4B;EvEspQlE;EuErpQM;;IAEE,8BAAoC;EvEupQ5C;EuErpQM;;IAEE,gCAAwC;EvEupQhD;EuErpQM;;IAEE,iCAA0C;EvEupQlD;EuErpQM;;IAEE,+BAAsC;EvEupQ9C;EuEtqQM;IAAgC,yBAA4B;EvEyqQlE;EuExqQM;;IAEE,6BAAoC;EvE0qQ5C;EuExqQM;;IAEE,+BAAwC;EvE0qQhD;EuExqQM;;IAEE,gCAA0C;EvE0qQlD;EuExqQM;;IAEE,8BAAsC;EvE0qQ9C;EuEzrQM;IAAgC,uBAA4B;EvE4rQlE;EuE3rQM;;IAEE,2BAAoC;EvE6rQ5C;EuE3rQM;;IAEE,6BAAwC;EvE6rQhD;EuE3rQM;;IAEE,8BAA0C;EvE6rQlD;EuE3rQM;;IAEE,4BAAsC;EvE6rQ9C;EuE5sQM;IAAgC,yBAA4B;EvE+sQlE;EuE9sQM;;IAEE,6BAAoC;EvEgtQ5C;EuE9sQM;;IAEE,+BAAwC;EvEgtQhD;EuE9sQM;;IAEE,gCAA0C;EvEgtQlD;EuE9sQM;;IAEE,8BAAsC;EvEgtQ9C;EuE/tQM;IAAgC,uBAA4B;EvEkuQlE;EuEjuQM;;IAEE,2BAAoC;EvEmuQ5C;EuEjuQM;;IAEE,6BAAwC;EvEmuQhD;EuEjuQM;;IAEE,8BAA0C;EvEmuQlD;EuEjuQM;;IAEE,4BAAsC;EvEmuQ9C;EuElvQM;IAAgC,qBAA4B;EvEqvQlE;EuEpvQM;;IAEE,yBAAoC;EvEsvQ5C;EuEpvQM;;IAEE,2BAAwC;EvEsvQhD;EuEpvQM;;IAEE,4BAA0C;EvEsvQlD;EuEpvQM;;IAEE,0BAAsC;EvEsvQ9C;EuErwQM;IAAgC,2BAA4B;EvEwwQlE;EuEvwQM;;IAEE,+BAAoC;EvEywQ5C;EuEvwQM;;IAEE,iCAAwC;EvEywQhD;EuEvwQM;;IAEE,kCAA0C;EvEywQlD;EuEvwQM;;IAEE,gCAAsC;EvEywQ9C;EuExxQM;IAAgC,0BAA4B;EvE2xQlE;EuE1xQM;;IAEE,8BAAoC;EvE4xQ5C;EuE1xQM;;IAEE,gCAAwC;EvE4xQhD;EuE1xQM;;IAEE,iCAA0C;EvE4xQlD;EuE1xQM;;IAEE,+BAAsC;EvE4xQ9C;EuE3yQM;IAAgC,wBAA4B;EvE8yQlE;EuE7yQM;;IAEE,4BAAoC;EvE+yQ5C;EuE7yQM;;IAEE,8BAAwC;EvE+yQhD;EuE7yQM;;IAEE,+BAA0C;EvE+yQlD;EuE7yQM;;IAEE,6BAAsC;EvE+yQ9C;EuE9zQM;IAAgC,0BAA4B;EvEi0QlE;EuEh0QM;;IAEE,8BAAoC;EvEk0Q5C;EuEh0QM;;IAEE,gCAAwC;EvEk0QhD;EuEh0QM;;IAEE,iCAA0C;EvEk0QlD;EuEh0QM;;IAEE,+BAAsC;EvEk0Q9C;EuEj1QM;IAAgC,wBAA4B;EvEo1QlE;EuEn1QM;;IAEE,4BAAoC;EvEq1Q5C;EuEn1QM;;IAEE,8BAAwC;EvEq1QhD;EuEn1QM;;IAEE,+BAA0C;EvEq1QlD;EuEn1QM;;IAEE,6BAAsC;EvEq1Q9C;EuE70QM;IAAwB,2BAA2B;EvEg1QzD;EuE/0QM;;IAEE,+BAA+B;EvEi1QvC;EuE/0QM;;IAEE,iCAAiC;EvEi1QzC;EuE/0QM;;IAEE,kCAAkC;EvEi1Q1C;EuE/0QM;;IAEE,gCAAgC;EvEi1QxC;EuEh2QM;IAAwB,0BAA2B;EvEm2QzD;EuEl2QM;;IAEE,8BAA+B;EvEo2QvC;EuEl2QM;;IAEE,gCAAiC;EvEo2QzC;EuEl2QM;;IAEE,iCAAkC;EvEo2Q1C;EuEl2QM;;IAEE,+BAAgC;EvEo2QxC;EuEn3QM;IAAwB,wBAA2B;EvEs3QzD;EuEr3QM;;IAEE,4BAA+B;EvEu3QvC;EuEr3QM;;IAEE,8BAAiC;EvEu3QzC;EuEr3QM;;IAEE,+BAAkC;EvEu3Q1C;EuEr3QM;;IAEE,6BAAgC;EvEu3QxC;EuEt4QM;IAAwB,0BAA2B;EvEy4QzD;EuEx4QM;;IAEE,8BAA+B;EvE04QvC;EuEx4QM;;IAEE,gCAAiC;EvE04QzC;EuEx4QM;;IAEE,iCAAkC;EvE04Q1C;EuEx4QM;;IAEE,+BAAgC;EvE04QxC;EuEz5QM;IAAwB,wBAA2B;EvE45QzD;EuE35QM;;IAEE,4BAA+B;EvE65QvC;EuE35QM;;IAEE,8BAAiC;EvE65QzC;EuE35QM;;IAEE,+BAAkC;EvE65Q1C;EuE35QM;;IAEE,6BAAgC;EvE65QxC;EuEv5QE;IAAmB,uBAAuB;EvE05Q5C;EuEz5QE;;IAEE,2BAA2B;EvE25Q/B;EuEz5QE;;IAEE,6BAA6B;EvE25QjC;EuEz5QE;;IAEE,8BAA8B;EvE25QlC;EuEz5QE;;IAEE,4BAA4B;EvE25QhC;AACF;;Acr6QI;EyDlDI;IAAgC,oBAA4B;EvE49QlE;EuE39QM;;IAEE,wBAAoC;EvE69Q5C;EuE39QM;;IAEE,0BAAwC;EvE69QhD;EuE39QM;;IAEE,2BAA0C;EvE69QlD;EuE39QM;;IAEE,yBAAsC;EvE69Q9C;EuE5+QM;IAAgC,0BAA4B;EvE++QlE;EuE9+QM;;IAEE,8BAAoC;EvEg/Q5C;EuE9+QM;;IAEE,gCAAwC;EvEg/QhD;EuE9+QM;;IAEE,iCAA0C;EvEg/QlD;EuE9+QM;;IAEE,+BAAsC;EvEg/Q9C;EuE//QM;IAAgC,yBAA4B;EvEkgRlE;EuEjgRM;;IAEE,6BAAoC;EvEmgR5C;EuEjgRM;;IAEE,+BAAwC;EvEmgRhD;EuEjgRM;;IAEE,gCAA0C;EvEmgRlD;EuEjgRM;;IAEE,8BAAsC;EvEmgR9C;EuElhRM;IAAgC,uBAA4B;EvEqhRlE;EuEphRM;;IAEE,2BAAoC;EvEshR5C;EuEphRM;;IAEE,6BAAwC;EvEshRhD;EuEphRM;;IAEE,8BAA0C;EvEshRlD;EuEphRM;;IAEE,4BAAsC;EvEshR9C;EuEriRM;IAAgC,yBAA4B;EvEwiRlE;EuEviRM;;IAEE,6BAAoC;EvEyiR5C;EuEviRM;;IAEE,+BAAwC;EvEyiRhD;EuEviRM;;IAEE,gCAA0C;EvEyiRlD;EuEviRM;;IAEE,8BAAsC;EvEyiR9C;EuExjRM;IAAgC,uBAA4B;EvE2jRlE;EuE1jRM;;IAEE,2BAAoC;EvE4jR5C;EuE1jRM;;IAEE,6BAAwC;EvE4jRhD;EuE1jRM;;IAEE,8BAA0C;EvE4jRlD;EuE1jRM;;IAEE,4BAAsC;EvE4jR9C;EuE3kRM;IAAgC,qBAA4B;EvE8kRlE;EuE7kRM;;IAEE,yBAAoC;EvE+kR5C;EuE7kRM;;IAEE,2BAAwC;EvE+kRhD;EuE7kRM;;IAEE,4BAA0C;EvE+kRlD;EuE7kRM;;IAEE,0BAAsC;EvE+kR9C;EuE9lRM;IAAgC,2BAA4B;EvEimRlE;EuEhmRM;;IAEE,+BAAoC;EvEkmR5C;EuEhmRM;;IAEE,iCAAwC;EvEkmRhD;EuEhmRM;;IAEE,kCAA0C;EvEkmRlD;EuEhmRM;;IAEE,gCAAsC;EvEkmR9C;EuEjnRM;IAAgC,0BAA4B;EvEonRlE;EuEnnRM;;IAEE,8BAAoC;EvEqnR5C;EuEnnRM;;IAEE,gCAAwC;EvEqnRhD;EuEnnRM;;IAEE,iCAA0C;EvEqnRlD;EuEnnRM;;IAEE,+BAAsC;EvEqnR9C;EuEpoRM;IAAgC,wBAA4B;EvEuoRlE;EuEtoRM;;IAEE,4BAAoC;EvEwoR5C;EuEtoRM;;IAEE,8BAAwC;EvEwoRhD;EuEtoRM;;IAEE,+BAA0C;EvEwoRlD;EuEtoRM;;IAEE,6BAAsC;EvEwoR9C;EuEvpRM;IAAgC,0BAA4B;EvE0pRlE;EuEzpRM;;IAEE,8BAAoC;EvE2pR5C;EuEzpRM;;IAEE,gCAAwC;EvE2pRhD;EuEzpRM;;IAEE,iCAA0C;EvE2pRlD;EuEzpRM;;IAEE,+BAAsC;EvE2pR9C;EuE1qRM;IAAgC,wBAA4B;EvE6qRlE;EuE5qRM;;IAEE,4BAAoC;EvE8qR5C;EuE5qRM;;IAEE,8BAAwC;EvE8qRhD;EuE5qRM;;IAEE,+BAA0C;EvE8qRlD;EuE5qRM;;IAEE,6BAAsC;EvE8qR9C;EuEtqRM;IAAwB,2BAA2B;EvEyqRzD;EuExqRM;;IAEE,+BAA+B;EvE0qRvC;EuExqRM;;IAEE,iCAAiC;EvE0qRzC;EuExqRM;;IAEE,kCAAkC;EvE0qR1C;EuExqRM;;IAEE,gCAAgC;EvE0qRxC;EuEzrRM;IAAwB,0BAA2B;EvE4rRzD;EuE3rRM;;IAEE,8BAA+B;EvE6rRvC;EuE3rRM;;IAEE,gCAAiC;EvE6rRzC;EuE3rRM;;IAEE,iCAAkC;EvE6rR1C;EuE3rRM;;IAEE,+BAAgC;EvE6rRxC;EuE5sRM;IAAwB,wBAA2B;EvE+sRzD;EuE9sRM;;IAEE,4BAA+B;EvEgtRvC;EuE9sRM;;IAEE,8BAAiC;EvEgtRzC;EuE9sRM;;IAEE,+BAAkC;EvEgtR1C;EuE9sRM;;IAEE,6BAAgC;EvEgtRxC;EuE/tRM;IAAwB,0BAA2B;EvEkuRzD;EuEjuRM;;IAEE,8BAA+B;EvEmuRvC;EuEjuRM;;IAEE,gCAAiC;EvEmuRzC;EuEjuRM;;IAEE,iCAAkC;EvEmuR1C;EuEjuRM;;IAEE,+BAAgC;EvEmuRxC;EuElvRM;IAAwB,wBAA2B;EvEqvRzD;EuEpvRM;;IAEE,4BAA+B;EvEsvRvC;EuEpvRM;;IAEE,8BAAiC;EvEsvRzC;EuEpvRM;;IAEE,+BAAkC;EvEsvR1C;EuEpvRM;;IAEE,6BAAgC;EvEsvRxC;EuEhvRE;IAAmB,uBAAuB;EvEmvR5C;EuElvRE;;IAEE,2BAA2B;EvEovR/B;EuElvRE;;IAEE,6BAA6B;EvEovRjC;EuElvRE;;IAEE,8BAA8B;EvEovRlC;EuElvRE;;IAEE,4BAA4B;EvEovRhC;AACF;;Ac9vRI;EyDlDI;IAAgC,oBAA4B;EvEqzRlE;EuEpzRM;;IAEE,wBAAoC;EvEszR5C;EuEpzRM;;IAEE,0BAAwC;EvEszRhD;EuEpzRM;;IAEE,2BAA0C;EvEszRlD;EuEpzRM;;IAEE,yBAAsC;EvEszR9C;EuEr0RM;IAAgC,0BAA4B;EvEw0RlE;EuEv0RM;;IAEE,8BAAoC;EvEy0R5C;EuEv0RM;;IAEE,gCAAwC;EvEy0RhD;EuEv0RM;;IAEE,iCAA0C;EvEy0RlD;EuEv0RM;;IAEE,+BAAsC;EvEy0R9C;EuEx1RM;IAAgC,yBAA4B;EvE21RlE;EuE11RM;;IAEE,6BAAoC;EvE41R5C;EuE11RM;;IAEE,+BAAwC;EvE41RhD;EuE11RM;;IAEE,gCAA0C;EvE41RlD;EuE11RM;;IAEE,8BAAsC;EvE41R9C;EuE32RM;IAAgC,uBAA4B;EvE82RlE;EuE72RM;;IAEE,2BAAoC;EvE+2R5C;EuE72RM;;IAEE,6BAAwC;EvE+2RhD;EuE72RM;;IAEE,8BAA0C;EvE+2RlD;EuE72RM;;IAEE,4BAAsC;EvE+2R9C;EuE93RM;IAAgC,yBAA4B;EvEi4RlE;EuEh4RM;;IAEE,6BAAoC;EvEk4R5C;EuEh4RM;;IAEE,+BAAwC;EvEk4RhD;EuEh4RM;;IAEE,gCAA0C;EvEk4RlD;EuEh4RM;;IAEE,8BAAsC;EvEk4R9C;EuEj5RM;IAAgC,uBAA4B;EvEo5RlE;EuEn5RM;;IAEE,2BAAoC;EvEq5R5C;EuEn5RM;;IAEE,6BAAwC;EvEq5RhD;EuEn5RM;;IAEE,8BAA0C;EvEq5RlD;EuEn5RM;;IAEE,4BAAsC;EvEq5R9C;EuEp6RM;IAAgC,qBAA4B;EvEu6RlE;EuEt6RM;;IAEE,yBAAoC;EvEw6R5C;EuEt6RM;;IAEE,2BAAwC;EvEw6RhD;EuEt6RM;;IAEE,4BAA0C;EvEw6RlD;EuEt6RM;;IAEE,0BAAsC;EvEw6R9C;EuEv7RM;IAAgC,2BAA4B;EvE07RlE;EuEz7RM;;IAEE,+BAAoC;EvE27R5C;EuEz7RM;;IAEE,iCAAwC;EvE27RhD;EuEz7RM;;IAEE,kCAA0C;EvE27RlD;EuEz7RM;;IAEE,gCAAsC;EvE27R9C;EuE18RM;IAAgC,0BAA4B;EvE68RlE;EuE58RM;;IAEE,8BAAoC;EvE88R5C;EuE58RM;;IAEE,gCAAwC;EvE88RhD;EuE58RM;;IAEE,iCAA0C;EvE88RlD;EuE58RM;;IAEE,+BAAsC;EvE88R9C;EuE79RM;IAAgC,wBAA4B;EvEg+RlE;EuE/9RM;;IAEE,4BAAoC;EvEi+R5C;EuE/9RM;;IAEE,8BAAwC;EvEi+RhD;EuE/9RM;;IAEE,+BAA0C;EvEi+RlD;EuE/9RM;;IAEE,6BAAsC;EvEi+R9C;EuEh/RM;IAAgC,0BAA4B;EvEm/RlE;EuEl/RM;;IAEE,8BAAoC;EvEo/R5C;EuEl/RM;;IAEE,gCAAwC;EvEo/RhD;EuEl/RM;;IAEE,iCAA0C;EvEo/RlD;EuEl/RM;;IAEE,+BAAsC;EvEo/R9C;EuEngSM;IAAgC,wBAA4B;EvEsgSlE;EuErgSM;;IAEE,4BAAoC;EvEugS5C;EuErgSM;;IAEE,8BAAwC;EvEugShD;EuErgSM;;IAEE,+BAA0C;EvEugSlD;EuErgSM;;IAEE,6BAAsC;EvEugS9C;EuE//RM;IAAwB,2BAA2B;EvEkgSzD;EuEjgSM;;IAEE,+BAA+B;EvEmgSvC;EuEjgSM;;IAEE,iCAAiC;EvEmgSzC;EuEjgSM;;IAEE,kCAAkC;EvEmgS1C;EuEjgSM;;IAEE,gCAAgC;EvEmgSxC;EuElhSM;IAAwB,0BAA2B;EvEqhSzD;EuEphSM;;IAEE,8BAA+B;EvEshSvC;EuEphSM;;IAEE,gCAAiC;EvEshSzC;EuEphSM;;IAEE,iCAAkC;EvEshS1C;EuEphSM;;IAEE,+BAAgC;EvEshSxC;EuEriSM;IAAwB,wBAA2B;EvEwiSzD;EuEviSM;;IAEE,4BAA+B;EvEyiSvC;EuEviSM;;IAEE,8BAAiC;EvEyiSzC;EuEviSM;;IAEE,+BAAkC;EvEyiS1C;EuEviSM;;IAEE,6BAAgC;EvEyiSxC;EuExjSM;IAAwB,0BAA2B;EvE2jSzD;EuE1jSM;;IAEE,8BAA+B;EvE4jSvC;EuE1jSM;;IAEE,gCAAiC;EvE4jSzC;EuE1jSM;;IAEE,iCAAkC;EvE4jS1C;EuE1jSM;;IAEE,+BAAgC;EvE4jSxC;EuE3kSM;IAAwB,wBAA2B;EvE8kSzD;EuE7kSM;;IAEE,4BAA+B;EvE+kSvC;EuE7kSM;;IAEE,8BAAiC;EvE+kSzC;EuE7kSM;;IAEE,+BAAkC;EvE+kS1C;EuE7kSM;;IAEE,6BAAgC;EvE+kSxC;EuEzkSE;IAAmB,uBAAuB;EvE4kS5C;EuE3kSE;;IAEE,2BAA2B;EvE6kS/B;EuE3kSE;;IAEE,6BAA6B;EvE6kSjC;EuE3kSE;;IAEE,8BAA8B;EvE6kSlC;EuE3kSE;;IAEE,4BAA4B;EvE6kShC;AACF;;AwE/oSA;EAEI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,OAAO;EACP,UAAU;EAEV,oBAAoB;EACpB,WAAW;EAEX,kCAAkC;AxE+oStC;;AyEzpSA;EAAkB,4GAA8C;AzE6pShE;;AyEzpSA;EAAiB,8BAA8B;AzE6pS/C;;AyE5pSA;EAAiB,8BAA8B;AzEgqS/C;;AyE/pSA;EAAiB,8BAA8B;AzEmqS/C;;AyElqSA;ECTE,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;A1E+qSrB;;AyEhqSI;EAAwB,2BAA2B;AzEoqSvD;;AyEnqSI;EAAwB,4BAA4B;AzEuqSxD;;AyEtqSI;EAAwB,6BAA6B;AzE0qSzD;;AcroSI;E2DvCA;IAAwB,2BAA2B;EzEirSrD;EyEhrSE;IAAwB,4BAA4B;EzEmrStD;EyElrSE;IAAwB,6BAA6B;EzEqrSvD;AACF;;AcjpSI;E2DvCA;IAAwB,2BAA2B;EzE6rSrD;EyE5rSE;IAAwB,4BAA4B;EzE+rStD;EyE9rSE;IAAwB,6BAA6B;EzEisSvD;AACF;;Ac7pSI;E2DvCA;IAAwB,2BAA2B;EzEysSrD;EyExsSE;IAAwB,4BAA4B;EzE2sStD;EyE1sSE;IAAwB,6BAA6B;EzE6sSvD;AACF;;AczqSI;E2DvCA;IAAwB,2BAA2B;EzEqtSrD;EyEptSE;IAAwB,4BAA4B;EzEutStD;EyEttSE;IAAwB,6BAA6B;EzEytSvD;AACF;;AyEptSA;EAAmB,oCAAoC;AzEwtSvD;;AyEvtSA;EAAmB,oCAAoC;AzE2tSvD;;AyE1tSA;EAAmB,qCAAqC;AzE8tSxD;;AyE1tSA;EAAuB,2BAA0C;AzE8tSjE;;AyE7tSA;EAAuB,+BAA4C;AzEiuSnE;;AyEhuSA;EAAuB,2BAA2C;AzEouSlE;;AyEnuSA;EAAuB,2BAAyC;AzEuuShE;;AyEtuSA;EAAuB,8BAA2C;AzE0uSlE;;AyEzuSA;EAAuB,6BAA6B;AzE6uSpD;;AyEzuSA;EAAc,sBAAwB;AzE6uStC;;A2EpxSE;EACE,yBAAwB;A3EuxS5B;;AK7wSE;EsELM,yBAA0E;A3EsxSlF;;A2E5xSE;EACE,yBAAwB;A3E+xS5B;;AKrxSE;EsELM,yBAA0E;A3E8xSlF;;A2EpySE;EACE,yBAAwB;A3EuyS5B;;AK7xSE;EsELM,yBAA0E;A3EsySlF;;A2E5ySE;EACE,yBAAwB;A3E+yS5B;;AKrySE;EsELM,yBAA0E;A3E8ySlF;;A2EpzSE;EACE,yBAAwB;A3EuzS5B;;AK7ySE;EsELM,yBAA0E;A3EszSlF;;A2E5zSE;EACE,yBAAwB;A3E+zS5B;;AKrzSE;EsELM,yBAA0E;A3E8zSlF;;A2Ep0SE;EACE,yBAAwB;A3Eu0S5B;;AK7zSE;EsELM,yBAA0E;A3Es0SlF;;A2E50SE;EACE,yBAAwB;A3E+0S5B;;AKr0SE;EsELM,yBAA0E;A3E80SlF;;AyEvySA;EAAa,yBAA6B;AzE2yS1C;;AyE1ySA;EAAc,yBAA6B;AzE8yS3C;;AyE5ySA;EAAiB,oCAAkC;AzEgzSnD;;AyE/ySA;EAAiB,0CAAkC;AzEmzSnD;;AyE/ySA;EGvDE,WAAW;EACX,kBAAkB;EAClB,iBAAiB;EACjB,6BAA6B;EAC7B,SAAS;A5E02SX;;AyEnzSA;EAAwB,gCAAgC;AzEuzSxD;;AyErzSA;EACE,iCAAiC;EACjC,gCAAgC;AzEwzSlC;;AyEnzSA;EAAc,yBAAyB;AzEuzSvC;;A6Ex3SA;EACE,8BAA8B;A7E23ShC;;A6Ex3SA;EACE,6BAA6B;A7E23S/B;;A8E33SE;E5EOF;;;I4EDM,4BAA4B;IAE5B,2BAA2B;E9E23S/B;E8Ex3SE;IAEI,0BAA0B;E9Ey3ShC;E8Eh3SE;IACE,6BAA6B;E9Ek3SjC;EEprSF;I4E/KM,gCAAgC;E9Es2SpC;E8Ep2SE;;IAEE,yB3EzCY;I2E0CZ,wBAAwB;E9Es2S5B;E8E91SE;IACE,2BAA2B;E9Eg2S/B;E8E71SE;;IAEE,wBAAwB;E9E+1S5B;E8E51SE;;;IAGE,UAAU;IACV,SAAS;E9E81Sb;E8E31SE;;IAEE,uBAAuB;E9E61S3B;E8Er1SE;IACE,Q3E+hCgC;EHwzQpC;EEn4SF;I4E+CM,2BAA2C;E9Eu1S/C;E8Er1SE;IACE,2BAA2C;E9Eu1S/C;EiCr6SF;I6CmFM,aAAa;E9Eq1SjB;EsCp7SF;IwCkGM,sB3EtFS;EH26Sb;EgBx7SF;I8DuGM,oCAAoC;E9Eo1SxC;E8Er1SE;;IAKI,iCAAmC;E9Eo1SzC;EgBv5SF;;I8D0EQ,oCAAsC;E9Ei1S5C;EgBt0SF;I8DNM,cAAc;E9E+0SlB;EiBr8SA;;;;I6D4HM,qB3EvHU;EHs8ShB;EgBj2SF;I8DuBM,cAAc;IACd,qB3E7HY;EH08ShB;AACF","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"code\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"input-group\";\n@import \"custom-forms\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"jumbotron\";\n@import \"alert\";\n@import \"progress\";\n@import \"media\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"utilities\";\n@import \"print\";\n","/*!\n * Bootstrap v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-wrap: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n color: #212529;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n color: #212529;\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #343a40;\n border-color: #454d55;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #454d55;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\ninput[type=\"date\"].form-control,\ninput[type=\"time\"].form-control,\ninput[type=\"datetime-local\"].form-control,\ninput[type=\"month\"].form-control {\n appearance: none;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: 0.375rem 0;\n margin-bottom: 0;\n font-size: 1rem;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(1.5em + 1rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input[disabled] ~ .form-check-label,\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.form-row > .col > .valid-tooltip,\n.form-row > [class*=\"col-\"] > .valid-tooltip {\n left: 5px;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat, #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.form-row > .col > .invalid-tooltip,\n.form-row > [class*=\"col-\"] > .invalid-tooltip {\n left: 5px;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat, #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n text-decoration: none;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #e9ecef;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #adb5bd;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n min-width: 0;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group:not(.has-validation) > .form-control:not(:last-child),\n.input-group:not(.has-validation) > .custom-select:not(:last-child),\n.input-group:not(.has-validation) > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group.has-validation > .form-control:nth-last-child(n + 3),\n.input-group.has-validation > .custom-select:nth-last-child(n + 3),\n.input-group.has-validation > .custom-file:nth-last-child(n + 3) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(1.5em + 1rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.5em + 0.5rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n color-adjust: exact;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1;\n width: 1rem;\n height: 1.25rem;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background: 50% / 50% 50% no-repeat;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n display: none;\n}\n\n.custom-select:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.custom-select-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(1.5em + 1rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin: 0;\n overflow: hidden;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input[disabled] ~ .custom-file-label,\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n overflow: hidden;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(1.5em + 0.75rem);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: 1.4rem;\n padding: 0;\n background-color: transparent;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: 0;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-link {\n margin-bottom: -1px;\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar .container,\n.navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: 50% / 100% 100% no-repeat;\n}\n\n.navbar-nav-scroll {\n max-height: 75vh;\n overflow-y: auto;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-nav-scroll {\n overflow: visible;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n}\n\n.card > .list-group:first-child {\n border-top-width: 0;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card > .list-group:last-child {\n border-bottom-width: 0;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n border-top: 0;\n}\n\n.card-body {\n flex: 1 1 auto;\n min-height: 1px;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0;\n width: 100%;\n}\n\n.card-img,\n.card-img-top {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n display: flex;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n flex: 1 0 0%;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n display: flex;\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion {\n overflow-anchor: none;\n}\n\n.accordion > .card {\n overflow: hidden;\n}\n\n.accordion > .card:not(:last-of-type) {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion > .card:not(:first-of-type) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion > .card > .card-header {\n border-radius: 0;\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n float: left;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 3;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 3;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .badge {\n transition: none;\n }\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\na.badge-primary:focus, a.badge-primary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\na.badge-secondary:focus, a.badge-secondary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\na.badge-success:focus, a.badge-success.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\na.badge-info:focus, a.badge-info.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\na.badge-warning:focus, a.badge-warning.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\na.badge-danger:focus, a.badge-danger.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\na.badge-light:focus, a.badge-light.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\na.badge-dark:focus, a.badge-dark.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n line-height: 0;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: 1s linear infinite progress-bar-stripes;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n animation: none;\n }\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n border-radius: 0.25rem;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n\n.list-group-item:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-item + .list-group-item {\n border-top-width: 0;\n}\n\n.list-group-item + .list-group-item.active {\n margin-top: -1px;\n border-top-width: 1px;\n}\n\n.list-group-horizontal {\n flex-direction: row;\n}\n\n.list-group-horizontal > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item.active {\n margin-top: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n flex-direction: row;\n }\n .list-group-horizontal-sm > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n flex-direction: row;\n }\n .list-group-horizontal-md > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n flex-direction: row;\n }\n .list-group-horizontal-lg > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n flex-direction: row;\n }\n .list-group-horizontal-xl > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n.list-group-flush {\n border-radius: 0;\n}\n\n.list-group-flush > .list-group-item {\n border-width: 0 0 1px;\n}\n\n.list-group-flush > .list-group-item:last-child {\n border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n flex-basis: 350px;\n max-width: 350px;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n opacity: 0;\n border-radius: 0.25rem;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -50px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n transform: none;\n}\n\n.modal.modal-static .modal-dialog {\n transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n display: flex;\n max-height: calc(100% - 1rem);\n}\n\n.modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 1rem);\n overflow: hidden;\n}\n\n.modal-dialog-scrollable .modal-header,\n.modal-dialog-scrollable .modal-footer {\n flex-shrink: 0;\n}\n\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - 1rem);\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - 1rem);\n height: min-content;\n content: \"\";\n}\n\n.modal-dialog-centered.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable .modal-content {\n max-height: none;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable::before {\n content: none;\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #dee2e6;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n padding: 0.75rem;\n border-top: 1px solid #dee2e6;\n border-bottom-right-radius: calc(0.3rem - 1px);\n border-bottom-left-radius: calc(0.3rem - 1px);\n}\n\n.modal-footer > * {\n margin: 0.25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-scrollable {\n max-height: calc(100% - 3.5rem);\n }\n .modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 3.5rem);\n }\n .modal-dialog-centered {\n min-height: calc(100% - 3.5rem);\n }\n .modal-dialog-centered::before {\n height: calc(100vh - 3.5rem);\n height: min-content;\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=\"top\"] > .arrow {\n bottom: calc(-0.5rem - 1px);\n}\n\n.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=\"top\"] > .arrow::before {\n bottom: 0;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=\"top\"] > .arrow::after {\n bottom: 1px;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=\"right\"] > .arrow {\n left: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=\"right\"] > .arrow::before {\n left: 0;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=\"right\"] > .arrow::after {\n left: 1px;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow {\n top: calc(-0.5rem - 1px);\n}\n\n.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::before {\n top: 0;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::after {\n top: 1px;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=\"left\"] > .arrow {\n right: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=\"left\"] > .arrow::before {\n right: 0;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=\"left\"] > .arrow::after {\n right: 1px;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n transition: transform 0.6s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: opacity 0s 0.6s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: 50% / 100% 100% no-repeat;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@keyframes spinner-border {\n to {\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: .75s linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n animation: .75s linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .spinner-border,\n .spinner-grow {\n animation-duration: 1.5s;\n }\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded-sm {\n border-radius: 0.2rem !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-lg {\n border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.user-select-all {\n user-select: all !important;\n}\n\n.user-select-auto {\n user-select: auto !important;\n}\n\n.user-select-none {\n user-select: none !important;\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n pointer-events: auto;\n content: \"\";\n background-color: rgba(0, 0, 0, 0);\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !important;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-break {\n word-break: break-word !important;\n word-wrap: break-word !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n$grid-row-columns: 6 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n$table-th-font-weight: null !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height-lg * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n$custom-control-cursor: null !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-label-color: null !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: null !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: null !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/></svg>\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'><path stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/></svg>\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: null !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'><circle r='3' fill='#{$custom-control-indicator-checked-color}'/></svg>\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>\") !default;\n$custom-select-background: escape-svg($custom-select-indicator) right $custom-select-padding-x center / $custom-select-bg-size no-repeat !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n\n$form-validation-states: () !default;\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-nav-scroll-max-height: 75vh !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-200 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-500 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n$pagination-border-radius-sm: $border-radius-sm !default;\n$pagination-border-radius-lg: $border-radius-lg !default;\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-font-size: null !default;\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' width='8' height='8' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n$user-selects: all, auto, none !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { @include font-size($h1-font-size); }\nh2, .h2 { @include font-size($h2-font-size); }\nh3, .h3 { @include font-size($h3-font-size); }\nh4, .h4 { @include font-size($h4-font-size); }\nh5, .h5 { @include font-size($h5-font-size); }\nh6, .h6 { @include font-size($h6-font-size); }\n\n.lead {\n @include font-size($lead-font-size);\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n @include font-size($display1-size);\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n @include font-size($display2-size);\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n @include font-size($display3-size);\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n @include font-size($display4-size);\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n @include font-size($small-font-size);\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled();\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled();\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n @include font-size(90%);\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n @include font-size($blockquote-font-size);\n}\n\n.blockquote-footer {\n display: block;\n @include font-size($blockquote-small-font-size);\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014\\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled() {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid();\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid();\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: $spacer / 2;\n line-height: 1;\n}\n\n.figure-caption {\n @include font-size($figure-caption-font-size);\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid() {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n @include deprecate(\"`img-retina()`\", \"v4.3.0\", \"v5\");\n}\n","// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n $return: ();\n @each $value in $radius {\n @if type-of($value) == number {\n $return: append($return, max($value, 0));\n } @else {\n $return: append($return, $value);\n }\n }\n @return $return;\n}\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: valid-radius($radius);\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n","// Inline code\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n @include font-size(100%);\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n margin-bottom: $spacer;\n color: $table-color;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: 2 * $table-border-width;\n }\n }\n}\n\n.table-borderless {\n th,\n td,\n thead th,\n tbody + tbody {\n border: 0;\n }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover() {\n color: $table-hover-color;\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover() {\n color: $table-dark-hover-color;\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background, $border: null) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n\n @if $border != null {\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $border;\n }\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover() {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// Bootstrap functions\n//\n// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.\n\n// Ascending\n// Used to evaluate Sass maps like our grid breakpoints.\n@mixin _assert-ascending($map, $map-name) {\n $prev-key: null;\n $prev-num: null;\n @each $key, $num in $map {\n @if $prev-num == null or unit($num) == \"%\" or unit($prev-num) == \"%\" {\n // Do nothing\n } @else if not comparable($prev-num, $num) {\n @warn \"Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n } @else if $prev-num >= $num {\n @warn \"Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n }\n $prev-key: $key;\n $prev-num: $num;\n }\n}\n\n// Starts at zero\n// Used to ensure the min-width of the lowest breakpoint starts at 0.\n@mixin _assert-starts-at-zero($map, $map-name: \"$grid-breakpoints\") {\n @if length($map) > 0 {\n $values: map-values($map);\n $first-value: nth($values, 1);\n @if $first-value != 0 {\n @warn \"First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.\";\n }\n }\n}\n\n// Replace `$search` with `$replace` in `$string`\n// Used on our SVG icon backgrounds for custom forms.\n//\n// @author Hugo Giraudel\n// @param {String} $string - Initial string\n// @param {String} $search - Substring to replace\n// @param {String} $replace ('') - New value\n// @return {String} - Updated string\n@function str-replace($string, $search, $replace: \"\") {\n $index: str-index($string, $search);\n\n @if $index {\n @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);\n }\n\n @return $string;\n}\n\n// See https://codepen.io/kevinweber/pen/dXWoRw\n//\n// Requires the use of quotes around data URIs.\n\n@function escape-svg($string) {\n @if str-index($string, \"data:image/svg+xml\") {\n @each $char, $encoded in $escaped-characters {\n // Do not escape the url brackets\n @if str-index($string, \"url(\") == 1 {\n $string: url(\"#{str-replace(str-slice($string, 6, -3), $char, $encoded)}\");\n } @else {\n $string: str-replace($string, $char, $encoded);\n }\n }\n }\n\n @return $string;\n}\n\n// Color contrast\n@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {\n $r: red($color);\n $g: green($color);\n $b: blue($color);\n\n $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;\n\n @if ($yiq >= $yiq-contrasted-threshold) {\n @return $dark;\n } @else {\n @return $light;\n }\n}\n\n// Retrieve color Sass maps\n@function color($key: \"blue\") {\n @return map-get($colors, $key);\n}\n\n@function theme-color($key: \"primary\") {\n @return map-get($theme-colors, $key);\n}\n\n@function gray($key: \"100\") {\n @return map-get($grays, $key);\n}\n\n// Request a theme color level\n@function theme-color-level($color-name: \"primary\", $level: 0) {\n $color: theme-color($color-name);\n $color-base: if($level > 0, $black, $white);\n $level: abs($level);\n\n @return mix($color-base, $color, $level * $theme-color-interval);\n}\n\n// Return valid calc\n@function add($value1, $value2, $return-calc: true) {\n @if $value1 == null {\n @return $value2;\n }\n\n @if $value2 == null {\n @return $value1;\n }\n\n @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n @return $value1 + $value2;\n }\n\n @return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(\" + \") + $value2);\n}\n\n@function subtract($value1, $value2, $return-calc: true) {\n @if $value1 == null and $value2 == null {\n @return null;\n }\n\n @if $value1 == null {\n @return -$value2;\n }\n\n @if $value2 == null {\n @return $value1;\n }\n\n @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n @return $value1 - $value2;\n }\n\n @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(\" - \") + $value2);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n height: $input-height;\n padding: $input-padding-y $input-padding-x;\n font-family: $input-font-family;\n @include font-size($input-font-size);\n font-weight: $input-font-weight;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n @include border-radius($input-border-radius, 0);\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n background-color: transparent;\n border: 0;\n }\n\n // Remove select outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $input-color;\n }\n\n // Customize the `:focus` state to imitate native WebKit styles.\n @include form-control-focus($ignore-warning: true);\n\n // Placeholder\n &::placeholder {\n color: $input-placeholder-color;\n // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n opacity: 1;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &:disabled,\n &[readonly] {\n background-color: $input-disabled-bg;\n // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n opacity: 1;\n }\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n &.form-control {\n appearance: none; // Fix appearance for date inputs in Safari\n }\n}\n\nselect.form-control {\n &:focus::-ms-value {\n // Suppress the nested default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: add($input-padding-y, $input-border-width);\n padding-bottom: add($input-padding-y, $input-border-width);\n margin-bottom: 0; // Override the `<label>/<legend>` default\n @include font-size(inherit); // Override the `<legend>` default\n line-height: $input-line-height;\n}\n\n.col-form-label-lg {\n padding-top: add($input-padding-y-lg, $input-border-width);\n padding-bottom: add($input-padding-y-lg, $input-border-width);\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n}\n\n.col-form-label-sm {\n padding-top: add($input-padding-y-sm, $input-border-width);\n padding-bottom: add($input-padding-y-sm, $input-border-width);\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n}\n\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: $input-padding-y 0;\n margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n @include font-size($input-font-size);\n line-height: $input-line-height;\n color: $input-plaintext-color;\n background-color: transparent;\n border: solid transparent;\n border-width: $input-border-width 0;\n\n &.form-control-sm,\n &.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n height: $input-height-sm;\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.form-control-lg {\n height: $input-height-lg;\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n// stylelint-disable-next-line no-duplicate-selectors\nselect.form-control {\n &[size],\n &[multiple] {\n height: auto;\n }\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: $form-group-margin-bottom;\n}\n\n.form-text {\n display: block;\n margin-top: $form-text-margin-top;\n}\n\n\n// Form grid\n//\n// Special replacement for our grid system's `.row` for tighter form layouts.\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$form-grid-gutter-width / 2;\n margin-left: -$form-grid-gutter-width / 2;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: $form-grid-gutter-width / 2;\n padding-left: $form-grid-gutter-width / 2;\n }\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.form-check {\n position: relative;\n display: block;\n padding-left: $form-check-input-gutter;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: $form-check-input-margin-y;\n margin-left: -$form-check-input-gutter;\n\n // Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .form-check-label,\n &:disabled ~ .form-check-label {\n color: $text-muted;\n }\n}\n\n.form-check-label {\n margin-bottom: 0; // Override default `<label>` bottom margin\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0; // Override base .form-check\n margin-right: $form-check-inline-margin-x;\n\n // Undo .form-check-input defaults and add some `margin-right`.\n .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: $form-check-inline-input-margin-x;\n margin-left: 0;\n }\n}\n\n\n// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server side validation.\n\n@each $state, $data in $form-validation-states {\n @include form-validation-state($state, map-get($data, color), map-get($data, icon));\n}\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)\n\n // Because we use flex, the initial sizing of checkboxes is collapsed and\n // doesn't occupy the full-width (which is what we want for xs grid tier),\n // so we force that here.\n .form-check {\n width: 100%;\n }\n\n // Kick in the inline\n @include media-breakpoint-up(sm) {\n label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n\n // Inline-block all the things for \"inline\"\n .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n\n // Allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-plaintext {\n display: inline-block;\n }\n\n .input-group,\n .custom-select {\n width: auto;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: $form-check-input-margin-x;\n margin-left: 0;\n }\n\n .custom-control {\n align-items: center;\n justify-content: center;\n }\n .custom-control-label {\n margin-bottom: 0;\n }\n }\n}\n","// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n @if length($transition) == 0 {\n $transition: $transition-base;\n }\n\n @if length($transition) > 1 {\n @each $value in $transition {\n @if $value == null or $value == none {\n @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n }\n }\n }\n\n @if $enable-transitions {\n @if nth($transition, 1) != null {\n transition: $transition;\n }\n\n @if $enable-prefers-reduced-motion-media-query and nth($transition, 1) != null and nth($transition, 1) != none {\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n }\n}\n","// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `$input-focus-border-color` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n@mixin form-control-focus($ignore-warning: false) {\n &:focus {\n color: $input-focus-color;\n background-color: $input-focus-bg;\n border-color: $input-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($input-box-shadow, $input-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $input-focus-box-shadow;\n }\n }\n @include deprecate(\"The `form-control-focus()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n// This mixin uses an `if()` technique to be compatible with Dart Sass\n// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details\n@mixin form-validation-state-selector($state) {\n @if ($state == \"valid\" or $state == \"invalid\") {\n .was-validated #{if(&, \"&\", \"\")}:#{$state},\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n } @else {\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n }\n}\n\n@mixin form-validation-state($state, $color, $icon) {\n .#{$state}-feedback {\n display: none;\n width: 100%;\n margin-top: $form-feedback-margin-top;\n @include font-size($form-feedback-font-size);\n color: $color;\n }\n\n .#{$state}-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%; // Contain to parent when possible\n padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n margin-top: .1rem;\n @include font-size($form-feedback-tooltip-font-size);\n line-height: $form-feedback-tooltip-line-height;\n color: color-yiq($color);\n background-color: rgba($color, $form-feedback-tooltip-opacity);\n @include border-radius($form-feedback-tooltip-border-radius);\n\n // See https://github.com/twbs/bootstrap/pull/31557\n // Align tooltip to form elements\n .form-row > .col > &,\n .form-row > [class*=\"col-\"] > & {\n left: $form-grid-gutter-width / 2;\n }\n }\n\n @include form-validation-state-selector($state) {\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n\n .form-control {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-image: escape-svg($icon);\n background-repeat: no-repeat;\n background-position: right $input-height-inner-quarter center;\n background-size: $input-height-inner-half $input-height-inner-half;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n // stylelint-disable-next-line selector-no-qualifying-type\n textarea.form-control {\n @include form-validation-state-selector($state) {\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n }\n }\n }\n\n .custom-select {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $custom-select-feedback-icon-padding-right;\n background: $custom-select-background, $custom-select-bg escape-svg($icon) $custom-select-feedback-icon-position / $custom-select-feedback-icon-size no-repeat;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n .form-check-input {\n @include form-validation-state-selector($state) {\n ~ .form-check-label {\n color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .custom-control-input {\n @include form-validation-state-selector($state) {\n ~ .custom-control-label {\n color: $color;\n\n &::before {\n border-color: $color;\n }\n }\n\n &:checked {\n ~ .custom-control-label::before {\n border-color: lighten($color, 10%);\n @include gradient-bg(lighten($color, 10%));\n }\n }\n\n &:focus {\n ~ .custom-control-label::before {\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n &:not(:checked) ~ .custom-control-label::before {\n border-color: $color;\n }\n }\n }\n }\n\n // custom file\n .custom-file-input {\n @include form-validation-state-selector($state) {\n ~ .custom-file-label {\n border-color: $color;\n }\n\n &:focus {\n ~ .custom-file-label {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.btn {\n display: inline-block;\n font-family: $btn-font-family;\n font-weight: $btn-font-weight;\n color: $body-color;\n text-align: center;\n text-decoration: if($link-decoration == none, null, none);\n white-space: $btn-white-space;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: $btn-border-width solid transparent;\n @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);\n @include transition($btn-transition);\n\n @include hover() {\n color: $body-color;\n text-decoration: none;\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: $btn-focus-box-shadow;\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n opacity: $btn-disabled-opacity;\n @include box-shadow(none);\n }\n\n &:not(:disabled):not(.disabled) {\n cursor: if($enable-pointer-cursor-for-buttons, pointer, null);\n\n &:active,\n &.active {\n @include box-shadow($btn-active-box-shadow);\n\n &:focus {\n @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n }\n }\n }\n}\n\n// Future-proof disabling of clicks on `<a>` elements\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n\n//\n// Alternate buttons\n//\n\n@each $color, $value in $theme-colors {\n .btn-#{$color} {\n @include button-variant($value, $value);\n }\n}\n\n@each $color, $value in $theme-colors {\n .btn-outline-#{$color} {\n @include button-outline-variant($value);\n }\n}\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n font-weight: $font-weight-normal;\n color: $link-color;\n text-decoration: $link-decoration;\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n\n &:focus,\n &.focus {\n text-decoration: $link-hover-decoration;\n }\n\n &:disabled,\n &.disabled {\n color: $btn-link-disabled-color;\n pointer-events: none;\n }\n\n // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);\n}\n\n\n//\n// Block button\n//\n\n.btn-block {\n display: block;\n width: 100%;\n\n // Vertically space out multiple block buttons\n + .btn-block {\n margin-top: $btn-block-spacing-y;\n }\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {\n color: color-yiq($background);\n @include gradient-bg($background);\n border-color: $border;\n @include box-shadow($btn-box-shadow);\n\n @include hover() {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n }\n\n &:focus,\n &.focus {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n @if $enable-shadows {\n @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n color: color-yiq($background);\n background-color: $background;\n border-color: $border;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n @if $enable-gradients {\n background-image: none; // Remove the gradient for the pressed/active state\n }\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n }\n}\n\n@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {\n color: $color;\n border-color: $color;\n\n @include hover() {\n color: $color-hover;\n background-color: $active-background;\n border-color: $active-border;\n }\n\n &:focus,\n &.focus {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n\n &.disabled,\n &:disabled {\n color: $color;\n background-color: transparent;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n }\n }\n}\n\n// Button sizes\n@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n // Manually declare to provide an override to the browser default\n @include border-radius($border-radius, 0);\n}\n",".fade {\n @include transition($transition-fade);\n\n &:not(.show) {\n opacity: 0;\n }\n}\n\n.collapse {\n &:not(.show) {\n display: none;\n }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n @include transition($transition-collapse);\n}\n","// The dropdown wrapper (`<div>`)\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n\n // Generate the caret automatically\n @include caret();\n}\n\n// The dropdown menu\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: $zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: $dropdown-min-width;\n padding: $dropdown-padding-y $dropdown-padding-x;\n margin: $dropdown-spacer 0 0; // override default ul\n @include font-size($dropdown-font-size);\n color: $dropdown-color;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n list-style: none;\n background-color: $dropdown-bg;\n background-clip: padding-box;\n border: $dropdown-border-width solid $dropdown-border-color;\n @include border-radius($dropdown-border-radius);\n @include box-shadow($dropdown-box-shadow);\n}\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .dropdown-menu#{$infix}-left {\n right: auto;\n left: 0;\n }\n\n .dropdown-menu#{$infix}-right {\n right: 0;\n left: auto;\n }\n }\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(up);\n }\n}\n\n.dropright {\n .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(right);\n &::after {\n vertical-align: 0;\n }\n }\n}\n\n.dropleft {\n .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(left);\n &::before {\n vertical-align: 0;\n }\n }\n}\n\n// When Popper is enabled, reset the basic dropdown position\n// stylelint-disable-next-line no-duplicate-selectors\n.dropdown-menu {\n &[x-placement^=\"top\"],\n &[x-placement^=\"right\"],\n &[x-placement^=\"bottom\"],\n &[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n }\n}\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n @include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n display: block;\n width: 100%; // For `<button>`s\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n clear: both;\n font-weight: $font-weight-normal;\n color: $dropdown-link-color;\n text-align: inherit; // For `<button>`s\n text-decoration: if($link-decoration == none, null, none);\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n background-color: transparent; // For `<button>`s\n border: 0; // For `<button>`s\n\n // Prevent dropdown overflow if there's no padding\n // See https://github.com/twbs/bootstrap/pull/27703\n @if $dropdown-padding-y == 0 {\n &:first-child {\n @include border-top-radius($dropdown-inner-border-radius);\n }\n\n &:last-child {\n @include border-bottom-radius($dropdown-inner-border-radius);\n }\n }\n\n @include hover-focus() {\n color: $dropdown-link-hover-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-hover-bg);\n }\n\n &.active,\n &:active {\n color: $dropdown-link-active-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-active-bg);\n }\n\n &.disabled,\n &:disabled {\n color: $dropdown-link-disabled-color;\n pointer-events: none;\n background-color: transparent;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: $dropdown-header-padding;\n margin-bottom: 0; // for use with heading elements\n @include font-size($font-size-sm);\n color: $dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n display: block;\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n color: $dropdown-link-color;\n}\n","@mixin caret-down() {\n border-top: $caret-width solid;\n border-right: $caret-width solid transparent;\n border-bottom: 0;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up() {\n border-top: 0;\n border-right: $caret-width solid transparent;\n border-bottom: $caret-width solid;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-right() {\n border-top: $caret-width solid transparent;\n border-right: 0;\n border-bottom: $caret-width solid transparent;\n border-left: $caret-width solid;\n}\n\n@mixin caret-left() {\n border-top: $caret-width solid transparent;\n border-right: $caret-width solid;\n border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n @if $enable-caret {\n &::after {\n display: inline-block;\n margin-left: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @if $direction == down {\n @include caret-down();\n } @else if $direction == up {\n @include caret-up();\n } @else if $direction == right {\n @include caret-right();\n }\n }\n\n @if $direction == left {\n &::after {\n display: none;\n }\n\n &::before {\n display: inline-block;\n margin-right: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @include caret-left();\n }\n }\n\n &:empty::after {\n margin-left: 0;\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y, $ignore-warning: false) {\n height: 0;\n margin: $margin-y 0;\n overflow: hidden;\n border-top: 1px solid $color;\n @include deprecate(\"The `nav-divider()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle; // match .btn alignment given font-size hack above\n\n > .btn {\n position: relative;\n flex: 1 1 auto;\n\n // Bring the hover, focused, and \"active\" buttons to the front to overlay\n // the borders properly\n @include hover() {\n z-index: 1;\n }\n &:focus,\n &:active,\n &.active {\n z-index: 1;\n }\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n\n .input-group {\n width: auto;\n }\n}\n\n.btn-group {\n // Prevent double borders when buttons are next to each other\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-left: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-right-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-left-radius(0);\n }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n padding-right: $btn-padding-x * .75;\n padding-left: $btn-padding-x * .75;\n\n &::after,\n .dropup &::after,\n .dropright &::after {\n margin-left: 0;\n }\n\n .dropleft &::before {\n margin-right: 0;\n }\n}\n\n.btn-sm + .dropdown-toggle-split {\n padding-right: $btn-padding-x-sm * .75;\n padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n padding-right: $btn-padding-x-lg * .75;\n padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n @include box-shadow($btn-active-box-shadow);\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n @include box-shadow(none);\n }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n\n > .btn,\n > .btn-group {\n width: 100%;\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-top: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-bottom-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-top-radius(0);\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n.btn-group-toggle {\n > .btn,\n > .btn-group > .btn {\n margin-bottom: 0; // Override default `<label>` value\n\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap; // For form validation feedback\n align-items: stretch;\n width: 100%;\n\n > .form-control,\n > .form-control-plaintext,\n > .custom-select,\n > .custom-file {\n position: relative; // For focus state's z-index\n flex: 1 1 auto;\n width: 1%;\n min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size\n margin-bottom: 0;\n\n + .form-control,\n + .custom-select,\n + .custom-file {\n margin-left: -$input-border-width;\n }\n }\n\n // Bring the \"active\" form control to the top of surrounding elements\n > .form-control:focus,\n > .custom-select:focus,\n > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n }\n\n // Bring the custom file input above the label\n > .custom-file .custom-file-input:focus {\n z-index: 4;\n }\n\n > .form-control,\n > .custom-select {\n &:not(:first-child) { @include border-left-radius(0); }\n }\n\n // Custom file inputs have more complex markup, thus requiring different\n // border-radius overrides.\n > .custom-file {\n display: flex;\n align-items: center;\n\n &:not(:last-child) .custom-file-label,\n &:not(:first-child) .custom-file-label { @include border-left-radius(0); }\n }\n\n &:not(.has-validation) {\n > .form-control:not(:last-child),\n > .custom-select:not(:last-child),\n > .custom-file:not(:last-child) .custom-file-label::after {\n @include border-right-radius(0);\n }\n }\n\n &.has-validation {\n > .form-control:nth-last-child(n + 3),\n > .custom-select:nth-last-child(n + 3),\n > .custom-file:nth-last-child(n + 3) .custom-file-label::after {\n @include border-right-radius(0);\n }\n }\n}\n\n\n// Prepend and append\n//\n// While it requires one extra layer of HTML for each, dedicated prepend and\n// append elements allow us to 1) be less clever, 2) simplify our selectors, and\n// 3) support HTML5 form validation.\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n\n // Ensure buttons are always above inputs for more visually pleasing borders.\n // This isn't needed for `.input-group-text` since it shares the same border-color\n // as our inputs.\n .btn {\n position: relative;\n z-index: 2;\n\n &:focus {\n z-index: 3;\n }\n }\n\n .btn + .btn,\n .btn + .input-group-text,\n .input-group-text + .input-group-text,\n .input-group-text + .btn {\n margin-left: -$input-border-width;\n }\n}\n\n.input-group-prepend { margin-right: -$input-border-width; }\n.input-group-append { margin-left: -$input-border-width; }\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: $input-padding-y $input-padding-x;\n margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom\n @include font-size($input-font-size); // Match inputs\n font-weight: $font-weight-normal;\n line-height: $input-line-height;\n color: $input-group-addon-color;\n text-align: center;\n white-space: nowrap;\n background-color: $input-group-addon-bg;\n border: $input-border-width solid $input-group-addon-border-color;\n @include border-radius($input-border-radius);\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: $input-height-lg;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: $input-height-sm;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: $custom-select-padding-x + $custom-select-indicator-padding;\n}\n\n\n// Prepend and append rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n @include border-right-radius(0);\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n @include border-left-radius(0);\n}\n","// Embedded icons from Open Iconic.\n// Released under MIT and copyright 2014 Waybury.\n// https://useiconic.com/open\n\n\n// Checkboxes and radios\n//\n// Base class takes care of all the key behavioral aspects.\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: $font-size-base * $line-height-base;\n padding-left: $custom-control-gutter + $custom-control-indicator-size;\n color-adjust: exact; // Keep themed appearance for print\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: $custom-control-spacer-x;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1; // Put the input behind the label so it doesn't overlay text\n width: $custom-control-indicator-size;\n height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;\n opacity: 0;\n\n &:checked ~ .custom-control-label::before {\n color: $custom-control-indicator-checked-color;\n border-color: $custom-control-indicator-checked-border-color;\n @include gradient-bg($custom-control-indicator-checked-bg);\n @include box-shadow($custom-control-indicator-checked-box-shadow);\n }\n\n &:focus ~ .custom-control-label::before {\n // the mixin is not used here to make sure there is feedback\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $custom-control-indicator-focus-box-shadow;\n } @else {\n box-shadow: $custom-control-indicator-focus-box-shadow;\n }\n }\n\n &:focus:not(:checked) ~ .custom-control-label::before {\n border-color: $custom-control-indicator-focus-border-color;\n }\n\n &:not(:disabled):active ~ .custom-control-label::before {\n color: $custom-control-indicator-active-color;\n background-color: $custom-control-indicator-active-bg;\n border-color: $custom-control-indicator-active-border-color;\n @include box-shadow($custom-control-indicator-active-box-shadow);\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled],\n &:disabled {\n ~ .custom-control-label {\n color: $custom-control-label-disabled-color;\n\n &::before {\n background-color: $custom-control-indicator-disabled-bg;\n }\n }\n }\n}\n\n// Custom control indicators\n//\n// Build the custom controls out of pseudo-elements.\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n color: $custom-control-label-color;\n vertical-align: top;\n cursor: $custom-control-cursor;\n\n // Background-color and (when enabled) gradient\n &::before {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n pointer-events: none;\n content: \"\";\n background-color: $custom-control-indicator-bg;\n border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;\n @include box-shadow($custom-control-indicator-box-shadow);\n }\n\n // Foreground (icon)\n &::after {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n content: \"\";\n background: 50% / #{$custom-control-indicator-bg-size} no-repeat;\n }\n}\n\n\n// Checkboxes\n//\n// Tweak just a few things for checkboxes.\n\n.custom-checkbox {\n .custom-control-label::before {\n @include border-radius($custom-checkbox-indicator-border-radius);\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-checked);\n }\n }\n\n .custom-control-input:indeterminate ~ .custom-control-label {\n &::before {\n border-color: $custom-checkbox-indicator-indeterminate-border-color;\n @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);\n @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);\n }\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n &:indeterminate ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n// Radios\n//\n// Tweak just a few things for radios.\n\n.custom-radio {\n .custom-control-label::before {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-radio-indicator-border-radius;\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-radio-indicator-icon-checked);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// switches\n//\n// Tweak a few things for switches\n\n.custom-switch {\n padding-left: $custom-switch-width + $custom-control-gutter;\n\n .custom-control-label {\n &::before {\n left: -($custom-switch-width + $custom-control-gutter);\n width: $custom-switch-width;\n pointer-events: all;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n }\n\n &::after {\n top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);\n left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);\n width: $custom-switch-indicator-size;\n height: $custom-switch-indicator-size;\n background-color: $custom-control-indicator-border-color;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n @include transition(transform .15s ease-in-out, $custom-forms-transition);\n }\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-color: $custom-control-indicator-bg;\n transform: translateX($custom-switch-width - $custom-control-indicator-size);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n//\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: $custom-select-height;\n padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;\n font-family: $custom-select-font-family;\n @include font-size($custom-select-font-size);\n font-weight: $custom-select-font-weight;\n line-height: $custom-select-line-height;\n color: $custom-select-color;\n vertical-align: middle;\n background: $custom-select-bg $custom-select-background;\n border: $custom-select-border-width solid $custom-select-border-color;\n @include border-radius($custom-select-border-radius, 0);\n @include box-shadow($custom-select-box-shadow);\n appearance: none;\n\n &:focus {\n border-color: $custom-select-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $custom-select-focus-box-shadow;\n }\n\n &::-ms-value {\n // For visual consistency with other platforms/browsers,\n // suppress the default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n }\n\n &[multiple],\n &[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: $custom-select-padding-x;\n background-image: none;\n }\n\n &:disabled {\n color: $custom-select-disabled-color;\n background-color: $custom-select-disabled-bg;\n }\n\n // Hides the default caret in IE11\n &::-ms-expand {\n display: none;\n }\n\n // Remove outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $custom-select-color;\n }\n}\n\n.custom-select-sm {\n height: $custom-select-height-sm;\n padding-top: $custom-select-padding-y-sm;\n padding-bottom: $custom-select-padding-y-sm;\n padding-left: $custom-select-padding-x-sm;\n @include font-size($custom-select-font-size-sm);\n}\n\n.custom-select-lg {\n height: $custom-select-height-lg;\n padding-top: $custom-select-padding-y-lg;\n padding-bottom: $custom-select-padding-y-lg;\n padding-left: $custom-select-padding-x-lg;\n @include font-size($custom-select-font-size-lg);\n}\n\n\n// File\n//\n// Custom file input.\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: $custom-file-height;\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: $custom-file-height;\n margin: 0;\n overflow: hidden;\n opacity: 0;\n\n &:focus ~ .custom-file-label {\n border-color: $custom-file-focus-border-color;\n box-shadow: $custom-file-focus-box-shadow;\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .custom-file-label,\n &:disabled ~ .custom-file-label {\n background-color: $custom-file-disabled-bg;\n }\n\n @each $lang, $value in $custom-file-text {\n &:lang(#{$lang}) ~ .custom-file-label::after {\n content: $value;\n }\n }\n\n ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n }\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: $custom-file-height;\n padding: $custom-file-padding-y $custom-file-padding-x;\n overflow: hidden;\n font-family: $custom-file-font-family;\n font-weight: $custom-file-font-weight;\n line-height: $custom-file-line-height;\n color: $custom-file-color;\n background-color: $custom-file-bg;\n border: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius($custom-file-border-radius);\n @include box-shadow($custom-file-box-shadow);\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: $custom-file-height-inner;\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-button-color;\n content: \"Browse\";\n @include gradient-bg($custom-file-button-bg);\n border-left: inherit;\n @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);\n }\n}\n\n// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.custom-range {\n width: 100%;\n height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);\n padding: 0; // Need to reset padding\n background-color: transparent;\n appearance: none;\n\n &:focus {\n outline: 0;\n\n // Pseudo-elements must be split across multiple rulesets to have an effect.\n // No box-shadow() mixin for focus accessibility.\n &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n }\n\n &::-moz-focus-outer {\n border: 0;\n }\n\n &::-webkit-slider-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-webkit-slider-runnable-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent; // Why?\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent;\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-moz-range-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-moz-range-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent; // Firefox specific?\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: 0; // Edge specific\n margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-ms-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: transparent;\n border-color: transparent;\n border-width: $custom-range-thumb-height / 2;\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-fill-lower {\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &::-ms-fill-upper {\n margin-right: 15px; // arbitrary?\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &:disabled {\n &::-webkit-slider-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-webkit-slider-runnable-track {\n cursor: default;\n }\n\n &::-moz-range-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-moz-range-track {\n cursor: default;\n }\n\n &::-ms-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n }\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n @include transition($custom-forms-transition);\n}\n","// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s, `<ul>`s or `<ol>`s.\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: $nav-link-padding-y $nav-link-padding-x;\n text-decoration: if($link-decoration == none, null, none);\n\n @include hover-focus() {\n text-decoration: none;\n }\n\n // Disabled state lightens text\n &.disabled {\n color: $nav-link-disabled-color;\n pointer-events: none;\n cursor: default;\n }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n .nav-link {\n margin-bottom: -$nav-tabs-border-width;\n border: $nav-tabs-border-width solid transparent;\n @include border-top-radius($nav-tabs-border-radius);\n\n @include hover-focus() {\n border-color: $nav-tabs-link-hover-border-color;\n }\n\n &.disabled {\n color: $nav-link-disabled-color;\n background-color: transparent;\n border-color: transparent;\n }\n }\n\n .nav-link.active,\n .nav-item.show .nav-link {\n color: $nav-tabs-link-active-color;\n background-color: $nav-tabs-link-active-bg;\n border-color: $nav-tabs-link-active-border-color;\n }\n\n .dropdown-menu {\n // Make dropdown border overlap tab border\n margin-top: -$nav-tabs-border-width;\n // Remove the top rounded corners here since there is a hard edge above the menu\n @include border-top-radius(0);\n }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n .nav-link {\n @include border-radius($nav-pills-border-radius);\n }\n\n .nav-link.active,\n .show > .nav-link {\n color: $nav-pills-link-active-color;\n background-color: $nav-pills-link-active-bg;\n }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n > .nav-link,\n .nav-item {\n flex: 1 1 auto;\n text-align: center;\n }\n}\n\n.nav-justified {\n > .nav-link,\n .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n","// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Navbar divider\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap; // allow us to do the line break for collapsing content\n align-items: center;\n justify-content: space-between; // space out brand from logo\n padding: $navbar-padding-y $navbar-padding-x;\n\n // Because flex properties aren't inherited, we need to redeclare these first\n // few properties so that content nested within behave properly.\n %container-flex-properties {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n }\n\n .container,\n .container-fluid {\n @extend %container-flex-properties;\n }\n\n @each $breakpoint, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {\n @extend %container-flex-properties;\n }\n }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n display: inline-block;\n padding-top: $navbar-brand-padding-y;\n padding-bottom: $navbar-brand-padding-y;\n margin-right: $navbar-padding-x;\n @include font-size($navbar-brand-font-size);\n line-height: inherit;\n white-space: nowrap;\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n display: flex;\n flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n\n .nav-link {\n padding-right: 0;\n padding-left: 0;\n }\n\n .dropdown-menu {\n position: static;\n float: none;\n }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n display: inline-block;\n padding-top: $nav-link-padding-y;\n padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n // For always expanded or extra full navbars, ensure content aligns itself\n // properly vertically. Can be easily overridden with flex utilities.\n align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n @include font-size($navbar-toggler-font-size);\n line-height: 1;\n background-color: transparent; // remove default button style\n border: $border-width solid transparent; // remove default button style\n @include border-radius($navbar-toggler-border-radius);\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: 50% / 100% 100% no-repeat;\n}\n\n.navbar-nav-scroll {\n max-height: $navbar-nav-scroll-max-height;\n overflow-y: auto;\n}\n\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n %container-navbar-expand-#{$breakpoint} {\n padding-right: 0;\n padding-left: 0;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n }\n }\n\n @include media-breakpoint-up($next) {\n flex-flow: row nowrap;\n justify-content: flex-start;\n\n .navbar-nav {\n flex-direction: row;\n\n .dropdown-menu {\n position: absolute;\n }\n\n .nav-link {\n padding-right: $navbar-nav-link-padding-x;\n padding-left: $navbar-nav-link-padding-x;\n }\n }\n\n // For nesting containers, have to redeclare for alignment purposes\n %container-nesting-#{$breakpoint} {\n flex-wrap: nowrap;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-nesting-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-nesting-#{$breakpoint};\n }\n }\n\n .navbar-nav-scroll {\n overflow: visible;\n }\n\n .navbar-collapse {\n display: flex !important; // stylelint-disable-line declaration-no-important\n\n // Changes flex-bases to auto because of an IE10 bug\n flex-basis: auto;\n }\n\n .navbar-toggler {\n display: none;\n }\n }\n }\n }\n}\n\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n .navbar-brand {\n color: $navbar-light-brand-color;\n\n @include hover-focus() {\n color: $navbar-light-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-light-color;\n\n @include hover-focus() {\n color: $navbar-light-hover-color;\n }\n\n &.disabled {\n color: $navbar-light-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-light-color;\n border-color: $navbar-light-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-light-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-light-color;\n a {\n color: $navbar-light-active-color;\n\n @include hover-focus() {\n color: $navbar-light-active-color;\n }\n }\n }\n}\n\n// White links against a dark background\n.navbar-dark {\n .navbar-brand {\n color: $navbar-dark-brand-color;\n\n @include hover-focus() {\n color: $navbar-dark-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-dark-color;\n\n @include hover-focus() {\n color: $navbar-dark-hover-color;\n }\n\n &.disabled {\n color: $navbar-dark-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-dark-color;\n border-color: $navbar-dark-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-dark-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-dark-color;\n a {\n color: $navbar-dark-active-color;\n\n @include hover-focus() {\n color: $navbar-dark-active-color;\n }\n }\n }\n}\n","//\n// Base styles\n//\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106\n height: $card-height;\n word-wrap: break-word;\n background-color: $card-bg;\n background-clip: border-box;\n border: $card-border-width solid $card-border-color;\n @include border-radius($card-border-radius);\n\n > hr {\n margin-right: 0;\n margin-left: 0;\n }\n\n > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n\n &:first-child {\n border-top-width: 0;\n @include border-top-radius($card-inner-border-radius);\n }\n\n &:last-child {\n border-bottom-width: 0;\n @include border-bottom-radius($card-inner-border-radius);\n }\n }\n\n // Due to specificity of the above selector (`.card > .list-group`), we must\n // use a child selector here to prevent double borders.\n > .card-header + .list-group,\n > .list-group + .card-footer {\n border-top: 0;\n }\n}\n\n.card-body {\n // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n // as much space as possible, ensuring footers are aligned to the bottom.\n flex: 1 1 auto;\n // Workaround for the image size bug in IE\n // See: https://github.com/twbs/bootstrap/pull/28855\n min-height: 1px;\n padding: $card-spacer-x;\n color: $card-color;\n}\n\n.card-title {\n margin-bottom: $card-spacer-y;\n}\n\n.card-subtitle {\n margin-top: -$card-spacer-y / 2;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link {\n @include hover() {\n text-decoration: none;\n }\n\n + .card-link {\n margin-left: $card-spacer-x;\n }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n padding: $card-spacer-y $card-spacer-x;\n margin-bottom: 0; // Removes the default margin-bottom of <hN>\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-bottom: $card-border-width solid $card-border-color;\n\n &:first-child {\n @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n }\n}\n\n.card-footer {\n padding: $card-spacer-y $card-spacer-x;\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-top: $card-border-width solid $card-border-color;\n\n &:last-child {\n @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n margin-right: -$card-spacer-x / 2;\n margin-bottom: -$card-spacer-y;\n margin-left: -$card-spacer-x / 2;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -$card-spacer-x / 2;\n margin-left: -$card-spacer-x / 2;\n}\n\n// Card image\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: $card-img-overlay-padding;\n @include border-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n}\n\n.card-img,\n.card-img-top {\n @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n// Card deck\n\n.card-deck {\n .card {\n margin-bottom: $card-deck-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n margin-right: -$card-deck-margin;\n margin-left: -$card-deck-margin;\n\n .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-right: $card-deck-margin;\n margin-bottom: 0; // Override the default\n margin-left: $card-deck-margin;\n }\n }\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n margin-bottom: $card-group-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-bottom: 0;\n\n + .card {\n margin-left: 0;\n border-left: 0;\n }\n\n // Handle rounded corners\n @if $enable-rounded {\n &:not(:last-child) {\n @include border-right-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-right-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-right-radius: 0;\n }\n }\n\n &:not(:first-child) {\n @include border-left-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-left-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-left-radius: 0;\n }\n }\n }\n }\n }\n}\n\n\n//\n// Columns\n//\n\n.card-columns {\n .card {\n margin-bottom: $card-columns-margin;\n }\n\n @include media-breakpoint-up(sm) {\n column-count: $card-columns-count;\n column-gap: $card-columns-gap;\n orphans: 1;\n widows: 1;\n\n .card {\n display: inline-block; // Don't let them vertically span multiple columns\n width: 100%; // Don't let their width change\n }\n }\n}\n\n\n//\n// Accordion\n//\n\n.accordion {\n overflow-anchor: none;\n\n > .card {\n overflow: hidden;\n\n &:not(:last-of-type) {\n border-bottom: 0;\n @include border-bottom-radius(0);\n }\n\n &:not(:first-of-type) {\n @include border-top-radius(0);\n }\n\n > .card-header {\n @include border-radius(0);\n margin-bottom: -$card-border-width;\n }\n }\n}\n",".breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n margin-bottom: $breadcrumb-margin-bottom;\n @include font-size($breadcrumb-font-size);\n list-style: none;\n background-color: $breadcrumb-bg;\n @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n + .breadcrumb-item {\n padding-left: $breadcrumb-item-padding;\n\n &::before {\n float: left; // Suppress inline spacings and underlining of the separator\n padding-right: $breadcrumb-item-padding;\n color: $breadcrumb-divider-color;\n content: escape-svg($breadcrumb-divider);\n }\n }\n\n // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built\n // without `<ul>`s. The `::before` pseudo-element generates an element\n // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.\n //\n // To trick IE into suppressing the underline, we give the pseudo-element an\n // underline and then immediately remove it.\n + .breadcrumb-item:hover::before {\n text-decoration: underline;\n }\n // stylelint-disable-next-line no-duplicate-selectors\n + .breadcrumb-item:hover::before {\n text-decoration: none;\n }\n\n &.active {\n color: $breadcrumb-active-color;\n }\n}\n",".pagination {\n display: flex;\n @include list-unstyled();\n @include border-radius();\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: $pagination-padding-y $pagination-padding-x;\n margin-left: -$pagination-border-width;\n line-height: $pagination-line-height;\n color: $pagination-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $pagination-bg;\n border: $pagination-border-width solid $pagination-border-color;\n\n &:hover {\n z-index: 2;\n color: $pagination-hover-color;\n text-decoration: none;\n background-color: $pagination-hover-bg;\n border-color: $pagination-hover-border-color;\n }\n\n &:focus {\n z-index: 3;\n outline: $pagination-focus-outline;\n box-shadow: $pagination-focus-box-shadow;\n }\n}\n\n.page-item {\n &:first-child {\n .page-link {\n margin-left: 0;\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n\n &.active .page-link {\n z-index: 3;\n color: $pagination-active-color;\n background-color: $pagination-active-bg;\n border-color: $pagination-active-border-color;\n }\n\n &.disabled .page-link {\n color: $pagination-disabled-color;\n pointer-events: none;\n // Opinionated: remove the \"hand\" cursor set previously for .page-link\n cursor: auto;\n background-color: $pagination-disabled-bg;\n border-color: $pagination-disabled-border-color;\n }\n}\n\n\n//\n// Sizing\n//\n\n.pagination-lg {\n @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $pagination-border-radius-lg);\n}\n\n.pagination-sm {\n @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $pagination-border-radius-sm);\n}\n","// Pagination\n\n@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n .page-link {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n }\n\n .page-item {\n &:first-child {\n .page-link {\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n }\n}\n","// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n display: inline-block;\n padding: $badge-padding-y $badge-padding-x;\n @include font-size($badge-font-size);\n font-weight: $badge-font-weight;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n @include border-radius($badge-border-radius);\n @include transition($badge-transition);\n\n @at-root a#{&} {\n @include hover-focus() {\n text-decoration: none;\n }\n }\n\n // Empty badges collapse automatically\n &:empty {\n display: none;\n }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Pill badges\n//\n// Make them extra rounded with a modifier to replace v3's badges.\n\n.badge-pill {\n padding-right: $badge-pill-padding-x;\n padding-left: $badge-pill-padding-x;\n @include border-radius($badge-pill-border-radius);\n}\n\n// Colors\n//\n// Contextual variations (linked badges get darker on :hover).\n\n@each $color, $value in $theme-colors {\n .badge-#{$color} {\n @include badge-variant($value);\n }\n}\n","@mixin badge-variant($bg) {\n color: color-yiq($bg);\n background-color: $bg;\n\n @at-root a#{&} {\n @include hover-focus() {\n color: color-yiq($bg);\n background-color: darken($bg, 10%);\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);\n }\n }\n}\n",".jumbotron {\n padding: $jumbotron-padding ($jumbotron-padding / 2);\n margin-bottom: $jumbotron-padding;\n color: $jumbotron-color;\n background-color: $jumbotron-bg;\n @include border-radius($border-radius-lg);\n\n @include media-breakpoint-up(sm) {\n padding: ($jumbotron-padding * 2) $jumbotron-padding;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n @include border-radius(0);\n}\n","//\n// Base styles\n//\n\n.alert {\n position: relative;\n padding: $alert-padding-y $alert-padding-x;\n margin-bottom: $alert-margin-bottom;\n border: $alert-border-width solid transparent;\n @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n // Specified to prevent conflicts of changing $headings-color\n color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n padding-right: $close-font-size + $alert-padding-x * 2;\n\n // Adjust close link position\n .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: $alert-padding-y $alert-padding-x;\n color: inherit;\n }\n}\n\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $color, $value in $theme-colors {\n .alert-#{$color} {\n @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));\n }\n}\n","@mixin alert-variant($background, $border, $color) {\n color: $color;\n @include gradient-bg($background);\n border-color: $border;\n\n hr {\n border-top-color: darken($border, 5%);\n }\n\n .alert-link {\n color: darken($color, 10%);\n }\n}\n","// Disable animation if transitions are disabled\n@if $enable-transitions {\n @keyframes progress-bar-stripes {\n from { background-position: $progress-height 0; }\n to { background-position: 0 0; }\n }\n}\n\n.progress {\n display: flex;\n height: $progress-height;\n overflow: hidden; // force rounded corners by cropping it\n line-height: 0;\n @include font-size($progress-font-size);\n background-color: $progress-bg;\n @include border-radius($progress-border-radius);\n @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: $progress-bar-color;\n text-align: center;\n white-space: nowrap;\n background-color: $progress-bar-bg;\n @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n @include gradient-striped();\n background-size: $progress-height $progress-height;\n}\n\n@if $enable-transitions {\n .progress-bar-animated {\n animation: $progress-bar-animation-timing progress-bar-stripes;\n\n @if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n}\n",".media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n","// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n display: flex;\n flex-direction: column;\n\n // No need to set list-style: none; since .list-group-item is block level\n padding-left: 0; // reset padding because ul and ol\n margin-bottom: 0;\n @include border-radius($list-group-border-radius);\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n width: 100%; // For `<button>`s (anchors become 100% by default though)\n color: $list-group-action-color;\n text-align: inherit; // For `<button>`s (anchors inherit)\n\n // Hover state\n @include hover-focus() {\n z-index: 1; // Place hover/focus items above their siblings for proper border styling\n color: $list-group-action-hover-color;\n text-decoration: none;\n background-color: $list-group-hover-bg;\n }\n\n &:active {\n color: $list-group-action-active-color;\n background-color: $list-group-action-active-bg;\n }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: $list-group-item-padding-y $list-group-item-padding-x;\n color: $list-group-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $list-group-bg;\n border: $list-group-border-width solid $list-group-border-color;\n\n &:first-child {\n @include border-top-radius(inherit);\n }\n\n &:last-child {\n @include border-bottom-radius(inherit);\n }\n\n &.disabled,\n &:disabled {\n color: $list-group-disabled-color;\n pointer-events: none;\n background-color: $list-group-disabled-bg;\n }\n\n // Include both here for `<a>`s and `<button>`s\n &.active {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: $list-group-active-color;\n background-color: $list-group-active-bg;\n border-color: $list-group-active-border-color;\n }\n\n & + & {\n border-top-width: 0;\n\n &.active {\n margin-top: -$list-group-border-width;\n border-top-width: $list-group-border-width;\n }\n }\n}\n\n\n// Horizontal\n//\n// Change the layout of list group items from vertical (default) to horizontal.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .list-group-horizontal#{$infix} {\n flex-direction: row;\n\n > .list-group-item {\n &:first-child {\n @include border-bottom-left-radius($list-group-border-radius);\n @include border-top-right-radius(0);\n }\n\n &:last-child {\n @include border-top-right-radius($list-group-border-radius);\n @include border-bottom-left-radius(0);\n }\n\n &.active {\n margin-top: 0;\n }\n\n + .list-group-item {\n border-top-width: $list-group-border-width;\n border-left-width: 0;\n\n &.active {\n margin-left: -$list-group-border-width;\n border-left-width: $list-group-border-width;\n }\n }\n }\n }\n }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n @include border-radius(0);\n\n > .list-group-item {\n border-width: 0 0 $list-group-border-width;\n\n &:last-child {\n border-bottom-width: 0;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $color, $value in $theme-colors {\n @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));\n}\n","// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n .list-group-item-#{$state} {\n color: $color;\n background-color: $background;\n\n &.list-group-item-action {\n @include hover-focus() {\n color: $color;\n background-color: darken($background, 5%);\n }\n\n &.active {\n color: $white;\n background-color: $color;\n border-color: $color;\n }\n }\n }\n}\n",".close {\n float: right;\n @include font-size($close-font-size);\n font-weight: $close-font-weight;\n line-height: 1;\n color: $close-color;\n text-shadow: $close-text-shadow;\n opacity: .5;\n\n // Override <a>'s hover style\n @include hover() {\n color: $close-color;\n text-decoration: none;\n }\n\n &:not(:disabled):not(.disabled) {\n @include hover-focus() {\n opacity: .75;\n }\n }\n}\n\n// Additional properties for button version\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n// stylelint-disable-next-line selector-no-qualifying-type\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\n// Future-proof disabling of clicks on `<a>` elements\n\n// stylelint-disable-next-line selector-no-qualifying-type\na.close.disabled {\n pointer-events: none;\n}\n",".toast {\n // Prevents from shrinking in IE11, when in a flex container\n // See https://github.com/twbs/bootstrap/issues/28341\n flex-basis: $toast-max-width;\n max-width: $toast-max-width;\n @include font-size($toast-font-size);\n color: $toast-color;\n background-color: $toast-background-color;\n background-clip: padding-box;\n border: $toast-border-width solid $toast-border-color;\n box-shadow: $toast-box-shadow;\n opacity: 0;\n @include border-radius($toast-border-radius);\n\n &:not(:last-child) {\n margin-bottom: $toast-padding-x;\n }\n\n &.showing {\n opacity: 1;\n }\n\n &.show {\n display: block;\n opacity: 1;\n }\n\n &.hide {\n display: none;\n }\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: $toast-padding-y $toast-padding-x;\n color: $toast-header-color;\n background-color: $toast-header-background-color;\n background-clip: padding-box;\n border-bottom: $toast-border-width solid $toast-header-border-color;\n @include border-top-radius(subtract($toast-border-radius, $toast-border-width));\n}\n\n.toast-body {\n padding: $toast-padding-x; // apply to both vertical and horizontal\n}\n","// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and stuff\n\n\n.modal-open {\n // Kill the scroll on the body\n overflow: hidden;\n\n .modal {\n overflow-x: hidden;\n overflow-y: auto;\n }\n}\n\n// Container that the modal scrolls within\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: $modal-dialog-margin;\n // allow clicks to pass through for custom click handling to close modal\n pointer-events: none;\n\n // When fading in the modal, animate it to slide down\n .modal.fade & {\n @include transition($modal-transition);\n transform: $modal-fade-transform;\n }\n .modal.show & {\n transform: $modal-show-transform;\n }\n\n // When trying to close, animate focus to scale\n .modal.modal-static & {\n transform: $modal-scale-transform;\n }\n}\n\n.modal-dialog-scrollable {\n display: flex; // IE10/11\n max-height: subtract(100%, $modal-dialog-margin * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11\n overflow: hidden;\n }\n\n .modal-header,\n .modal-footer {\n flex-shrink: 0;\n }\n\n .modal-body {\n overflow-y: auto;\n }\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: subtract(100%, $modal-dialog-margin * 2);\n\n // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)\n &::before {\n display: block; // IE10\n height: subtract(100vh, $modal-dialog-margin * 2);\n height: min-content; // Reset height to 0 except on IE\n content: \"\";\n }\n\n // Ensure `.modal-body` shows scrollbar (IE10/11)\n &.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n\n .modal-content {\n max-height: none;\n }\n\n &::before {\n content: none;\n }\n }\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n // counteract the pointer-events: none; in the .modal-dialog\n color: $modal-content-color;\n pointer-events: auto;\n background-color: $modal-content-bg;\n background-clip: padding-box;\n border: $modal-content-border-width solid $modal-content-border-color;\n @include border-radius($modal-content-border-radius);\n @include box-shadow($modal-content-box-shadow-xs);\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal-backdrop;\n width: 100vw;\n height: 100vh;\n background-color: $modal-backdrop-bg;\n\n // Fade for backdrop\n &.fade { opacity: 0; }\n &.show { opacity: $modal-backdrop-opacity; }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n display: flex;\n align-items: flex-start; // so the close btn always stays on the upper right corner\n justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n padding: $modal-header-padding;\n border-bottom: $modal-header-border-width solid $modal-header-border-color;\n @include border-top-radius($modal-content-inner-border-radius);\n\n .close {\n padding: $modal-header-padding;\n // auto on the left force icon to the right even when there is no .modal-title\n margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;\n }\n}\n\n// Title text within header\n.modal-title {\n margin-bottom: 0;\n line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n // Enable `flex-grow: 1` so that the body take up as much space as possible\n // when there should be a fixed height on `.modal-dialog`.\n flex: 1 1 auto;\n padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center; // vertically center\n justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n padding: $modal-inner-padding - $modal-footer-margin-between / 2;\n border-top: $modal-footer-border-width solid $modal-footer-border-color;\n @include border-bottom-radius($modal-content-inner-border-radius);\n\n // Place margin between footer elements\n // This solution is far from ideal because of the universal selector usage,\n // but is needed to fix https://github.com/twbs/bootstrap/issues/24800\n > * {\n margin: $modal-footer-margin-between / 2;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n max-width: $modal-md;\n margin: $modal-dialog-margin-y-sm-up auto;\n }\n\n .modal-dialog-scrollable {\n max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n }\n }\n\n .modal-dialog-centered {\n min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n &::before {\n height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n height: min-content;\n }\n }\n\n .modal-content {\n @include box-shadow($modal-content-box-shadow-sm-up);\n }\n\n .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n .modal-lg,\n .modal-xl {\n max-width: $modal-lg;\n }\n}\n\n@include media-breakpoint-up(xl) {\n .modal-xl { max-width: $modal-xl; }\n}\n","// Base class\n.tooltip {\n position: absolute;\n z-index: $zindex-tooltip;\n display: block;\n margin: $tooltip-margin;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($tooltip-font-size);\n // Allow breaking very long words so they don't overflow the tooltip's bounds\n word-wrap: break-word;\n opacity: 0;\n\n &.show { opacity: $tooltip-opacity; }\n\n .arrow {\n position: absolute;\n display: block;\n width: $tooltip-arrow-width;\n height: $tooltip-arrow-height;\n\n &::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-tooltip-top {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n bottom: 0;\n\n &::before {\n top: 0;\n border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-top-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-right {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n left: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n right: 0;\n border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-right-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-bottom {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n top: 0;\n\n &::before {\n bottom: 0;\n border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-bottom-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-left {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n right: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n left: 0;\n border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-left-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-tooltip-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-tooltip-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-tooltip-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-tooltip-left;\n }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: $tooltip-max-width;\n padding: $tooltip-padding-y $tooltip-padding-x;\n color: $tooltip-color;\n text-align: center;\n background-color: $tooltip-bg;\n @include border-radius($tooltip-border-radius);\n}\n","@mixin reset-text() {\n font-family: $font-family-base;\n // We deliberately do NOT reset font-size or word-wrap.\n font-style: normal;\n font-weight: $font-weight-normal;\n line-height: $line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n}\n",".popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: $zindex-popover;\n display: block;\n max-width: $popover-max-width;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($popover-font-size);\n // Allow breaking very long words so they don't overflow the popover's bounds\n word-wrap: break-word;\n background-color: $popover-bg;\n background-clip: padding-box;\n border: $popover-border-width solid $popover-border-color;\n @include border-radius($popover-border-radius);\n @include box-shadow($popover-box-shadow);\n\n .arrow {\n position: absolute;\n display: block;\n width: $popover-arrow-width;\n height: $popover-arrow-height;\n margin: 0 $popover-border-radius;\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-popover-top {\n margin-bottom: $popover-arrow-height;\n\n > .arrow {\n bottom: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n bottom: 0;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-outer-color;\n }\n\n &::after {\n bottom: $popover-border-width;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-right {\n margin-left: $popover-arrow-height;\n\n > .arrow {\n left: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n left: 0;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-outer-color;\n }\n\n &::after {\n left: $popover-border-width;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-bottom {\n margin-top: $popover-arrow-height;\n\n > .arrow {\n top: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n top: 0;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-outer-color;\n }\n\n &::after {\n top: $popover-border-width;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-color;\n }\n }\n\n // This will remove the popover-header's border just below the arrow\n .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: $popover-arrow-width;\n margin-left: -$popover-arrow-width / 2;\n content: \"\";\n border-bottom: $popover-border-width solid $popover-header-bg;\n }\n}\n\n.bs-popover-left {\n margin-right: $popover-arrow-height;\n\n > .arrow {\n right: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n right: 0;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-outer-color;\n }\n\n &::after {\n right: $popover-border-width;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-popover-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-popover-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-popover-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-popover-left;\n }\n}\n\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n padding: $popover-header-padding-y $popover-header-padding-x;\n margin-bottom: 0; // Reset the default from Reboot\n @include font-size($font-size-base);\n color: $popover-header-color;\n background-color: $popover-header-bg;\n border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);\n @include border-top-radius($popover-inner-border-radius);\n\n &:empty {\n display: none;\n }\n}\n\n.popover-body {\n padding: $popover-body-padding-y $popover-body-padding-x;\n color: $popover-body-color;\n}\n","// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n// even when their scroll action started on a carousel, but for compatibility (with Firefox)\n// we're preventing all actions instead\n// 2. The .carousel-item-left and .carousel-item-right is used to indicate where\n// the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-left and .active.carousel-item-right is the current\n// slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right\n// is the upcoming slide in transition.\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n @include clearfix();\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n }\n\n .carousel-item.active,\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n }\n\n .active.carousel-item-left,\n .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n @include transition(opacity 0s $carousel-transition-duration);\n }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n // Use flex for alignment (1-3)\n display: flex; // 1. allow flex styles\n align-items: center; // 2. vertically center contents\n justify-content: center; // 3. horizontally center contents\n width: $carousel-control-width;\n color: $carousel-control-color;\n text-align: center;\n opacity: $carousel-control-opacity;\n @include transition($carousel-control-transition);\n\n // Hover/focus state\n @include hover-focus() {\n color: $carousel-control-color;\n text-decoration: none;\n outline: 0;\n opacity: $carousel-control-hover-opacity;\n }\n}\n.carousel-control-prev {\n left: 0;\n @if $enable-gradients {\n background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));\n }\n}\n.carousel-control-next {\n right: 0;\n @if $enable-gradients {\n background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));\n }\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: $carousel-control-icon-width;\n height: $carousel-control-icon-width;\n background: 50% / 100% 100% no-repeat;\n}\n.carousel-control-prev-icon {\n background-image: escape-svg($carousel-control-prev-icon-bg);\n}\n.carousel-control-next-icon {\n background-image: escape-svg($carousel-control-next-icon-bg);\n}\n\n\n// Optional indicator pips\n//\n// Add an ordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0; // override <ol> default\n // Use the .carousel-control's width as margin so we don't overlay those\n margin-right: $carousel-control-width;\n margin-left: $carousel-control-width;\n list-style: none;\n\n li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: $carousel-indicator-width;\n height: $carousel-indicator-height;\n margin-right: $carousel-indicator-spacer;\n margin-left: $carousel-indicator-spacer;\n text-indent: -999px;\n cursor: pointer;\n background-color: $carousel-indicator-active-bg;\n background-clip: padding-box;\n // Use transparent borders to increase the hit area by 10px on top and bottom.\n border-top: $carousel-indicator-hit-area-height solid transparent;\n border-bottom: $carousel-indicator-hit-area-height solid transparent;\n opacity: .5;\n @include transition($carousel-indicator-transition);\n }\n\n .active {\n opacity: 1;\n }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n position: absolute;\n right: (100% - $carousel-caption-width) / 2;\n bottom: 20px;\n left: (100% - $carousel-caption-width) / 2;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: $carousel-caption-color;\n text-align: center;\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","//\n// Rotating border\n//\n\n@keyframes spinner-border {\n to { transform: rotate(360deg); }\n}\n\n.spinner-border {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n border: $spinner-border-width solid currentColor;\n border-right-color: transparent;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n animation: .75s linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n background-color: currentColor;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n opacity: 0;\n animation: .75s linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n}\n\n@if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n .spinner-border,\n .spinner-grow {\n animation-duration: 1.5s;\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n.align-baseline { vertical-align: baseline !important; } // Browser default\n.align-top { vertical-align: top !important; }\n.align-middle { vertical-align: middle !important; }\n.align-bottom { vertical-align: bottom !important; }\n.align-text-bottom { vertical-align: text-bottom !important; }\n.align-text-top { vertical-align: text-top !important; }\n","// stylelint-disable declaration-no-important\n\n// Contextual backgrounds\n\n@mixin bg-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background-color: $color !important;\n }\n a#{$parent},\n button#{$parent} {\n @include hover-focus() {\n background-color: darken($color, 10%) !important;\n }\n }\n @include deprecate(\"The `bg-variant` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n@mixin bg-gradient-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;\n }\n @include deprecate(\"The `bg-gradient-variant` mixin\", \"v4.5.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n@each $color, $value in $theme-colors {\n @include bg-variant(\".bg-#{$color}\", $value, true);\n}\n\n@if $enable-gradients {\n @each $color, $value in $theme-colors {\n @include bg-gradient-variant(\".bg-gradient-#{$color}\", $value, true);\n }\n}\n\n.bg-white {\n background-color: $white !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n","// stylelint-disable property-disallowed-list, declaration-no-important\n\n//\n// Border\n//\n\n.border { border: $border-width solid $border-color !important; }\n.border-top { border-top: $border-width solid $border-color !important; }\n.border-right { border-right: $border-width solid $border-color !important; }\n.border-bottom { border-bottom: $border-width solid $border-color !important; }\n.border-left { border-left: $border-width solid $border-color !important; }\n\n.border-0 { border: 0 !important; }\n.border-top-0 { border-top: 0 !important; }\n.border-right-0 { border-right: 0 !important; }\n.border-bottom-0 { border-bottom: 0 !important; }\n.border-left-0 { border-left: 0 !important; }\n\n@each $color, $value in $theme-colors {\n .border-#{$color} {\n border-color: $value !important;\n }\n}\n\n.border-white {\n border-color: $white !important;\n}\n\n//\n// Border-radius\n//\n\n.rounded-sm {\n border-radius: $border-radius-sm !important;\n}\n\n.rounded {\n border-radius: $border-radius !important;\n}\n\n.rounded-top {\n border-top-left-radius: $border-radius !important;\n border-top-right-radius: $border-radius !important;\n}\n\n.rounded-right {\n border-top-right-radius: $border-radius !important;\n border-bottom-right-radius: $border-radius !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-left {\n border-top-left-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-lg {\n border-radius: $border-radius-lg !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: $rounded-pill !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n\n &::before {\n display: block;\n content: \"\";\n }\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n }\n}\n\n@each $embed-responsive-aspect-ratio in $embed-responsive-aspect-ratios {\n $embed-responsive-aspect-ratio-x: nth($embed-responsive-aspect-ratio, 1);\n $embed-responsive-aspect-ratio-y: nth($embed-responsive-aspect-ratio, 2);\n\n .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} {\n &::before {\n padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x);\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .float#{$infix}-left { float: left !important; }\n .float#{$infix}-right { float: right !important; }\n .float#{$infix}-none { float: none !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $user-selects {\n .user-select-#{$value} { user-select: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $overflows {\n .overflow-#{$value} { overflow: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Common values\n@each $position in $positions {\n .position-#{$position} { position: $position !important; }\n}\n\n// Shorthand\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.sticky-top {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: $zindex-sticky;\n }\n}\n","//\n// Screenreaders\n//\n\n.sr-only {\n @include sr-only();\n}\n\n.sr-only-focusable {\n @include sr-only-focusable();\n}\n","// Only display content to screen readers\n//\n// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/\n// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin sr-only() {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px; // Fix for https://github.com/twbs/bootstrap/issues/25686\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable() {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n }\n}\n","// stylelint-disable declaration-no-important\n\n.shadow-sm { box-shadow: $box-shadow-sm !important; }\n.shadow { box-shadow: $box-shadow !important; }\n.shadow-lg { box-shadow: $box-shadow-lg !important; }\n.shadow-none { box-shadow: none !important; }\n","// stylelint-disable declaration-no-important\n\n// Width and height\n\n@each $prop, $abbrev in (width: w, height: h) {\n @each $size, $length in $sizes {\n .#{$abbrev}-#{$size} { #{$prop}: $length !important; }\n }\n}\n\n.mw-100 { max-width: 100% !important; }\n.mh-100 { max-height: 100% !important; }\n\n// Viewport additional helpers\n\n.min-vw-100 { min-width: 100vw !important; }\n.min-vh-100 { min-height: 100vh !important; }\n\n.vw-100 { width: 100vw !important; }\n.vh-100 { height: 100vh !important; }\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n","//\n// Stretched link\n//\n\n.stretched-link {\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n // Just in case `pointer-events: none` is set on a parent\n pointer-events: auto;\n content: \"\";\n // IE10 bugfix, see https://stackoverflow.com/questions/16947967/ie10-hover-pseudo-class-doesnt-work-without-background-color\n background-color: rgba(0, 0, 0, 0);\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Text\n//\n\n.text-monospace { font-family: $font-family-monospace !important; }\n\n// Alignment\n\n.text-justify { text-align: justify !important; }\n.text-wrap { white-space: normal !important; }\n.text-nowrap { white-space: nowrap !important; }\n.text-truncate { @include text-truncate(); }\n\n// Responsive alignment\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .text#{$infix}-left { text-align: left !important; }\n .text#{$infix}-right { text-align: right !important; }\n .text#{$infix}-center { text-align: center !important; }\n }\n}\n\n// Transformation\n\n.text-lowercase { text-transform: lowercase !important; }\n.text-uppercase { text-transform: uppercase !important; }\n.text-capitalize { text-transform: capitalize !important; }\n\n// Weight and italics\n\n.font-weight-light { font-weight: $font-weight-light !important; }\n.font-weight-lighter { font-weight: $font-weight-lighter !important; }\n.font-weight-normal { font-weight: $font-weight-normal !important; }\n.font-weight-bold { font-weight: $font-weight-bold !important; }\n.font-weight-bolder { font-weight: $font-weight-bolder !important; }\n.font-italic { font-style: italic !important; }\n\n// Contextual colors\n\n.text-white { color: $white !important; }\n\n@each $color, $value in $theme-colors {\n @include text-emphasis-variant(\".text-#{$color}\", $value, true);\n}\n\n.text-body { color: $body-color !important; }\n.text-muted { color: $text-muted !important; }\n\n.text-black-50 { color: rgba($black, .5) !important; }\n.text-white-50 { color: rgba($white, .5) !important; }\n\n// Misc\n\n.text-hide {\n @include text-hide($ignore-warning: true);\n}\n\n.text-decoration-none { text-decoration: none !important; }\n\n.text-break {\n word-break: break-word !important; // Deprecated, but avoids issues with flex containers\n word-wrap: break-word !important; // Used instead of `overflow-wrap` for IE & Edge Legacy\n}\n\n// Reset\n\n.text-reset { color: inherit !important; }\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// stylelint-disable declaration-no-important\n\n// Typography\n\n@mixin text-emphasis-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n color: $color !important;\n }\n @if $emphasized-link-hover-darken-percentage != 0 {\n a#{$parent} {\n @include hover-focus() {\n color: darken($color, $emphasized-link-hover-darken-percentage) !important;\n }\n }\n }\n @include deprecate(\"`text-emphasis-variant()`\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// CSS image replacement\n@mixin text-hide($ignore-warning: false) {\n // stylelint-disable-next-line font-family-no-missing-generic-family-keyword\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n\n @include deprecate(\"`text-hide()`\", \"v4.1.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Visibility utilities\n//\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n// Source: https://github.com/h5bp/main.css/blob/master/src/_print.css\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request:\n// https://www.phpied.com/delay-loading-your-print-css/\n// ==========================================================================\n\n@if $enable-print-styles {\n @media print {\n *,\n *::before,\n *::after {\n // Bootstrap specific; comment out `color` and `background`\n //color: $black !important; // Black prints faster\n text-shadow: none !important;\n //background: transparent !important;\n box-shadow: none !important;\n }\n\n a {\n &:not(.btn) {\n text-decoration: underline;\n }\n }\n\n // Bootstrap specific; comment the following selector out\n //a[href]::after {\n // content: \" (\" attr(href) \")\";\n //}\n\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n // Bootstrap specific; comment the following selector out\n //\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n //\n\n //a[href^=\"#\"]::after,\n //a[href^=\"javascript:\"]::after {\n // content: \"\";\n //}\n\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px\n page-break-inside: avoid;\n }\n\n //\n // Printing Tables:\n // https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables\n //\n\n thead {\n display: table-header-group;\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Specify a size and min-width to make printing closer across browsers.\n // We don't set margin here because it breaks `size` in Chrome. We also\n // don't use `!important` on `size` as it breaks in Chrome.\n @page {\n size: $print-page-size;\n }\n body {\n min-width: $print-body-min-width !important;\n }\n .container {\n min-width: $print-body-min-width !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .badge {\n border: $border-width solid $black;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: $white !important;\n }\n }\n\n .table-bordered {\n th,\n td {\n border: 1px solid $gray-300 !important;\n }\n }\n\n .table-dark {\n color: inherit;\n\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $table-border-color;\n }\n }\n\n .table .thead-dark th {\n color: inherit;\n border-color: $table-border-color;\n }\n\n // Bootstrap specific changes end\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap.min.css b/vendor/twbs/bootstrap/dist/css/bootstrap.min.css index 286cde4c0..ef399d21c 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap.min.css +++ b/vendor/twbs/bootstrap/dist/css/bootstrap.min.css @@ -1,7 +1,7 @@ /*! - * Bootstrap v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} /*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/css/bootstrap.min.css.map b/vendor/twbs/bootstrap/dist/css/bootstrap.min.css.map index 30a397279..78a0c1230 100644 --- a/vendor/twbs/bootstrap/dist/css/bootstrap.min.css.map +++ b/vendor/twbs/bootstrap/dist/css/bootstrap.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","bootstrap.css","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/utilities/_interactions.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_stretched-link.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"code\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"input-group\";\n@import \"custom-forms\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"jumbotron\";\n@import \"alert\";\n@import \"progress\";\n@import \"media\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"utilities\";\n@import \"print\";\n","// Do not forget to update getting-started/theming.md!\n:root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n -webkit-text-decoration-skip-ink: none;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-wrap: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n color: #212529;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n color: #212529;\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #343a40;\n border-color: #454d55;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #454d55;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::-webkit-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-moz-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\ninput[type=\"date\"].form-control,\ninput[type=\"time\"].form-control,\ninput[type=\"datetime-local\"].form-control,\ninput[type=\"month\"].form-control {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: 0.375rem 0;\n margin-bottom: 0;\n font-size: 1rem;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(1.5em + 1rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input[disabled] ~ .form-check-label,\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: -ms-inline-flexbox;\n display: inline-flex;\n -ms-flex-align: center;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -ms-flex-align: center;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n -ms-flex-negative: 0;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n text-decoration: none;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: -ms-inline-flexbox;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: stretch;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 1%;\n min-width: 0;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: -ms-flexbox;\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(1.5em + 1rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.5em + 0.5rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n -webkit-print-color-adjust: exact;\n color-adjust: exact;\n}\n\n.custom-control-inline {\n display: -ms-inline-flexbox;\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1;\n width: 1rem;\n height: 1.25rem;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background: no-repeat 50% / 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n -webkit-transform: translateX(0.75rem);\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n display: none;\n}\n\n.custom-select:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.custom-select-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(1.5em + 1rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input[disabled] ~ .custom-file-label,\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(1.5em + 0.75rem);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: 1.4rem;\n padding: 0;\n background-color: transparent;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: none;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -webkit-appearance: none;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n -webkit-transition: none;\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -moz-appearance: none;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n -moz-transition: none;\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n -ms-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n -ms-transition: none;\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar .container,\n.navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: justify;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n -ms-flex-preferred-size: 100%;\n flex-basis: 100%;\n -ms-flex-positive: 1;\n flex-grow: 1;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n}\n\n.card > .list-group:first-child {\n border-top-width: 0;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card > .list-group:last-child {\n border-bottom-width: 0;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n border-top: 0;\n}\n\n.card-body {\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n min-height: 1px;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n -ms-flex-negative: 0;\n flex-shrink: 0;\n width: 100%;\n}\n\n.card-img,\n.card-img-top {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n }\n .card-group > .card {\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n -webkit-column-count: 3;\n -moz-column-count: 3;\n column-count: 3;\n -webkit-column-gap: 1.25rem;\n -moz-column-gap: 1.25rem;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion {\n overflow-anchor: none;\n}\n\n.accordion > .card {\n overflow: hidden;\n}\n\n.accordion > .card:not(:last-of-type) {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion > .card:not(:first-of-type) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion > .card > .card-header {\n border-radius: 0;\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item {\n display: -ms-flexbox;\n display: flex;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: -ms-flexbox;\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 3;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 3;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .badge {\n transition: none;\n }\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\na.badge-primary:focus, a.badge-primary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\na.badge-secondary:focus, a.badge-secondary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\na.badge-success:focus, a.badge-success.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\na.badge-info:focus, a.badge-info.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\na.badge-warning:focus, a.badge-warning.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\na.badge-danger:focus, a.badge-danger.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\na.badge-light:focus, a.badge-light.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\na.badge-dark:focus, a.badge-dark.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: -ms-flexbox;\n display: flex;\n height: 1rem;\n overflow: hidden;\n line-height: 0;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: center;\n justify-content: center;\n overflow: hidden;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n -webkit-animation: progress-bar-stripes 1s linear infinite;\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n -webkit-animation: none;\n animation: none;\n }\n}\n\n.media {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n.media-body {\n -ms-flex: 1;\n flex: 1;\n}\n\n.list-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n border-radius: 0.25rem;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n\n.list-group-item:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-item + .list-group-item {\n border-top-width: 0;\n}\n\n.list-group-item + .list-group-item.active {\n margin-top: -1px;\n border-top-width: 1px;\n}\n\n.list-group-horizontal {\n -ms-flex-direction: row;\n flex-direction: row;\n}\n\n.list-group-horizontal > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item.active {\n margin-top: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-sm > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-md > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-lg > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-xl > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n.list-group-flush {\n border-radius: 0;\n}\n\n.list-group-flush > .list-group-item {\n border-width: 0 0 1px;\n}\n\n.list-group-flush > .list-group-item:last-child {\n border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n -ms-flex-preferred-size: 350px;\n flex-basis: 350px;\n max-width: 350px;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n opacity: 0;\n border-radius: 0.25rem;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: -webkit-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;\n -webkit-transform: translate(0, -50px);\n transform: translate(0, -50px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n -webkit-transform: none;\n transform: none;\n}\n\n.modal.modal-static .modal-dialog {\n -webkit-transform: scale(1.02);\n transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n display: -ms-flexbox;\n display: flex;\n max-height: calc(100% - 1rem);\n}\n\n.modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 1rem);\n overflow: hidden;\n}\n\n.modal-dialog-scrollable .modal-header,\n.modal-dialog-scrollable .modal-footer {\n -ms-flex-negative: 0;\n flex-shrink: 0;\n}\n\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n min-height: calc(100% - 1rem);\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - 1rem);\n height: -webkit-min-content;\n height: -moz-min-content;\n height: min-content;\n content: \"\";\n}\n\n.modal-dialog-centered.modal-dialog-scrollable {\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: center;\n justify-content: center;\n height: 100%;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable .modal-content {\n max-height: none;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable::before {\n content: none;\n}\n\n.modal-content {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #dee2e6;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: end;\n justify-content: flex-end;\n padding: 0.75rem;\n border-top: 1px solid #dee2e6;\n border-bottom-right-radius: calc(0.3rem - 1px);\n border-bottom-left-radius: calc(0.3rem - 1px);\n}\n\n.modal-footer > * {\n margin: 0.25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-scrollable {\n max-height: calc(100% - 3.5rem);\n }\n .modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 3.5rem);\n }\n .modal-dialog-centered {\n min-height: calc(100% - 3.5rem);\n }\n .modal-dialog-centered::before {\n height: calc(100vh - 3.5rem);\n height: -webkit-min-content;\n height: -moz-min-content;\n height: min-content;\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=\"top\"] > .arrow {\n bottom: calc(-0.5rem - 1px);\n}\n\n.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=\"top\"] > .arrow::before {\n bottom: 0;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=\"top\"] > .arrow::after {\n bottom: 1px;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=\"right\"] > .arrow {\n left: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=\"right\"] > .arrow::before {\n left: 0;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=\"right\"] > .arrow::after {\n left: 1px;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow {\n top: calc(-0.5rem - 1px);\n}\n\n.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::before {\n top: 0;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::after {\n top: 1px;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=\"left\"] > .arrow {\n right: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=\"left\"] > .arrow::before {\n right: 0;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=\"left\"] > .arrow::after {\n right: 1px;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n -ms-touch-action: pan-y;\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n transition: -webkit-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n -webkit-transform: translateX(100%);\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n -webkit-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n -webkit-transform: none;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: opacity 0s 0.6s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: no-repeat 50% / 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-pack: center;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n -ms-flex: 0 1 auto;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@-webkit-keyframes spinner-border {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes spinner-border {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n -webkit-animation: spinner-border .75s linear infinite;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@-webkit-keyframes spinner-grow {\n 0% {\n -webkit-transform: scale(0);\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n -webkit-transform: none;\n transform: none;\n }\n}\n\n@keyframes spinner-grow {\n 0% {\n -webkit-transform: scale(0);\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n -webkit-transform: none;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n -webkit-animation: spinner-grow .75s linear infinite;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded-sm {\n border-radius: 0.2rem !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-lg {\n border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.user-select-all {\n -webkit-user-select: all !important;\n -moz-user-select: all !important;\n -ms-user-select: all !important;\n user-select: all !important;\n}\n\n.user-select-auto {\n -webkit-user-select: auto !important;\n -moz-user-select: auto !important;\n -ms-user-select: auto !important;\n user-select: auto !important;\n}\n\n.user-select-none {\n -webkit-user-select: none !important;\n -moz-user-select: none !important;\n -ms-user-select: none !important;\n user-select: none !important;\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: -webkit-sticky !important;\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .sticky-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n pointer-events: auto;\n content: \"\";\n background-color: rgba(0, 0, 0, 0);\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !important;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-break {\n word-break: break-word !important;\n word-wrap: break-word !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","/*!\n * Bootstrap v4.5.3 (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-wrap: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n color: #212529;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n color: #212529;\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #343a40;\n border-color: #454d55;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #454d55;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\ninput[type=\"date\"].form-control,\ninput[type=\"time\"].form-control,\ninput[type=\"datetime-local\"].form-control,\ninput[type=\"month\"].form-control {\n appearance: none;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: 0.375rem 0;\n margin-bottom: 0;\n font-size: 1rem;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(1.5em + 1rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input[disabled] ~ .form-check-label,\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n text-decoration: none;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n min-width: 0;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(1.5em + 1rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.5em + 0.5rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n color-adjust: exact;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1;\n width: 1rem;\n height: 1.25rem;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background: no-repeat 50% / 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n display: none;\n}\n\n.custom-select:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.custom-select-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(1.5em + 1rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input[disabled] ~ .custom-file-label,\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(1.5em + 0.75rem);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: 1.4rem;\n padding: 0;\n background-color: transparent;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: none;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar .container,\n.navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n}\n\n.card > .list-group:first-child {\n border-top-width: 0;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card > .list-group:last-child {\n border-bottom-width: 0;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n border-top: 0;\n}\n\n.card-body {\n flex: 1 1 auto;\n min-height: 1px;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0;\n width: 100%;\n}\n\n.card-img,\n.card-img-top {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n display: flex;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n flex: 1 0 0%;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n display: flex;\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion {\n overflow-anchor: none;\n}\n\n.accordion > .card {\n overflow: hidden;\n}\n\n.accordion > .card:not(:last-of-type) {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion > .card:not(:first-of-type) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion > .card > .card-header {\n border-radius: 0;\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item {\n display: flex;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 3;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 3;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .badge {\n transition: none;\n }\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\na.badge-primary:focus, a.badge-primary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\na.badge-secondary:focus, a.badge-secondary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\na.badge-success:focus, a.badge-success.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\na.badge-info:focus, a.badge-info.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\na.badge-warning:focus, a.badge-warning.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\na.badge-danger:focus, a.badge-danger.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\na.badge-light:focus, a.badge-light.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\na.badge-dark:focus, a.badge-dark.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n line-height: 0;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n animation: none;\n }\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n border-radius: 0.25rem;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n\n.list-group-item:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-item + .list-group-item {\n border-top-width: 0;\n}\n\n.list-group-item + .list-group-item.active {\n margin-top: -1px;\n border-top-width: 1px;\n}\n\n.list-group-horizontal {\n flex-direction: row;\n}\n\n.list-group-horizontal > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item.active {\n margin-top: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n flex-direction: row;\n }\n .list-group-horizontal-sm > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n flex-direction: row;\n }\n .list-group-horizontal-md > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n flex-direction: row;\n }\n .list-group-horizontal-lg > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n flex-direction: row;\n }\n .list-group-horizontal-xl > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n.list-group-flush {\n border-radius: 0;\n}\n\n.list-group-flush > .list-group-item {\n border-width: 0 0 1px;\n}\n\n.list-group-flush > .list-group-item:last-child {\n border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n flex-basis: 350px;\n max-width: 350px;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n opacity: 0;\n border-radius: 0.25rem;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -50px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n transform: none;\n}\n\n.modal.modal-static .modal-dialog {\n transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n display: flex;\n max-height: calc(100% - 1rem);\n}\n\n.modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 1rem);\n overflow: hidden;\n}\n\n.modal-dialog-scrollable .modal-header,\n.modal-dialog-scrollable .modal-footer {\n flex-shrink: 0;\n}\n\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - 1rem);\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - 1rem);\n height: min-content;\n content: \"\";\n}\n\n.modal-dialog-centered.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable .modal-content {\n max-height: none;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable::before {\n content: none;\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #dee2e6;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n padding: 0.75rem;\n border-top: 1px solid #dee2e6;\n border-bottom-right-radius: calc(0.3rem - 1px);\n border-bottom-left-radius: calc(0.3rem - 1px);\n}\n\n.modal-footer > * {\n margin: 0.25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-scrollable {\n max-height: calc(100% - 3.5rem);\n }\n .modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 3.5rem);\n }\n .modal-dialog-centered {\n min-height: calc(100% - 3.5rem);\n }\n .modal-dialog-centered::before {\n height: calc(100vh - 3.5rem);\n height: min-content;\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=\"top\"] > .arrow {\n bottom: calc(-0.5rem - 1px);\n}\n\n.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=\"top\"] > .arrow::before {\n bottom: 0;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=\"top\"] > .arrow::after {\n bottom: 1px;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=\"right\"] > .arrow {\n left: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=\"right\"] > .arrow::before {\n left: 0;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=\"right\"] > .arrow::after {\n left: 1px;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow {\n top: calc(-0.5rem - 1px);\n}\n\n.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::before {\n top: 0;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::after {\n top: 1px;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=\"left\"] > .arrow {\n right: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=\"left\"] > .arrow::before {\n right: 0;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=\"left\"] > .arrow::after {\n right: 1px;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n transition: transform 0.6s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: opacity 0s 0.6s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: no-repeat 50% / 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@keyframes spinner-border {\n to {\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded-sm {\n border-radius: 0.2rem !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-lg {\n border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.user-select-all {\n user-select: all !important;\n}\n\n.user-select-auto {\n user-select: auto !important;\n}\n\n.user-select-none {\n user-select: none !important;\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n pointer-events: auto;\n content: \"\";\n background-color: rgba(0, 0, 0, 0);\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !important;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-break {\n word-break: break-word !important;\n word-wrap: break-word !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable declaration-no-important, selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { @include font-size($h1-font-size); }\nh2, .h2 { @include font-size($h2-font-size); }\nh3, .h3 { @include font-size($h3-font-size); }\nh4, .h4 { @include font-size($h4-font-size); }\nh5, .h5 { @include font-size($h5-font-size); }\nh6, .h6 { @include font-size($h6-font-size); }\n\n.lead {\n @include font-size($lead-font-size);\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n @include font-size($display1-size);\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n @include font-size($display2-size);\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n @include font-size($display3-size);\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n @include font-size($display4-size);\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n @include font-size($small-font-size);\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled();\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled();\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n @include font-size(90%);\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n @include font-size($blockquote-font-size);\n}\n\n.blockquote-footer {\n display: block;\n @include font-size($blockquote-small-font-size);\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014\\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled() {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid();\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid();\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: $spacer / 2;\n line-height: 1;\n}\n\n.figure-caption {\n @include font-size($figure-caption-font-size);\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid() {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/#feat=css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n @include deprecate(\"`img-retina()`\", \"v4.3.0\", \"v5\");\n}\n","// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n $return: ();\n @each $value in $radius {\n @if type-of($value) == number {\n $return: append($return, max($value, 0));\n } @else {\n $return: append($return, $value);\n }\n }\n @return $return;\n}\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: valid-radius($radius);\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n","// Inline code\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n @include font-size(100%);\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n margin-bottom: $spacer;\n color: $table-color;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: 2 * $table-border-width;\n }\n }\n}\n\n.table-borderless {\n th,\n td,\n thead th,\n tbody + tbody {\n border: 0;\n }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover() {\n color: $table-hover-color;\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover() {\n color: $table-dark-hover-color;\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background, $border: null) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n\n @if $border != null {\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $border;\n }\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover() {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n height: $input-height;\n padding: $input-padding-y $input-padding-x;\n font-family: $input-font-family;\n @include font-size($input-font-size);\n font-weight: $input-font-weight;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n @include border-radius($input-border-radius, 0);\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n background-color: transparent;\n border: 0;\n }\n\n // Remove select outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $input-color;\n }\n\n // Customize the `:focus` state to imitate native WebKit styles.\n @include form-control-focus($ignore-warning: true);\n\n // Placeholder\n &::placeholder {\n color: $input-placeholder-color;\n // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n opacity: 1;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &:disabled,\n &[readonly] {\n background-color: $input-disabled-bg;\n // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n opacity: 1;\n }\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n &.form-control {\n appearance: none; // Fix appearance for date inputs in Safari\n }\n}\n\nselect.form-control {\n &:focus::-ms-value {\n // Suppress the nested default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: add($input-padding-y, $input-border-width);\n padding-bottom: add($input-padding-y, $input-border-width);\n margin-bottom: 0; // Override the `<label>/<legend>` default\n @include font-size(inherit); // Override the `<legend>` default\n line-height: $input-line-height;\n}\n\n.col-form-label-lg {\n padding-top: add($input-padding-y-lg, $input-border-width);\n padding-bottom: add($input-padding-y-lg, $input-border-width);\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n}\n\n.col-form-label-sm {\n padding-top: add($input-padding-y-sm, $input-border-width);\n padding-bottom: add($input-padding-y-sm, $input-border-width);\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n}\n\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: $input-padding-y 0;\n margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n @include font-size($input-font-size);\n line-height: $input-line-height;\n color: $input-plaintext-color;\n background-color: transparent;\n border: solid transparent;\n border-width: $input-border-width 0;\n\n &.form-control-sm,\n &.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n height: $input-height-sm;\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.form-control-lg {\n height: $input-height-lg;\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n// stylelint-disable-next-line no-duplicate-selectors\nselect.form-control {\n &[size],\n &[multiple] {\n height: auto;\n }\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: $form-group-margin-bottom;\n}\n\n.form-text {\n display: block;\n margin-top: $form-text-margin-top;\n}\n\n\n// Form grid\n//\n// Special replacement for our grid system's `.row` for tighter form layouts.\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$form-grid-gutter-width / 2;\n margin-left: -$form-grid-gutter-width / 2;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: $form-grid-gutter-width / 2;\n padding-left: $form-grid-gutter-width / 2;\n }\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.form-check {\n position: relative;\n display: block;\n padding-left: $form-check-input-gutter;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: $form-check-input-margin-y;\n margin-left: -$form-check-input-gutter;\n\n // Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .form-check-label,\n &:disabled ~ .form-check-label {\n color: $text-muted;\n }\n}\n\n.form-check-label {\n margin-bottom: 0; // Override default `<label>` bottom margin\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0; // Override base .form-check\n margin-right: $form-check-inline-margin-x;\n\n // Undo .form-check-input defaults and add some `margin-right`.\n .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: $form-check-inline-input-margin-x;\n margin-left: 0;\n }\n}\n\n\n// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server side validation.\n\n@each $state, $data in $form-validation-states {\n @include form-validation-state($state, map-get($data, color), map-get($data, icon));\n}\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)\n\n // Because we use flex, the initial sizing of checkboxes is collapsed and\n // doesn't occupy the full-width (which is what we want for xs grid tier),\n // so we force that here.\n .form-check {\n width: 100%;\n }\n\n // Kick in the inline\n @include media-breakpoint-up(sm) {\n label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n\n // Inline-block all the things for \"inline\"\n .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n\n // Allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-plaintext {\n display: inline-block;\n }\n\n .input-group,\n .custom-select {\n width: auto;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: $form-check-input-margin-x;\n margin-left: 0;\n }\n\n .custom-control {\n align-items: center;\n justify-content: center;\n }\n .custom-control-label {\n margin-bottom: 0;\n }\n }\n}\n","// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n @if length($transition) == 0 {\n $transition: $transition-base;\n }\n\n @if length($transition) > 1 {\n @each $value in $transition {\n @if $value == null or $value == none {\n @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n }\n }\n }\n\n @if $enable-transitions {\n @if nth($transition, 1) != null {\n transition: $transition;\n }\n\n @if $enable-prefers-reduced-motion-media-query and nth($transition, 1) != null and nth($transition, 1) != none {\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n }\n}\n","// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `$input-focus-border-color` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n@mixin form-control-focus($ignore-warning: false) {\n &:focus {\n color: $input-focus-color;\n background-color: $input-focus-bg;\n border-color: $input-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($input-box-shadow, $input-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $input-focus-box-shadow;\n }\n }\n @include deprecate(\"The `form-control-focus()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n// This mixin uses an `if()` technique to be compatible with Dart Sass\n// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details\n@mixin form-validation-state-selector($state) {\n @if ($state == \"valid\" or $state == \"invalid\") {\n .was-validated #{if(&, \"&\", \"\")}:#{$state},\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n } @else {\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n }\n}\n\n@mixin form-validation-state($state, $color, $icon) {\n .#{$state}-feedback {\n display: none;\n width: 100%;\n margin-top: $form-feedback-margin-top;\n @include font-size($form-feedback-font-size);\n color: $color;\n }\n\n .#{$state}-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%; // Contain to parent when possible\n padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n margin-top: .1rem;\n @include font-size($form-feedback-tooltip-font-size);\n line-height: $form-feedback-tooltip-line-height;\n color: color-yiq($color);\n background-color: rgba($color, $form-feedback-tooltip-opacity);\n @include border-radius($form-feedback-tooltip-border-radius);\n }\n\n @include form-validation-state-selector($state) {\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n\n .form-control {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-image: escape-svg($icon);\n background-repeat: no-repeat;\n background-position: right $input-height-inner-quarter center;\n background-size: $input-height-inner-half $input-height-inner-half;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n // stylelint-disable-next-line selector-no-qualifying-type\n textarea.form-control {\n @include form-validation-state-selector($state) {\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n }\n }\n }\n\n .custom-select {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $custom-select-feedback-icon-padding-right;\n background: $custom-select-background, escape-svg($icon) $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n .form-check-input {\n @include form-validation-state-selector($state) {\n ~ .form-check-label {\n color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .custom-control-input {\n @include form-validation-state-selector($state) {\n ~ .custom-control-label {\n color: $color;\n\n &::before {\n border-color: $color;\n }\n }\n\n &:checked {\n ~ .custom-control-label::before {\n border-color: lighten($color, 10%);\n @include gradient-bg(lighten($color, 10%));\n }\n }\n\n &:focus {\n ~ .custom-control-label::before {\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n &:not(:checked) ~ .custom-control-label::before {\n border-color: $color;\n }\n }\n }\n }\n\n // custom file\n .custom-file-input {\n @include form-validation-state-selector($state) {\n ~ .custom-file-label {\n border-color: $color;\n }\n\n &:focus {\n ~ .custom-file-label {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.btn {\n display: inline-block;\n font-family: $btn-font-family;\n font-weight: $btn-font-weight;\n color: $body-color;\n text-align: center;\n text-decoration: if($link-decoration == none, null, none);\n white-space: $btn-white-space;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: $btn-border-width solid transparent;\n @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);\n @include transition($btn-transition);\n\n @include hover() {\n color: $body-color;\n text-decoration: none;\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: $btn-focus-box-shadow;\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n opacity: $btn-disabled-opacity;\n @include box-shadow(none);\n }\n\n &:not(:disabled):not(.disabled) {\n cursor: if($enable-pointer-cursor-for-buttons, pointer, null);\n\n &:active,\n &.active {\n @include box-shadow($btn-active-box-shadow);\n\n &:focus {\n @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n }\n }\n }\n}\n\n// Future-proof disabling of clicks on `<a>` elements\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n\n//\n// Alternate buttons\n//\n\n@each $color, $value in $theme-colors {\n .btn-#{$color} {\n @include button-variant($value, $value);\n }\n}\n\n@each $color, $value in $theme-colors {\n .btn-outline-#{$color} {\n @include button-outline-variant($value);\n }\n}\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n font-weight: $font-weight-normal;\n color: $link-color;\n text-decoration: $link-decoration;\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n\n &:focus,\n &.focus {\n text-decoration: $link-hover-decoration;\n }\n\n &:disabled,\n &.disabled {\n color: $btn-link-disabled-color;\n pointer-events: none;\n }\n\n // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);\n}\n\n\n//\n// Block button\n//\n\n.btn-block {\n display: block;\n width: 100%;\n\n // Vertically space out multiple block buttons\n + .btn-block {\n margin-top: $btn-block-spacing-y;\n }\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {\n color: color-yiq($background);\n @include gradient-bg($background);\n border-color: $border;\n @include box-shadow($btn-box-shadow);\n\n @include hover() {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n }\n\n &:focus,\n &.focus {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n @if $enable-shadows {\n @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n color: color-yiq($background);\n background-color: $background;\n border-color: $border;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n @if $enable-gradients {\n background-image: none; // Remove the gradient for the pressed/active state\n }\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n }\n}\n\n@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {\n color: $color;\n border-color: $color;\n\n @include hover() {\n color: $color-hover;\n background-color: $active-background;\n border-color: $active-border;\n }\n\n &:focus,\n &.focus {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n\n &.disabled,\n &:disabled {\n color: $color;\n background-color: transparent;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n }\n }\n}\n\n// Button sizes\n@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n // Manually declare to provide an override to the browser default\n @include border-radius($border-radius, 0);\n}\n",".fade {\n @include transition($transition-fade);\n\n &:not(.show) {\n opacity: 0;\n }\n}\n\n.collapse {\n &:not(.show) {\n display: none;\n }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n @include transition($transition-collapse);\n}\n","// The dropdown wrapper (`<div>`)\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n\n // Generate the caret automatically\n @include caret();\n}\n\n// The dropdown menu\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: $zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: $dropdown-min-width;\n padding: $dropdown-padding-y $dropdown-padding-x;\n margin: $dropdown-spacer 0 0; // override default ul\n @include font-size($dropdown-font-size);\n color: $dropdown-color;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n list-style: none;\n background-color: $dropdown-bg;\n background-clip: padding-box;\n border: $dropdown-border-width solid $dropdown-border-color;\n @include border-radius($dropdown-border-radius);\n @include box-shadow($dropdown-box-shadow);\n}\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .dropdown-menu#{$infix}-left {\n right: auto;\n left: 0;\n }\n\n .dropdown-menu#{$infix}-right {\n right: 0;\n left: auto;\n }\n }\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(up);\n }\n}\n\n.dropright {\n .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(right);\n &::after {\n vertical-align: 0;\n }\n }\n}\n\n.dropleft {\n .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(left);\n &::before {\n vertical-align: 0;\n }\n }\n}\n\n// When enabled Popper.js, reset basic dropdown position\n// stylelint-disable-next-line no-duplicate-selectors\n.dropdown-menu {\n &[x-placement^=\"top\"],\n &[x-placement^=\"right\"],\n &[x-placement^=\"bottom\"],\n &[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n }\n}\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n @include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n display: block;\n width: 100%; // For `<button>`s\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n clear: both;\n font-weight: $font-weight-normal;\n color: $dropdown-link-color;\n text-align: inherit; // For `<button>`s\n text-decoration: if($link-decoration == none, null, none);\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n background-color: transparent; // For `<button>`s\n border: 0; // For `<button>`s\n\n // Prevent dropdown overflow if there's no padding\n // See https://github.com/twbs/bootstrap/pull/27703\n @if $dropdown-padding-y == 0 {\n &:first-child {\n @include border-top-radius($dropdown-inner-border-radius);\n }\n\n &:last-child {\n @include border-bottom-radius($dropdown-inner-border-radius);\n }\n }\n\n @include hover-focus() {\n color: $dropdown-link-hover-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-hover-bg);\n }\n\n &.active,\n &:active {\n color: $dropdown-link-active-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-active-bg);\n }\n\n &.disabled,\n &:disabled {\n color: $dropdown-link-disabled-color;\n pointer-events: none;\n background-color: transparent;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: $dropdown-header-padding;\n margin-bottom: 0; // for use with heading elements\n @include font-size($font-size-sm);\n color: $dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n display: block;\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n color: $dropdown-link-color;\n}\n","@mixin caret-down() {\n border-top: $caret-width solid;\n border-right: $caret-width solid transparent;\n border-bottom: 0;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up() {\n border-top: 0;\n border-right: $caret-width solid transparent;\n border-bottom: $caret-width solid;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-right() {\n border-top: $caret-width solid transparent;\n border-right: 0;\n border-bottom: $caret-width solid transparent;\n border-left: $caret-width solid;\n}\n\n@mixin caret-left() {\n border-top: $caret-width solid transparent;\n border-right: $caret-width solid;\n border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n @if $enable-caret {\n &::after {\n display: inline-block;\n margin-left: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @if $direction == down {\n @include caret-down();\n } @else if $direction == up {\n @include caret-up();\n } @else if $direction == right {\n @include caret-right();\n }\n }\n\n @if $direction == left {\n &::after {\n display: none;\n }\n\n &::before {\n display: inline-block;\n margin-right: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @include caret-left();\n }\n }\n\n &:empty::after {\n margin-left: 0;\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y, $ignore-warning: false) {\n height: 0;\n margin: $margin-y 0;\n overflow: hidden;\n border-top: 1px solid $color;\n @include deprecate(\"The `nav-divider()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle; // match .btn alignment given font-size hack above\n\n > .btn {\n position: relative;\n flex: 1 1 auto;\n\n // Bring the hover, focused, and \"active\" buttons to the front to overlay\n // the borders properly\n @include hover() {\n z-index: 1;\n }\n &:focus,\n &:active,\n &.active {\n z-index: 1;\n }\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n\n .input-group {\n width: auto;\n }\n}\n\n.btn-group {\n // Prevent double borders when buttons are next to each other\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-left: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-right-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-left-radius(0);\n }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n padding-right: $btn-padding-x * .75;\n padding-left: $btn-padding-x * .75;\n\n &::after,\n .dropup &::after,\n .dropright &::after {\n margin-left: 0;\n }\n\n .dropleft &::before {\n margin-right: 0;\n }\n}\n\n.btn-sm + .dropdown-toggle-split {\n padding-right: $btn-padding-x-sm * .75;\n padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n padding-right: $btn-padding-x-lg * .75;\n padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n @include box-shadow($btn-active-box-shadow);\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n @include box-shadow(none);\n }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n\n > .btn,\n > .btn-group {\n width: 100%;\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-top: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-bottom-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-top-radius(0);\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n.btn-group-toggle {\n > .btn,\n > .btn-group > .btn {\n margin-bottom: 0; // Override default `<label>` value\n\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap; // For form validation feedback\n align-items: stretch;\n width: 100%;\n\n > .form-control,\n > .form-control-plaintext,\n > .custom-select,\n > .custom-file {\n position: relative; // For focus state's z-index\n flex: 1 1 auto;\n width: 1%;\n min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size\n margin-bottom: 0;\n\n + .form-control,\n + .custom-select,\n + .custom-file {\n margin-left: -$input-border-width;\n }\n }\n\n // Bring the \"active\" form control to the top of surrounding elements\n > .form-control:focus,\n > .custom-select:focus,\n > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n }\n\n // Bring the custom file input above the label\n > .custom-file .custom-file-input:focus {\n z-index: 4;\n }\n\n > .form-control,\n > .custom-select {\n &:not(:last-child) { @include border-right-radius(0); }\n &:not(:first-child) { @include border-left-radius(0); }\n }\n\n // Custom file inputs have more complex markup, thus requiring different\n // border-radius overrides.\n > .custom-file {\n display: flex;\n align-items: center;\n\n &:not(:last-child) .custom-file-label,\n &:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }\n &:not(:first-child) .custom-file-label { @include border-left-radius(0); }\n }\n}\n\n\n// Prepend and append\n//\n// While it requires one extra layer of HTML for each, dedicated prepend and\n// append elements allow us to 1) be less clever, 2) simplify our selectors, and\n// 3) support HTML5 form validation.\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n\n // Ensure buttons are always above inputs for more visually pleasing borders.\n // This isn't needed for `.input-group-text` since it shares the same border-color\n // as our inputs.\n .btn {\n position: relative;\n z-index: 2;\n\n &:focus {\n z-index: 3;\n }\n }\n\n .btn + .btn,\n .btn + .input-group-text,\n .input-group-text + .input-group-text,\n .input-group-text + .btn {\n margin-left: -$input-border-width;\n }\n}\n\n.input-group-prepend { margin-right: -$input-border-width; }\n.input-group-append { margin-left: -$input-border-width; }\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: $input-padding-y $input-padding-x;\n margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom\n @include font-size($input-font-size); // Match inputs\n font-weight: $font-weight-normal;\n line-height: $input-line-height;\n color: $input-group-addon-color;\n text-align: center;\n white-space: nowrap;\n background-color: $input-group-addon-bg;\n border: $input-border-width solid $input-group-addon-border-color;\n @include border-radius($input-border-radius);\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: $input-height-lg;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: $input-height-sm;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: $custom-select-padding-x + $custom-select-indicator-padding;\n}\n\n\n// Prepend and append rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n @include border-right-radius(0);\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n @include border-left-radius(0);\n}\n","// Embedded icons from Open Iconic.\n// Released under MIT and copyright 2014 Waybury.\n// https://useiconic.com/open\n\n\n// Checkboxes and radios\n//\n// Base class takes care of all the key behavioral aspects.\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: $font-size-base * $line-height-base;\n padding-left: $custom-control-gutter + $custom-control-indicator-size;\n color-adjust: exact; // Keep themed appearance for print\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: $custom-control-spacer-x;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1; // Put the input behind the label so it doesn't overlay text\n width: $custom-control-indicator-size;\n height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;\n opacity: 0;\n\n &:checked ~ .custom-control-label::before {\n color: $custom-control-indicator-checked-color;\n border-color: $custom-control-indicator-checked-border-color;\n @include gradient-bg($custom-control-indicator-checked-bg);\n @include box-shadow($custom-control-indicator-checked-box-shadow);\n }\n\n &:focus ~ .custom-control-label::before {\n // the mixin is not used here to make sure there is feedback\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $custom-control-indicator-focus-box-shadow;\n } @else {\n box-shadow: $custom-control-indicator-focus-box-shadow;\n }\n }\n\n &:focus:not(:checked) ~ .custom-control-label::before {\n border-color: $custom-control-indicator-focus-border-color;\n }\n\n &:not(:disabled):active ~ .custom-control-label::before {\n color: $custom-control-indicator-active-color;\n background-color: $custom-control-indicator-active-bg;\n border-color: $custom-control-indicator-active-border-color;\n @include box-shadow($custom-control-indicator-active-box-shadow);\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled],\n &:disabled {\n ~ .custom-control-label {\n color: $custom-control-label-disabled-color;\n\n &::before {\n background-color: $custom-control-indicator-disabled-bg;\n }\n }\n }\n}\n\n// Custom control indicators\n//\n// Build the custom controls out of pseudo-elements.\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n color: $custom-control-label-color;\n vertical-align: top;\n cursor: $custom-control-cursor;\n\n // Background-color and (when enabled) gradient\n &::before {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n pointer-events: none;\n content: \"\";\n background-color: $custom-control-indicator-bg;\n border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;\n @include box-shadow($custom-control-indicator-box-shadow);\n }\n\n // Foreground (icon)\n &::after {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n content: \"\";\n background: no-repeat 50% / #{$custom-control-indicator-bg-size};\n }\n}\n\n\n// Checkboxes\n//\n// Tweak just a few things for checkboxes.\n\n.custom-checkbox {\n .custom-control-label::before {\n @include border-radius($custom-checkbox-indicator-border-radius);\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-checked);\n }\n }\n\n .custom-control-input:indeterminate ~ .custom-control-label {\n &::before {\n border-color: $custom-checkbox-indicator-indeterminate-border-color;\n @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);\n @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);\n }\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n &:indeterminate ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n// Radios\n//\n// Tweak just a few things for radios.\n\n.custom-radio {\n .custom-control-label::before {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-radio-indicator-border-radius;\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-radio-indicator-icon-checked);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// switches\n//\n// Tweak a few things for switches\n\n.custom-switch {\n padding-left: $custom-switch-width + $custom-control-gutter;\n\n .custom-control-label {\n &::before {\n left: -($custom-switch-width + $custom-control-gutter);\n width: $custom-switch-width;\n pointer-events: all;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n }\n\n &::after {\n top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);\n left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);\n width: $custom-switch-indicator-size;\n height: $custom-switch-indicator-size;\n background-color: $custom-control-indicator-border-color;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n @include transition(transform .15s ease-in-out, $custom-forms-transition);\n }\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-color: $custom-control-indicator-bg;\n transform: translateX($custom-switch-width - $custom-control-indicator-size);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n//\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: $custom-select-height;\n padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;\n font-family: $custom-select-font-family;\n @include font-size($custom-select-font-size);\n font-weight: $custom-select-font-weight;\n line-height: $custom-select-line-height;\n color: $custom-select-color;\n vertical-align: middle;\n background: $custom-select-bg $custom-select-background;\n border: $custom-select-border-width solid $custom-select-border-color;\n @include border-radius($custom-select-border-radius, 0);\n @include box-shadow($custom-select-box-shadow);\n appearance: none;\n\n &:focus {\n border-color: $custom-select-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $custom-select-focus-box-shadow;\n }\n\n &::-ms-value {\n // For visual consistency with other platforms/browsers,\n // suppress the default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n }\n\n &[multiple],\n &[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: $custom-select-padding-x;\n background-image: none;\n }\n\n &:disabled {\n color: $custom-select-disabled-color;\n background-color: $custom-select-disabled-bg;\n }\n\n // Hides the default caret in IE11\n &::-ms-expand {\n display: none;\n }\n\n // Remove outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $custom-select-color;\n }\n}\n\n.custom-select-sm {\n height: $custom-select-height-sm;\n padding-top: $custom-select-padding-y-sm;\n padding-bottom: $custom-select-padding-y-sm;\n padding-left: $custom-select-padding-x-sm;\n @include font-size($custom-select-font-size-sm);\n}\n\n.custom-select-lg {\n height: $custom-select-height-lg;\n padding-top: $custom-select-padding-y-lg;\n padding-bottom: $custom-select-padding-y-lg;\n padding-left: $custom-select-padding-x-lg;\n @include font-size($custom-select-font-size-lg);\n}\n\n\n// File\n//\n// Custom file input.\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: $custom-file-height;\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: $custom-file-height;\n margin: 0;\n opacity: 0;\n\n &:focus ~ .custom-file-label {\n border-color: $custom-file-focus-border-color;\n box-shadow: $custom-file-focus-box-shadow;\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .custom-file-label,\n &:disabled ~ .custom-file-label {\n background-color: $custom-file-disabled-bg;\n }\n\n @each $lang, $value in $custom-file-text {\n &:lang(#{$lang}) ~ .custom-file-label::after {\n content: $value;\n }\n }\n\n ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n }\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: $custom-file-height;\n padding: $custom-file-padding-y $custom-file-padding-x;\n font-family: $custom-file-font-family;\n font-weight: $custom-file-font-weight;\n line-height: $custom-file-line-height;\n color: $custom-file-color;\n background-color: $custom-file-bg;\n border: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius($custom-file-border-radius);\n @include box-shadow($custom-file-box-shadow);\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: $custom-file-height-inner;\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-button-color;\n content: \"Browse\";\n @include gradient-bg($custom-file-button-bg);\n border-left: inherit;\n @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);\n }\n}\n\n// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.custom-range {\n width: 100%;\n height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);\n padding: 0; // Need to reset padding\n background-color: transparent;\n appearance: none;\n\n &:focus {\n outline: none;\n\n // Pseudo-elements must be split across multiple rulesets to have an effect.\n // No box-shadow() mixin for focus accessibility.\n &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n }\n\n &::-moz-focus-outer {\n border: 0;\n }\n\n &::-webkit-slider-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-webkit-slider-runnable-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent; // Why?\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent;\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-moz-range-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-moz-range-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent; // Firefox specific?\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: 0; // Edge specific\n margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-ms-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: transparent;\n border-color: transparent;\n border-width: $custom-range-thumb-height / 2;\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-fill-lower {\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &::-ms-fill-upper {\n margin-right: 15px; // arbitrary?\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &:disabled {\n &::-webkit-slider-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-webkit-slider-runnable-track {\n cursor: default;\n }\n\n &::-moz-range-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-moz-range-track {\n cursor: default;\n }\n\n &::-ms-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n }\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n @include transition($custom-forms-transition);\n}\n","// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s, `<ul>`s or `<ol>`s.\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: $nav-link-padding-y $nav-link-padding-x;\n text-decoration: if($link-decoration == none, null, none);\n\n @include hover-focus() {\n text-decoration: none;\n }\n\n // Disabled state lightens text\n &.disabled {\n color: $nav-link-disabled-color;\n pointer-events: none;\n cursor: default;\n }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n .nav-item {\n margin-bottom: -$nav-tabs-border-width;\n }\n\n .nav-link {\n border: $nav-tabs-border-width solid transparent;\n @include border-top-radius($nav-tabs-border-radius);\n\n @include hover-focus() {\n border-color: $nav-tabs-link-hover-border-color;\n }\n\n &.disabled {\n color: $nav-link-disabled-color;\n background-color: transparent;\n border-color: transparent;\n }\n }\n\n .nav-link.active,\n .nav-item.show .nav-link {\n color: $nav-tabs-link-active-color;\n background-color: $nav-tabs-link-active-bg;\n border-color: $nav-tabs-link-active-border-color;\n }\n\n .dropdown-menu {\n // Make dropdown border overlap tab border\n margin-top: -$nav-tabs-border-width;\n // Remove the top rounded corners here since there is a hard edge above the menu\n @include border-top-radius(0);\n }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n .nav-link {\n @include border-radius($nav-pills-border-radius);\n }\n\n .nav-link.active,\n .show > .nav-link {\n color: $nav-pills-link-active-color;\n background-color: $nav-pills-link-active-bg;\n }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n > .nav-link,\n .nav-item {\n flex: 1 1 auto;\n text-align: center;\n }\n}\n\n.nav-justified {\n > .nav-link,\n .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n","// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Navbar divider\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap; // allow us to do the line break for collapsing content\n align-items: center;\n justify-content: space-between; // space out brand from logo\n padding: $navbar-padding-y $navbar-padding-x;\n\n // Because flex properties aren't inherited, we need to redeclare these first\n // few properties so that content nested within behave properly.\n %container-flex-properties {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n }\n\n .container,\n .container-fluid {\n @extend %container-flex-properties;\n }\n\n @each $breakpoint, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {\n @extend %container-flex-properties;\n }\n }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n display: inline-block;\n padding-top: $navbar-brand-padding-y;\n padding-bottom: $navbar-brand-padding-y;\n margin-right: $navbar-padding-x;\n @include font-size($navbar-brand-font-size);\n line-height: inherit;\n white-space: nowrap;\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n display: flex;\n flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n\n .nav-link {\n padding-right: 0;\n padding-left: 0;\n }\n\n .dropdown-menu {\n position: static;\n float: none;\n }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n display: inline-block;\n padding-top: $nav-link-padding-y;\n padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n // For always expanded or extra full navbars, ensure content aligns itself\n // properly vertically. Can be easily overridden with flex utilities.\n align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n @include font-size($navbar-toggler-font-size);\n line-height: 1;\n background-color: transparent; // remove default button style\n border: $border-width solid transparent; // remove default button style\n @include border-radius($navbar-toggler-border-radius);\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n %container-navbar-expand-#{$breakpoint} {\n padding-right: 0;\n padding-left: 0;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n }\n }\n\n @include media-breakpoint-up($next) {\n flex-flow: row nowrap;\n justify-content: flex-start;\n\n .navbar-nav {\n flex-direction: row;\n\n .dropdown-menu {\n position: absolute;\n }\n\n .nav-link {\n padding-right: $navbar-nav-link-padding-x;\n padding-left: $navbar-nav-link-padding-x;\n }\n }\n\n // For nesting containers, have to redeclare for alignment purposes\n %container-nesting-#{$breakpoint} {\n flex-wrap: nowrap;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-nesting-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-nesting-#{$breakpoint};\n }\n }\n\n .navbar-collapse {\n display: flex !important; // stylelint-disable-line declaration-no-important\n\n // Changes flex-bases to auto because of an IE10 bug\n flex-basis: auto;\n }\n\n .navbar-toggler {\n display: none;\n }\n }\n }\n }\n}\n\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n .navbar-brand {\n color: $navbar-light-brand-color;\n\n @include hover-focus() {\n color: $navbar-light-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-light-color;\n\n @include hover-focus() {\n color: $navbar-light-hover-color;\n }\n\n &.disabled {\n color: $navbar-light-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-light-color;\n border-color: $navbar-light-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-light-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-light-color;\n a {\n color: $navbar-light-active-color;\n\n @include hover-focus() {\n color: $navbar-light-active-color;\n }\n }\n }\n}\n\n// White links against a dark background\n.navbar-dark {\n .navbar-brand {\n color: $navbar-dark-brand-color;\n\n @include hover-focus() {\n color: $navbar-dark-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-dark-color;\n\n @include hover-focus() {\n color: $navbar-dark-hover-color;\n }\n\n &.disabled {\n color: $navbar-dark-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-dark-color;\n border-color: $navbar-dark-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-dark-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-dark-color;\n a {\n color: $navbar-dark-active-color;\n\n @include hover-focus() {\n color: $navbar-dark-active-color;\n }\n }\n }\n}\n","//\n// Base styles\n//\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106\n height: $card-height;\n word-wrap: break-word;\n background-color: $card-bg;\n background-clip: border-box;\n border: $card-border-width solid $card-border-color;\n @include border-radius($card-border-radius);\n\n > hr {\n margin-right: 0;\n margin-left: 0;\n }\n\n > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n\n &:first-child {\n border-top-width: 0;\n @include border-top-radius($card-inner-border-radius);\n }\n\n &:last-child {\n border-bottom-width: 0;\n @include border-bottom-radius($card-inner-border-radius);\n }\n }\n\n // Due to specificity of the above selector (`.card > .list-group`), we must\n // use a child selector here to prevent double borders.\n > .card-header + .list-group,\n > .list-group + .card-footer {\n border-top: 0;\n }\n}\n\n.card-body {\n // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n // as much space as possible, ensuring footers are aligned to the bottom.\n flex: 1 1 auto;\n // Workaround for the image size bug in IE\n // See: https://github.com/twbs/bootstrap/pull/28855\n min-height: 1px;\n padding: $card-spacer-x;\n color: $card-color;\n}\n\n.card-title {\n margin-bottom: $card-spacer-y;\n}\n\n.card-subtitle {\n margin-top: -$card-spacer-y / 2;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link {\n @include hover() {\n text-decoration: none;\n }\n\n + .card-link {\n margin-left: $card-spacer-x;\n }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n padding: $card-spacer-y $card-spacer-x;\n margin-bottom: 0; // Removes the default margin-bottom of <hN>\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-bottom: $card-border-width solid $card-border-color;\n\n &:first-child {\n @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n }\n}\n\n.card-footer {\n padding: $card-spacer-y $card-spacer-x;\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-top: $card-border-width solid $card-border-color;\n\n &:last-child {\n @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n margin-right: -$card-spacer-x / 2;\n margin-bottom: -$card-spacer-y;\n margin-left: -$card-spacer-x / 2;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -$card-spacer-x / 2;\n margin-left: -$card-spacer-x / 2;\n}\n\n// Card image\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: $card-img-overlay-padding;\n @include border-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n}\n\n.card-img,\n.card-img-top {\n @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n// Card deck\n\n.card-deck {\n .card {\n margin-bottom: $card-deck-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n margin-right: -$card-deck-margin;\n margin-left: -$card-deck-margin;\n\n .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-right: $card-deck-margin;\n margin-bottom: 0; // Override the default\n margin-left: $card-deck-margin;\n }\n }\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n margin-bottom: $card-group-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-bottom: 0;\n\n + .card {\n margin-left: 0;\n border-left: 0;\n }\n\n // Handle rounded corners\n @if $enable-rounded {\n &:not(:last-child) {\n @include border-right-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-right-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-right-radius: 0;\n }\n }\n\n &:not(:first-child) {\n @include border-left-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-left-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-left-radius: 0;\n }\n }\n }\n }\n }\n}\n\n\n//\n// Columns\n//\n\n.card-columns {\n .card {\n margin-bottom: $card-columns-margin;\n }\n\n @include media-breakpoint-up(sm) {\n column-count: $card-columns-count;\n column-gap: $card-columns-gap;\n orphans: 1;\n widows: 1;\n\n .card {\n display: inline-block; // Don't let them vertically span multiple columns\n width: 100%; // Don't let their width change\n }\n }\n}\n\n\n//\n// Accordion\n//\n\n.accordion {\n overflow-anchor: none;\n\n > .card {\n overflow: hidden;\n\n &:not(:last-of-type) {\n border-bottom: 0;\n @include border-bottom-radius(0);\n }\n\n &:not(:first-of-type) {\n @include border-top-radius(0);\n }\n\n > .card-header {\n @include border-radius(0);\n margin-bottom: -$card-border-width;\n }\n }\n}\n",".breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n margin-bottom: $breadcrumb-margin-bottom;\n @include font-size($breadcrumb-font-size);\n list-style: none;\n background-color: $breadcrumb-bg;\n @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n display: flex;\n\n // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n + .breadcrumb-item {\n padding-left: $breadcrumb-item-padding;\n\n &::before {\n display: inline-block; // Suppress underlining of the separator in modern browsers\n padding-right: $breadcrumb-item-padding;\n color: $breadcrumb-divider-color;\n content: escape-svg($breadcrumb-divider);\n }\n }\n\n // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built\n // without `<ul>`s. The `::before` pseudo-element generates an element\n // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.\n //\n // To trick IE into suppressing the underline, we give the pseudo-element an\n // underline and then immediately remove it.\n + .breadcrumb-item:hover::before {\n text-decoration: underline;\n }\n // stylelint-disable-next-line no-duplicate-selectors\n + .breadcrumb-item:hover::before {\n text-decoration: none;\n }\n\n &.active {\n color: $breadcrumb-active-color;\n }\n}\n",".pagination {\n display: flex;\n @include list-unstyled();\n @include border-radius();\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: $pagination-padding-y $pagination-padding-x;\n margin-left: -$pagination-border-width;\n line-height: $pagination-line-height;\n color: $pagination-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $pagination-bg;\n border: $pagination-border-width solid $pagination-border-color;\n\n &:hover {\n z-index: 2;\n color: $pagination-hover-color;\n text-decoration: none;\n background-color: $pagination-hover-bg;\n border-color: $pagination-hover-border-color;\n }\n\n &:focus {\n z-index: 3;\n outline: $pagination-focus-outline;\n box-shadow: $pagination-focus-box-shadow;\n }\n}\n\n.page-item {\n &:first-child {\n .page-link {\n margin-left: 0;\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n\n &.active .page-link {\n z-index: 3;\n color: $pagination-active-color;\n background-color: $pagination-active-bg;\n border-color: $pagination-active-border-color;\n }\n\n &.disabled .page-link {\n color: $pagination-disabled-color;\n pointer-events: none;\n // Opinionated: remove the \"hand\" cursor set previously for .page-link\n cursor: auto;\n background-color: $pagination-disabled-bg;\n border-color: $pagination-disabled-border-color;\n }\n}\n\n\n//\n// Sizing\n//\n\n.pagination-lg {\n @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);\n}\n\n.pagination-sm {\n @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);\n}\n","// Pagination\n\n@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n .page-link {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n }\n\n .page-item {\n &:first-child {\n .page-link {\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n }\n}\n","// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n display: inline-block;\n padding: $badge-padding-y $badge-padding-x;\n @include font-size($badge-font-size);\n font-weight: $badge-font-weight;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n @include border-radius($badge-border-radius);\n @include transition($badge-transition);\n\n @at-root a#{&} {\n @include hover-focus() {\n text-decoration: none;\n }\n }\n\n // Empty badges collapse automatically\n &:empty {\n display: none;\n }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Pill badges\n//\n// Make them extra rounded with a modifier to replace v3's badges.\n\n.badge-pill {\n padding-right: $badge-pill-padding-x;\n padding-left: $badge-pill-padding-x;\n @include border-radius($badge-pill-border-radius);\n}\n\n// Colors\n//\n// Contextual variations (linked badges get darker on :hover).\n\n@each $color, $value in $theme-colors {\n .badge-#{$color} {\n @include badge-variant($value);\n }\n}\n","@mixin badge-variant($bg) {\n color: color-yiq($bg);\n background-color: $bg;\n\n @at-root a#{&} {\n @include hover-focus() {\n color: color-yiq($bg);\n background-color: darken($bg, 10%);\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);\n }\n }\n}\n",".jumbotron {\n padding: $jumbotron-padding ($jumbotron-padding / 2);\n margin-bottom: $jumbotron-padding;\n color: $jumbotron-color;\n background-color: $jumbotron-bg;\n @include border-radius($border-radius-lg);\n\n @include media-breakpoint-up(sm) {\n padding: ($jumbotron-padding * 2) $jumbotron-padding;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n @include border-radius(0);\n}\n","//\n// Base styles\n//\n\n.alert {\n position: relative;\n padding: $alert-padding-y $alert-padding-x;\n margin-bottom: $alert-margin-bottom;\n border: $alert-border-width solid transparent;\n @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n // Specified to prevent conflicts of changing $headings-color\n color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n padding-right: $close-font-size + $alert-padding-x * 2;\n\n // Adjust close link position\n .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: $alert-padding-y $alert-padding-x;\n color: inherit;\n }\n}\n\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $color, $value in $theme-colors {\n .alert-#{$color} {\n @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));\n }\n}\n","@mixin alert-variant($background, $border, $color) {\n color: $color;\n @include gradient-bg($background);\n border-color: $border;\n\n hr {\n border-top-color: darken($border, 5%);\n }\n\n .alert-link {\n color: darken($color, 10%);\n }\n}\n","// Disable animation if transitions are disabled\n@if $enable-transitions {\n @keyframes progress-bar-stripes {\n from { background-position: $progress-height 0; }\n to { background-position: 0 0; }\n }\n}\n\n.progress {\n display: flex;\n height: $progress-height;\n overflow: hidden; // force rounded corners by cropping it\n line-height: 0;\n @include font-size($progress-font-size);\n background-color: $progress-bg;\n @include border-radius($progress-border-radius);\n @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: $progress-bar-color;\n text-align: center;\n white-space: nowrap;\n background-color: $progress-bar-bg;\n @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n @include gradient-striped();\n background-size: $progress-height $progress-height;\n}\n\n@if $enable-transitions {\n .progress-bar-animated {\n animation: progress-bar-stripes $progress-bar-animation-timing;\n\n @if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n}\n",".media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n","// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n display: flex;\n flex-direction: column;\n\n // No need to set list-style: none; since .list-group-item is block level\n padding-left: 0; // reset padding because ul and ol\n margin-bottom: 0;\n @include border-radius($list-group-border-radius);\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n width: 100%; // For `<button>`s (anchors become 100% by default though)\n color: $list-group-action-color;\n text-align: inherit; // For `<button>`s (anchors inherit)\n\n // Hover state\n @include hover-focus() {\n z-index: 1; // Place hover/focus items above their siblings for proper border styling\n color: $list-group-action-hover-color;\n text-decoration: none;\n background-color: $list-group-hover-bg;\n }\n\n &:active {\n color: $list-group-action-active-color;\n background-color: $list-group-action-active-bg;\n }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: $list-group-item-padding-y $list-group-item-padding-x;\n color: $list-group-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $list-group-bg;\n border: $list-group-border-width solid $list-group-border-color;\n\n &:first-child {\n @include border-top-radius(inherit);\n }\n\n &:last-child {\n @include border-bottom-radius(inherit);\n }\n\n &.disabled,\n &:disabled {\n color: $list-group-disabled-color;\n pointer-events: none;\n background-color: $list-group-disabled-bg;\n }\n\n // Include both here for `<a>`s and `<button>`s\n &.active {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: $list-group-active-color;\n background-color: $list-group-active-bg;\n border-color: $list-group-active-border-color;\n }\n\n & + & {\n border-top-width: 0;\n\n &.active {\n margin-top: -$list-group-border-width;\n border-top-width: $list-group-border-width;\n }\n }\n}\n\n\n// Horizontal\n//\n// Change the layout of list group items from vertical (default) to horizontal.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .list-group-horizontal#{$infix} {\n flex-direction: row;\n\n > .list-group-item {\n &:first-child {\n @include border-bottom-left-radius($list-group-border-radius);\n @include border-top-right-radius(0);\n }\n\n &:last-child {\n @include border-top-right-radius($list-group-border-radius);\n @include border-bottom-left-radius(0);\n }\n\n &.active {\n margin-top: 0;\n }\n\n + .list-group-item {\n border-top-width: $list-group-border-width;\n border-left-width: 0;\n\n &.active {\n margin-left: -$list-group-border-width;\n border-left-width: $list-group-border-width;\n }\n }\n }\n }\n }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n @include border-radius(0);\n\n > .list-group-item {\n border-width: 0 0 $list-group-border-width;\n\n &:last-child {\n border-bottom-width: 0;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $color, $value in $theme-colors {\n @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));\n}\n","// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n .list-group-item-#{$state} {\n color: $color;\n background-color: $background;\n\n &.list-group-item-action {\n @include hover-focus() {\n color: $color;\n background-color: darken($background, 5%);\n }\n\n &.active {\n color: $white;\n background-color: $color;\n border-color: $color;\n }\n }\n }\n}\n",".close {\n float: right;\n @include font-size($close-font-size);\n font-weight: $close-font-weight;\n line-height: 1;\n color: $close-color;\n text-shadow: $close-text-shadow;\n opacity: .5;\n\n // Override <a>'s hover style\n @include hover() {\n color: $close-color;\n text-decoration: none;\n }\n\n &:not(:disabled):not(.disabled) {\n @include hover-focus() {\n opacity: .75;\n }\n }\n}\n\n// Additional properties for button version\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n// stylelint-disable-next-line selector-no-qualifying-type\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\n// Future-proof disabling of clicks on `<a>` elements\n\n// stylelint-disable-next-line selector-no-qualifying-type\na.close.disabled {\n pointer-events: none;\n}\n",".toast {\n // Prevents from shrinking in IE11, when in a flex container\n // See https://github.com/twbs/bootstrap/issues/28341\n flex-basis: $toast-max-width;\n max-width: $toast-max-width;\n @include font-size($toast-font-size);\n color: $toast-color;\n background-color: $toast-background-color;\n background-clip: padding-box;\n border: $toast-border-width solid $toast-border-color;\n box-shadow: $toast-box-shadow;\n opacity: 0;\n @include border-radius($toast-border-radius);\n\n &:not(:last-child) {\n margin-bottom: $toast-padding-x;\n }\n\n &.showing {\n opacity: 1;\n }\n\n &.show {\n display: block;\n opacity: 1;\n }\n\n &.hide {\n display: none;\n }\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: $toast-padding-y $toast-padding-x;\n color: $toast-header-color;\n background-color: $toast-header-background-color;\n background-clip: padding-box;\n border-bottom: $toast-border-width solid $toast-header-border-color;\n @include border-top-radius(subtract($toast-border-radius, $toast-border-width));\n}\n\n.toast-body {\n padding: $toast-padding-x; // apply to both vertical and horizontal\n}\n","// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and stuff\n\n\n.modal-open {\n // Kill the scroll on the body\n overflow: hidden;\n\n .modal {\n overflow-x: hidden;\n overflow-y: auto;\n }\n}\n\n// Container that the modal scrolls within\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: $modal-dialog-margin;\n // allow clicks to pass through for custom click handling to close modal\n pointer-events: none;\n\n // When fading in the modal, animate it to slide down\n .modal.fade & {\n @include transition($modal-transition);\n transform: $modal-fade-transform;\n }\n .modal.show & {\n transform: $modal-show-transform;\n }\n\n // When trying to close, animate focus to scale\n .modal.modal-static & {\n transform: $modal-scale-transform;\n }\n}\n\n.modal-dialog-scrollable {\n display: flex; // IE10/11\n max-height: subtract(100%, $modal-dialog-margin * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11\n overflow: hidden;\n }\n\n .modal-header,\n .modal-footer {\n flex-shrink: 0;\n }\n\n .modal-body {\n overflow-y: auto;\n }\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: subtract(100%, $modal-dialog-margin * 2);\n\n // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)\n &::before {\n display: block; // IE10\n height: subtract(100vh, $modal-dialog-margin * 2);\n height: min-content; // Reset height to 0 except on IE\n content: \"\";\n }\n\n // Ensure `.modal-body` shows scrollbar (IE10/11)\n &.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n\n .modal-content {\n max-height: none;\n }\n\n &::before {\n content: none;\n }\n }\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n // counteract the pointer-events: none; in the .modal-dialog\n color: $modal-content-color;\n pointer-events: auto;\n background-color: $modal-content-bg;\n background-clip: padding-box;\n border: $modal-content-border-width solid $modal-content-border-color;\n @include border-radius($modal-content-border-radius);\n @include box-shadow($modal-content-box-shadow-xs);\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal-backdrop;\n width: 100vw;\n height: 100vh;\n background-color: $modal-backdrop-bg;\n\n // Fade for backdrop\n &.fade { opacity: 0; }\n &.show { opacity: $modal-backdrop-opacity; }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n display: flex;\n align-items: flex-start; // so the close btn always stays on the upper right corner\n justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n padding: $modal-header-padding;\n border-bottom: $modal-header-border-width solid $modal-header-border-color;\n @include border-top-radius($modal-content-inner-border-radius);\n\n .close {\n padding: $modal-header-padding;\n // auto on the left force icon to the right even when there is no .modal-title\n margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;\n }\n}\n\n// Title text within header\n.modal-title {\n margin-bottom: 0;\n line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n // Enable `flex-grow: 1` so that the body take up as much space as possible\n // when there should be a fixed height on `.modal-dialog`.\n flex: 1 1 auto;\n padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center; // vertically center\n justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n padding: $modal-inner-padding - $modal-footer-margin-between / 2;\n border-top: $modal-footer-border-width solid $modal-footer-border-color;\n @include border-bottom-radius($modal-content-inner-border-radius);\n\n // Place margin between footer elements\n // This solution is far from ideal because of the universal selector usage,\n // but is needed to fix https://github.com/twbs/bootstrap/issues/24800\n > * {\n margin: $modal-footer-margin-between / 2;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n max-width: $modal-md;\n margin: $modal-dialog-margin-y-sm-up auto;\n }\n\n .modal-dialog-scrollable {\n max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n }\n }\n\n .modal-dialog-centered {\n min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n &::before {\n height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n height: min-content;\n }\n }\n\n .modal-content {\n @include box-shadow($modal-content-box-shadow-sm-up);\n }\n\n .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n .modal-lg,\n .modal-xl {\n max-width: $modal-lg;\n }\n}\n\n@include media-breakpoint-up(xl) {\n .modal-xl { max-width: $modal-xl; }\n}\n","// Base class\n.tooltip {\n position: absolute;\n z-index: $zindex-tooltip;\n display: block;\n margin: $tooltip-margin;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($tooltip-font-size);\n // Allow breaking very long words so they don't overflow the tooltip's bounds\n word-wrap: break-word;\n opacity: 0;\n\n &.show { opacity: $tooltip-opacity; }\n\n .arrow {\n position: absolute;\n display: block;\n width: $tooltip-arrow-width;\n height: $tooltip-arrow-height;\n\n &::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-tooltip-top {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n bottom: 0;\n\n &::before {\n top: 0;\n border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-top-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-right {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n left: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n right: 0;\n border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-right-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-bottom {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n top: 0;\n\n &::before {\n bottom: 0;\n border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-bottom-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-left {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n right: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n left: 0;\n border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-left-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-tooltip-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-tooltip-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-tooltip-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-tooltip-left;\n }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: $tooltip-max-width;\n padding: $tooltip-padding-y $tooltip-padding-x;\n color: $tooltip-color;\n text-align: center;\n background-color: $tooltip-bg;\n @include border-radius($tooltip-border-radius);\n}\n","@mixin reset-text() {\n font-family: $font-family-base;\n // We deliberately do NOT reset font-size or word-wrap.\n font-style: normal;\n font-weight: $font-weight-normal;\n line-height: $line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n}\n",".popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: $zindex-popover;\n display: block;\n max-width: $popover-max-width;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($popover-font-size);\n // Allow breaking very long words so they don't overflow the popover's bounds\n word-wrap: break-word;\n background-color: $popover-bg;\n background-clip: padding-box;\n border: $popover-border-width solid $popover-border-color;\n @include border-radius($popover-border-radius);\n @include box-shadow($popover-box-shadow);\n\n .arrow {\n position: absolute;\n display: block;\n width: $popover-arrow-width;\n height: $popover-arrow-height;\n margin: 0 $popover-border-radius;\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-popover-top {\n margin-bottom: $popover-arrow-height;\n\n > .arrow {\n bottom: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n bottom: 0;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-outer-color;\n }\n\n &::after {\n bottom: $popover-border-width;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-right {\n margin-left: $popover-arrow-height;\n\n > .arrow {\n left: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n left: 0;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-outer-color;\n }\n\n &::after {\n left: $popover-border-width;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-bottom {\n margin-top: $popover-arrow-height;\n\n > .arrow {\n top: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n top: 0;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-outer-color;\n }\n\n &::after {\n top: $popover-border-width;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-color;\n }\n }\n\n // This will remove the popover-header's border just below the arrow\n .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: $popover-arrow-width;\n margin-left: -$popover-arrow-width / 2;\n content: \"\";\n border-bottom: $popover-border-width solid $popover-header-bg;\n }\n}\n\n.bs-popover-left {\n margin-right: $popover-arrow-height;\n\n > .arrow {\n right: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n right: 0;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-outer-color;\n }\n\n &::after {\n right: $popover-border-width;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-popover-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-popover-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-popover-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-popover-left;\n }\n}\n\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n padding: $popover-header-padding-y $popover-header-padding-x;\n margin-bottom: 0; // Reset the default from Reboot\n @include font-size($font-size-base);\n color: $popover-header-color;\n background-color: $popover-header-bg;\n border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);\n @include border-top-radius($popover-inner-border-radius);\n\n &:empty {\n display: none;\n }\n}\n\n.popover-body {\n padding: $popover-body-padding-y $popover-body-padding-x;\n color: $popover-body-color;\n}\n","// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n// even when their scroll action started on a carousel, but for compatibility (with Firefox)\n// we're preventing all actions instead\n// 2. The .carousel-item-left and .carousel-item-right is used to indicate where\n// the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-left and .active.carousel-item-right is the current\n// slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right\n// is the upcoming slide in transition.\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n @include clearfix();\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n }\n\n .carousel-item.active,\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n }\n\n .active.carousel-item-left,\n .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n @include transition(opacity 0s $carousel-transition-duration);\n }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n // Use flex for alignment (1-3)\n display: flex; // 1. allow flex styles\n align-items: center; // 2. vertically center contents\n justify-content: center; // 3. horizontally center contents\n width: $carousel-control-width;\n color: $carousel-control-color;\n text-align: center;\n opacity: $carousel-control-opacity;\n @include transition($carousel-control-transition);\n\n // Hover/focus state\n @include hover-focus() {\n color: $carousel-control-color;\n text-decoration: none;\n outline: 0;\n opacity: $carousel-control-hover-opacity;\n }\n}\n.carousel-control-prev {\n left: 0;\n @if $enable-gradients {\n background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));\n }\n}\n.carousel-control-next {\n right: 0;\n @if $enable-gradients {\n background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));\n }\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: $carousel-control-icon-width;\n height: $carousel-control-icon-width;\n background: no-repeat 50% / 100% 100%;\n}\n.carousel-control-prev-icon {\n background-image: escape-svg($carousel-control-prev-icon-bg);\n}\n.carousel-control-next-icon {\n background-image: escape-svg($carousel-control-next-icon-bg);\n}\n\n\n// Optional indicator pips\n//\n// Add an ordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0; // override <ol> default\n // Use the .carousel-control's width as margin so we don't overlay those\n margin-right: $carousel-control-width;\n margin-left: $carousel-control-width;\n list-style: none;\n\n li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: $carousel-indicator-width;\n height: $carousel-indicator-height;\n margin-right: $carousel-indicator-spacer;\n margin-left: $carousel-indicator-spacer;\n text-indent: -999px;\n cursor: pointer;\n background-color: $carousel-indicator-active-bg;\n background-clip: padding-box;\n // Use transparent borders to increase the hit area by 10px on top and bottom.\n border-top: $carousel-indicator-hit-area-height solid transparent;\n border-bottom: $carousel-indicator-hit-area-height solid transparent;\n opacity: .5;\n @include transition($carousel-indicator-transition);\n }\n\n .active {\n opacity: 1;\n }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n position: absolute;\n right: (100% - $carousel-caption-width) / 2;\n bottom: 20px;\n left: (100% - $carousel-caption-width) / 2;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: $carousel-caption-color;\n text-align: center;\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","//\n// Rotating border\n//\n\n@keyframes spinner-border {\n to { transform: rotate(360deg); }\n}\n\n.spinner-border {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n border: $spinner-border-width solid currentColor;\n border-right-color: transparent;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n background-color: currentColor;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n}\n","// stylelint-disable declaration-no-important\n\n.align-baseline { vertical-align: baseline !important; } // Browser default\n.align-top { vertical-align: top !important; }\n.align-middle { vertical-align: middle !important; }\n.align-bottom { vertical-align: bottom !important; }\n.align-text-bottom { vertical-align: text-bottom !important; }\n.align-text-top { vertical-align: text-top !important; }\n","// stylelint-disable declaration-no-important\n\n// Contextual backgrounds\n\n@mixin bg-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background-color: $color !important;\n }\n a#{$parent},\n button#{$parent} {\n @include hover-focus() {\n background-color: darken($color, 10%) !important;\n }\n }\n @include deprecate(\"The `bg-variant` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n@mixin bg-gradient-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;\n }\n @include deprecate(\"The `bg-gradient-variant` mixin\", \"v4.5.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n@each $color, $value in $theme-colors {\n @include bg-variant(\".bg-#{$color}\", $value, true);\n}\n\n@if $enable-gradients {\n @each $color, $value in $theme-colors {\n @include bg-gradient-variant(\".bg-gradient-#{$color}\", $value, true);\n }\n}\n\n.bg-white {\n background-color: $white !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n","// stylelint-disable property-disallowed-list, declaration-no-important\n\n//\n// Border\n//\n\n.border { border: $border-width solid $border-color !important; }\n.border-top { border-top: $border-width solid $border-color !important; }\n.border-right { border-right: $border-width solid $border-color !important; }\n.border-bottom { border-bottom: $border-width solid $border-color !important; }\n.border-left { border-left: $border-width solid $border-color !important; }\n\n.border-0 { border: 0 !important; }\n.border-top-0 { border-top: 0 !important; }\n.border-right-0 { border-right: 0 !important; }\n.border-bottom-0 { border-bottom: 0 !important; }\n.border-left-0 { border-left: 0 !important; }\n\n@each $color, $value in $theme-colors {\n .border-#{$color} {\n border-color: $value !important;\n }\n}\n\n.border-white {\n border-color: $white !important;\n}\n\n//\n// Border-radius\n//\n\n.rounded-sm {\n border-radius: $border-radius-sm !important;\n}\n\n.rounded {\n border-radius: $border-radius !important;\n}\n\n.rounded-top {\n border-top-left-radius: $border-radius !important;\n border-top-right-radius: $border-radius !important;\n}\n\n.rounded-right {\n border-top-right-radius: $border-radius !important;\n border-bottom-right-radius: $border-radius !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-left {\n border-top-left-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-lg {\n border-radius: $border-radius-lg !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: $rounded-pill !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n\n &::before {\n display: block;\n content: \"\";\n }\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n }\n}\n\n@each $embed-responsive-aspect-ratio in $embed-responsive-aspect-ratios {\n $embed-responsive-aspect-ratio-x: nth($embed-responsive-aspect-ratio, 1);\n $embed-responsive-aspect-ratio-y: nth($embed-responsive-aspect-ratio, 2);\n\n .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} {\n &::before {\n padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x);\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .float#{$infix}-left { float: left !important; }\n .float#{$infix}-right { float: right !important; }\n .float#{$infix}-none { float: none !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $user-selects {\n .user-select-#{$value} { user-select: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $overflows {\n .overflow-#{$value} { overflow: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Common values\n@each $position in $positions {\n .position-#{$position} { position: $position !important; }\n}\n\n// Shorthand\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.sticky-top {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: $zindex-sticky;\n }\n}\n","//\n// Screenreaders\n//\n\n.sr-only {\n @include sr-only();\n}\n\n.sr-only-focusable {\n @include sr-only-focusable();\n}\n","// Only display content to screen readers\n//\n// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/\n// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin sr-only() {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px; // Fix for https://github.com/twbs/bootstrap/issues/25686\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable() {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n }\n}\n","// stylelint-disable declaration-no-important\n\n.shadow-sm { box-shadow: $box-shadow-sm !important; }\n.shadow { box-shadow: $box-shadow !important; }\n.shadow-lg { box-shadow: $box-shadow-lg !important; }\n.shadow-none { box-shadow: none !important; }\n","// stylelint-disable declaration-no-important\n\n// Width and height\n\n@each $prop, $abbrev in (width: w, height: h) {\n @each $size, $length in $sizes {\n .#{$abbrev}-#{$size} { #{$prop}: $length !important; }\n }\n}\n\n.mw-100 { max-width: 100% !important; }\n.mh-100 { max-height: 100% !important; }\n\n// Viewport additional helpers\n\n.min-vw-100 { min-width: 100vw !important; }\n.min-vh-100 { min-height: 100vh !important; }\n\n.vw-100 { width: 100vw !important; }\n.vh-100 { height: 100vh !important; }\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n","//\n// Stretched link\n//\n\n.stretched-link {\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n // Just in case `pointer-events: none` is set on a parent\n pointer-events: auto;\n content: \"\";\n // IE10 bugfix, see https://stackoverflow.com/questions/16947967/ie10-hover-pseudo-class-doesnt-work-without-background-color\n background-color: rgba(0, 0, 0, 0);\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Text\n//\n\n.text-monospace { font-family: $font-family-monospace !important; }\n\n// Alignment\n\n.text-justify { text-align: justify !important; }\n.text-wrap { white-space: normal !important; }\n.text-nowrap { white-space: nowrap !important; }\n.text-truncate { @include text-truncate(); }\n\n// Responsive alignment\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .text#{$infix}-left { text-align: left !important; }\n .text#{$infix}-right { text-align: right !important; }\n .text#{$infix}-center { text-align: center !important; }\n }\n}\n\n// Transformation\n\n.text-lowercase { text-transform: lowercase !important; }\n.text-uppercase { text-transform: uppercase !important; }\n.text-capitalize { text-transform: capitalize !important; }\n\n// Weight and italics\n\n.font-weight-light { font-weight: $font-weight-light !important; }\n.font-weight-lighter { font-weight: $font-weight-lighter !important; }\n.font-weight-normal { font-weight: $font-weight-normal !important; }\n.font-weight-bold { font-weight: $font-weight-bold !important; }\n.font-weight-bolder { font-weight: $font-weight-bolder !important; }\n.font-italic { font-style: italic !important; }\n\n// Contextual colors\n\n.text-white { color: $white !important; }\n\n@each $color, $value in $theme-colors {\n @include text-emphasis-variant(\".text-#{$color}\", $value, true);\n}\n\n.text-body { color: $body-color !important; }\n.text-muted { color: $text-muted !important; }\n\n.text-black-50 { color: rgba($black, .5) !important; }\n.text-white-50 { color: rgba($white, .5) !important; }\n\n// Misc\n\n.text-hide {\n @include text-hide($ignore-warning: true);\n}\n\n.text-decoration-none { text-decoration: none !important; }\n\n.text-break {\n word-break: break-word !important; // Deprecated, but avoids issues with flex containers\n word-wrap: break-word !important; // Used instead of `overflow-wrap` for IE & Edge Legacy\n}\n\n// Reset\n\n.text-reset { color: inherit !important; }\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// stylelint-disable declaration-no-important\n\n// Typography\n\n@mixin text-emphasis-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n color: $color !important;\n }\n @if $emphasized-link-hover-darken-percentage != 0 {\n a#{$parent} {\n @include hover-focus() {\n color: darken($color, $emphasized-link-hover-darken-percentage) !important;\n }\n }\n }\n @include deprecate(\"`text-emphasis-variant()`\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// CSS image replacement\n@mixin text-hide($ignore-warning: false) {\n // stylelint-disable-next-line font-family-no-missing-generic-family-keyword\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n\n @include deprecate(\"`text-hide()`\", \"v4.1.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Visibility utilities\n//\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n// Source: https://github.com/h5bp/main.css/blob/master/src/_print.css\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request:\n// https://www.phpied.com/delay-loading-your-print-css/\n// ==========================================================================\n\n@if $enable-print-styles {\n @media print {\n *,\n *::before,\n *::after {\n // Bootstrap specific; comment out `color` and `background`\n //color: $black !important; // Black prints faster\n text-shadow: none !important;\n //background: transparent !important;\n box-shadow: none !important;\n }\n\n a {\n &:not(.btn) {\n text-decoration: underline;\n }\n }\n\n // Bootstrap specific; comment the following selector out\n //a[href]::after {\n // content: \" (\" attr(href) \")\";\n //}\n\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n // Bootstrap specific; comment the following selector out\n //\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n //\n\n //a[href^=\"#\"]::after,\n //a[href^=\"javascript:\"]::after {\n // content: \"\";\n //}\n\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px\n page-break-inside: avoid;\n }\n\n //\n // Printing Tables:\n // https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables\n //\n\n thead {\n display: table-header-group;\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Specify a size and min-width to make printing closer across browsers.\n // We don't set margin here because it breaks `size` in Chrome. We also\n // don't use `!important` on `size` as it breaks in Chrome.\n @page {\n size: $print-page-size;\n }\n body {\n min-width: $print-body-min-width !important;\n }\n .container {\n min-width: $print-body-min-width !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .badge {\n border: $border-width solid $black;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: $white !important;\n }\n }\n\n .table-bordered {\n th,\n td {\n border: 1px solid $gray-300 !important;\n }\n }\n\n .table-dark {\n color: inherit;\n\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $table-border-color;\n }\n }\n\n .table .thead-dark th {\n color: inherit;\n border-color: $table-border-color;\n }\n\n // Bootstrap specific changes end\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","bootstrap.css","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/utilities/_interactions.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_stretched-link.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"code\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"input-group\";\n@import \"custom-forms\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"jumbotron\";\n@import \"alert\";\n@import \"progress\";\n@import \"media\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"utilities\";\n@import \"print\";\n",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n cursor: pointer;\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n -webkit-text-decoration-skip-ink: none;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-wrap: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n -ms-flex: 0 0 20%;\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n color: #212529;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n color: #212529;\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #343a40;\n border-color: #454d55;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #454d55;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::-webkit-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-moz-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\ninput[type=\"date\"].form-control,\ninput[type=\"time\"].form-control,\ninput[type=\"datetime-local\"].form-control,\ninput[type=\"month\"].form-control {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: 0.375rem 0;\n margin-bottom: 0;\n font-size: 1rem;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(1.5em + 1rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input[disabled] ~ .form-check-label,\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: -ms-inline-flexbox;\n display: inline-flex;\n -ms-flex-align: center;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.form-row > .col > .valid-tooltip,\n.form-row > [class*=\"col-\"] > .valid-tooltip {\n left: 5px;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat, #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.form-row > .col > .invalid-tooltip,\n.form-row > [class*=\"col-\"] > .invalid-tooltip {\n left: 5px;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat, #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -ms-flex-align: center;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n -ms-flex-negative: 0;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n text-decoration: none;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #e9ecef;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #adb5bd;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: -ms-inline-flexbox;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: stretch;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 1%;\n min-width: 0;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group:not(.has-validation) > .form-control:not(:last-child),\n.input-group:not(.has-validation) > .custom-select:not(:last-child),\n.input-group:not(.has-validation) > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group.has-validation > .form-control:nth-last-child(n + 3),\n.input-group.has-validation > .custom-select:nth-last-child(n + 3),\n.input-group.has-validation > .custom-file:nth-last-child(n + 3) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: -ms-flexbox;\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(1.5em + 1rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.5em + 0.5rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n -webkit-print-color-adjust: exact;\n color-adjust: exact;\n}\n\n.custom-control-inline {\n display: -ms-inline-flexbox;\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1;\n width: 1rem;\n height: 1.25rem;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background: 50% / 50% 50% no-repeat;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n -webkit-transform: translateX(0.75rem);\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n display: none;\n}\n\n.custom-select:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.custom-select-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(1.5em + 1rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin: 0;\n overflow: hidden;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input[disabled] ~ .custom-file-label,\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n overflow: hidden;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(1.5em + 0.75rem);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: 1.4rem;\n padding: 0;\n background-color: transparent;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: 0;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -webkit-appearance: none;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n -webkit-transition: none;\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -moz-appearance: none;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n -moz-transition: none;\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n -ms-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n -ms-transition: none;\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-link {\n margin-bottom: -1px;\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -ms-flex-positive: 1;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar .container,\n.navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: justify;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n -ms-flex-preferred-size: 100%;\n flex-basis: 100%;\n -ms-flex-positive: 1;\n flex-grow: 1;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: 50% / 100% 100% no-repeat;\n}\n\n.navbar-nav-scroll {\n max-height: 75vh;\n overflow-y: auto;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-sm .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-md .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-lg .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-xl .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n -ms-flex-direction: row;\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-nav-scroll {\n overflow: visible;\n}\n\n.navbar-expand .navbar-collapse {\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n}\n\n.card > .list-group:first-child {\n border-top-width: 0;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card > .list-group:last-child {\n border-bottom-width: 0;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n border-top: 0;\n}\n\n.card-body {\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n min-height: 1px;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n -ms-flex-negative: 0;\n flex-shrink: 0;\n width: 100%;\n}\n\n.card-img,\n.card-img-top {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n }\n .card-group > .card {\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n -webkit-column-count: 3;\n -moz-column-count: 3;\n column-count: 3;\n -webkit-column-gap: 1.25rem;\n -moz-column-gap: 1.25rem;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion {\n overflow-anchor: none;\n}\n\n.accordion > .card {\n overflow: hidden;\n}\n\n.accordion > .card:not(:last-of-type) {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion > .card:not(:first-of-type) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion > .card > .card-header {\n border-radius: 0;\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n float: left;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: -ms-flexbox;\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 3;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 3;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .badge {\n transition: none;\n }\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\na.badge-primary:focus, a.badge-primary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\na.badge-secondary:focus, a.badge-secondary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\na.badge-success:focus, a.badge-success.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\na.badge-info:focus, a.badge-info.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\na.badge-warning:focus, a.badge-warning.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\na.badge-danger:focus, a.badge-danger.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\na.badge-light:focus, a.badge-light.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\na.badge-dark:focus, a.badge-dark.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: -ms-flexbox;\n display: flex;\n height: 1rem;\n overflow: hidden;\n line-height: 0;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: center;\n justify-content: center;\n overflow: hidden;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n -webkit-animation: 1s linear infinite progress-bar-stripes;\n animation: 1s linear infinite progress-bar-stripes;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n -webkit-animation: none;\n animation: none;\n }\n}\n\n.media {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n.media-body {\n -ms-flex: 1;\n flex: 1;\n}\n\n.list-group {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n border-radius: 0.25rem;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n\n.list-group-item:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-item + .list-group-item {\n border-top-width: 0;\n}\n\n.list-group-item + .list-group-item.active {\n margin-top: -1px;\n border-top-width: 1px;\n}\n\n.list-group-horizontal {\n -ms-flex-direction: row;\n flex-direction: row;\n}\n\n.list-group-horizontal > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item.active {\n margin-top: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-sm > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-md > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-lg > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .list-group-horizontal-xl > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n.list-group-flush {\n border-radius: 0;\n}\n\n.list-group-flush > .list-group-item {\n border-width: 0 0 1px;\n}\n\n.list-group-flush > .list-group-item:last-child {\n border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n -ms-flex-preferred-size: 350px;\n flex-basis: 350px;\n max-width: 350px;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n opacity: 0;\n border-radius: 0.25rem;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: -webkit-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;\n -webkit-transform: translate(0, -50px);\n transform: translate(0, -50px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n -webkit-transform: none;\n transform: none;\n}\n\n.modal.modal-static .modal-dialog {\n -webkit-transform: scale(1.02);\n transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n display: -ms-flexbox;\n display: flex;\n max-height: calc(100% - 1rem);\n}\n\n.modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 1rem);\n overflow: hidden;\n}\n\n.modal-dialog-scrollable .modal-header,\n.modal-dialog-scrollable .modal-footer {\n -ms-flex-negative: 0;\n flex-shrink: 0;\n}\n\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n min-height: calc(100% - 1rem);\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - 1rem);\n height: -webkit-min-content;\n height: -moz-min-content;\n height: min-content;\n content: \"\";\n}\n\n.modal-dialog-centered.modal-dialog-scrollable {\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: center;\n justify-content: center;\n height: 100%;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable .modal-content {\n max-height: none;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable::before {\n content: none;\n}\n\n.modal-content {\n position: relative;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #dee2e6;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: end;\n justify-content: flex-end;\n padding: 0.75rem;\n border-top: 1px solid #dee2e6;\n border-bottom-right-radius: calc(0.3rem - 1px);\n border-bottom-left-radius: calc(0.3rem - 1px);\n}\n\n.modal-footer > * {\n margin: 0.25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-scrollable {\n max-height: calc(100% - 3.5rem);\n }\n .modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 3.5rem);\n }\n .modal-dialog-centered {\n min-height: calc(100% - 3.5rem);\n }\n .modal-dialog-centered::before {\n height: calc(100vh - 3.5rem);\n height: -webkit-min-content;\n height: -moz-min-content;\n height: min-content;\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=\"top\"] > .arrow {\n bottom: calc(-0.5rem - 1px);\n}\n\n.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=\"top\"] > .arrow::before {\n bottom: 0;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=\"top\"] > .arrow::after {\n bottom: 1px;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=\"right\"] > .arrow {\n left: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=\"right\"] > .arrow::before {\n left: 0;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=\"right\"] > .arrow::after {\n left: 1px;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow {\n top: calc(-0.5rem - 1px);\n}\n\n.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::before {\n top: 0;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::after {\n top: 1px;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=\"left\"] > .arrow {\n right: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=\"left\"] > .arrow::before {\n right: 0;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=\"left\"] > .arrow::after {\n right: 1px;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n -ms-touch-action: pan-y;\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n transition: -webkit-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n -webkit-transform: translateX(100%);\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n -webkit-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n -webkit-transform: none;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: opacity 0s 0.6s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: 50% / 100% 100% no-repeat;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-pack: center;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n -ms-flex: 0 1 auto;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@-webkit-keyframes spinner-border {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes spinner-border {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n -webkit-animation: .75s linear infinite spinner-border;\n animation: .75s linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@-webkit-keyframes spinner-grow {\n 0% {\n -webkit-transform: scale(0);\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n -webkit-transform: none;\n transform: none;\n }\n}\n\n@keyframes spinner-grow {\n 0% {\n -webkit-transform: scale(0);\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n -webkit-transform: none;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n -webkit-animation: .75s linear infinite spinner-grow;\n animation: .75s linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .spinner-border,\n .spinner-grow {\n -webkit-animation-duration: 1.5s;\n animation-duration: 1.5s;\n }\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded-sm {\n border-radius: 0.2rem !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-lg {\n border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n -ms-flex: 1 1 auto !important;\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n -ms-flex-positive: 0 !important;\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n -ms-flex-positive: 1 !important;\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n -ms-flex-negative: 0 !important;\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n -ms-flex-negative: 1 !important;\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.user-select-all {\n -webkit-user-select: all !important;\n -moz-user-select: all !important;\n user-select: all !important;\n}\n\n.user-select-auto {\n -webkit-user-select: auto !important;\n -moz-user-select: auto !important;\n -ms-user-select: auto !important;\n user-select: auto !important;\n}\n\n.user-select-none {\n -webkit-user-select: none !important;\n -moz-user-select: none !important;\n -ms-user-select: none !important;\n user-select: none !important;\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: -webkit-sticky !important;\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .sticky-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n pointer-events: auto;\n content: \"\";\n background-color: rgba(0, 0, 0, 0);\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !important;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-break {\n word-break: break-word !important;\n word-wrap: break-word !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","/*!\n * Bootstrap v4.6.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=\"button\"] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-wrap: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container,\n.container-fluid,\n.container-sm,\n.container-md,\n.container-lg,\n.container-xl {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container, .container-sm {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container, .container-sm, .container-md {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container, .container-sm, .container-md, .container-lg {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container, .container-sm, .container-md, .container-lg, .container-xl {\n max-width: 1140px;\n }\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.row-cols-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-md-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 20%;\n max-width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n color: #212529;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n color: #212529;\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #343a40;\n border-color: #454d55;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #454d55;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\ninput[type=\"date\"].form-control,\ninput[type=\"time\"].form-control,\ninput[type=\"datetime-local\"].form-control,\ninput[type=\"month\"].form-control {\n appearance: none;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: 0.375rem 0;\n margin-bottom: 0;\n font-size: 1rem;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(1.5em + 1rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input[disabled] ~ .form-check-label,\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.form-row > .col > .valid-tooltip,\n.form-row > [class*=\"col-\"] > .valid-tooltip {\n left: 5px;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat, #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.form-row > .col > .invalid-tooltip,\n.form-row > [class*=\"col-\"] > .invalid-tooltip {\n left: 5px;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: calc(0.75em + 2.3125rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat, #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n text-decoration: none;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #e9ecef;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #adb5bd;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n min-width: 0;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group:not(.has-validation) > .form-control:not(:last-child),\n.input-group:not(.has-validation) > .custom-select:not(:last-child),\n.input-group:not(.has-validation) > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group.has-validation > .form-control:nth-last-child(n + 3),\n.input-group.has-validation > .custom-select:nth-last-child(n + 3),\n.input-group.has-validation > .custom-file:nth-last-child(n + 3) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(1.5em + 1rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.5em + 0.5rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n color-adjust: exact;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1;\n width: 1rem;\n height: 1.25rem;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background: 50% / 50% 50% no-repeat;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") right 0.75rem center/8px 10px no-repeat;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n display: none;\n}\n\n.custom-select:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 #495057;\n}\n\n.custom-select-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(1.5em + 1rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin: 0;\n overflow: hidden;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input[disabled] ~ .custom-file-label,\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n overflow: hidden;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(1.5em + 0.75rem);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: 1.4rem;\n padding: 0;\n background-color: transparent;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: 0;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-link {\n margin-bottom: -1px;\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar .container,\n.navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: 50% / 100% 100% no-repeat;\n}\n\n.navbar-nav-scroll {\n max-height: 75vh;\n overflow-y: auto;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-nav-scroll {\n overflow: visible;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n}\n\n.card > .list-group:first-child {\n border-top-width: 0;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card > .list-group:last-child {\n border-bottom-width: 0;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n border-top: 0;\n}\n\n.card-body {\n flex: 1 1 auto;\n min-height: 1px;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0;\n width: 100%;\n}\n\n.card-img,\n.card-img-top {\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n display: flex;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n flex: 1 0 0%;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n display: flex;\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion {\n overflow-anchor: none;\n}\n\n.accordion > .card {\n overflow: hidden;\n}\n\n.accordion > .card:not(:last-of-type) {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion > .card:not(:first-of-type) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion > .card > .card-header {\n border-radius: 0;\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n float: left;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 3;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 3;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .badge {\n transition: none;\n }\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\na.badge-primary:focus, a.badge-primary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\na.badge-secondary:focus, a.badge-secondary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\na.badge-success:focus, a.badge-success.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\na.badge-info:focus, a.badge-info.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\na.badge-warning:focus, a.badge-warning.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\na.badge-danger:focus, a.badge-danger.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\na.badge-light:focus, a.badge-light.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\na.badge-dark:focus, a.badge-dark.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n line-height: 0;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: 1s linear infinite progress-bar-stripes;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n animation: none;\n }\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n border-radius: 0.25rem;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n\n.list-group-item:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-item + .list-group-item {\n border-top-width: 0;\n}\n\n.list-group-item + .list-group-item.active {\n margin-top: -1px;\n border-top-width: 1px;\n}\n\n.list-group-horizontal {\n flex-direction: row;\n}\n\n.list-group-horizontal > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n}\n\n.list-group-horizontal > .list-group-item.active {\n margin-top: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n}\n\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n flex-direction: row;\n }\n .list-group-horizontal-sm > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n flex-direction: row;\n }\n .list-group-horizontal-md > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n flex-direction: row;\n }\n .list-group-horizontal-lg > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n flex-direction: row;\n }\n .list-group-horizontal-xl > .list-group-item:first-child {\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item:last-child {\n border-top-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item {\n border-top-width: 1px;\n border-left-width: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n margin-left: -1px;\n border-left-width: 1px;\n }\n}\n\n.list-group-flush {\n border-radius: 0;\n}\n\n.list-group-flush > .list-group-item {\n border-width: 0 0 1px;\n}\n\n.list-group-flush > .list-group-item:last-child {\n border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n flex-basis: 350px;\n max-width: 350px;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n opacity: 0;\n border-radius: 0.25rem;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -50px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n transform: none;\n}\n\n.modal.modal-static .modal-dialog {\n transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n display: flex;\n max-height: calc(100% - 1rem);\n}\n\n.modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 1rem);\n overflow: hidden;\n}\n\n.modal-dialog-scrollable .modal-header,\n.modal-dialog-scrollable .modal-footer {\n flex-shrink: 0;\n}\n\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - 1rem);\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - 1rem);\n height: min-content;\n content: \"\";\n}\n\n.modal-dialog-centered.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable .modal-content {\n max-height: none;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable::before {\n content: none;\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #dee2e6;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n padding: 0.75rem;\n border-top: 1px solid #dee2e6;\n border-bottom-right-radius: calc(0.3rem - 1px);\n border-bottom-left-radius: calc(0.3rem - 1px);\n}\n\n.modal-footer > * {\n margin: 0.25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-scrollable {\n max-height: calc(100% - 3.5rem);\n }\n .modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 3.5rem);\n }\n .modal-dialog-centered {\n min-height: calc(100% - 3.5rem);\n }\n .modal-dialog-centered::before {\n height: calc(100vh - 3.5rem);\n height: min-content;\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=\"top\"] > .arrow {\n bottom: calc(-0.5rem - 1px);\n}\n\n.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=\"top\"] > .arrow::before {\n bottom: 0;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=\"top\"] > .arrow::after {\n bottom: 1px;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=\"right\"] > .arrow {\n left: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=\"right\"] > .arrow::before {\n left: 0;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=\"right\"] > .arrow::after {\n left: 1px;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow {\n top: calc(-0.5rem - 1px);\n}\n\n.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::before {\n top: 0;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::after {\n top: 1px;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=\"left\"] > .arrow {\n right: calc(-0.5rem - 1px);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=\"left\"] > .arrow::before {\n right: 0;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=\"left\"] > .arrow::after {\n right: 1px;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n transition: transform 0.6s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: opacity 0s 0.6s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: 50% / 100% 100% no-repeat;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@keyframes spinner-border {\n to {\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: .75s linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n animation: .75s linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .spinner-border,\n .spinner-grow {\n animation-duration: 1.5s;\n }\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded-sm {\n border-radius: 0.2rem !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-lg {\n border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.user-select-all {\n user-select: all !important;\n}\n\n.user-select-auto {\n user-select: auto !important;\n}\n\n.user-select-none {\n user-select: none !important;\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n pointer-events: auto;\n content: \"\";\n background-color: rgba(0, 0, 0, 0);\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !important;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-break {\n word-break: break-word !important;\n word-wrap: break-word !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover() {\n &:hover { @content; }\n}\n\n@mixin hover-focus() {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus() {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active() {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { @include font-size($h1-font-size); }\nh2, .h2 { @include font-size($h2-font-size); }\nh3, .h3 { @include font-size($h3-font-size); }\nh4, .h4 { @include font-size($h4-font-size); }\nh5, .h5 { @include font-size($h5-font-size); }\nh6, .h6 { @include font-size($h6-font-size); }\n\n.lead {\n @include font-size($lead-font-size);\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n @include font-size($display1-size);\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n @include font-size($display2-size);\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n @include font-size($display3-size);\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n @include font-size($display4-size);\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n @include font-size($small-font-size);\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled();\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled();\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n @include font-size(90%);\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n @include font-size($blockquote-font-size);\n}\n\n.blockquote-footer {\n display: block;\n @include font-size($blockquote-small-font-size);\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014\\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled() {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid();\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid();\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: $spacer / 2;\n line-height: 1;\n}\n\n.figure-caption {\n @include font-size($figure-caption-font-size);\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid() {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n @include deprecate(\"`img-retina()`\", \"v4.3.0\", \"v5\");\n}\n","// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n $return: ();\n @each $value in $radius {\n @if type-of($value) == number {\n $return: append($return, max($value, 0));\n } @else {\n $return: append($return, $value);\n }\n }\n @return $return;\n}\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: valid-radius($radius);\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n","// Inline code\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n @include font-size(100%);\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n\n\n// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @if $columns > 0 {\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n }\n\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n @if $columns > 0 {\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n margin-bottom: $spacer;\n color: $table-color;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: 2 * $table-border-width;\n }\n }\n}\n\n.table-borderless {\n th,\n td,\n thead th,\n tbody + tbody {\n border: 0;\n }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover() {\n color: $table-hover-color;\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover() {\n color: $table-dark-hover-color;\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background, $border: null) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n\n @if $border != null {\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $border;\n }\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover() {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n height: $input-height;\n padding: $input-padding-y $input-padding-x;\n font-family: $input-font-family;\n @include font-size($input-font-size);\n font-weight: $input-font-weight;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n @include border-radius($input-border-radius, 0);\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n background-color: transparent;\n border: 0;\n }\n\n // Remove select outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $input-color;\n }\n\n // Customize the `:focus` state to imitate native WebKit styles.\n @include form-control-focus($ignore-warning: true);\n\n // Placeholder\n &::placeholder {\n color: $input-placeholder-color;\n // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n opacity: 1;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &:disabled,\n &[readonly] {\n background-color: $input-disabled-bg;\n // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n opacity: 1;\n }\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n &.form-control {\n appearance: none; // Fix appearance for date inputs in Safari\n }\n}\n\nselect.form-control {\n &:focus::-ms-value {\n // Suppress the nested default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: add($input-padding-y, $input-border-width);\n padding-bottom: add($input-padding-y, $input-border-width);\n margin-bottom: 0; // Override the `<label>/<legend>` default\n @include font-size(inherit); // Override the `<legend>` default\n line-height: $input-line-height;\n}\n\n.col-form-label-lg {\n padding-top: add($input-padding-y-lg, $input-border-width);\n padding-bottom: add($input-padding-y-lg, $input-border-width);\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n}\n\n.col-form-label-sm {\n padding-top: add($input-padding-y-sm, $input-border-width);\n padding-bottom: add($input-padding-y-sm, $input-border-width);\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n}\n\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: $input-padding-y 0;\n margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n @include font-size($input-font-size);\n line-height: $input-line-height;\n color: $input-plaintext-color;\n background-color: transparent;\n border: solid transparent;\n border-width: $input-border-width 0;\n\n &.form-control-sm,\n &.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n height: $input-height-sm;\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.form-control-lg {\n height: $input-height-lg;\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n// stylelint-disable-next-line no-duplicate-selectors\nselect.form-control {\n &[size],\n &[multiple] {\n height: auto;\n }\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: $form-group-margin-bottom;\n}\n\n.form-text {\n display: block;\n margin-top: $form-text-margin-top;\n}\n\n\n// Form grid\n//\n// Special replacement for our grid system's `.row` for tighter form layouts.\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$form-grid-gutter-width / 2;\n margin-left: -$form-grid-gutter-width / 2;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: $form-grid-gutter-width / 2;\n padding-left: $form-grid-gutter-width / 2;\n }\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.form-check {\n position: relative;\n display: block;\n padding-left: $form-check-input-gutter;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: $form-check-input-margin-y;\n margin-left: -$form-check-input-gutter;\n\n // Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .form-check-label,\n &:disabled ~ .form-check-label {\n color: $text-muted;\n }\n}\n\n.form-check-label {\n margin-bottom: 0; // Override default `<label>` bottom margin\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0; // Override base .form-check\n margin-right: $form-check-inline-margin-x;\n\n // Undo .form-check-input defaults and add some `margin-right`.\n .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: $form-check-inline-input-margin-x;\n margin-left: 0;\n }\n}\n\n\n// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server side validation.\n\n@each $state, $data in $form-validation-states {\n @include form-validation-state($state, map-get($data, color), map-get($data, icon));\n}\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)\n\n // Because we use flex, the initial sizing of checkboxes is collapsed and\n // doesn't occupy the full-width (which is what we want for xs grid tier),\n // so we force that here.\n .form-check {\n width: 100%;\n }\n\n // Kick in the inline\n @include media-breakpoint-up(sm) {\n label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n\n // Inline-block all the things for \"inline\"\n .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n\n // Allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-plaintext {\n display: inline-block;\n }\n\n .input-group,\n .custom-select {\n width: auto;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: $form-check-input-margin-x;\n margin-left: 0;\n }\n\n .custom-control {\n align-items: center;\n justify-content: center;\n }\n .custom-control-label {\n margin-bottom: 0;\n }\n }\n}\n","// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n @if length($transition) == 0 {\n $transition: $transition-base;\n }\n\n @if length($transition) > 1 {\n @each $value in $transition {\n @if $value == null or $value == none {\n @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n }\n }\n }\n\n @if $enable-transitions {\n @if nth($transition, 1) != null {\n transition: $transition;\n }\n\n @if $enable-prefers-reduced-motion-media-query and nth($transition, 1) != null and nth($transition, 1) != none {\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n }\n}\n","// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `$input-focus-border-color` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n@mixin form-control-focus($ignore-warning: false) {\n &:focus {\n color: $input-focus-color;\n background-color: $input-focus-bg;\n border-color: $input-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($input-box-shadow, $input-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $input-focus-box-shadow;\n }\n }\n @include deprecate(\"The `form-control-focus()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n// This mixin uses an `if()` technique to be compatible with Dart Sass\n// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details\n@mixin form-validation-state-selector($state) {\n @if ($state == \"valid\" or $state == \"invalid\") {\n .was-validated #{if(&, \"&\", \"\")}:#{$state},\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n } @else {\n #{if(&, \"&\", \"\")}.is-#{$state} {\n @content;\n }\n }\n}\n\n@mixin form-validation-state($state, $color, $icon) {\n .#{$state}-feedback {\n display: none;\n width: 100%;\n margin-top: $form-feedback-margin-top;\n @include font-size($form-feedback-font-size);\n color: $color;\n }\n\n .#{$state}-tooltip {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 5;\n display: none;\n max-width: 100%; // Contain to parent when possible\n padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n margin-top: .1rem;\n @include font-size($form-feedback-tooltip-font-size);\n line-height: $form-feedback-tooltip-line-height;\n color: color-yiq($color);\n background-color: rgba($color, $form-feedback-tooltip-opacity);\n @include border-radius($form-feedback-tooltip-border-radius);\n\n // See https://github.com/twbs/bootstrap/pull/31557\n // Align tooltip to form elements\n .form-row > .col > &,\n .form-row > [class*=\"col-\"] > & {\n left: $form-grid-gutter-width / 2;\n }\n }\n\n @include form-validation-state-selector($state) {\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n\n .form-control {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-image: escape-svg($icon);\n background-repeat: no-repeat;\n background-position: right $input-height-inner-quarter center;\n background-size: $input-height-inner-half $input-height-inner-half;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n // stylelint-disable-next-line selector-no-qualifying-type\n textarea.form-control {\n @include form-validation-state-selector($state) {\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n }\n }\n }\n\n .custom-select {\n @include form-validation-state-selector($state) {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $custom-select-feedback-icon-padding-right;\n background: $custom-select-background, $custom-select-bg escape-svg($icon) $custom-select-feedback-icon-position / $custom-select-feedback-icon-size no-repeat;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n\n .form-check-input {\n @include form-validation-state-selector($state) {\n ~ .form-check-label {\n color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .custom-control-input {\n @include form-validation-state-selector($state) {\n ~ .custom-control-label {\n color: $color;\n\n &::before {\n border-color: $color;\n }\n }\n\n &:checked {\n ~ .custom-control-label::before {\n border-color: lighten($color, 10%);\n @include gradient-bg(lighten($color, 10%));\n }\n }\n\n &:focus {\n ~ .custom-control-label::before {\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n &:not(:checked) ~ .custom-control-label::before {\n border-color: $color;\n }\n }\n }\n }\n\n // custom file\n .custom-file-input {\n @include form-validation-state-selector($state) {\n ~ .custom-file-label {\n border-color: $color;\n }\n\n &:focus {\n ~ .custom-file-label {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.btn {\n display: inline-block;\n font-family: $btn-font-family;\n font-weight: $btn-font-weight;\n color: $body-color;\n text-align: center;\n text-decoration: if($link-decoration == none, null, none);\n white-space: $btn-white-space;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: $btn-border-width solid transparent;\n @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);\n @include transition($btn-transition);\n\n @include hover() {\n color: $body-color;\n text-decoration: none;\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: $btn-focus-box-shadow;\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n opacity: $btn-disabled-opacity;\n @include box-shadow(none);\n }\n\n &:not(:disabled):not(.disabled) {\n cursor: if($enable-pointer-cursor-for-buttons, pointer, null);\n\n &:active,\n &.active {\n @include box-shadow($btn-active-box-shadow);\n\n &:focus {\n @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n }\n }\n }\n}\n\n// Future-proof disabling of clicks on `<a>` elements\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n\n//\n// Alternate buttons\n//\n\n@each $color, $value in $theme-colors {\n .btn-#{$color} {\n @include button-variant($value, $value);\n }\n}\n\n@each $color, $value in $theme-colors {\n .btn-outline-#{$color} {\n @include button-outline-variant($value);\n }\n}\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n font-weight: $font-weight-normal;\n color: $link-color;\n text-decoration: $link-decoration;\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n\n &:focus,\n &.focus {\n text-decoration: $link-hover-decoration;\n }\n\n &:disabled,\n &.disabled {\n color: $btn-link-disabled-color;\n pointer-events: none;\n }\n\n // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);\n}\n\n\n//\n// Block button\n//\n\n.btn-block {\n display: block;\n width: 100%;\n\n // Vertically space out multiple block buttons\n + .btn-block {\n margin-top: $btn-block-spacing-y;\n }\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {\n color: color-yiq($background);\n @include gradient-bg($background);\n border-color: $border;\n @include box-shadow($btn-box-shadow);\n\n @include hover() {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n }\n\n &:focus,\n &.focus {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n @if $enable-shadows {\n @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n color: color-yiq($background);\n background-color: $background;\n border-color: $border;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n @if $enable-gradients {\n background-image: none; // Remove the gradient for the pressed/active state\n }\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n }\n}\n\n@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {\n color: $color;\n border-color: $color;\n\n @include hover() {\n color: $color-hover;\n background-color: $active-background;\n border-color: $active-border;\n }\n\n &:focus,\n &.focus {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n\n &.disabled,\n &:disabled {\n color: $color;\n background-color: transparent;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n border-color: $active-border;\n\n &:focus {\n @if $enable-shadows and $btn-active-box-shadow != none {\n @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n }\n }\n}\n\n// Button sizes\n@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n // Manually declare to provide an override to the browser default\n @include border-radius($border-radius, 0);\n}\n",".fade {\n @include transition($transition-fade);\n\n &:not(.show) {\n opacity: 0;\n }\n}\n\n.collapse {\n &:not(.show) {\n display: none;\n }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n @include transition($transition-collapse);\n}\n","// The dropdown wrapper (`<div>`)\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n\n // Generate the caret automatically\n @include caret();\n}\n\n// The dropdown menu\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: $zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: $dropdown-min-width;\n padding: $dropdown-padding-y $dropdown-padding-x;\n margin: $dropdown-spacer 0 0; // override default ul\n @include font-size($dropdown-font-size);\n color: $dropdown-color;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n list-style: none;\n background-color: $dropdown-bg;\n background-clip: padding-box;\n border: $dropdown-border-width solid $dropdown-border-color;\n @include border-radius($dropdown-border-radius);\n @include box-shadow($dropdown-box-shadow);\n}\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .dropdown-menu#{$infix}-left {\n right: auto;\n left: 0;\n }\n\n .dropdown-menu#{$infix}-right {\n right: 0;\n left: auto;\n }\n }\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(up);\n }\n}\n\n.dropright {\n .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(right);\n &::after {\n vertical-align: 0;\n }\n }\n}\n\n.dropleft {\n .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(left);\n &::before {\n vertical-align: 0;\n }\n }\n}\n\n// When Popper is enabled, reset the basic dropdown position\n// stylelint-disable-next-line no-duplicate-selectors\n.dropdown-menu {\n &[x-placement^=\"top\"],\n &[x-placement^=\"right\"],\n &[x-placement^=\"bottom\"],\n &[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n }\n}\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n @include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n display: block;\n width: 100%; // For `<button>`s\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n clear: both;\n font-weight: $font-weight-normal;\n color: $dropdown-link-color;\n text-align: inherit; // For `<button>`s\n text-decoration: if($link-decoration == none, null, none);\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n background-color: transparent; // For `<button>`s\n border: 0; // For `<button>`s\n\n // Prevent dropdown overflow if there's no padding\n // See https://github.com/twbs/bootstrap/pull/27703\n @if $dropdown-padding-y == 0 {\n &:first-child {\n @include border-top-radius($dropdown-inner-border-radius);\n }\n\n &:last-child {\n @include border-bottom-radius($dropdown-inner-border-radius);\n }\n }\n\n @include hover-focus() {\n color: $dropdown-link-hover-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-hover-bg);\n }\n\n &.active,\n &:active {\n color: $dropdown-link-active-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-active-bg);\n }\n\n &.disabled,\n &:disabled {\n color: $dropdown-link-disabled-color;\n pointer-events: none;\n background-color: transparent;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: $dropdown-header-padding;\n margin-bottom: 0; // for use with heading elements\n @include font-size($font-size-sm);\n color: $dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n display: block;\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n color: $dropdown-link-color;\n}\n","@mixin caret-down() {\n border-top: $caret-width solid;\n border-right: $caret-width solid transparent;\n border-bottom: 0;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up() {\n border-top: 0;\n border-right: $caret-width solid transparent;\n border-bottom: $caret-width solid;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-right() {\n border-top: $caret-width solid transparent;\n border-right: 0;\n border-bottom: $caret-width solid transparent;\n border-left: $caret-width solid;\n}\n\n@mixin caret-left() {\n border-top: $caret-width solid transparent;\n border-right: $caret-width solid;\n border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n @if $enable-caret {\n &::after {\n display: inline-block;\n margin-left: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @if $direction == down {\n @include caret-down();\n } @else if $direction == up {\n @include caret-up();\n } @else if $direction == right {\n @include caret-right();\n }\n }\n\n @if $direction == left {\n &::after {\n display: none;\n }\n\n &::before {\n display: inline-block;\n margin-right: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @include caret-left();\n }\n }\n\n &:empty::after {\n margin-left: 0;\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y, $ignore-warning: false) {\n height: 0;\n margin: $margin-y 0;\n overflow: hidden;\n border-top: 1px solid $color;\n @include deprecate(\"The `nav-divider()` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle; // match .btn alignment given font-size hack above\n\n > .btn {\n position: relative;\n flex: 1 1 auto;\n\n // Bring the hover, focused, and \"active\" buttons to the front to overlay\n // the borders properly\n @include hover() {\n z-index: 1;\n }\n &:focus,\n &:active,\n &.active {\n z-index: 1;\n }\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n\n .input-group {\n width: auto;\n }\n}\n\n.btn-group {\n // Prevent double borders when buttons are next to each other\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-left: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-right-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-left-radius(0);\n }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n padding-right: $btn-padding-x * .75;\n padding-left: $btn-padding-x * .75;\n\n &::after,\n .dropup &::after,\n .dropright &::after {\n margin-left: 0;\n }\n\n .dropleft &::before {\n margin-right: 0;\n }\n}\n\n.btn-sm + .dropdown-toggle-split {\n padding-right: $btn-padding-x-sm * .75;\n padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n padding-right: $btn-padding-x-lg * .75;\n padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n @include box-shadow($btn-active-box-shadow);\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n @include box-shadow(none);\n }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n\n > .btn,\n > .btn-group {\n width: 100%;\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-top: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-bottom-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-top-radius(0);\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n.btn-group-toggle {\n > .btn,\n > .btn-group > .btn {\n margin-bottom: 0; // Override default `<label>` value\n\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap; // For form validation feedback\n align-items: stretch;\n width: 100%;\n\n > .form-control,\n > .form-control-plaintext,\n > .custom-select,\n > .custom-file {\n position: relative; // For focus state's z-index\n flex: 1 1 auto;\n width: 1%;\n min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size\n margin-bottom: 0;\n\n + .form-control,\n + .custom-select,\n + .custom-file {\n margin-left: -$input-border-width;\n }\n }\n\n // Bring the \"active\" form control to the top of surrounding elements\n > .form-control:focus,\n > .custom-select:focus,\n > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n }\n\n // Bring the custom file input above the label\n > .custom-file .custom-file-input:focus {\n z-index: 4;\n }\n\n > .form-control,\n > .custom-select {\n &:not(:first-child) { @include border-left-radius(0); }\n }\n\n // Custom file inputs have more complex markup, thus requiring different\n // border-radius overrides.\n > .custom-file {\n display: flex;\n align-items: center;\n\n &:not(:last-child) .custom-file-label,\n &:not(:first-child) .custom-file-label { @include border-left-radius(0); }\n }\n\n &:not(.has-validation) {\n > .form-control:not(:last-child),\n > .custom-select:not(:last-child),\n > .custom-file:not(:last-child) .custom-file-label::after {\n @include border-right-radius(0);\n }\n }\n\n &.has-validation {\n > .form-control:nth-last-child(n + 3),\n > .custom-select:nth-last-child(n + 3),\n > .custom-file:nth-last-child(n + 3) .custom-file-label::after {\n @include border-right-radius(0);\n }\n }\n}\n\n\n// Prepend and append\n//\n// While it requires one extra layer of HTML for each, dedicated prepend and\n// append elements allow us to 1) be less clever, 2) simplify our selectors, and\n// 3) support HTML5 form validation.\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n\n // Ensure buttons are always above inputs for more visually pleasing borders.\n // This isn't needed for `.input-group-text` since it shares the same border-color\n // as our inputs.\n .btn {\n position: relative;\n z-index: 2;\n\n &:focus {\n z-index: 3;\n }\n }\n\n .btn + .btn,\n .btn + .input-group-text,\n .input-group-text + .input-group-text,\n .input-group-text + .btn {\n margin-left: -$input-border-width;\n }\n}\n\n.input-group-prepend { margin-right: -$input-border-width; }\n.input-group-append { margin-left: -$input-border-width; }\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: $input-padding-y $input-padding-x;\n margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom\n @include font-size($input-font-size); // Match inputs\n font-weight: $font-weight-normal;\n line-height: $input-line-height;\n color: $input-group-addon-color;\n text-align: center;\n white-space: nowrap;\n background-color: $input-group-addon-bg;\n border: $input-border-width solid $input-group-addon-border-color;\n @include border-radius($input-border-radius);\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: $input-height-lg;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: $input-height-sm;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: $custom-select-padding-x + $custom-select-indicator-padding;\n}\n\n\n// Prepend and append rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,\n.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,\n.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n @include border-right-radius(0);\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n @include border-left-radius(0);\n}\n","// Embedded icons from Open Iconic.\n// Released under MIT and copyright 2014 Waybury.\n// https://useiconic.com/open\n\n\n// Checkboxes and radios\n//\n// Base class takes care of all the key behavioral aspects.\n\n.custom-control {\n position: relative;\n z-index: 1;\n display: block;\n min-height: $font-size-base * $line-height-base;\n padding-left: $custom-control-gutter + $custom-control-indicator-size;\n color-adjust: exact; // Keep themed appearance for print\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: $custom-control-spacer-x;\n}\n\n.custom-control-input {\n position: absolute;\n left: 0;\n z-index: -1; // Put the input behind the label so it doesn't overlay text\n width: $custom-control-indicator-size;\n height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;\n opacity: 0;\n\n &:checked ~ .custom-control-label::before {\n color: $custom-control-indicator-checked-color;\n border-color: $custom-control-indicator-checked-border-color;\n @include gradient-bg($custom-control-indicator-checked-bg);\n @include box-shadow($custom-control-indicator-checked-box-shadow);\n }\n\n &:focus ~ .custom-control-label::before {\n // the mixin is not used here to make sure there is feedback\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $custom-control-indicator-focus-box-shadow;\n } @else {\n box-shadow: $custom-control-indicator-focus-box-shadow;\n }\n }\n\n &:focus:not(:checked) ~ .custom-control-label::before {\n border-color: $custom-control-indicator-focus-border-color;\n }\n\n &:not(:disabled):active ~ .custom-control-label::before {\n color: $custom-control-indicator-active-color;\n background-color: $custom-control-indicator-active-bg;\n border-color: $custom-control-indicator-active-border-color;\n @include box-shadow($custom-control-indicator-active-box-shadow);\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled],\n &:disabled {\n ~ .custom-control-label {\n color: $custom-control-label-disabled-color;\n\n &::before {\n background-color: $custom-control-indicator-disabled-bg;\n }\n }\n }\n}\n\n// Custom control indicators\n//\n// Build the custom controls out of pseudo-elements.\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n color: $custom-control-label-color;\n vertical-align: top;\n cursor: $custom-control-cursor;\n\n // Background-color and (when enabled) gradient\n &::before {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n pointer-events: none;\n content: \"\";\n background-color: $custom-control-indicator-bg;\n border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;\n @include box-shadow($custom-control-indicator-box-shadow);\n }\n\n // Foreground (icon)\n &::after {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n content: \"\";\n background: 50% / #{$custom-control-indicator-bg-size} no-repeat;\n }\n}\n\n\n// Checkboxes\n//\n// Tweak just a few things for checkboxes.\n\n.custom-checkbox {\n .custom-control-label::before {\n @include border-radius($custom-checkbox-indicator-border-radius);\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-checked);\n }\n }\n\n .custom-control-input:indeterminate ~ .custom-control-label {\n &::before {\n border-color: $custom-checkbox-indicator-indeterminate-border-color;\n @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);\n @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);\n }\n &::after {\n background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n &:indeterminate ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n// Radios\n//\n// Tweak just a few things for radios.\n\n.custom-radio {\n .custom-control-label::before {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-radio-indicator-border-radius;\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: escape-svg($custom-radio-indicator-icon-checked);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// switches\n//\n// Tweak a few things for switches\n\n.custom-switch {\n padding-left: $custom-switch-width + $custom-control-gutter;\n\n .custom-control-label {\n &::before {\n left: -($custom-switch-width + $custom-control-gutter);\n width: $custom-switch-width;\n pointer-events: all;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n }\n\n &::after {\n top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);\n left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);\n width: $custom-switch-indicator-size;\n height: $custom-switch-indicator-size;\n background-color: $custom-control-indicator-border-color;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: $custom-switch-indicator-border-radius;\n @include transition(transform .15s ease-in-out, $custom-forms-transition);\n }\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-color: $custom-control-indicator-bg;\n transform: translateX($custom-switch-width - $custom-control-indicator-size);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n @include gradient-bg($custom-control-indicator-checked-disabled-bg);\n }\n }\n}\n\n\n// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n//\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: $custom-select-height;\n padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;\n font-family: $custom-select-font-family;\n @include font-size($custom-select-font-size);\n font-weight: $custom-select-font-weight;\n line-height: $custom-select-line-height;\n color: $custom-select-color;\n vertical-align: middle;\n background: $custom-select-bg $custom-select-background;\n border: $custom-select-border-width solid $custom-select-border-color;\n @include border-radius($custom-select-border-radius, 0);\n @include box-shadow($custom-select-box-shadow);\n appearance: none;\n\n &:focus {\n border-color: $custom-select-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n @include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);\n } @else {\n // Avoid using mixin so we can pass custom focus shadow properly\n box-shadow: $custom-select-focus-box-shadow;\n }\n\n &::-ms-value {\n // For visual consistency with other platforms/browsers,\n // suppress the default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n }\n\n &[multiple],\n &[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: $custom-select-padding-x;\n background-image: none;\n }\n\n &:disabled {\n color: $custom-select-disabled-color;\n background-color: $custom-select-disabled-bg;\n }\n\n // Hides the default caret in IE11\n &::-ms-expand {\n display: none;\n }\n\n // Remove outline from select box in FF\n &:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 $custom-select-color;\n }\n}\n\n.custom-select-sm {\n height: $custom-select-height-sm;\n padding-top: $custom-select-padding-y-sm;\n padding-bottom: $custom-select-padding-y-sm;\n padding-left: $custom-select-padding-x-sm;\n @include font-size($custom-select-font-size-sm);\n}\n\n.custom-select-lg {\n height: $custom-select-height-lg;\n padding-top: $custom-select-padding-y-lg;\n padding-bottom: $custom-select-padding-y-lg;\n padding-left: $custom-select-padding-x-lg;\n @include font-size($custom-select-font-size-lg);\n}\n\n\n// File\n//\n// Custom file input.\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: $custom-file-height;\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: $custom-file-height;\n margin: 0;\n overflow: hidden;\n opacity: 0;\n\n &:focus ~ .custom-file-label {\n border-color: $custom-file-focus-border-color;\n box-shadow: $custom-file-focus-box-shadow;\n }\n\n // Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247\n &[disabled] ~ .custom-file-label,\n &:disabled ~ .custom-file-label {\n background-color: $custom-file-disabled-bg;\n }\n\n @each $lang, $value in $custom-file-text {\n &:lang(#{$lang}) ~ .custom-file-label::after {\n content: $value;\n }\n }\n\n ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n }\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: $custom-file-height;\n padding: $custom-file-padding-y $custom-file-padding-x;\n overflow: hidden;\n font-family: $custom-file-font-family;\n font-weight: $custom-file-font-weight;\n line-height: $custom-file-line-height;\n color: $custom-file-color;\n background-color: $custom-file-bg;\n border: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius($custom-file-border-radius);\n @include box-shadow($custom-file-box-shadow);\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: $custom-file-height-inner;\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-button-color;\n content: \"Browse\";\n @include gradient-bg($custom-file-button-bg);\n border-left: inherit;\n @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);\n }\n}\n\n// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.custom-range {\n width: 100%;\n height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);\n padding: 0; // Need to reset padding\n background-color: transparent;\n appearance: none;\n\n &:focus {\n outline: 0;\n\n // Pseudo-elements must be split across multiple rulesets to have an effect.\n // No box-shadow() mixin for focus accessibility.\n &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n }\n\n &::-moz-focus-outer {\n border: 0;\n }\n\n &::-webkit-slider-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-webkit-slider-runnable-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent; // Why?\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent;\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-moz-range-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-moz-range-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent; // Firefox specific?\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: 0; // Edge specific\n margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-ms-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: transparent;\n border-color: transparent;\n border-width: $custom-range-thumb-height / 2;\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-fill-lower {\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &::-ms-fill-upper {\n margin-right: 15px; // arbitrary?\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &:disabled {\n &::-webkit-slider-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-webkit-slider-runnable-track {\n cursor: default;\n }\n\n &::-moz-range-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-moz-range-track {\n cursor: default;\n }\n\n &::-ms-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n }\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n @include transition($custom-forms-transition);\n}\n","// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s, `<ul>`s or `<ol>`s.\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: $nav-link-padding-y $nav-link-padding-x;\n text-decoration: if($link-decoration == none, null, none);\n\n @include hover-focus() {\n text-decoration: none;\n }\n\n // Disabled state lightens text\n &.disabled {\n color: $nav-link-disabled-color;\n pointer-events: none;\n cursor: default;\n }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n .nav-link {\n margin-bottom: -$nav-tabs-border-width;\n border: $nav-tabs-border-width solid transparent;\n @include border-top-radius($nav-tabs-border-radius);\n\n @include hover-focus() {\n border-color: $nav-tabs-link-hover-border-color;\n }\n\n &.disabled {\n color: $nav-link-disabled-color;\n background-color: transparent;\n border-color: transparent;\n }\n }\n\n .nav-link.active,\n .nav-item.show .nav-link {\n color: $nav-tabs-link-active-color;\n background-color: $nav-tabs-link-active-bg;\n border-color: $nav-tabs-link-active-border-color;\n }\n\n .dropdown-menu {\n // Make dropdown border overlap tab border\n margin-top: -$nav-tabs-border-width;\n // Remove the top rounded corners here since there is a hard edge above the menu\n @include border-top-radius(0);\n }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n .nav-link {\n @include border-radius($nav-pills-border-radius);\n }\n\n .nav-link.active,\n .show > .nav-link {\n color: $nav-pills-link-active-color;\n background-color: $nav-pills-link-active-bg;\n }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n > .nav-link,\n .nav-item {\n flex: 1 1 auto;\n text-align: center;\n }\n}\n\n.nav-justified {\n > .nav-link,\n .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n","// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Navbar divider\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap; // allow us to do the line break for collapsing content\n align-items: center;\n justify-content: space-between; // space out brand from logo\n padding: $navbar-padding-y $navbar-padding-x;\n\n // Because flex properties aren't inherited, we need to redeclare these first\n // few properties so that content nested within behave properly.\n %container-flex-properties {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n }\n\n .container,\n .container-fluid {\n @extend %container-flex-properties;\n }\n\n @each $breakpoint, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {\n @extend %container-flex-properties;\n }\n }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n display: inline-block;\n padding-top: $navbar-brand-padding-y;\n padding-bottom: $navbar-brand-padding-y;\n margin-right: $navbar-padding-x;\n @include font-size($navbar-brand-font-size);\n line-height: inherit;\n white-space: nowrap;\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n display: flex;\n flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n\n .nav-link {\n padding-right: 0;\n padding-left: 0;\n }\n\n .dropdown-menu {\n position: static;\n float: none;\n }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n display: inline-block;\n padding-top: $nav-link-padding-y;\n padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n // For always expanded or extra full navbars, ensure content aligns itself\n // properly vertically. Can be easily overridden with flex utilities.\n align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n @include font-size($navbar-toggler-font-size);\n line-height: 1;\n background-color: transparent; // remove default button style\n border: $border-width solid transparent; // remove default button style\n @include border-radius($navbar-toggler-border-radius);\n\n @include hover-focus() {\n text-decoration: none;\n }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: 50% / 100% 100% no-repeat;\n}\n\n.navbar-nav-scroll {\n max-height: $navbar-nav-scroll-max-height;\n overflow-y: auto;\n}\n\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n %container-navbar-expand-#{$breakpoint} {\n padding-right: 0;\n padding-left: 0;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-navbar-expand-#{$breakpoint};\n }\n }\n }\n\n @include media-breakpoint-up($next) {\n flex-flow: row nowrap;\n justify-content: flex-start;\n\n .navbar-nav {\n flex-direction: row;\n\n .dropdown-menu {\n position: absolute;\n }\n\n .nav-link {\n padding-right: $navbar-nav-link-padding-x;\n padding-left: $navbar-nav-link-padding-x;\n }\n }\n\n // For nesting containers, have to redeclare for alignment purposes\n %container-nesting-#{$breakpoint} {\n flex-wrap: nowrap;\n }\n\n > .container,\n > .container-fluid {\n @extend %container-nesting-#{$breakpoint};\n }\n\n @each $size, $container-max-width in $container-max-widths {\n > .container#{breakpoint-infix($size, $container-max-widths)} {\n @extend %container-nesting-#{$breakpoint};\n }\n }\n\n .navbar-nav-scroll {\n overflow: visible;\n }\n\n .navbar-collapse {\n display: flex !important; // stylelint-disable-line declaration-no-important\n\n // Changes flex-bases to auto because of an IE10 bug\n flex-basis: auto;\n }\n\n .navbar-toggler {\n display: none;\n }\n }\n }\n }\n}\n\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n .navbar-brand {\n color: $navbar-light-brand-color;\n\n @include hover-focus() {\n color: $navbar-light-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-light-color;\n\n @include hover-focus() {\n color: $navbar-light-hover-color;\n }\n\n &.disabled {\n color: $navbar-light-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-light-color;\n border-color: $navbar-light-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-light-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-light-color;\n a {\n color: $navbar-light-active-color;\n\n @include hover-focus() {\n color: $navbar-light-active-color;\n }\n }\n }\n}\n\n// White links against a dark background\n.navbar-dark {\n .navbar-brand {\n color: $navbar-dark-brand-color;\n\n @include hover-focus() {\n color: $navbar-dark-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-dark-color;\n\n @include hover-focus() {\n color: $navbar-dark-hover-color;\n }\n\n &.disabled {\n color: $navbar-dark-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-dark-color;\n border-color: $navbar-dark-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: escape-svg($navbar-dark-toggler-icon-bg);\n }\n\n .navbar-text {\n color: $navbar-dark-color;\n a {\n color: $navbar-dark-active-color;\n\n @include hover-focus() {\n color: $navbar-dark-active-color;\n }\n }\n }\n}\n","//\n// Base styles\n//\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106\n height: $card-height;\n word-wrap: break-word;\n background-color: $card-bg;\n background-clip: border-box;\n border: $card-border-width solid $card-border-color;\n @include border-radius($card-border-radius);\n\n > hr {\n margin-right: 0;\n margin-left: 0;\n }\n\n > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n\n &:first-child {\n border-top-width: 0;\n @include border-top-radius($card-inner-border-radius);\n }\n\n &:last-child {\n border-bottom-width: 0;\n @include border-bottom-radius($card-inner-border-radius);\n }\n }\n\n // Due to specificity of the above selector (`.card > .list-group`), we must\n // use a child selector here to prevent double borders.\n > .card-header + .list-group,\n > .list-group + .card-footer {\n border-top: 0;\n }\n}\n\n.card-body {\n // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n // as much space as possible, ensuring footers are aligned to the bottom.\n flex: 1 1 auto;\n // Workaround for the image size bug in IE\n // See: https://github.com/twbs/bootstrap/pull/28855\n min-height: 1px;\n padding: $card-spacer-x;\n color: $card-color;\n}\n\n.card-title {\n margin-bottom: $card-spacer-y;\n}\n\n.card-subtitle {\n margin-top: -$card-spacer-y / 2;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link {\n @include hover() {\n text-decoration: none;\n }\n\n + .card-link {\n margin-left: $card-spacer-x;\n }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n padding: $card-spacer-y $card-spacer-x;\n margin-bottom: 0; // Removes the default margin-bottom of <hN>\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-bottom: $card-border-width solid $card-border-color;\n\n &:first-child {\n @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n }\n}\n\n.card-footer {\n padding: $card-spacer-y $card-spacer-x;\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-top: $card-border-width solid $card-border-color;\n\n &:last-child {\n @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n margin-right: -$card-spacer-x / 2;\n margin-bottom: -$card-spacer-y;\n margin-left: -$card-spacer-x / 2;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -$card-spacer-x / 2;\n margin-left: -$card-spacer-x / 2;\n}\n\n// Card image\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: $card-img-overlay-padding;\n @include border-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n}\n\n.card-img,\n.card-img-top {\n @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n// Card deck\n\n.card-deck {\n .card {\n margin-bottom: $card-deck-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n margin-right: -$card-deck-margin;\n margin-left: -$card-deck-margin;\n\n .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-right: $card-deck-margin;\n margin-bottom: 0; // Override the default\n margin-left: $card-deck-margin;\n }\n }\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n margin-bottom: $card-group-margin;\n }\n\n @include media-breakpoint-up(sm) {\n display: flex;\n flex-flow: row wrap;\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-bottom: 0;\n\n + .card {\n margin-left: 0;\n border-left: 0;\n }\n\n // Handle rounded corners\n @if $enable-rounded {\n &:not(:last-child) {\n @include border-right-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-right-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-right-radius: 0;\n }\n }\n\n &:not(:first-child) {\n @include border-left-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-disallowed-list\n border-top-left-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-disallowed-list\n border-bottom-left-radius: 0;\n }\n }\n }\n }\n }\n}\n\n\n//\n// Columns\n//\n\n.card-columns {\n .card {\n margin-bottom: $card-columns-margin;\n }\n\n @include media-breakpoint-up(sm) {\n column-count: $card-columns-count;\n column-gap: $card-columns-gap;\n orphans: 1;\n widows: 1;\n\n .card {\n display: inline-block; // Don't let them vertically span multiple columns\n width: 100%; // Don't let their width change\n }\n }\n}\n\n\n//\n// Accordion\n//\n\n.accordion {\n overflow-anchor: none;\n\n > .card {\n overflow: hidden;\n\n &:not(:last-of-type) {\n border-bottom: 0;\n @include border-bottom-radius(0);\n }\n\n &:not(:first-of-type) {\n @include border-top-radius(0);\n }\n\n > .card-header {\n @include border-radius(0);\n margin-bottom: -$card-border-width;\n }\n }\n}\n",".breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n margin-bottom: $breadcrumb-margin-bottom;\n @include font-size($breadcrumb-font-size);\n list-style: none;\n background-color: $breadcrumb-bg;\n @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n + .breadcrumb-item {\n padding-left: $breadcrumb-item-padding;\n\n &::before {\n float: left; // Suppress inline spacings and underlining of the separator\n padding-right: $breadcrumb-item-padding;\n color: $breadcrumb-divider-color;\n content: escape-svg($breadcrumb-divider);\n }\n }\n\n // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built\n // without `<ul>`s. The `::before` pseudo-element generates an element\n // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.\n //\n // To trick IE into suppressing the underline, we give the pseudo-element an\n // underline and then immediately remove it.\n + .breadcrumb-item:hover::before {\n text-decoration: underline;\n }\n // stylelint-disable-next-line no-duplicate-selectors\n + .breadcrumb-item:hover::before {\n text-decoration: none;\n }\n\n &.active {\n color: $breadcrumb-active-color;\n }\n}\n",".pagination {\n display: flex;\n @include list-unstyled();\n @include border-radius();\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: $pagination-padding-y $pagination-padding-x;\n margin-left: -$pagination-border-width;\n line-height: $pagination-line-height;\n color: $pagination-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $pagination-bg;\n border: $pagination-border-width solid $pagination-border-color;\n\n &:hover {\n z-index: 2;\n color: $pagination-hover-color;\n text-decoration: none;\n background-color: $pagination-hover-bg;\n border-color: $pagination-hover-border-color;\n }\n\n &:focus {\n z-index: 3;\n outline: $pagination-focus-outline;\n box-shadow: $pagination-focus-box-shadow;\n }\n}\n\n.page-item {\n &:first-child {\n .page-link {\n margin-left: 0;\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n\n &.active .page-link {\n z-index: 3;\n color: $pagination-active-color;\n background-color: $pagination-active-bg;\n border-color: $pagination-active-border-color;\n }\n\n &.disabled .page-link {\n color: $pagination-disabled-color;\n pointer-events: none;\n // Opinionated: remove the \"hand\" cursor set previously for .page-link\n cursor: auto;\n background-color: $pagination-disabled-bg;\n border-color: $pagination-disabled-border-color;\n }\n}\n\n\n//\n// Sizing\n//\n\n.pagination-lg {\n @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $pagination-border-radius-lg);\n}\n\n.pagination-sm {\n @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $pagination-border-radius-sm);\n}\n","// Pagination\n\n@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n .page-link {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n }\n\n .page-item {\n &:first-child {\n .page-link {\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n }\n}\n","// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n display: inline-block;\n padding: $badge-padding-y $badge-padding-x;\n @include font-size($badge-font-size);\n font-weight: $badge-font-weight;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n @include border-radius($badge-border-radius);\n @include transition($badge-transition);\n\n @at-root a#{&} {\n @include hover-focus() {\n text-decoration: none;\n }\n }\n\n // Empty badges collapse automatically\n &:empty {\n display: none;\n }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Pill badges\n//\n// Make them extra rounded with a modifier to replace v3's badges.\n\n.badge-pill {\n padding-right: $badge-pill-padding-x;\n padding-left: $badge-pill-padding-x;\n @include border-radius($badge-pill-border-radius);\n}\n\n// Colors\n//\n// Contextual variations (linked badges get darker on :hover).\n\n@each $color, $value in $theme-colors {\n .badge-#{$color} {\n @include badge-variant($value);\n }\n}\n","@mixin badge-variant($bg) {\n color: color-yiq($bg);\n background-color: $bg;\n\n @at-root a#{&} {\n @include hover-focus() {\n color: color-yiq($bg);\n background-color: darken($bg, 10%);\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);\n }\n }\n}\n",".jumbotron {\n padding: $jumbotron-padding ($jumbotron-padding / 2);\n margin-bottom: $jumbotron-padding;\n color: $jumbotron-color;\n background-color: $jumbotron-bg;\n @include border-radius($border-radius-lg);\n\n @include media-breakpoint-up(sm) {\n padding: ($jumbotron-padding * 2) $jumbotron-padding;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n @include border-radius(0);\n}\n","//\n// Base styles\n//\n\n.alert {\n position: relative;\n padding: $alert-padding-y $alert-padding-x;\n margin-bottom: $alert-margin-bottom;\n border: $alert-border-width solid transparent;\n @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n // Specified to prevent conflicts of changing $headings-color\n color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n padding-right: $close-font-size + $alert-padding-x * 2;\n\n // Adjust close link position\n .close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: $alert-padding-y $alert-padding-x;\n color: inherit;\n }\n}\n\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $color, $value in $theme-colors {\n .alert-#{$color} {\n @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));\n }\n}\n","@mixin alert-variant($background, $border, $color) {\n color: $color;\n @include gradient-bg($background);\n border-color: $border;\n\n hr {\n border-top-color: darken($border, 5%);\n }\n\n .alert-link {\n color: darken($color, 10%);\n }\n}\n","// Disable animation if transitions are disabled\n@if $enable-transitions {\n @keyframes progress-bar-stripes {\n from { background-position: $progress-height 0; }\n to { background-position: 0 0; }\n }\n}\n\n.progress {\n display: flex;\n height: $progress-height;\n overflow: hidden; // force rounded corners by cropping it\n line-height: 0;\n @include font-size($progress-font-size);\n background-color: $progress-bg;\n @include border-radius($progress-border-radius);\n @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: $progress-bar-color;\n text-align: center;\n white-space: nowrap;\n background-color: $progress-bar-bg;\n @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n @include gradient-striped();\n background-size: $progress-height $progress-height;\n}\n\n@if $enable-transitions {\n .progress-bar-animated {\n animation: $progress-bar-animation-timing progress-bar-stripes;\n\n @if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n }\n}\n",".media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n","// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n display: flex;\n flex-direction: column;\n\n // No need to set list-style: none; since .list-group-item is block level\n padding-left: 0; // reset padding because ul and ol\n margin-bottom: 0;\n @include border-radius($list-group-border-radius);\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n width: 100%; // For `<button>`s (anchors become 100% by default though)\n color: $list-group-action-color;\n text-align: inherit; // For `<button>`s (anchors inherit)\n\n // Hover state\n @include hover-focus() {\n z-index: 1; // Place hover/focus items above their siblings for proper border styling\n color: $list-group-action-hover-color;\n text-decoration: none;\n background-color: $list-group-hover-bg;\n }\n\n &:active {\n color: $list-group-action-active-color;\n background-color: $list-group-action-active-bg;\n }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: $list-group-item-padding-y $list-group-item-padding-x;\n color: $list-group-color;\n text-decoration: if($link-decoration == none, null, none);\n background-color: $list-group-bg;\n border: $list-group-border-width solid $list-group-border-color;\n\n &:first-child {\n @include border-top-radius(inherit);\n }\n\n &:last-child {\n @include border-bottom-radius(inherit);\n }\n\n &.disabled,\n &:disabled {\n color: $list-group-disabled-color;\n pointer-events: none;\n background-color: $list-group-disabled-bg;\n }\n\n // Include both here for `<a>`s and `<button>`s\n &.active {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: $list-group-active-color;\n background-color: $list-group-active-bg;\n border-color: $list-group-active-border-color;\n }\n\n & + & {\n border-top-width: 0;\n\n &.active {\n margin-top: -$list-group-border-width;\n border-top-width: $list-group-border-width;\n }\n }\n}\n\n\n// Horizontal\n//\n// Change the layout of list group items from vertical (default) to horizontal.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .list-group-horizontal#{$infix} {\n flex-direction: row;\n\n > .list-group-item {\n &:first-child {\n @include border-bottom-left-radius($list-group-border-radius);\n @include border-top-right-radius(0);\n }\n\n &:last-child {\n @include border-top-right-radius($list-group-border-radius);\n @include border-bottom-left-radius(0);\n }\n\n &.active {\n margin-top: 0;\n }\n\n + .list-group-item {\n border-top-width: $list-group-border-width;\n border-left-width: 0;\n\n &.active {\n margin-left: -$list-group-border-width;\n border-left-width: $list-group-border-width;\n }\n }\n }\n }\n }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n @include border-radius(0);\n\n > .list-group-item {\n border-width: 0 0 $list-group-border-width;\n\n &:last-child {\n border-bottom-width: 0;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $color, $value in $theme-colors {\n @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));\n}\n","// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n .list-group-item-#{$state} {\n color: $color;\n background-color: $background;\n\n &.list-group-item-action {\n @include hover-focus() {\n color: $color;\n background-color: darken($background, 5%);\n }\n\n &.active {\n color: $white;\n background-color: $color;\n border-color: $color;\n }\n }\n }\n}\n",".close {\n float: right;\n @include font-size($close-font-size);\n font-weight: $close-font-weight;\n line-height: 1;\n color: $close-color;\n text-shadow: $close-text-shadow;\n opacity: .5;\n\n // Override <a>'s hover style\n @include hover() {\n color: $close-color;\n text-decoration: none;\n }\n\n &:not(:disabled):not(.disabled) {\n @include hover-focus() {\n opacity: .75;\n }\n }\n}\n\n// Additional properties for button version\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n// stylelint-disable-next-line selector-no-qualifying-type\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n}\n\n// Future-proof disabling of clicks on `<a>` elements\n\n// stylelint-disable-next-line selector-no-qualifying-type\na.close.disabled {\n pointer-events: none;\n}\n",".toast {\n // Prevents from shrinking in IE11, when in a flex container\n // See https://github.com/twbs/bootstrap/issues/28341\n flex-basis: $toast-max-width;\n max-width: $toast-max-width;\n @include font-size($toast-font-size);\n color: $toast-color;\n background-color: $toast-background-color;\n background-clip: padding-box;\n border: $toast-border-width solid $toast-border-color;\n box-shadow: $toast-box-shadow;\n opacity: 0;\n @include border-radius($toast-border-radius);\n\n &:not(:last-child) {\n margin-bottom: $toast-padding-x;\n }\n\n &.showing {\n opacity: 1;\n }\n\n &.show {\n display: block;\n opacity: 1;\n }\n\n &.hide {\n display: none;\n }\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: $toast-padding-y $toast-padding-x;\n color: $toast-header-color;\n background-color: $toast-header-background-color;\n background-clip: padding-box;\n border-bottom: $toast-border-width solid $toast-header-border-color;\n @include border-top-radius(subtract($toast-border-radius, $toast-border-width));\n}\n\n.toast-body {\n padding: $toast-padding-x; // apply to both vertical and horizontal\n}\n","// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and stuff\n\n\n.modal-open {\n // Kill the scroll on the body\n overflow: hidden;\n\n .modal {\n overflow-x: hidden;\n overflow-y: auto;\n }\n}\n\n// Container that the modal scrolls within\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: $modal-dialog-margin;\n // allow clicks to pass through for custom click handling to close modal\n pointer-events: none;\n\n // When fading in the modal, animate it to slide down\n .modal.fade & {\n @include transition($modal-transition);\n transform: $modal-fade-transform;\n }\n .modal.show & {\n transform: $modal-show-transform;\n }\n\n // When trying to close, animate focus to scale\n .modal.modal-static & {\n transform: $modal-scale-transform;\n }\n}\n\n.modal-dialog-scrollable {\n display: flex; // IE10/11\n max-height: subtract(100%, $modal-dialog-margin * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11\n overflow: hidden;\n }\n\n .modal-header,\n .modal-footer {\n flex-shrink: 0;\n }\n\n .modal-body {\n overflow-y: auto;\n }\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: subtract(100%, $modal-dialog-margin * 2);\n\n // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)\n &::before {\n display: block; // IE10\n height: subtract(100vh, $modal-dialog-margin * 2);\n height: min-content; // Reset height to 0 except on IE\n content: \"\";\n }\n\n // Ensure `.modal-body` shows scrollbar (IE10/11)\n &.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n\n .modal-content {\n max-height: none;\n }\n\n &::before {\n content: none;\n }\n }\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n // counteract the pointer-events: none; in the .modal-dialog\n color: $modal-content-color;\n pointer-events: auto;\n background-color: $modal-content-bg;\n background-clip: padding-box;\n border: $modal-content-border-width solid $modal-content-border-color;\n @include border-radius($modal-content-border-radius);\n @include box-shadow($modal-content-box-shadow-xs);\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal-backdrop;\n width: 100vw;\n height: 100vh;\n background-color: $modal-backdrop-bg;\n\n // Fade for backdrop\n &.fade { opacity: 0; }\n &.show { opacity: $modal-backdrop-opacity; }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n display: flex;\n align-items: flex-start; // so the close btn always stays on the upper right corner\n justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n padding: $modal-header-padding;\n border-bottom: $modal-header-border-width solid $modal-header-border-color;\n @include border-top-radius($modal-content-inner-border-radius);\n\n .close {\n padding: $modal-header-padding;\n // auto on the left force icon to the right even when there is no .modal-title\n margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;\n }\n}\n\n// Title text within header\n.modal-title {\n margin-bottom: 0;\n line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n // Enable `flex-grow: 1` so that the body take up as much space as possible\n // when there should be a fixed height on `.modal-dialog`.\n flex: 1 1 auto;\n padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center; // vertically center\n justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n padding: $modal-inner-padding - $modal-footer-margin-between / 2;\n border-top: $modal-footer-border-width solid $modal-footer-border-color;\n @include border-bottom-radius($modal-content-inner-border-radius);\n\n // Place margin between footer elements\n // This solution is far from ideal because of the universal selector usage,\n // but is needed to fix https://github.com/twbs/bootstrap/issues/24800\n > * {\n margin: $modal-footer-margin-between / 2;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n max-width: $modal-md;\n margin: $modal-dialog-margin-y-sm-up auto;\n }\n\n .modal-dialog-scrollable {\n max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n .modal-content {\n max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n }\n }\n\n .modal-dialog-centered {\n min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n\n &::before {\n height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);\n height: min-content;\n }\n }\n\n .modal-content {\n @include box-shadow($modal-content-box-shadow-sm-up);\n }\n\n .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n .modal-lg,\n .modal-xl {\n max-width: $modal-lg;\n }\n}\n\n@include media-breakpoint-up(xl) {\n .modal-xl { max-width: $modal-xl; }\n}\n","// Base class\n.tooltip {\n position: absolute;\n z-index: $zindex-tooltip;\n display: block;\n margin: $tooltip-margin;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($tooltip-font-size);\n // Allow breaking very long words so they don't overflow the tooltip's bounds\n word-wrap: break-word;\n opacity: 0;\n\n &.show { opacity: $tooltip-opacity; }\n\n .arrow {\n position: absolute;\n display: block;\n width: $tooltip-arrow-width;\n height: $tooltip-arrow-height;\n\n &::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-tooltip-top {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n bottom: 0;\n\n &::before {\n top: 0;\n border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-top-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-right {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n left: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n right: 0;\n border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-right-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-bottom {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n top: 0;\n\n &::before {\n bottom: 0;\n border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-bottom-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-left {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n right: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n left: 0;\n border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-left-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-tooltip-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-tooltip-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-tooltip-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-tooltip-left;\n }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: $tooltip-max-width;\n padding: $tooltip-padding-y $tooltip-padding-x;\n color: $tooltip-color;\n text-align: center;\n background-color: $tooltip-bg;\n @include border-radius($tooltip-border-radius);\n}\n","@mixin reset-text() {\n font-family: $font-family-base;\n // We deliberately do NOT reset font-size or word-wrap.\n font-style: normal;\n font-weight: $font-weight-normal;\n line-height: $line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n}\n",".popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: $zindex-popover;\n display: block;\n max-width: $popover-max-width;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($popover-font-size);\n // Allow breaking very long words so they don't overflow the popover's bounds\n word-wrap: break-word;\n background-color: $popover-bg;\n background-clip: padding-box;\n border: $popover-border-width solid $popover-border-color;\n @include border-radius($popover-border-radius);\n @include box-shadow($popover-box-shadow);\n\n .arrow {\n position: absolute;\n display: block;\n width: $popover-arrow-width;\n height: $popover-arrow-height;\n margin: 0 $popover-border-radius;\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-popover-top {\n margin-bottom: $popover-arrow-height;\n\n > .arrow {\n bottom: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n bottom: 0;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-outer-color;\n }\n\n &::after {\n bottom: $popover-border-width;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-right {\n margin-left: $popover-arrow-height;\n\n > .arrow {\n left: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n left: 0;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-outer-color;\n }\n\n &::after {\n left: $popover-border-width;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-bottom {\n margin-top: $popover-arrow-height;\n\n > .arrow {\n top: subtract(-$popover-arrow-height, $popover-border-width);\n\n &::before {\n top: 0;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-outer-color;\n }\n\n &::after {\n top: $popover-border-width;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-color;\n }\n }\n\n // This will remove the popover-header's border just below the arrow\n .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: $popover-arrow-width;\n margin-left: -$popover-arrow-width / 2;\n content: \"\";\n border-bottom: $popover-border-width solid $popover-header-bg;\n }\n}\n\n.bs-popover-left {\n margin-right: $popover-arrow-height;\n\n > .arrow {\n right: subtract(-$popover-arrow-height, $popover-border-width);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n right: 0;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-outer-color;\n }\n\n &::after {\n right: $popover-border-width;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-popover-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-popover-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-popover-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-popover-left;\n }\n}\n\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n padding: $popover-header-padding-y $popover-header-padding-x;\n margin-bottom: 0; // Reset the default from Reboot\n @include font-size($font-size-base);\n color: $popover-header-color;\n background-color: $popover-header-bg;\n border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);\n @include border-top-radius($popover-inner-border-radius);\n\n &:empty {\n display: none;\n }\n}\n\n.popover-body {\n padding: $popover-body-padding-y $popover-body-padding-x;\n color: $popover-body-color;\n}\n","// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n// even when their scroll action started on a carousel, but for compatibility (with Firefox)\n// we're preventing all actions instead\n// 2. The .carousel-item-left and .carousel-item-right is used to indicate where\n// the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-left and .active.carousel-item-right is the current\n// slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right\n// is the upcoming slide in transition.\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n @include clearfix();\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n }\n\n .carousel-item.active,\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n }\n\n .active.carousel-item-left,\n .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n @include transition(opacity 0s $carousel-transition-duration);\n }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n // Use flex for alignment (1-3)\n display: flex; // 1. allow flex styles\n align-items: center; // 2. vertically center contents\n justify-content: center; // 3. horizontally center contents\n width: $carousel-control-width;\n color: $carousel-control-color;\n text-align: center;\n opacity: $carousel-control-opacity;\n @include transition($carousel-control-transition);\n\n // Hover/focus state\n @include hover-focus() {\n color: $carousel-control-color;\n text-decoration: none;\n outline: 0;\n opacity: $carousel-control-hover-opacity;\n }\n}\n.carousel-control-prev {\n left: 0;\n @if $enable-gradients {\n background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));\n }\n}\n.carousel-control-next {\n right: 0;\n @if $enable-gradients {\n background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));\n }\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: $carousel-control-icon-width;\n height: $carousel-control-icon-width;\n background: 50% / 100% 100% no-repeat;\n}\n.carousel-control-prev-icon {\n background-image: escape-svg($carousel-control-prev-icon-bg);\n}\n.carousel-control-next-icon {\n background-image: escape-svg($carousel-control-next-icon-bg);\n}\n\n\n// Optional indicator pips\n//\n// Add an ordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0; // override <ol> default\n // Use the .carousel-control's width as margin so we don't overlay those\n margin-right: $carousel-control-width;\n margin-left: $carousel-control-width;\n list-style: none;\n\n li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: $carousel-indicator-width;\n height: $carousel-indicator-height;\n margin-right: $carousel-indicator-spacer;\n margin-left: $carousel-indicator-spacer;\n text-indent: -999px;\n cursor: pointer;\n background-color: $carousel-indicator-active-bg;\n background-clip: padding-box;\n // Use transparent borders to increase the hit area by 10px on top and bottom.\n border-top: $carousel-indicator-hit-area-height solid transparent;\n border-bottom: $carousel-indicator-hit-area-height solid transparent;\n opacity: .5;\n @include transition($carousel-indicator-transition);\n }\n\n .active {\n opacity: 1;\n }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n position: absolute;\n right: (100% - $carousel-caption-width) / 2;\n bottom: 20px;\n left: (100% - $carousel-caption-width) / 2;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: $carousel-caption-color;\n text-align: center;\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","//\n// Rotating border\n//\n\n@keyframes spinner-border {\n to { transform: rotate(360deg); }\n}\n\n.spinner-border {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n border: $spinner-border-width solid currentColor;\n border-right-color: transparent;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n animation: .75s linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n background-color: currentColor;\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 50%;\n opacity: 0;\n animation: .75s linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n}\n\n@if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n .spinner-border,\n .spinner-grow {\n animation-duration: 1.5s;\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n.align-baseline { vertical-align: baseline !important; } // Browser default\n.align-top { vertical-align: top !important; }\n.align-middle { vertical-align: middle !important; }\n.align-bottom { vertical-align: bottom !important; }\n.align-text-bottom { vertical-align: text-bottom !important; }\n.align-text-top { vertical-align: text-top !important; }\n","// stylelint-disable declaration-no-important\n\n// Contextual backgrounds\n\n@mixin bg-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background-color: $color !important;\n }\n a#{$parent},\n button#{$parent} {\n @include hover-focus() {\n background-color: darken($color, 10%) !important;\n }\n }\n @include deprecate(\"The `bg-variant` mixin\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n\n@mixin bg-gradient-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;\n }\n @include deprecate(\"The `bg-gradient-variant` mixin\", \"v4.5.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n@each $color, $value in $theme-colors {\n @include bg-variant(\".bg-#{$color}\", $value, true);\n}\n\n@if $enable-gradients {\n @each $color, $value in $theme-colors {\n @include bg-gradient-variant(\".bg-gradient-#{$color}\", $value, true);\n }\n}\n\n.bg-white {\n background-color: $white !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n","// stylelint-disable property-disallowed-list, declaration-no-important\n\n//\n// Border\n//\n\n.border { border: $border-width solid $border-color !important; }\n.border-top { border-top: $border-width solid $border-color !important; }\n.border-right { border-right: $border-width solid $border-color !important; }\n.border-bottom { border-bottom: $border-width solid $border-color !important; }\n.border-left { border-left: $border-width solid $border-color !important; }\n\n.border-0 { border: 0 !important; }\n.border-top-0 { border-top: 0 !important; }\n.border-right-0 { border-right: 0 !important; }\n.border-bottom-0 { border-bottom: 0 !important; }\n.border-left-0 { border-left: 0 !important; }\n\n@each $color, $value in $theme-colors {\n .border-#{$color} {\n border-color: $value !important;\n }\n}\n\n.border-white {\n border-color: $white !important;\n}\n\n//\n// Border-radius\n//\n\n.rounded-sm {\n border-radius: $border-radius-sm !important;\n}\n\n.rounded {\n border-radius: $border-radius !important;\n}\n\n.rounded-top {\n border-top-left-radius: $border-radius !important;\n border-top-right-radius: $border-radius !important;\n}\n\n.rounded-right {\n border-top-right-radius: $border-radius !important;\n border-bottom-right-radius: $border-radius !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-left {\n border-top-left-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-lg {\n border-radius: $border-radius-lg !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: $rounded-pill !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n\n &::before {\n display: block;\n content: \"\";\n }\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n }\n}\n\n@each $embed-responsive-aspect-ratio in $embed-responsive-aspect-ratios {\n $embed-responsive-aspect-ratio-x: nth($embed-responsive-aspect-ratio, 1);\n $embed-responsive-aspect-ratio-y: nth($embed-responsive-aspect-ratio, 2);\n\n .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} {\n &::before {\n padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x);\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .float#{$infix}-left { float: left !important; }\n .float#{$infix}-right { float: right !important; }\n .float#{$infix}-none { float: none !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $user-selects {\n .user-select-#{$value} { user-select: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $overflows {\n .overflow-#{$value} { overflow: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Common values\n@each $position in $positions {\n .position-#{$position} { position: $position !important; }\n}\n\n// Shorthand\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.sticky-top {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: $zindex-sticky;\n }\n}\n","//\n// Screenreaders\n//\n\n.sr-only {\n @include sr-only();\n}\n\n.sr-only-focusable {\n @include sr-only-focusable();\n}\n","// Only display content to screen readers\n//\n// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/\n// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin sr-only() {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px; // Fix for https://github.com/twbs/bootstrap/issues/25686\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable() {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n }\n}\n","// stylelint-disable declaration-no-important\n\n.shadow-sm { box-shadow: $box-shadow-sm !important; }\n.shadow { box-shadow: $box-shadow !important; }\n.shadow-lg { box-shadow: $box-shadow-lg !important; }\n.shadow-none { box-shadow: none !important; }\n","// stylelint-disable declaration-no-important\n\n// Width and height\n\n@each $prop, $abbrev in (width: w, height: h) {\n @each $size, $length in $sizes {\n .#{$abbrev}-#{$size} { #{$prop}: $length !important; }\n }\n}\n\n.mw-100 { max-width: 100% !important; }\n.mh-100 { max-height: 100% !important; }\n\n// Viewport additional helpers\n\n.min-vw-100 { min-width: 100vw !important; }\n.min-vh-100 { min-height: 100vh !important; }\n\n.vw-100 { width: 100vw !important; }\n.vh-100 { height: 100vh !important; }\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n","//\n// Stretched link\n//\n\n.stretched-link {\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n // Just in case `pointer-events: none` is set on a parent\n pointer-events: auto;\n content: \"\";\n // IE10 bugfix, see https://stackoverflow.com/questions/16947967/ie10-hover-pseudo-class-doesnt-work-without-background-color\n background-color: rgba(0, 0, 0, 0);\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Text\n//\n\n.text-monospace { font-family: $font-family-monospace !important; }\n\n// Alignment\n\n.text-justify { text-align: justify !important; }\n.text-wrap { white-space: normal !important; }\n.text-nowrap { white-space: nowrap !important; }\n.text-truncate { @include text-truncate(); }\n\n// Responsive alignment\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .text#{$infix}-left { text-align: left !important; }\n .text#{$infix}-right { text-align: right !important; }\n .text#{$infix}-center { text-align: center !important; }\n }\n}\n\n// Transformation\n\n.text-lowercase { text-transform: lowercase !important; }\n.text-uppercase { text-transform: uppercase !important; }\n.text-capitalize { text-transform: capitalize !important; }\n\n// Weight and italics\n\n.font-weight-light { font-weight: $font-weight-light !important; }\n.font-weight-lighter { font-weight: $font-weight-lighter !important; }\n.font-weight-normal { font-weight: $font-weight-normal !important; }\n.font-weight-bold { font-weight: $font-weight-bold !important; }\n.font-weight-bolder { font-weight: $font-weight-bolder !important; }\n.font-italic { font-style: italic !important; }\n\n// Contextual colors\n\n.text-white { color: $white !important; }\n\n@each $color, $value in $theme-colors {\n @include text-emphasis-variant(\".text-#{$color}\", $value, true);\n}\n\n.text-body { color: $body-color !important; }\n.text-muted { color: $text-muted !important; }\n\n.text-black-50 { color: rgba($black, .5) !important; }\n.text-white-50 { color: rgba($white, .5) !important; }\n\n// Misc\n\n.text-hide {\n @include text-hide($ignore-warning: true);\n}\n\n.text-decoration-none { text-decoration: none !important; }\n\n.text-break {\n word-break: break-word !important; // Deprecated, but avoids issues with flex containers\n word-wrap: break-word !important; // Used instead of `overflow-wrap` for IE & Edge Legacy\n}\n\n// Reset\n\n.text-reset { color: inherit !important; }\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// stylelint-disable declaration-no-important\n\n// Typography\n\n@mixin text-emphasis-variant($parent, $color, $ignore-warning: false) {\n #{$parent} {\n color: $color !important;\n }\n @if $emphasized-link-hover-darken-percentage != 0 {\n a#{$parent} {\n @include hover-focus() {\n color: darken($color, $emphasized-link-hover-darken-percentage) !important;\n }\n }\n }\n @include deprecate(\"`text-emphasis-variant()`\", \"v4.4.0\", \"v5\", $ignore-warning);\n}\n","// CSS image replacement\n@mixin text-hide($ignore-warning: false) {\n // stylelint-disable-next-line font-family-no-missing-generic-family-keyword\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n\n @include deprecate(\"`text-hide()`\", \"v4.1.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Visibility utilities\n//\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n// Source: https://github.com/h5bp/main.css/blob/master/src/_print.css\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request:\n// https://www.phpied.com/delay-loading-your-print-css/\n// ==========================================================================\n\n@if $enable-print-styles {\n @media print {\n *,\n *::before,\n *::after {\n // Bootstrap specific; comment out `color` and `background`\n //color: $black !important; // Black prints faster\n text-shadow: none !important;\n //background: transparent !important;\n box-shadow: none !important;\n }\n\n a {\n &:not(.btn) {\n text-decoration: underline;\n }\n }\n\n // Bootstrap specific; comment the following selector out\n //a[href]::after {\n // content: \" (\" attr(href) \")\";\n //}\n\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n // Bootstrap specific; comment the following selector out\n //\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n //\n\n //a[href^=\"#\"]::after,\n //a[href^=\"javascript:\"]::after {\n // content: \"\";\n //}\n\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px\n page-break-inside: avoid;\n }\n\n //\n // Printing Tables:\n // https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables\n //\n\n thead {\n display: table-header-group;\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Specify a size and min-width to make printing closer across browsers.\n // We don't set margin here because it breaks `size` in Chrome. We also\n // don't use `!important` on `size` as it breaks in Chrome.\n @page {\n size: $print-page-size;\n }\n body {\n min-width: $print-body-min-width !important;\n }\n .container {\n min-width: $print-body-min-width !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .badge {\n border: $border-width solid $black;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: $white !important;\n }\n }\n\n .table-bordered {\n th,\n td {\n border: 1px solid $gray-300 !important;\n }\n }\n\n .table-dark {\n color: inherit;\n\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $table-border-color;\n }\n }\n\n .table .thead-dark th {\n color: inherit;\n border-color: $table-border-color;\n }\n\n // Bootstrap specific changes end\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js index 5fda309c9..d5c19832a 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js @@ -1,6 +1,6 @@ /*! - * Bootstrap v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { @@ -55,7 +55,7 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): util.js + * Bootstrap (v4.6.0): util.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -234,7 +234,7 @@ */ var NAME = 'alert'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.alert'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -390,7 +390,7 @@ */ var NAME$1 = 'button'; - var VERSION$1 = '4.5.3'; + var VERSION$1 = '4.6.0'; var DATA_KEY$1 = 'bs.button'; var EVENT_KEY$1 = "." + DATA_KEY$1; var DATA_API_KEY$1 = '.data-api'; @@ -589,7 +589,7 @@ */ var NAME$2 = 'carousel'; - var VERSION$2 = '4.5.3'; + var VERSION$2 = '4.6.0'; var DATA_KEY$2 = 'bs.carousel'; var EVENT_KEY$2 = "." + DATA_KEY$2; var DATA_API_KEY$2 = '.data-api'; @@ -729,6 +729,8 @@ } if (this._config.interval && !this._isPaused) { + this._updateInterval(); + this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); } }; @@ -970,6 +972,23 @@ } }; + _proto._updateInterval = function _updateInterval() { + var element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM); + + if (!element) { + return; + } + + var elementInterval = parseInt(element.getAttribute('data-interval'), 10); + + if (elementInterval) { + this._config.defaultInterval = this._config.defaultInterval || this._config.interval; + this._config.interval = elementInterval; + } else { + this._config.interval = this._config.defaultInterval || this._config.interval; + } + }; + _proto._slide = function _slide(direction, element) { var _this4 = this; @@ -1020,6 +1039,7 @@ this._setActiveIndicatorElement(nextElement); + this._activeElement = nextElement; var slidEvent = $__default['default'].Event(EVENT_SLID, { relatedTarget: nextElement, direction: eventDirectionName, @@ -1032,15 +1052,6 @@ Util.reflow(nextElement); $__default['default'](activeElement).addClass(directionalClassName); $__default['default'](nextElement).addClass(directionalClassName); - var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10); - - if (nextElementInterval) { - this._config.defaultInterval = this._config.defaultInterval || this._config.interval; - this._config.interval = nextElementInterval; - } else { - this._config.interval = this._config.defaultInterval || this._config.interval; - } - var transitionDuration = Util.getTransitionDurationFromElement(activeElement); $__default['default'](activeElement).one(Util.TRANSITION_END, function () { $__default['default'](nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE$1); @@ -1177,7 +1188,7 @@ */ var NAME$3 = 'collapse'; - var VERSION$3 = '4.5.3'; + var VERSION$3 = '4.6.0'; var DATA_KEY$3 = 'bs.collapse'; var EVENT_KEY$3 = "." + DATA_KEY$3; var DATA_API_KEY$3 = '.data-api'; @@ -4140,7 +4151,7 @@ */ var NAME$4 = 'dropdown'; - var VERSION$4 = '4.5.3'; + var VERSION$4 = '4.6.0'; var DATA_KEY$4 = 'bs.dropdown'; var EVENT_KEY$4 = "." + DATA_KEY$4; var DATA_API_KEY$4 = '.data-api'; @@ -4257,7 +4268,7 @@ if (showEvent.isDefaultPrevented()) { return; - } // Disable totally Popper.js for Dropdown in Navbar + } // Totally disable Popper for Dropdowns in Navbar if (!this._inNavbar && usePopper) { @@ -4266,7 +4277,7 @@ * Popper - https://popper.js.org */ if (typeof Popper === 'undefined') { - throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); + throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)'); } var referenceElement = this._element; @@ -4434,7 +4445,7 @@ boundariesElement: this._config.boundary } } - }; // Disable Popper.js if we have a static display + }; // Disable Popper if we have a static display if (this._config.display === 'static') { popperConfig.modifiers.applyStyle = { @@ -4654,7 +4665,7 @@ */ var NAME$5 = 'modal'; - var VERSION$5 = '4.5.3'; + var VERSION$5 = '4.6.0'; var DATA_KEY$5 = 'bs.modal'; var EVENT_KEY$5 = "." + DATA_KEY$5; var DATA_API_KEY$5 = '.data-api'; @@ -4854,38 +4865,34 @@ _proto._triggerBackdropTransition = function _triggerBackdropTransition() { var _this3 = this; - if (this._config.backdrop === 'static') { - var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED); - $__default['default'](this._element).trigger(hideEventPrevented); + var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED); + $__default['default'](this._element).trigger(hideEventPrevented); - if (hideEventPrevented.isDefaultPrevented()) { - return; - } + if (hideEventPrevented.isDefaultPrevented()) { + return; + } - var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; - if (!isModalOverflowing) { - this._element.style.overflowY = 'hidden'; - } + if (!isModalOverflowing) { + this._element.style.overflowY = 'hidden'; + } - this._element.classList.add(CLASS_NAME_STATIC); + this._element.classList.add(CLASS_NAME_STATIC); - var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog); - $__default['default'](this._element).off(Util.TRANSITION_END); - $__default['default'](this._element).one(Util.TRANSITION_END, function () { - _this3._element.classList.remove(CLASS_NAME_STATIC); + var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog); + $__default['default'](this._element).off(Util.TRANSITION_END); + $__default['default'](this._element).one(Util.TRANSITION_END, function () { + _this3._element.classList.remove(CLASS_NAME_STATIC); - if (!isModalOverflowing) { - $__default['default'](_this3._element).one(Util.TRANSITION_END, function () { - _this3._element.style.overflowY = ''; - }).emulateTransitionEnd(_this3._element, modalTransitionDuration); - } - }).emulateTransitionEnd(modalTransitionDuration); + if (!isModalOverflowing) { + $__default['default'](_this3._element).one(Util.TRANSITION_END, function () { + _this3._element.style.overflowY = ''; + }).emulateTransitionEnd(_this3._element, modalTransitionDuration); + } + }).emulateTransitionEnd(modalTransitionDuration); - this._element.focus(); - } else { - this.hide(); - } + this._element.focus(); }; _proto._showElement = function _showElement(relatedTarget) { @@ -5040,7 +5047,11 @@ return; } - _this9._triggerBackdropTransition(); + if (_this9._config.backdrop === 'static') { + _this9._triggerBackdropTransition(); + } else { + _this9.hide(); + } }); if (animate) { @@ -5264,7 +5275,7 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): tools/sanitizer.js + * Bootstrap (v4.6.0): tools/sanitizer.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -5390,7 +5401,7 @@ */ var NAME$6 = 'tooltip'; - var VERSION$6 = '4.5.3'; + var VERSION$6 = '4.6.0'; var DATA_KEY$6 = 'bs.tooltip'; var EVENT_KEY$6 = "." + DATA_KEY$6; var JQUERY_NO_CONFLICT$6 = $__default['default'].fn[NAME$6]; @@ -5410,6 +5421,7 @@ container: '(string|element|boolean)', fallbackPlacement: '(string|array)', boundary: '(string|element)', + customClass: '(string|function)', sanitize: 'boolean', sanitizeFn: '(null|function)', whiteList: 'object', @@ -5435,6 +5447,7 @@ container: false, fallbackPlacement: 'flip', boundary: 'scrollParent', + customClass: '', sanitize: true, sanitizeFn: null, whiteList: DefaultWhitelist, @@ -5471,7 +5484,7 @@ var Tooltip = /*#__PURE__*/function () { function Tooltip(element, config) { if (typeof Popper === 'undefined') { - throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); + throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); } // private @@ -5605,7 +5618,8 @@ $__default['default'](this.element).trigger(this.constructor.Event.INSERTED); this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)); - $__default['default'](tip).addClass(CLASS_NAME_SHOW$4); // If this is a touch-enabled device we add extra + $__default['default'](tip).addClass(CLASS_NAME_SHOW$4); + $__default['default'](tip).addClass(this.config.customClass); // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html @@ -6103,7 +6117,7 @@ */ var NAME$7 = 'popover'; - var VERSION$7 = '4.5.3'; + var VERSION$7 = '4.6.0'; var DATA_KEY$7 = 'bs.popover'; var EVENT_KEY$7 = "." + DATA_KEY$7; var JQUERY_NO_CONFLICT$7 = $__default['default'].fn[NAME$7]; @@ -6283,7 +6297,7 @@ */ var NAME$8 = 'scrollspy'; - var VERSION$8 = '4.5.3'; + var VERSION$8 = '4.6.0'; var DATA_KEY$8 = 'bs.scrollspy'; var EVENT_KEY$8 = "." + DATA_KEY$8; var DATA_API_KEY$6 = '.data-api'; @@ -6575,7 +6589,7 @@ */ var NAME$9 = 'tab'; - var VERSION$9 = '4.5.3'; + var VERSION$9 = '4.6.0'; var DATA_KEY$9 = 'bs.tab'; var EVENT_KEY$9 = "." + DATA_KEY$9; var DATA_API_KEY$7 = '.data-api'; @@ -6801,7 +6815,7 @@ */ var NAME$a = 'toast'; - var VERSION$a = '4.5.3'; + var VERSION$a = '4.6.0'; var DATA_KEY$a = 'bs.toast'; var EVENT_KEY$a = "." + DATA_KEY$a; var JQUERY_NO_CONFLICT$a = $__default['default'].fn[NAME$a]; diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js.map b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js.map index 0ffc67bdb..60270c32b 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js.map +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.js.map @@ -1 +1 @@ -{"version":3,"file":"bootstrap.bundle.js","sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/popper.js/dist/esm/popper.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = nextElementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**!\n * @fileOverview Kickass library to create and place poppers near their reference elements.\n * @version 1.16.1\n * @license\n * Copyright (c) 2016 Federico Zivolo and contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';\n\nvar timeoutDuration = function () {\n var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];\n for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {\n if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {\n return 1;\n }\n }\n return 0;\n}();\n\nfunction microtaskDebounce(fn) {\n var called = false;\n return function () {\n if (called) {\n return;\n }\n called = true;\n window.Promise.resolve().then(function () {\n called = false;\n fn();\n });\n };\n}\n\nfunction taskDebounce(fn) {\n var scheduled = false;\n return function () {\n if (!scheduled) {\n scheduled = true;\n setTimeout(function () {\n scheduled = false;\n fn();\n }, timeoutDuration);\n }\n };\n}\n\nvar supportsMicroTasks = isBrowser && window.Promise;\n\n/**\n* Create a debounced version of a method, that's asynchronously deferred\n* but called in the minimum time possible.\n*\n* @method\n* @memberof Popper.Utils\n* @argument {Function} fn\n* @returns {Function}\n*/\nvar debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;\n\n/**\n * Check if the given variable is a function\n * @method\n * @memberof Popper.Utils\n * @argument {Any} functionToCheck - variable to check\n * @returns {Boolean} answer to: is a function?\n */\nfunction isFunction(functionToCheck) {\n var getType = {};\n return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';\n}\n\n/**\n * Get CSS computed property of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Eement} element\n * @argument {String} property\n */\nfunction getStyleComputedProperty(element, property) {\n if (element.nodeType !== 1) {\n return [];\n }\n // NOTE: 1 DOM access here\n var window = element.ownerDocument.defaultView;\n var css = window.getComputedStyle(element, null);\n return property ? css[property] : css;\n}\n\n/**\n * Returns the parentNode or the host of the element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} parent\n */\nfunction getParentNode(element) {\n if (element.nodeName === 'HTML') {\n return element;\n }\n return element.parentNode || element.host;\n}\n\n/**\n * Returns the scrolling parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} scroll parent\n */\nfunction getScrollParent(element) {\n // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n if (!element) {\n return document.body;\n }\n\n switch (element.nodeName) {\n case 'HTML':\n case 'BODY':\n return element.ownerDocument.body;\n case '#document':\n return element.body;\n }\n\n // Firefox want us to check `-x` and `-y` variations as well\n\n var _getStyleComputedProp = getStyleComputedProperty(element),\n overflow = _getStyleComputedProp.overflow,\n overflowX = _getStyleComputedProp.overflowX,\n overflowY = _getStyleComputedProp.overflowY;\n\n if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {\n return element;\n }\n\n return getScrollParent(getParentNode(element));\n}\n\n/**\n * Returns the reference node of the reference object, or the reference object itself.\n * @method\n * @memberof Popper.Utils\n * @param {Element|Object} reference - the reference element (the popper will be relative to this)\n * @returns {Element} parent\n */\nfunction getReferenceNode(reference) {\n return reference && reference.referenceNode ? reference.referenceNode : reference;\n}\n\nvar isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);\nvar isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);\n\n/**\n * Determines if the browser is Internet Explorer\n * @method\n * @memberof Popper.Utils\n * @param {Number} version to check\n * @returns {Boolean} isIE\n */\nfunction isIE(version) {\n if (version === 11) {\n return isIE11;\n }\n if (version === 10) {\n return isIE10;\n }\n return isIE11 || isIE10;\n}\n\n/**\n * Returns the offset parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} offset parent\n */\nfunction getOffsetParent(element) {\n if (!element) {\n return document.documentElement;\n }\n\n var noOffsetParent = isIE(10) ? document.body : null;\n\n // NOTE: 1 DOM access here\n var offsetParent = element.offsetParent || null;\n // Skip hidden elements which don't have an offsetParent\n while (offsetParent === noOffsetParent && element.nextElementSibling) {\n offsetParent = (element = element.nextElementSibling).offsetParent;\n }\n\n var nodeName = offsetParent && offsetParent.nodeName;\n\n if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {\n return element ? element.ownerDocument.documentElement : document.documentElement;\n }\n\n // .offsetParent will return the closest TH, TD or TABLE in case\n // no offsetParent is present, I hate this job...\n if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {\n return getOffsetParent(offsetParent);\n }\n\n return offsetParent;\n}\n\nfunction isOffsetContainer(element) {\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY') {\n return false;\n }\n return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;\n}\n\n/**\n * Finds the root node (document, shadowDOM root) of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} node\n * @returns {Element} root node\n */\nfunction getRoot(node) {\n if (node.parentNode !== null) {\n return getRoot(node.parentNode);\n }\n\n return node;\n}\n\n/**\n * Finds the offset parent common to the two provided nodes\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element1\n * @argument {Element} element2\n * @returns {Element} common offset parent\n */\nfunction findCommonOffsetParent(element1, element2) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {\n return document.documentElement;\n }\n\n // Here we make sure to give as \"start\" the element that comes first in the DOM\n var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;\n var start = order ? element1 : element2;\n var end = order ? element2 : element1;\n\n // Get common ancestor container\n var range = document.createRange();\n range.setStart(start, 0);\n range.setEnd(end, 0);\n var commonAncestorContainer = range.commonAncestorContainer;\n\n // Both nodes are inside #document\n\n if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {\n if (isOffsetContainer(commonAncestorContainer)) {\n return commonAncestorContainer;\n }\n\n return getOffsetParent(commonAncestorContainer);\n }\n\n // one of the nodes is inside shadowDOM, find which one\n var element1root = getRoot(element1);\n if (element1root.host) {\n return findCommonOffsetParent(element1root.host, element2);\n } else {\n return findCommonOffsetParent(element1, getRoot(element2).host);\n }\n}\n\n/**\n * Gets the scroll value of the given element in the given side (top and left)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {String} side `top` or `left`\n * @returns {number} amount of scrolled pixels\n */\nfunction getScroll(element) {\n var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';\n\n var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n var html = element.ownerDocument.documentElement;\n var scrollingElement = element.ownerDocument.scrollingElement || html;\n return scrollingElement[upperSide];\n }\n\n return element[upperSide];\n}\n\n/*\n * Sum or subtract the element scroll values (left and top) from a given rect object\n * @method\n * @memberof Popper.Utils\n * @param {Object} rect - Rect object you want to change\n * @param {HTMLElement} element - The element from the function reads the scroll values\n * @param {Boolean} subtract - set to true if you want to subtract the scroll values\n * @return {Object} rect - The modifier rect object\n */\nfunction includeScroll(rect, element) {\n var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n var modifier = subtract ? -1 : 1;\n rect.top += scrollTop * modifier;\n rect.bottom += scrollTop * modifier;\n rect.left += scrollLeft * modifier;\n rect.right += scrollLeft * modifier;\n return rect;\n}\n\n/*\n * Helper to detect borders of a given element\n * @method\n * @memberof Popper.Utils\n * @param {CSSStyleDeclaration} styles\n * Result of `getStyleComputedProperty` on the given element\n * @param {String} axis - `x` or `y`\n * @return {number} borders - The borders size of the given axis\n */\n\nfunction getBordersSize(styles, axis) {\n var sideA = axis === 'x' ? 'Left' : 'Top';\n var sideB = sideA === 'Left' ? 'Right' : 'Bottom';\n\n return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);\n}\n\nfunction getSize(axis, body, html, computedStyle) {\n return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);\n}\n\nfunction getWindowSizes(document) {\n var body = document.body;\n var html = document.documentElement;\n var computedStyle = isIE(10) && getComputedStyle(html);\n\n return {\n height: getSize('Height', body, html, computedStyle),\n width: getSize('Width', body, html, computedStyle)\n };\n}\n\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\n\n\n\n\nvar defineProperty = function (obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\n/**\n * Given element offsets, generate an output similar to getBoundingClientRect\n * @method\n * @memberof Popper.Utils\n * @argument {Object} offsets\n * @returns {Object} ClientRect like output\n */\nfunction getClientRect(offsets) {\n return _extends({}, offsets, {\n right: offsets.left + offsets.width,\n bottom: offsets.top + offsets.height\n });\n}\n\n/**\n * Get bounding client rect of given element\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} element\n * @return {Object} client rect\n */\nfunction getBoundingClientRect(element) {\n var rect = {};\n\n // IE10 10 FIX: Please, don't ask, the element isn't\n // considered in DOM in some circumstances...\n // This isn't reproducible in IE10 compatibility mode of IE11\n try {\n if (isIE(10)) {\n rect = element.getBoundingClientRect();\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n rect.top += scrollTop;\n rect.left += scrollLeft;\n rect.bottom += scrollTop;\n rect.right += scrollLeft;\n } else {\n rect = element.getBoundingClientRect();\n }\n } catch (e) {}\n\n var result = {\n left: rect.left,\n top: rect.top,\n width: rect.right - rect.left,\n height: rect.bottom - rect.top\n };\n\n // subtract scrollbar size from sizes\n var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};\n var width = sizes.width || element.clientWidth || result.width;\n var height = sizes.height || element.clientHeight || result.height;\n\n var horizScrollbar = element.offsetWidth - width;\n var vertScrollbar = element.offsetHeight - height;\n\n // if an hypothetical scrollbar is detected, we must be sure it's not a `border`\n // we make this check conditional for performance reasons\n if (horizScrollbar || vertScrollbar) {\n var styles = getStyleComputedProperty(element);\n horizScrollbar -= getBordersSize(styles, 'x');\n vertScrollbar -= getBordersSize(styles, 'y');\n\n result.width -= horizScrollbar;\n result.height -= vertScrollbar;\n }\n\n return getClientRect(result);\n}\n\nfunction getOffsetRectRelativeToArbitraryNode(children, parent) {\n var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var isIE10 = isIE(10);\n var isHTML = parent.nodeName === 'HTML';\n var childrenRect = getBoundingClientRect(children);\n var parentRect = getBoundingClientRect(parent);\n var scrollParent = getScrollParent(children);\n\n var styles = getStyleComputedProperty(parent);\n var borderTopWidth = parseFloat(styles.borderTopWidth);\n var borderLeftWidth = parseFloat(styles.borderLeftWidth);\n\n // In cases where the parent is fixed, we must ignore negative scroll in offset calc\n if (fixedPosition && isHTML) {\n parentRect.top = Math.max(parentRect.top, 0);\n parentRect.left = Math.max(parentRect.left, 0);\n }\n var offsets = getClientRect({\n top: childrenRect.top - parentRect.top - borderTopWidth,\n left: childrenRect.left - parentRect.left - borderLeftWidth,\n width: childrenRect.width,\n height: childrenRect.height\n });\n offsets.marginTop = 0;\n offsets.marginLeft = 0;\n\n // Subtract margins of documentElement in case it's being used as parent\n // we do this only on HTML because it's the only element that behaves\n // differently when margins are applied to it. The margins are included in\n // the box of the documentElement, in the other cases not.\n if (!isIE10 && isHTML) {\n var marginTop = parseFloat(styles.marginTop);\n var marginLeft = parseFloat(styles.marginLeft);\n\n offsets.top -= borderTopWidth - marginTop;\n offsets.bottom -= borderTopWidth - marginTop;\n offsets.left -= borderLeftWidth - marginLeft;\n offsets.right -= borderLeftWidth - marginLeft;\n\n // Attach marginTop and marginLeft because in some circumstances we may need them\n offsets.marginTop = marginTop;\n offsets.marginLeft = marginLeft;\n }\n\n if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {\n offsets = includeScroll(offsets, parent);\n }\n\n return offsets;\n}\n\nfunction getViewportOffsetRectRelativeToArtbitraryNode(element) {\n var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var html = element.ownerDocument.documentElement;\n var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);\n var width = Math.max(html.clientWidth, window.innerWidth || 0);\n var height = Math.max(html.clientHeight, window.innerHeight || 0);\n\n var scrollTop = !excludeScroll ? getScroll(html) : 0;\n var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;\n\n var offset = {\n top: scrollTop - relativeOffset.top + relativeOffset.marginTop,\n left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,\n width: width,\n height: height\n };\n\n return getClientRect(offset);\n}\n\n/**\n * Check if the given element is fixed or is inside a fixed parent\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {Element} customContainer\n * @returns {Boolean} answer to \"isFixed?\"\n */\nfunction isFixed(element) {\n var nodeName = element.nodeName;\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n return false;\n }\n if (getStyleComputedProperty(element, 'position') === 'fixed') {\n return true;\n }\n var parentNode = getParentNode(element);\n if (!parentNode) {\n return false;\n }\n return isFixed(parentNode);\n}\n\n/**\n * Finds the first parent of an element that has a transformed property defined\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} first transformed parent or documentElement\n */\n\nfunction getFixedPositionOffsetParent(element) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element || !element.parentElement || isIE()) {\n return document.documentElement;\n }\n var el = element.parentElement;\n while (el && getStyleComputedProperty(el, 'transform') === 'none') {\n el = el.parentElement;\n }\n return el || document.documentElement;\n}\n\n/**\n * Computed the boundaries limits and return them\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} popper\n * @param {HTMLElement} reference\n * @param {number} padding\n * @param {HTMLElement} boundariesElement - Element used to define the boundaries\n * @param {Boolean} fixedPosition - Is in fixed position mode\n * @returns {Object} Coordinates of the boundaries\n */\nfunction getBoundaries(popper, reference, padding, boundariesElement) {\n var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n\n // NOTE: 1 DOM access here\n\n var boundaries = { top: 0, left: 0 };\n var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n\n // Handle viewport case\n if (boundariesElement === 'viewport') {\n boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);\n } else {\n // Handle other cases based on DOM element used as boundaries\n var boundariesNode = void 0;\n if (boundariesElement === 'scrollParent') {\n boundariesNode = getScrollParent(getParentNode(reference));\n if (boundariesNode.nodeName === 'BODY') {\n boundariesNode = popper.ownerDocument.documentElement;\n }\n } else if (boundariesElement === 'window') {\n boundariesNode = popper.ownerDocument.documentElement;\n } else {\n boundariesNode = boundariesElement;\n }\n\n var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);\n\n // In case of HTML, we need a different computation\n if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {\n var _getWindowSizes = getWindowSizes(popper.ownerDocument),\n height = _getWindowSizes.height,\n width = _getWindowSizes.width;\n\n boundaries.top += offsets.top - offsets.marginTop;\n boundaries.bottom = height + offsets.top;\n boundaries.left += offsets.left - offsets.marginLeft;\n boundaries.right = width + offsets.left;\n } else {\n // for all the other DOM elements, this one is good\n boundaries = offsets;\n }\n }\n\n // Add paddings\n padding = padding || 0;\n var isPaddingNumber = typeof padding === 'number';\n boundaries.left += isPaddingNumber ? padding : padding.left || 0;\n boundaries.top += isPaddingNumber ? padding : padding.top || 0;\n boundaries.right -= isPaddingNumber ? padding : padding.right || 0;\n boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;\n\n return boundaries;\n}\n\nfunction getArea(_ref) {\n var width = _ref.width,\n height = _ref.height;\n\n return width * height;\n}\n\n/**\n * Utility used to transform the `auto` placement to the placement with more\n * available space.\n * @method\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {\n var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n if (placement.indexOf('auto') === -1) {\n return placement;\n }\n\n var boundaries = getBoundaries(popper, reference, padding, boundariesElement);\n\n var rects = {\n top: {\n width: boundaries.width,\n height: refRect.top - boundaries.top\n },\n right: {\n width: boundaries.right - refRect.right,\n height: boundaries.height\n },\n bottom: {\n width: boundaries.width,\n height: boundaries.bottom - refRect.bottom\n },\n left: {\n width: refRect.left - boundaries.left,\n height: boundaries.height\n }\n };\n\n var sortedAreas = Object.keys(rects).map(function (key) {\n return _extends({\n key: key\n }, rects[key], {\n area: getArea(rects[key])\n });\n }).sort(function (a, b) {\n return b.area - a.area;\n });\n\n var filteredAreas = sortedAreas.filter(function (_ref2) {\n var width = _ref2.width,\n height = _ref2.height;\n return width >= popper.clientWidth && height >= popper.clientHeight;\n });\n\n var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;\n\n var variation = placement.split('-')[1];\n\n return computedPlacement + (variation ? '-' + variation : '');\n}\n\n/**\n * Get offsets to the reference element\n * @method\n * @memberof Popper.Utils\n * @param {Object} state\n * @param {Element} popper - the popper element\n * @param {Element} reference - the reference element (the popper will be relative to this)\n * @param {Element} fixedPosition - is in fixed position mode\n * @returns {Object} An object containing the offsets which will be applied to the popper\n */\nfunction getReferenceOffsets(state, popper, reference) {\n var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n\n var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);\n}\n\n/**\n * Get the outer sizes of the given element (offset size + margins)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Object} object containing width and height properties\n */\nfunction getOuterSizes(element) {\n var window = element.ownerDocument.defaultView;\n var styles = window.getComputedStyle(element);\n var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);\n var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);\n var result = {\n width: element.offsetWidth + y,\n height: element.offsetHeight + x\n };\n return result;\n}\n\n/**\n * Get the opposite placement of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement\n * @returns {String} flipped placement\n */\nfunction getOppositePlacement(placement) {\n var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}\n\n/**\n * Get offsets to the popper\n * @method\n * @memberof Popper.Utils\n * @param {Object} position - CSS position the Popper will get applied\n * @param {HTMLElement} popper - the popper element\n * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)\n * @param {String} placement - one of the valid placement options\n * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper\n */\nfunction getPopperOffsets(popper, referenceOffsets, placement) {\n placement = placement.split('-')[0];\n\n // Get popper node sizes\n var popperRect = getOuterSizes(popper);\n\n // Add position, width and height to our offsets object\n var popperOffsets = {\n width: popperRect.width,\n height: popperRect.height\n };\n\n // depending by the popper placement we have to compute its offsets slightly differently\n var isHoriz = ['right', 'left'].indexOf(placement) !== -1;\n var mainSide = isHoriz ? 'top' : 'left';\n var secondarySide = isHoriz ? 'left' : 'top';\n var measurement = isHoriz ? 'height' : 'width';\n var secondaryMeasurement = !isHoriz ? 'height' : 'width';\n\n popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;\n if (placement === secondarySide) {\n popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];\n } else {\n popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];\n }\n\n return popperOffsets;\n}\n\n/**\n * Mimics the `find` method of Array\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction find(arr, check) {\n // use native find if supported\n if (Array.prototype.find) {\n return arr.find(check);\n }\n\n // use `filter` to obtain the same behavior of `find`\n return arr.filter(check)[0];\n}\n\n/**\n * Return the index of the matching object\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction findIndex(arr, prop, value) {\n // use native findIndex if supported\n if (Array.prototype.findIndex) {\n return arr.findIndex(function (cur) {\n return cur[prop] === value;\n });\n }\n\n // use `find` + `indexOf` if `findIndex` isn't supported\n var match = find(arr, function (obj) {\n return obj[prop] === value;\n });\n return arr.indexOf(match);\n}\n\n/**\n * Loop trough the list of modifiers and run them in order,\n * each of them will then edit the data object.\n * @method\n * @memberof Popper.Utils\n * @param {dataObject} data\n * @param {Array} modifiers\n * @param {String} ends - Optional modifier name used as stopper\n * @returns {dataObject}\n */\nfunction runModifiers(modifiers, data, ends) {\n var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));\n\n modifiersToRun.forEach(function (modifier) {\n if (modifier['function']) {\n // eslint-disable-line dot-notation\n console.warn('`modifier.function` is deprecated, use `modifier.fn`!');\n }\n var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation\n if (modifier.enabled && isFunction(fn)) {\n // Add properties to offsets to make them a complete clientRect object\n // we do this before each modifier to make sure the previous one doesn't\n // mess with these values\n data.offsets.popper = getClientRect(data.offsets.popper);\n data.offsets.reference = getClientRect(data.offsets.reference);\n\n data = fn(data, modifier);\n }\n });\n\n return data;\n}\n\n/**\n * Updates the position of the popper, computing the new offsets and applying\n * the new style.<br />\n * Prefer `scheduleUpdate` over `update` because of performance reasons.\n * @method\n * @memberof Popper\n */\nfunction update() {\n // if popper is destroyed, don't perform any further update\n if (this.state.isDestroyed) {\n return;\n }\n\n var data = {\n instance: this,\n styles: {},\n arrowStyles: {},\n attributes: {},\n flipped: false,\n offsets: {}\n };\n\n // compute reference element offsets\n data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);\n\n // store the computed placement inside `originalPlacement`\n data.originalPlacement = data.placement;\n\n data.positionFixed = this.options.positionFixed;\n\n // compute the popper offsets\n data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);\n\n data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';\n\n // run the modifiers\n data = runModifiers(this.modifiers, data);\n\n // the first `update` will call `onCreate` callback\n // the other ones will call `onUpdate` callback\n if (!this.state.isCreated) {\n this.state.isCreated = true;\n this.options.onCreate(data);\n } else {\n this.options.onUpdate(data);\n }\n}\n\n/**\n * Helper used to know if the given modifier is enabled.\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean}\n */\nfunction isModifierEnabled(modifiers, modifierName) {\n return modifiers.some(function (_ref) {\n var name = _ref.name,\n enabled = _ref.enabled;\n return enabled && name === modifierName;\n });\n}\n\n/**\n * Get the prefixed supported property name\n * @method\n * @memberof Popper.Utils\n * @argument {String} property (camelCase)\n * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)\n */\nfunction getSupportedPropertyName(property) {\n var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];\n var upperProp = property.charAt(0).toUpperCase() + property.slice(1);\n\n for (var i = 0; i < prefixes.length; i++) {\n var prefix = prefixes[i];\n var toCheck = prefix ? '' + prefix + upperProp : property;\n if (typeof document.body.style[toCheck] !== 'undefined') {\n return toCheck;\n }\n }\n return null;\n}\n\n/**\n * Destroys the popper.\n * @method\n * @memberof Popper\n */\nfunction destroy() {\n this.state.isDestroyed = true;\n\n // touch DOM only if `applyStyle` modifier is enabled\n if (isModifierEnabled(this.modifiers, 'applyStyle')) {\n this.popper.removeAttribute('x-placement');\n this.popper.style.position = '';\n this.popper.style.top = '';\n this.popper.style.left = '';\n this.popper.style.right = '';\n this.popper.style.bottom = '';\n this.popper.style.willChange = '';\n this.popper.style[getSupportedPropertyName('transform')] = '';\n }\n\n this.disableEventListeners();\n\n // remove the popper if user explicitly asked for the deletion on destroy\n // do not use `remove` because IE11 doesn't support it\n if (this.options.removeOnDestroy) {\n this.popper.parentNode.removeChild(this.popper);\n }\n return this;\n}\n\n/**\n * Get the window associated with the element\n * @argument {Element} element\n * @returns {Window}\n */\nfunction getWindow(element) {\n var ownerDocument = element.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView : window;\n}\n\nfunction attachToScrollParents(scrollParent, event, callback, scrollParents) {\n var isBody = scrollParent.nodeName === 'BODY';\n var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;\n target.addEventListener(event, callback, { passive: true });\n\n if (!isBody) {\n attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);\n }\n scrollParents.push(target);\n}\n\n/**\n * Setup needed event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction setupEventListeners(reference, options, state, updateBound) {\n // Resize event listener on window\n state.updateBound = updateBound;\n getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });\n\n // Scroll event listener on scroll parents\n var scrollElement = getScrollParent(reference);\n attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);\n state.scrollElement = scrollElement;\n state.eventsEnabled = true;\n\n return state;\n}\n\n/**\n * It will add resize/scroll events and start recalculating\n * position of the popper element when they are triggered.\n * @method\n * @memberof Popper\n */\nfunction enableEventListeners() {\n if (!this.state.eventsEnabled) {\n this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);\n }\n}\n\n/**\n * Remove event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction removeEventListeners(reference, state) {\n // Remove resize event listener on window\n getWindow(reference).removeEventListener('resize', state.updateBound);\n\n // Remove scroll event listener on scroll parents\n state.scrollParents.forEach(function (target) {\n target.removeEventListener('scroll', state.updateBound);\n });\n\n // Reset state\n state.updateBound = null;\n state.scrollParents = [];\n state.scrollElement = null;\n state.eventsEnabled = false;\n return state;\n}\n\n/**\n * It will remove resize/scroll events and won't recalculate popper position\n * when they are triggered. It also won't trigger `onUpdate` callback anymore,\n * unless you call `update` method manually.\n * @method\n * @memberof Popper\n */\nfunction disableEventListeners() {\n if (this.state.eventsEnabled) {\n cancelAnimationFrame(this.scheduleUpdate);\n this.state = removeEventListeners(this.reference, this.state);\n }\n}\n\n/**\n * Tells if a given input is a number\n * @method\n * @memberof Popper.Utils\n * @param {*} input to check\n * @return {Boolean}\n */\nfunction isNumeric(n) {\n return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n/**\n * Set the style to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the style to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setStyles(element, styles) {\n Object.keys(styles).forEach(function (prop) {\n var unit = '';\n // add unit if the value is numeric and is one of the following\n if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {\n unit = 'px';\n }\n element.style[prop] = styles[prop] + unit;\n });\n}\n\n/**\n * Set the attributes to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the attributes to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setAttributes(element, attributes) {\n Object.keys(attributes).forEach(function (prop) {\n var value = attributes[prop];\n if (value !== false) {\n element.setAttribute(prop, attributes[prop]);\n } else {\n element.removeAttribute(prop);\n }\n });\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} data.styles - List of style properties - values to apply to popper element\n * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The same data object\n */\nfunction applyStyle(data) {\n // any property present in `data.styles` will be applied to the popper,\n // in this way we can make the 3rd party modifiers add custom styles to it\n // Be aware, modifiers could override the properties defined in the previous\n // lines of this modifier!\n setStyles(data.instance.popper, data.styles);\n\n // any property present in `data.attributes` will be applied to the popper,\n // they will be set as HTML attributes of the element\n setAttributes(data.instance.popper, data.attributes);\n\n // if arrowElement is defined and arrowStyles has some properties\n if (data.arrowElement && Object.keys(data.arrowStyles).length) {\n setStyles(data.arrowElement, data.arrowStyles);\n }\n\n return data;\n}\n\n/**\n * Set the x-placement attribute before everything else because it could be used\n * to add margins to the popper margins needs to be calculated to get the\n * correct popper offsets.\n * @method\n * @memberof Popper.modifiers\n * @param {HTMLElement} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper\n * @param {Object} options - Popper.js options\n */\nfunction applyStyleOnLoad(reference, popper, options, modifierOptions, state) {\n // compute reference element offsets\n var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);\n\n popper.setAttribute('x-placement', placement);\n\n // Apply `position` to popper before anything else because\n // without the position applied we can't guarantee correct computations\n setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });\n\n return options;\n}\n\n/**\n * @function\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Boolean} shouldRound - If the offsets should be rounded at all\n * @returns {Object} The popper's position offsets rounded\n *\n * The tale of pixel-perfect positioning. It's still not 100% perfect, but as\n * good as it can be within reason.\n * Discussion here: https://github.com/FezVrasta/popper.js/pull/715\n *\n * Low DPI screens cause a popper to be blurry if not using full pixels (Safari\n * as well on High DPI screens).\n *\n * Firefox prefers no rounding for positioning and does not have blurriness on\n * high DPI screens.\n *\n * Only horizontal placement and left/right values need to be considered.\n */\nfunction getRoundedOffsets(data, shouldRound) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n var round = Math.round,\n floor = Math.floor;\n\n var noRound = function noRound(v) {\n return v;\n };\n\n var referenceWidth = round(reference.width);\n var popperWidth = round(popper.width);\n\n var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;\n var isVariation = data.placement.indexOf('-') !== -1;\n var sameWidthParity = referenceWidth % 2 === popperWidth % 2;\n var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;\n\n var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;\n var verticalToInteger = !shouldRound ? noRound : round;\n\n return {\n left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),\n top: verticalToInteger(popper.top),\n bottom: verticalToInteger(popper.bottom),\n right: horizontalToInteger(popper.right)\n };\n}\n\nvar isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeStyle(data, options) {\n var x = options.x,\n y = options.y;\n var popper = data.offsets.popper;\n\n // Remove this legacy support in Popper.js v2\n\n var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'applyStyle';\n }).gpuAcceleration;\n if (legacyGpuAccelerationOption !== undefined) {\n console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');\n }\n var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;\n\n var offsetParent = getOffsetParent(data.instance.popper);\n var offsetParentRect = getBoundingClientRect(offsetParent);\n\n // Styles\n var styles = {\n position: popper.position\n };\n\n var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);\n\n var sideA = x === 'bottom' ? 'top' : 'bottom';\n var sideB = y === 'right' ? 'left' : 'right';\n\n // if gpuAcceleration is set to `true` and transform is supported,\n // we use `translate3d` to apply the position to the popper we\n // automatically use the supported prefixed version if needed\n var prefixedProperty = getSupportedPropertyName('transform');\n\n // now, let's make a step back and look at this code closely (wtf?)\n // If the content of the popper grows once it's been positioned, it\n // may happen that the popper gets misplaced because of the new content\n // overflowing its reference element\n // To avoid this problem, we provide two options (x and y), which allow\n // the consumer to define the offset origin.\n // If we position a popper on top of a reference element, we can set\n // `x` to `top` to make the popper grow towards its top instead of\n // its bottom.\n var left = void 0,\n top = void 0;\n if (sideA === 'bottom') {\n // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)\n // and not the bottom of the html element\n if (offsetParent.nodeName === 'HTML') {\n top = -offsetParent.clientHeight + offsets.bottom;\n } else {\n top = -offsetParentRect.height + offsets.bottom;\n }\n } else {\n top = offsets.top;\n }\n if (sideB === 'right') {\n if (offsetParent.nodeName === 'HTML') {\n left = -offsetParent.clientWidth + offsets.right;\n } else {\n left = -offsetParentRect.width + offsets.right;\n }\n } else {\n left = offsets.left;\n }\n if (gpuAcceleration && prefixedProperty) {\n styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';\n styles[sideA] = 0;\n styles[sideB] = 0;\n styles.willChange = 'transform';\n } else {\n // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties\n var invertTop = sideA === 'bottom' ? -1 : 1;\n var invertLeft = sideB === 'right' ? -1 : 1;\n styles[sideA] = top * invertTop;\n styles[sideB] = left * invertLeft;\n styles.willChange = sideA + ', ' + sideB;\n }\n\n // Attributes\n var attributes = {\n 'x-placement': data.placement\n };\n\n // Update `data` attributes, styles and arrowStyles\n data.attributes = _extends({}, attributes, data.attributes);\n data.styles = _extends({}, styles, data.styles);\n data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);\n\n return data;\n}\n\n/**\n * Helper used to know if the given modifier depends from another one.<br />\n * It checks if the needed modifier is listed and enabled.\n * @method\n * @memberof Popper.Utils\n * @param {Array} modifiers - list of modifiers\n * @param {String} requestingName - name of requesting modifier\n * @param {String} requestedName - name of requested modifier\n * @returns {Boolean}\n */\nfunction isModifierRequired(modifiers, requestingName, requestedName) {\n var requesting = find(modifiers, function (_ref) {\n var name = _ref.name;\n return name === requestingName;\n });\n\n var isRequired = !!requesting && modifiers.some(function (modifier) {\n return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;\n });\n\n if (!isRequired) {\n var _requesting = '`' + requestingName + '`';\n var requested = '`' + requestedName + '`';\n console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');\n }\n return isRequired;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction arrow(data, options) {\n var _data$offsets$arrow;\n\n // arrow depends on keepTogether in order to work\n if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {\n return data;\n }\n\n var arrowElement = options.element;\n\n // if arrowElement is a string, suppose it's a CSS selector\n if (typeof arrowElement === 'string') {\n arrowElement = data.instance.popper.querySelector(arrowElement);\n\n // if arrowElement is not found, don't run the modifier\n if (!arrowElement) {\n return data;\n }\n } else {\n // if the arrowElement isn't a query selector we must check that the\n // provided DOM node is child of its popper node\n if (!data.instance.popper.contains(arrowElement)) {\n console.warn('WARNING: `arrow.element` must be child of its popper element!');\n return data;\n }\n }\n\n var placement = data.placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isVertical = ['left', 'right'].indexOf(placement) !== -1;\n\n var len = isVertical ? 'height' : 'width';\n var sideCapitalized = isVertical ? 'Top' : 'Left';\n var side = sideCapitalized.toLowerCase();\n var altSide = isVertical ? 'left' : 'top';\n var opSide = isVertical ? 'bottom' : 'right';\n var arrowElementSize = getOuterSizes(arrowElement)[len];\n\n //\n // extends keepTogether behavior making sure the popper and its\n // reference have enough pixels in conjunction\n //\n\n // top/left side\n if (reference[opSide] - arrowElementSize < popper[side]) {\n data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);\n }\n // bottom/right side\n if (reference[side] + arrowElementSize > popper[opSide]) {\n data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];\n }\n data.offsets.popper = getClientRect(data.offsets.popper);\n\n // compute center of the popper\n var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;\n\n // Compute the sideValue using the updated popper offsets\n // take popper margin in account because we don't have this info available\n var css = getStyleComputedProperty(data.instance.popper);\n var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);\n var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);\n var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;\n\n // prevent arrowElement from being placed not contiguously to its popper\n sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);\n\n data.arrowElement = arrowElement;\n data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);\n\n return data;\n}\n\n/**\n * Get the opposite placement variation of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement variation\n * @returns {String} flipped placement variation\n */\nfunction getOppositeVariation(variation) {\n if (variation === 'end') {\n return 'start';\n } else if (variation === 'start') {\n return 'end';\n }\n return variation;\n}\n\n/**\n * List of accepted placements to use as values of the `placement` option.<br />\n * Valid placements are:\n * - `auto`\n * - `top`\n * - `right`\n * - `bottom`\n * - `left`\n *\n * Each placement can have a variation from this list:\n * - `-start`\n * - `-end`\n *\n * Variations are interpreted easily if you think of them as the left to right\n * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`\n * is right.<br />\n * Vertically (`left` and `right`), `start` is top and `end` is bottom.\n *\n * Some valid examples are:\n * - `top-end` (on top of reference, right aligned)\n * - `right-start` (on right of reference, top aligned)\n * - `bottom` (on bottom, centered)\n * - `auto-end` (on the side with more space available, alignment depends by placement)\n *\n * @static\n * @type {Array}\n * @enum {String}\n * @readonly\n * @method placements\n * @memberof Popper\n */\nvar placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];\n\n// Get rid of `auto` `auto-start` and `auto-end`\nvar validPlacements = placements.slice(3);\n\n/**\n * Given an initial placement, returns all the subsequent placements\n * clockwise (or counter-clockwise).\n *\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement - A valid placement (it accepts variations)\n * @argument {Boolean} counter - Set to true to walk the placements counterclockwise\n * @returns {Array} placements including their variations\n */\nfunction clockwise(placement) {\n var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var index = validPlacements.indexOf(placement);\n var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));\n return counter ? arr.reverse() : arr;\n}\n\nvar BEHAVIORS = {\n FLIP: 'flip',\n CLOCKWISE: 'clockwise',\n COUNTERCLOCKWISE: 'counterclockwise'\n};\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction flip(data, options) {\n // if `inner` modifier is enabled, we can't use the `flip` modifier\n if (isModifierEnabled(data.instance.modifiers, 'inner')) {\n return data;\n }\n\n if (data.flipped && data.placement === data.originalPlacement) {\n // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides\n return data;\n }\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);\n\n var placement = data.placement.split('-')[0];\n var placementOpposite = getOppositePlacement(placement);\n var variation = data.placement.split('-')[1] || '';\n\n var flipOrder = [];\n\n switch (options.behavior) {\n case BEHAVIORS.FLIP:\n flipOrder = [placement, placementOpposite];\n break;\n case BEHAVIORS.CLOCKWISE:\n flipOrder = clockwise(placement);\n break;\n case BEHAVIORS.COUNTERCLOCKWISE:\n flipOrder = clockwise(placement, true);\n break;\n default:\n flipOrder = options.behavior;\n }\n\n flipOrder.forEach(function (step, index) {\n if (placement !== step || flipOrder.length === index + 1) {\n return data;\n }\n\n placement = data.placement.split('-')[0];\n placementOpposite = getOppositePlacement(placement);\n\n var popperOffsets = data.offsets.popper;\n var refOffsets = data.offsets.reference;\n\n // using floor because the reference offsets may contain decimals we are not going to consider here\n var floor = Math.floor;\n var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);\n\n var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);\n var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);\n var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);\n var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);\n\n var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;\n\n // flip the variation if required\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n\n // flips variation if reference element overflows boundaries\n var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);\n\n // flips variation if popper content overflows boundaries\n var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);\n\n var flippedVariation = flippedVariationByRef || flippedVariationByContent;\n\n if (overlapsRef || overflowsBoundaries || flippedVariation) {\n // this boolean to detect any flip loop\n data.flipped = true;\n\n if (overlapsRef || overflowsBoundaries) {\n placement = flipOrder[index + 1];\n }\n\n if (flippedVariation) {\n variation = getOppositeVariation(variation);\n }\n\n data.placement = placement + (variation ? '-' + variation : '');\n\n // this object contains `position`, we want to preserve it along with\n // any additional property we may add in the future\n data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));\n\n data = runModifiers(data.instance.modifiers, data, 'flip');\n }\n });\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction keepTogether(data) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var placement = data.placement.split('-')[0];\n var floor = Math.floor;\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var side = isVertical ? 'right' : 'bottom';\n var opSide = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n if (popper[side] < floor(reference[opSide])) {\n data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];\n }\n if (popper[opSide] > floor(reference[side])) {\n data.offsets.popper[opSide] = floor(reference[side]);\n }\n\n return data;\n}\n\n/**\n * Converts a string containing value + unit into a px value number\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} str - Value + unit string\n * @argument {String} measurement - `height` or `width`\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @returns {Number|String}\n * Value in pixels, or original string if no values were extracted\n */\nfunction toValue(str, measurement, popperOffsets, referenceOffsets) {\n // separate value from unit\n var split = str.match(/((?:\\-|\\+)?\\d*\\.?\\d*)(.*)/);\n var value = +split[1];\n var unit = split[2];\n\n // If it's not a number it's an operator, I guess\n if (!value) {\n return str;\n }\n\n if (unit.indexOf('%') === 0) {\n var element = void 0;\n switch (unit) {\n case '%p':\n element = popperOffsets;\n break;\n case '%':\n case '%r':\n default:\n element = referenceOffsets;\n }\n\n var rect = getClientRect(element);\n return rect[measurement] / 100 * value;\n } else if (unit === 'vh' || unit === 'vw') {\n // if is a vh or vw, we calculate the size based on the viewport\n var size = void 0;\n if (unit === 'vh') {\n size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n } else {\n size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n }\n return size / 100 * value;\n } else {\n // if is an explicit pixel unit, we get rid of the unit and keep the value\n // if is an implicit unit, it's px, and we return just the value\n return value;\n }\n}\n\n/**\n * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} offset\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @argument {String} basePlacement\n * @returns {Array} a two cells array with x and y offsets in numbers\n */\nfunction parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {\n var offsets = [0, 0];\n\n // Use height if placement is left or right and index is 0 otherwise use width\n // in this way the first offset will use an axis and the second one\n // will use the other one\n var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;\n\n // Split the offset string to obtain a list of values and operands\n // The regex addresses values with the plus or minus sign in front (+10, -20, etc)\n var fragments = offset.split(/(\\+|\\-)/).map(function (frag) {\n return frag.trim();\n });\n\n // Detect if the offset string contains a pair of values or a single one\n // they could be separated by comma or space\n var divider = fragments.indexOf(find(fragments, function (frag) {\n return frag.search(/,|\\s/) !== -1;\n }));\n\n if (fragments[divider] && fragments[divider].indexOf(',') === -1) {\n console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');\n }\n\n // If divider is found, we divide the list of values and operands to divide\n // them by ofset X and Y.\n var splitRegex = /\\s*,\\s*|\\s+/;\n var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];\n\n // Convert the values with units to absolute pixels to allow our computations\n ops = ops.map(function (op, index) {\n // Most of the units rely on the orientation of the popper\n var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';\n var mergeWithPrevious = false;\n return op\n // This aggregates any `+` or `-` sign that aren't considered operators\n // e.g.: 10 + +5 => [10, +, +5]\n .reduce(function (a, b) {\n if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {\n a[a.length - 1] = b;\n mergeWithPrevious = true;\n return a;\n } else if (mergeWithPrevious) {\n a[a.length - 1] += b;\n mergeWithPrevious = false;\n return a;\n } else {\n return a.concat(b);\n }\n }, [])\n // Here we convert the string values into number values (in px)\n .map(function (str) {\n return toValue(str, measurement, popperOffsets, referenceOffsets);\n });\n });\n\n // Loop trough the offsets arrays and execute the operations\n ops.forEach(function (op, index) {\n op.forEach(function (frag, index2) {\n if (isNumeric(frag)) {\n offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);\n }\n });\n });\n return offsets;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @argument {Number|String} options.offset=0\n * The offset value as described in the modifier description\n * @returns {Object} The data object, properly modified\n */\nfunction offset(data, _ref) {\n var offset = _ref.offset;\n var placement = data.placement,\n _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var basePlacement = placement.split('-')[0];\n\n var offsets = void 0;\n if (isNumeric(+offset)) {\n offsets = [+offset, 0];\n } else {\n offsets = parseOffset(offset, popper, reference, basePlacement);\n }\n\n if (basePlacement === 'left') {\n popper.top += offsets[0];\n popper.left -= offsets[1];\n } else if (basePlacement === 'right') {\n popper.top += offsets[0];\n popper.left += offsets[1];\n } else if (basePlacement === 'top') {\n popper.left += offsets[0];\n popper.top -= offsets[1];\n } else if (basePlacement === 'bottom') {\n popper.left += offsets[0];\n popper.top += offsets[1];\n }\n\n data.popper = popper;\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction preventOverflow(data, options) {\n var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);\n\n // If offsetParent is the reference element, we really want to\n // go one step up and use the next offsetParent as reference to\n // avoid to make this modifier completely useless and look like broken\n if (data.instance.reference === boundariesElement) {\n boundariesElement = getOffsetParent(boundariesElement);\n }\n\n // NOTE: DOM access here\n // resets the popper's position so that the document size can be calculated excluding\n // the size of the popper element itself\n var transformProp = getSupportedPropertyName('transform');\n var popperStyles = data.instance.popper.style; // assignment to help minification\n var top = popperStyles.top,\n left = popperStyles.left,\n transform = popperStyles[transformProp];\n\n popperStyles.top = '';\n popperStyles.left = '';\n popperStyles[transformProp] = '';\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);\n\n // NOTE: DOM access here\n // restores the original style properties after the offsets have been computed\n popperStyles.top = top;\n popperStyles.left = left;\n popperStyles[transformProp] = transform;\n\n options.boundaries = boundaries;\n\n var order = options.priority;\n var popper = data.offsets.popper;\n\n var check = {\n primary: function primary(placement) {\n var value = popper[placement];\n if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {\n value = Math.max(popper[placement], boundaries[placement]);\n }\n return defineProperty({}, placement, value);\n },\n secondary: function secondary(placement) {\n var mainSide = placement === 'right' ? 'left' : 'top';\n var value = popper[mainSide];\n if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {\n value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));\n }\n return defineProperty({}, mainSide, value);\n }\n };\n\n order.forEach(function (placement) {\n var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';\n popper = _extends({}, popper, check[side](placement));\n });\n\n data.offsets.popper = popper;\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction shift(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var shiftvariation = placement.split('-')[1];\n\n // if shift shiftvariation is specified, run the modifier\n if (shiftvariation) {\n var _data$offsets = data.offsets,\n reference = _data$offsets.reference,\n popper = _data$offsets.popper;\n\n var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;\n var side = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n var shiftOffsets = {\n start: defineProperty({}, side, reference[side]),\n end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])\n };\n\n data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction hide(data) {\n if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {\n return data;\n }\n\n var refRect = data.offsets.reference;\n var bound = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'preventOverflow';\n }).boundaries;\n\n if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === true) {\n return data;\n }\n\n data.hide = true;\n data.attributes['x-out-of-boundaries'] = '';\n } else {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === false) {\n return data;\n }\n\n data.hide = false;\n data.attributes['x-out-of-boundaries'] = false;\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction inner(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;\n\n var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;\n\n popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);\n\n data.placement = getOppositePlacement(placement);\n data.offsets.popper = getClientRect(popper);\n\n return data;\n}\n\n/**\n * Modifier function, each modifier can have a function of this type assigned\n * to its `fn` property.<br />\n * These functions will be called on each update, this means that you must\n * make sure they are performant enough to avoid performance bottlenecks.\n *\n * @function ModifierFn\n * @argument {dataObject} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {dataObject} The data object, properly modified\n */\n\n/**\n * Modifiers are plugins used to alter the behavior of your poppers.<br />\n * Popper.js uses a set of 9 modifiers to provide all the basic functionalities\n * needed by the library.\n *\n * Usually you don't want to override the `order`, `fn` and `onLoad` props.\n * All the other properties are configurations that could be tweaked.\n * @namespace modifiers\n */\nvar modifiers = {\n /**\n * Modifier used to shift the popper on the start or end of its reference\n * element.<br />\n * It will read the variation of the `placement` property.<br />\n * It can be one either `-end` or `-start`.\n * @memberof modifiers\n * @inner\n */\n shift: {\n /** @prop {number} order=100 - Index used to define the order of execution */\n order: 100,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: shift\n },\n\n /**\n * The `offset` modifier can shift your popper on both its axis.\n *\n * It accepts the following units:\n * - `px` or unit-less, interpreted as pixels\n * - `%` or `%r`, percentage relative to the length of the reference element\n * - `%p`, percentage relative to the length of the popper element\n * - `vw`, CSS viewport width unit\n * - `vh`, CSS viewport height unit\n *\n * For length is intended the main axis relative to the placement of the popper.<br />\n * This means that if the placement is `top` or `bottom`, the length will be the\n * `width`. In case of `left` or `right`, it will be the `height`.\n *\n * You can provide a single value (as `Number` or `String`), or a pair of values\n * as `String` divided by a comma or one (or more) white spaces.<br />\n * The latter is a deprecated method because it leads to confusion and will be\n * removed in v2.<br />\n * Additionally, it accepts additions and subtractions between different units.\n * Note that multiplications and divisions aren't supported.\n *\n * Valid examples are:\n * ```\n * 10\n * '10%'\n * '10, 10'\n * '10%, 10'\n * '10 + 10%'\n * '10 - 5vh + 3%'\n * '-10px + 5vh, 5px - 6%'\n * ```\n * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap\n * > with their reference element, unfortunately, you will have to disable the `flip` modifier.\n * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).\n *\n * @memberof modifiers\n * @inner\n */\n offset: {\n /** @prop {number} order=200 - Index used to define the order of execution */\n order: 200,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: offset,\n /** @prop {Number|String} offset=0\n * The offset value as described in the modifier description\n */\n offset: 0\n },\n\n /**\n * Modifier used to prevent the popper from being positioned outside the boundary.\n *\n * A scenario exists where the reference itself is not within the boundaries.<br />\n * We can say it has \"escaped the boundaries\" — or just \"escaped\".<br />\n * In this case we need to decide whether the popper should either:\n *\n * - detach from the reference and remain \"trapped\" in the boundaries, or\n * - if it should ignore the boundary and \"escape with its reference\"\n *\n * When `escapeWithReference` is set to`true` and reference is completely\n * outside its boundaries, the popper will overflow (or completely leave)\n * the boundaries in order to remain attached to the edge of the reference.\n *\n * @memberof modifiers\n * @inner\n */\n preventOverflow: {\n /** @prop {number} order=300 - Index used to define the order of execution */\n order: 300,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: preventOverflow,\n /**\n * @prop {Array} [priority=['left','right','top','bottom']]\n * Popper will try to prevent overflow following these priorities by default,\n * then, it could overflow on the left and on top of the `boundariesElement`\n */\n priority: ['left', 'right', 'top', 'bottom'],\n /**\n * @prop {number} padding=5\n * Amount of pixel used to define a minimum distance between the boundaries\n * and the popper. This makes sure the popper always has a little padding\n * between the edges of its container\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='scrollParent'\n * Boundaries used by the modifier. Can be `scrollParent`, `window`,\n * `viewport` or any DOM element.\n */\n boundariesElement: 'scrollParent'\n },\n\n /**\n * Modifier used to make sure the reference and its popper stay near each other\n * without leaving any gap between the two. Especially useful when the arrow is\n * enabled and you want to ensure that it points to its reference element.\n * It cares only about the first axis. You can still have poppers with margin\n * between the popper and its reference element.\n * @memberof modifiers\n * @inner\n */\n keepTogether: {\n /** @prop {number} order=400 - Index used to define the order of execution */\n order: 400,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: keepTogether\n },\n\n /**\n * This modifier is used to move the `arrowElement` of the popper to make\n * sure it is positioned between the reference element and its popper element.\n * It will read the outer size of the `arrowElement` node to detect how many\n * pixels of conjunction are needed.\n *\n * It has no effect if no `arrowElement` is provided.\n * @memberof modifiers\n * @inner\n */\n arrow: {\n /** @prop {number} order=500 - Index used to define the order of execution */\n order: 500,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: arrow,\n /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */\n element: '[x-arrow]'\n },\n\n /**\n * Modifier used to flip the popper's placement when it starts to overlap its\n * reference element.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n *\n * **NOTE:** this modifier will interrupt the current update cycle and will\n * restart it if it detects the need to flip the placement.\n * @memberof modifiers\n * @inner\n */\n flip: {\n /** @prop {number} order=600 - Index used to define the order of execution */\n order: 600,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: flip,\n /**\n * @prop {String|Array} behavior='flip'\n * The behavior used to change the popper's placement. It can be one of\n * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid\n * placements (with optional variations)\n */\n behavior: 'flip',\n /**\n * @prop {number} padding=5\n * The popper will flip if it hits the edges of the `boundariesElement`\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='viewport'\n * The element which will define the boundaries of the popper position.\n * The popper will never be placed outside of the defined boundaries\n * (except if `keepTogether` is enabled)\n */\n boundariesElement: 'viewport',\n /**\n * @prop {Boolean} flipVariations=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the reference element overlaps its boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariations: false,\n /**\n * @prop {Boolean} flipVariationsByContent=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the popper element overlaps its reference boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariationsByContent: false\n },\n\n /**\n * Modifier used to make the popper flow toward the inner of the reference element.\n * By default, when this modifier is disabled, the popper will be placed outside\n * the reference element.\n * @memberof modifiers\n * @inner\n */\n inner: {\n /** @prop {number} order=700 - Index used to define the order of execution */\n order: 700,\n /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */\n enabled: false,\n /** @prop {ModifierFn} */\n fn: inner\n },\n\n /**\n * Modifier used to hide the popper when its reference element is outside of the\n * popper boundaries. It will set a `x-out-of-boundaries` attribute which can\n * be used to hide with a CSS selector the popper when its reference is\n * out of boundaries.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n * @memberof modifiers\n * @inner\n */\n hide: {\n /** @prop {number} order=800 - Index used to define the order of execution */\n order: 800,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: hide\n },\n\n /**\n * Computes the style that will be applied to the popper element to gets\n * properly positioned.\n *\n * Note that this modifier will not touch the DOM, it just prepares the styles\n * so that `applyStyle` modifier can apply it. This separation is useful\n * in case you need to replace `applyStyle` with a custom implementation.\n *\n * This modifier has `850` as `order` value to maintain backward compatibility\n * with previous versions of Popper.js. Expect the modifiers ordering method\n * to change in future major versions of the library.\n *\n * @memberof modifiers\n * @inner\n */\n computeStyle: {\n /** @prop {number} order=850 - Index used to define the order of execution */\n order: 850,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: computeStyle,\n /**\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: true,\n /**\n * @prop {string} [x='bottom']\n * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.\n * Change this if your popper should grow in a direction different from `bottom`\n */\n x: 'bottom',\n /**\n * @prop {string} [x='left']\n * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.\n * Change this if your popper should grow in a direction different from `right`\n */\n y: 'right'\n },\n\n /**\n * Applies the computed styles to the popper element.\n *\n * All the DOM manipulations are limited to this modifier. This is useful in case\n * you want to integrate Popper.js inside a framework or view library and you\n * want to delegate all the DOM manipulations to it.\n *\n * Note that if you disable this modifier, you must make sure the popper element\n * has its position set to `absolute` before Popper.js can do its work!\n *\n * Just disable this modifier and define your own to achieve the desired effect.\n *\n * @memberof modifiers\n * @inner\n */\n applyStyle: {\n /** @prop {number} order=900 - Index used to define the order of execution */\n order: 900,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: applyStyle,\n /** @prop {Function} */\n onLoad: applyStyleOnLoad,\n /**\n * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: undefined\n }\n};\n\n/**\n * The `dataObject` is an object containing all the information used by Popper.js.\n * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.\n * @name dataObject\n * @property {Object} data.instance The Popper.js instance\n * @property {String} data.placement Placement applied to popper\n * @property {String} data.originalPlacement Placement originally defined on init\n * @property {Boolean} data.flipped True if popper has been flipped by flip modifier\n * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper\n * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier\n * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.boundaries Offsets of the popper boundaries\n * @property {Object} data.offsets The measurements of popper, reference and arrow elements\n * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0\n */\n\n/**\n * Default options provided to Popper.js constructor.<br />\n * These can be overridden using the `options` argument of Popper.js.<br />\n * To override an option, simply pass an object with the same\n * structure of the `options` object, as the 3rd argument. For example:\n * ```\n * new Popper(ref, pop, {\n * modifiers: {\n * preventOverflow: { enabled: false }\n * }\n * })\n * ```\n * @type {Object}\n * @static\n * @memberof Popper\n */\nvar Defaults = {\n /**\n * Popper's placement.\n * @prop {Popper.placements} placement='bottom'\n */\n placement: 'bottom',\n\n /**\n * Set this to true if you want popper to position it self in 'fixed' mode\n * @prop {Boolean} positionFixed=false\n */\n positionFixed: false,\n\n /**\n * Whether events (resize, scroll) are initially enabled.\n * @prop {Boolean} eventsEnabled=true\n */\n eventsEnabled: true,\n\n /**\n * Set to true if you want to automatically remove the popper when\n * you call the `destroy` method.\n * @prop {Boolean} removeOnDestroy=false\n */\n removeOnDestroy: false,\n\n /**\n * Callback called when the popper is created.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onCreate}\n */\n onCreate: function onCreate() {},\n\n /**\n * Callback called when the popper is updated. This callback is not called\n * on the initialization/creation of the popper, but only on subsequent\n * updates.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onUpdate}\n */\n onUpdate: function onUpdate() {},\n\n /**\n * List of modifiers used to modify the offsets before they are applied to the popper.\n * They provide most of the functionalities of Popper.js.\n * @prop {modifiers}\n */\n modifiers: modifiers\n};\n\n/**\n * @callback onCreate\n * @param {dataObject} data\n */\n\n/**\n * @callback onUpdate\n * @param {dataObject} data\n */\n\n// Utils\n// Methods\nvar Popper = function () {\n /**\n * Creates a new Popper.js instance.\n * @class Popper\n * @param {Element|referenceObject} reference - The reference element used to position the popper\n * @param {Element} popper - The HTML / XML element used as the popper\n * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)\n * @return {Object} instance - The generated Popper.js instance\n */\n function Popper(reference, popper) {\n var _this = this;\n\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n classCallCheck(this, Popper);\n\n this.scheduleUpdate = function () {\n return requestAnimationFrame(_this.update);\n };\n\n // make update() debounced, so that it only runs at most once-per-tick\n this.update = debounce(this.update.bind(this));\n\n // with {} we create a new object with the options inside it\n this.options = _extends({}, Popper.Defaults, options);\n\n // init state\n this.state = {\n isDestroyed: false,\n isCreated: false,\n scrollParents: []\n };\n\n // get reference and popper elements (allow jQuery wrappers)\n this.reference = reference && reference.jquery ? reference[0] : reference;\n this.popper = popper && popper.jquery ? popper[0] : popper;\n\n // Deep merge modifiers options\n this.options.modifiers = {};\n Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {\n _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});\n });\n\n // Refactoring modifiers' list (Object => Array)\n this.modifiers = Object.keys(this.options.modifiers).map(function (name) {\n return _extends({\n name: name\n }, _this.options.modifiers[name]);\n })\n // sort the modifiers by order\n .sort(function (a, b) {\n return a.order - b.order;\n });\n\n // modifiers have the ability to execute arbitrary code when Popper.js get inited\n // such code is executed in the same order of its modifier\n // they could add new properties to their options configuration\n // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!\n this.modifiers.forEach(function (modifierOptions) {\n if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {\n modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);\n }\n });\n\n // fire the first update to position the popper in the right place\n this.update();\n\n var eventsEnabled = this.options.eventsEnabled;\n if (eventsEnabled) {\n // setup event listeners, they will take care of update the position in specific situations\n this.enableEventListeners();\n }\n\n this.state.eventsEnabled = eventsEnabled;\n }\n\n // We can't use class properties because they don't get listed in the\n // class prototype and break stuff like Sinon stubs\n\n\n createClass(Popper, [{\n key: 'update',\n value: function update$$1() {\n return update.call(this);\n }\n }, {\n key: 'destroy',\n value: function destroy$$1() {\n return destroy.call(this);\n }\n }, {\n key: 'enableEventListeners',\n value: function enableEventListeners$$1() {\n return enableEventListeners.call(this);\n }\n }, {\n key: 'disableEventListeners',\n value: function disableEventListeners$$1() {\n return disableEventListeners.call(this);\n }\n\n /**\n * Schedules an update. It will run on the next UI update available.\n * @method scheduleUpdate\n * @memberof Popper\n */\n\n\n /**\n * Collection of utilities useful when writing custom modifiers.\n * Starting from version 1.7, this method is available only if you\n * include `popper-utils.js` before `popper.js`.\n *\n * **DEPRECATION**: This way to access PopperUtils is deprecated\n * and will be removed in v2! Use the PopperUtils module directly instead.\n * Due to the high instability of the methods contained in Utils, we can't\n * guarantee them to follow semver. Use them at your own risk!\n * @static\n * @private\n * @type {Object}\n * @deprecated since version 1.8\n * @member Utils\n * @memberof Popper\n */\n\n }]);\n return Popper;\n}();\n\n/**\n * The `referenceObject` is an object that provides an interface compatible with Popper.js\n * and lets you use it as replacement of a real DOM node.<br />\n * You can use this method to position a popper relatively to a set of coordinates\n * in case you don't have a DOM node to use as reference.\n *\n * ```\n * new Popper(referenceObject, popperNode);\n * ```\n *\n * NB: This feature isn't supported in Internet Explorer 10.\n * @name referenceObject\n * @property {Function} data.getBoundingClientRect\n * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.\n * @property {number} data.clientWidth\n * An ES6 getter that will return the width of the virtual reference element.\n * @property {number} data.clientHeight\n * An ES6 getter that will return the height of the virtual reference element.\n */\n\n\nPopper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;\nPopper.placements = placements;\nPopper.Defaults = Defaults;\n\nexport default Popper;\n//# sourceMappingURL=popper.js.map\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper.js (https://popper.js.org/)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n if (this._config.backdrop === 'static') {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n } else {\n this.hide()\n }\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper.js (https://popper.js.org/)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"],"names":["TRANSITION_END","MAX_UID","MILLISECONDS_MULTIPLIER","toType","obj","toString","call","match","toLowerCase","getSpecialTransitionEndEvent","bindType","delegateType","handle","event","$","target","is","handleObj","handler","apply","arguments","undefined","transitionEndEmulator","duration","called","one","Util","setTimeout","triggerTransitionEnd","setTransitionEndSupport","fn","emulateTransitionEnd","special","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","expectedTypes","value","valueType","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","jquery","minMajor","ltMajor","minMinor","minPatch","maxMajor","NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","SELECTOR_DISMISS","EVENT_CLOSE","EVENT_CLOSED","EVENT_CLICK_DATA_API","CLASS_NAME_ALERT","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","_element","close","rootElement","_getRootElement","customEvent","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","CLASS_NAME_ACTIVE","CLASS_NAME_BUTTON","CLASS_NAME_FOCUS","SELECTOR_DATA_TOGGLE_CARROT","SELECTOR_DATA_TOGGLES","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_TOGGLES_BUTTONS","SELECTOR_INPUT","SELECTOR_ACTIVE","SELECTOR_BUTTON","EVENT_FOCUS_BLUR_DATA_API","EVENT_LOAD_DATA_API","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","ARROW_LEFT_KEYCODE","ARROW_RIGHT_KEYCODE","TOUCHEVENT_COMPAT_WAIT","SWIPE_THRESHOLD","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","DIRECTION_NEXT","DIRECTION_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLIDE","EVENT_SLID","EVENT_KEYDOWN","EVENT_MOUSEENTER","EVENT_MOUSELEAVE","EVENT_TOUCHSTART","EVENT_TOUCHMOVE","EVENT_TOUCHEND","EVENT_POINTERDOWN","EVENT_POINTERUP","EVENT_DRAG_START","CLASS_NAME_CAROUSEL","CLASS_NAME_SLIDE","CLASS_NAME_RIGHT","CLASS_NAME_LEFT","CLASS_NAME_NEXT","CLASS_NAME_PREV","CLASS_NAME_POINTER_EVENT","SELECTOR_ACTIVE_ITEM","SELECTOR_ITEM","SELECTOR_ITEM_IMG","SELECTOR_NEXT_PREV","SELECTOR_INDICATORS","SELECTOR_DATA_SLIDE","SELECTOR_DATA_RIDE","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_handleSwipe","absDeltax","abs","_keydown","_addTouchEventListeners","start","originalEvent","pointerType","clientX","touches","move","end","clearTimeout","e","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","isGoingToWrap","delta","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","activeElementIndex","nextElement","nextElementIndex","isCycling","directionalClassName","orderClassName","slidEvent","nextElementInterval","parseInt","defaultInterval","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","EVENT_SHOW","EVENT_SHOWN","EVENT_HIDE","EVENT_HIDDEN","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","CLASS_NAME_COLLAPSED","DIMENSION_WIDTH","DIMENSION_HEIGHT","SELECTOR_ACTIVES","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","complete","capitalizedDimension","scrollSize","getBoundingClientRect","triggerArrayLength","$elem","isTransitioning","hasWidth","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","_extends","ESCAPE_KEYCODE","SPACE_KEYCODE","TAB_KEYCODE","ARROW_UP_KEYCODE","ARROW_DOWN_KEYCODE","RIGHT_MOUSE_BUTTON_WHICH","REGEXP_KEYDOWN","EVENT_CLICK","EVENT_KEYDOWN_DATA_API","EVENT_KEYUP_DATA_API","CLASS_NAME_DISABLED","CLASS_NAME_DROPUP","CLASS_NAME_DROPRIGHT","CLASS_NAME_DROPLEFT","CLASS_NAME_MENURIGHT","CLASS_NAME_POSITION_STATIC","SELECTOR_FORM_CHILD","SELECTOR_MENU","SELECTOR_NAVBAR_NAV","SELECTOR_VISIBLE_ITEMS","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","offset","flip","boundary","reference","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","Popper","referenceElement","_getPopperConfig","body","noop","hideEvent","destroy","update","scheduleUpdate","stopPropagation","constructor","_getPlacement","$parentDropdown","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","backdrop","EVENT_HIDE_PREVENTED","EVENT_FOCUSIN","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_KEYDOWN_DISMISS","EVENT_MOUSEUP_DISMISS","EVENT_MOUSEDOWN_DISMISS","CLASS_NAME_SCROLLABLE","CLASS_NAME_SCROLLBAR_MEASURER","CLASS_NAME_BACKDROP","CLASS_NAME_OPEN","CLASS_NAME_STATIC","SELECTOR_DIALOG","SELECTOR_MODAL_BODY","SELECTOR_DATA_DISMISS","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","forEach","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","clientHeight","overflowY","modalTransitionDuration","modalBody","Node","ELEMENT_NODE","appendChild","removeAttribute","scrollTop","_enforceFocus","shownEvent","transitionComplete","has","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","round","left","right","innerWidth","_getScrollbarWidth","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","uriAttrs","ARIA_ATTRIBUTE_PATTERN","DefaultWhitelist","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","allowedAttributeList","attrName","nodeName","nodeValue","regExp","attrRegex","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","domParser","DOMParser","createdDocument","parseFromString","whitelistKeys","keys","el","elName","attributeList","attributes","whitelistedAttributes","concat","innerHTML","CLASS_PREFIX","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","html","container","fallbackPlacement","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HOVER_STATE_SHOW","HOVER_STATE_OUT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","SELECTOR_TOOLTIP_INNER","SELECTOR_ARROW","TRIGGER_HOVER","TRIGGER_FOCUS","TRIGGER_CLICK","TRIGGER_MANUAL","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","ownerDocument","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","_fixTransition","prevHoverState","_cleanTipClass","getTitle","setElementContent","content","empty","append","text","defaultBsConfig","behavior","arrow","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","find","triggers","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","SELECTOR_TITLE","SELECTOR_CONTENT","Popover","_getContent","method","EVENT_ACTIVATE","EVENT_SCROLL","CLASS_NAME_DROPDOWN_ITEM","SELECTOR_DATA_SPY","SELECTOR_NAV_LIST_GROUP","SELECTOR_NAV_LINKS","SELECTOR_NAV_ITEMS","SELECTOR_LIST_ITEMS","SELECTOR_DROPDOWN","SELECTOR_DROPDOWN_ITEMS","SELECTOR_DROPDOWN_TOGGLE","METHOD_OFFSET","METHOD_POSITION","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targets","map","targetSelector","targetBCR","height","top","sort","pageYOffset","max","_getOffsetHeight","innerHeight","maxScroll","_activate","_clear","isActiveTarget","queries","$link","parents","node","scrollSpys","scrollSpysLength","$spy","CLASS_NAME_DROPDOWN_MENU","SELECTOR_ACTIVE_UL","SELECTOR_DROPDOWN_ACTIVE_CHILD","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","activeElements","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","CLASS_NAME_HIDE","CLASS_NAME_SHOWING","autohide","Toast","_clearTimeout","_close"],"mappings":"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AAC9C;EACA,EAAE,OAAO,IAAI,CAAC;EACd,CAAC;AACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,SAAS,GAAG;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,KAAK,EAAE;EACT;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,KAAK;EACb,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,MAAM,EAAE;EACV;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,MAAM;EACd;EACA;EACA;EACA,IAAI,MAAM,EAAE,CAAC;EACb,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,eAAe,EAAE;EACnB;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,eAAe;EACvB;EACA;EACA;EACA;EACA;EACA,IAAI,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;EAChD;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,OAAO,EAAE,CAAC;EACd;EACA;EACA;EACA;EACA;EACA,IAAI,iBAAiB,EAAE,cAAc;EACrC,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,YAAY,EAAE;EAChB;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,YAAY;EACpB,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,KAAK,EAAE;EACT;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,KAAK;EACb;EACA,IAAI,OAAO,EAAE,WAAW;EACxB,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,IAAI,EAAE;EACR;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,IAAI;EACZ;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,QAAQ,EAAE,MAAM;EACpB;EACA;EACA;EACA;EACA,IAAI,OAAO,EAAE,CAAC;EACd;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,iBAAiB,EAAE,UAAU;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,cAAc,EAAE,KAAK;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,uBAAuB,EAAE,KAAK;EAClC,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,KAAK,EAAE;EACT;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,KAAK;EAClB;EACA,IAAI,EAAE,EAAE,KAAK;EACb,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,IAAI,EAAE;EACR;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,IAAI;EACZ,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,YAAY,EAAE;EAChB;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,YAAY;EACpB;EACA;EACA;EACA;EACA;EACA,IAAI,eAAe,EAAE,IAAI;EACzB;EACA;EACA;EACA;EACA;EACA,IAAI,CAAC,EAAE,QAAQ;EACf;EACA;EACA;EACA;EACA;EACA,IAAI,CAAC,EAAE,OAAO;EACd,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,UAAU,EAAE;EACd;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,UAAU;EAClB;EACA,IAAI,MAAM,EAAE,gBAAgB;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,eAAe,EAAE,SAAS;EAC9B,GAAG;EACH,CAAC,CAAC;AACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,QAAQ,GAAG;EACf;EACA;EACA;EACA;EACA,EAAE,SAAS,EAAE,QAAQ;AACrB;EACA;EACA;EACA;EACA;EACA,EAAE,aAAa,EAAE,KAAK;AACtB;EACA;EACA;EACA;EACA;EACA,EAAE,aAAa,EAAE,IAAI;AACrB;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,eAAe,EAAE,KAAK;AACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,QAAQ,EAAE,SAAS,QAAQ,GAAG,EAAE;AAClC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,QAAQ,EAAE,SAAS,QAAQ,GAAG,EAAE;AAClC;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,SAAS,EAAE,SAAS;EACtB,CAAC,CAAC;AACF;EACA;EACA;EACA;E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"} \ No newline at end of file +{"version":3,"file":"bootstrap.bundle.js","sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/popper.js/dist/esm/popper.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._updateInterval()\n\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n if (!element) {\n return\n }\n\n const elementInterval = parseInt(element.getAttribute('data-interval'), 10)\n\n if (elementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = elementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n this._activeElement = nextElement\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**!\n * @fileOverview Kickass library to create and place poppers near their reference elements.\n * @version 1.16.1\n * @license\n * Copyright (c) 2016 Federico Zivolo and contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';\n\nvar timeoutDuration = function () {\n var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];\n for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {\n if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {\n return 1;\n }\n }\n return 0;\n}();\n\nfunction microtaskDebounce(fn) {\n var called = false;\n return function () {\n if (called) {\n return;\n }\n called = true;\n window.Promise.resolve().then(function () {\n called = false;\n fn();\n });\n };\n}\n\nfunction taskDebounce(fn) {\n var scheduled = false;\n return function () {\n if (!scheduled) {\n scheduled = true;\n setTimeout(function () {\n scheduled = false;\n fn();\n }, timeoutDuration);\n }\n };\n}\n\nvar supportsMicroTasks = isBrowser && window.Promise;\n\n/**\n* Create a debounced version of a method, that's asynchronously deferred\n* but called in the minimum time possible.\n*\n* @method\n* @memberof Popper.Utils\n* @argument {Function} fn\n* @returns {Function}\n*/\nvar debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;\n\n/**\n * Check if the given variable is a function\n * @method\n * @memberof Popper.Utils\n * @argument {Any} functionToCheck - variable to check\n * @returns {Boolean} answer to: is a function?\n */\nfunction isFunction(functionToCheck) {\n var getType = {};\n return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';\n}\n\n/**\n * Get CSS computed property of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Eement} element\n * @argument {String} property\n */\nfunction getStyleComputedProperty(element, property) {\n if (element.nodeType !== 1) {\n return [];\n }\n // NOTE: 1 DOM access here\n var window = element.ownerDocument.defaultView;\n var css = window.getComputedStyle(element, null);\n return property ? css[property] : css;\n}\n\n/**\n * Returns the parentNode or the host of the element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} parent\n */\nfunction getParentNode(element) {\n if (element.nodeName === 'HTML') {\n return element;\n }\n return element.parentNode || element.host;\n}\n\n/**\n * Returns the scrolling parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} scroll parent\n */\nfunction getScrollParent(element) {\n // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n if (!element) {\n return document.body;\n }\n\n switch (element.nodeName) {\n case 'HTML':\n case 'BODY':\n return element.ownerDocument.body;\n case '#document':\n return element.body;\n }\n\n // Firefox want us to check `-x` and `-y` variations as well\n\n var _getStyleComputedProp = getStyleComputedProperty(element),\n overflow = _getStyleComputedProp.overflow,\n overflowX = _getStyleComputedProp.overflowX,\n overflowY = _getStyleComputedProp.overflowY;\n\n if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {\n return element;\n }\n\n return getScrollParent(getParentNode(element));\n}\n\n/**\n * Returns the reference node of the reference object, or the reference object itself.\n * @method\n * @memberof Popper.Utils\n * @param {Element|Object} reference - the reference element (the popper will be relative to this)\n * @returns {Element} parent\n */\nfunction getReferenceNode(reference) {\n return reference && reference.referenceNode ? reference.referenceNode : reference;\n}\n\nvar isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);\nvar isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);\n\n/**\n * Determines if the browser is Internet Explorer\n * @method\n * @memberof Popper.Utils\n * @param {Number} version to check\n * @returns {Boolean} isIE\n */\nfunction isIE(version) {\n if (version === 11) {\n return isIE11;\n }\n if (version === 10) {\n return isIE10;\n }\n return isIE11 || isIE10;\n}\n\n/**\n * Returns the offset parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} offset parent\n */\nfunction getOffsetParent(element) {\n if (!element) {\n return document.documentElement;\n }\n\n var noOffsetParent = isIE(10) ? document.body : null;\n\n // NOTE: 1 DOM access here\n var offsetParent = element.offsetParent || null;\n // Skip hidden elements which don't have an offsetParent\n while (offsetParent === noOffsetParent && element.nextElementSibling) {\n offsetParent = (element = element.nextElementSibling).offsetParent;\n }\n\n var nodeName = offsetParent && offsetParent.nodeName;\n\n if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {\n return element ? element.ownerDocument.documentElement : document.documentElement;\n }\n\n // .offsetParent will return the closest TH, TD or TABLE in case\n // no offsetParent is present, I hate this job...\n if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {\n return getOffsetParent(offsetParent);\n }\n\n return offsetParent;\n}\n\nfunction isOffsetContainer(element) {\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY') {\n return false;\n }\n return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;\n}\n\n/**\n * Finds the root node (document, shadowDOM root) of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} node\n * @returns {Element} root node\n */\nfunction getRoot(node) {\n if (node.parentNode !== null) {\n return getRoot(node.parentNode);\n }\n\n return node;\n}\n\n/**\n * Finds the offset parent common to the two provided nodes\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element1\n * @argument {Element} element2\n * @returns {Element} common offset parent\n */\nfunction findCommonOffsetParent(element1, element2) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {\n return document.documentElement;\n }\n\n // Here we make sure to give as \"start\" the element that comes first in the DOM\n var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;\n var start = order ? element1 : element2;\n var end = order ? element2 : element1;\n\n // Get common ancestor container\n var range = document.createRange();\n range.setStart(start, 0);\n range.setEnd(end, 0);\n var commonAncestorContainer = range.commonAncestorContainer;\n\n // Both nodes are inside #document\n\n if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {\n if (isOffsetContainer(commonAncestorContainer)) {\n return commonAncestorContainer;\n }\n\n return getOffsetParent(commonAncestorContainer);\n }\n\n // one of the nodes is inside shadowDOM, find which one\n var element1root = getRoot(element1);\n if (element1root.host) {\n return findCommonOffsetParent(element1root.host, element2);\n } else {\n return findCommonOffsetParent(element1, getRoot(element2).host);\n }\n}\n\n/**\n * Gets the scroll value of the given element in the given side (top and left)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {String} side `top` or `left`\n * @returns {number} amount of scrolled pixels\n */\nfunction getScroll(element) {\n var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';\n\n var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n var html = element.ownerDocument.documentElement;\n var scrollingElement = element.ownerDocument.scrollingElement || html;\n return scrollingElement[upperSide];\n }\n\n return element[upperSide];\n}\n\n/*\n * Sum or subtract the element scroll values (left and top) from a given rect object\n * @method\n * @memberof Popper.Utils\n * @param {Object} rect - Rect object you want to change\n * @param {HTMLElement} element - The element from the function reads the scroll values\n * @param {Boolean} subtract - set to true if you want to subtract the scroll values\n * @return {Object} rect - The modifier rect object\n */\nfunction includeScroll(rect, element) {\n var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n var modifier = subtract ? -1 : 1;\n rect.top += scrollTop * modifier;\n rect.bottom += scrollTop * modifier;\n rect.left += scrollLeft * modifier;\n rect.right += scrollLeft * modifier;\n return rect;\n}\n\n/*\n * Helper to detect borders of a given element\n * @method\n * @memberof Popper.Utils\n * @param {CSSStyleDeclaration} styles\n * Result of `getStyleComputedProperty` on the given element\n * @param {String} axis - `x` or `y`\n * @return {number} borders - The borders size of the given axis\n */\n\nfunction getBordersSize(styles, axis) {\n var sideA = axis === 'x' ? 'Left' : 'Top';\n var sideB = sideA === 'Left' ? 'Right' : 'Bottom';\n\n return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);\n}\n\nfunction getSize(axis, body, html, computedStyle) {\n return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);\n}\n\nfunction getWindowSizes(document) {\n var body = document.body;\n var html = document.documentElement;\n var computedStyle = isIE(10) && getComputedStyle(html);\n\n return {\n height: getSize('Height', body, html, computedStyle),\n width: getSize('Width', body, html, computedStyle)\n };\n}\n\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\n\n\n\n\nvar defineProperty = function (obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\n/**\n * Given element offsets, generate an output similar to getBoundingClientRect\n * @method\n * @memberof Popper.Utils\n * @argument {Object} offsets\n * @returns {Object} ClientRect like output\n */\nfunction getClientRect(offsets) {\n return _extends({}, offsets, {\n right: offsets.left + offsets.width,\n bottom: offsets.top + offsets.height\n });\n}\n\n/**\n * Get bounding client rect of given element\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} element\n * @return {Object} client rect\n */\nfunction getBoundingClientRect(element) {\n var rect = {};\n\n // IE10 10 FIX: Please, don't ask, the element isn't\n // considered in DOM in some circumstances...\n // This isn't reproducible in IE10 compatibility mode of IE11\n try {\n if (isIE(10)) {\n rect = element.getBoundingClientRect();\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n rect.top += scrollTop;\n rect.left += scrollLeft;\n rect.bottom += scrollTop;\n rect.right += scrollLeft;\n } else {\n rect = element.getBoundingClientRect();\n }\n } catch (e) {}\n\n var result = {\n left: rect.left,\n top: rect.top,\n width: rect.right - rect.left,\n height: rect.bottom - rect.top\n };\n\n // subtract scrollbar size from sizes\n var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};\n var width = sizes.width || element.clientWidth || result.width;\n var height = sizes.height || element.clientHeight || result.height;\n\n var horizScrollbar = element.offsetWidth - width;\n var vertScrollbar = element.offsetHeight - height;\n\n // if an hypothetical scrollbar is detected, we must be sure it's not a `border`\n // we make this check conditional for performance reasons\n if (horizScrollbar || vertScrollbar) {\n var styles = getStyleComputedProperty(element);\n horizScrollbar -= getBordersSize(styles, 'x');\n vertScrollbar -= getBordersSize(styles, 'y');\n\n result.width -= horizScrollbar;\n result.height -= vertScrollbar;\n }\n\n return getClientRect(result);\n}\n\nfunction getOffsetRectRelativeToArbitraryNode(children, parent) {\n var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var isIE10 = isIE(10);\n var isHTML = parent.nodeName === 'HTML';\n var childrenRect = getBoundingClientRect(children);\n var parentRect = getBoundingClientRect(parent);\n var scrollParent = getScrollParent(children);\n\n var styles = getStyleComputedProperty(parent);\n var borderTopWidth = parseFloat(styles.borderTopWidth);\n var borderLeftWidth = parseFloat(styles.borderLeftWidth);\n\n // In cases where the parent is fixed, we must ignore negative scroll in offset calc\n if (fixedPosition && isHTML) {\n parentRect.top = Math.max(parentRect.top, 0);\n parentRect.left = Math.max(parentRect.left, 0);\n }\n var offsets = getClientRect({\n top: childrenRect.top - parentRect.top - borderTopWidth,\n left: childrenRect.left - parentRect.left - borderLeftWidth,\n width: childrenRect.width,\n height: childrenRect.height\n });\n offsets.marginTop = 0;\n offsets.marginLeft = 0;\n\n // Subtract margins of documentElement in case it's being used as parent\n // we do this only on HTML because it's the only element that behaves\n // differently when margins are applied to it. The margins are included in\n // the box of the documentElement, in the other cases not.\n if (!isIE10 && isHTML) {\n var marginTop = parseFloat(styles.marginTop);\n var marginLeft = parseFloat(styles.marginLeft);\n\n offsets.top -= borderTopWidth - marginTop;\n offsets.bottom -= borderTopWidth - marginTop;\n offsets.left -= borderLeftWidth - marginLeft;\n offsets.right -= borderLeftWidth - marginLeft;\n\n // Attach marginTop and marginLeft because in some circumstances we may need them\n offsets.marginTop = marginTop;\n offsets.marginLeft = marginLeft;\n }\n\n if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {\n offsets = includeScroll(offsets, parent);\n }\n\n return offsets;\n}\n\nfunction getViewportOffsetRectRelativeToArtbitraryNode(element) {\n var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var html = element.ownerDocument.documentElement;\n var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);\n var width = Math.max(html.clientWidth, window.innerWidth || 0);\n var height = Math.max(html.clientHeight, window.innerHeight || 0);\n\n var scrollTop = !excludeScroll ? getScroll(html) : 0;\n var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;\n\n var offset = {\n top: scrollTop - relativeOffset.top + relativeOffset.marginTop,\n left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,\n width: width,\n height: height\n };\n\n return getClientRect(offset);\n}\n\n/**\n * Check if the given element is fixed or is inside a fixed parent\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {Element} customContainer\n * @returns {Boolean} answer to \"isFixed?\"\n */\nfunction isFixed(element) {\n var nodeName = element.nodeName;\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n return false;\n }\n if (getStyleComputedProperty(element, 'position') === 'fixed') {\n return true;\n }\n var parentNode = getParentNode(element);\n if (!parentNode) {\n return false;\n }\n return isFixed(parentNode);\n}\n\n/**\n * Finds the first parent of an element that has a transformed property defined\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} first transformed parent or documentElement\n */\n\nfunction getFixedPositionOffsetParent(element) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element || !element.parentElement || isIE()) {\n return document.documentElement;\n }\n var el = element.parentElement;\n while (el && getStyleComputedProperty(el, 'transform') === 'none') {\n el = el.parentElement;\n }\n return el || document.documentElement;\n}\n\n/**\n * Computed the boundaries limits and return them\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} popper\n * @param {HTMLElement} reference\n * @param {number} padding\n * @param {HTMLElement} boundariesElement - Element used to define the boundaries\n * @param {Boolean} fixedPosition - Is in fixed position mode\n * @returns {Object} Coordinates of the boundaries\n */\nfunction getBoundaries(popper, reference, padding, boundariesElement) {\n var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n\n // NOTE: 1 DOM access here\n\n var boundaries = { top: 0, left: 0 };\n var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n\n // Handle viewport case\n if (boundariesElement === 'viewport') {\n boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);\n } else {\n // Handle other cases based on DOM element used as boundaries\n var boundariesNode = void 0;\n if (boundariesElement === 'scrollParent') {\n boundariesNode = getScrollParent(getParentNode(reference));\n if (boundariesNode.nodeName === 'BODY') {\n boundariesNode = popper.ownerDocument.documentElement;\n }\n } else if (boundariesElement === 'window') {\n boundariesNode = popper.ownerDocument.documentElement;\n } else {\n boundariesNode = boundariesElement;\n }\n\n var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);\n\n // In case of HTML, we need a different computation\n if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {\n var _getWindowSizes = getWindowSizes(popper.ownerDocument),\n height = _getWindowSizes.height,\n width = _getWindowSizes.width;\n\n boundaries.top += offsets.top - offsets.marginTop;\n boundaries.bottom = height + offsets.top;\n boundaries.left += offsets.left - offsets.marginLeft;\n boundaries.right = width + offsets.left;\n } else {\n // for all the other DOM elements, this one is good\n boundaries = offsets;\n }\n }\n\n // Add paddings\n padding = padding || 0;\n var isPaddingNumber = typeof padding === 'number';\n boundaries.left += isPaddingNumber ? padding : padding.left || 0;\n boundaries.top += isPaddingNumber ? padding : padding.top || 0;\n boundaries.right -= isPaddingNumber ? padding : padding.right || 0;\n boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;\n\n return boundaries;\n}\n\nfunction getArea(_ref) {\n var width = _ref.width,\n height = _ref.height;\n\n return width * height;\n}\n\n/**\n * Utility used to transform the `auto` placement to the placement with more\n * available space.\n * @method\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {\n var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n if (placement.indexOf('auto') === -1) {\n return placement;\n }\n\n var boundaries = getBoundaries(popper, reference, padding, boundariesElement);\n\n var rects = {\n top: {\n width: boundaries.width,\n height: refRect.top - boundaries.top\n },\n right: {\n width: boundaries.right - refRect.right,\n height: boundaries.height\n },\n bottom: {\n width: boundaries.width,\n height: boundaries.bottom - refRect.bottom\n },\n left: {\n width: refRect.left - boundaries.left,\n height: boundaries.height\n }\n };\n\n var sortedAreas = Object.keys(rects).map(function (key) {\n return _extends({\n key: key\n }, rects[key], {\n area: getArea(rects[key])\n });\n }).sort(function (a, b) {\n return b.area - a.area;\n });\n\n var filteredAreas = sortedAreas.filter(function (_ref2) {\n var width = _ref2.width,\n height = _ref2.height;\n return width >= popper.clientWidth && height >= popper.clientHeight;\n });\n\n var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;\n\n var variation = placement.split('-')[1];\n\n return computedPlacement + (variation ? '-' + variation : '');\n}\n\n/**\n * Get offsets to the reference element\n * @method\n * @memberof Popper.Utils\n * @param {Object} state\n * @param {Element} popper - the popper element\n * @param {Element} reference - the reference element (the popper will be relative to this)\n * @param {Element} fixedPosition - is in fixed position mode\n * @returns {Object} An object containing the offsets which will be applied to the popper\n */\nfunction getReferenceOffsets(state, popper, reference) {\n var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n\n var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);\n}\n\n/**\n * Get the outer sizes of the given element (offset size + margins)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Object} object containing width and height properties\n */\nfunction getOuterSizes(element) {\n var window = element.ownerDocument.defaultView;\n var styles = window.getComputedStyle(element);\n var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);\n var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);\n var result = {\n width: element.offsetWidth + y,\n height: element.offsetHeight + x\n };\n return result;\n}\n\n/**\n * Get the opposite placement of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement\n * @returns {String} flipped placement\n */\nfunction getOppositePlacement(placement) {\n var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}\n\n/**\n * Get offsets to the popper\n * @method\n * @memberof Popper.Utils\n * @param {Object} position - CSS position the Popper will get applied\n * @param {HTMLElement} popper - the popper element\n * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)\n * @param {String} placement - one of the valid placement options\n * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper\n */\nfunction getPopperOffsets(popper, referenceOffsets, placement) {\n placement = placement.split('-')[0];\n\n // Get popper node sizes\n var popperRect = getOuterSizes(popper);\n\n // Add position, width and height to our offsets object\n var popperOffsets = {\n width: popperRect.width,\n height: popperRect.height\n };\n\n // depending by the popper placement we have to compute its offsets slightly differently\n var isHoriz = ['right', 'left'].indexOf(placement) !== -1;\n var mainSide = isHoriz ? 'top' : 'left';\n var secondarySide = isHoriz ? 'left' : 'top';\n var measurement = isHoriz ? 'height' : 'width';\n var secondaryMeasurement = !isHoriz ? 'height' : 'width';\n\n popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;\n if (placement === secondarySide) {\n popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];\n } else {\n popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];\n }\n\n return popperOffsets;\n}\n\n/**\n * Mimics the `find` method of Array\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction find(arr, check) {\n // use native find if supported\n if (Array.prototype.find) {\n return arr.find(check);\n }\n\n // use `filter` to obtain the same behavior of `find`\n return arr.filter(check)[0];\n}\n\n/**\n * Return the index of the matching object\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction findIndex(arr, prop, value) {\n // use native findIndex if supported\n if (Array.prototype.findIndex) {\n return arr.findIndex(function (cur) {\n return cur[prop] === value;\n });\n }\n\n // use `find` + `indexOf` if `findIndex` isn't supported\n var match = find(arr, function (obj) {\n return obj[prop] === value;\n });\n return arr.indexOf(match);\n}\n\n/**\n * Loop trough the list of modifiers and run them in order,\n * each of them will then edit the data object.\n * @method\n * @memberof Popper.Utils\n * @param {dataObject} data\n * @param {Array} modifiers\n * @param {String} ends - Optional modifier name used as stopper\n * @returns {dataObject}\n */\nfunction runModifiers(modifiers, data, ends) {\n var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));\n\n modifiersToRun.forEach(function (modifier) {\n if (modifier['function']) {\n // eslint-disable-line dot-notation\n console.warn('`modifier.function` is deprecated, use `modifier.fn`!');\n }\n var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation\n if (modifier.enabled && isFunction(fn)) {\n // Add properties to offsets to make them a complete clientRect object\n // we do this before each modifier to make sure the previous one doesn't\n // mess with these values\n data.offsets.popper = getClientRect(data.offsets.popper);\n data.offsets.reference = getClientRect(data.offsets.reference);\n\n data = fn(data, modifier);\n }\n });\n\n return data;\n}\n\n/**\n * Updates the position of the popper, computing the new offsets and applying\n * the new style.<br />\n * Prefer `scheduleUpdate` over `update` because of performance reasons.\n * @method\n * @memberof Popper\n */\nfunction update() {\n // if popper is destroyed, don't perform any further update\n if (this.state.isDestroyed) {\n return;\n }\n\n var data = {\n instance: this,\n styles: {},\n arrowStyles: {},\n attributes: {},\n flipped: false,\n offsets: {}\n };\n\n // compute reference element offsets\n data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);\n\n // store the computed placement inside `originalPlacement`\n data.originalPlacement = data.placement;\n\n data.positionFixed = this.options.positionFixed;\n\n // compute the popper offsets\n data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);\n\n data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';\n\n // run the modifiers\n data = runModifiers(this.modifiers, data);\n\n // the first `update` will call `onCreate` callback\n // the other ones will call `onUpdate` callback\n if (!this.state.isCreated) {\n this.state.isCreated = true;\n this.options.onCreate(data);\n } else {\n this.options.onUpdate(data);\n }\n}\n\n/**\n * Helper used to know if the given modifier is enabled.\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean}\n */\nfunction isModifierEnabled(modifiers, modifierName) {\n return modifiers.some(function (_ref) {\n var name = _ref.name,\n enabled = _ref.enabled;\n return enabled && name === modifierName;\n });\n}\n\n/**\n * Get the prefixed supported property name\n * @method\n * @memberof Popper.Utils\n * @argument {String} property (camelCase)\n * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)\n */\nfunction getSupportedPropertyName(property) {\n var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];\n var upperProp = property.charAt(0).toUpperCase() + property.slice(1);\n\n for (var i = 0; i < prefixes.length; i++) {\n var prefix = prefixes[i];\n var toCheck = prefix ? '' + prefix + upperProp : property;\n if (typeof document.body.style[toCheck] !== 'undefined') {\n return toCheck;\n }\n }\n return null;\n}\n\n/**\n * Destroys the popper.\n * @method\n * @memberof Popper\n */\nfunction destroy() {\n this.state.isDestroyed = true;\n\n // touch DOM only if `applyStyle` modifier is enabled\n if (isModifierEnabled(this.modifiers, 'applyStyle')) {\n this.popper.removeAttribute('x-placement');\n this.popper.style.position = '';\n this.popper.style.top = '';\n this.popper.style.left = '';\n this.popper.style.right = '';\n this.popper.style.bottom = '';\n this.popper.style.willChange = '';\n this.popper.style[getSupportedPropertyName('transform')] = '';\n }\n\n this.disableEventListeners();\n\n // remove the popper if user explicitly asked for the deletion on destroy\n // do not use `remove` because IE11 doesn't support it\n if (this.options.removeOnDestroy) {\n this.popper.parentNode.removeChild(this.popper);\n }\n return this;\n}\n\n/**\n * Get the window associated with the element\n * @argument {Element} element\n * @returns {Window}\n */\nfunction getWindow(element) {\n var ownerDocument = element.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView : window;\n}\n\nfunction attachToScrollParents(scrollParent, event, callback, scrollParents) {\n var isBody = scrollParent.nodeName === 'BODY';\n var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;\n target.addEventListener(event, callback, { passive: true });\n\n if (!isBody) {\n attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);\n }\n scrollParents.push(target);\n}\n\n/**\n * Setup needed event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction setupEventListeners(reference, options, state, updateBound) {\n // Resize event listener on window\n state.updateBound = updateBound;\n getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });\n\n // Scroll event listener on scroll parents\n var scrollElement = getScrollParent(reference);\n attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);\n state.scrollElement = scrollElement;\n state.eventsEnabled = true;\n\n return state;\n}\n\n/**\n * It will add resize/scroll events and start recalculating\n * position of the popper element when they are triggered.\n * @method\n * @memberof Popper\n */\nfunction enableEventListeners() {\n if (!this.state.eventsEnabled) {\n this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);\n }\n}\n\n/**\n * Remove event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction removeEventListeners(reference, state) {\n // Remove resize event listener on window\n getWindow(reference).removeEventListener('resize', state.updateBound);\n\n // Remove scroll event listener on scroll parents\n state.scrollParents.forEach(function (target) {\n target.removeEventListener('scroll', state.updateBound);\n });\n\n // Reset state\n state.updateBound = null;\n state.scrollParents = [];\n state.scrollElement = null;\n state.eventsEnabled = false;\n return state;\n}\n\n/**\n * It will remove resize/scroll events and won't recalculate popper position\n * when they are triggered. It also won't trigger `onUpdate` callback anymore,\n * unless you call `update` method manually.\n * @method\n * @memberof Popper\n */\nfunction disableEventListeners() {\n if (this.state.eventsEnabled) {\n cancelAnimationFrame(this.scheduleUpdate);\n this.state = removeEventListeners(this.reference, this.state);\n }\n}\n\n/**\n * Tells if a given input is a number\n * @method\n * @memberof Popper.Utils\n * @param {*} input to check\n * @return {Boolean}\n */\nfunction isNumeric(n) {\n return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n/**\n * Set the style to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the style to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setStyles(element, styles) {\n Object.keys(styles).forEach(function (prop) {\n var unit = '';\n // add unit if the value is numeric and is one of the following\n if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {\n unit = 'px';\n }\n element.style[prop] = styles[prop] + unit;\n });\n}\n\n/**\n * Set the attributes to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the attributes to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setAttributes(element, attributes) {\n Object.keys(attributes).forEach(function (prop) {\n var value = attributes[prop];\n if (value !== false) {\n element.setAttribute(prop, attributes[prop]);\n } else {\n element.removeAttribute(prop);\n }\n });\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} data.styles - List of style properties - values to apply to popper element\n * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The same data object\n */\nfunction applyStyle(data) {\n // any property present in `data.styles` will be applied to the popper,\n // in this way we can make the 3rd party modifiers add custom styles to it\n // Be aware, modifiers could override the properties defined in the previous\n // lines of this modifier!\n setStyles(data.instance.popper, data.styles);\n\n // any property present in `data.attributes` will be applied to the popper,\n // they will be set as HTML attributes of the element\n setAttributes(data.instance.popper, data.attributes);\n\n // if arrowElement is defined and arrowStyles has some properties\n if (data.arrowElement && Object.keys(data.arrowStyles).length) {\n setStyles(data.arrowElement, data.arrowStyles);\n }\n\n return data;\n}\n\n/**\n * Set the x-placement attribute before everything else because it could be used\n * to add margins to the popper margins needs to be calculated to get the\n * correct popper offsets.\n * @method\n * @memberof Popper.modifiers\n * @param {HTMLElement} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper\n * @param {Object} options - Popper.js options\n */\nfunction applyStyleOnLoad(reference, popper, options, modifierOptions, state) {\n // compute reference element offsets\n var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);\n\n popper.setAttribute('x-placement', placement);\n\n // Apply `position` to popper before anything else because\n // without the position applied we can't guarantee correct computations\n setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });\n\n return options;\n}\n\n/**\n * @function\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Boolean} shouldRound - If the offsets should be rounded at all\n * @returns {Object} The popper's position offsets rounded\n *\n * The tale of pixel-perfect positioning. It's still not 100% perfect, but as\n * good as it can be within reason.\n * Discussion here: https://github.com/FezVrasta/popper.js/pull/715\n *\n * Low DPI screens cause a popper to be blurry if not using full pixels (Safari\n * as well on High DPI screens).\n *\n * Firefox prefers no rounding for positioning and does not have blurriness on\n * high DPI screens.\n *\n * Only horizontal placement and left/right values need to be considered.\n */\nfunction getRoundedOffsets(data, shouldRound) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n var round = Math.round,\n floor = Math.floor;\n\n var noRound = function noRound(v) {\n return v;\n };\n\n var referenceWidth = round(reference.width);\n var popperWidth = round(popper.width);\n\n var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;\n var isVariation = data.placement.indexOf('-') !== -1;\n var sameWidthParity = referenceWidth % 2 === popperWidth % 2;\n var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;\n\n var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;\n var verticalToInteger = !shouldRound ? noRound : round;\n\n return {\n left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),\n top: verticalToInteger(popper.top),\n bottom: verticalToInteger(popper.bottom),\n right: horizontalToInteger(popper.right)\n };\n}\n\nvar isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeStyle(data, options) {\n var x = options.x,\n y = options.y;\n var popper = data.offsets.popper;\n\n // Remove this legacy support in Popper.js v2\n\n var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'applyStyle';\n }).gpuAcceleration;\n if (legacyGpuAccelerationOption !== undefined) {\n console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');\n }\n var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;\n\n var offsetParent = getOffsetParent(data.instance.popper);\n var offsetParentRect = getBoundingClientRect(offsetParent);\n\n // Styles\n var styles = {\n position: popper.position\n };\n\n var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);\n\n var sideA = x === 'bottom' ? 'top' : 'bottom';\n var sideB = y === 'right' ? 'left' : 'right';\n\n // if gpuAcceleration is set to `true` and transform is supported,\n // we use `translate3d` to apply the position to the popper we\n // automatically use the supported prefixed version if needed\n var prefixedProperty = getSupportedPropertyName('transform');\n\n // now, let's make a step back and look at this code closely (wtf?)\n // If the content of the popper grows once it's been positioned, it\n // may happen that the popper gets misplaced because of the new content\n // overflowing its reference element\n // To avoid this problem, we provide two options (x and y), which allow\n // the consumer to define the offset origin.\n // If we position a popper on top of a reference element, we can set\n // `x` to `top` to make the popper grow towards its top instead of\n // its bottom.\n var left = void 0,\n top = void 0;\n if (sideA === 'bottom') {\n // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)\n // and not the bottom of the html element\n if (offsetParent.nodeName === 'HTML') {\n top = -offsetParent.clientHeight + offsets.bottom;\n } else {\n top = -offsetParentRect.height + offsets.bottom;\n }\n } else {\n top = offsets.top;\n }\n if (sideB === 'right') {\n if (offsetParent.nodeName === 'HTML') {\n left = -offsetParent.clientWidth + offsets.right;\n } else {\n left = -offsetParentRect.width + offsets.right;\n }\n } else {\n left = offsets.left;\n }\n if (gpuAcceleration && prefixedProperty) {\n styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';\n styles[sideA] = 0;\n styles[sideB] = 0;\n styles.willChange = 'transform';\n } else {\n // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties\n var invertTop = sideA === 'bottom' ? -1 : 1;\n var invertLeft = sideB === 'right' ? -1 : 1;\n styles[sideA] = top * invertTop;\n styles[sideB] = left * invertLeft;\n styles.willChange = sideA + ', ' + sideB;\n }\n\n // Attributes\n var attributes = {\n 'x-placement': data.placement\n };\n\n // Update `data` attributes, styles and arrowStyles\n data.attributes = _extends({}, attributes, data.attributes);\n data.styles = _extends({}, styles, data.styles);\n data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);\n\n return data;\n}\n\n/**\n * Helper used to know if the given modifier depends from another one.<br />\n * It checks if the needed modifier is listed and enabled.\n * @method\n * @memberof Popper.Utils\n * @param {Array} modifiers - list of modifiers\n * @param {String} requestingName - name of requesting modifier\n * @param {String} requestedName - name of requested modifier\n * @returns {Boolean}\n */\nfunction isModifierRequired(modifiers, requestingName, requestedName) {\n var requesting = find(modifiers, function (_ref) {\n var name = _ref.name;\n return name === requestingName;\n });\n\n var isRequired = !!requesting && modifiers.some(function (modifier) {\n return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;\n });\n\n if (!isRequired) {\n var _requesting = '`' + requestingName + '`';\n var requested = '`' + requestedName + '`';\n console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');\n }\n return isRequired;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction arrow(data, options) {\n var _data$offsets$arrow;\n\n // arrow depends on keepTogether in order to work\n if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {\n return data;\n }\n\n var arrowElement = options.element;\n\n // if arrowElement is a string, suppose it's a CSS selector\n if (typeof arrowElement === 'string') {\n arrowElement = data.instance.popper.querySelector(arrowElement);\n\n // if arrowElement is not found, don't run the modifier\n if (!arrowElement) {\n return data;\n }\n } else {\n // if the arrowElement isn't a query selector we must check that the\n // provided DOM node is child of its popper node\n if (!data.instance.popper.contains(arrowElement)) {\n console.warn('WARNING: `arrow.element` must be child of its popper element!');\n return data;\n }\n }\n\n var placement = data.placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isVertical = ['left', 'right'].indexOf(placement) !== -1;\n\n var len = isVertical ? 'height' : 'width';\n var sideCapitalized = isVertical ? 'Top' : 'Left';\n var side = sideCapitalized.toLowerCase();\n var altSide = isVertical ? 'left' : 'top';\n var opSide = isVertical ? 'bottom' : 'right';\n var arrowElementSize = getOuterSizes(arrowElement)[len];\n\n //\n // extends keepTogether behavior making sure the popper and its\n // reference have enough pixels in conjunction\n //\n\n // top/left side\n if (reference[opSide] - arrowElementSize < popper[side]) {\n data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);\n }\n // bottom/right side\n if (reference[side] + arrowElementSize > popper[opSide]) {\n data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];\n }\n data.offsets.popper = getClientRect(data.offsets.popper);\n\n // compute center of the popper\n var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;\n\n // Compute the sideValue using the updated popper offsets\n // take popper margin in account because we don't have this info available\n var css = getStyleComputedProperty(data.instance.popper);\n var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);\n var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);\n var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;\n\n // prevent arrowElement from being placed not contiguously to its popper\n sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);\n\n data.arrowElement = arrowElement;\n data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);\n\n return data;\n}\n\n/**\n * Get the opposite placement variation of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement variation\n * @returns {String} flipped placement variation\n */\nfunction getOppositeVariation(variation) {\n if (variation === 'end') {\n return 'start';\n } else if (variation === 'start') {\n return 'end';\n }\n return variation;\n}\n\n/**\n * List of accepted placements to use as values of the `placement` option.<br />\n * Valid placements are:\n * - `auto`\n * - `top`\n * - `right`\n * - `bottom`\n * - `left`\n *\n * Each placement can have a variation from this list:\n * - `-start`\n * - `-end`\n *\n * Variations are interpreted easily if you think of them as the left to right\n * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`\n * is right.<br />\n * Vertically (`left` and `right`), `start` is top and `end` is bottom.\n *\n * Some valid examples are:\n * - `top-end` (on top of reference, right aligned)\n * - `right-start` (on right of reference, top aligned)\n * - `bottom` (on bottom, centered)\n * - `auto-end` (on the side with more space available, alignment depends by placement)\n *\n * @static\n * @type {Array}\n * @enum {String}\n * @readonly\n * @method placements\n * @memberof Popper\n */\nvar placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];\n\n// Get rid of `auto` `auto-start` and `auto-end`\nvar validPlacements = placements.slice(3);\n\n/**\n * Given an initial placement, returns all the subsequent placements\n * clockwise (or counter-clockwise).\n *\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement - A valid placement (it accepts variations)\n * @argument {Boolean} counter - Set to true to walk the placements counterclockwise\n * @returns {Array} placements including their variations\n */\nfunction clockwise(placement) {\n var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var index = validPlacements.indexOf(placement);\n var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));\n return counter ? arr.reverse() : arr;\n}\n\nvar BEHAVIORS = {\n FLIP: 'flip',\n CLOCKWISE: 'clockwise',\n COUNTERCLOCKWISE: 'counterclockwise'\n};\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction flip(data, options) {\n // if `inner` modifier is enabled, we can't use the `flip` modifier\n if (isModifierEnabled(data.instance.modifiers, 'inner')) {\n return data;\n }\n\n if (data.flipped && data.placement === data.originalPlacement) {\n // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides\n return data;\n }\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);\n\n var placement = data.placement.split('-')[0];\n var placementOpposite = getOppositePlacement(placement);\n var variation = data.placement.split('-')[1] || '';\n\n var flipOrder = [];\n\n switch (options.behavior) {\n case BEHAVIORS.FLIP:\n flipOrder = [placement, placementOpposite];\n break;\n case BEHAVIORS.CLOCKWISE:\n flipOrder = clockwise(placement);\n break;\n case BEHAVIORS.COUNTERCLOCKWISE:\n flipOrder = clockwise(placement, true);\n break;\n default:\n flipOrder = options.behavior;\n }\n\n flipOrder.forEach(function (step, index) {\n if (placement !== step || flipOrder.length === index + 1) {\n return data;\n }\n\n placement = data.placement.split('-')[0];\n placementOpposite = getOppositePlacement(placement);\n\n var popperOffsets = data.offsets.popper;\n var refOffsets = data.offsets.reference;\n\n // using floor because the reference offsets may contain decimals we are not going to consider here\n var floor = Math.floor;\n var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);\n\n var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);\n var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);\n var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);\n var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);\n\n var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;\n\n // flip the variation if required\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n\n // flips variation if reference element overflows boundaries\n var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);\n\n // flips variation if popper content overflows boundaries\n var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);\n\n var flippedVariation = flippedVariationByRef || flippedVariationByContent;\n\n if (overlapsRef || overflowsBoundaries || flippedVariation) {\n // this boolean to detect any flip loop\n data.flipped = true;\n\n if (overlapsRef || overflowsBoundaries) {\n placement = flipOrder[index + 1];\n }\n\n if (flippedVariation) {\n variation = getOppositeVariation(variation);\n }\n\n data.placement = placement + (variation ? '-' + variation : '');\n\n // this object contains `position`, we want to preserve it along with\n // any additional property we may add in the future\n data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));\n\n data = runModifiers(data.instance.modifiers, data, 'flip');\n }\n });\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction keepTogether(data) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var placement = data.placement.split('-')[0];\n var floor = Math.floor;\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var side = isVertical ? 'right' : 'bottom';\n var opSide = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n if (popper[side] < floor(reference[opSide])) {\n data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];\n }\n if (popper[opSide] > floor(reference[side])) {\n data.offsets.popper[opSide] = floor(reference[side]);\n }\n\n return data;\n}\n\n/**\n * Converts a string containing value + unit into a px value number\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} str - Value + unit string\n * @argument {String} measurement - `height` or `width`\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @returns {Number|String}\n * Value in pixels, or original string if no values were extracted\n */\nfunction toValue(str, measurement, popperOffsets, referenceOffsets) {\n // separate value from unit\n var split = str.match(/((?:\\-|\\+)?\\d*\\.?\\d*)(.*)/);\n var value = +split[1];\n var unit = split[2];\n\n // If it's not a number it's an operator, I guess\n if (!value) {\n return str;\n }\n\n if (unit.indexOf('%') === 0) {\n var element = void 0;\n switch (unit) {\n case '%p':\n element = popperOffsets;\n break;\n case '%':\n case '%r':\n default:\n element = referenceOffsets;\n }\n\n var rect = getClientRect(element);\n return rect[measurement] / 100 * value;\n } else if (unit === 'vh' || unit === 'vw') {\n // if is a vh or vw, we calculate the size based on the viewport\n var size = void 0;\n if (unit === 'vh') {\n size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n } else {\n size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n }\n return size / 100 * value;\n } else {\n // if is an explicit pixel unit, we get rid of the unit and keep the value\n // if is an implicit unit, it's px, and we return just the value\n return value;\n }\n}\n\n/**\n * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} offset\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @argument {String} basePlacement\n * @returns {Array} a two cells array with x and y offsets in numbers\n */\nfunction parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {\n var offsets = [0, 0];\n\n // Use height if placement is left or right and index is 0 otherwise use width\n // in this way the first offset will use an axis and the second one\n // will use the other one\n var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;\n\n // Split the offset string to obtain a list of values and operands\n // The regex addresses values with the plus or minus sign in front (+10, -20, etc)\n var fragments = offset.split(/(\\+|\\-)/).map(function (frag) {\n return frag.trim();\n });\n\n // Detect if the offset string contains a pair of values or a single one\n // they could be separated by comma or space\n var divider = fragments.indexOf(find(fragments, function (frag) {\n return frag.search(/,|\\s/) !== -1;\n }));\n\n if (fragments[divider] && fragments[divider].indexOf(',') === -1) {\n console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');\n }\n\n // If divider is found, we divide the list of values and operands to divide\n // them by ofset X and Y.\n var splitRegex = /\\s*,\\s*|\\s+/;\n var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];\n\n // Convert the values with units to absolute pixels to allow our computations\n ops = ops.map(function (op, index) {\n // Most of the units rely on the orientation of the popper\n var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';\n var mergeWithPrevious = false;\n return op\n // This aggregates any `+` or `-` sign that aren't considered operators\n // e.g.: 10 + +5 => [10, +, +5]\n .reduce(function (a, b) {\n if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {\n a[a.length - 1] = b;\n mergeWithPrevious = true;\n return a;\n } else if (mergeWithPrevious) {\n a[a.length - 1] += b;\n mergeWithPrevious = false;\n return a;\n } else {\n return a.concat(b);\n }\n }, [])\n // Here we convert the string values into number values (in px)\n .map(function (str) {\n return toValue(str, measurement, popperOffsets, referenceOffsets);\n });\n });\n\n // Loop trough the offsets arrays and execute the operations\n ops.forEach(function (op, index) {\n op.forEach(function (frag, index2) {\n if (isNumeric(frag)) {\n offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);\n }\n });\n });\n return offsets;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @argument {Number|String} options.offset=0\n * The offset value as described in the modifier description\n * @returns {Object} The data object, properly modified\n */\nfunction offset(data, _ref) {\n var offset = _ref.offset;\n var placement = data.placement,\n _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var basePlacement = placement.split('-')[0];\n\n var offsets = void 0;\n if (isNumeric(+offset)) {\n offsets = [+offset, 0];\n } else {\n offsets = parseOffset(offset, popper, reference, basePlacement);\n }\n\n if (basePlacement === 'left') {\n popper.top += offsets[0];\n popper.left -= offsets[1];\n } else if (basePlacement === 'right') {\n popper.top += offsets[0];\n popper.left += offsets[1];\n } else if (basePlacement === 'top') {\n popper.left += offsets[0];\n popper.top -= offsets[1];\n } else if (basePlacement === 'bottom') {\n popper.left += offsets[0];\n popper.top += offsets[1];\n }\n\n data.popper = popper;\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction preventOverflow(data, options) {\n var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);\n\n // If offsetParent is the reference element, we really want to\n // go one step up and use the next offsetParent as reference to\n // avoid to make this modifier completely useless and look like broken\n if (data.instance.reference === boundariesElement) {\n boundariesElement = getOffsetParent(boundariesElement);\n }\n\n // NOTE: DOM access here\n // resets the popper's position so that the document size can be calculated excluding\n // the size of the popper element itself\n var transformProp = getSupportedPropertyName('transform');\n var popperStyles = data.instance.popper.style; // assignment to help minification\n var top = popperStyles.top,\n left = popperStyles.left,\n transform = popperStyles[transformProp];\n\n popperStyles.top = '';\n popperStyles.left = '';\n popperStyles[transformProp] = '';\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);\n\n // NOTE: DOM access here\n // restores the original style properties after the offsets have been computed\n popperStyles.top = top;\n popperStyles.left = left;\n popperStyles[transformProp] = transform;\n\n options.boundaries = boundaries;\n\n var order = options.priority;\n var popper = data.offsets.popper;\n\n var check = {\n primary: function primary(placement) {\n var value = popper[placement];\n if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {\n value = Math.max(popper[placement], boundaries[placement]);\n }\n return defineProperty({}, placement, value);\n },\n secondary: function secondary(placement) {\n var mainSide = placement === 'right' ? 'left' : 'top';\n var value = popper[mainSide];\n if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {\n value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));\n }\n return defineProperty({}, mainSide, value);\n }\n };\n\n order.forEach(function (placement) {\n var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';\n popper = _extends({}, popper, check[side](placement));\n });\n\n data.offsets.popper = popper;\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction shift(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var shiftvariation = placement.split('-')[1];\n\n // if shift shiftvariation is specified, run the modifier\n if (shiftvariation) {\n var _data$offsets = data.offsets,\n reference = _data$offsets.reference,\n popper = _data$offsets.popper;\n\n var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;\n var side = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n var shiftOffsets = {\n start: defineProperty({}, side, reference[side]),\n end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])\n };\n\n data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction hide(data) {\n if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {\n return data;\n }\n\n var refRect = data.offsets.reference;\n var bound = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'preventOverflow';\n }).boundaries;\n\n if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === true) {\n return data;\n }\n\n data.hide = true;\n data.attributes['x-out-of-boundaries'] = '';\n } else {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === false) {\n return data;\n }\n\n data.hide = false;\n data.attributes['x-out-of-boundaries'] = false;\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction inner(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;\n\n var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;\n\n popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);\n\n data.placement = getOppositePlacement(placement);\n data.offsets.popper = getClientRect(popper);\n\n return data;\n}\n\n/**\n * Modifier function, each modifier can have a function of this type assigned\n * to its `fn` property.<br />\n * These functions will be called on each update, this means that you must\n * make sure they are performant enough to avoid performance bottlenecks.\n *\n * @function ModifierFn\n * @argument {dataObject} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {dataObject} The data object, properly modified\n */\n\n/**\n * Modifiers are plugins used to alter the behavior of your poppers.<br />\n * Popper.js uses a set of 9 modifiers to provide all the basic functionalities\n * needed by the library.\n *\n * Usually you don't want to override the `order`, `fn` and `onLoad` props.\n * All the other properties are configurations that could be tweaked.\n * @namespace modifiers\n */\nvar modifiers = {\n /**\n * Modifier used to shift the popper on the start or end of its reference\n * element.<br />\n * It will read the variation of the `placement` property.<br />\n * It can be one either `-end` or `-start`.\n * @memberof modifiers\n * @inner\n */\n shift: {\n /** @prop {number} order=100 - Index used to define the order of execution */\n order: 100,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: shift\n },\n\n /**\n * The `offset` modifier can shift your popper on both its axis.\n *\n * It accepts the following units:\n * - `px` or unit-less, interpreted as pixels\n * - `%` or `%r`, percentage relative to the length of the reference element\n * - `%p`, percentage relative to the length of the popper element\n * - `vw`, CSS viewport width unit\n * - `vh`, CSS viewport height unit\n *\n * For length is intended the main axis relative to the placement of the popper.<br />\n * This means that if the placement is `top` or `bottom`, the length will be the\n * `width`. In case of `left` or `right`, it will be the `height`.\n *\n * You can provide a single value (as `Number` or `String`), or a pair of values\n * as `String` divided by a comma or one (or more) white spaces.<br />\n * The latter is a deprecated method because it leads to confusion and will be\n * removed in v2.<br />\n * Additionally, it accepts additions and subtractions between different units.\n * Note that multiplications and divisions aren't supported.\n *\n * Valid examples are:\n * ```\n * 10\n * '10%'\n * '10, 10'\n * '10%, 10'\n * '10 + 10%'\n * '10 - 5vh + 3%'\n * '-10px + 5vh, 5px - 6%'\n * ```\n * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap\n * > with their reference element, unfortunately, you will have to disable the `flip` modifier.\n * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).\n *\n * @memberof modifiers\n * @inner\n */\n offset: {\n /** @prop {number} order=200 - Index used to define the order of execution */\n order: 200,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: offset,\n /** @prop {Number|String} offset=0\n * The offset value as described in the modifier description\n */\n offset: 0\n },\n\n /**\n * Modifier used to prevent the popper from being positioned outside the boundary.\n *\n * A scenario exists where the reference itself is not within the boundaries.<br />\n * We can say it has \"escaped the boundaries\" — or just \"escaped\".<br />\n * In this case we need to decide whether the popper should either:\n *\n * - detach from the reference and remain \"trapped\" in the boundaries, or\n * - if it should ignore the boundary and \"escape with its reference\"\n *\n * When `escapeWithReference` is set to`true` and reference is completely\n * outside its boundaries, the popper will overflow (or completely leave)\n * the boundaries in order to remain attached to the edge of the reference.\n *\n * @memberof modifiers\n * @inner\n */\n preventOverflow: {\n /** @prop {number} order=300 - Index used to define the order of execution */\n order: 300,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: preventOverflow,\n /**\n * @prop {Array} [priority=['left','right','top','bottom']]\n * Popper will try to prevent overflow following these priorities by default,\n * then, it could overflow on the left and on top of the `boundariesElement`\n */\n priority: ['left', 'right', 'top', 'bottom'],\n /**\n * @prop {number} padding=5\n * Amount of pixel used to define a minimum distance between the boundaries\n * and the popper. This makes sure the popper always has a little padding\n * between the edges of its container\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='scrollParent'\n * Boundaries used by the modifier. Can be `scrollParent`, `window`,\n * `viewport` or any DOM element.\n */\n boundariesElement: 'scrollParent'\n },\n\n /**\n * Modifier used to make sure the reference and its popper stay near each other\n * without leaving any gap between the two. Especially useful when the arrow is\n * enabled and you want to ensure that it points to its reference element.\n * It cares only about the first axis. You can still have poppers with margin\n * between the popper and its reference element.\n * @memberof modifiers\n * @inner\n */\n keepTogether: {\n /** @prop {number} order=400 - Index used to define the order of execution */\n order: 400,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: keepTogether\n },\n\n /**\n * This modifier is used to move the `arrowElement` of the popper to make\n * sure it is positioned between the reference element and its popper element.\n * It will read the outer size of the `arrowElement` node to detect how many\n * pixels of conjunction are needed.\n *\n * It has no effect if no `arrowElement` is provided.\n * @memberof modifiers\n * @inner\n */\n arrow: {\n /** @prop {number} order=500 - Index used to define the order of execution */\n order: 500,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: arrow,\n /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */\n element: '[x-arrow]'\n },\n\n /**\n * Modifier used to flip the popper's placement when it starts to overlap its\n * reference element.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n *\n * **NOTE:** this modifier will interrupt the current update cycle and will\n * restart it if it detects the need to flip the placement.\n * @memberof modifiers\n * @inner\n */\n flip: {\n /** @prop {number} order=600 - Index used to define the order of execution */\n order: 600,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: flip,\n /**\n * @prop {String|Array} behavior='flip'\n * The behavior used to change the popper's placement. It can be one of\n * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid\n * placements (with optional variations)\n */\n behavior: 'flip',\n /**\n * @prop {number} padding=5\n * The popper will flip if it hits the edges of the `boundariesElement`\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='viewport'\n * The element which will define the boundaries of the popper position.\n * The popper will never be placed outside of the defined boundaries\n * (except if `keepTogether` is enabled)\n */\n boundariesElement: 'viewport',\n /**\n * @prop {Boolean} flipVariations=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the reference element overlaps its boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariations: false,\n /**\n * @prop {Boolean} flipVariationsByContent=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the popper element overlaps its reference boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariationsByContent: false\n },\n\n /**\n * Modifier used to make the popper flow toward the inner of the reference element.\n * By default, when this modifier is disabled, the popper will be placed outside\n * the reference element.\n * @memberof modifiers\n * @inner\n */\n inner: {\n /** @prop {number} order=700 - Index used to define the order of execution */\n order: 700,\n /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */\n enabled: false,\n /** @prop {ModifierFn} */\n fn: inner\n },\n\n /**\n * Modifier used to hide the popper when its reference element is outside of the\n * popper boundaries. It will set a `x-out-of-boundaries` attribute which can\n * be used to hide with a CSS selector the popper when its reference is\n * out of boundaries.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n * @memberof modifiers\n * @inner\n */\n hide: {\n /** @prop {number} order=800 - Index used to define the order of execution */\n order: 800,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: hide\n },\n\n /**\n * Computes the style that will be applied to the popper element to gets\n * properly positioned.\n *\n * Note that this modifier will not touch the DOM, it just prepares the styles\n * so that `applyStyle` modifier can apply it. This separation is useful\n * in case you need to replace `applyStyle` with a custom implementation.\n *\n * This modifier has `850` as `order` value to maintain backward compatibility\n * with previous versions of Popper.js. Expect the modifiers ordering method\n * to change in future major versions of the library.\n *\n * @memberof modifiers\n * @inner\n */\n computeStyle: {\n /** @prop {number} order=850 - Index used to define the order of execution */\n order: 850,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: computeStyle,\n /**\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: true,\n /**\n * @prop {string} [x='bottom']\n * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.\n * Change this if your popper should grow in a direction different from `bottom`\n */\n x: 'bottom',\n /**\n * @prop {string} [x='left']\n * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.\n * Change this if your popper should grow in a direction different from `right`\n */\n y: 'right'\n },\n\n /**\n * Applies the computed styles to the popper element.\n *\n * All the DOM manipulations are limited to this modifier. This is useful in case\n * you want to integrate Popper.js inside a framework or view library and you\n * want to delegate all the DOM manipulations to it.\n *\n * Note that if you disable this modifier, you must make sure the popper element\n * has its position set to `absolute` before Popper.js can do its work!\n *\n * Just disable this modifier and define your own to achieve the desired effect.\n *\n * @memberof modifiers\n * @inner\n */\n applyStyle: {\n /** @prop {number} order=900 - Index used to define the order of execution */\n order: 900,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: applyStyle,\n /** @prop {Function} */\n onLoad: applyStyleOnLoad,\n /**\n * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: undefined\n }\n};\n\n/**\n * The `dataObject` is an object containing all the information used by Popper.js.\n * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.\n * @name dataObject\n * @property {Object} data.instance The Popper.js instance\n * @property {String} data.placement Placement applied to popper\n * @property {String} data.originalPlacement Placement originally defined on init\n * @property {Boolean} data.flipped True if popper has been flipped by flip modifier\n * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper\n * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier\n * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.boundaries Offsets of the popper boundaries\n * @property {Object} data.offsets The measurements of popper, reference and arrow elements\n * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0\n */\n\n/**\n * Default options provided to Popper.js constructor.<br />\n * These can be overridden using the `options` argument of Popper.js.<br />\n * To override an option, simply pass an object with the same\n * structure of the `options` object, as the 3rd argument. For example:\n * ```\n * new Popper(ref, pop, {\n * modifiers: {\n * preventOverflow: { enabled: false }\n * }\n * })\n * ```\n * @type {Object}\n * @static\n * @memberof Popper\n */\nvar Defaults = {\n /**\n * Popper's placement.\n * @prop {Popper.placements} placement='bottom'\n */\n placement: 'bottom',\n\n /**\n * Set this to true if you want popper to position it self in 'fixed' mode\n * @prop {Boolean} positionFixed=false\n */\n positionFixed: false,\n\n /**\n * Whether events (resize, scroll) are initially enabled.\n * @prop {Boolean} eventsEnabled=true\n */\n eventsEnabled: true,\n\n /**\n * Set to true if you want to automatically remove the popper when\n * you call the `destroy` method.\n * @prop {Boolean} removeOnDestroy=false\n */\n removeOnDestroy: false,\n\n /**\n * Callback called when the popper is created.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onCreate}\n */\n onCreate: function onCreate() {},\n\n /**\n * Callback called when the popper is updated. This callback is not called\n * on the initialization/creation of the popper, but only on subsequent\n * updates.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onUpdate}\n */\n onUpdate: function onUpdate() {},\n\n /**\n * List of modifiers used to modify the offsets before they are applied to the popper.\n * They provide most of the functionalities of Popper.js.\n * @prop {modifiers}\n */\n modifiers: modifiers\n};\n\n/**\n * @callback onCreate\n * @param {dataObject} data\n */\n\n/**\n * @callback onUpdate\n * @param {dataObject} data\n */\n\n// Utils\n// Methods\nvar Popper = function () {\n /**\n * Creates a new Popper.js instance.\n * @class Popper\n * @param {Element|referenceObject} reference - The reference element used to position the popper\n * @param {Element} popper - The HTML / XML element used as the popper\n * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)\n * @return {Object} instance - The generated Popper.js instance\n */\n function Popper(reference, popper) {\n var _this = this;\n\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n classCallCheck(this, Popper);\n\n this.scheduleUpdate = function () {\n return requestAnimationFrame(_this.update);\n };\n\n // make update() debounced, so that it only runs at most once-per-tick\n this.update = debounce(this.update.bind(this));\n\n // with {} we create a new object with the options inside it\n this.options = _extends({}, Popper.Defaults, options);\n\n // init state\n this.state = {\n isDestroyed: false,\n isCreated: false,\n scrollParents: []\n };\n\n // get reference and popper elements (allow jQuery wrappers)\n this.reference = reference && reference.jquery ? reference[0] : reference;\n this.popper = popper && popper.jquery ? popper[0] : popper;\n\n // Deep merge modifiers options\n this.options.modifiers = {};\n Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {\n _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});\n });\n\n // Refactoring modifiers' list (Object => Array)\n this.modifiers = Object.keys(this.options.modifiers).map(function (name) {\n return _extends({\n name: name\n }, _this.options.modifiers[name]);\n })\n // sort the modifiers by order\n .sort(function (a, b) {\n return a.order - b.order;\n });\n\n // modifiers have the ability to execute arbitrary code when Popper.js get inited\n // such code is executed in the same order of its modifier\n // they could add new properties to their options configuration\n // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!\n this.modifiers.forEach(function (modifierOptions) {\n if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {\n modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);\n }\n });\n\n // fire the first update to position the popper in the right place\n this.update();\n\n var eventsEnabled = this.options.eventsEnabled;\n if (eventsEnabled) {\n // setup event listeners, they will take care of update the position in specific situations\n this.enableEventListeners();\n }\n\n this.state.eventsEnabled = eventsEnabled;\n }\n\n // We can't use class properties because they don't get listed in the\n // class prototype and break stuff like Sinon stubs\n\n\n createClass(Popper, [{\n key: 'update',\n value: function update$$1() {\n return update.call(this);\n }\n }, {\n key: 'destroy',\n value: function destroy$$1() {\n return destroy.call(this);\n }\n }, {\n key: 'enableEventListeners',\n value: function enableEventListeners$$1() {\n return enableEventListeners.call(this);\n }\n }, {\n key: 'disableEventListeners',\n value: function disableEventListeners$$1() {\n return disableEventListeners.call(this);\n }\n\n /**\n * Schedules an update. It will run on the next UI update available.\n * @method scheduleUpdate\n * @memberof Popper\n */\n\n\n /**\n * Collection of utilities useful when writing custom modifiers.\n * Starting from version 1.7, this method is available only if you\n * include `popper-utils.js` before `popper.js`.\n *\n * **DEPRECATION**: This way to access PopperUtils is deprecated\n * and will be removed in v2! Use the PopperUtils module directly instead.\n * Due to the high instability of the methods contained in Utils, we can't\n * guarantee them to follow semver. Use them at your own risk!\n * @static\n * @private\n * @type {Object}\n * @deprecated since version 1.8\n * @member Utils\n * @memberof Popper\n */\n\n }]);\n return Popper;\n}();\n\n/**\n * The `referenceObject` is an object that provides an interface compatible with Popper.js\n * and lets you use it as replacement of a real DOM node.<br />\n * You can use this method to position a popper relatively to a set of coordinates\n * in case you don't have a DOM node to use as reference.\n *\n * ```\n * new Popper(referenceObject, popperNode);\n * ```\n *\n * NB: This feature isn't supported in Internet Explorer 10.\n * @name referenceObject\n * @property {Function} data.getBoundingClientRect\n * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.\n * @property {number} data.clientWidth\n * An ES6 getter that will return the width of the virtual reference element.\n * @property {number} data.clientHeight\n * An ES6 getter that will return the height of the virtual reference element.\n */\n\n\nPopper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;\nPopper.placements = placements;\nPopper.Defaults = Defaults;\n\nexport default Popper;\n//# sourceMappingURL=popper.js.map\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Totally disable Popper for Dropdowns in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n customClass: '(string|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n customClass: '',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n $(tip).addClass(this.config.customClass)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"],"names":["TRANSITION_END","MAX_UID","MILLISECONDS_MULTIPLIER","toType","obj","toString","call","match","toLowerCase","getSpecialTransitionEndEvent","bindType","delegateType","handle","event","$","target","is","handleObj","handler","apply","arguments","undefined","transitionEndEmulator","duration","called","one","Util","setTimeout","triggerTransitionEnd","setTransitionEndSupport","fn","emulateTransitionEnd","special","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","expectedTypes","value","valueType","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","jquery","minMajor","ltMajor","minMinor","minPatch","maxMajor","NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","SELECTOR_DISMISS","EVENT_CLOSE","EVENT_CLOSED","EVENT_CLICK_DATA_API","CLASS_NAME_ALERT","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","_element","close","rootElement","_getRootElement","customEvent","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","CLASS_NAME_ACTIVE","CLASS_NAME_BUTTON","CLASS_NAME_FOCUS","SELECTOR_DATA_TOGGLE_CARROT","SELECTOR_DATA_TOGGLES","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_TOGGLES_BUTTONS","SELECTOR_INPUT","SELECTOR_ACTIVE","SELECTOR_BUTTON","EVENT_FOCUS_BLUR_DATA_API","EVENT_LOAD_DATA_API","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","ARROW_LEFT_KEYCODE","ARROW_RIGHT_KEYCODE","TOUCHEVENT_COMPAT_WAIT","SWIPE_THRESHOLD","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","DIRECTION_NEXT","DIRECTION_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLIDE","EVENT_SLID","EVENT_KEYDOWN","EVENT_MOUSEENTER","EVENT_MOUSELEAVE","EVENT_TOUCHSTART","EVENT_TOUCHMOVE","EVENT_TOUCHEND","EVENT_POINTERDOWN","EVENT_POINTERUP","EVENT_DRAG_START","CLASS_NAME_CAROUSEL","CLASS_NAME_SLIDE","CLASS_NAME_RIGHT","CLASS_NAME_LEFT","CLASS_NAME_NEXT","CLASS_NAME_PREV","CLASS_NAME_POINTER_EVENT","SELECTOR_ACTIVE_ITEM","SELECTOR_ITEM","SELECTOR_ITEM_IMG","SELECTOR_NEXT_PREV","SELECTOR_INDICATORS","SELECTOR_DATA_SLIDE","SELECTOR_DATA_RIDE","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","_updateInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_handleSwipe","absDeltax","abs","_keydown","_addTouchEventListeners","start","originalEvent","pointerType","clientX","touches","move","end","clearTimeout","e","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","isGoingToWrap","delta","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","elementInterval","parseInt","defaultInterval","activeElementIndex","nextElement","nextElementIndex","isCycling","directionalClassName","orderClassName","slidEvent","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","EVENT_SHOW","EVENT_SHOWN","EVENT_HIDE","EVENT_HIDDEN","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","CLASS_NAME_COLLAPSED","DIMENSION_WIDTH","DIMENSION_HEIGHT","SELECTOR_ACTIVES","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","complete","capitalizedDimension","scrollSize","getBoundingClientRect","triggerArrayLength","$elem","isTransitioning","hasWidth","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","_extends","ESCAPE_KEYCODE","SPACE_KEYCODE","TAB_KEYCODE","ARROW_UP_KEYCODE","ARROW_DOWN_KEYCODE","RIGHT_MOUSE_BUTTON_WHICH","REGEXP_KEYDOWN","EVENT_CLICK","EVENT_KEYDOWN_DATA_API","EVENT_KEYUP_DATA_API","CLASS_NAME_DISABLED","CLASS_NAME_DROPUP","CLASS_NAME_DROPRIGHT","CLASS_NAME_DROPLEFT","CLASS_NAME_MENURIGHT","CLASS_NAME_POSITION_STATIC","SELECTOR_FORM_CHILD","SELECTOR_MENU","SELECTOR_NAVBAR_NAV","SELECTOR_VISIBLE_ITEMS","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","offset","flip","boundary","reference","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","Popper","referenceElement","_getPopperConfig","body","noop","hideEvent","destroy","update","scheduleUpdate","stopPropagation","constructor","_getPlacement","$parentDropdown","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","backdrop","EVENT_HIDE_PREVENTED","EVENT_FOCUSIN","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_KEYDOWN_DISMISS","EVENT_MOUSEUP_DISMISS","EVENT_MOUSEDOWN_DISMISS","CLASS_NAME_SCROLLABLE","CLASS_NAME_SCROLLBAR_MEASURER","CLASS_NAME_BACKDROP","CLASS_NAME_OPEN","CLASS_NAME_STATIC","SELECTOR_DIALOG","SELECTOR_MODAL_BODY","SELECTOR_DATA_DISMISS","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","forEach","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","clientHeight","overflowY","modalTransitionDuration","modalBody","Node","ELEMENT_NODE","appendChild","removeAttribute","scrollTop","_enforceFocus","shownEvent","transitionComplete","has","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","round","left","right","innerWidth","_getScrollbarWidth","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","uriAttrs","ARIA_ATTRIBUTE_PATTERN","DefaultWhitelist","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","allowedAttributeList","attrName","nodeName","nodeValue","regExp","attrRegex","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","domParser","DOMParser","createdDocument","parseFromString","whitelistKeys","keys","el","elName","attributeList","attributes","whitelistedAttributes","concat","innerHTML","CLASS_PREFIX","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","html","container","fallbackPlacement","customClass","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HOVER_STATE_SHOW","HOVER_STATE_OUT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","SELECTOR_TOOLTIP_INNER","SELECTOR_ARROW","TRIGGER_HOVER","TRIGGER_FOCUS","TRIGGER_CLICK","TRIGGER_MANUAL","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","ownerDocument","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","_fixTransition","prevHoverState","_cleanTipClass","getTitle","setElementContent","content","empty","append","text","defaultBsConfig","behavior","arrow","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","find","triggers","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","SELECTOR_TITLE","SELECTOR_CONTENT","Popover","_getContent","method","EVENT_ACTIVATE","EVENT_SCROLL","CLASS_NAME_DROPDOWN_ITEM","SELECTOR_DATA_SPY","SELECTOR_NAV_LIST_GROUP","SELECTOR_NAV_LINKS","SELECTOR_NAV_ITEMS","SELECTOR_LIST_ITEMS","SELECTOR_DROPDOWN","SELECTOR_DROPDOWN_ITEMS","SELECTOR_DROPDOWN_TOGGLE","METHOD_OFFSET","METHOD_POSITION","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targets","map","targetSelector","targetBCR","height","top","sort","pageYOffset","max","_getOffsetHeight","innerHeight","maxScroll","_activate","_clear","isActiveTarget","queries","$link","parents","node","scrollSpys","scrollSpysLength","$spy","CLASS_NAME_DROPDOWN_MENU","SELECTOR_ACTIVE_UL","SELECTOR_DROPDOWN_ACTIVE_CHILD","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","activeElements","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","CLASS_NAME_HIDE","CLASS_NAME_SHOWING","autohide","Toast","_clearTimeout","_close"],"mappings":"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;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,eAAe,EAAE;EACnB;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,eAAe;EACvB;EACA;EACA;EACA;EACA;EACA,IAAI,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;EAChD;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,OAAO,EAAE,CAAC;EACd;EACA;EACA;EACA;EACA;EACA,IAAI,iBAAiB,EAAE,cAAc;EACrC,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,YAAY,EAAE;EAChB;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,YAAY;EACpB,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,KAAK,EAAE;EACT;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,KAAK;EACb;EACA,IAAI,OAAO,EAAE,WAAW;EACxB,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,IAAI,EAAE;EACR;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,IAAI;EACZ;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,QAAQ,EAAE,MAAM;EACpB;EACA;EACA;EACA;EACA,IAAI,OAAO,EAAE,CAAC;EACd;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,iBAAiB,EAAE,UAAU;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,cAAc,EAAE,KAAK;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,uBAAuB,EAAE,KAAK;EAClC,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,KAAK,EAAE;EACT;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,KAAK;EAClB;EACA,IAAI,EAAE,EAAE,KAAK;EACb,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,IAAI,EAAE;EACR;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,IAAI;EACZ,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,YAAY,EAAE;EAChB;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,YAAY;EACpB;EACA;EACA;EACA;EACA;EACA,IAAI,eAAe,EAAE,IAAI;EACzB;EACA;EACA;EACA;EACA;EACA,IAAI,CAAC,EAAE,QAAQ;EACf;EACA;EACA;EACA;EACA;EACA,IAAI,CAAC,EAAE,OAAO;EACd,GAAG;AACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAE,UAAU,EAAE;EACd;EACA,IAAI,KAAK,EAAE,GAAG;EACd;EACA,IAAI,OAAO,EAAE,IAAI;EACjB;EACA,IAAI,EAAE,EAAE,UAAU;EAClB;EACA,IAAI,MAAM,EAAE,gBAAgB;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA,IAAI,eAAe,EAAE,SAAS;EAC9B,GAAG;EACH,CAAC,CAAC;AACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;E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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js index ef603dadf..7961bdaf8 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js @@ -1,7 +1,7 @@ /*! - * Bootstrap v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery)}(this,(function(t,e){"use strict";function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var i=n(e);function o(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function r(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function s(t){var e=this,n=!1;return i.default(this).one(l.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||l.triggerTransitionEnd(e)}),t),this}var l={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=i.default(t).css("transition-duration"),n=i.default(t).css("transition-delay"),o=parseFloat(e),r=parseFloat(n);return o||r?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){i.default(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],r=e[i],a=r&&l.isElement(r)?"element":null===(s=r)||"undefined"==typeof s?""+s:{}.toString.call(s).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(a))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+a+'" but expected type "'+o+'".')}var s},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?l.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof i.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=i.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};l.jQueryDetection(),i.default.fn.emulateTransitionEnd=s,i.default.event.special[l.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(i.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var u="alert",f=i.default.fn[u],d=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){i.default.removeData(this._element,"bs.alert"),this._element=null},e._getRootElement=function(t){var e=l.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=i.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=i.default.Event("close.bs.alert");return i.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(i.default(t).removeClass("show"),i.default(t).hasClass("fade")){var n=l.getTransitionDurationFromElement(t);i.default(t).one(l.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){i.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.alert");o||(o=new t(this),n.data("bs.alert",o)),"close"===e&&o[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}}]),t}();i.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',d._handleDismiss(new d)),i.default.fn[u]=d._jQueryInterface,i.default.fn[u].Constructor=d,i.default.fn[u].noConflict=function(){return i.default.fn[u]=f,d._jQueryInterface};var c=i.default.fn.button,h=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=i.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var r=n.querySelector(".active");r&&i.default(r).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),this.shouldAvoidTriggerChange||i.default(o).trigger("change")),o.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&i.default(this._element).toggleClass("active"))},e.dispose=function(){i.default.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var o=i.default(this),r=o.data("bs.button");r||(r=new t(this),o.data("bs.button",r)),r.shouldAvoidTriggerChange=n,"toggle"===e&&r[e]()}))},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}}]),t}();i.default(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target,n=e;if(i.default(e).hasClass("btn")||(e=i.default(e).closest(".btn")[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var o=e.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||h._jQueryInterface.call(i.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=i.default(t.target).closest(".btn")[0];i.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),i.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var r=0,a=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;r<a;r++){var s=t[r];"true"===s.getAttribute("aria-pressed")?s.classList.add("active"):s.classList.remove("active")}})),i.default.fn.button=h._jQueryInterface,i.default.fn.button.Constructor=h,i.default.fn.button.noConflict=function(){return i.default.fn.button=c,h._jQueryInterface};var p="carousel",m=".bs.carousel",g=i.default.fn[p],v={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},_={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},b={TOUCH:"touch",PEN:"pen"},y=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide("next")},e.nextWhenVisible=function(){var t=i.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide("prev")},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(l.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(".active.carousel-item");var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)i.default(this._element).one("slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var o=t>n?"next":"prev";this._slide(o,this._items[t])}},e.dispose=function(){i.default(this._element).off(m),i.default.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=a({},v,t),l.typeCheckConfig(p,t,_),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&i.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&i.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};i.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(i.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(i.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),i.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var a=(o+("prev"===t?-1:1))%this._items.length;return-1===a?this._items[this._items.length-1]:this._items[a]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),r=i.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:o,to:n});return i.default(this._element).trigger(r),r},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));i.default(e).removeClass("active");var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&i.default(n).addClass("active")}},e._slide=function(t,e){var n,o,r,a=this,s=this._element.querySelector(".active.carousel-item"),u=this._getItemIndex(s),f=e||s&&this._getItemByDirection(t,s),d=this._getItemIndex(f),c=Boolean(this._interval);if("next"===t?(n="carousel-item-left",o="carousel-item-next",r="left"):(n="carousel-item-right",o="carousel-item-prev",r="right"),f&&i.default(f).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(f,r).isDefaultPrevented()&&s&&f){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(f);var h=i.default.Event("slid.bs.carousel",{relatedTarget:f,direction:r,from:u,to:d});if(i.default(this._element).hasClass("slide")){i.default(f).addClass(o),l.reflow(f),i.default(s).addClass(n),i.default(f).addClass(n);var p=parseInt(f.getAttribute("data-interval"),10);p?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=p):this._config.interval=this._config.defaultInterval||this._config.interval;var m=l.getTransitionDurationFromElement(s);i.default(s).one(l.TRANSITION_END,(function(){i.default(f).removeClass(n+" "+o).addClass("active"),i.default(s).removeClass("active "+o+" "+n),a._isSliding=!1,setTimeout((function(){return i.default(a._element).trigger(h)}),0)})).emulateTransitionEnd(m)}else i.default(s).removeClass("active"),i.default(f).addClass("active"),this._isSliding=!1,i.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.carousel"),o=a({},v,i.default(this).data());"object"==typeof e&&(o=a({},o,e));var r="string"==typeof e?e:o.slide;if(n||(n=new t(this,o),i.default(this).data("bs.carousel",n)),"number"==typeof e)n.to(e);else if("string"==typeof r){if("undefined"==typeof n[r])throw new TypeError('No method named "'+r+'"');n[r]()}else o.interval&&o.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=l.getSelectorFromElement(this);if(n){var o=i.default(n)[0];if(o&&i.default(o).hasClass("carousel")){var r=a({},i.default(o).data(),i.default(this).data()),s=this.getAttribute("data-slide-to");s&&(r.interval=!1),t._jQueryInterface.call(i.default(o),r),s&&i.default(o).data("bs.carousel").to(s),e.preventDefault()}}},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return v}}]),t}();i.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",y._dataApiClickHandler),i.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e<n;e++){var o=i.default(t[e]);y._jQueryInterface.call(o,o.data())}})),i.default.fn[p]=y._jQueryInterface,i.default.fn[p].Constructor=y,i.default.fn[p].noConflict=function(){return i.default.fn[p]=g,y._jQueryInterface};var w="collapse",E=i.default.fn[w],T={toggle:!0,parent:""},C={toggle:"boolean",parent:"(string|element)"},S=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var r=n[i],a=l.getSelectorFromElement(r),s=[].slice.call(document.querySelectorAll(a)).filter((function(e){return e===t}));null!==a&&s.length>0&&(this._selector=a,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){i.default(this._element).hasClass("show")?this.hide():this.show()},e.show=function(){var e,n,o=this;if(!this._isTransitioning&&!i.default(this._element).hasClass("show")&&(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(e=null),!(e&&(n=i.default(e).not(this._selector).data("bs.collapse"))&&n._isTransitioning))){var r=i.default.Event("show.bs.collapse");if(i.default(this._element).trigger(r),!r.isDefaultPrevented()){e&&(t._jQueryInterface.call(i.default(e).not(this._selector),"hide"),n||i.default(e).data("bs.collapse",null));var a=this._getDimension();i.default(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[a]=0,this._triggerArray.length&&i.default(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var s="scroll"+(a[0].toUpperCase()+a.slice(1)),u=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,(function(){i.default(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[a]="",o.setTransitioning(!1),i.default(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(u),this._element.style[a]=this._element[s]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&i.default(this._element).hasClass("show")){var e=i.default.Event("hide.bs.collapse");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",l.reflow(this._element),i.default(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var r=0;r<o;r++){var a=this._triggerArray[r],s=l.getSelectorFromElement(a);if(null!==s)i.default([].slice.call(document.querySelectorAll(s))).hasClass("show")||i.default(a).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[n]="";var u=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,(function(){t.setTransitioning(!1),i.default(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(u)}}},e.setTransitioning=function(t){this._isTransitioning=t},e.dispose=function(){i.default.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},e._getConfig=function(t){return(t=a({},T,t)).toggle=Boolean(t.toggle),l.typeCheckConfig(w,t,C),t},e._getDimension=function(){return i.default(this._element).hasClass("width")?"width":"height"},e._getParent=function(){var e,n=this;l.isElement(this._config.parent)?(e=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(e=this._config.parent[0])):e=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',r=[].slice.call(e.querySelectorAll(o));return i.default(r).each((function(e,i){n._addAriaAndCollapsedClass(t._getTargetFromElement(i),[i])})),e},e._addAriaAndCollapsedClass=function(t,e){var n=i.default(t).hasClass("show");e.length&&i.default(e).toggleClass("collapsed",!n).attr("aria-expanded",n)},t._getTargetFromElement=function(t){var e=l.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.collapse"),r=a({},T,n.data(),"object"==typeof e&&e?e:{});if(!o&&r.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(r.toggle=!1),o||(o=new t(this,r),n.data("bs.collapse",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return T}}]),t}();i.default(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var e=i.default(this),n=l.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(n));i.default(o).each((function(){var t=i.default(this),n=t.data("bs.collapse")?"toggle":e.data();S._jQueryInterface.call(t,n)}))})),i.default.fn[w]=S._jQueryInterface,i.default.fn[w].Constructor=S,i.default.fn[w].noConflict=function(){return i.default.fn[w]=E,S._jQueryInterface};var D="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,N=function(){for(var t=["Edge","Trident","Firefox"],e=0;e<t.length;e+=1)if(D&&navigator.userAgent.indexOf(t[e])>=0)return 1;return 0}();var k=D&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),N))}};function A(t){return t&&"[object Function]"==={}.toString.call(t)}function I(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function O(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function x(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=I(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:x(O(t))}function j(t){return t&&t.referenceNode?t.referenceNode:t}var L=D&&!(!window.MSInputMethodContext||!document.documentMode),P=D&&/MSIE 10/.test(navigator.userAgent);function F(t){return 11===t?L:10===t?P:L||P}function R(t){if(!t)return document.documentElement;for(var e=F(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===I(n,"position")?R(n):n:t?t.ownerDocument.documentElement:document.documentElement}function H(t){return null!==t.parentNode?H(t.parentNode):t}function M(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var a,s,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(s=(a=l).nodeName)||"HTML"!==s&&R(a.firstElementChild)!==a?R(l):l;var u=H(t);return u.host?M(u.host,e):M(t,H(e).host)}function B(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function q(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=B(e,"top"),o=B(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function Q(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+i+"Width"])}function W(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],F(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function U(t){var e=t.body,n=t.documentElement,i=F(10)&&getComputedStyle(n);return{height:W("Height",e,n,i),width:W("Width",e,n,i)}}var V=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},Y=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),z=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},X=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t};function K(t){return X({},t,{right:t.left+t.width,bottom:t.top+t.height})}function G(t){var e={};try{if(F(10)){e=t.getBoundingClientRect();var n=B(t,"top"),i=B(t,"left");e.top+=n,e.left+=i,e.bottom+=n,e.right+=i}else e=t.getBoundingClientRect()}catch(t){}var o={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},r="HTML"===t.nodeName?U(t.ownerDocument):{},a=r.width||t.clientWidth||o.width,s=r.height||t.clientHeight||o.height,l=t.offsetWidth-a,u=t.offsetHeight-s;if(l||u){var f=I(t);l-=Q(f,"x"),u-=Q(f,"y"),o.width-=l,o.height-=u}return K(o)}function $(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=F(10),o="HTML"===e.nodeName,r=G(t),a=G(e),s=x(t),l=I(e),u=parseFloat(l.borderTopWidth),f=parseFloat(l.borderLeftWidth);n&&o&&(a.top=Math.max(a.top,0),a.left=Math.max(a.left,0));var d=K({top:r.top-a.top-u,left:r.left-a.left-f,width:r.width,height:r.height});if(d.marginTop=0,d.marginLeft=0,!i&&o){var c=parseFloat(l.marginTop),h=parseFloat(l.marginLeft);d.top-=u-c,d.bottom-=u-c,d.left-=f-h,d.right-=f-h,d.marginTop=c,d.marginLeft=h}return(i&&!n?e.contains(s):e===s&&"BODY"!==s.nodeName)&&(d=q(d,e)),d}function J(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=$(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),a=e?0:B(n),s=e?0:B(n,"left"),l={top:a-i.top+i.marginTop,left:s-i.left+i.marginLeft,width:o,height:r};return K(l)}function Z(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===I(t,"position"))return!0;var n=O(t);return!!n&&Z(n)}function tt(t){if(!t||!t.parentElement||F())return document.documentElement;for(var e=t.parentElement;e&&"none"===I(e,"transform");)e=e.parentElement;return e||document.documentElement}function et(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},a=o?tt(t):M(t,j(e));if("viewport"===i)r=J(a,o);else{var s=void 0;"scrollParent"===i?"BODY"===(s=x(O(e))).nodeName&&(s=t.ownerDocument.documentElement):s="window"===i?t.ownerDocument.documentElement:i;var l=$(s,a,o);if("HTML"!==s.nodeName||Z(a))r=l;else{var u=U(t.ownerDocument),f=u.height,d=u.width;r.top+=l.top-l.marginTop,r.bottom=f+l.top,r.left+=l.left-l.marginLeft,r.right=d+l.left}}var c="number"==typeof(n=n||0);return r.left+=c?n:n.left||0,r.top+=c?n:n.top||0,r.right-=c?n:n.right||0,r.bottom-=c?n:n.bottom||0,r}function nt(t){return t.width*t.height}function it(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var a=et(n,i,r,o),s={top:{width:a.width,height:e.top-a.top},right:{width:a.right-e.right,height:a.height},bottom:{width:a.width,height:a.bottom-e.bottom},left:{width:e.left-a.left,height:a.height}},l=Object.keys(s).map((function(t){return X({key:t},s[t],{area:nt(s[t])})})).sort((function(t,e){return e.area-t.area})),u=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),f=u.length>0?u[0].key:l[0].key,d=t.split("-")[1];return f+(d?"-"+d:"")}function ot(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?tt(e):M(e,j(n));return $(n,o,i)}function rt(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function at(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function st(t,e,n){n=n.split("-")[0];var i=rt(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),a=r?"top":"left",s=r?"left":"top",l=r?"height":"width",u=r?"width":"height";return o[a]=e[a]+e[l]/2-i[l]/2,o[s]=n===s?e[s]-i[u]:e[at(s)],o}function lt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function ut(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=lt(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&A(n)&&(e.offsets.popper=K(e.offsets.popper),e.offsets.reference=K(e.offsets.reference),e=n(e,t))})),e}function ft(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=ot(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=it(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=st(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=ut(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function dt(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ct(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i<e.length;i++){var o=e[i],r=o?""+o+n:t;if("undefined"!=typeof document.body.style[r])return r}return null}function ht(){return this.state.isDestroyed=!0,dt(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.position="",this.popper.style.top="",this.popper.style.left="",this.popper.style.right="",this.popper.style.bottom="",this.popper.style.willChange="",this.popper.style[ct("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function pt(t){var e=t.ownerDocument;return e?e.defaultView:window}function mt(t,e,n,i){n.updateBound=i,pt(t).addEventListener("resize",n.updateBound,{passive:!0});var o=x(t);return function t(e,n,i,o){var r="BODY"===e.nodeName,a=r?e.ownerDocument.defaultView:e;a.addEventListener(n,i,{passive:!0}),r||t(x(a.parentNode),n,i,o),o.push(a)}(o,"scroll",n.updateBound,n.scrollParents),n.scrollElement=o,n.eventsEnabled=!0,n}function gt(){this.state.eventsEnabled||(this.state=mt(this.reference,this.options,this.state,this.scheduleUpdate))}function vt(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,pt(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach((function(t){t.removeEventListener("scroll",e.updateBound)})),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function _t(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function bt(t,e){Object.keys(e).forEach((function(n){var i="";-1!==["width","height","top","right","bottom","left"].indexOf(n)&&_t(e[n])&&(i="px"),t.style[n]=e[n]+i}))}var yt=D&&/Firefox/i.test(navigator.userAgent);function wt(t,e,n){var i=lt(t,(function(t){return t.name===e})),o=!!i&&t.some((function(t){return t.name===n&&t.enabled&&t.order<i.order}));if(!o){var r="`"+e+"`",a="`"+n+"`";console.warn(a+" modifier is required by "+r+" modifier in order to work, be sure to include it before "+r+"!")}return o}var Et=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],Tt=Et.slice(3);function Ct(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=Tt.indexOf(t),i=Tt.slice(n+1).concat(Tt.slice(0,n));return e?i.reverse():i}var St="flip",Dt="clockwise",Nt="counterclockwise";function kt(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),a=t.split(/(\+|\-)/).map((function(t){return t.trim()})),s=a.indexOf(lt(a,(function(t){return-1!==t.search(/,|\s/)})));a[s]&&-1===a[s].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,u=-1!==s?[a.slice(0,s).concat([a[s].split(l)[0]]),[a[s].split(l)[1]].concat(a.slice(s+1))]:[a];return(u=u.map((function(t,i){var o=(1===i?!r:r)?"height":"width",a=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,a=!0,t):a?(t[t.length-1]+=e,a=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],a=o[2];if(!r)return t;if(0===a.indexOf("%")){var s=void 0;switch(a){case"%p":s=n;break;case"%":case"%r":default:s=i}return K(s)[e]/100*r}if("vh"===a||"vw"===a){return("vh"===a?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r}return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){_t(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var At={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,a=o.popper,s=-1!==["bottom","top"].indexOf(n),l=s?"left":"top",u=s?"width":"height",f={start:z({},l,r[l]),end:z({},l,r[l]+r[u]-a[u])};t.offsets.popper=X({},a,f[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,a=o.reference,s=i.split("-")[0],l=void 0;return l=_t(+n)?[+n,0]:kt(n,r,a,s),"left"===s?(r.top+=l[0],r.left-=l[1]):"right"===s?(r.top+=l[0],r.left+=l[1]):"top"===s?(r.left+=l[0],r.top-=l[1]):"bottom"===s&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||R(t.instance.popper);t.instance.reference===n&&(n=R(n));var i=ct("transform"),o=t.instance.popper.style,r=o.top,a=o.left,s=o[i];o.top="",o.left="",o[i]="";var l=et(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=a,o[i]=s,e.boundaries=l;var u=e.priority,f=t.offsets.popper,d={primary:function(t){var n=f[t];return f[t]<l[t]&&!e.escapeWithReference&&(n=Math.max(f[t],l[t])),z({},t,n)},secondary:function(t){var n="right"===t?"left":"top",i=f[n];return f[t]>l[t]&&!e.escapeWithReference&&(i=Math.min(f[n],l[t]-("right"===t?f.width:f.height))),z({},n,i)}};return u.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";f=X({},f,d[e](t))})),t.offsets.popper=f,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(o),s=a?"right":"bottom",l=a?"left":"top",u=a?"width":"height";return n[s]<r(i[l])&&(t.offsets.popper[l]=r(i[l])-n[u]),n[l]>r(i[s])&&(t.offsets.popper[l]=r(i[s])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!wt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,a=r.popper,s=r.reference,l=-1!==["left","right"].indexOf(o),u=l?"height":"width",f=l?"Top":"Left",d=f.toLowerCase(),c=l?"left":"top",h=l?"bottom":"right",p=rt(i)[u];s[h]-p<a[d]&&(t.offsets.popper[d]-=a[d]-(s[h]-p)),s[d]+p>a[h]&&(t.offsets.popper[d]+=s[d]+p-a[h]),t.offsets.popper=K(t.offsets.popper);var m=s[d]+s[u]/2-p/2,g=I(t.instance.popper),v=parseFloat(g["margin"+f]),_=parseFloat(g["border"+f+"Width"]),b=m-t.offsets.popper[d]-v-_;return b=Math.max(Math.min(a[u]-p,b),0),t.arrowElement=i,t.offsets.arrow=(z(n={},d,Math.round(b)),z(n,c,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(dt(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=et(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=at(i),r=t.placement.split("-")[1]||"",a=[];switch(e.behavior){case St:a=[i,o];break;case Dt:a=Ct(i);break;case Nt:a=Ct(i,!0);break;default:a=e.behavior}return a.forEach((function(s,l){if(i!==s||a.length===l+1)return t;i=t.placement.split("-")[0],o=at(i);var u=t.offsets.popper,f=t.offsets.reference,d=Math.floor,c="left"===i&&d(u.right)>d(f.left)||"right"===i&&d(u.left)<d(f.right)||"top"===i&&d(u.bottom)>d(f.top)||"bottom"===i&&d(u.top)<d(f.bottom),h=d(u.left)<d(n.left),p=d(u.right)>d(n.right),m=d(u.top)<d(n.top),g=d(u.bottom)>d(n.bottom),v="left"===i&&h||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,_=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(_&&"start"===r&&h||_&&"end"===r&&p||!_&&"start"===r&&m||!_&&"end"===r&&g),y=!!e.flipVariationsByContent&&(_&&"start"===r&&p||_&&"end"===r&&h||!_&&"start"===r&&g||!_&&"end"===r&&m),w=b||y;(c||v||w)&&(t.flipped=!0,(c||v)&&(i=a[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=X({},t.offsets.popper,st(t.instance.popper,t.offsets.reference,t.placement)),t=ut(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,a=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return o[a?"left":"top"]=r[n]-(s?o[a?"width":"height"]:0),t.placement=at(e),t.offsets.popper=K(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!wt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=lt(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottom<n.top||e.left>n.right||e.top>n.bottom||e.right<n.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var n=e.x,i=e.y,o=t.offsets.popper,r=lt(t.instance.modifiers,(function(t){return"applyStyle"===t.name})).gpuAcceleration;void 0!==r&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var a=void 0!==r?r:e.gpuAcceleration,s=R(t.instance.popper),l=G(s),u={position:o.position},f=function(t,e){var n=t.offsets,i=n.popper,o=n.reference,r=Math.round,a=Math.floor,s=function(t){return t},l=r(o.width),u=r(i.width),f=-1!==["left","right"].indexOf(t.placement),d=-1!==t.placement.indexOf("-"),c=e?f||d||l%2==u%2?r:a:s,h=e?r:s;return{left:c(l%2==1&&u%2==1&&!d&&e?i.left-1:i.left),top:h(i.top),bottom:h(i.bottom),right:c(i.right)}}(t,window.devicePixelRatio<2||!yt),d="bottom"===n?"top":"bottom",c="right"===i?"left":"right",h=ct("transform"),p=void 0,m=void 0;if(m="bottom"===d?"HTML"===s.nodeName?-s.clientHeight+f.bottom:-l.height+f.bottom:f.top,p="right"===c?"HTML"===s.nodeName?-s.clientWidth+f.right:-l.width+f.right:f.left,a&&h)u[h]="translate3d("+p+"px, "+m+"px, 0)",u[d]=0,u[c]=0,u.willChange="transform";else{var g="bottom"===d?-1:1,v="right"===c?-1:1;u[d]=m*g,u[c]=p*v,u.willChange=d+", "+c}var _={"x-placement":t.placement};return t.attributes=X({},_,t.attributes),t.styles=X({},u,t.styles),t.arrowStyles=X({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){var e,n;return bt(t.instance.popper,t.styles),e=t.instance.popper,n=t.attributes,Object.keys(n).forEach((function(t){!1!==n[t]?e.setAttribute(t,n[t]):e.removeAttribute(t)})),t.arrowElement&&Object.keys(t.arrowStyles).length&&bt(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,n,i,o){var r=ot(o,e,t,n.positionFixed),a=it(n.placement,r,e,t,n.modifiers.flip.boundariesElement,n.modifiers.flip.padding);return e.setAttribute("x-placement",a),bt(e,{position:n.positionFixed?"fixed":"absolute"}),n},gpuAcceleration:void 0}}},It=function(){function t(e,n){var i=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};V(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=k(this.update.bind(this)),this.options=X({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(X({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=X({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return X({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&A(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return Y(t,[{key:"update",value:function(){return ft.call(this)}},{key:"destroy",value:function(){return ht.call(this)}},{key:"enableEventListeners",value:function(){return gt.call(this)}},{key:"disableEventListeners",value:function(){return vt.call(this)}}]),t}();It.Utils=("undefined"!=typeof window?window:global).PopperUtils,It.placements=Et,It.Defaults=At;var Ot="dropdown",xt=i.default.fn[Ot],jt=new RegExp("38|40|27"),Lt={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Pt={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},Ft=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!i.default(this._element).hasClass("disabled")){var e=i.default(this._menu).hasClass("show");t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||i.default(this._element).hasClass("disabled")||i.default(this._menu).hasClass("show"))){var n={relatedTarget:this._element},o=i.default.Event("show.bs.dropdown",n),r=t._getParentFromElement(this._element);if(i.default(r).trigger(o),!o.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof It)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var a=this._element;"parent"===this._config.reference?a=r:l.isElement(this._config.reference)&&(a=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(a=this._config.reference[0])),"scrollParent"!==this._config.boundary&&i.default(r).addClass("position-static"),this._popper=new It(a,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===i.default(r).closest(".navbar-nav").length&&i.default(document.body).children().on("mouseover",null,i.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),i.default(this._menu).toggleClass("show"),i.default(r).toggleClass("show").trigger(i.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!i.default(this._element).hasClass("disabled")&&i.default(this._menu).hasClass("show")){var e={relatedTarget:this._element},n=i.default.Event("hide.bs.dropdown",e),o=t._getParentFromElement(this._element);i.default(o).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),i.default(this._menu).toggleClass("show"),i.default(o).toggleClass("show").trigger(i.default.Event("hidden.bs.dropdown",e)))}},e.dispose=function(){i.default.removeData(this._element,"bs.dropdown"),i.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;i.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=a({},this.constructor.Default,i.default(this._element).data(),t),l.typeCheckConfig(Ot,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},e._getPlacement=function(){var t=i.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=i.default(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":i.default(this._menu).hasClass("dropdown-menu-right")&&(e="bottom-end"),e},e._detectNavbar=function(){return i.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),a({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.dropdown");if(n||(n=new t(this,"object"==typeof e?e:null),i.default(this).data("bs.dropdown",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,r=n.length;o<r;o++){var a=t._getParentFromElement(n[o]),s=i.default(n[o]).data("bs.dropdown"),l={relatedTarget:n[o]};if(e&&"click"===e.type&&(l.clickEvent=e),s){var u=s._menu;if(i.default(a).hasClass("show")&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&i.default.contains(a,e.target))){var f=i.default.Event("hide.bs.dropdown",l);i.default(a).trigger(f),f.isDefaultPrevented()||("ontouchstart"in document.documentElement&&i.default(document.body).children().off("mouseover",null,i.default.noop),n[o].setAttribute("aria-expanded","false"),s._popper&&s._popper.destroy(),i.default(u).removeClass("show"),i.default(a).removeClass("show").trigger(i.default.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=l.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||i.default(e.target).closest(".dropdown-menu").length):!jt.test(e.which))&&!this.disabled&&!i.default(this).hasClass("disabled")){var n=t._getParentFromElement(this),o=i.default(n).hasClass("show");if(o||27!==e.which){if(e.preventDefault(),e.stopPropagation(),!o||27===e.which||32===e.which)return 27===e.which&&i.default(n.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void i.default(this).trigger("click");var r=[].slice.call(n.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return i.default(t).is(":visible")}));if(0!==r.length){var a=r.indexOf(e.target);38===e.which&&a>0&&a--,40===e.which&&a<r.length-1&&a++,a<0&&(a=0),r[a].focus()}}}},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return Lt}},{key:"DefaultType",get:function(){return Pt}}]),t}();i.default(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',Ft._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",Ft._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",Ft._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),Ft._jQueryInterface.call(i.default(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),i.default.fn[Ot]=Ft._jQueryInterface,i.default.fn[Ot].Constructor=Ft,i.default.fn[Ot].noConflict=function(){return i.default.fn[Ot]=xt,Ft._jQueryInterface};var Rt=i.default.fn.modal,Ht={backdrop:!0,keyboard:!0,focus:!0,show:!0},Mt={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Bt=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var e=t.prototype;return e.toggle=function(t){return this._isShown?this.hide():this.show(t)},e.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){i.default(this._element).hasClass("fade")&&(this._isTransitioning=!0);var n=i.default.Event("show.bs.modal",{relatedTarget:t});i.default(this._element).trigger(n),this._isShown||n.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),i.default(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return e.hide(t)})),i.default(this._dialog).on("mousedown.dismiss.bs.modal",(function(){i.default(e._element).one("mouseup.dismiss.bs.modal",(function(t){i.default(t.target).is(e._element)&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},e.hide=function(t){var e=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var n=i.default.Event("hide.bs.modal");if(i.default(this._element).trigger(n),this._isShown&&!n.isDefaultPrevented()){this._isShown=!1;var o=i.default(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),i.default(document).off("focusin.bs.modal"),i.default(this._element).removeClass("show"),i.default(this._element).off("click.dismiss.bs.modal"),i.default(this._dialog).off("mousedown.dismiss.bs.modal"),o){var r=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,(function(t){return e._hideModal(t)})).emulateTransitionEnd(r)}else this._hideModal()}}},e.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return i.default(t).off(".bs.modal")})),i.default(document).off("focusin.bs.modal"),i.default.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},e.handleUpdate=function(){this._adjustDialog()},e._getConfig=function(t){return t=a({},Ht,t),l.typeCheckConfig("modal",t,Mt),t},e._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var e=i.default.Event("hidePrevented.bs.modal");if(i.default(this._element).trigger(e),e.isDefaultPrevented())return;var n=this._element.scrollHeight>document.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=l.getTransitionDurationFromElement(this._dialog);i.default(this._element).off(l.TRANSITION_END),i.default(this._element).one(l.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),n||i.default(t._element).one(l.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}else this.hide()},e._showElement=function(t){var e=this,n=i.default(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),i.default(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,n&&l.reflow(this._element),i.default(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var r=i.default.Event("shown.bs.modal",{relatedTarget:t}),a=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,i.default(e._element).trigger(r)};if(n){var s=l.getTransitionDurationFromElement(this._dialog);i.default(this._dialog).one(l.TRANSITION_END,a).emulateTransitionEnd(s)}else a()},e._enforceFocus=function(){var t=this;i.default(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(e){document!==e.target&&t._element!==e.target&&0===i.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?i.default(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||i.default(this._element).off("keydown.dismiss.bs.modal")},e._setResizeEvent=function(){var t=this;this._isShown?i.default(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):i.default(window).off("resize.bs.modal")},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){i.default(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),i.default(t._element).trigger("hidden.bs.modal")}))},e._removeBackdrop=function(){this._backdrop&&(i.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=i.default(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),i.default(this._backdrop).appendTo(document.body),i.default(this._element).on("click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&e._triggerBackdropTransition()})),n&&l.reflow(this._backdrop),i.default(this._backdrop).addClass("show"),!t)return;if(!n)return void t();var o=l.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(l.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){i.default(this._backdrop).removeClass("show");var r=function(){e._removeBackdrop(),t&&t()};if(i.default(this._element).hasClass("fade")){var a=l.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(l.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},e._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var e=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),n=[].slice.call(document.querySelectorAll(".sticky-top"));i.default(e).each((function(e,n){var o=n.style.paddingRight,r=i.default(n).css("padding-right");i.default(n).data("padding-right",o).css("padding-right",parseFloat(r)+t._scrollbarWidth+"px")})),i.default(n).each((function(e,n){var o=n.style.marginRight,r=i.default(n).css("margin-right");i.default(n).data("margin-right",o).css("margin-right",parseFloat(r)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,r=i.default(document.body).css("padding-right");i.default(document.body).data("padding-right",o).css("padding-right",parseFloat(r)+this._scrollbarWidth+"px")}i.default(document.body).addClass("modal-open")},e._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));i.default(t).each((function(t,e){var n=i.default(e).data("padding-right");i.default(e).removeData("padding-right"),e.style.paddingRight=n||""}));var e=[].slice.call(document.querySelectorAll(".sticky-top"));i.default(e).each((function(t,e){var n=i.default(e).data("margin-right");"undefined"!=typeof n&&i.default(e).css("margin-right",n).removeData("margin-right")}));var n=i.default(document.body).data("padding-right");i.default(document.body).removeData("padding-right"),document.body.style.paddingRight=n||""},e._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(e,n){return this.each((function(){var o=i.default(this).data("bs.modal"),r=a({},Ht,i.default(this).data(),"object"==typeof e&&e?e:{});if(o||(o=new t(this,r),i.default(this).data("bs.modal",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e](n)}else r.show&&o.show(n)}))},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return Ht}}]),t}();i.default(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e,n=this,o=l.getSelectorFromElement(this);o&&(e=document.querySelector(o));var r=i.default(e).data("bs.modal")?"toggle":a({},i.default(e).data(),i.default(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var s=i.default(e).one("show.bs.modal",(function(t){t.isDefaultPrevented()||s.one("hidden.bs.modal",(function(){i.default(n).is(":visible")&&n.focus()}))}));Bt._jQueryInterface.call(i.default(e),r,this)})),i.default.fn.modal=Bt._jQueryInterface,i.default.fn.modal.Constructor=Bt,i.default.fn.modal.noConflict=function(){return i.default.fn.modal=Rt,Bt._jQueryInterface};var qt=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Qt={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Wt=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,Ut=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Vt(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),r=[].slice.call(i.body.querySelectorAll("*")),a=function(t,n){var i=r[t],a=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var s=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[a]||[]);s.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===qt.indexOf(n)||Boolean(t.nodeValue.match(Wt)||t.nodeValue.match(Ut));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,r=i.length;o<r;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},s=0,l=r.length;s<l;s++)a(s);return i.body.innerHTML}var Yt="tooltip",zt=i.default.fn[Yt],Xt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Kt=["sanitize","whiteList","sanitizeFn"],Gt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},$t={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Jt={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Qt,popperConfig:null},Zt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},te=function(){function t(t,e){if("undefined"==typeof It)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=i.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(i.default(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),i.default.removeData(this.element,this.constructor.DATA_KEY),i.default(this.element).off(this.constructor.EVENT_KEY),i.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&i.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===i.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=i.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){i.default(this.element).trigger(e);var n=l.findShadowRoot(this.element),o=i.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!o)return;var r=this.getTipElement(),a=l.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&i.default(r).addClass("fade");var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,u=this._getAttachment(s);this.addAttachmentClass(u);var f=this._getContainer();i.default(r).data(this.constructor.DATA_KEY,this),i.default.contains(this.element.ownerDocument.documentElement,this.tip)||i.default(r).appendTo(f),i.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new It(this.element,r,this._getPopperConfig(u)),i.default(r).addClass("show"),"ontouchstart"in document.documentElement&&i.default(document.body).children().on("mouseover",null,i.default.noop);var d=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,i.default(t.element).trigger(t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(i.default(this.tip).hasClass("fade")){var c=l.getTransitionDurationFromElement(this.tip);i.default(this.tip).one(l.TRANSITION_END,d).emulateTransitionEnd(c)}else d()}},e.hide=function(t){var e=this,n=this.getTipElement(),o=i.default.Event(this.constructor.Event.HIDE),r=function(){"show"!==e._hoverState&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),i.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(i.default(this.element).trigger(o),!o.isDefaultPrevented()){if(i.default(n).removeClass("show"),"ontouchstart"in document.documentElement&&i.default(document.body).children().off("mouseover",null,i.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,i.default(this.tip).hasClass("fade")){var a=l.getTransitionDurationFromElement(n);i.default(n).one(l.TRANSITION_END,r).emulateTransitionEnd(a)}else r();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(i.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),i.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Vt(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?i.default(e).parent().is(t)||t.empty().append(e):t.text(i.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return a({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:l.isElement(this.config.container)?i.default(this.config.container):i.default(document).find(this.config.container)},e._getAttachment=function(t){return $t[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)i.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;i.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},i.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=a({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),i.default(e.getTipElement()).hasClass("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=i.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Kt.indexOf(t)&&delete e[t]})),"number"==typeof(t=a({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),l.typeCheckConfig(Yt,t,this.constructor.DefaultType),t.sanitize&&(t.template=Vt(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(Xt);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(i.default(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.tooltip"),r="object"==typeof e&&e;if((o||!/dispose|hide/.test(e))&&(o||(o=new t(this,r),n.data("bs.tooltip",o)),"string"==typeof e)){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return Jt}},{key:"NAME",get:function(){return Yt}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Zt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Gt}}]),t}();i.default.fn[Yt]=te._jQueryInterface,i.default.fn[Yt].Constructor=te,i.default.fn[Yt].noConflict=function(){return i.default.fn[Yt]=zt,te._jQueryInterface};var ee="popover",ne=i.default.fn[ee],ie=new RegExp("(^|\\s)bs-popover\\S+","g"),oe=a({},te.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),re=a({},te.DefaultType,{content:"(string|element|function)"}),ae={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},se=function(t){var e,n;function o(){return t.apply(this,arguments)||this}n=t,(e=o).prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n;var a=o.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},a.setContent=function(){var t=i.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(ie);null!==e&&e.length>0&&t.removeClass(e.join(""))},o._jQueryInterface=function(t){return this.each((function(){var e=i.default(this).data("bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n),i.default(this).data("bs.popover",e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},r(o,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return oe}},{key:"NAME",get:function(){return ee}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return ae}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return re}}]),o}(te);i.default.fn[ee]=se._jQueryInterface,i.default.fn[ee].Constructor=se,i.default.fn[ee].noConflict=function(){return i.default.fn[ee]=ne,se._jQueryInterface};var le="scrollspy",ue=i.default.fn[le],fe={offset:10,method:"auto",target:""},de={offset:"number",method:"string",target:"(string|element)"},ce=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,i.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,o="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,r=l.getSelectorFromElement(t);if(r&&(e=document.querySelector(r)),e){var a=e.getBoundingClientRect();if(a.width||a.height)return[i.default(e)[n]().top+o,r]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){i.default.removeData(this._element,"bs.scrollspy"),i.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=a({},fe,"object"==typeof t&&t?t:{})).target&&l.isElement(t.target)){var e=i.default(t.target).attr("id");e||(e=l.getUID(le),i.default(t.target).attr("id",e)),t.target="#"+e}return l.typeCheckConfig(le,t,de),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},e._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=i.default([].slice.call(document.querySelectorAll(e.join(","))));n.hasClass("dropdown-item")?(n.closest(".dropdown").find(".dropdown-toggle").addClass("active"),n.addClass("active")):(n.addClass("active"),n.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),n.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),i.default(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},e._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.scrollspy");if(n||(n=new t(this,"object"==typeof e&&e),i.default(this).data("bs.scrollspy",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return fe}}]),t}();i.default(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),e=t.length;e--;){var n=i.default(t[e]);ce._jQueryInterface.call(n,n.data())}})),i.default.fn[le]=ce._jQueryInterface,i.default.fn[le].Constructor=ce,i.default.fn[le].noConflict=function(){return i.default.fn[le]=ue,ce._jQueryInterface};var he=i.default.fn.tab,pe=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&i.default(this._element).hasClass("active")||i.default(this._element).hasClass("disabled"))){var e,n,o=i.default(this._element).closest(".nav, .list-group")[0],r=l.getSelectorFromElement(this._element);if(o){var a="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";n=(n=i.default.makeArray(i.default(o).find(a)))[n.length-1]}var s=i.default.Event("hide.bs.tab",{relatedTarget:this._element}),u=i.default.Event("show.bs.tab",{relatedTarget:n});if(n&&i.default(n).trigger(s),i.default(this._element).trigger(u),!u.isDefaultPrevented()&&!s.isDefaultPrevented()){r&&(e=document.querySelector(r)),this._activate(this._element,o);var f=function(){var e=i.default.Event("hidden.bs.tab",{relatedTarget:t._element}),o=i.default.Event("shown.bs.tab",{relatedTarget:n});i.default(n).trigger(e),i.default(t._element).trigger(o)};e?this._activate(e,e.parentNode,f):f()}}},e.dispose=function(){i.default.removeData(this._element,"bs.tab"),this._element=null},e._activate=function(t,e,n){var o=this,r=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?i.default(e).children(".active"):i.default(e).find("> li > .active"))[0],a=n&&r&&i.default(r).hasClass("fade"),s=function(){return o._transitionComplete(t,r,n)};if(r&&a){var u=l.getTransitionDurationFromElement(r);i.default(r).removeClass("show").one(l.TRANSITION_END,s).emulateTransitionEnd(u)}else s()},e._transitionComplete=function(t,e,n){if(e){i.default(e).removeClass("active");var o=i.default(e.parentNode).find("> .dropdown-menu .active")[0];o&&i.default(o).removeClass("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}if(i.default(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),l.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&i.default(t.parentNode).hasClass("dropdown-menu")){var r=i.default(t).closest(".dropdown")[0];if(r){var a=[].slice.call(r.querySelectorAll(".dropdown-toggle"));i.default(a).addClass("active")}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.tab");if(o||(o=new t(this),n.data("bs.tab",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}}]),t}();i.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),pe._jQueryInterface.call(i.default(this),"show")})),i.default.fn.tab=pe._jQueryInterface,i.default.fn.tab.Constructor=pe,i.default.fn.tab.noConflict=function(){return i.default.fn.tab=he,pe._jQueryInterface};var me=i.default.fn.toast,ge={animation:"boolean",autohide:"boolean",delay:"number"},ve={animation:!0,autohide:!0,delay:500},_e=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=i.default.Event("show.bs.toast");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),i.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),l.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,n).emulateTransitionEnd(o)}else n()}},e.hide=function(){if(this._element.classList.contains("show")){var t=i.default.Event("hide.bs.toast");i.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),i.default(this._element).off("click.dismiss.bs.toast"),i.default.removeData(this._element,"bs.toast"),this._element=null,this._config=null},e._getConfig=function(t){return t=a({},ve,i.default(this._element).data(),"object"==typeof t&&t?t:{}),l.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;i.default(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add("hide"),i.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.toast");if(o||(o=new t(this,"object"==typeof e&&e),n.data("bs.toast",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e](this)}}))},r(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"DefaultType",get:function(){return ge}},{key:"Default",get:function(){return ve}}]),t}();i.default.fn.toast=_e._jQueryInterface,i.default.fn.toast.Constructor=_e,i.default.fn.toast.noConflict=function(){return i.default.fn.toast=me,_e._jQueryInterface},t.Alert=d,t.Button=h,t.Carousel=y,t.Collapse=S,t.Dropdown=Ft,t.Modal=Bt,t.Popover=se,t.Scrollspy=ce,t.Tab=pe,t.Toast=_e,t.Tooltip=te,t.Util=l,Object.defineProperty(t,"__esModule",{value:!0})})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery)}(this,(function(t,e){"use strict";function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var i=n(e);function o(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function r(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function s(t){var e=this,n=!1;return i.default(this).one(l.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||l.triggerTransitionEnd(e)}),t),this}var l={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=i.default(t).css("transition-duration"),n=i.default(t).css("transition-delay"),o=parseFloat(e),r=parseFloat(n);return o||r?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){i.default(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],r=e[i],a=r&&l.isElement(r)?"element":null===(s=r)||"undefined"==typeof s?""+s:{}.toString.call(s).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(a))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+a+'" but expected type "'+o+'".')}var s},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?l.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof i.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=i.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};l.jQueryDetection(),i.default.fn.emulateTransitionEnd=s,i.default.event.special[l.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(i.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var u="alert",f=i.default.fn[u],d=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){i.default.removeData(this._element,"bs.alert"),this._element=null},e._getRootElement=function(t){var e=l.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=i.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=i.default.Event("close.bs.alert");return i.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(i.default(t).removeClass("show"),i.default(t).hasClass("fade")){var n=l.getTransitionDurationFromElement(t);i.default(t).one(l.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){i.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.alert");o||(o=new t(this),n.data("bs.alert",o)),"close"===e&&o[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();i.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',d._handleDismiss(new d)),i.default.fn[u]=d._jQueryInterface,i.default.fn[u].Constructor=d,i.default.fn[u].noConflict=function(){return i.default.fn[u]=f,d._jQueryInterface};var c=i.default.fn.button,h=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=i.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var r=n.querySelector(".active");r&&i.default(r).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),this.shouldAvoidTriggerChange||i.default(o).trigger("change")),o.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&i.default(this._element).toggleClass("active"))},e.dispose=function(){i.default.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var o=i.default(this),r=o.data("bs.button");r||(r=new t(this),o.data("bs.button",r)),r.shouldAvoidTriggerChange=n,"toggle"===e&&r[e]()}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();i.default(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target,n=e;if(i.default(e).hasClass("btn")||(e=i.default(e).closest(".btn")[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var o=e.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||h._jQueryInterface.call(i.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=i.default(t.target).closest(".btn")[0];i.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),i.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var r=0,a=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;r<a;r++){var s=t[r];"true"===s.getAttribute("aria-pressed")?s.classList.add("active"):s.classList.remove("active")}})),i.default.fn.button=h._jQueryInterface,i.default.fn.button.Constructor=h,i.default.fn.button.noConflict=function(){return i.default.fn.button=c,h._jQueryInterface};var p="carousel",m=".bs.carousel",g=i.default.fn[p],v={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},_={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},b={TOUCH:"touch",PEN:"pen"},y=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide("next")},e.nextWhenVisible=function(){var t=i.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide("prev")},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(l.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(".active.carousel-item");var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)i.default(this._element).one("slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var o=t>n?"next":"prev";this._slide(o,this._items[t])}},e.dispose=function(){i.default(this._element).off(m),i.default.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=a({},v,t),l.typeCheckConfig(p,t,_),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&i.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&i.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};i.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(i.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(i.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),i.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),i.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var a=(o+("prev"===t?-1:1))%this._items.length;return-1===a?this._items[this._items.length-1]:this._items[a]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),r=i.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:o,to:n});return i.default(this._element).trigger(r),r},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));i.default(e).removeClass("active");var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&i.default(n).addClass("active")}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(".active.carousel-item");if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,o,r,a=this,s=this._element.querySelector(".active.carousel-item"),u=this._getItemIndex(s),f=e||s&&this._getItemByDirection(t,s),d=this._getItemIndex(f),c=Boolean(this._interval);if("next"===t?(n="carousel-item-left",o="carousel-item-next",r="left"):(n="carousel-item-right",o="carousel-item-prev",r="right"),f&&i.default(f).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(f,r).isDefaultPrevented()&&s&&f){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(f),this._activeElement=f;var h=i.default.Event("slid.bs.carousel",{relatedTarget:f,direction:r,from:u,to:d});if(i.default(this._element).hasClass("slide")){i.default(f).addClass(o),l.reflow(f),i.default(s).addClass(n),i.default(f).addClass(n);var p=l.getTransitionDurationFromElement(s);i.default(s).one(l.TRANSITION_END,(function(){i.default(f).removeClass(n+" "+o).addClass("active"),i.default(s).removeClass("active "+o+" "+n),a._isSliding=!1,setTimeout((function(){return i.default(a._element).trigger(h)}),0)})).emulateTransitionEnd(p)}else i.default(s).removeClass("active"),i.default(f).addClass("active"),this._isSliding=!1,i.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.carousel"),o=a({},v,i.default(this).data());"object"==typeof e&&(o=a({},o,e));var r="string"==typeof e?e:o.slide;if(n||(n=new t(this,o),i.default(this).data("bs.carousel",n)),"number"==typeof e)n.to(e);else if("string"==typeof r){if("undefined"==typeof n[r])throw new TypeError('No method named "'+r+'"');n[r]()}else o.interval&&o.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=l.getSelectorFromElement(this);if(n){var o=i.default(n)[0];if(o&&i.default(o).hasClass("carousel")){var r=a({},i.default(o).data(),i.default(this).data()),s=this.getAttribute("data-slide-to");s&&(r.interval=!1),t._jQueryInterface.call(i.default(o),r),s&&i.default(o).data("bs.carousel").to(s),e.preventDefault()}}},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return v}}]),t}();i.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",y._dataApiClickHandler),i.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e<n;e++){var o=i.default(t[e]);y._jQueryInterface.call(o,o.data())}})),i.default.fn[p]=y._jQueryInterface,i.default.fn[p].Constructor=y,i.default.fn[p].noConflict=function(){return i.default.fn[p]=g,y._jQueryInterface};var w="collapse",E=i.default.fn[w],T={toggle:!0,parent:""},C={toggle:"boolean",parent:"(string|element)"},S=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var r=n[i],a=l.getSelectorFromElement(r),s=[].slice.call(document.querySelectorAll(a)).filter((function(e){return e===t}));null!==a&&s.length>0&&(this._selector=a,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){i.default(this._element).hasClass("show")?this.hide():this.show()},e.show=function(){var e,n,o=this;if(!this._isTransitioning&&!i.default(this._element).hasClass("show")&&(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(e=null),!(e&&(n=i.default(e).not(this._selector).data("bs.collapse"))&&n._isTransitioning))){var r=i.default.Event("show.bs.collapse");if(i.default(this._element).trigger(r),!r.isDefaultPrevented()){e&&(t._jQueryInterface.call(i.default(e).not(this._selector),"hide"),n||i.default(e).data("bs.collapse",null));var a=this._getDimension();i.default(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[a]=0,this._triggerArray.length&&i.default(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var s="scroll"+(a[0].toUpperCase()+a.slice(1)),u=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,(function(){i.default(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[a]="",o.setTransitioning(!1),i.default(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(u),this._element.style[a]=this._element[s]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&i.default(this._element).hasClass("show")){var e=i.default.Event("hide.bs.collapse");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",l.reflow(this._element),i.default(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var r=0;r<o;r++){var a=this._triggerArray[r],s=l.getSelectorFromElement(a);if(null!==s)i.default([].slice.call(document.querySelectorAll(s))).hasClass("show")||i.default(a).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[n]="";var u=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,(function(){t.setTransitioning(!1),i.default(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(u)}}},e.setTransitioning=function(t){this._isTransitioning=t},e.dispose=function(){i.default.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},e._getConfig=function(t){return(t=a({},T,t)).toggle=Boolean(t.toggle),l.typeCheckConfig(w,t,C),t},e._getDimension=function(){return i.default(this._element).hasClass("width")?"width":"height"},e._getParent=function(){var e,n=this;l.isElement(this._config.parent)?(e=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(e=this._config.parent[0])):e=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',r=[].slice.call(e.querySelectorAll(o));return i.default(r).each((function(e,i){n._addAriaAndCollapsedClass(t._getTargetFromElement(i),[i])})),e},e._addAriaAndCollapsedClass=function(t,e){var n=i.default(t).hasClass("show");e.length&&i.default(e).toggleClass("collapsed",!n).attr("aria-expanded",n)},t._getTargetFromElement=function(t){var e=l.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.collapse"),r=a({},T,n.data(),"object"==typeof e&&e?e:{});if(!o&&r.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(r.toggle=!1),o||(o=new t(this,r),n.data("bs.collapse",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return T}}]),t}();i.default(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var e=i.default(this),n=l.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(n));i.default(o).each((function(){var t=i.default(this),n=t.data("bs.collapse")?"toggle":e.data();S._jQueryInterface.call(t,n)}))})),i.default.fn[w]=S._jQueryInterface,i.default.fn[w].Constructor=S,i.default.fn[w].noConflict=function(){return i.default.fn[w]=E,S._jQueryInterface};var D="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,N=function(){for(var t=["Edge","Trident","Firefox"],e=0;e<t.length;e+=1)if(D&&navigator.userAgent.indexOf(t[e])>=0)return 1;return 0}();var k=D&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),N))}};function A(t){return t&&"[object Function]"==={}.toString.call(t)}function I(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function O(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function x(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=I(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:x(O(t))}function j(t){return t&&t.referenceNode?t.referenceNode:t}var L=D&&!(!window.MSInputMethodContext||!document.documentMode),P=D&&/MSIE 10/.test(navigator.userAgent);function F(t){return 11===t?L:10===t?P:L||P}function R(t){if(!t)return document.documentElement;for(var e=F(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===I(n,"position")?R(n):n:t?t.ownerDocument.documentElement:document.documentElement}function H(t){return null!==t.parentNode?H(t.parentNode):t}function M(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var a,s,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(s=(a=l).nodeName)||"HTML"!==s&&R(a.firstElementChild)!==a?R(l):l;var u=H(t);return u.host?M(u.host,e):M(t,H(e).host)}function q(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function B(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=q(e,"top"),o=q(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function Q(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+i+"Width"])}function W(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],F(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function U(t){var e=t.body,n=t.documentElement,i=F(10)&&getComputedStyle(n);return{height:W("Height",e,n,i),width:W("Width",e,n,i)}}var V=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},Y=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),z=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},X=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t};function K(t){return X({},t,{right:t.left+t.width,bottom:t.top+t.height})}function G(t){var e={};try{if(F(10)){e=t.getBoundingClientRect();var n=q(t,"top"),i=q(t,"left");e.top+=n,e.left+=i,e.bottom+=n,e.right+=i}else e=t.getBoundingClientRect()}catch(t){}var o={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},r="HTML"===t.nodeName?U(t.ownerDocument):{},a=r.width||t.clientWidth||o.width,s=r.height||t.clientHeight||o.height,l=t.offsetWidth-a,u=t.offsetHeight-s;if(l||u){var f=I(t);l-=Q(f,"x"),u-=Q(f,"y"),o.width-=l,o.height-=u}return K(o)}function $(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=F(10),o="HTML"===e.nodeName,r=G(t),a=G(e),s=x(t),l=I(e),u=parseFloat(l.borderTopWidth),f=parseFloat(l.borderLeftWidth);n&&o&&(a.top=Math.max(a.top,0),a.left=Math.max(a.left,0));var d=K({top:r.top-a.top-u,left:r.left-a.left-f,width:r.width,height:r.height});if(d.marginTop=0,d.marginLeft=0,!i&&o){var c=parseFloat(l.marginTop),h=parseFloat(l.marginLeft);d.top-=u-c,d.bottom-=u-c,d.left-=f-h,d.right-=f-h,d.marginTop=c,d.marginLeft=h}return(i&&!n?e.contains(s):e===s&&"BODY"!==s.nodeName)&&(d=B(d,e)),d}function J(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=$(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),a=e?0:q(n),s=e?0:q(n,"left"),l={top:a-i.top+i.marginTop,left:s-i.left+i.marginLeft,width:o,height:r};return K(l)}function Z(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===I(t,"position"))return!0;var n=O(t);return!!n&&Z(n)}function tt(t){if(!t||!t.parentElement||F())return document.documentElement;for(var e=t.parentElement;e&&"none"===I(e,"transform");)e=e.parentElement;return e||document.documentElement}function et(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},a=o?tt(t):M(t,j(e));if("viewport"===i)r=J(a,o);else{var s=void 0;"scrollParent"===i?"BODY"===(s=x(O(e))).nodeName&&(s=t.ownerDocument.documentElement):s="window"===i?t.ownerDocument.documentElement:i;var l=$(s,a,o);if("HTML"!==s.nodeName||Z(a))r=l;else{var u=U(t.ownerDocument),f=u.height,d=u.width;r.top+=l.top-l.marginTop,r.bottom=f+l.top,r.left+=l.left-l.marginLeft,r.right=d+l.left}}var c="number"==typeof(n=n||0);return r.left+=c?n:n.left||0,r.top+=c?n:n.top||0,r.right-=c?n:n.right||0,r.bottom-=c?n:n.bottom||0,r}function nt(t){return t.width*t.height}function it(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var a=et(n,i,r,o),s={top:{width:a.width,height:e.top-a.top},right:{width:a.right-e.right,height:a.height},bottom:{width:a.width,height:a.bottom-e.bottom},left:{width:e.left-a.left,height:a.height}},l=Object.keys(s).map((function(t){return X({key:t},s[t],{area:nt(s[t])})})).sort((function(t,e){return e.area-t.area})),u=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),f=u.length>0?u[0].key:l[0].key,d=t.split("-")[1];return f+(d?"-"+d:"")}function ot(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?tt(e):M(e,j(n));return $(n,o,i)}function rt(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function at(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function st(t,e,n){n=n.split("-")[0];var i=rt(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),a=r?"top":"left",s=r?"left":"top",l=r?"height":"width",u=r?"width":"height";return o[a]=e[a]+e[l]/2-i[l]/2,o[s]=n===s?e[s]-i[u]:e[at(s)],o}function lt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function ut(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=lt(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&A(n)&&(e.offsets.popper=K(e.offsets.popper),e.offsets.reference=K(e.offsets.reference),e=n(e,t))})),e}function ft(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=ot(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=it(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=st(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=ut(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function dt(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ct(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i<e.length;i++){var o=e[i],r=o?""+o+n:t;if("undefined"!=typeof document.body.style[r])return r}return null}function ht(){return this.state.isDestroyed=!0,dt(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.position="",this.popper.style.top="",this.popper.style.left="",this.popper.style.right="",this.popper.style.bottom="",this.popper.style.willChange="",this.popper.style[ct("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function pt(t){var e=t.ownerDocument;return e?e.defaultView:window}function mt(t,e,n,i){n.updateBound=i,pt(t).addEventListener("resize",n.updateBound,{passive:!0});var o=x(t);return function t(e,n,i,o){var r="BODY"===e.nodeName,a=r?e.ownerDocument.defaultView:e;a.addEventListener(n,i,{passive:!0}),r||t(x(a.parentNode),n,i,o),o.push(a)}(o,"scroll",n.updateBound,n.scrollParents),n.scrollElement=o,n.eventsEnabled=!0,n}function gt(){this.state.eventsEnabled||(this.state=mt(this.reference,this.options,this.state,this.scheduleUpdate))}function vt(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,pt(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach((function(t){t.removeEventListener("scroll",e.updateBound)})),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function _t(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function bt(t,e){Object.keys(e).forEach((function(n){var i="";-1!==["width","height","top","right","bottom","left"].indexOf(n)&&_t(e[n])&&(i="px"),t.style[n]=e[n]+i}))}var yt=D&&/Firefox/i.test(navigator.userAgent);function wt(t,e,n){var i=lt(t,(function(t){return t.name===e})),o=!!i&&t.some((function(t){return t.name===n&&t.enabled&&t.order<i.order}));if(!o){var r="`"+e+"`",a="`"+n+"`";console.warn(a+" modifier is required by "+r+" modifier in order to work, be sure to include it before "+r+"!")}return o}var Et=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],Tt=Et.slice(3);function Ct(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=Tt.indexOf(t),i=Tt.slice(n+1).concat(Tt.slice(0,n));return e?i.reverse():i}var St="flip",Dt="clockwise",Nt="counterclockwise";function kt(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),a=t.split(/(\+|\-)/).map((function(t){return t.trim()})),s=a.indexOf(lt(a,(function(t){return-1!==t.search(/,|\s/)})));a[s]&&-1===a[s].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,u=-1!==s?[a.slice(0,s).concat([a[s].split(l)[0]]),[a[s].split(l)[1]].concat(a.slice(s+1))]:[a];return(u=u.map((function(t,i){var o=(1===i?!r:r)?"height":"width",a=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,a=!0,t):a?(t[t.length-1]+=e,a=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],a=o[2];if(!r)return t;if(0===a.indexOf("%")){var s=void 0;switch(a){case"%p":s=n;break;case"%":case"%r":default:s=i}return K(s)[e]/100*r}if("vh"===a||"vw"===a)return("vh"===a?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r;return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){_t(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var At={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,a=o.popper,s=-1!==["bottom","top"].indexOf(n),l=s?"left":"top",u=s?"width":"height",f={start:z({},l,r[l]),end:z({},l,r[l]+r[u]-a[u])};t.offsets.popper=X({},a,f[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,a=o.reference,s=i.split("-")[0],l=void 0;return l=_t(+n)?[+n,0]:kt(n,r,a,s),"left"===s?(r.top+=l[0],r.left-=l[1]):"right"===s?(r.top+=l[0],r.left+=l[1]):"top"===s?(r.left+=l[0],r.top-=l[1]):"bottom"===s&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||R(t.instance.popper);t.instance.reference===n&&(n=R(n));var i=ct("transform"),o=t.instance.popper.style,r=o.top,a=o.left,s=o[i];o.top="",o.left="",o[i]="";var l=et(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=a,o[i]=s,e.boundaries=l;var u=e.priority,f=t.offsets.popper,d={primary:function(t){var n=f[t];return f[t]<l[t]&&!e.escapeWithReference&&(n=Math.max(f[t],l[t])),z({},t,n)},secondary:function(t){var n="right"===t?"left":"top",i=f[n];return f[t]>l[t]&&!e.escapeWithReference&&(i=Math.min(f[n],l[t]-("right"===t?f.width:f.height))),z({},n,i)}};return u.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";f=X({},f,d[e](t))})),t.offsets.popper=f,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(o),s=a?"right":"bottom",l=a?"left":"top",u=a?"width":"height";return n[s]<r(i[l])&&(t.offsets.popper[l]=r(i[l])-n[u]),n[l]>r(i[s])&&(t.offsets.popper[l]=r(i[s])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!wt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,a=r.popper,s=r.reference,l=-1!==["left","right"].indexOf(o),u=l?"height":"width",f=l?"Top":"Left",d=f.toLowerCase(),c=l?"left":"top",h=l?"bottom":"right",p=rt(i)[u];s[h]-p<a[d]&&(t.offsets.popper[d]-=a[d]-(s[h]-p)),s[d]+p>a[h]&&(t.offsets.popper[d]+=s[d]+p-a[h]),t.offsets.popper=K(t.offsets.popper);var m=s[d]+s[u]/2-p/2,g=I(t.instance.popper),v=parseFloat(g["margin"+f]),_=parseFloat(g["border"+f+"Width"]),b=m-t.offsets.popper[d]-v-_;return b=Math.max(Math.min(a[u]-p,b),0),t.arrowElement=i,t.offsets.arrow=(z(n={},d,Math.round(b)),z(n,c,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(dt(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=et(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=at(i),r=t.placement.split("-")[1]||"",a=[];switch(e.behavior){case St:a=[i,o];break;case Dt:a=Ct(i);break;case Nt:a=Ct(i,!0);break;default:a=e.behavior}return a.forEach((function(s,l){if(i!==s||a.length===l+1)return t;i=t.placement.split("-")[0],o=at(i);var u=t.offsets.popper,f=t.offsets.reference,d=Math.floor,c="left"===i&&d(u.right)>d(f.left)||"right"===i&&d(u.left)<d(f.right)||"top"===i&&d(u.bottom)>d(f.top)||"bottom"===i&&d(u.top)<d(f.bottom),h=d(u.left)<d(n.left),p=d(u.right)>d(n.right),m=d(u.top)<d(n.top),g=d(u.bottom)>d(n.bottom),v="left"===i&&h||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,_=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(_&&"start"===r&&h||_&&"end"===r&&p||!_&&"start"===r&&m||!_&&"end"===r&&g),y=!!e.flipVariationsByContent&&(_&&"start"===r&&p||_&&"end"===r&&h||!_&&"start"===r&&g||!_&&"end"===r&&m),w=b||y;(c||v||w)&&(t.flipped=!0,(c||v)&&(i=a[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=X({},t.offsets.popper,st(t.instance.popper,t.offsets.reference,t.placement)),t=ut(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,a=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return o[a?"left":"top"]=r[n]-(s?o[a?"width":"height"]:0),t.placement=at(e),t.offsets.popper=K(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!wt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=lt(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottom<n.top||e.left>n.right||e.top>n.bottom||e.right<n.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var n=e.x,i=e.y,o=t.offsets.popper,r=lt(t.instance.modifiers,(function(t){return"applyStyle"===t.name})).gpuAcceleration;void 0!==r&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var a=void 0!==r?r:e.gpuAcceleration,s=R(t.instance.popper),l=G(s),u={position:o.position},f=function(t,e){var n=t.offsets,i=n.popper,o=n.reference,r=Math.round,a=Math.floor,s=function(t){return t},l=r(o.width),u=r(i.width),f=-1!==["left","right"].indexOf(t.placement),d=-1!==t.placement.indexOf("-"),c=e?f||d||l%2==u%2?r:a:s,h=e?r:s;return{left:c(l%2==1&&u%2==1&&!d&&e?i.left-1:i.left),top:h(i.top),bottom:h(i.bottom),right:c(i.right)}}(t,window.devicePixelRatio<2||!yt),d="bottom"===n?"top":"bottom",c="right"===i?"left":"right",h=ct("transform"),p=void 0,m=void 0;if(m="bottom"===d?"HTML"===s.nodeName?-s.clientHeight+f.bottom:-l.height+f.bottom:f.top,p="right"===c?"HTML"===s.nodeName?-s.clientWidth+f.right:-l.width+f.right:f.left,a&&h)u[h]="translate3d("+p+"px, "+m+"px, 0)",u[d]=0,u[c]=0,u.willChange="transform";else{var g="bottom"===d?-1:1,v="right"===c?-1:1;u[d]=m*g,u[c]=p*v,u.willChange=d+", "+c}var _={"x-placement":t.placement};return t.attributes=X({},_,t.attributes),t.styles=X({},u,t.styles),t.arrowStyles=X({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){var e,n;return bt(t.instance.popper,t.styles),e=t.instance.popper,n=t.attributes,Object.keys(n).forEach((function(t){!1!==n[t]?e.setAttribute(t,n[t]):e.removeAttribute(t)})),t.arrowElement&&Object.keys(t.arrowStyles).length&&bt(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,n,i,o){var r=ot(o,e,t,n.positionFixed),a=it(n.placement,r,e,t,n.modifiers.flip.boundariesElement,n.modifiers.flip.padding);return e.setAttribute("x-placement",a),bt(e,{position:n.positionFixed?"fixed":"absolute"}),n},gpuAcceleration:void 0}}},It=function(){function t(e,n){var i=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};V(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=k(this.update.bind(this)),this.options=X({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(X({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=X({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return X({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&A(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return Y(t,[{key:"update",value:function(){return ft.call(this)}},{key:"destroy",value:function(){return ht.call(this)}},{key:"enableEventListeners",value:function(){return gt.call(this)}},{key:"disableEventListeners",value:function(){return vt.call(this)}}]),t}();It.Utils=("undefined"!=typeof window?window:global).PopperUtils,It.placements=Et,It.Defaults=At;var Ot="dropdown",xt=i.default.fn[Ot],jt=new RegExp("38|40|27"),Lt={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Pt={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},Ft=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!i.default(this._element).hasClass("disabled")){var e=i.default(this._menu).hasClass("show");t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||i.default(this._element).hasClass("disabled")||i.default(this._menu).hasClass("show"))){var n={relatedTarget:this._element},o=i.default.Event("show.bs.dropdown",n),r=t._getParentFromElement(this._element);if(i.default(r).trigger(o),!o.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof It)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");var a=this._element;"parent"===this._config.reference?a=r:l.isElement(this._config.reference)&&(a=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(a=this._config.reference[0])),"scrollParent"!==this._config.boundary&&i.default(r).addClass("position-static"),this._popper=new It(a,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===i.default(r).closest(".navbar-nav").length&&i.default(document.body).children().on("mouseover",null,i.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),i.default(this._menu).toggleClass("show"),i.default(r).toggleClass("show").trigger(i.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!i.default(this._element).hasClass("disabled")&&i.default(this._menu).hasClass("show")){var e={relatedTarget:this._element},n=i.default.Event("hide.bs.dropdown",e),o=t._getParentFromElement(this._element);i.default(o).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),i.default(this._menu).toggleClass("show"),i.default(o).toggleClass("show").trigger(i.default.Event("hidden.bs.dropdown",e)))}},e.dispose=function(){i.default.removeData(this._element,"bs.dropdown"),i.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;i.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=a({},this.constructor.Default,i.default(this._element).data(),t),l.typeCheckConfig(Ot,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},e._getPlacement=function(){var t=i.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=i.default(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":i.default(this._menu).hasClass("dropdown-menu-right")&&(e="bottom-end"),e},e._detectNavbar=function(){return i.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),a({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.dropdown");if(n||(n=new t(this,"object"==typeof e?e:null),i.default(this).data("bs.dropdown",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,r=n.length;o<r;o++){var a=t._getParentFromElement(n[o]),s=i.default(n[o]).data("bs.dropdown"),l={relatedTarget:n[o]};if(e&&"click"===e.type&&(l.clickEvent=e),s){var u=s._menu;if(i.default(a).hasClass("show")&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&i.default.contains(a,e.target))){var f=i.default.Event("hide.bs.dropdown",l);i.default(a).trigger(f),f.isDefaultPrevented()||("ontouchstart"in document.documentElement&&i.default(document.body).children().off("mouseover",null,i.default.noop),n[o].setAttribute("aria-expanded","false"),s._popper&&s._popper.destroy(),i.default(u).removeClass("show"),i.default(a).removeClass("show").trigger(i.default.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=l.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||i.default(e.target).closest(".dropdown-menu").length):!jt.test(e.which))&&!this.disabled&&!i.default(this).hasClass("disabled")){var n=t._getParentFromElement(this),o=i.default(n).hasClass("show");if(o||27!==e.which){if(e.preventDefault(),e.stopPropagation(),!o||27===e.which||32===e.which)return 27===e.which&&i.default(n.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void i.default(this).trigger("click");var r=[].slice.call(n.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return i.default(t).is(":visible")}));if(0!==r.length){var a=r.indexOf(e.target);38===e.which&&a>0&&a--,40===e.which&&a<r.length-1&&a++,a<0&&(a=0),r[a].focus()}}}},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return Lt}},{key:"DefaultType",get:function(){return Pt}}]),t}();i.default(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',Ft._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",Ft._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",Ft._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),Ft._jQueryInterface.call(i.default(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),i.default.fn[Ot]=Ft._jQueryInterface,i.default.fn[Ot].Constructor=Ft,i.default.fn[Ot].noConflict=function(){return i.default.fn[Ot]=xt,Ft._jQueryInterface};var Rt=i.default.fn.modal,Ht={backdrop:!0,keyboard:!0,focus:!0,show:!0},Mt={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},qt=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var e=t.prototype;return e.toggle=function(t){return this._isShown?this.hide():this.show(t)},e.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){i.default(this._element).hasClass("fade")&&(this._isTransitioning=!0);var n=i.default.Event("show.bs.modal",{relatedTarget:t});i.default(this._element).trigger(n),this._isShown||n.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),i.default(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return e.hide(t)})),i.default(this._dialog).on("mousedown.dismiss.bs.modal",(function(){i.default(e._element).one("mouseup.dismiss.bs.modal",(function(t){i.default(t.target).is(e._element)&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},e.hide=function(t){var e=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var n=i.default.Event("hide.bs.modal");if(i.default(this._element).trigger(n),this._isShown&&!n.isDefaultPrevented()){this._isShown=!1;var o=i.default(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),i.default(document).off("focusin.bs.modal"),i.default(this._element).removeClass("show"),i.default(this._element).off("click.dismiss.bs.modal"),i.default(this._dialog).off("mousedown.dismiss.bs.modal"),o){var r=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,(function(t){return e._hideModal(t)})).emulateTransitionEnd(r)}else this._hideModal()}}},e.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return i.default(t).off(".bs.modal")})),i.default(document).off("focusin.bs.modal"),i.default.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},e.handleUpdate=function(){this._adjustDialog()},e._getConfig=function(t){return t=a({},Ht,t),l.typeCheckConfig("modal",t,Mt),t},e._triggerBackdropTransition=function(){var t=this,e=i.default.Event("hidePrevented.bs.modal");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._element.scrollHeight>document.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=l.getTransitionDurationFromElement(this._dialog);i.default(this._element).off(l.TRANSITION_END),i.default(this._element).one(l.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),n||i.default(t._element).one(l.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}},e._showElement=function(t){var e=this,n=i.default(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),i.default(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,n&&l.reflow(this._element),i.default(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var r=i.default.Event("shown.bs.modal",{relatedTarget:t}),a=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,i.default(e._element).trigger(r)};if(n){var s=l.getTransitionDurationFromElement(this._dialog);i.default(this._dialog).one(l.TRANSITION_END,a).emulateTransitionEnd(s)}else a()},e._enforceFocus=function(){var t=this;i.default(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(e){document!==e.target&&t._element!==e.target&&0===i.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?i.default(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||i.default(this._element).off("keydown.dismiss.bs.modal")},e._setResizeEvent=function(){var t=this;this._isShown?i.default(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):i.default(window).off("resize.bs.modal")},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){i.default(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),i.default(t._element).trigger("hidden.bs.modal")}))},e._removeBackdrop=function(){this._backdrop&&(i.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=i.default(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),i.default(this._backdrop).appendTo(document.body),i.default(this._element).on("click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&l.reflow(this._backdrop),i.default(this._backdrop).addClass("show"),!t)return;if(!n)return void t();var o=l.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(l.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){i.default(this._backdrop).removeClass("show");var r=function(){e._removeBackdrop(),t&&t()};if(i.default(this._element).hasClass("fade")){var a=l.getTransitionDurationFromElement(this._backdrop);i.default(this._backdrop).one(l.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},e._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var e=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),n=[].slice.call(document.querySelectorAll(".sticky-top"));i.default(e).each((function(e,n){var o=n.style.paddingRight,r=i.default(n).css("padding-right");i.default(n).data("padding-right",o).css("padding-right",parseFloat(r)+t._scrollbarWidth+"px")})),i.default(n).each((function(e,n){var o=n.style.marginRight,r=i.default(n).css("margin-right");i.default(n).data("margin-right",o).css("margin-right",parseFloat(r)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,r=i.default(document.body).css("padding-right");i.default(document.body).data("padding-right",o).css("padding-right",parseFloat(r)+this._scrollbarWidth+"px")}i.default(document.body).addClass("modal-open")},e._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));i.default(t).each((function(t,e){var n=i.default(e).data("padding-right");i.default(e).removeData("padding-right"),e.style.paddingRight=n||""}));var e=[].slice.call(document.querySelectorAll(".sticky-top"));i.default(e).each((function(t,e){var n=i.default(e).data("margin-right");"undefined"!=typeof n&&i.default(e).css("margin-right",n).removeData("margin-right")}));var n=i.default(document.body).data("padding-right");i.default(document.body).removeData("padding-right"),document.body.style.paddingRight=n||""},e._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(e,n){return this.each((function(){var o=i.default(this).data("bs.modal"),r=a({},Ht,i.default(this).data(),"object"==typeof e&&e?e:{});if(o||(o=new t(this,r),i.default(this).data("bs.modal",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e](n)}else r.show&&o.show(n)}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return Ht}}]),t}();i.default(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e,n=this,o=l.getSelectorFromElement(this);o&&(e=document.querySelector(o));var r=i.default(e).data("bs.modal")?"toggle":a({},i.default(e).data(),i.default(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var s=i.default(e).one("show.bs.modal",(function(t){t.isDefaultPrevented()||s.one("hidden.bs.modal",(function(){i.default(n).is(":visible")&&n.focus()}))}));qt._jQueryInterface.call(i.default(e),r,this)})),i.default.fn.modal=qt._jQueryInterface,i.default.fn.modal.Constructor=qt,i.default.fn.modal.noConflict=function(){return i.default.fn.modal=Rt,qt._jQueryInterface};var Bt=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Qt={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Wt=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,Ut=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Vt(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),r=[].slice.call(i.body.querySelectorAll("*")),a=function(t,n){var i=r[t],a=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var s=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[a]||[]);s.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===Bt.indexOf(n)||Boolean(t.nodeValue.match(Wt)||t.nodeValue.match(Ut));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,r=i.length;o<r;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},s=0,l=r.length;s<l;s++)a(s);return i.body.innerHTML}var Yt="tooltip",zt=i.default.fn[Yt],Xt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Kt=["sanitize","whiteList","sanitizeFn"],Gt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},$t={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Jt={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:Qt,popperConfig:null},Zt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},te=function(){function t(t,e){if("undefined"==typeof It)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=i.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(i.default(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),i.default.removeData(this.element,this.constructor.DATA_KEY),i.default(this.element).off(this.constructor.EVENT_KEY),i.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&i.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===i.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=i.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){i.default(this.element).trigger(e);var n=l.findShadowRoot(this.element),o=i.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!o)return;var r=this.getTipElement(),a=l.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&i.default(r).addClass("fade");var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,u=this._getAttachment(s);this.addAttachmentClass(u);var f=this._getContainer();i.default(r).data(this.constructor.DATA_KEY,this),i.default.contains(this.element.ownerDocument.documentElement,this.tip)||i.default(r).appendTo(f),i.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new It(this.element,r,this._getPopperConfig(u)),i.default(r).addClass("show"),i.default(r).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&i.default(document.body).children().on("mouseover",null,i.default.noop);var d=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,i.default(t.element).trigger(t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(i.default(this.tip).hasClass("fade")){var c=l.getTransitionDurationFromElement(this.tip);i.default(this.tip).one(l.TRANSITION_END,d).emulateTransitionEnd(c)}else d()}},e.hide=function(t){var e=this,n=this.getTipElement(),o=i.default.Event(this.constructor.Event.HIDE),r=function(){"show"!==e._hoverState&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),i.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(i.default(this.element).trigger(o),!o.isDefaultPrevented()){if(i.default(n).removeClass("show"),"ontouchstart"in document.documentElement&&i.default(document.body).children().off("mouseover",null,i.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,i.default(this.tip).hasClass("fade")){var a=l.getTransitionDurationFromElement(n);i.default(n).one(l.TRANSITION_END,r).emulateTransitionEnd(a)}else r();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(i.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),i.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Vt(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?i.default(e).parent().is(t)||t.empty().append(e):t.text(i.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return a({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=a({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:l.isElement(this.config.container)?i.default(this.config.container):i.default(document).find(this.config.container)},e._getAttachment=function(t){return $t[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)i.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;i.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},i.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=a({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),i.default(e.getTipElement()).hasClass("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||i.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),i.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=i.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Kt.indexOf(t)&&delete e[t]})),"number"==typeof(t=a({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),l.typeCheckConfig(Yt,t,this.constructor.DefaultType),t.sanitize&&(t.template=Vt(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(Xt);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(i.default(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.tooltip"),r="object"==typeof e&&e;if((o||!/dispose|hide/.test(e))&&(o||(o=new t(this,r),n.data("bs.tooltip",o)),"string"==typeof e)){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return Jt}},{key:"NAME",get:function(){return Yt}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Zt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Gt}}]),t}();i.default.fn[Yt]=te._jQueryInterface,i.default.fn[Yt].Constructor=te,i.default.fn[Yt].noConflict=function(){return i.default.fn[Yt]=zt,te._jQueryInterface};var ee="popover",ne=i.default.fn[ee],ie=new RegExp("(^|\\s)bs-popover\\S+","g"),oe=a({},te.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),re=a({},te.DefaultType,{content:"(string|element|function)"}),ae={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},se=function(t){var e,n;function o(){return t.apply(this,arguments)||this}n=t,(e=o).prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n;var a=o.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){i.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||i.default(this.config.template)[0],this.tip},a.setContent=function(){var t=i.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=i.default(this.getTipElement()),e=t.attr("class").match(ie);null!==e&&e.length>0&&t.removeClass(e.join(""))},o._jQueryInterface=function(t){return this.each((function(){var e=i.default(this).data("bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n),i.default(this).data("bs.popover",e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},r(o,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return oe}},{key:"NAME",get:function(){return ee}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return ae}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return re}}]),o}(te);i.default.fn[ee]=se._jQueryInterface,i.default.fn[ee].Constructor=se,i.default.fn[ee].noConflict=function(){return i.default.fn[ee]=ne,se._jQueryInterface};var le="scrollspy",ue=i.default.fn[le],fe={offset:10,method:"auto",target:""},de={offset:"number",method:"string",target:"(string|element)"},ce=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,i.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,o="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,r=l.getSelectorFromElement(t);if(r&&(e=document.querySelector(r)),e){var a=e.getBoundingClientRect();if(a.width||a.height)return[i.default(e)[n]().top+o,r]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){i.default.removeData(this._element,"bs.scrollspy"),i.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=a({},fe,"object"==typeof t&&t?t:{})).target&&l.isElement(t.target)){var e=i.default(t.target).attr("id");e||(e=l.getUID(le),i.default(t.target).attr("id",e)),t.target="#"+e}return l.typeCheckConfig(le,t,de),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},e._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=i.default([].slice.call(document.querySelectorAll(e.join(","))));n.hasClass("dropdown-item")?(n.closest(".dropdown").find(".dropdown-toggle").addClass("active"),n.addClass("active")):(n.addClass("active"),n.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),n.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),i.default(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},e._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this).data("bs.scrollspy");if(n||(n=new t(this,"object"==typeof e&&e),i.default(this).data("bs.scrollspy",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return fe}}]),t}();i.default(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),e=t.length;e--;){var n=i.default(t[e]);ce._jQueryInterface.call(n,n.data())}})),i.default.fn[le]=ce._jQueryInterface,i.default.fn[le].Constructor=ce,i.default.fn[le].noConflict=function(){return i.default.fn[le]=ue,ce._jQueryInterface};var he=i.default.fn.tab,pe=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&i.default(this._element).hasClass("active")||i.default(this._element).hasClass("disabled"))){var e,n,o=i.default(this._element).closest(".nav, .list-group")[0],r=l.getSelectorFromElement(this._element);if(o){var a="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";n=(n=i.default.makeArray(i.default(o).find(a)))[n.length-1]}var s=i.default.Event("hide.bs.tab",{relatedTarget:this._element}),u=i.default.Event("show.bs.tab",{relatedTarget:n});if(n&&i.default(n).trigger(s),i.default(this._element).trigger(u),!u.isDefaultPrevented()&&!s.isDefaultPrevented()){r&&(e=document.querySelector(r)),this._activate(this._element,o);var f=function(){var e=i.default.Event("hidden.bs.tab",{relatedTarget:t._element}),o=i.default.Event("shown.bs.tab",{relatedTarget:n});i.default(n).trigger(e),i.default(t._element).trigger(o)};e?this._activate(e,e.parentNode,f):f()}}},e.dispose=function(){i.default.removeData(this._element,"bs.tab"),this._element=null},e._activate=function(t,e,n){var o=this,r=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?i.default(e).children(".active"):i.default(e).find("> li > .active"))[0],a=n&&r&&i.default(r).hasClass("fade"),s=function(){return o._transitionComplete(t,r,n)};if(r&&a){var u=l.getTransitionDurationFromElement(r);i.default(r).removeClass("show").one(l.TRANSITION_END,s).emulateTransitionEnd(u)}else s()},e._transitionComplete=function(t,e,n){if(e){i.default(e).removeClass("active");var o=i.default(e.parentNode).find("> .dropdown-menu .active")[0];o&&i.default(o).removeClass("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}if(i.default(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),l.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&i.default(t.parentNode).hasClass("dropdown-menu")){var r=i.default(t).closest(".dropdown")[0];if(r){var a=[].slice.call(r.querySelectorAll(".dropdown-toggle"));i.default(a).addClass("active")}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.tab");if(o||(o=new t(this),n.data("bs.tab",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();i.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),pe._jQueryInterface.call(i.default(this),"show")})),i.default.fn.tab=pe._jQueryInterface,i.default.fn.tab.Constructor=pe,i.default.fn.tab.noConflict=function(){return i.default.fn.tab=he,pe._jQueryInterface};var me=i.default.fn.toast,ge={animation:"boolean",autohide:"boolean",delay:"number"},ve={animation:!0,autohide:!0,delay:500},_e=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=i.default.Event("show.bs.toast");if(i.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),i.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),l.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,n).emulateTransitionEnd(o)}else n()}},e.hide=function(){if(this._element.classList.contains("show")){var t=i.default.Event("hide.bs.toast");i.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),i.default(this._element).off("click.dismiss.bs.toast"),i.default.removeData(this._element,"bs.toast"),this._element=null,this._config=null},e._getConfig=function(t){return t=a({},ve,i.default(this._element).data(),"object"==typeof t&&t?t:{}),l.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;i.default(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add("hide"),i.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=l.getTransitionDurationFromElement(this._element);i.default(this._element).one(l.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=i.default(this),o=n.data("bs.toast");if(o||(o=new t(this,"object"==typeof e&&e),n.data("bs.toast",o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e](this)}}))},r(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"DefaultType",get:function(){return ge}},{key:"Default",get:function(){return ve}}]),t}();i.default.fn.toast=_e._jQueryInterface,i.default.fn.toast.Constructor=_e,i.default.fn.toast.noConflict=function(){return i.default.fn.toast=me,_e._jQueryInterface},t.Alert=d,t.Button=h,t.Carousel=y,t.Collapse=S,t.Dropdown=Ft,t.Modal=qt,t.Popover=se,t.Scrollspy=ce,t.Tab=pe,t.Toast=_e,t.Tooltip=te,t.Util=l,Object.defineProperty(t,"__esModule",{value:!0})})); //# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js.map b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js.map index 4146d43c2..7fcd06e5c 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js.map +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/popper.js/dist/esm/popper.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"names":["transitionEndEmulator","duration","_this","this","called","$","one","Util","TRANSITION_END","setTimeout","triggerTransitionEnd","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","obj","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","call","expectedTypes","value","valueType","toString","match","toLowerCase","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","fn","jquery","emulateTransitionEnd","event","special","bindType","delegateType","handle","target","is","handleObj","handler","apply","arguments","NAME","JQUERY_NO_CONFLICT","Alert","_element","close","rootElement","_getRootElement","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","EVENT_KEY","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_extends","_handleSwipe","absDeltax","abs","_this2","_keydown","_addTouchEventListeners","_this3","start","originalEvent","pointerType","clientX","touches","end","clearTimeout","e","move","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","directionalClassName","orderClassName","_this4","activeElementIndex","nextElement","nextElementIndex","isCycling","slidEvent","nextElementInterval","parseInt","defaultInterval","CLASS_NAME_ACTIVE","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","scrollSize","CLASS_NAME_COLLAPSE","getBoundingClientRect","triggerArrayLength","isTransitioning","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","isBrowser","timeoutDuration","longerTimeoutBrowsers","userAgent","debounce","Promise","resolve","then","scheduled","isFunction","functionToCheck","getStyleComputedProperty","ownerDocument","defaultView","getComputedStyle","getParentNode","nodeName","host","getScrollParent","body","_getStyleComputedProp","overflow","overflowX","overflowY","getReferenceNode","reference","referenceNode","isIE11","MSInputMethodContext","documentMode","isIE10","isIE","getOffsetParent","noOffsetParent","offsetParent","nextElementSibling","getRoot","node","findCommonOffsetParent","element1","element2","order","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","range","createRange","setStart","setEnd","commonAncestorContainer","firstElementChild","element1root","getScroll","side","undefined","upperSide","html","scrollingElement","includeScroll","rect","subtract","scrollTop","scrollLeft","modifier","top","bottom","left","right","getBordersSize","styles","axis","sideA","sideB","getSize","computedStyle","max","getWindowSizes","height","width","classCallCheck","instance","createClass","defineProperties","props","descriptor","enumerable","configurable","writable","defineProperty","key","protoProps","staticProps","assign","source","getClientRect","offsets","result","sizes","clientWidth","clientHeight","horizScrollbar","offsetWidth","vertScrollbar","getOffsetRectRelativeToArbitraryNode","fixedPosition","isHTML","childrenRect","parentRect","scrollParent","borderTopWidth","borderLeftWidth","marginTop","marginLeft","getViewportOffsetRectRelativeToArtbitraryNode","excludeScroll","relativeOffset","innerWidth","innerHeight","offset","isFixed","getFixedPositionOffsetParent","parentElement","el","getBoundaries","popper","padding","boundariesElement","boundaries","boundariesNode","_getWindowSizes","isPaddingNumber","getArea","_ref","computeAutoPlacement","placement","refRect","rects","sortedAreas","keys","map","area","sort","a","b","filteredAreas","_ref2","computedPlacement","variation","getReferenceOffsets","state","commonOffsetParent","getOuterSizes","x","marginBottom","y","marginRight","getOppositePlacement","hash","replace","matched","getPopperOffsets","referenceOffsets","popperRect","popperOffsets","isHoriz","mainSide","secondarySide","measurement","secondaryMeasurement","find","arr","check","Array","runModifiers","modifiers","ends","prop","findIndex","cur","forEach","console","warn","enabled","update","isDestroyed","arrowStyles","attributes","flipped","options","positionFixed","flip","originalPlacement","position","isCreated","onUpdate","onCreate","isModifierEnabled","modifierName","some","name","getSupportedPropertyName","prefixes","upperProp","charAt","toCheck","destroy","removeAttribute","willChange","disableEventListeners","removeOnDestroy","removeChild","getWindow","setupEventListeners","updateBound","addEventListener","passive","scrollElement","attachToScrollParents","callback","scrollParents","isBody","eventsEnabled","enableEventListeners","scheduleUpdate","cancelAnimationFrame","removeEventListener","isNumeric","n","isNaN","isFinite","setStyles","unit","isFirefox","isModifierRequired","requestingName","requestedName","requesting","isRequired","_requesting","requested","placements","validPlacements","clockwise","counter","concat","reverse","BEHAVIORS","parseOffset","basePlacement","useHeight","fragments","frag","divider","search","splitRegex","ops","op","mergeWithPrevious","reduce","str","toValue","index2","Defaults","shift","shiftvariation","_data$offsets","isVertical","shiftOffsets","preventOverflow","transformProp","popperStyles","transform","priority","primary","escapeWithReference","secondary","min","keepTogether","floor","opSide","arrow","_data$offsets$arrow","arrowElement","sideCapitalized","altSide","arrowElementSize","center","popperMarginSide","popperBorderSide","sideValue","round","placementOpposite","flipOrder","behavior","step","refOffsets","overlapsRef","overflowsLeft","overflowsRight","overflowsTop","overflowsBottom","overflowsBoundaries","flippedVariationByRef","flipVariations","flippedVariationByContent","flipVariationsByContent","flippedVariation","getOppositeVariation","inner","subtractLength","bound","computeStyle","legacyGpuAccelerationOption","gpuAcceleration","offsetParentRect","shouldRound","noRound","v","referenceWidth","popperWidth","isVariation","horizontalToInteger","verticalToInteger","getRoundedOffsets","devicePixelRatio","prefixedProperty","invertTop","invertLeft","x-placement","applyStyle","onLoad","modifierOptions","Popper","requestAnimationFrame","Utils","global","PopperUtils","REGEXP_KEYDOWN","ARROW_UP_KEYCODE","boundary","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","referenceElement","_getPopperConfig","noop","hideEvent","stopPropagation","constructor","_getPlacement","$parentDropdown","_getOffset","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","EVENT_CLICK_DATA_API","backdrop","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","modalTransitionDuration","modalBody","ELEMENT_NODE","appendChild","_enforceFocus","shownEvent","transitionComplete","_this5","has","_this6","_this7","_this8","_resetAdjustments","_resetScrollbar","_removeBackdrop","_this9","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","_getScrollbarWidth","_this10","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","calculatedMargin","elements","margin","scrollDiv","scrollbarWidth","_this11","uriAttrs","DefaultWhitelist","*","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","createdDocument","DOMParser","parseFromString","whitelistKeys","_loop","elName","attributeList","whitelistedAttributes","allowedAttributeList","attrName","nodeValue","regExp","attrRegex","allowedAttribute","innerHTML","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","container","fallbackPlacement","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","DATA_KEY","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","complete","_fixTransition","prevHoverState","_cleanTipClass","getTitle","CLASS_PREFIX","setElementContent","CLASS_NAME_FADE","content","text","empty","append","_handlePopperPlacementChange","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","$tip","tabClass","join","popperData","initConfigAnimation","Popover","_getContent","method","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targetSelector","targetBCR","pageYOffset","_getOffsetHeight","maxScroll","_activate","_clear","queries","$link","parents","SELECTOR_NAV_LINKS","scrollSpys","$spy","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","autohide","Toast","_clearTimeout","_close"],"mappings":"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","sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = nextElementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**!\n * @fileOverview Kickass library to create and place poppers near their reference elements.\n * @version 1.16.1\n * @license\n * Copyright (c) 2016 Federico Zivolo and contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';\n\nvar timeoutDuration = function () {\n var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];\n for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {\n if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {\n return 1;\n }\n }\n return 0;\n}();\n\nfunction microtaskDebounce(fn) {\n var called = false;\n return function () {\n if (called) {\n return;\n }\n called = true;\n window.Promise.resolve().then(function () {\n called = false;\n fn();\n });\n };\n}\n\nfunction taskDebounce(fn) {\n var scheduled = false;\n return function () {\n if (!scheduled) {\n scheduled = true;\n setTimeout(function () {\n scheduled = false;\n fn();\n }, timeoutDuration);\n }\n };\n}\n\nvar supportsMicroTasks = isBrowser && window.Promise;\n\n/**\n* Create a debounced version of a method, that's asynchronously deferred\n* but called in the minimum time possible.\n*\n* @method\n* @memberof Popper.Utils\n* @argument {Function} fn\n* @returns {Function}\n*/\nvar debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;\n\n/**\n * Check if the given variable is a function\n * @method\n * @memberof Popper.Utils\n * @argument {Any} functionToCheck - variable to check\n * @returns {Boolean} answer to: is a function?\n */\nfunction isFunction(functionToCheck) {\n var getType = {};\n return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';\n}\n\n/**\n * Get CSS computed property of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Eement} element\n * @argument {String} property\n */\nfunction getStyleComputedProperty(element, property) {\n if (element.nodeType !== 1) {\n return [];\n }\n // NOTE: 1 DOM access here\n var window = element.ownerDocument.defaultView;\n var css = window.getComputedStyle(element, null);\n return property ? css[property] : css;\n}\n\n/**\n * Returns the parentNode or the host of the element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} parent\n */\nfunction getParentNode(element) {\n if (element.nodeName === 'HTML') {\n return element;\n }\n return element.parentNode || element.host;\n}\n\n/**\n * Returns the scrolling parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} scroll parent\n */\nfunction getScrollParent(element) {\n // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n if (!element) {\n return document.body;\n }\n\n switch (element.nodeName) {\n case 'HTML':\n case 'BODY':\n return element.ownerDocument.body;\n case '#document':\n return element.body;\n }\n\n // Firefox want us to check `-x` and `-y` variations as well\n\n var _getStyleComputedProp = getStyleComputedProperty(element),\n overflow = _getStyleComputedProp.overflow,\n overflowX = _getStyleComputedProp.overflowX,\n overflowY = _getStyleComputedProp.overflowY;\n\n if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {\n return element;\n }\n\n return getScrollParent(getParentNode(element));\n}\n\n/**\n * Returns the reference node of the reference object, or the reference object itself.\n * @method\n * @memberof Popper.Utils\n * @param {Element|Object} reference - the reference element (the popper will be relative to this)\n * @returns {Element} parent\n */\nfunction getReferenceNode(reference) {\n return reference && reference.referenceNode ? reference.referenceNode : reference;\n}\n\nvar isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);\nvar isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);\n\n/**\n * Determines if the browser is Internet Explorer\n * @method\n * @memberof Popper.Utils\n * @param {Number} version to check\n * @returns {Boolean} isIE\n */\nfunction isIE(version) {\n if (version === 11) {\n return isIE11;\n }\n if (version === 10) {\n return isIE10;\n }\n return isIE11 || isIE10;\n}\n\n/**\n * Returns the offset parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} offset parent\n */\nfunction getOffsetParent(element) {\n if (!element) {\n return document.documentElement;\n }\n\n var noOffsetParent = isIE(10) ? document.body : null;\n\n // NOTE: 1 DOM access here\n var offsetParent = element.offsetParent || null;\n // Skip hidden elements which don't have an offsetParent\n while (offsetParent === noOffsetParent && element.nextElementSibling) {\n offsetParent = (element = element.nextElementSibling).offsetParent;\n }\n\n var nodeName = offsetParent && offsetParent.nodeName;\n\n if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {\n return element ? element.ownerDocument.documentElement : document.documentElement;\n }\n\n // .offsetParent will return the closest TH, TD or TABLE in case\n // no offsetParent is present, I hate this job...\n if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {\n return getOffsetParent(offsetParent);\n }\n\n return offsetParent;\n}\n\nfunction isOffsetContainer(element) {\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY') {\n return false;\n }\n return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;\n}\n\n/**\n * Finds the root node (document, shadowDOM root) of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} node\n * @returns {Element} root node\n */\nfunction getRoot(node) {\n if (node.parentNode !== null) {\n return getRoot(node.parentNode);\n }\n\n return node;\n}\n\n/**\n * Finds the offset parent common to the two provided nodes\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element1\n * @argument {Element} element2\n * @returns {Element} common offset parent\n */\nfunction findCommonOffsetParent(element1, element2) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {\n return document.documentElement;\n }\n\n // Here we make sure to give as \"start\" the element that comes first in the DOM\n var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;\n var start = order ? element1 : element2;\n var end = order ? element2 : element1;\n\n // Get common ancestor container\n var range = document.createRange();\n range.setStart(start, 0);\n range.setEnd(end, 0);\n var commonAncestorContainer = range.commonAncestorContainer;\n\n // Both nodes are inside #document\n\n if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {\n if (isOffsetContainer(commonAncestorContainer)) {\n return commonAncestorContainer;\n }\n\n return getOffsetParent(commonAncestorContainer);\n }\n\n // one of the nodes is inside shadowDOM, find which one\n var element1root = getRoot(element1);\n if (element1root.host) {\n return findCommonOffsetParent(element1root.host, element2);\n } else {\n return findCommonOffsetParent(element1, getRoot(element2).host);\n }\n}\n\n/**\n * Gets the scroll value of the given element in the given side (top and left)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {String} side `top` or `left`\n * @returns {number} amount of scrolled pixels\n */\nfunction getScroll(element) {\n var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';\n\n var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n var html = element.ownerDocument.documentElement;\n var scrollingElement = element.ownerDocument.scrollingElement || html;\n return scrollingElement[upperSide];\n }\n\n return element[upperSide];\n}\n\n/*\n * Sum or subtract the element scroll values (left and top) from a given rect object\n * @method\n * @memberof Popper.Utils\n * @param {Object} rect - Rect object you want to change\n * @param {HTMLElement} element - The element from the function reads the scroll values\n * @param {Boolean} subtract - set to true if you want to subtract the scroll values\n * @return {Object} rect - The modifier rect object\n */\nfunction includeScroll(rect, element) {\n var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n var modifier = subtract ? -1 : 1;\n rect.top += scrollTop * modifier;\n rect.bottom += scrollTop * modifier;\n rect.left += scrollLeft * modifier;\n rect.right += scrollLeft * modifier;\n return rect;\n}\n\n/*\n * Helper to detect borders of a given element\n * @method\n * @memberof Popper.Utils\n * @param {CSSStyleDeclaration} styles\n * Result of `getStyleComputedProperty` on the given element\n * @param {String} axis - `x` or `y`\n * @return {number} borders - The borders size of the given axis\n */\n\nfunction getBordersSize(styles, axis) {\n var sideA = axis === 'x' ? 'Left' : 'Top';\n var sideB = sideA === 'Left' ? 'Right' : 'Bottom';\n\n return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);\n}\n\nfunction getSize(axis, body, html, computedStyle) {\n return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);\n}\n\nfunction getWindowSizes(document) {\n var body = document.body;\n var html = document.documentElement;\n var computedStyle = isIE(10) && getComputedStyle(html);\n\n return {\n height: getSize('Height', body, html, computedStyle),\n width: getSize('Width', body, html, computedStyle)\n };\n}\n\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\n\n\n\n\nvar defineProperty = function (obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\n/**\n * Given element offsets, generate an output similar to getBoundingClientRect\n * @method\n * @memberof Popper.Utils\n * @argument {Object} offsets\n * @returns {Object} ClientRect like output\n */\nfunction getClientRect(offsets) {\n return _extends({}, offsets, {\n right: offsets.left + offsets.width,\n bottom: offsets.top + offsets.height\n });\n}\n\n/**\n * Get bounding client rect of given element\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} element\n * @return {Object} client rect\n */\nfunction getBoundingClientRect(element) {\n var rect = {};\n\n // IE10 10 FIX: Please, don't ask, the element isn't\n // considered in DOM in some circumstances...\n // This isn't reproducible in IE10 compatibility mode of IE11\n try {\n if (isIE(10)) {\n rect = element.getBoundingClientRect();\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n rect.top += scrollTop;\n rect.left += scrollLeft;\n rect.bottom += scrollTop;\n rect.right += scrollLeft;\n } else {\n rect = element.getBoundingClientRect();\n }\n } catch (e) {}\n\n var result = {\n left: rect.left,\n top: rect.top,\n width: rect.right - rect.left,\n height: rect.bottom - rect.top\n };\n\n // subtract scrollbar size from sizes\n var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};\n var width = sizes.width || element.clientWidth || result.width;\n var height = sizes.height || element.clientHeight || result.height;\n\n var horizScrollbar = element.offsetWidth - width;\n var vertScrollbar = element.offsetHeight - height;\n\n // if an hypothetical scrollbar is detected, we must be sure it's not a `border`\n // we make this check conditional for performance reasons\n if (horizScrollbar || vertScrollbar) {\n var styles = getStyleComputedProperty(element);\n horizScrollbar -= getBordersSize(styles, 'x');\n vertScrollbar -= getBordersSize(styles, 'y');\n\n result.width -= horizScrollbar;\n result.height -= vertScrollbar;\n }\n\n return getClientRect(result);\n}\n\nfunction getOffsetRectRelativeToArbitraryNode(children, parent) {\n var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var isIE10 = isIE(10);\n var isHTML = parent.nodeName === 'HTML';\n var childrenRect = getBoundingClientRect(children);\n var parentRect = getBoundingClientRect(parent);\n var scrollParent = getScrollParent(children);\n\n var styles = getStyleComputedProperty(parent);\n var borderTopWidth = parseFloat(styles.borderTopWidth);\n var borderLeftWidth = parseFloat(styles.borderLeftWidth);\n\n // In cases where the parent is fixed, we must ignore negative scroll in offset calc\n if (fixedPosition && isHTML) {\n parentRect.top = Math.max(parentRect.top, 0);\n parentRect.left = Math.max(parentRect.left, 0);\n }\n var offsets = getClientRect({\n top: childrenRect.top - parentRect.top - borderTopWidth,\n left: childrenRect.left - parentRect.left - borderLeftWidth,\n width: childrenRect.width,\n height: childrenRect.height\n });\n offsets.marginTop = 0;\n offsets.marginLeft = 0;\n\n // Subtract margins of documentElement in case it's being used as parent\n // we do this only on HTML because it's the only element that behaves\n // differently when margins are applied to it. The margins are included in\n // the box of the documentElement, in the other cases not.\n if (!isIE10 && isHTML) {\n var marginTop = parseFloat(styles.marginTop);\n var marginLeft = parseFloat(styles.marginLeft);\n\n offsets.top -= borderTopWidth - marginTop;\n offsets.bottom -= borderTopWidth - marginTop;\n offsets.left -= borderLeftWidth - marginLeft;\n offsets.right -= borderLeftWidth - marginLeft;\n\n // Attach marginTop and marginLeft because in some circumstances we may need them\n offsets.marginTop = marginTop;\n offsets.marginLeft = marginLeft;\n }\n\n if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {\n offsets = includeScroll(offsets, parent);\n }\n\n return offsets;\n}\n\nfunction getViewportOffsetRectRelativeToArtbitraryNode(element) {\n var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var html = element.ownerDocument.documentElement;\n var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);\n var width = Math.max(html.clientWidth, window.innerWidth || 0);\n var height = Math.max(html.clientHeight, window.innerHeight || 0);\n\n var scrollTop = !excludeScroll ? getScroll(html) : 0;\n var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;\n\n var offset = {\n top: scrollTop - relativeOffset.top + relativeOffset.marginTop,\n left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,\n width: width,\n height: height\n };\n\n return getClientRect(offset);\n}\n\n/**\n * Check if the given element is fixed or is inside a fixed parent\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {Element} customContainer\n * @returns {Boolean} answer to \"isFixed?\"\n */\nfunction isFixed(element) {\n var nodeName = element.nodeName;\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n return false;\n }\n if (getStyleComputedProperty(element, 'position') === 'fixed') {\n return true;\n }\n var parentNode = getParentNode(element);\n if (!parentNode) {\n return false;\n }\n return isFixed(parentNode);\n}\n\n/**\n * Finds the first parent of an element that has a transformed property defined\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} first transformed parent or documentElement\n */\n\nfunction getFixedPositionOffsetParent(element) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element || !element.parentElement || isIE()) {\n return document.documentElement;\n }\n var el = element.parentElement;\n while (el && getStyleComputedProperty(el, 'transform') === 'none') {\n el = el.parentElement;\n }\n return el || document.documentElement;\n}\n\n/**\n * Computed the boundaries limits and return them\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} popper\n * @param {HTMLElement} reference\n * @param {number} padding\n * @param {HTMLElement} boundariesElement - Element used to define the boundaries\n * @param {Boolean} fixedPosition - Is in fixed position mode\n * @returns {Object} Coordinates of the boundaries\n */\nfunction getBoundaries(popper, reference, padding, boundariesElement) {\n var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n\n // NOTE: 1 DOM access here\n\n var boundaries = { top: 0, left: 0 };\n var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n\n // Handle viewport case\n if (boundariesElement === 'viewport') {\n boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);\n } else {\n // Handle other cases based on DOM element used as boundaries\n var boundariesNode = void 0;\n if (boundariesElement === 'scrollParent') {\n boundariesNode = getScrollParent(getParentNode(reference));\n if (boundariesNode.nodeName === 'BODY') {\n boundariesNode = popper.ownerDocument.documentElement;\n }\n } else if (boundariesElement === 'window') {\n boundariesNode = popper.ownerDocument.documentElement;\n } else {\n boundariesNode = boundariesElement;\n }\n\n var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);\n\n // In case of HTML, we need a different computation\n if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {\n var _getWindowSizes = getWindowSizes(popper.ownerDocument),\n height = _getWindowSizes.height,\n width = _getWindowSizes.width;\n\n boundaries.top += offsets.top - offsets.marginTop;\n boundaries.bottom = height + offsets.top;\n boundaries.left += offsets.left - offsets.marginLeft;\n boundaries.right = width + offsets.left;\n } else {\n // for all the other DOM elements, this one is good\n boundaries = offsets;\n }\n }\n\n // Add paddings\n padding = padding || 0;\n var isPaddingNumber = typeof padding === 'number';\n boundaries.left += isPaddingNumber ? padding : padding.left || 0;\n boundaries.top += isPaddingNumber ? padding : padding.top || 0;\n boundaries.right -= isPaddingNumber ? padding : padding.right || 0;\n boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;\n\n return boundaries;\n}\n\nfunction getArea(_ref) {\n var width = _ref.width,\n height = _ref.height;\n\n return width * height;\n}\n\n/**\n * Utility used to transform the `auto` placement to the placement with more\n * available space.\n * @method\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {\n var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n if (placement.indexOf('auto') === -1) {\n return placement;\n }\n\n var boundaries = getBoundaries(popper, reference, padding, boundariesElement);\n\n var rects = {\n top: {\n width: boundaries.width,\n height: refRect.top - boundaries.top\n },\n right: {\n width: boundaries.right - refRect.right,\n height: boundaries.height\n },\n bottom: {\n width: boundaries.width,\n height: boundaries.bottom - refRect.bottom\n },\n left: {\n width: refRect.left - boundaries.left,\n height: boundaries.height\n }\n };\n\n var sortedAreas = Object.keys(rects).map(function (key) {\n return _extends({\n key: key\n }, rects[key], {\n area: getArea(rects[key])\n });\n }).sort(function (a, b) {\n return b.area - a.area;\n });\n\n var filteredAreas = sortedAreas.filter(function (_ref2) {\n var width = _ref2.width,\n height = _ref2.height;\n return width >= popper.clientWidth && height >= popper.clientHeight;\n });\n\n var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;\n\n var variation = placement.split('-')[1];\n\n return computedPlacement + (variation ? '-' + variation : '');\n}\n\n/**\n * Get offsets to the reference element\n * @method\n * @memberof Popper.Utils\n * @param {Object} state\n * @param {Element} popper - the popper element\n * @param {Element} reference - the reference element (the popper will be relative to this)\n * @param {Element} fixedPosition - is in fixed position mode\n * @returns {Object} An object containing the offsets which will be applied to the popper\n */\nfunction getReferenceOffsets(state, popper, reference) {\n var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n\n var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);\n}\n\n/**\n * Get the outer sizes of the given element (offset size + margins)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Object} object containing width and height properties\n */\nfunction getOuterSizes(element) {\n var window = element.ownerDocument.defaultView;\n var styles = window.getComputedStyle(element);\n var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);\n var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);\n var result = {\n width: element.offsetWidth + y,\n height: element.offsetHeight + x\n };\n return result;\n}\n\n/**\n * Get the opposite placement of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement\n * @returns {String} flipped placement\n */\nfunction getOppositePlacement(placement) {\n var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}\n\n/**\n * Get offsets to the popper\n * @method\n * @memberof Popper.Utils\n * @param {Object} position - CSS position the Popper will get applied\n * @param {HTMLElement} popper - the popper element\n * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)\n * @param {String} placement - one of the valid placement options\n * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper\n */\nfunction getPopperOffsets(popper, referenceOffsets, placement) {\n placement = placement.split('-')[0];\n\n // Get popper node sizes\n var popperRect = getOuterSizes(popper);\n\n // Add position, width and height to our offsets object\n var popperOffsets = {\n width: popperRect.width,\n height: popperRect.height\n };\n\n // depending by the popper placement we have to compute its offsets slightly differently\n var isHoriz = ['right', 'left'].indexOf(placement) !== -1;\n var mainSide = isHoriz ? 'top' : 'left';\n var secondarySide = isHoriz ? 'left' : 'top';\n var measurement = isHoriz ? 'height' : 'width';\n var secondaryMeasurement = !isHoriz ? 'height' : 'width';\n\n popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;\n if (placement === secondarySide) {\n popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];\n } else {\n popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];\n }\n\n return popperOffsets;\n}\n\n/**\n * Mimics the `find` method of Array\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction find(arr, check) {\n // use native find if supported\n if (Array.prototype.find) {\n return arr.find(check);\n }\n\n // use `filter` to obtain the same behavior of `find`\n return arr.filter(check)[0];\n}\n\n/**\n * Return the index of the matching object\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction findIndex(arr, prop, value) {\n // use native findIndex if supported\n if (Array.prototype.findIndex) {\n return arr.findIndex(function (cur) {\n return cur[prop] === value;\n });\n }\n\n // use `find` + `indexOf` if `findIndex` isn't supported\n var match = find(arr, function (obj) {\n return obj[prop] === value;\n });\n return arr.indexOf(match);\n}\n\n/**\n * Loop trough the list of modifiers and run them in order,\n * each of them will then edit the data object.\n * @method\n * @memberof Popper.Utils\n * @param {dataObject} data\n * @param {Array} modifiers\n * @param {String} ends - Optional modifier name used as stopper\n * @returns {dataObject}\n */\nfunction runModifiers(modifiers, data, ends) {\n var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));\n\n modifiersToRun.forEach(function (modifier) {\n if (modifier['function']) {\n // eslint-disable-line dot-notation\n console.warn('`modifier.function` is deprecated, use `modifier.fn`!');\n }\n var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation\n if (modifier.enabled && isFunction(fn)) {\n // Add properties to offsets to make them a complete clientRect object\n // we do this before each modifier to make sure the previous one doesn't\n // mess with these values\n data.offsets.popper = getClientRect(data.offsets.popper);\n data.offsets.reference = getClientRect(data.offsets.reference);\n\n data = fn(data, modifier);\n }\n });\n\n return data;\n}\n\n/**\n * Updates the position of the popper, computing the new offsets and applying\n * the new style.<br />\n * Prefer `scheduleUpdate` over `update` because of performance reasons.\n * @method\n * @memberof Popper\n */\nfunction update() {\n // if popper is destroyed, don't perform any further update\n if (this.state.isDestroyed) {\n return;\n }\n\n var data = {\n instance: this,\n styles: {},\n arrowStyles: {},\n attributes: {},\n flipped: false,\n offsets: {}\n };\n\n // compute reference element offsets\n data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);\n\n // store the computed placement inside `originalPlacement`\n data.originalPlacement = data.placement;\n\n data.positionFixed = this.options.positionFixed;\n\n // compute the popper offsets\n data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);\n\n data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';\n\n // run the modifiers\n data = runModifiers(this.modifiers, data);\n\n // the first `update` will call `onCreate` callback\n // the other ones will call `onUpdate` callback\n if (!this.state.isCreated) {\n this.state.isCreated = true;\n this.options.onCreate(data);\n } else {\n this.options.onUpdate(data);\n }\n}\n\n/**\n * Helper used to know if the given modifier is enabled.\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean}\n */\nfunction isModifierEnabled(modifiers, modifierName) {\n return modifiers.some(function (_ref) {\n var name = _ref.name,\n enabled = _ref.enabled;\n return enabled && name === modifierName;\n });\n}\n\n/**\n * Get the prefixed supported property name\n * @method\n * @memberof Popper.Utils\n * @argument {String} property (camelCase)\n * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)\n */\nfunction getSupportedPropertyName(property) {\n var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];\n var upperProp = property.charAt(0).toUpperCase() + property.slice(1);\n\n for (var i = 0; i < prefixes.length; i++) {\n var prefix = prefixes[i];\n var toCheck = prefix ? '' + prefix + upperProp : property;\n if (typeof document.body.style[toCheck] !== 'undefined') {\n return toCheck;\n }\n }\n return null;\n}\n\n/**\n * Destroys the popper.\n * @method\n * @memberof Popper\n */\nfunction destroy() {\n this.state.isDestroyed = true;\n\n // touch DOM only if `applyStyle` modifier is enabled\n if (isModifierEnabled(this.modifiers, 'applyStyle')) {\n this.popper.removeAttribute('x-placement');\n this.popper.style.position = '';\n this.popper.style.top = '';\n this.popper.style.left = '';\n this.popper.style.right = '';\n this.popper.style.bottom = '';\n this.popper.style.willChange = '';\n this.popper.style[getSupportedPropertyName('transform')] = '';\n }\n\n this.disableEventListeners();\n\n // remove the popper if user explicitly asked for the deletion on destroy\n // do not use `remove` because IE11 doesn't support it\n if (this.options.removeOnDestroy) {\n this.popper.parentNode.removeChild(this.popper);\n }\n return this;\n}\n\n/**\n * Get the window associated with the element\n * @argument {Element} element\n * @returns {Window}\n */\nfunction getWindow(element) {\n var ownerDocument = element.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView : window;\n}\n\nfunction attachToScrollParents(scrollParent, event, callback, scrollParents) {\n var isBody = scrollParent.nodeName === 'BODY';\n var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;\n target.addEventListener(event, callback, { passive: true });\n\n if (!isBody) {\n attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);\n }\n scrollParents.push(target);\n}\n\n/**\n * Setup needed event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction setupEventListeners(reference, options, state, updateBound) {\n // Resize event listener on window\n state.updateBound = updateBound;\n getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });\n\n // Scroll event listener on scroll parents\n var scrollElement = getScrollParent(reference);\n attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);\n state.scrollElement = scrollElement;\n state.eventsEnabled = true;\n\n return state;\n}\n\n/**\n * It will add resize/scroll events and start recalculating\n * position of the popper element when they are triggered.\n * @method\n * @memberof Popper\n */\nfunction enableEventListeners() {\n if (!this.state.eventsEnabled) {\n this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);\n }\n}\n\n/**\n * Remove event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction removeEventListeners(reference, state) {\n // Remove resize event listener on window\n getWindow(reference).removeEventListener('resize', state.updateBound);\n\n // Remove scroll event listener on scroll parents\n state.scrollParents.forEach(function (target) {\n target.removeEventListener('scroll', state.updateBound);\n });\n\n // Reset state\n state.updateBound = null;\n state.scrollParents = [];\n state.scrollElement = null;\n state.eventsEnabled = false;\n return state;\n}\n\n/**\n * It will remove resize/scroll events and won't recalculate popper position\n * when they are triggered. It also won't trigger `onUpdate` callback anymore,\n * unless you call `update` method manually.\n * @method\n * @memberof Popper\n */\nfunction disableEventListeners() {\n if (this.state.eventsEnabled) {\n cancelAnimationFrame(this.scheduleUpdate);\n this.state = removeEventListeners(this.reference, this.state);\n }\n}\n\n/**\n * Tells if a given input is a number\n * @method\n * @memberof Popper.Utils\n * @param {*} input to check\n * @return {Boolean}\n */\nfunction isNumeric(n) {\n return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n/**\n * Set the style to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the style to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setStyles(element, styles) {\n Object.keys(styles).forEach(function (prop) {\n var unit = '';\n // add unit if the value is numeric and is one of the following\n if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {\n unit = 'px';\n }\n element.style[prop] = styles[prop] + unit;\n });\n}\n\n/**\n * Set the attributes to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the attributes to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setAttributes(element, attributes) {\n Object.keys(attributes).forEach(function (prop) {\n var value = attributes[prop];\n if (value !== false) {\n element.setAttribute(prop, attributes[prop]);\n } else {\n element.removeAttribute(prop);\n }\n });\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} data.styles - List of style properties - values to apply to popper element\n * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The same data object\n */\nfunction applyStyle(data) {\n // any property present in `data.styles` will be applied to the popper,\n // in this way we can make the 3rd party modifiers add custom styles to it\n // Be aware, modifiers could override the properties defined in the previous\n // lines of this modifier!\n setStyles(data.instance.popper, data.styles);\n\n // any property present in `data.attributes` will be applied to the popper,\n // they will be set as HTML attributes of the element\n setAttributes(data.instance.popper, data.attributes);\n\n // if arrowElement is defined and arrowStyles has some properties\n if (data.arrowElement && Object.keys(data.arrowStyles).length) {\n setStyles(data.arrowElement, data.arrowStyles);\n }\n\n return data;\n}\n\n/**\n * Set the x-placement attribute before everything else because it could be used\n * to add margins to the popper margins needs to be calculated to get the\n * correct popper offsets.\n * @method\n * @memberof Popper.modifiers\n * @param {HTMLElement} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper\n * @param {Object} options - Popper.js options\n */\nfunction applyStyleOnLoad(reference, popper, options, modifierOptions, state) {\n // compute reference element offsets\n var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);\n\n popper.setAttribute('x-placement', placement);\n\n // Apply `position` to popper before anything else because\n // without the position applied we can't guarantee correct computations\n setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });\n\n return options;\n}\n\n/**\n * @function\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Boolean} shouldRound - If the offsets should be rounded at all\n * @returns {Object} The popper's position offsets rounded\n *\n * The tale of pixel-perfect positioning. It's still not 100% perfect, but as\n * good as it can be within reason.\n * Discussion here: https://github.com/FezVrasta/popper.js/pull/715\n *\n * Low DPI screens cause a popper to be blurry if not using full pixels (Safari\n * as well on High DPI screens).\n *\n * Firefox prefers no rounding for positioning and does not have blurriness on\n * high DPI screens.\n *\n * Only horizontal placement and left/right values need to be considered.\n */\nfunction getRoundedOffsets(data, shouldRound) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n var round = Math.round,\n floor = Math.floor;\n\n var noRound = function noRound(v) {\n return v;\n };\n\n var referenceWidth = round(reference.width);\n var popperWidth = round(popper.width);\n\n var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;\n var isVariation = data.placement.indexOf('-') !== -1;\n var sameWidthParity = referenceWidth % 2 === popperWidth % 2;\n var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;\n\n var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;\n var verticalToInteger = !shouldRound ? noRound : round;\n\n return {\n left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),\n top: verticalToInteger(popper.top),\n bottom: verticalToInteger(popper.bottom),\n right: horizontalToInteger(popper.right)\n };\n}\n\nvar isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeStyle(data, options) {\n var x = options.x,\n y = options.y;\n var popper = data.offsets.popper;\n\n // Remove this legacy support in Popper.js v2\n\n var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'applyStyle';\n }).gpuAcceleration;\n if (legacyGpuAccelerationOption !== undefined) {\n console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');\n }\n var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;\n\n var offsetParent = getOffsetParent(data.instance.popper);\n var offsetParentRect = getBoundingClientRect(offsetParent);\n\n // Styles\n var styles = {\n position: popper.position\n };\n\n var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);\n\n var sideA = x === 'bottom' ? 'top' : 'bottom';\n var sideB = y === 'right' ? 'left' : 'right';\n\n // if gpuAcceleration is set to `true` and transform is supported,\n // we use `translate3d` to apply the position to the popper we\n // automatically use the supported prefixed version if needed\n var prefixedProperty = getSupportedPropertyName('transform');\n\n // now, let's make a step back and look at this code closely (wtf?)\n // If the content of the popper grows once it's been positioned, it\n // may happen that the popper gets misplaced because of the new content\n // overflowing its reference element\n // To avoid this problem, we provide two options (x and y), which allow\n // the consumer to define the offset origin.\n // If we position a popper on top of a reference element, we can set\n // `x` to `top` to make the popper grow towards its top instead of\n // its bottom.\n var left = void 0,\n top = void 0;\n if (sideA === 'bottom') {\n // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)\n // and not the bottom of the html element\n if (offsetParent.nodeName === 'HTML') {\n top = -offsetParent.clientHeight + offsets.bottom;\n } else {\n top = -offsetParentRect.height + offsets.bottom;\n }\n } else {\n top = offsets.top;\n }\n if (sideB === 'right') {\n if (offsetParent.nodeName === 'HTML') {\n left = -offsetParent.clientWidth + offsets.right;\n } else {\n left = -offsetParentRect.width + offsets.right;\n }\n } else {\n left = offsets.left;\n }\n if (gpuAcceleration && prefixedProperty) {\n styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';\n styles[sideA] = 0;\n styles[sideB] = 0;\n styles.willChange = 'transform';\n } else {\n // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties\n var invertTop = sideA === 'bottom' ? -1 : 1;\n var invertLeft = sideB === 'right' ? -1 : 1;\n styles[sideA] = top * invertTop;\n styles[sideB] = left * invertLeft;\n styles.willChange = sideA + ', ' + sideB;\n }\n\n // Attributes\n var attributes = {\n 'x-placement': data.placement\n };\n\n // Update `data` attributes, styles and arrowStyles\n data.attributes = _extends({}, attributes, data.attributes);\n data.styles = _extends({}, styles, data.styles);\n data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);\n\n return data;\n}\n\n/**\n * Helper used to know if the given modifier depends from another one.<br />\n * It checks if the needed modifier is listed and enabled.\n * @method\n * @memberof Popper.Utils\n * @param {Array} modifiers - list of modifiers\n * @param {String} requestingName - name of requesting modifier\n * @param {String} requestedName - name of requested modifier\n * @returns {Boolean}\n */\nfunction isModifierRequired(modifiers, requestingName, requestedName) {\n var requesting = find(modifiers, function (_ref) {\n var name = _ref.name;\n return name === requestingName;\n });\n\n var isRequired = !!requesting && modifiers.some(function (modifier) {\n return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;\n });\n\n if (!isRequired) {\n var _requesting = '`' + requestingName + '`';\n var requested = '`' + requestedName + '`';\n console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');\n }\n return isRequired;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction arrow(data, options) {\n var _data$offsets$arrow;\n\n // arrow depends on keepTogether in order to work\n if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {\n return data;\n }\n\n var arrowElement = options.element;\n\n // if arrowElement is a string, suppose it's a CSS selector\n if (typeof arrowElement === 'string') {\n arrowElement = data.instance.popper.querySelector(arrowElement);\n\n // if arrowElement is not found, don't run the modifier\n if (!arrowElement) {\n return data;\n }\n } else {\n // if the arrowElement isn't a query selector we must check that the\n // provided DOM node is child of its popper node\n if (!data.instance.popper.contains(arrowElement)) {\n console.warn('WARNING: `arrow.element` must be child of its popper element!');\n return data;\n }\n }\n\n var placement = data.placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isVertical = ['left', 'right'].indexOf(placement) !== -1;\n\n var len = isVertical ? 'height' : 'width';\n var sideCapitalized = isVertical ? 'Top' : 'Left';\n var side = sideCapitalized.toLowerCase();\n var altSide = isVertical ? 'left' : 'top';\n var opSide = isVertical ? 'bottom' : 'right';\n var arrowElementSize = getOuterSizes(arrowElement)[len];\n\n //\n // extends keepTogether behavior making sure the popper and its\n // reference have enough pixels in conjunction\n //\n\n // top/left side\n if (reference[opSide] - arrowElementSize < popper[side]) {\n data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);\n }\n // bottom/right side\n if (reference[side] + arrowElementSize > popper[opSide]) {\n data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];\n }\n data.offsets.popper = getClientRect(data.offsets.popper);\n\n // compute center of the popper\n var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;\n\n // Compute the sideValue using the updated popper offsets\n // take popper margin in account because we don't have this info available\n var css = getStyleComputedProperty(data.instance.popper);\n var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);\n var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);\n var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;\n\n // prevent arrowElement from being placed not contiguously to its popper\n sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);\n\n data.arrowElement = arrowElement;\n data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);\n\n return data;\n}\n\n/**\n * Get the opposite placement variation of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement variation\n * @returns {String} flipped placement variation\n */\nfunction getOppositeVariation(variation) {\n if (variation === 'end') {\n return 'start';\n } else if (variation === 'start') {\n return 'end';\n }\n return variation;\n}\n\n/**\n * List of accepted placements to use as values of the `placement` option.<br />\n * Valid placements are:\n * - `auto`\n * - `top`\n * - `right`\n * - `bottom`\n * - `left`\n *\n * Each placement can have a variation from this list:\n * - `-start`\n * - `-end`\n *\n * Variations are interpreted easily if you think of them as the left to right\n * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`\n * is right.<br />\n * Vertically (`left` and `right`), `start` is top and `end` is bottom.\n *\n * Some valid examples are:\n * - `top-end` (on top of reference, right aligned)\n * - `right-start` (on right of reference, top aligned)\n * - `bottom` (on bottom, centered)\n * - `auto-end` (on the side with more space available, alignment depends by placement)\n *\n * @static\n * @type {Array}\n * @enum {String}\n * @readonly\n * @method placements\n * @memberof Popper\n */\nvar placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];\n\n// Get rid of `auto` `auto-start` and `auto-end`\nvar validPlacements = placements.slice(3);\n\n/**\n * Given an initial placement, returns all the subsequent placements\n * clockwise (or counter-clockwise).\n *\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement - A valid placement (it accepts variations)\n * @argument {Boolean} counter - Set to true to walk the placements counterclockwise\n * @returns {Array} placements including their variations\n */\nfunction clockwise(placement) {\n var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var index = validPlacements.indexOf(placement);\n var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));\n return counter ? arr.reverse() : arr;\n}\n\nvar BEHAVIORS = {\n FLIP: 'flip',\n CLOCKWISE: 'clockwise',\n COUNTERCLOCKWISE: 'counterclockwise'\n};\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction flip(data, options) {\n // if `inner` modifier is enabled, we can't use the `flip` modifier\n if (isModifierEnabled(data.instance.modifiers, 'inner')) {\n return data;\n }\n\n if (data.flipped && data.placement === data.originalPlacement) {\n // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides\n return data;\n }\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);\n\n var placement = data.placement.split('-')[0];\n var placementOpposite = getOppositePlacement(placement);\n var variation = data.placement.split('-')[1] || '';\n\n var flipOrder = [];\n\n switch (options.behavior) {\n case BEHAVIORS.FLIP:\n flipOrder = [placement, placementOpposite];\n break;\n case BEHAVIORS.CLOCKWISE:\n flipOrder = clockwise(placement);\n break;\n case BEHAVIORS.COUNTERCLOCKWISE:\n flipOrder = clockwise(placement, true);\n break;\n default:\n flipOrder = options.behavior;\n }\n\n flipOrder.forEach(function (step, index) {\n if (placement !== step || flipOrder.length === index + 1) {\n return data;\n }\n\n placement = data.placement.split('-')[0];\n placementOpposite = getOppositePlacement(placement);\n\n var popperOffsets = data.offsets.popper;\n var refOffsets = data.offsets.reference;\n\n // using floor because the reference offsets may contain decimals we are not going to consider here\n var floor = Math.floor;\n var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);\n\n var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);\n var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);\n var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);\n var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);\n\n var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;\n\n // flip the variation if required\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n\n // flips variation if reference element overflows boundaries\n var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);\n\n // flips variation if popper content overflows boundaries\n var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);\n\n var flippedVariation = flippedVariationByRef || flippedVariationByContent;\n\n if (overlapsRef || overflowsBoundaries || flippedVariation) {\n // this boolean to detect any flip loop\n data.flipped = true;\n\n if (overlapsRef || overflowsBoundaries) {\n placement = flipOrder[index + 1];\n }\n\n if (flippedVariation) {\n variation = getOppositeVariation(variation);\n }\n\n data.placement = placement + (variation ? '-' + variation : '');\n\n // this object contains `position`, we want to preserve it along with\n // any additional property we may add in the future\n data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));\n\n data = runModifiers(data.instance.modifiers, data, 'flip');\n }\n });\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction keepTogether(data) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var placement = data.placement.split('-')[0];\n var floor = Math.floor;\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var side = isVertical ? 'right' : 'bottom';\n var opSide = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n if (popper[side] < floor(reference[opSide])) {\n data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];\n }\n if (popper[opSide] > floor(reference[side])) {\n data.offsets.popper[opSide] = floor(reference[side]);\n }\n\n return data;\n}\n\n/**\n * Converts a string containing value + unit into a px value number\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} str - Value + unit string\n * @argument {String} measurement - `height` or `width`\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @returns {Number|String}\n * Value in pixels, or original string if no values were extracted\n */\nfunction toValue(str, measurement, popperOffsets, referenceOffsets) {\n // separate value from unit\n var split = str.match(/((?:\\-|\\+)?\\d*\\.?\\d*)(.*)/);\n var value = +split[1];\n var unit = split[2];\n\n // If it's not a number it's an operator, I guess\n if (!value) {\n return str;\n }\n\n if (unit.indexOf('%') === 0) {\n var element = void 0;\n switch (unit) {\n case '%p':\n element = popperOffsets;\n break;\n case '%':\n case '%r':\n default:\n element = referenceOffsets;\n }\n\n var rect = getClientRect(element);\n return rect[measurement] / 100 * value;\n } else if (unit === 'vh' || unit === 'vw') {\n // if is a vh or vw, we calculate the size based on the viewport\n var size = void 0;\n if (unit === 'vh') {\n size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n } else {\n size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n }\n return size / 100 * value;\n } else {\n // if is an explicit pixel unit, we get rid of the unit and keep the value\n // if is an implicit unit, it's px, and we return just the value\n return value;\n }\n}\n\n/**\n * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} offset\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @argument {String} basePlacement\n * @returns {Array} a two cells array with x and y offsets in numbers\n */\nfunction parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {\n var offsets = [0, 0];\n\n // Use height if placement is left or right and index is 0 otherwise use width\n // in this way the first offset will use an axis and the second one\n // will use the other one\n var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;\n\n // Split the offset string to obtain a list of values and operands\n // The regex addresses values with the plus or minus sign in front (+10, -20, etc)\n var fragments = offset.split(/(\\+|\\-)/).map(function (frag) {\n return frag.trim();\n });\n\n // Detect if the offset string contains a pair of values or a single one\n // they could be separated by comma or space\n var divider = fragments.indexOf(find(fragments, function (frag) {\n return frag.search(/,|\\s/) !== -1;\n }));\n\n if (fragments[divider] && fragments[divider].indexOf(',') === -1) {\n console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');\n }\n\n // If divider is found, we divide the list of values and operands to divide\n // them by ofset X and Y.\n var splitRegex = /\\s*,\\s*|\\s+/;\n var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];\n\n // Convert the values with units to absolute pixels to allow our computations\n ops = ops.map(function (op, index) {\n // Most of the units rely on the orientation of the popper\n var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';\n var mergeWithPrevious = false;\n return op\n // This aggregates any `+` or `-` sign that aren't considered operators\n // e.g.: 10 + +5 => [10, +, +5]\n .reduce(function (a, b) {\n if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {\n a[a.length - 1] = b;\n mergeWithPrevious = true;\n return a;\n } else if (mergeWithPrevious) {\n a[a.length - 1] += b;\n mergeWithPrevious = false;\n return a;\n } else {\n return a.concat(b);\n }\n }, [])\n // Here we convert the string values into number values (in px)\n .map(function (str) {\n return toValue(str, measurement, popperOffsets, referenceOffsets);\n });\n });\n\n // Loop trough the offsets arrays and execute the operations\n ops.forEach(function (op, index) {\n op.forEach(function (frag, index2) {\n if (isNumeric(frag)) {\n offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);\n }\n });\n });\n return offsets;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @argument {Number|String} options.offset=0\n * The offset value as described in the modifier description\n * @returns {Object} The data object, properly modified\n */\nfunction offset(data, _ref) {\n var offset = _ref.offset;\n var placement = data.placement,\n _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var basePlacement = placement.split('-')[0];\n\n var offsets = void 0;\n if (isNumeric(+offset)) {\n offsets = [+offset, 0];\n } else {\n offsets = parseOffset(offset, popper, reference, basePlacement);\n }\n\n if (basePlacement === 'left') {\n popper.top += offsets[0];\n popper.left -= offsets[1];\n } else if (basePlacement === 'right') {\n popper.top += offsets[0];\n popper.left += offsets[1];\n } else if (basePlacement === 'top') {\n popper.left += offsets[0];\n popper.top -= offsets[1];\n } else if (basePlacement === 'bottom') {\n popper.left += offsets[0];\n popper.top += offsets[1];\n }\n\n data.popper = popper;\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction preventOverflow(data, options) {\n var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);\n\n // If offsetParent is the reference element, we really want to\n // go one step up and use the next offsetParent as reference to\n // avoid to make this modifier completely useless and look like broken\n if (data.instance.reference === boundariesElement) {\n boundariesElement = getOffsetParent(boundariesElement);\n }\n\n // NOTE: DOM access here\n // resets the popper's position so that the document size can be calculated excluding\n // the size of the popper element itself\n var transformProp = getSupportedPropertyName('transform');\n var popperStyles = data.instance.popper.style; // assignment to help minification\n var top = popperStyles.top,\n left = popperStyles.left,\n transform = popperStyles[transformProp];\n\n popperStyles.top = '';\n popperStyles.left = '';\n popperStyles[transformProp] = '';\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);\n\n // NOTE: DOM access here\n // restores the original style properties after the offsets have been computed\n popperStyles.top = top;\n popperStyles.left = left;\n popperStyles[transformProp] = transform;\n\n options.boundaries = boundaries;\n\n var order = options.priority;\n var popper = data.offsets.popper;\n\n var check = {\n primary: function primary(placement) {\n var value = popper[placement];\n if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {\n value = Math.max(popper[placement], boundaries[placement]);\n }\n return defineProperty({}, placement, value);\n },\n secondary: function secondary(placement) {\n var mainSide = placement === 'right' ? 'left' : 'top';\n var value = popper[mainSide];\n if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {\n value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));\n }\n return defineProperty({}, mainSide, value);\n }\n };\n\n order.forEach(function (placement) {\n var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';\n popper = _extends({}, popper, check[side](placement));\n });\n\n data.offsets.popper = popper;\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction shift(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var shiftvariation = placement.split('-')[1];\n\n // if shift shiftvariation is specified, run the modifier\n if (shiftvariation) {\n var _data$offsets = data.offsets,\n reference = _data$offsets.reference,\n popper = _data$offsets.popper;\n\n var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;\n var side = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n var shiftOffsets = {\n start: defineProperty({}, side, reference[side]),\n end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])\n };\n\n data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction hide(data) {\n if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {\n return data;\n }\n\n var refRect = data.offsets.reference;\n var bound = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'preventOverflow';\n }).boundaries;\n\n if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === true) {\n return data;\n }\n\n data.hide = true;\n data.attributes['x-out-of-boundaries'] = '';\n } else {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === false) {\n return data;\n }\n\n data.hide = false;\n data.attributes['x-out-of-boundaries'] = false;\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction inner(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;\n\n var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;\n\n popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);\n\n data.placement = getOppositePlacement(placement);\n data.offsets.popper = getClientRect(popper);\n\n return data;\n}\n\n/**\n * Modifier function, each modifier can have a function of this type assigned\n * to its `fn` property.<br />\n * These functions will be called on each update, this means that you must\n * make sure they are performant enough to avoid performance bottlenecks.\n *\n * @function ModifierFn\n * @argument {dataObject} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {dataObject} The data object, properly modified\n */\n\n/**\n * Modifiers are plugins used to alter the behavior of your poppers.<br />\n * Popper.js uses a set of 9 modifiers to provide all the basic functionalities\n * needed by the library.\n *\n * Usually you don't want to override the `order`, `fn` and `onLoad` props.\n * All the other properties are configurations that could be tweaked.\n * @namespace modifiers\n */\nvar modifiers = {\n /**\n * Modifier used to shift the popper on the start or end of its reference\n * element.<br />\n * It will read the variation of the `placement` property.<br />\n * It can be one either `-end` or `-start`.\n * @memberof modifiers\n * @inner\n */\n shift: {\n /** @prop {number} order=100 - Index used to define the order of execution */\n order: 100,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: shift\n },\n\n /**\n * The `offset` modifier can shift your popper on both its axis.\n *\n * It accepts the following units:\n * - `px` or unit-less, interpreted as pixels\n * - `%` or `%r`, percentage relative to the length of the reference element\n * - `%p`, percentage relative to the length of the popper element\n * - `vw`, CSS viewport width unit\n * - `vh`, CSS viewport height unit\n *\n * For length is intended the main axis relative to the placement of the popper.<br />\n * This means that if the placement is `top` or `bottom`, the length will be the\n * `width`. In case of `left` or `right`, it will be the `height`.\n *\n * You can provide a single value (as `Number` or `String`), or a pair of values\n * as `String` divided by a comma or one (or more) white spaces.<br />\n * The latter is a deprecated method because it leads to confusion and will be\n * removed in v2.<br />\n * Additionally, it accepts additions and subtractions between different units.\n * Note that multiplications and divisions aren't supported.\n *\n * Valid examples are:\n * ```\n * 10\n * '10%'\n * '10, 10'\n * '10%, 10'\n * '10 + 10%'\n * '10 - 5vh + 3%'\n * '-10px + 5vh, 5px - 6%'\n * ```\n * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap\n * > with their reference element, unfortunately, you will have to disable the `flip` modifier.\n * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).\n *\n * @memberof modifiers\n * @inner\n */\n offset: {\n /** @prop {number} order=200 - Index used to define the order of execution */\n order: 200,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: offset,\n /** @prop {Number|String} offset=0\n * The offset value as described in the modifier description\n */\n offset: 0\n },\n\n /**\n * Modifier used to prevent the popper from being positioned outside the boundary.\n *\n * A scenario exists where the reference itself is not within the boundaries.<br />\n * We can say it has \"escaped the boundaries\" — or just \"escaped\".<br />\n * In this case we need to decide whether the popper should either:\n *\n * - detach from the reference and remain \"trapped\" in the boundaries, or\n * - if it should ignore the boundary and \"escape with its reference\"\n *\n * When `escapeWithReference` is set to`true` and reference is completely\n * outside its boundaries, the popper will overflow (or completely leave)\n * the boundaries in order to remain attached to the edge of the reference.\n *\n * @memberof modifiers\n * @inner\n */\n preventOverflow: {\n /** @prop {number} order=300 - Index used to define the order of execution */\n order: 300,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: preventOverflow,\n /**\n * @prop {Array} [priority=['left','right','top','bottom']]\n * Popper will try to prevent overflow following these priorities by default,\n * then, it could overflow on the left and on top of the `boundariesElement`\n */\n priority: ['left', 'right', 'top', 'bottom'],\n /**\n * @prop {number} padding=5\n * Amount of pixel used to define a minimum distance between the boundaries\n * and the popper. This makes sure the popper always has a little padding\n * between the edges of its container\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='scrollParent'\n * Boundaries used by the modifier. Can be `scrollParent`, `window`,\n * `viewport` or any DOM element.\n */\n boundariesElement: 'scrollParent'\n },\n\n /**\n * Modifier used to make sure the reference and its popper stay near each other\n * without leaving any gap between the two. Especially useful when the arrow is\n * enabled and you want to ensure that it points to its reference element.\n * It cares only about the first axis. You can still have poppers with margin\n * between the popper and its reference element.\n * @memberof modifiers\n * @inner\n */\n keepTogether: {\n /** @prop {number} order=400 - Index used to define the order of execution */\n order: 400,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: keepTogether\n },\n\n /**\n * This modifier is used to move the `arrowElement` of the popper to make\n * sure it is positioned between the reference element and its popper element.\n * It will read the outer size of the `arrowElement` node to detect how many\n * pixels of conjunction are needed.\n *\n * It has no effect if no `arrowElement` is provided.\n * @memberof modifiers\n * @inner\n */\n arrow: {\n /** @prop {number} order=500 - Index used to define the order of execution */\n order: 500,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: arrow,\n /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */\n element: '[x-arrow]'\n },\n\n /**\n * Modifier used to flip the popper's placement when it starts to overlap its\n * reference element.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n *\n * **NOTE:** this modifier will interrupt the current update cycle and will\n * restart it if it detects the need to flip the placement.\n * @memberof modifiers\n * @inner\n */\n flip: {\n /** @prop {number} order=600 - Index used to define the order of execution */\n order: 600,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: flip,\n /**\n * @prop {String|Array} behavior='flip'\n * The behavior used to change the popper's placement. It can be one of\n * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid\n * placements (with optional variations)\n */\n behavior: 'flip',\n /**\n * @prop {number} padding=5\n * The popper will flip if it hits the edges of the `boundariesElement`\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='viewport'\n * The element which will define the boundaries of the popper position.\n * The popper will never be placed outside of the defined boundaries\n * (except if `keepTogether` is enabled)\n */\n boundariesElement: 'viewport',\n /**\n * @prop {Boolean} flipVariations=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the reference element overlaps its boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariations: false,\n /**\n * @prop {Boolean} flipVariationsByContent=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the popper element overlaps its reference boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariationsByContent: false\n },\n\n /**\n * Modifier used to make the popper flow toward the inner of the reference element.\n * By default, when this modifier is disabled, the popper will be placed outside\n * the reference element.\n * @memberof modifiers\n * @inner\n */\n inner: {\n /** @prop {number} order=700 - Index used to define the order of execution */\n order: 700,\n /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */\n enabled: false,\n /** @prop {ModifierFn} */\n fn: inner\n },\n\n /**\n * Modifier used to hide the popper when its reference element is outside of the\n * popper boundaries. It will set a `x-out-of-boundaries` attribute which can\n * be used to hide with a CSS selector the popper when its reference is\n * out of boundaries.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n * @memberof modifiers\n * @inner\n */\n hide: {\n /** @prop {number} order=800 - Index used to define the order of execution */\n order: 800,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: hide\n },\n\n /**\n * Computes the style that will be applied to the popper element to gets\n * properly positioned.\n *\n * Note that this modifier will not touch the DOM, it just prepares the styles\n * so that `applyStyle` modifier can apply it. This separation is useful\n * in case you need to replace `applyStyle` with a custom implementation.\n *\n * This modifier has `850` as `order` value to maintain backward compatibility\n * with previous versions of Popper.js. Expect the modifiers ordering method\n * to change in future major versions of the library.\n *\n * @memberof modifiers\n * @inner\n */\n computeStyle: {\n /** @prop {number} order=850 - Index used to define the order of execution */\n order: 850,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: computeStyle,\n /**\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: true,\n /**\n * @prop {string} [x='bottom']\n * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.\n * Change this if your popper should grow in a direction different from `bottom`\n */\n x: 'bottom',\n /**\n * @prop {string} [x='left']\n * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.\n * Change this if your popper should grow in a direction different from `right`\n */\n y: 'right'\n },\n\n /**\n * Applies the computed styles to the popper element.\n *\n * All the DOM manipulations are limited to this modifier. This is useful in case\n * you want to integrate Popper.js inside a framework or view library and you\n * want to delegate all the DOM manipulations to it.\n *\n * Note that if you disable this modifier, you must make sure the popper element\n * has its position set to `absolute` before Popper.js can do its work!\n *\n * Just disable this modifier and define your own to achieve the desired effect.\n *\n * @memberof modifiers\n * @inner\n */\n applyStyle: {\n /** @prop {number} order=900 - Index used to define the order of execution */\n order: 900,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: applyStyle,\n /** @prop {Function} */\n onLoad: applyStyleOnLoad,\n /**\n * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: undefined\n }\n};\n\n/**\n * The `dataObject` is an object containing all the information used by Popper.js.\n * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.\n * @name dataObject\n * @property {Object} data.instance The Popper.js instance\n * @property {String} data.placement Placement applied to popper\n * @property {String} data.originalPlacement Placement originally defined on init\n * @property {Boolean} data.flipped True if popper has been flipped by flip modifier\n * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper\n * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier\n * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.boundaries Offsets of the popper boundaries\n * @property {Object} data.offsets The measurements of popper, reference and arrow elements\n * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0\n */\n\n/**\n * Default options provided to Popper.js constructor.<br />\n * These can be overridden using the `options` argument of Popper.js.<br />\n * To override an option, simply pass an object with the same\n * structure of the `options` object, as the 3rd argument. For example:\n * ```\n * new Popper(ref, pop, {\n * modifiers: {\n * preventOverflow: { enabled: false }\n * }\n * })\n * ```\n * @type {Object}\n * @static\n * @memberof Popper\n */\nvar Defaults = {\n /**\n * Popper's placement.\n * @prop {Popper.placements} placement='bottom'\n */\n placement: 'bottom',\n\n /**\n * Set this to true if you want popper to position it self in 'fixed' mode\n * @prop {Boolean} positionFixed=false\n */\n positionFixed: false,\n\n /**\n * Whether events (resize, scroll) are initially enabled.\n * @prop {Boolean} eventsEnabled=true\n */\n eventsEnabled: true,\n\n /**\n * Set to true if you want to automatically remove the popper when\n * you call the `destroy` method.\n * @prop {Boolean} removeOnDestroy=false\n */\n removeOnDestroy: false,\n\n /**\n * Callback called when the popper is created.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onCreate}\n */\n onCreate: function onCreate() {},\n\n /**\n * Callback called when the popper is updated. This callback is not called\n * on the initialization/creation of the popper, but only on subsequent\n * updates.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onUpdate}\n */\n onUpdate: function onUpdate() {},\n\n /**\n * List of modifiers used to modify the offsets before they are applied to the popper.\n * They provide most of the functionalities of Popper.js.\n * @prop {modifiers}\n */\n modifiers: modifiers\n};\n\n/**\n * @callback onCreate\n * @param {dataObject} data\n */\n\n/**\n * @callback onUpdate\n * @param {dataObject} data\n */\n\n// Utils\n// Methods\nvar Popper = function () {\n /**\n * Creates a new Popper.js instance.\n * @class Popper\n * @param {Element|referenceObject} reference - The reference element used to position the popper\n * @param {Element} popper - The HTML / XML element used as the popper\n * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)\n * @return {Object} instance - The generated Popper.js instance\n */\n function Popper(reference, popper) {\n var _this = this;\n\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n classCallCheck(this, Popper);\n\n this.scheduleUpdate = function () {\n return requestAnimationFrame(_this.update);\n };\n\n // make update() debounced, so that it only runs at most once-per-tick\n this.update = debounce(this.update.bind(this));\n\n // with {} we create a new object with the options inside it\n this.options = _extends({}, Popper.Defaults, options);\n\n // init state\n this.state = {\n isDestroyed: false,\n isCreated: false,\n scrollParents: []\n };\n\n // get reference and popper elements (allow jQuery wrappers)\n this.reference = reference && reference.jquery ? reference[0] : reference;\n this.popper = popper && popper.jquery ? popper[0] : popper;\n\n // Deep merge modifiers options\n this.options.modifiers = {};\n Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {\n _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});\n });\n\n // Refactoring modifiers' list (Object => Array)\n this.modifiers = Object.keys(this.options.modifiers).map(function (name) {\n return _extends({\n name: name\n }, _this.options.modifiers[name]);\n })\n // sort the modifiers by order\n .sort(function (a, b) {\n return a.order - b.order;\n });\n\n // modifiers have the ability to execute arbitrary code when Popper.js get inited\n // such code is executed in the same order of its modifier\n // they could add new properties to their options configuration\n // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!\n this.modifiers.forEach(function (modifierOptions) {\n if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {\n modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);\n }\n });\n\n // fire the first update to position the popper in the right place\n this.update();\n\n var eventsEnabled = this.options.eventsEnabled;\n if (eventsEnabled) {\n // setup event listeners, they will take care of update the position in specific situations\n this.enableEventListeners();\n }\n\n this.state.eventsEnabled = eventsEnabled;\n }\n\n // We can't use class properties because they don't get listed in the\n // class prototype and break stuff like Sinon stubs\n\n\n createClass(Popper, [{\n key: 'update',\n value: function update$$1() {\n return update.call(this);\n }\n }, {\n key: 'destroy',\n value: function destroy$$1() {\n return destroy.call(this);\n }\n }, {\n key: 'enableEventListeners',\n value: function enableEventListeners$$1() {\n return enableEventListeners.call(this);\n }\n }, {\n key: 'disableEventListeners',\n value: function disableEventListeners$$1() {\n return disableEventListeners.call(this);\n }\n\n /**\n * Schedules an update. It will run on the next UI update available.\n * @method scheduleUpdate\n * @memberof Popper\n */\n\n\n /**\n * Collection of utilities useful when writing custom modifiers.\n * Starting from version 1.7, this method is available only if you\n * include `popper-utils.js` before `popper.js`.\n *\n * **DEPRECATION**: This way to access PopperUtils is deprecated\n * and will be removed in v2! Use the PopperUtils module directly instead.\n * Due to the high instability of the methods contained in Utils, we can't\n * guarantee them to follow semver. Use them at your own risk!\n * @static\n * @private\n * @type {Object}\n * @deprecated since version 1.8\n * @member Utils\n * @memberof Popper\n */\n\n }]);\n return Popper;\n}();\n\n/**\n * The `referenceObject` is an object that provides an interface compatible with Popper.js\n * and lets you use it as replacement of a real DOM node.<br />\n * You can use this method to position a popper relatively to a set of coordinates\n * in case you don't have a DOM node to use as reference.\n *\n * ```\n * new Popper(referenceObject, popperNode);\n * ```\n *\n * NB: This feature isn't supported in Internet Explorer 10.\n * @name referenceObject\n * @property {Function} data.getBoundingClientRect\n * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.\n * @property {number} data.clientWidth\n * An ES6 getter that will return the width of the virtual reference element.\n * @property {number} data.clientHeight\n * An ES6 getter that will return the height of the virtual reference element.\n */\n\n\nPopper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;\nPopper.placements = placements;\nPopper.Defaults = Defaults;\n\nexport default Popper;\n//# sourceMappingURL=popper.js.map\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper.js (https://popper.js.org/)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n if (this._config.backdrop === 'static') {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n } else {\n this.hide()\n }\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper.js (https://popper.js.org/)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"]} \ No newline at end of file +{"version":3,"sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/popper.js/dist/esm/popper.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"names":["transitionEndEmulator","duration","_this","this","called","$","one","Util","TRANSITION_END","setTimeout","triggerTransitionEnd","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","obj","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","call","expectedTypes","value","valueType","toString","match","toLowerCase","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","fn","jquery","emulateTransitionEnd","event","special","bindType","delegateType","handle","target","is","handleObj","handler","apply","arguments","NAME","JQUERY_NO_CONFLICT","Alert","_element","close","rootElement","_getRootElement","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","EVENT_KEY","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","_updateInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_extends","_handleSwipe","absDeltax","abs","_this2","_keydown","_addTouchEventListeners","_this3","start","originalEvent","pointerType","clientX","touches","end","clearTimeout","e","move","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","elementInterval","parseInt","defaultInterval","directionalClassName","orderClassName","_this4","activeElementIndex","nextElement","nextElementIndex","isCycling","slidEvent","CLASS_NAME_ACTIVE","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","scrollSize","CLASS_NAME_COLLAPSE","getBoundingClientRect","triggerArrayLength","isTransitioning","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","isBrowser","timeoutDuration","longerTimeoutBrowsers","userAgent","debounce","Promise","resolve","then","scheduled","isFunction","functionToCheck","getStyleComputedProperty","ownerDocument","defaultView","getComputedStyle","getParentNode","nodeName","host","getScrollParent","body","_getStyleComputedProp","overflow","overflowX","overflowY","getReferenceNode","reference","referenceNode","isIE11","MSInputMethodContext","documentMode","isIE10","isIE","getOffsetParent","noOffsetParent","offsetParent","nextElementSibling","getRoot","node","findCommonOffsetParent","element1","element2","order","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","range","createRange","setStart","setEnd","commonAncestorContainer","firstElementChild","element1root","getScroll","side","undefined","upperSide","html","scrollingElement","includeScroll","rect","subtract","scrollTop","scrollLeft","modifier","top","bottom","left","right","getBordersSize","styles","axis","sideA","sideB","getSize","computedStyle","max","getWindowSizes","height","width","classCallCheck","instance","createClass","defineProperties","props","descriptor","enumerable","configurable","writable","defineProperty","key","protoProps","staticProps","assign","source","getClientRect","offsets","result","sizes","clientWidth","clientHeight","horizScrollbar","offsetWidth","vertScrollbar","getOffsetRectRelativeToArbitraryNode","fixedPosition","isHTML","childrenRect","parentRect","scrollParent","borderTopWidth","borderLeftWidth","marginTop","marginLeft","getViewportOffsetRectRelativeToArtbitraryNode","excludeScroll","relativeOffset","innerWidth","innerHeight","offset","isFixed","getFixedPositionOffsetParent","parentElement","el","getBoundaries","popper","padding","boundariesElement","boundaries","boundariesNode","_getWindowSizes","isPaddingNumber","getArea","_ref","computeAutoPlacement","placement","refRect","rects","sortedAreas","keys","map","area","sort","a","b","filteredAreas","_ref2","computedPlacement","variation","getReferenceOffsets","state","commonOffsetParent","getOuterSizes","x","marginBottom","y","marginRight","getOppositePlacement","hash","replace","matched","getPopperOffsets","referenceOffsets","popperRect","popperOffsets","isHoriz","mainSide","secondarySide","measurement","secondaryMeasurement","find","arr","check","Array","runModifiers","modifiers","ends","prop","findIndex","cur","forEach","console","warn","enabled","update","isDestroyed","arrowStyles","attributes","flipped","options","positionFixed","flip","originalPlacement","position","isCreated","onUpdate","onCreate","isModifierEnabled","modifierName","some","name","getSupportedPropertyName","prefixes","upperProp","charAt","toCheck","destroy","removeAttribute","willChange","disableEventListeners","removeOnDestroy","removeChild","getWindow","setupEventListeners","updateBound","addEventListener","passive","scrollElement","attachToScrollParents","callback","scrollParents","isBody","eventsEnabled","enableEventListeners","scheduleUpdate","cancelAnimationFrame","removeEventListener","isNumeric","n","isNaN","isFinite","setStyles","unit","isFirefox","isModifierRequired","requestingName","requestedName","requesting","isRequired","_requesting","requested","placements","validPlacements","clockwise","counter","concat","reverse","BEHAVIORS","parseOffset","basePlacement","useHeight","fragments","frag","divider","search","splitRegex","ops","op","mergeWithPrevious","reduce","str","toValue","index2","Defaults","shift","shiftvariation","_data$offsets","isVertical","shiftOffsets","preventOverflow","transformProp","popperStyles","transform","priority","primary","escapeWithReference","secondary","min","keepTogether","floor","opSide","arrow","_data$offsets$arrow","arrowElement","sideCapitalized","altSide","arrowElementSize","center","popperMarginSide","popperBorderSide","sideValue","round","placementOpposite","flipOrder","behavior","step","refOffsets","overlapsRef","overflowsLeft","overflowsRight","overflowsTop","overflowsBottom","overflowsBoundaries","flippedVariationByRef","flipVariations","flippedVariationByContent","flipVariationsByContent","flippedVariation","getOppositeVariation","inner","subtractLength","bound","computeStyle","legacyGpuAccelerationOption","gpuAcceleration","offsetParentRect","shouldRound","noRound","v","referenceWidth","popperWidth","isVariation","horizontalToInteger","verticalToInteger","getRoundedOffsets","devicePixelRatio","prefixedProperty","invertTop","invertLeft","x-placement","applyStyle","onLoad","modifierOptions","Popper","requestAnimationFrame","Utils","global","PopperUtils","REGEXP_KEYDOWN","ARROW_UP_KEYCODE","boundary","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","referenceElement","_getPopperConfig","noop","hideEvent","stopPropagation","constructor","_getPlacement","$parentDropdown","_getOffset","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","EVENT_CLICK_DATA_API","backdrop","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","modalTransitionDuration","modalBody","ELEMENT_NODE","appendChild","_enforceFocus","shownEvent","transitionComplete","_this5","has","_this6","_this7","_this8","_resetAdjustments","_resetScrollbar","_removeBackdrop","_this9","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","_getScrollbarWidth","_this10","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","calculatedMargin","elements","margin","scrollDiv","scrollbarWidth","_this11","uriAttrs","DefaultWhitelist","*","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","createdDocument","DOMParser","parseFromString","whitelistKeys","_loop","elName","attributeList","whitelistedAttributes","allowedAttributeList","attrName","nodeValue","regExp","attrRegex","allowedAttribute","innerHTML","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","container","fallbackPlacement","customClass","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","DATA_KEY","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","complete","_fixTransition","prevHoverState","_cleanTipClass","getTitle","CLASS_PREFIX","setElementContent","CLASS_NAME_FADE","content","text","empty","append","_handlePopperPlacementChange","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","$tip","tabClass","join","popperData","initConfigAnimation","Popover","_getContent","method","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targetSelector","targetBCR","pageYOffset","_getOffsetHeight","maxScroll","_activate","_clear","queries","$link","parents","SELECTOR_NAV_LINKS","scrollSpys","$spy","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","autohide","Toast","_clearTimeout","_close"],"mappings":"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","sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._updateInterval()\n\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n if (!element) {\n return\n }\n\n const elementInterval = parseInt(element.getAttribute('data-interval'), 10)\n\n if (elementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = elementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n this._activeElement = nextElement\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**!\n * @fileOverview Kickass library to create and place poppers near their reference elements.\n * @version 1.16.1\n * @license\n * Copyright (c) 2016 Federico Zivolo and contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';\n\nvar timeoutDuration = function () {\n var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];\n for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {\n if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {\n return 1;\n }\n }\n return 0;\n}();\n\nfunction microtaskDebounce(fn) {\n var called = false;\n return function () {\n if (called) {\n return;\n }\n called = true;\n window.Promise.resolve().then(function () {\n called = false;\n fn();\n });\n };\n}\n\nfunction taskDebounce(fn) {\n var scheduled = false;\n return function () {\n if (!scheduled) {\n scheduled = true;\n setTimeout(function () {\n scheduled = false;\n fn();\n }, timeoutDuration);\n }\n };\n}\n\nvar supportsMicroTasks = isBrowser && window.Promise;\n\n/**\n* Create a debounced version of a method, that's asynchronously deferred\n* but called in the minimum time possible.\n*\n* @method\n* @memberof Popper.Utils\n* @argument {Function} fn\n* @returns {Function}\n*/\nvar debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;\n\n/**\n * Check if the given variable is a function\n * @method\n * @memberof Popper.Utils\n * @argument {Any} functionToCheck - variable to check\n * @returns {Boolean} answer to: is a function?\n */\nfunction isFunction(functionToCheck) {\n var getType = {};\n return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';\n}\n\n/**\n * Get CSS computed property of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Eement} element\n * @argument {String} property\n */\nfunction getStyleComputedProperty(element, property) {\n if (element.nodeType !== 1) {\n return [];\n }\n // NOTE: 1 DOM access here\n var window = element.ownerDocument.defaultView;\n var css = window.getComputedStyle(element, null);\n return property ? css[property] : css;\n}\n\n/**\n * Returns the parentNode or the host of the element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} parent\n */\nfunction getParentNode(element) {\n if (element.nodeName === 'HTML') {\n return element;\n }\n return element.parentNode || element.host;\n}\n\n/**\n * Returns the scrolling parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} scroll parent\n */\nfunction getScrollParent(element) {\n // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n if (!element) {\n return document.body;\n }\n\n switch (element.nodeName) {\n case 'HTML':\n case 'BODY':\n return element.ownerDocument.body;\n case '#document':\n return element.body;\n }\n\n // Firefox want us to check `-x` and `-y` variations as well\n\n var _getStyleComputedProp = getStyleComputedProperty(element),\n overflow = _getStyleComputedProp.overflow,\n overflowX = _getStyleComputedProp.overflowX,\n overflowY = _getStyleComputedProp.overflowY;\n\n if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {\n return element;\n }\n\n return getScrollParent(getParentNode(element));\n}\n\n/**\n * Returns the reference node of the reference object, or the reference object itself.\n * @method\n * @memberof Popper.Utils\n * @param {Element|Object} reference - the reference element (the popper will be relative to this)\n * @returns {Element} parent\n */\nfunction getReferenceNode(reference) {\n return reference && reference.referenceNode ? reference.referenceNode : reference;\n}\n\nvar isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);\nvar isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);\n\n/**\n * Determines if the browser is Internet Explorer\n * @method\n * @memberof Popper.Utils\n * @param {Number} version to check\n * @returns {Boolean} isIE\n */\nfunction isIE(version) {\n if (version === 11) {\n return isIE11;\n }\n if (version === 10) {\n return isIE10;\n }\n return isIE11 || isIE10;\n}\n\n/**\n * Returns the offset parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} offset parent\n */\nfunction getOffsetParent(element) {\n if (!element) {\n return document.documentElement;\n }\n\n var noOffsetParent = isIE(10) ? document.body : null;\n\n // NOTE: 1 DOM access here\n var offsetParent = element.offsetParent || null;\n // Skip hidden elements which don't have an offsetParent\n while (offsetParent === noOffsetParent && element.nextElementSibling) {\n offsetParent = (element = element.nextElementSibling).offsetParent;\n }\n\n var nodeName = offsetParent && offsetParent.nodeName;\n\n if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {\n return element ? element.ownerDocument.documentElement : document.documentElement;\n }\n\n // .offsetParent will return the closest TH, TD or TABLE in case\n // no offsetParent is present, I hate this job...\n if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {\n return getOffsetParent(offsetParent);\n }\n\n return offsetParent;\n}\n\nfunction isOffsetContainer(element) {\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY') {\n return false;\n }\n return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;\n}\n\n/**\n * Finds the root node (document, shadowDOM root) of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} node\n * @returns {Element} root node\n */\nfunction getRoot(node) {\n if (node.parentNode !== null) {\n return getRoot(node.parentNode);\n }\n\n return node;\n}\n\n/**\n * Finds the offset parent common to the two provided nodes\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element1\n * @argument {Element} element2\n * @returns {Element} common offset parent\n */\nfunction findCommonOffsetParent(element1, element2) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {\n return document.documentElement;\n }\n\n // Here we make sure to give as \"start\" the element that comes first in the DOM\n var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;\n var start = order ? element1 : element2;\n var end = order ? element2 : element1;\n\n // Get common ancestor container\n var range = document.createRange();\n range.setStart(start, 0);\n range.setEnd(end, 0);\n var commonAncestorContainer = range.commonAncestorContainer;\n\n // Both nodes are inside #document\n\n if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {\n if (isOffsetContainer(commonAncestorContainer)) {\n return commonAncestorContainer;\n }\n\n return getOffsetParent(commonAncestorContainer);\n }\n\n // one of the nodes is inside shadowDOM, find which one\n var element1root = getRoot(element1);\n if (element1root.host) {\n return findCommonOffsetParent(element1root.host, element2);\n } else {\n return findCommonOffsetParent(element1, getRoot(element2).host);\n }\n}\n\n/**\n * Gets the scroll value of the given element in the given side (top and left)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {String} side `top` or `left`\n * @returns {number} amount of scrolled pixels\n */\nfunction getScroll(element) {\n var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';\n\n var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n var html = element.ownerDocument.documentElement;\n var scrollingElement = element.ownerDocument.scrollingElement || html;\n return scrollingElement[upperSide];\n }\n\n return element[upperSide];\n}\n\n/*\n * Sum or subtract the element scroll values (left and top) from a given rect object\n * @method\n * @memberof Popper.Utils\n * @param {Object} rect - Rect object you want to change\n * @param {HTMLElement} element - The element from the function reads the scroll values\n * @param {Boolean} subtract - set to true if you want to subtract the scroll values\n * @return {Object} rect - The modifier rect object\n */\nfunction includeScroll(rect, element) {\n var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n var modifier = subtract ? -1 : 1;\n rect.top += scrollTop * modifier;\n rect.bottom += scrollTop * modifier;\n rect.left += scrollLeft * modifier;\n rect.right += scrollLeft * modifier;\n return rect;\n}\n\n/*\n * Helper to detect borders of a given element\n * @method\n * @memberof Popper.Utils\n * @param {CSSStyleDeclaration} styles\n * Result of `getStyleComputedProperty` on the given element\n * @param {String} axis - `x` or `y`\n * @return {number} borders - The borders size of the given axis\n */\n\nfunction getBordersSize(styles, axis) {\n var sideA = axis === 'x' ? 'Left' : 'Top';\n var sideB = sideA === 'Left' ? 'Right' : 'Bottom';\n\n return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);\n}\n\nfunction getSize(axis, body, html, computedStyle) {\n return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);\n}\n\nfunction getWindowSizes(document) {\n var body = document.body;\n var html = document.documentElement;\n var computedStyle = isIE(10) && getComputedStyle(html);\n\n return {\n height: getSize('Height', body, html, computedStyle),\n width: getSize('Width', body, html, computedStyle)\n };\n}\n\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\n\n\n\n\nvar defineProperty = function (obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\n/**\n * Given element offsets, generate an output similar to getBoundingClientRect\n * @method\n * @memberof Popper.Utils\n * @argument {Object} offsets\n * @returns {Object} ClientRect like output\n */\nfunction getClientRect(offsets) {\n return _extends({}, offsets, {\n right: offsets.left + offsets.width,\n bottom: offsets.top + offsets.height\n });\n}\n\n/**\n * Get bounding client rect of given element\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} element\n * @return {Object} client rect\n */\nfunction getBoundingClientRect(element) {\n var rect = {};\n\n // IE10 10 FIX: Please, don't ask, the element isn't\n // considered in DOM in some circumstances...\n // This isn't reproducible in IE10 compatibility mode of IE11\n try {\n if (isIE(10)) {\n rect = element.getBoundingClientRect();\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n rect.top += scrollTop;\n rect.left += scrollLeft;\n rect.bottom += scrollTop;\n rect.right += scrollLeft;\n } else {\n rect = element.getBoundingClientRect();\n }\n } catch (e) {}\n\n var result = {\n left: rect.left,\n top: rect.top,\n width: rect.right - rect.left,\n height: rect.bottom - rect.top\n };\n\n // subtract scrollbar size from sizes\n var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};\n var width = sizes.width || element.clientWidth || result.width;\n var height = sizes.height || element.clientHeight || result.height;\n\n var horizScrollbar = element.offsetWidth - width;\n var vertScrollbar = element.offsetHeight - height;\n\n // if an hypothetical scrollbar is detected, we must be sure it's not a `border`\n // we make this check conditional for performance reasons\n if (horizScrollbar || vertScrollbar) {\n var styles = getStyleComputedProperty(element);\n horizScrollbar -= getBordersSize(styles, 'x');\n vertScrollbar -= getBordersSize(styles, 'y');\n\n result.width -= horizScrollbar;\n result.height -= vertScrollbar;\n }\n\n return getClientRect(result);\n}\n\nfunction getOffsetRectRelativeToArbitraryNode(children, parent) {\n var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var isIE10 = isIE(10);\n var isHTML = parent.nodeName === 'HTML';\n var childrenRect = getBoundingClientRect(children);\n var parentRect = getBoundingClientRect(parent);\n var scrollParent = getScrollParent(children);\n\n var styles = getStyleComputedProperty(parent);\n var borderTopWidth = parseFloat(styles.borderTopWidth);\n var borderLeftWidth = parseFloat(styles.borderLeftWidth);\n\n // In cases where the parent is fixed, we must ignore negative scroll in offset calc\n if (fixedPosition && isHTML) {\n parentRect.top = Math.max(parentRect.top, 0);\n parentRect.left = Math.max(parentRect.left, 0);\n }\n var offsets = getClientRect({\n top: childrenRect.top - parentRect.top - borderTopWidth,\n left: childrenRect.left - parentRect.left - borderLeftWidth,\n width: childrenRect.width,\n height: childrenRect.height\n });\n offsets.marginTop = 0;\n offsets.marginLeft = 0;\n\n // Subtract margins of documentElement in case it's being used as parent\n // we do this only on HTML because it's the only element that behaves\n // differently when margins are applied to it. The margins are included in\n // the box of the documentElement, in the other cases not.\n if (!isIE10 && isHTML) {\n var marginTop = parseFloat(styles.marginTop);\n var marginLeft = parseFloat(styles.marginLeft);\n\n offsets.top -= borderTopWidth - marginTop;\n offsets.bottom -= borderTopWidth - marginTop;\n offsets.left -= borderLeftWidth - marginLeft;\n offsets.right -= borderLeftWidth - marginLeft;\n\n // Attach marginTop and marginLeft because in some circumstances we may need them\n offsets.marginTop = marginTop;\n offsets.marginLeft = marginLeft;\n }\n\n if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {\n offsets = includeScroll(offsets, parent);\n }\n\n return offsets;\n}\n\nfunction getViewportOffsetRectRelativeToArtbitraryNode(element) {\n var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var html = element.ownerDocument.documentElement;\n var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);\n var width = Math.max(html.clientWidth, window.innerWidth || 0);\n var height = Math.max(html.clientHeight, window.innerHeight || 0);\n\n var scrollTop = !excludeScroll ? getScroll(html) : 0;\n var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;\n\n var offset = {\n top: scrollTop - relativeOffset.top + relativeOffset.marginTop,\n left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,\n width: width,\n height: height\n };\n\n return getClientRect(offset);\n}\n\n/**\n * Check if the given element is fixed or is inside a fixed parent\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {Element} customContainer\n * @returns {Boolean} answer to \"isFixed?\"\n */\nfunction isFixed(element) {\n var nodeName = element.nodeName;\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n return false;\n }\n if (getStyleComputedProperty(element, 'position') === 'fixed') {\n return true;\n }\n var parentNode = getParentNode(element);\n if (!parentNode) {\n return false;\n }\n return isFixed(parentNode);\n}\n\n/**\n * Finds the first parent of an element that has a transformed property defined\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} first transformed parent or documentElement\n */\n\nfunction getFixedPositionOffsetParent(element) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element || !element.parentElement || isIE()) {\n return document.documentElement;\n }\n var el = element.parentElement;\n while (el && getStyleComputedProperty(el, 'transform') === 'none') {\n el = el.parentElement;\n }\n return el || document.documentElement;\n}\n\n/**\n * Computed the boundaries limits and return them\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} popper\n * @param {HTMLElement} reference\n * @param {number} padding\n * @param {HTMLElement} boundariesElement - Element used to define the boundaries\n * @param {Boolean} fixedPosition - Is in fixed position mode\n * @returns {Object} Coordinates of the boundaries\n */\nfunction getBoundaries(popper, reference, padding, boundariesElement) {\n var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n\n // NOTE: 1 DOM access here\n\n var boundaries = { top: 0, left: 0 };\n var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n\n // Handle viewport case\n if (boundariesElement === 'viewport') {\n boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);\n } else {\n // Handle other cases based on DOM element used as boundaries\n var boundariesNode = void 0;\n if (boundariesElement === 'scrollParent') {\n boundariesNode = getScrollParent(getParentNode(reference));\n if (boundariesNode.nodeName === 'BODY') {\n boundariesNode = popper.ownerDocument.documentElement;\n }\n } else if (boundariesElement === 'window') {\n boundariesNode = popper.ownerDocument.documentElement;\n } else {\n boundariesNode = boundariesElement;\n }\n\n var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);\n\n // In case of HTML, we need a different computation\n if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {\n var _getWindowSizes = getWindowSizes(popper.ownerDocument),\n height = _getWindowSizes.height,\n width = _getWindowSizes.width;\n\n boundaries.top += offsets.top - offsets.marginTop;\n boundaries.bottom = height + offsets.top;\n boundaries.left += offsets.left - offsets.marginLeft;\n boundaries.right = width + offsets.left;\n } else {\n // for all the other DOM elements, this one is good\n boundaries = offsets;\n }\n }\n\n // Add paddings\n padding = padding || 0;\n var isPaddingNumber = typeof padding === 'number';\n boundaries.left += isPaddingNumber ? padding : padding.left || 0;\n boundaries.top += isPaddingNumber ? padding : padding.top || 0;\n boundaries.right -= isPaddingNumber ? padding : padding.right || 0;\n boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;\n\n return boundaries;\n}\n\nfunction getArea(_ref) {\n var width = _ref.width,\n height = _ref.height;\n\n return width * height;\n}\n\n/**\n * Utility used to transform the `auto` placement to the placement with more\n * available space.\n * @method\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {\n var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n if (placement.indexOf('auto') === -1) {\n return placement;\n }\n\n var boundaries = getBoundaries(popper, reference, padding, boundariesElement);\n\n var rects = {\n top: {\n width: boundaries.width,\n height: refRect.top - boundaries.top\n },\n right: {\n width: boundaries.right - refRect.right,\n height: boundaries.height\n },\n bottom: {\n width: boundaries.width,\n height: boundaries.bottom - refRect.bottom\n },\n left: {\n width: refRect.left - boundaries.left,\n height: boundaries.height\n }\n };\n\n var sortedAreas = Object.keys(rects).map(function (key) {\n return _extends({\n key: key\n }, rects[key], {\n area: getArea(rects[key])\n });\n }).sort(function (a, b) {\n return b.area - a.area;\n });\n\n var filteredAreas = sortedAreas.filter(function (_ref2) {\n var width = _ref2.width,\n height = _ref2.height;\n return width >= popper.clientWidth && height >= popper.clientHeight;\n });\n\n var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;\n\n var variation = placement.split('-')[1];\n\n return computedPlacement + (variation ? '-' + variation : '');\n}\n\n/**\n * Get offsets to the reference element\n * @method\n * @memberof Popper.Utils\n * @param {Object} state\n * @param {Element} popper - the popper element\n * @param {Element} reference - the reference element (the popper will be relative to this)\n * @param {Element} fixedPosition - is in fixed position mode\n * @returns {Object} An object containing the offsets which will be applied to the popper\n */\nfunction getReferenceOffsets(state, popper, reference) {\n var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n\n var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));\n return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);\n}\n\n/**\n * Get the outer sizes of the given element (offset size + margins)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Object} object containing width and height properties\n */\nfunction getOuterSizes(element) {\n var window = element.ownerDocument.defaultView;\n var styles = window.getComputedStyle(element);\n var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);\n var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);\n var result = {\n width: element.offsetWidth + y,\n height: element.offsetHeight + x\n };\n return result;\n}\n\n/**\n * Get the opposite placement of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement\n * @returns {String} flipped placement\n */\nfunction getOppositePlacement(placement) {\n var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}\n\n/**\n * Get offsets to the popper\n * @method\n * @memberof Popper.Utils\n * @param {Object} position - CSS position the Popper will get applied\n * @param {HTMLElement} popper - the popper element\n * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)\n * @param {String} placement - one of the valid placement options\n * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper\n */\nfunction getPopperOffsets(popper, referenceOffsets, placement) {\n placement = placement.split('-')[0];\n\n // Get popper node sizes\n var popperRect = getOuterSizes(popper);\n\n // Add position, width and height to our offsets object\n var popperOffsets = {\n width: popperRect.width,\n height: popperRect.height\n };\n\n // depending by the popper placement we have to compute its offsets slightly differently\n var isHoriz = ['right', 'left'].indexOf(placement) !== -1;\n var mainSide = isHoriz ? 'top' : 'left';\n var secondarySide = isHoriz ? 'left' : 'top';\n var measurement = isHoriz ? 'height' : 'width';\n var secondaryMeasurement = !isHoriz ? 'height' : 'width';\n\n popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;\n if (placement === secondarySide) {\n popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];\n } else {\n popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];\n }\n\n return popperOffsets;\n}\n\n/**\n * Mimics the `find` method of Array\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction find(arr, check) {\n // use native find if supported\n if (Array.prototype.find) {\n return arr.find(check);\n }\n\n // use `filter` to obtain the same behavior of `find`\n return arr.filter(check)[0];\n}\n\n/**\n * Return the index of the matching object\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction findIndex(arr, prop, value) {\n // use native findIndex if supported\n if (Array.prototype.findIndex) {\n return arr.findIndex(function (cur) {\n return cur[prop] === value;\n });\n }\n\n // use `find` + `indexOf` if `findIndex` isn't supported\n var match = find(arr, function (obj) {\n return obj[prop] === value;\n });\n return arr.indexOf(match);\n}\n\n/**\n * Loop trough the list of modifiers and run them in order,\n * each of them will then edit the data object.\n * @method\n * @memberof Popper.Utils\n * @param {dataObject} data\n * @param {Array} modifiers\n * @param {String} ends - Optional modifier name used as stopper\n * @returns {dataObject}\n */\nfunction runModifiers(modifiers, data, ends) {\n var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));\n\n modifiersToRun.forEach(function (modifier) {\n if (modifier['function']) {\n // eslint-disable-line dot-notation\n console.warn('`modifier.function` is deprecated, use `modifier.fn`!');\n }\n var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation\n if (modifier.enabled && isFunction(fn)) {\n // Add properties to offsets to make them a complete clientRect object\n // we do this before each modifier to make sure the previous one doesn't\n // mess with these values\n data.offsets.popper = getClientRect(data.offsets.popper);\n data.offsets.reference = getClientRect(data.offsets.reference);\n\n data = fn(data, modifier);\n }\n });\n\n return data;\n}\n\n/**\n * Updates the position of the popper, computing the new offsets and applying\n * the new style.<br />\n * Prefer `scheduleUpdate` over `update` because of performance reasons.\n * @method\n * @memberof Popper\n */\nfunction update() {\n // if popper is destroyed, don't perform any further update\n if (this.state.isDestroyed) {\n return;\n }\n\n var data = {\n instance: this,\n styles: {},\n arrowStyles: {},\n attributes: {},\n flipped: false,\n offsets: {}\n };\n\n // compute reference element offsets\n data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);\n\n // store the computed placement inside `originalPlacement`\n data.originalPlacement = data.placement;\n\n data.positionFixed = this.options.positionFixed;\n\n // compute the popper offsets\n data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);\n\n data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';\n\n // run the modifiers\n data = runModifiers(this.modifiers, data);\n\n // the first `update` will call `onCreate` callback\n // the other ones will call `onUpdate` callback\n if (!this.state.isCreated) {\n this.state.isCreated = true;\n this.options.onCreate(data);\n } else {\n this.options.onUpdate(data);\n }\n}\n\n/**\n * Helper used to know if the given modifier is enabled.\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean}\n */\nfunction isModifierEnabled(modifiers, modifierName) {\n return modifiers.some(function (_ref) {\n var name = _ref.name,\n enabled = _ref.enabled;\n return enabled && name === modifierName;\n });\n}\n\n/**\n * Get the prefixed supported property name\n * @method\n * @memberof Popper.Utils\n * @argument {String} property (camelCase)\n * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)\n */\nfunction getSupportedPropertyName(property) {\n var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];\n var upperProp = property.charAt(0).toUpperCase() + property.slice(1);\n\n for (var i = 0; i < prefixes.length; i++) {\n var prefix = prefixes[i];\n var toCheck = prefix ? '' + prefix + upperProp : property;\n if (typeof document.body.style[toCheck] !== 'undefined') {\n return toCheck;\n }\n }\n return null;\n}\n\n/**\n * Destroys the popper.\n * @method\n * @memberof Popper\n */\nfunction destroy() {\n this.state.isDestroyed = true;\n\n // touch DOM only if `applyStyle` modifier is enabled\n if (isModifierEnabled(this.modifiers, 'applyStyle')) {\n this.popper.removeAttribute('x-placement');\n this.popper.style.position = '';\n this.popper.style.top = '';\n this.popper.style.left = '';\n this.popper.style.right = '';\n this.popper.style.bottom = '';\n this.popper.style.willChange = '';\n this.popper.style[getSupportedPropertyName('transform')] = '';\n }\n\n this.disableEventListeners();\n\n // remove the popper if user explicitly asked for the deletion on destroy\n // do not use `remove` because IE11 doesn't support it\n if (this.options.removeOnDestroy) {\n this.popper.parentNode.removeChild(this.popper);\n }\n return this;\n}\n\n/**\n * Get the window associated with the element\n * @argument {Element} element\n * @returns {Window}\n */\nfunction getWindow(element) {\n var ownerDocument = element.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView : window;\n}\n\nfunction attachToScrollParents(scrollParent, event, callback, scrollParents) {\n var isBody = scrollParent.nodeName === 'BODY';\n var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;\n target.addEventListener(event, callback, { passive: true });\n\n if (!isBody) {\n attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);\n }\n scrollParents.push(target);\n}\n\n/**\n * Setup needed event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction setupEventListeners(reference, options, state, updateBound) {\n // Resize event listener on window\n state.updateBound = updateBound;\n getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });\n\n // Scroll event listener on scroll parents\n var scrollElement = getScrollParent(reference);\n attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);\n state.scrollElement = scrollElement;\n state.eventsEnabled = true;\n\n return state;\n}\n\n/**\n * It will add resize/scroll events and start recalculating\n * position of the popper element when they are triggered.\n * @method\n * @memberof Popper\n */\nfunction enableEventListeners() {\n if (!this.state.eventsEnabled) {\n this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);\n }\n}\n\n/**\n * Remove event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction removeEventListeners(reference, state) {\n // Remove resize event listener on window\n getWindow(reference).removeEventListener('resize', state.updateBound);\n\n // Remove scroll event listener on scroll parents\n state.scrollParents.forEach(function (target) {\n target.removeEventListener('scroll', state.updateBound);\n });\n\n // Reset state\n state.updateBound = null;\n state.scrollParents = [];\n state.scrollElement = null;\n state.eventsEnabled = false;\n return state;\n}\n\n/**\n * It will remove resize/scroll events and won't recalculate popper position\n * when they are triggered. It also won't trigger `onUpdate` callback anymore,\n * unless you call `update` method manually.\n * @method\n * @memberof Popper\n */\nfunction disableEventListeners() {\n if (this.state.eventsEnabled) {\n cancelAnimationFrame(this.scheduleUpdate);\n this.state = removeEventListeners(this.reference, this.state);\n }\n}\n\n/**\n * Tells if a given input is a number\n * @method\n * @memberof Popper.Utils\n * @param {*} input to check\n * @return {Boolean}\n */\nfunction isNumeric(n) {\n return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n/**\n * Set the style to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the style to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setStyles(element, styles) {\n Object.keys(styles).forEach(function (prop) {\n var unit = '';\n // add unit if the value is numeric and is one of the following\n if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {\n unit = 'px';\n }\n element.style[prop] = styles[prop] + unit;\n });\n}\n\n/**\n * Set the attributes to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the attributes to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setAttributes(element, attributes) {\n Object.keys(attributes).forEach(function (prop) {\n var value = attributes[prop];\n if (value !== false) {\n element.setAttribute(prop, attributes[prop]);\n } else {\n element.removeAttribute(prop);\n }\n });\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} data.styles - List of style properties - values to apply to popper element\n * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The same data object\n */\nfunction applyStyle(data) {\n // any property present in `data.styles` will be applied to the popper,\n // in this way we can make the 3rd party modifiers add custom styles to it\n // Be aware, modifiers could override the properties defined in the previous\n // lines of this modifier!\n setStyles(data.instance.popper, data.styles);\n\n // any property present in `data.attributes` will be applied to the popper,\n // they will be set as HTML attributes of the element\n setAttributes(data.instance.popper, data.attributes);\n\n // if arrowElement is defined and arrowStyles has some properties\n if (data.arrowElement && Object.keys(data.arrowStyles).length) {\n setStyles(data.arrowElement, data.arrowStyles);\n }\n\n return data;\n}\n\n/**\n * Set the x-placement attribute before everything else because it could be used\n * to add margins to the popper margins needs to be calculated to get the\n * correct popper offsets.\n * @method\n * @memberof Popper.modifiers\n * @param {HTMLElement} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper\n * @param {Object} options - Popper.js options\n */\nfunction applyStyleOnLoad(reference, popper, options, modifierOptions, state) {\n // compute reference element offsets\n var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);\n\n popper.setAttribute('x-placement', placement);\n\n // Apply `position` to popper before anything else because\n // without the position applied we can't guarantee correct computations\n setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });\n\n return options;\n}\n\n/**\n * @function\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Boolean} shouldRound - If the offsets should be rounded at all\n * @returns {Object} The popper's position offsets rounded\n *\n * The tale of pixel-perfect positioning. It's still not 100% perfect, but as\n * good as it can be within reason.\n * Discussion here: https://github.com/FezVrasta/popper.js/pull/715\n *\n * Low DPI screens cause a popper to be blurry if not using full pixels (Safari\n * as well on High DPI screens).\n *\n * Firefox prefers no rounding for positioning and does not have blurriness on\n * high DPI screens.\n *\n * Only horizontal placement and left/right values need to be considered.\n */\nfunction getRoundedOffsets(data, shouldRound) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n var round = Math.round,\n floor = Math.floor;\n\n var noRound = function noRound(v) {\n return v;\n };\n\n var referenceWidth = round(reference.width);\n var popperWidth = round(popper.width);\n\n var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;\n var isVariation = data.placement.indexOf('-') !== -1;\n var sameWidthParity = referenceWidth % 2 === popperWidth % 2;\n var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;\n\n var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;\n var verticalToInteger = !shouldRound ? noRound : round;\n\n return {\n left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),\n top: verticalToInteger(popper.top),\n bottom: verticalToInteger(popper.bottom),\n right: horizontalToInteger(popper.right)\n };\n}\n\nvar isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeStyle(data, options) {\n var x = options.x,\n y = options.y;\n var popper = data.offsets.popper;\n\n // Remove this legacy support in Popper.js v2\n\n var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'applyStyle';\n }).gpuAcceleration;\n if (legacyGpuAccelerationOption !== undefined) {\n console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');\n }\n var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;\n\n var offsetParent = getOffsetParent(data.instance.popper);\n var offsetParentRect = getBoundingClientRect(offsetParent);\n\n // Styles\n var styles = {\n position: popper.position\n };\n\n var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);\n\n var sideA = x === 'bottom' ? 'top' : 'bottom';\n var sideB = y === 'right' ? 'left' : 'right';\n\n // if gpuAcceleration is set to `true` and transform is supported,\n // we use `translate3d` to apply the position to the popper we\n // automatically use the supported prefixed version if needed\n var prefixedProperty = getSupportedPropertyName('transform');\n\n // now, let's make a step back and look at this code closely (wtf?)\n // If the content of the popper grows once it's been positioned, it\n // may happen that the popper gets misplaced because of the new content\n // overflowing its reference element\n // To avoid this problem, we provide two options (x and y), which allow\n // the consumer to define the offset origin.\n // If we position a popper on top of a reference element, we can set\n // `x` to `top` to make the popper grow towards its top instead of\n // its bottom.\n var left = void 0,\n top = void 0;\n if (sideA === 'bottom') {\n // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)\n // and not the bottom of the html element\n if (offsetParent.nodeName === 'HTML') {\n top = -offsetParent.clientHeight + offsets.bottom;\n } else {\n top = -offsetParentRect.height + offsets.bottom;\n }\n } else {\n top = offsets.top;\n }\n if (sideB === 'right') {\n if (offsetParent.nodeName === 'HTML') {\n left = -offsetParent.clientWidth + offsets.right;\n } else {\n left = -offsetParentRect.width + offsets.right;\n }\n } else {\n left = offsets.left;\n }\n if (gpuAcceleration && prefixedProperty) {\n styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';\n styles[sideA] = 0;\n styles[sideB] = 0;\n styles.willChange = 'transform';\n } else {\n // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties\n var invertTop = sideA === 'bottom' ? -1 : 1;\n var invertLeft = sideB === 'right' ? -1 : 1;\n styles[sideA] = top * invertTop;\n styles[sideB] = left * invertLeft;\n styles.willChange = sideA + ', ' + sideB;\n }\n\n // Attributes\n var attributes = {\n 'x-placement': data.placement\n };\n\n // Update `data` attributes, styles and arrowStyles\n data.attributes = _extends({}, attributes, data.attributes);\n data.styles = _extends({}, styles, data.styles);\n data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);\n\n return data;\n}\n\n/**\n * Helper used to know if the given modifier depends from another one.<br />\n * It checks if the needed modifier is listed and enabled.\n * @method\n * @memberof Popper.Utils\n * @param {Array} modifiers - list of modifiers\n * @param {String} requestingName - name of requesting modifier\n * @param {String} requestedName - name of requested modifier\n * @returns {Boolean}\n */\nfunction isModifierRequired(modifiers, requestingName, requestedName) {\n var requesting = find(modifiers, function (_ref) {\n var name = _ref.name;\n return name === requestingName;\n });\n\n var isRequired = !!requesting && modifiers.some(function (modifier) {\n return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;\n });\n\n if (!isRequired) {\n var _requesting = '`' + requestingName + '`';\n var requested = '`' + requestedName + '`';\n console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');\n }\n return isRequired;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction arrow(data, options) {\n var _data$offsets$arrow;\n\n // arrow depends on keepTogether in order to work\n if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {\n return data;\n }\n\n var arrowElement = options.element;\n\n // if arrowElement is a string, suppose it's a CSS selector\n if (typeof arrowElement === 'string') {\n arrowElement = data.instance.popper.querySelector(arrowElement);\n\n // if arrowElement is not found, don't run the modifier\n if (!arrowElement) {\n return data;\n }\n } else {\n // if the arrowElement isn't a query selector we must check that the\n // provided DOM node is child of its popper node\n if (!data.instance.popper.contains(arrowElement)) {\n console.warn('WARNING: `arrow.element` must be child of its popper element!');\n return data;\n }\n }\n\n var placement = data.placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isVertical = ['left', 'right'].indexOf(placement) !== -1;\n\n var len = isVertical ? 'height' : 'width';\n var sideCapitalized = isVertical ? 'Top' : 'Left';\n var side = sideCapitalized.toLowerCase();\n var altSide = isVertical ? 'left' : 'top';\n var opSide = isVertical ? 'bottom' : 'right';\n var arrowElementSize = getOuterSizes(arrowElement)[len];\n\n //\n // extends keepTogether behavior making sure the popper and its\n // reference have enough pixels in conjunction\n //\n\n // top/left side\n if (reference[opSide] - arrowElementSize < popper[side]) {\n data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);\n }\n // bottom/right side\n if (reference[side] + arrowElementSize > popper[opSide]) {\n data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];\n }\n data.offsets.popper = getClientRect(data.offsets.popper);\n\n // compute center of the popper\n var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;\n\n // Compute the sideValue using the updated popper offsets\n // take popper margin in account because we don't have this info available\n var css = getStyleComputedProperty(data.instance.popper);\n var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);\n var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);\n var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;\n\n // prevent arrowElement from being placed not contiguously to its popper\n sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);\n\n data.arrowElement = arrowElement;\n data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);\n\n return data;\n}\n\n/**\n * Get the opposite placement variation of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement variation\n * @returns {String} flipped placement variation\n */\nfunction getOppositeVariation(variation) {\n if (variation === 'end') {\n return 'start';\n } else if (variation === 'start') {\n return 'end';\n }\n return variation;\n}\n\n/**\n * List of accepted placements to use as values of the `placement` option.<br />\n * Valid placements are:\n * - `auto`\n * - `top`\n * - `right`\n * - `bottom`\n * - `left`\n *\n * Each placement can have a variation from this list:\n * - `-start`\n * - `-end`\n *\n * Variations are interpreted easily if you think of them as the left to right\n * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`\n * is right.<br />\n * Vertically (`left` and `right`), `start` is top and `end` is bottom.\n *\n * Some valid examples are:\n * - `top-end` (on top of reference, right aligned)\n * - `right-start` (on right of reference, top aligned)\n * - `bottom` (on bottom, centered)\n * - `auto-end` (on the side with more space available, alignment depends by placement)\n *\n * @static\n * @type {Array}\n * @enum {String}\n * @readonly\n * @method placements\n * @memberof Popper\n */\nvar placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];\n\n// Get rid of `auto` `auto-start` and `auto-end`\nvar validPlacements = placements.slice(3);\n\n/**\n * Given an initial placement, returns all the subsequent placements\n * clockwise (or counter-clockwise).\n *\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement - A valid placement (it accepts variations)\n * @argument {Boolean} counter - Set to true to walk the placements counterclockwise\n * @returns {Array} placements including their variations\n */\nfunction clockwise(placement) {\n var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var index = validPlacements.indexOf(placement);\n var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));\n return counter ? arr.reverse() : arr;\n}\n\nvar BEHAVIORS = {\n FLIP: 'flip',\n CLOCKWISE: 'clockwise',\n COUNTERCLOCKWISE: 'counterclockwise'\n};\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction flip(data, options) {\n // if `inner` modifier is enabled, we can't use the `flip` modifier\n if (isModifierEnabled(data.instance.modifiers, 'inner')) {\n return data;\n }\n\n if (data.flipped && data.placement === data.originalPlacement) {\n // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides\n return data;\n }\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);\n\n var placement = data.placement.split('-')[0];\n var placementOpposite = getOppositePlacement(placement);\n var variation = data.placement.split('-')[1] || '';\n\n var flipOrder = [];\n\n switch (options.behavior) {\n case BEHAVIORS.FLIP:\n flipOrder = [placement, placementOpposite];\n break;\n case BEHAVIORS.CLOCKWISE:\n flipOrder = clockwise(placement);\n break;\n case BEHAVIORS.COUNTERCLOCKWISE:\n flipOrder = clockwise(placement, true);\n break;\n default:\n flipOrder = options.behavior;\n }\n\n flipOrder.forEach(function (step, index) {\n if (placement !== step || flipOrder.length === index + 1) {\n return data;\n }\n\n placement = data.placement.split('-')[0];\n placementOpposite = getOppositePlacement(placement);\n\n var popperOffsets = data.offsets.popper;\n var refOffsets = data.offsets.reference;\n\n // using floor because the reference offsets may contain decimals we are not going to consider here\n var floor = Math.floor;\n var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);\n\n var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);\n var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);\n var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);\n var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);\n\n var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;\n\n // flip the variation if required\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n\n // flips variation if reference element overflows boundaries\n var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);\n\n // flips variation if popper content overflows boundaries\n var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);\n\n var flippedVariation = flippedVariationByRef || flippedVariationByContent;\n\n if (overlapsRef || overflowsBoundaries || flippedVariation) {\n // this boolean to detect any flip loop\n data.flipped = true;\n\n if (overlapsRef || overflowsBoundaries) {\n placement = flipOrder[index + 1];\n }\n\n if (flippedVariation) {\n variation = getOppositeVariation(variation);\n }\n\n data.placement = placement + (variation ? '-' + variation : '');\n\n // this object contains `position`, we want to preserve it along with\n // any additional property we may add in the future\n data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));\n\n data = runModifiers(data.instance.modifiers, data, 'flip');\n }\n });\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction keepTogether(data) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var placement = data.placement.split('-')[0];\n var floor = Math.floor;\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var side = isVertical ? 'right' : 'bottom';\n var opSide = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n if (popper[side] < floor(reference[opSide])) {\n data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];\n }\n if (popper[opSide] > floor(reference[side])) {\n data.offsets.popper[opSide] = floor(reference[side]);\n }\n\n return data;\n}\n\n/**\n * Converts a string containing value + unit into a px value number\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} str - Value + unit string\n * @argument {String} measurement - `height` or `width`\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @returns {Number|String}\n * Value in pixels, or original string if no values were extracted\n */\nfunction toValue(str, measurement, popperOffsets, referenceOffsets) {\n // separate value from unit\n var split = str.match(/((?:\\-|\\+)?\\d*\\.?\\d*)(.*)/);\n var value = +split[1];\n var unit = split[2];\n\n // If it's not a number it's an operator, I guess\n if (!value) {\n return str;\n }\n\n if (unit.indexOf('%') === 0) {\n var element = void 0;\n switch (unit) {\n case '%p':\n element = popperOffsets;\n break;\n case '%':\n case '%r':\n default:\n element = referenceOffsets;\n }\n\n var rect = getClientRect(element);\n return rect[measurement] / 100 * value;\n } else if (unit === 'vh' || unit === 'vw') {\n // if is a vh or vw, we calculate the size based on the viewport\n var size = void 0;\n if (unit === 'vh') {\n size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n } else {\n size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n }\n return size / 100 * value;\n } else {\n // if is an explicit pixel unit, we get rid of the unit and keep the value\n // if is an implicit unit, it's px, and we return just the value\n return value;\n }\n}\n\n/**\n * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} offset\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @argument {String} basePlacement\n * @returns {Array} a two cells array with x and y offsets in numbers\n */\nfunction parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {\n var offsets = [0, 0];\n\n // Use height if placement is left or right and index is 0 otherwise use width\n // in this way the first offset will use an axis and the second one\n // will use the other one\n var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;\n\n // Split the offset string to obtain a list of values and operands\n // The regex addresses values with the plus or minus sign in front (+10, -20, etc)\n var fragments = offset.split(/(\\+|\\-)/).map(function (frag) {\n return frag.trim();\n });\n\n // Detect if the offset string contains a pair of values or a single one\n // they could be separated by comma or space\n var divider = fragments.indexOf(find(fragments, function (frag) {\n return frag.search(/,|\\s/) !== -1;\n }));\n\n if (fragments[divider] && fragments[divider].indexOf(',') === -1) {\n console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');\n }\n\n // If divider is found, we divide the list of values and operands to divide\n // them by ofset X and Y.\n var splitRegex = /\\s*,\\s*|\\s+/;\n var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];\n\n // Convert the values with units to absolute pixels to allow our computations\n ops = ops.map(function (op, index) {\n // Most of the units rely on the orientation of the popper\n var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';\n var mergeWithPrevious = false;\n return op\n // This aggregates any `+` or `-` sign that aren't considered operators\n // e.g.: 10 + +5 => [10, +, +5]\n .reduce(function (a, b) {\n if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {\n a[a.length - 1] = b;\n mergeWithPrevious = true;\n return a;\n } else if (mergeWithPrevious) {\n a[a.length - 1] += b;\n mergeWithPrevious = false;\n return a;\n } else {\n return a.concat(b);\n }\n }, [])\n // Here we convert the string values into number values (in px)\n .map(function (str) {\n return toValue(str, measurement, popperOffsets, referenceOffsets);\n });\n });\n\n // Loop trough the offsets arrays and execute the operations\n ops.forEach(function (op, index) {\n op.forEach(function (frag, index2) {\n if (isNumeric(frag)) {\n offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);\n }\n });\n });\n return offsets;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @argument {Number|String} options.offset=0\n * The offset value as described in the modifier description\n * @returns {Object} The data object, properly modified\n */\nfunction offset(data, _ref) {\n var offset = _ref.offset;\n var placement = data.placement,\n _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var basePlacement = placement.split('-')[0];\n\n var offsets = void 0;\n if (isNumeric(+offset)) {\n offsets = [+offset, 0];\n } else {\n offsets = parseOffset(offset, popper, reference, basePlacement);\n }\n\n if (basePlacement === 'left') {\n popper.top += offsets[0];\n popper.left -= offsets[1];\n } else if (basePlacement === 'right') {\n popper.top += offsets[0];\n popper.left += offsets[1];\n } else if (basePlacement === 'top') {\n popper.left += offsets[0];\n popper.top -= offsets[1];\n } else if (basePlacement === 'bottom') {\n popper.left += offsets[0];\n popper.top += offsets[1];\n }\n\n data.popper = popper;\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction preventOverflow(data, options) {\n var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);\n\n // If offsetParent is the reference element, we really want to\n // go one step up and use the next offsetParent as reference to\n // avoid to make this modifier completely useless and look like broken\n if (data.instance.reference === boundariesElement) {\n boundariesElement = getOffsetParent(boundariesElement);\n }\n\n // NOTE: DOM access here\n // resets the popper's position so that the document size can be calculated excluding\n // the size of the popper element itself\n var transformProp = getSupportedPropertyName('transform');\n var popperStyles = data.instance.popper.style; // assignment to help minification\n var top = popperStyles.top,\n left = popperStyles.left,\n transform = popperStyles[transformProp];\n\n popperStyles.top = '';\n popperStyles.left = '';\n popperStyles[transformProp] = '';\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);\n\n // NOTE: DOM access here\n // restores the original style properties after the offsets have been computed\n popperStyles.top = top;\n popperStyles.left = left;\n popperStyles[transformProp] = transform;\n\n options.boundaries = boundaries;\n\n var order = options.priority;\n var popper = data.offsets.popper;\n\n var check = {\n primary: function primary(placement) {\n var value = popper[placement];\n if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {\n value = Math.max(popper[placement], boundaries[placement]);\n }\n return defineProperty({}, placement, value);\n },\n secondary: function secondary(placement) {\n var mainSide = placement === 'right' ? 'left' : 'top';\n var value = popper[mainSide];\n if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {\n value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));\n }\n return defineProperty({}, mainSide, value);\n }\n };\n\n order.forEach(function (placement) {\n var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';\n popper = _extends({}, popper, check[side](placement));\n });\n\n data.offsets.popper = popper;\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction shift(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var shiftvariation = placement.split('-')[1];\n\n // if shift shiftvariation is specified, run the modifier\n if (shiftvariation) {\n var _data$offsets = data.offsets,\n reference = _data$offsets.reference,\n popper = _data$offsets.popper;\n\n var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;\n var side = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n var shiftOffsets = {\n start: defineProperty({}, side, reference[side]),\n end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])\n };\n\n data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction hide(data) {\n if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {\n return data;\n }\n\n var refRect = data.offsets.reference;\n var bound = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'preventOverflow';\n }).boundaries;\n\n if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === true) {\n return data;\n }\n\n data.hide = true;\n data.attributes['x-out-of-boundaries'] = '';\n } else {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === false) {\n return data;\n }\n\n data.hide = false;\n data.attributes['x-out-of-boundaries'] = false;\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction inner(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;\n\n var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;\n\n popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);\n\n data.placement = getOppositePlacement(placement);\n data.offsets.popper = getClientRect(popper);\n\n return data;\n}\n\n/**\n * Modifier function, each modifier can have a function of this type assigned\n * to its `fn` property.<br />\n * These functions will be called on each update, this means that you must\n * make sure they are performant enough to avoid performance bottlenecks.\n *\n * @function ModifierFn\n * @argument {dataObject} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {dataObject} The data object, properly modified\n */\n\n/**\n * Modifiers are plugins used to alter the behavior of your poppers.<br />\n * Popper.js uses a set of 9 modifiers to provide all the basic functionalities\n * needed by the library.\n *\n * Usually you don't want to override the `order`, `fn` and `onLoad` props.\n * All the other properties are configurations that could be tweaked.\n * @namespace modifiers\n */\nvar modifiers = {\n /**\n * Modifier used to shift the popper on the start or end of its reference\n * element.<br />\n * It will read the variation of the `placement` property.<br />\n * It can be one either `-end` or `-start`.\n * @memberof modifiers\n * @inner\n */\n shift: {\n /** @prop {number} order=100 - Index used to define the order of execution */\n order: 100,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: shift\n },\n\n /**\n * The `offset` modifier can shift your popper on both its axis.\n *\n * It accepts the following units:\n * - `px` or unit-less, interpreted as pixels\n * - `%` or `%r`, percentage relative to the length of the reference element\n * - `%p`, percentage relative to the length of the popper element\n * - `vw`, CSS viewport width unit\n * - `vh`, CSS viewport height unit\n *\n * For length is intended the main axis relative to the placement of the popper.<br />\n * This means that if the placement is `top` or `bottom`, the length will be the\n * `width`. In case of `left` or `right`, it will be the `height`.\n *\n * You can provide a single value (as `Number` or `String`), or a pair of values\n * as `String` divided by a comma or one (or more) white spaces.<br />\n * The latter is a deprecated method because it leads to confusion and will be\n * removed in v2.<br />\n * Additionally, it accepts additions and subtractions between different units.\n * Note that multiplications and divisions aren't supported.\n *\n * Valid examples are:\n * ```\n * 10\n * '10%'\n * '10, 10'\n * '10%, 10'\n * '10 + 10%'\n * '10 - 5vh + 3%'\n * '-10px + 5vh, 5px - 6%'\n * ```\n * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap\n * > with their reference element, unfortunately, you will have to disable the `flip` modifier.\n * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).\n *\n * @memberof modifiers\n * @inner\n */\n offset: {\n /** @prop {number} order=200 - Index used to define the order of execution */\n order: 200,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: offset,\n /** @prop {Number|String} offset=0\n * The offset value as described in the modifier description\n */\n offset: 0\n },\n\n /**\n * Modifier used to prevent the popper from being positioned outside the boundary.\n *\n * A scenario exists where the reference itself is not within the boundaries.<br />\n * We can say it has \"escaped the boundaries\" — or just \"escaped\".<br />\n * In this case we need to decide whether the popper should either:\n *\n * - detach from the reference and remain \"trapped\" in the boundaries, or\n * - if it should ignore the boundary and \"escape with its reference\"\n *\n * When `escapeWithReference` is set to`true` and reference is completely\n * outside its boundaries, the popper will overflow (or completely leave)\n * the boundaries in order to remain attached to the edge of the reference.\n *\n * @memberof modifiers\n * @inner\n */\n preventOverflow: {\n /** @prop {number} order=300 - Index used to define the order of execution */\n order: 300,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: preventOverflow,\n /**\n * @prop {Array} [priority=['left','right','top','bottom']]\n * Popper will try to prevent overflow following these priorities by default,\n * then, it could overflow on the left and on top of the `boundariesElement`\n */\n priority: ['left', 'right', 'top', 'bottom'],\n /**\n * @prop {number} padding=5\n * Amount of pixel used to define a minimum distance between the boundaries\n * and the popper. This makes sure the popper always has a little padding\n * between the edges of its container\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='scrollParent'\n * Boundaries used by the modifier. Can be `scrollParent`, `window`,\n * `viewport` or any DOM element.\n */\n boundariesElement: 'scrollParent'\n },\n\n /**\n * Modifier used to make sure the reference and its popper stay near each other\n * without leaving any gap between the two. Especially useful when the arrow is\n * enabled and you want to ensure that it points to its reference element.\n * It cares only about the first axis. You can still have poppers with margin\n * between the popper and its reference element.\n * @memberof modifiers\n * @inner\n */\n keepTogether: {\n /** @prop {number} order=400 - Index used to define the order of execution */\n order: 400,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: keepTogether\n },\n\n /**\n * This modifier is used to move the `arrowElement` of the popper to make\n * sure it is positioned between the reference element and its popper element.\n * It will read the outer size of the `arrowElement` node to detect how many\n * pixels of conjunction are needed.\n *\n * It has no effect if no `arrowElement` is provided.\n * @memberof modifiers\n * @inner\n */\n arrow: {\n /** @prop {number} order=500 - Index used to define the order of execution */\n order: 500,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: arrow,\n /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */\n element: '[x-arrow]'\n },\n\n /**\n * Modifier used to flip the popper's placement when it starts to overlap its\n * reference element.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n *\n * **NOTE:** this modifier will interrupt the current update cycle and will\n * restart it if it detects the need to flip the placement.\n * @memberof modifiers\n * @inner\n */\n flip: {\n /** @prop {number} order=600 - Index used to define the order of execution */\n order: 600,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: flip,\n /**\n * @prop {String|Array} behavior='flip'\n * The behavior used to change the popper's placement. It can be one of\n * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid\n * placements (with optional variations)\n */\n behavior: 'flip',\n /**\n * @prop {number} padding=5\n * The popper will flip if it hits the edges of the `boundariesElement`\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='viewport'\n * The element which will define the boundaries of the popper position.\n * The popper will never be placed outside of the defined boundaries\n * (except if `keepTogether` is enabled)\n */\n boundariesElement: 'viewport',\n /**\n * @prop {Boolean} flipVariations=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the reference element overlaps its boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariations: false,\n /**\n * @prop {Boolean} flipVariationsByContent=false\n * The popper will switch placement variation between `-start` and `-end` when\n * the popper element overlaps its reference boundaries.\n *\n * The original placement should have a set variation.\n */\n flipVariationsByContent: false\n },\n\n /**\n * Modifier used to make the popper flow toward the inner of the reference element.\n * By default, when this modifier is disabled, the popper will be placed outside\n * the reference element.\n * @memberof modifiers\n * @inner\n */\n inner: {\n /** @prop {number} order=700 - Index used to define the order of execution */\n order: 700,\n /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */\n enabled: false,\n /** @prop {ModifierFn} */\n fn: inner\n },\n\n /**\n * Modifier used to hide the popper when its reference element is outside of the\n * popper boundaries. It will set a `x-out-of-boundaries` attribute which can\n * be used to hide with a CSS selector the popper when its reference is\n * out of boundaries.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n * @memberof modifiers\n * @inner\n */\n hide: {\n /** @prop {number} order=800 - Index used to define the order of execution */\n order: 800,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: hide\n },\n\n /**\n * Computes the style that will be applied to the popper element to gets\n * properly positioned.\n *\n * Note that this modifier will not touch the DOM, it just prepares the styles\n * so that `applyStyle` modifier can apply it. This separation is useful\n * in case you need to replace `applyStyle` with a custom implementation.\n *\n * This modifier has `850` as `order` value to maintain backward compatibility\n * with previous versions of Popper.js. Expect the modifiers ordering method\n * to change in future major versions of the library.\n *\n * @memberof modifiers\n * @inner\n */\n computeStyle: {\n /** @prop {number} order=850 - Index used to define the order of execution */\n order: 850,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: computeStyle,\n /**\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: true,\n /**\n * @prop {string} [x='bottom']\n * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.\n * Change this if your popper should grow in a direction different from `bottom`\n */\n x: 'bottom',\n /**\n * @prop {string} [x='left']\n * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.\n * Change this if your popper should grow in a direction different from `right`\n */\n y: 'right'\n },\n\n /**\n * Applies the computed styles to the popper element.\n *\n * All the DOM manipulations are limited to this modifier. This is useful in case\n * you want to integrate Popper.js inside a framework or view library and you\n * want to delegate all the DOM manipulations to it.\n *\n * Note that if you disable this modifier, you must make sure the popper element\n * has its position set to `absolute` before Popper.js can do its work!\n *\n * Just disable this modifier and define your own to achieve the desired effect.\n *\n * @memberof modifiers\n * @inner\n */\n applyStyle: {\n /** @prop {number} order=900 - Index used to define the order of execution */\n order: 900,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: applyStyle,\n /** @prop {Function} */\n onLoad: applyStyleOnLoad,\n /**\n * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3D transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties\n */\n gpuAcceleration: undefined\n }\n};\n\n/**\n * The `dataObject` is an object containing all the information used by Popper.js.\n * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.\n * @name dataObject\n * @property {Object} data.instance The Popper.js instance\n * @property {String} data.placement Placement applied to popper\n * @property {String} data.originalPlacement Placement originally defined on init\n * @property {Boolean} data.flipped True if popper has been flipped by flip modifier\n * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper\n * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier\n * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.boundaries Offsets of the popper boundaries\n * @property {Object} data.offsets The measurements of popper, reference and arrow elements\n * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0\n */\n\n/**\n * Default options provided to Popper.js constructor.<br />\n * These can be overridden using the `options` argument of Popper.js.<br />\n * To override an option, simply pass an object with the same\n * structure of the `options` object, as the 3rd argument. For example:\n * ```\n * new Popper(ref, pop, {\n * modifiers: {\n * preventOverflow: { enabled: false }\n * }\n * })\n * ```\n * @type {Object}\n * @static\n * @memberof Popper\n */\nvar Defaults = {\n /**\n * Popper's placement.\n * @prop {Popper.placements} placement='bottom'\n */\n placement: 'bottom',\n\n /**\n * Set this to true if you want popper to position it self in 'fixed' mode\n * @prop {Boolean} positionFixed=false\n */\n positionFixed: false,\n\n /**\n * Whether events (resize, scroll) are initially enabled.\n * @prop {Boolean} eventsEnabled=true\n */\n eventsEnabled: true,\n\n /**\n * Set to true if you want to automatically remove the popper when\n * you call the `destroy` method.\n * @prop {Boolean} removeOnDestroy=false\n */\n removeOnDestroy: false,\n\n /**\n * Callback called when the popper is created.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onCreate}\n */\n onCreate: function onCreate() {},\n\n /**\n * Callback called when the popper is updated. This callback is not called\n * on the initialization/creation of the popper, but only on subsequent\n * updates.<br />\n * By default, it is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onUpdate}\n */\n onUpdate: function onUpdate() {},\n\n /**\n * List of modifiers used to modify the offsets before they are applied to the popper.\n * They provide most of the functionalities of Popper.js.\n * @prop {modifiers}\n */\n modifiers: modifiers\n};\n\n/**\n * @callback onCreate\n * @param {dataObject} data\n */\n\n/**\n * @callback onUpdate\n * @param {dataObject} data\n */\n\n// Utils\n// Methods\nvar Popper = function () {\n /**\n * Creates a new Popper.js instance.\n * @class Popper\n * @param {Element|referenceObject} reference - The reference element used to position the popper\n * @param {Element} popper - The HTML / XML element used as the popper\n * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)\n * @return {Object} instance - The generated Popper.js instance\n */\n function Popper(reference, popper) {\n var _this = this;\n\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n classCallCheck(this, Popper);\n\n this.scheduleUpdate = function () {\n return requestAnimationFrame(_this.update);\n };\n\n // make update() debounced, so that it only runs at most once-per-tick\n this.update = debounce(this.update.bind(this));\n\n // with {} we create a new object with the options inside it\n this.options = _extends({}, Popper.Defaults, options);\n\n // init state\n this.state = {\n isDestroyed: false,\n isCreated: false,\n scrollParents: []\n };\n\n // get reference and popper elements (allow jQuery wrappers)\n this.reference = reference && reference.jquery ? reference[0] : reference;\n this.popper = popper && popper.jquery ? popper[0] : popper;\n\n // Deep merge modifiers options\n this.options.modifiers = {};\n Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {\n _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});\n });\n\n // Refactoring modifiers' list (Object => Array)\n this.modifiers = Object.keys(this.options.modifiers).map(function (name) {\n return _extends({\n name: name\n }, _this.options.modifiers[name]);\n })\n // sort the modifiers by order\n .sort(function (a, b) {\n return a.order - b.order;\n });\n\n // modifiers have the ability to execute arbitrary code when Popper.js get inited\n // such code is executed in the same order of its modifier\n // they could add new properties to their options configuration\n // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!\n this.modifiers.forEach(function (modifierOptions) {\n if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {\n modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);\n }\n });\n\n // fire the first update to position the popper in the right place\n this.update();\n\n var eventsEnabled = this.options.eventsEnabled;\n if (eventsEnabled) {\n // setup event listeners, they will take care of update the position in specific situations\n this.enableEventListeners();\n }\n\n this.state.eventsEnabled = eventsEnabled;\n }\n\n // We can't use class properties because they don't get listed in the\n // class prototype and break stuff like Sinon stubs\n\n\n createClass(Popper, [{\n key: 'update',\n value: function update$$1() {\n return update.call(this);\n }\n }, {\n key: 'destroy',\n value: function destroy$$1() {\n return destroy.call(this);\n }\n }, {\n key: 'enableEventListeners',\n value: function enableEventListeners$$1() {\n return enableEventListeners.call(this);\n }\n }, {\n key: 'disableEventListeners',\n value: function disableEventListeners$$1() {\n return disableEventListeners.call(this);\n }\n\n /**\n * Schedules an update. It will run on the next UI update available.\n * @method scheduleUpdate\n * @memberof Popper\n */\n\n\n /**\n * Collection of utilities useful when writing custom modifiers.\n * Starting from version 1.7, this method is available only if you\n * include `popper-utils.js` before `popper.js`.\n *\n * **DEPRECATION**: This way to access PopperUtils is deprecated\n * and will be removed in v2! Use the PopperUtils module directly instead.\n * Due to the high instability of the methods contained in Utils, we can't\n * guarantee them to follow semver. Use them at your own risk!\n * @static\n * @private\n * @type {Object}\n * @deprecated since version 1.8\n * @member Utils\n * @memberof Popper\n */\n\n }]);\n return Popper;\n}();\n\n/**\n * The `referenceObject` is an object that provides an interface compatible with Popper.js\n * and lets you use it as replacement of a real DOM node.<br />\n * You can use this method to position a popper relatively to a set of coordinates\n * in case you don't have a DOM node to use as reference.\n *\n * ```\n * new Popper(referenceObject, popperNode);\n * ```\n *\n * NB: This feature isn't supported in Internet Explorer 10.\n * @name referenceObject\n * @property {Function} data.getBoundingClientRect\n * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.\n * @property {number} data.clientWidth\n * An ES6 getter that will return the width of the virtual reference element.\n * @property {number} data.clientHeight\n * An ES6 getter that will return the height of the virtual reference element.\n */\n\n\nPopper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;\nPopper.placements = placements;\nPopper.Defaults = Defaults;\n\nexport default Popper;\n//# sourceMappingURL=popper.js.map\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Totally disable Popper for Dropdowns in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n customClass: '(string|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n customClass: '',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n $(tip).addClass(this.config.customClass)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.js b/vendor/twbs/bootstrap/dist/js/bootstrap.js index 8b95e652f..f46c53e6f 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.js +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.js @@ -1,6 +1,6 @@ /*! - * Bootstrap v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { @@ -56,7 +56,7 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): util.js + * Bootstrap (v4.6.0): util.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -235,7 +235,7 @@ */ var NAME = 'alert'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.alert'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -391,7 +391,7 @@ */ var NAME$1 = 'button'; - var VERSION$1 = '4.5.3'; + var VERSION$1 = '4.6.0'; var DATA_KEY$1 = 'bs.button'; var EVENT_KEY$1 = "." + DATA_KEY$1; var DATA_API_KEY$1 = '.data-api'; @@ -590,7 +590,7 @@ */ var NAME$2 = 'carousel'; - var VERSION$2 = '4.5.3'; + var VERSION$2 = '4.6.0'; var DATA_KEY$2 = 'bs.carousel'; var EVENT_KEY$2 = "." + DATA_KEY$2; var DATA_API_KEY$2 = '.data-api'; @@ -730,6 +730,8 @@ } if (this._config.interval && !this._isPaused) { + this._updateInterval(); + this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); } }; @@ -971,6 +973,23 @@ } }; + _proto._updateInterval = function _updateInterval() { + var element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM); + + if (!element) { + return; + } + + var elementInterval = parseInt(element.getAttribute('data-interval'), 10); + + if (elementInterval) { + this._config.defaultInterval = this._config.defaultInterval || this._config.interval; + this._config.interval = elementInterval; + } else { + this._config.interval = this._config.defaultInterval || this._config.interval; + } + }; + _proto._slide = function _slide(direction, element) { var _this4 = this; @@ -1021,6 +1040,7 @@ this._setActiveIndicatorElement(nextElement); + this._activeElement = nextElement; var slidEvent = $__default['default'].Event(EVENT_SLID, { relatedTarget: nextElement, direction: eventDirectionName, @@ -1033,15 +1053,6 @@ Util.reflow(nextElement); $__default['default'](activeElement).addClass(directionalClassName); $__default['default'](nextElement).addClass(directionalClassName); - var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10); - - if (nextElementInterval) { - this._config.defaultInterval = this._config.defaultInterval || this._config.interval; - this._config.interval = nextElementInterval; - } else { - this._config.interval = this._config.defaultInterval || this._config.interval; - } - var transitionDuration = Util.getTransitionDurationFromElement(activeElement); $__default['default'](activeElement).one(Util.TRANSITION_END, function () { $__default['default'](nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE$1); @@ -1178,7 +1189,7 @@ */ var NAME$3 = 'collapse'; - var VERSION$3 = '4.5.3'; + var VERSION$3 = '4.6.0'; var DATA_KEY$3 = 'bs.collapse'; var EVENT_KEY$3 = "." + DATA_KEY$3; var DATA_API_KEY$3 = '.data-api'; @@ -1527,7 +1538,7 @@ */ var NAME$4 = 'dropdown'; - var VERSION$4 = '4.5.3'; + var VERSION$4 = '4.6.0'; var DATA_KEY$4 = 'bs.dropdown'; var EVENT_KEY$4 = "." + DATA_KEY$4; var DATA_API_KEY$4 = '.data-api'; @@ -1644,7 +1655,7 @@ if (showEvent.isDefaultPrevented()) { return; - } // Disable totally Popper.js for Dropdown in Navbar + } // Totally disable Popper for Dropdowns in Navbar if (!this._inNavbar && usePopper) { @@ -1653,7 +1664,7 @@ * Popper - https://popper.js.org */ if (typeof Popper__default['default'] === 'undefined') { - throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); + throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)'); } var referenceElement = this._element; @@ -1821,7 +1832,7 @@ boundariesElement: this._config.boundary } } - }; // Disable Popper.js if we have a static display + }; // Disable Popper if we have a static display if (this._config.display === 'static') { popperConfig.modifiers.applyStyle = { @@ -2041,7 +2052,7 @@ */ var NAME$5 = 'modal'; - var VERSION$5 = '4.5.3'; + var VERSION$5 = '4.6.0'; var DATA_KEY$5 = 'bs.modal'; var EVENT_KEY$5 = "." + DATA_KEY$5; var DATA_API_KEY$5 = '.data-api'; @@ -2241,38 +2252,34 @@ _proto._triggerBackdropTransition = function _triggerBackdropTransition() { var _this3 = this; - if (this._config.backdrop === 'static') { - var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED); - $__default['default'](this._element).trigger(hideEventPrevented); + var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED); + $__default['default'](this._element).trigger(hideEventPrevented); - if (hideEventPrevented.isDefaultPrevented()) { - return; - } + if (hideEventPrevented.isDefaultPrevented()) { + return; + } - var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; - if (!isModalOverflowing) { - this._element.style.overflowY = 'hidden'; - } + if (!isModalOverflowing) { + this._element.style.overflowY = 'hidden'; + } - this._element.classList.add(CLASS_NAME_STATIC); + this._element.classList.add(CLASS_NAME_STATIC); - var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog); - $__default['default'](this._element).off(Util.TRANSITION_END); - $__default['default'](this._element).one(Util.TRANSITION_END, function () { - _this3._element.classList.remove(CLASS_NAME_STATIC); + var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog); + $__default['default'](this._element).off(Util.TRANSITION_END); + $__default['default'](this._element).one(Util.TRANSITION_END, function () { + _this3._element.classList.remove(CLASS_NAME_STATIC); - if (!isModalOverflowing) { - $__default['default'](_this3._element).one(Util.TRANSITION_END, function () { - _this3._element.style.overflowY = ''; - }).emulateTransitionEnd(_this3._element, modalTransitionDuration); - } - }).emulateTransitionEnd(modalTransitionDuration); + if (!isModalOverflowing) { + $__default['default'](_this3._element).one(Util.TRANSITION_END, function () { + _this3._element.style.overflowY = ''; + }).emulateTransitionEnd(_this3._element, modalTransitionDuration); + } + }).emulateTransitionEnd(modalTransitionDuration); - this._element.focus(); - } else { - this.hide(); - } + this._element.focus(); }; _proto._showElement = function _showElement(relatedTarget) { @@ -2427,7 +2434,11 @@ return; } - _this9._triggerBackdropTransition(); + if (_this9._config.backdrop === 'static') { + _this9._triggerBackdropTransition(); + } else { + _this9.hide(); + } }); if (animate) { @@ -2651,7 +2662,7 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): tools/sanitizer.js + * Bootstrap (v4.6.0): tools/sanitizer.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -2777,7 +2788,7 @@ */ var NAME$6 = 'tooltip'; - var VERSION$6 = '4.5.3'; + var VERSION$6 = '4.6.0'; var DATA_KEY$6 = 'bs.tooltip'; var EVENT_KEY$6 = "." + DATA_KEY$6; var JQUERY_NO_CONFLICT$6 = $__default['default'].fn[NAME$6]; @@ -2797,6 +2808,7 @@ container: '(string|element|boolean)', fallbackPlacement: '(string|array)', boundary: '(string|element)', + customClass: '(string|function)', sanitize: 'boolean', sanitizeFn: '(null|function)', whiteList: 'object', @@ -2822,6 +2834,7 @@ container: false, fallbackPlacement: 'flip', boundary: 'scrollParent', + customClass: '', sanitize: true, sanitizeFn: null, whiteList: DefaultWhitelist, @@ -2858,7 +2871,7 @@ var Tooltip = /*#__PURE__*/function () { function Tooltip(element, config) { if (typeof Popper__default['default'] === 'undefined') { - throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); + throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); } // private @@ -2992,7 +3005,8 @@ $__default['default'](this.element).trigger(this.constructor.Event.INSERTED); this._popper = new Popper__default['default'](this.element, tip, this._getPopperConfig(attachment)); - $__default['default'](tip).addClass(CLASS_NAME_SHOW$4); // If this is a touch-enabled device we add extra + $__default['default'](tip).addClass(CLASS_NAME_SHOW$4); + $__default['default'](tip).addClass(this.config.customClass); // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html @@ -3490,7 +3504,7 @@ */ var NAME$7 = 'popover'; - var VERSION$7 = '4.5.3'; + var VERSION$7 = '4.6.0'; var DATA_KEY$7 = 'bs.popover'; var EVENT_KEY$7 = "." + DATA_KEY$7; var JQUERY_NO_CONFLICT$7 = $__default['default'].fn[NAME$7]; @@ -3670,7 +3684,7 @@ */ var NAME$8 = 'scrollspy'; - var VERSION$8 = '4.5.3'; + var VERSION$8 = '4.6.0'; var DATA_KEY$8 = 'bs.scrollspy'; var EVENT_KEY$8 = "." + DATA_KEY$8; var DATA_API_KEY$6 = '.data-api'; @@ -3962,7 +3976,7 @@ */ var NAME$9 = 'tab'; - var VERSION$9 = '4.5.3'; + var VERSION$9 = '4.6.0'; var DATA_KEY$9 = 'bs.tab'; var EVENT_KEY$9 = "." + DATA_KEY$9; var DATA_API_KEY$7 = '.data-api'; @@ -4188,7 +4202,7 @@ */ var NAME$a = 'toast'; - var VERSION$a = '4.5.3'; + var VERSION$a = '4.6.0'; var DATA_KEY$a = 'bs.toast'; var EVENT_KEY$a = "." + DATA_KEY$a; var JQUERY_NO_CONFLICT$a = $__default['default'].fn[NAME$a]; diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.js.map b/vendor/twbs/bootstrap/dist/js/bootstrap.js.map index 3fb136f51..252423aaa 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.js.map +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.js.map @@ -1 +1 @@ -{"version":3,"file":"bootstrap.js","sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = nextElementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper.js (https://popper.js.org/)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n if (this._config.backdrop === 'static') {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n } else {\n this.hide()\n }\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper.js (https://popper.js.org/)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"],"names":["TRANSITION_END","MAX_UID","MILLISECONDS_MULTIPLIER","toType","obj","toString","call","match","toLowerCase","getSpecialTransitionEndEvent","bindType","delegateType","handle","event","$","target","is","handleObj","handler","apply","arguments","undefined","transitionEndEmulator","duration","called","one","Util","setTimeout","triggerTransitionEnd","setTransitionEndSupport","fn","emulateTransitionEnd","special","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","expectedTypes","value","valueType","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","jquery","minMajor","ltMajor","minMinor","minPatch","maxMajor","NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","SELECTOR_DISMISS","EVENT_CLOSE","EVENT_CLOSED","EVENT_CLICK_DATA_API","CLASS_NAME_ALERT","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","_element","close","rootElement","_getRootElement","customEvent","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","CLASS_NAME_ACTIVE","CLASS_NAME_BUTTON","CLASS_NAME_FOCUS","SELECTOR_DATA_TOGGLE_CARROT","SELECTOR_DATA_TOGGLES","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_TOGGLES_BUTTONS","SELECTOR_INPUT","SELECTOR_ACTIVE","SELECTOR_BUTTON","EVENT_FOCUS_BLUR_DATA_API","EVENT_LOAD_DATA_API","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","ARROW_LEFT_KEYCODE","ARROW_RIGHT_KEYCODE","TOUCHEVENT_COMPAT_WAIT","SWIPE_THRESHOLD","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","DIRECTION_NEXT","DIRECTION_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLIDE","EVENT_SLID","EVENT_KEYDOWN","EVENT_MOUSEENTER","EVENT_MOUSELEAVE","EVENT_TOUCHSTART","EVENT_TOUCHMOVE","EVENT_TOUCHEND","EVENT_POINTERDOWN","EVENT_POINTERUP","EVENT_DRAG_START","CLASS_NAME_CAROUSEL","CLASS_NAME_SLIDE","CLASS_NAME_RIGHT","CLASS_NAME_LEFT","CLASS_NAME_NEXT","CLASS_NAME_PREV","CLASS_NAME_POINTER_EVENT","SELECTOR_ACTIVE_ITEM","SELECTOR_ITEM","SELECTOR_ITEM_IMG","SELECTOR_NEXT_PREV","SELECTOR_INDICATORS","SELECTOR_DATA_SLIDE","SELECTOR_DATA_RIDE","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_handleSwipe","absDeltax","abs","_keydown","_addTouchEventListeners","start","originalEvent","pointerType","clientX","touches","move","end","clearTimeout","e","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","isGoingToWrap","delta","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","activeElementIndex","nextElement","nextElementIndex","isCycling","directionalClassName","orderClassName","slidEvent","nextElementInterval","parseInt","defaultInterval","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","EVENT_SHOW","EVENT_SHOWN","EVENT_HIDE","EVENT_HIDDEN","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","CLASS_NAME_COLLAPSED","DIMENSION_WIDTH","DIMENSION_HEIGHT","SELECTOR_ACTIVES","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","complete","capitalizedDimension","scrollSize","getBoundingClientRect","triggerArrayLength","$elem","isTransitioning","hasWidth","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","ESCAPE_KEYCODE","SPACE_KEYCODE","TAB_KEYCODE","ARROW_UP_KEYCODE","ARROW_DOWN_KEYCODE","RIGHT_MOUSE_BUTTON_WHICH","REGEXP_KEYDOWN","EVENT_CLICK","EVENT_KEYDOWN_DATA_API","EVENT_KEYUP_DATA_API","CLASS_NAME_DISABLED","CLASS_NAME_DROPUP","CLASS_NAME_DROPRIGHT","CLASS_NAME_DROPLEFT","CLASS_NAME_MENURIGHT","CLASS_NAME_POSITION_STATIC","SELECTOR_FORM_CHILD","SELECTOR_MENU","SELECTOR_NAVBAR_NAV","SELECTOR_VISIBLE_ITEMS","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","offset","flip","boundary","reference","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","Popper","referenceElement","_getPopperConfig","body","noop","hideEvent","destroy","update","scheduleUpdate","stopPropagation","constructor","_getPlacement","$parentDropdown","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","backdrop","EVENT_HIDE_PREVENTED","EVENT_FOCUSIN","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_KEYDOWN_DISMISS","EVENT_MOUSEUP_DISMISS","EVENT_MOUSEDOWN_DISMISS","CLASS_NAME_SCROLLABLE","CLASS_NAME_SCROLLBAR_MEASURER","CLASS_NAME_BACKDROP","CLASS_NAME_OPEN","CLASS_NAME_STATIC","SELECTOR_DIALOG","SELECTOR_MODAL_BODY","SELECTOR_DATA_DISMISS","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","forEach","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","clientHeight","overflowY","modalTransitionDuration","modalBody","Node","ELEMENT_NODE","appendChild","removeAttribute","scrollTop","_enforceFocus","shownEvent","transitionComplete","has","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","round","left","right","innerWidth","_getScrollbarWidth","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","uriAttrs","ARIA_ATTRIBUTE_PATTERN","DefaultWhitelist","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","allowedAttributeList","attrName","nodeName","nodeValue","regExp","attrRegex","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","domParser","DOMParser","createdDocument","parseFromString","whitelistKeys","keys","el","elName","attributeList","attributes","whitelistedAttributes","concat","innerHTML","CLASS_PREFIX","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","html","container","fallbackPlacement","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HOVER_STATE_SHOW","HOVER_STATE_OUT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","SELECTOR_TOOLTIP_INNER","SELECTOR_ARROW","TRIGGER_HOVER","TRIGGER_FOCUS","TRIGGER_CLICK","TRIGGER_MANUAL","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","ownerDocument","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","_fixTransition","prevHoverState","_cleanTipClass","getTitle","setElementContent","content","empty","append","text","defaultBsConfig","behavior","arrow","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","find","triggers","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","SELECTOR_TITLE","SELECTOR_CONTENT","Popover","_getContent","method","EVENT_ACTIVATE","EVENT_SCROLL","CLASS_NAME_DROPDOWN_ITEM","SELECTOR_DATA_SPY","SELECTOR_NAV_LIST_GROUP","SELECTOR_NAV_LINKS","SELECTOR_NAV_ITEMS","SELECTOR_LIST_ITEMS","SELECTOR_DROPDOWN","SELECTOR_DROPDOWN_ITEMS","SELECTOR_DROPDOWN_TOGGLE","METHOD_OFFSET","METHOD_POSITION","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targets","map","targetSelector","targetBCR","height","top","sort","pageYOffset","max","_getOffsetHeight","innerHeight","maxScroll","_activate","_clear","isActiveTarget","queries","$link","parents","node","scrollSpys","scrollSpysLength","$spy","CLASS_NAME_DROPDOWN_MENU","SELECTOR_ACTIVE_UL","SELECTOR_DROPDOWN_ACTIVE_CHILD","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","activeElements","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","CLASS_NAME_HIDE","CLASS_NAME_SHOWING","autohide","Toast","_clearTimeout","_close"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"bootstrap.js","sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._updateInterval()\n\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n if (!element) {\n return\n }\n\n const elementInterval = parseInt(element.getAttribute('data-interval'), 10)\n\n if (elementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = elementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n this._activeElement = nextElement\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Totally disable Popper for Dropdowns in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n customClass: '(string|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n customClass: '',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n $(tip).addClass(this.config.customClass)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"],"names":["TRANSITION_END","MAX_UID","MILLISECONDS_MULTIPLIER","toType","obj","toString","call","match","toLowerCase","getSpecialTransitionEndEvent","bindType","delegateType","handle","event","$","target","is","handleObj","handler","apply","arguments","undefined","transitionEndEmulator","duration","called","one","Util","setTimeout","triggerTransitionEnd","setTransitionEndSupport","fn","emulateTransitionEnd","special","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","expectedTypes","value","valueType","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","jquery","minMajor","ltMajor","minMinor","minPatch","maxMajor","NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","SELECTOR_DISMISS","EVENT_CLOSE","EVENT_CLOSED","EVENT_CLICK_DATA_API","CLASS_NAME_ALERT","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","_element","close","rootElement","_getRootElement","customEvent","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","CLASS_NAME_ACTIVE","CLASS_NAME_BUTTON","CLASS_NAME_FOCUS","SELECTOR_DATA_TOGGLE_CARROT","SELECTOR_DATA_TOGGLES","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_TOGGLES_BUTTONS","SELECTOR_INPUT","SELECTOR_ACTIVE","SELECTOR_BUTTON","EVENT_FOCUS_BLUR_DATA_API","EVENT_LOAD_DATA_API","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","ARROW_LEFT_KEYCODE","ARROW_RIGHT_KEYCODE","TOUCHEVENT_COMPAT_WAIT","SWIPE_THRESHOLD","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","DIRECTION_NEXT","DIRECTION_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLIDE","EVENT_SLID","EVENT_KEYDOWN","EVENT_MOUSEENTER","EVENT_MOUSELEAVE","EVENT_TOUCHSTART","EVENT_TOUCHMOVE","EVENT_TOUCHEND","EVENT_POINTERDOWN","EVENT_POINTERUP","EVENT_DRAG_START","CLASS_NAME_CAROUSEL","CLASS_NAME_SLIDE","CLASS_NAME_RIGHT","CLASS_NAME_LEFT","CLASS_NAME_NEXT","CLASS_NAME_PREV","CLASS_NAME_POINTER_EVENT","SELECTOR_ACTIVE_ITEM","SELECTOR_ITEM","SELECTOR_ITEM_IMG","SELECTOR_NEXT_PREV","SELECTOR_INDICATORS","SELECTOR_DATA_SLIDE","SELECTOR_DATA_RIDE","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","_updateInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_handleSwipe","absDeltax","abs","_keydown","_addTouchEventListeners","start","originalEvent","pointerType","clientX","touches","move","end","clearTimeout","e","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","isGoingToWrap","delta","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","elementInterval","parseInt","defaultInterval","activeElementIndex","nextElement","nextElementIndex","isCycling","directionalClassName","orderClassName","slidEvent","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","EVENT_SHOW","EVENT_SHOWN","EVENT_HIDE","EVENT_HIDDEN","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","CLASS_NAME_COLLAPSED","DIMENSION_WIDTH","DIMENSION_HEIGHT","SELECTOR_ACTIVES","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","complete","capitalizedDimension","scrollSize","getBoundingClientRect","triggerArrayLength","$elem","isTransitioning","hasWidth","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","ESCAPE_KEYCODE","SPACE_KEYCODE","TAB_KEYCODE","ARROW_UP_KEYCODE","ARROW_DOWN_KEYCODE","RIGHT_MOUSE_BUTTON_WHICH","REGEXP_KEYDOWN","EVENT_CLICK","EVENT_KEYDOWN_DATA_API","EVENT_KEYUP_DATA_API","CLASS_NAME_DISABLED","CLASS_NAME_DROPUP","CLASS_NAME_DROPRIGHT","CLASS_NAME_DROPLEFT","CLASS_NAME_MENURIGHT","CLASS_NAME_POSITION_STATIC","SELECTOR_FORM_CHILD","SELECTOR_MENU","SELECTOR_NAVBAR_NAV","SELECTOR_VISIBLE_ITEMS","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","offset","flip","boundary","reference","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","Popper","referenceElement","_getPopperConfig","body","noop","hideEvent","destroy","update","scheduleUpdate","stopPropagation","constructor","_getPlacement","$parentDropdown","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","backdrop","EVENT_HIDE_PREVENTED","EVENT_FOCUSIN","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_KEYDOWN_DISMISS","EVENT_MOUSEUP_DISMISS","EVENT_MOUSEDOWN_DISMISS","CLASS_NAME_SCROLLABLE","CLASS_NAME_SCROLLBAR_MEASURER","CLASS_NAME_BACKDROP","CLASS_NAME_OPEN","CLASS_NAME_STATIC","SELECTOR_DIALOG","SELECTOR_MODAL_BODY","SELECTOR_DATA_DISMISS","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","forEach","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","clientHeight","overflowY","modalTransitionDuration","modalBody","Node","ELEMENT_NODE","appendChild","removeAttribute","scrollTop","_enforceFocus","shownEvent","transitionComplete","has","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","round","left","right","innerWidth","_getScrollbarWidth","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","uriAttrs","ARIA_ATTRIBUTE_PATTERN","DefaultWhitelist","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","allowedAttributeList","attrName","nodeName","nodeValue","regExp","attrRegex","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","domParser","DOMParser","createdDocument","parseFromString","whitelistKeys","keys","el","elName","attributeList","attributes","whitelistedAttributes","concat","innerHTML","CLASS_PREFIX","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","html","container","fallbackPlacement","customClass","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HOVER_STATE_SHOW","HOVER_STATE_OUT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","SELECTOR_TOOLTIP_INNER","SELECTOR_ARROW","TRIGGER_HOVER","TRIGGER_FOCUS","TRIGGER_CLICK","TRIGGER_MANUAL","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","ownerDocument","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","_fixTransition","prevHoverState","_cleanTipClass","getTitle","setElementContent","content","empty","append","text","defaultBsConfig","behavior","arrow","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","find","triggers","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","SELECTOR_TITLE","SELECTOR_CONTENT","Popover","_getContent","method","EVENT_ACTIVATE","EVENT_SCROLL","CLASS_NAME_DROPDOWN_ITEM","SELECTOR_DATA_SPY","SELECTOR_NAV_LIST_GROUP","SELECTOR_NAV_LINKS","SELECTOR_NAV_ITEMS","SELECTOR_LIST_ITEMS","SELECTOR_DROPDOWN","SELECTOR_DROPDOWN_ITEMS","SELECTOR_DROPDOWN_TOGGLE","METHOD_OFFSET","METHOD_POSITION","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targets","map","targetSelector","targetBCR","height","top","sort","pageYOffset","max","_getOffsetHeight","innerHeight","maxScroll","_activate","_clear","isActiveTarget","queries","$link","parents","node","scrollSpys","scrollSpysLength","$spy","CLASS_NAME_DROPDOWN_MENU","SELECTOR_ACTIVE_UL","SELECTOR_DROPDOWN_ACTIVE_CHILD","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","activeElements","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","CLASS_NAME_HIDE","CLASS_NAME_SHOWING","autohide","Toast","_clearTimeout","_close"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;EAIA;EACA;EACA;EACA;EACA;;EAEA,IAAMA,cAAc,GAAG,eAAvB;EACA,IAAMC,OAAO,GAAG,OAAhB;EACA,IAAMC,uBAAuB,GAAG,IAAhC;;EAGA,SAASC,MAAT,CAAgBC,GAAhB,EAAqB;EACnB,MAAIA,GAAG,KAAK,IAAR,IAAgB,OAAOA,GAAP,KAAe,WAAnC,EAAgD;EAC9C,gBAAUA,GAAV;EACD;;EAED,SAAO,GAAGC,QAAH,CAAYC,IAAZ,CAAiBF,GAAjB,EAAsBG,KAAtB,CAA4B,aAA5B,EAA2C,CAA3C,EAA8CC,WAA9C,EAAP;EACD;;EAED,SAASC,4BAAT,GAAwC;EACtC,SAAO;EACLC,IAAAA,QAAQ,EAAEV,cADL;EAELW,IAAAA,YAAY,EAAEX,cAFT;EAGLY,IAAAA,MAHK,kBAGEC,KAHF,EAGS;EACZ,UAAIC,qBAAC,CAACD,KAAK,CAACE,MAAP,CAAD,CAAgBC,EAAhB,CAAmB,IAAnB,CAAJ,EAA8B;EAC5B,eAAOH,KAAK,CAACI,SAAN,CAAgBC,OAAhB,CAAwBC,KAAxB,CAA8B,IAA9B,EAAoCC,SAApC,CAAP,CAD4B;EAE7B;;EAED,aAAOC,SAAP;EACD;EATI,GAAP;EAWD;;EAED,SAASC,qBAAT,CAA+BC,QAA/B,EAAyC;EAAA;;EACvC,MAAIC,MAAM,GAAG,KAAb;EAEAV,EAAAA,qBAAC,CAAC,IAAD,CAAD,CAAQW,GAAR,CAAYC,IAAI,CAAC1B,cAAjB,EAAiC,YAAM;EACrCwB,IAAAA,MAAM,GAAG,IAAT;EACD,GAFD;EAIAG,EAAAA,UAAU,CAAC,YAAM;EACf,QAAI,CAACH,MAAL,EAAa;EACXE,MAAAA,IAAI,CAACE,oBAAL,CAA0B,KAA1B;EACD;EACF,GAJS,EAIPL,QAJO,CAAV;EAMA,SAAO,IAAP;EACD;;EAED,SAASM,uBAAT,GAAmC;EACjCf,EAAAA,qBAAC,CAACgB,EAAF,CAAKC,oBAAL,GAA4BT,qBAA5B;EACAR,EAAAA,qBAAC,CAACD,KAAF,CAAQmB,OAAR,CAAgBN,IAAI,CAAC1B,cAArB,IAAuCS,4BAA4B,EAAnE;EACD;EAED;EACA;EACA;EACA;EACA;;;MAEMiB,IAAI,GAAG;EACX1B,EAAAA,cAAc,EAAE,iBADL;EAGXiC,EAAAA,MAHW,kBAGJC,MAHI,EAGI;EACb,OAAG;EACDA,MAAAA,MAAM,IAAI,CAAC,EAAEC,IAAI,CAACC,MAAL,KAAgBnC,OAAlB,CAAX,CADC;EAEF,KAFD,QAESoC,QAAQ,CAACC,cAAT,CAAwBJ,MAAxB,CAFT;;EAIA,WAAOA,MAAP;EACD,GATU;EAWXK,EAAAA,sBAXW,kCAWYC,OAXZ,EAWqB;EAC9B,QAAIC,QAAQ,GAAGD,OAAO,CAACE,YAAR,CAAqB,aAArB,CAAf;;EAEA,QAAI,CAACD,QAAD,IAAaA,QAAQ,KAAK,GAA9B,EAAmC;EACjC,UAAME,QAAQ,GAAGH,OAAO,CAACE,YAAR,CAAqB,MAArB,CAAjB;EACAD,MAAAA,QAAQ,GAAGE,QAAQ,IAAIA,QAAQ,KAAK,GAAzB,GAA+BA,QAAQ,CAACC,IAAT,EAA/B,GAAiD,EAA5D;EACD;;EAED,QAAI;EACF,aAAOP,QAAQ,CAACQ,aAAT,CAAuBJ,QAAvB,IAAmCA,QAAnC,GAA8C,IAArD;EACD,KAFD,CAEE,OAAOK,CAAP,EAAU;EACV,aAAO,IAAP;EACD;EACF,GAxBU;EA0BXC,EAAAA,gCA1BW,4CA0BsBP,OA1BtB,EA0B+B;EACxC,QAAI,CAACA,OAAL,EAAc;EACZ,aAAO,CAAP;EACD,KAHuC;;;EAMxC,QAAIQ,kBAAkB,GAAGlC,qBAAC,CAAC0B,OAAD,CAAD,CAAWS,GAAX,CAAe,qBAAf,CAAzB;EACA,QAAIC,eAAe,GAAGpC,qBAAC,CAAC0B,OAAD,CAAD,CAAWS,GAAX,CAAe,kBAAf,CAAtB;EAEA,QAAME,uBAAuB,GAAGC,UAAU,CAACJ,kBAAD,CAA1C;EACA,QAAMK,oBAAoB,GAAGD,UAAU,CAACF,eAAD,CAAvC,CAVwC;;EAaxC,QAAI,CAACC,uBAAD,IAA4B,CAACE,oBAAjC,EAAuD;EACrD,aAAO,CAAP;EACD,KAfuC;;;EAkBxCL,IAAAA,kBAAkB,GAAGA,kBAAkB,CAACM,KAAnB,CAAyB,GAAzB,EAA8B,CAA9B,CAArB;EACAJ,IAAAA,eAAe,GAAGA,eAAe,CAACI,KAAhB,CAAsB,GAAtB,EAA2B,CAA3B,CAAlB;EAEA,WAAO,CAACF,UAAU,CAACJ,kBAAD,CAAV,GAAiCI,UAAU,CAACF,eAAD,CAA5C,IAAiEhD,uBAAxE;EACD,GAhDU;EAkDXqD,EAAAA,MAlDW,kBAkDJf,OAlDI,EAkDK;EACd,WAAOA,OAAO,CAACgB,YAAf;EACD,GApDU;EAsDX5B,EAAAA,oBAtDW,gCAsDUY,OAtDV,EAsDmB;EAC5B1B,IAAAA,qBAAC,CAAC0B,OAAD,CAAD,CAAWiB,OAAX,CAAmBzD,cAAnB;EACD,GAxDU;EA0DX0D,EAAAA,qBA1DW,mCA0Da;EACtB,WAAOC,OAAO,CAAC3D,cAAD,CAAd;EACD,GA5DU;EA8DX4D,EAAAA,SA9DW,qBA8DDxD,GA9DC,EA8DI;EACb,WAAO,CAACA,GAAG,CAAC,CAAD,CAAH,IAAUA,GAAX,EAAgByD,QAAvB;EACD,GAhEU;EAkEXC,EAAAA,eAlEW,2BAkEKC,aAlEL,EAkEoBC,MAlEpB,EAkE4BC,WAlE5B,EAkEyC;EAClD,SAAK,IAAMC,QAAX,IAAuBD,WAAvB,EAAoC;EAClC,UAAIE,MAAM,CAACC,SAAP,CAAiBC,cAAjB,CAAgC/D,IAAhC,CAAqC2D,WAArC,EAAkDC,QAAlD,CAAJ,EAAiE;EAC/D,YAAMI,aAAa,GAAGL,WAAW,CAACC,QAAD,CAAjC;EACA,YAAMK,KAAK,GAAGP,MAAM,CAACE,QAAD,CAApB;EACA,YAAMM,SAAS,GAAGD,KAAK,IAAI7C,IAAI,CAACkC,SAAL,CAAeW,KAAf,CAAT,GAChB,SADgB,GACJpE,MAAM,CAACoE,KAAD,CADpB;;EAGA,YAAI,CAAC,IAAIE,MAAJ,CAAWH,aAAX,EAA0BI,IAA1B,CAA+BF,SAA/B,CAAL,EAAgD;EAC9C,gBAAM,IAAIG,KAAJ,CACDZ,aAAa,CAACa,WAAd,EAAH,yBACWV,QADX,2BACuCM,SADvC,sCAEsBF,aAFtB,SADI,CAAN;EAID;EACF;EACF;EACF,GAlFU;EAoFXO,EAAAA,cApFW,0BAoFIrC,OApFJ,EAoFa;EACtB,QAAI,CAACH,QAAQ,CAACyC,eAAT,CAAyBC,YAA9B,EAA4C;EAC1C,aAAO,IAAP;EACD,KAHqB;;;EAMtB,QAAI,OAAOvC,OAAO,CAACwC,WAAf,KAA+B,UAAnC,EAA+C;EAC7C,UAAMC,IAAI,GAAGzC,OAAO,CAACwC,WAAR,EAAb;EACA,aAAOC,IAAI,YAAYC,UAAhB,GAA6BD,IAA7B,GAAoC,IAA3C;EACD;;EAED,QAAIzC,OAAO,YAAY0C,UAAvB,EAAmC;EACjC,aAAO1C,OAAP;EACD,KAbqB;;;EAgBtB,QAAI,CAACA,OAAO,CAAC2C,UAAb,EAAyB;EACvB,aAAO,IAAP;EACD;;EAED,WAAOzD,IAAI,CAACmD,cAAL,CAAoBrC,OAAO,CAAC2C,UAA5B,CAAP;EACD,GAzGU;EA2GXC,EAAAA,eA3GW,6BA2GO;EAChB,QAAI,OAAOtE,qBAAP,KAAa,WAAjB,EAA8B;EAC5B,YAAM,IAAIuE,SAAJ,CAAc,kGAAd,CAAN;EACD;;EAED,QAAMC,OAAO,GAAGxE,qBAAC,CAACgB,EAAF,CAAKyD,MAAL,CAAYjC,KAAZ,CAAkB,GAAlB,EAAuB,CAAvB,EAA0BA,KAA1B,CAAgC,GAAhC,CAAhB;EACA,QAAMkC,QAAQ,GAAG,CAAjB;EACA,QAAMC,OAAO,GAAG,CAAhB;EACA,QAAMC,QAAQ,GAAG,CAAjB;EACA,QAAMC,QAAQ,GAAG,CAAjB;EACA,QAAMC,QAAQ,GAAG,CAAjB;;EAEA,QAAIN,OAAO,CAAC,CAAD,CAAP,GAAaG,OAAb,IAAwBH,OAAO,CAAC,CAAD,CAAP,GAAaI,QAArC,IAAiDJ,OAAO,CAAC,CAAD,CAAP,KAAeE,QAAf,IAA2BF,OAAO,CAAC,CAAD,CAAP,KAAeI,QAA1C,IAAsDJ,OAAO,CAAC,CAAD,CAAP,GAAaK,QAApH,IAAgIL,OAAO,CAAC,CAAD,CAAP,IAAcM,QAAlJ,EAA4J;EAC1J,YAAM,IAAIjB,KAAJ,CAAU,8EAAV,CAAN;EACD;EACF;EA1HU;EA6HbjD,IAAI,CAAC0D,eAAL;EACAvD,uBAAuB;;ECzLvB;EACA;EACA;EACA;EACA;;EAEA,IAAMgE,IAAI,GAAG,OAAb;EACA,IAAMC,OAAO,GAAG,OAAhB;EACA,IAAMC,QAAQ,GAAG,UAAjB;EACA,IAAMC,SAAS,SAAOD,QAAtB;EACA,IAAME,YAAY,GAAG,WAArB;EACA,IAAMC,kBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,IAAL,CAA3B;EAEA,IAAMM,gBAAgB,GAAG,wBAAzB;EAEA,IAAMC,WAAW,aAAWJ,SAA5B;EACA,IAAMK,YAAY,cAAYL,SAA9B;EACA,IAAMM,oBAAoB,aAAWN,SAAX,GAAuBC,YAAjD;EAEA,IAAMM,gBAAgB,GAAG,OAAzB;EACA,IAAMC,eAAe,GAAG,MAAxB;EACA,IAAMC,eAAe,GAAG,MAAxB;EAEA;EACA;EACA;EACA;EACA;;MAEMC;EACJ,iBAAYlE,OAAZ,EAAqB;EACnB,SAAKmE,QAAL,GAAgBnE,OAAhB;EACD;;;;;EAQD;WAEAoE,QAAA,eAAMpE,OAAN,EAAe;EACb,QAAIqE,WAAW,GAAG,KAAKF,QAAvB;;EACA,QAAInE,OAAJ,EAAa;EACXqE,MAAAA,WAAW,GAAG,KAAKC,eAAL,CAAqBtE,OAArB,CAAd;EACD;;EAED,QAAMuE,WAAW,GAAG,KAAKC,kBAAL,CAAwBH,WAAxB,CAApB;;EAEA,QAAIE,WAAW,CAACE,kBAAZ,EAAJ,EAAsC;EACpC;EACD;;EAED,SAAKC,cAAL,CAAoBL,WAApB;EACD;;WAEDM,UAAA,mBAAU;EACRrG,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,QAA5B;EACA,SAAKY,QAAL,GAAgB,IAAhB;EACD;;;WAIDG,kBAAA,yBAAgBtE,OAAhB,EAAyB;EACvB,QAAMC,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4BC,OAA5B,CAAjB;EACA,QAAI6E,MAAM,GAAG,KAAb;;EAEA,QAAI5E,QAAJ,EAAc;EACZ4E,MAAAA,MAAM,GAAGhF,QAAQ,CAACQ,aAAT,CAAuBJ,QAAvB,CAAT;EACD;;EAED,QAAI,CAAC4E,MAAL,EAAa;EACXA,MAAAA,MAAM,GAAGvG,qBAAC,CAAC0B,OAAD,CAAD,CAAW8E,OAAX,OAAuBf,gBAAvB,EAA2C,CAA3C,CAAT;EACD;;EAED,WAAOc,MAAP;EACD;;WAEDL,qBAAA,4BAAmBxE,OAAnB,EAA4B;EAC1B,QAAM+E,UAAU,GAAGzG,qBAAC,CAAC0G,KAAF,CAAQpB,WAAR,CAAnB;EAEAtF,IAAAA,qBAAC,CAAC0B,OAAD,CAAD,CAAWiB,OAAX,CAAmB8D,UAAnB;EACA,WAAOA,UAAP;EACD;;WAEDL,iBAAA,wBAAe1E,OAAf,EAAwB;EAAA;;EACtB1B,IAAAA,qBAAC,CAAC0B,OAAD,CAAD,CAAWiF,WAAX,CAAuBhB,eAAvB;;EAEA,QAAI,CAAC3F,qBAAC,CAAC0B,OAAD,CAAD,CAAWkF,QAAX,CAAoBlB,eAApB,CAAL,EAA2C;EACzC,WAAKmB,eAAL,CAAqBnF,OAArB;;EACA;EACD;;EAED,QAAMQ,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsCP,OAAtC,CAA3B;EAEA1B,IAAAA,qBAAC,CAAC0B,OAAD,CAAD,CACGf,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4B,UAAAa,KAAK;EAAA,aAAI,KAAI,CAAC8G,eAAL,CAAqBnF,OAArB,EAA8B3B,KAA9B,CAAJ;EAAA,KADjC,EAEGkB,oBAFH,CAEwBiB,kBAFxB;EAGD;;WAED2E,kBAAA,yBAAgBnF,OAAhB,EAAyB;EACvB1B,IAAAA,qBAAC,CAAC0B,OAAD,CAAD,CACGoF,MADH,GAEGnE,OAFH,CAEW4C,YAFX,EAGGwB,MAHH;EAID;;;UAIMC,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAMC,QAAQ,GAAGlH,qBAAC,CAAC,IAAD,CAAlB;EACA,UAAImH,IAAI,GAAGD,QAAQ,CAACC,IAAT,CAAclC,QAAd,CAAX;;EAEA,UAAI,CAACkC,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAIvB,KAAJ,CAAU,IAAV,CAAP;EACAsB,QAAAA,QAAQ,CAACC,IAAT,CAAclC,QAAd,EAAwBkC,IAAxB;EACD;;EAED,UAAIjE,MAAM,KAAK,OAAf,EAAwB;EACtBiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ,CAAa,IAAb;EACD;EACF,KAZM,CAAP;EAaD;;UAEMkE,iBAAP,wBAAsBC,aAAtB,EAAqC;EACnC,WAAO,UAAUtH,KAAV,EAAiB;EACtB,UAAIA,KAAJ,EAAW;EACTA,QAAAA,KAAK,CAACuH,cAAN;EACD;;EAEDD,MAAAA,aAAa,CAACvB,KAAd,CAAoB,IAApB;EACD,KAND;EAOD;;;;0BAlGoB;EACnB,aAAOd,OAAP;EACD;;;;;EAmGH;EACA;EACA;EACA;EACA;;;AAEAhF,uBAAC,CAACuB,QAAD,CAAD,CAAYgG,EAAZ,CACE/B,oBADF,EAEEH,gBAFF,EAGEO,KAAK,CAACwB,cAAN,CAAqB,IAAIxB,KAAJ,EAArB,CAHF;EAMA;EACA;EACA;EACA;EACA;;AAEA5F,uBAAC,CAACgB,EAAF,CAAK+D,IAAL,IAAaa,KAAK,CAACoB,gBAAnB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,IAAL,EAAWyC,WAAX,GAAyB5B,KAAzB;;AACA5F,uBAAC,CAACgB,EAAF,CAAK+D,IAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,IAAL,IAAaK,kBAAb;EACA,SAAOQ,KAAK,CAACoB,gBAAb;EACD,CAHD;;EC9JA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,QAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,WAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAME,cAAY,GAAG,WAArB;EACA,IAAMC,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EAEA,IAAM2C,iBAAiB,GAAG,QAA1B;EACA,IAAMC,iBAAiB,GAAG,KAA1B;EACA,IAAMC,gBAAgB,GAAG,OAAzB;EAEA,IAAMC,2BAA2B,GAAG,yBAApC;EACA,IAAMC,qBAAqB,GAAG,yBAA9B;EACA,IAAMC,oBAAoB,GAAG,wBAA7B;EACA,IAAMC,6BAA6B,GAAG,8BAAtC;EACA,IAAMC,cAAc,GAAG,4BAAvB;EACA,IAAMC,eAAe,GAAG,SAAxB;EACA,IAAMC,eAAe,GAAG,MAAxB;EAEA,IAAM3C,sBAAoB,aAAWN,WAAX,GAAuBC,cAAjD;EACA,IAAMiD,yBAAyB,GAAG,UAAQlD,WAAR,GAAoBC,cAApB,mBACDD,WADC,GACWC,cADX,CAAlC;EAEA,IAAMkD,mBAAmB,YAAUnD,WAAV,GAAsBC,cAA/C;EAEA;EACA;EACA;EACA;EACA;;MAEMmD;EACJ,kBAAY5G,OAAZ,EAAqB;EACnB,SAAKmE,QAAL,GAAgBnE,OAAhB;EACA,SAAK6G,wBAAL,GAAgC,KAAhC;EACD;;;;;EAQD;WAEAC,SAAA,kBAAS;EACP,QAAIC,kBAAkB,GAAG,IAAzB;EACA,QAAIC,cAAc,GAAG,IAArB;EACA,QAAM3C,WAAW,GAAG/F,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBW,OAAjB,CAAyBsB,qBAAzB,EAAgD,CAAhD,CAApB;;EAEA,QAAI/B,WAAJ,EAAiB;EACf,UAAM4C,KAAK,GAAG,KAAK9C,QAAL,CAAc9D,aAAd,CAA4BkG,cAA5B,CAAd;;EAEA,UAAIU,KAAJ,EAAW;EACT,YAAIA,KAAK,CAACC,IAAN,KAAe,OAAnB,EAA4B;EAC1B,cAAID,KAAK,CAACE,OAAN,IAAiB,KAAKhD,QAAL,CAAciD,SAAd,CAAwBC,QAAxB,CAAiCrB,iBAAjC,CAArB,EAA0E;EACxEe,YAAAA,kBAAkB,GAAG,KAArB;EACD,WAFD,MAEO;EACL,gBAAMO,aAAa,GAAGjD,WAAW,CAAChE,aAAZ,CAA0BmG,eAA1B,CAAtB;;EAEA,gBAAIc,aAAJ,EAAmB;EACjBhJ,cAAAA,qBAAC,CAACgJ,aAAD,CAAD,CAAiBrC,WAAjB,CAA6Be,iBAA7B;EACD;EACF;EACF;;EAED,YAAIe,kBAAJ,EAAwB;EACtB;EACA,cAAIE,KAAK,CAACC,IAAN,KAAe,UAAf,IAA6BD,KAAK,CAACC,IAAN,KAAe,OAAhD,EAAyD;EACvDD,YAAAA,KAAK,CAACE,OAAN,GAAgB,CAAC,KAAKhD,QAAL,CAAciD,SAAd,CAAwBC,QAAxB,CAAiCrB,iBAAjC,CAAjB;EACD;;EAED,cAAI,CAAC,KAAKa,wBAAV,EAAoC;EAClCvI,YAAAA,qBAAC,CAAC2I,KAAD,CAAD,CAAShG,OAAT,CAAiB,QAAjB;EACD;EACF;;EAEDgG,QAAAA,KAAK,CAACM,KAAN;EACAP,QAAAA,cAAc,GAAG,KAAjB;EACD;EACF;;EAED,QAAI,EAAE,KAAK7C,QAAL,CAAcqD,YAAd,CAA2B,UAA3B,KAA0C,KAAKrD,QAAL,CAAciD,SAAd,CAAwBC,QAAxB,CAAiC,UAAjC,CAA5C,CAAJ,EAA+F;EAC7F,UAAIL,cAAJ,EAAoB;EAClB,aAAK7C,QAAL,CAAcsD,YAAd,CAA2B,cAA3B,EAA2C,CAAC,KAAKtD,QAAL,CAAciD,SAAd,CAAwBC,QAAxB,CAAiCrB,iBAAjC,CAA5C;EACD;;EAED,UAAIe,kBAAJ,EAAwB;EACtBzI,QAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBuD,WAAjB,CAA6B1B,iBAA7B;EACD;EACF;EACF;;WAEDrB,UAAA,mBAAU;EACRrG,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EACA,SAAKY,QAAL,GAAgB,IAAhB;EACD;;;WAIMmB,mBAAP,0BAAwB9D,MAAxB,EAAgCmG,kBAAhC,EAAoD;EAClD,WAAO,KAAKpC,IAAL,CAAU,YAAY;EAC3B,UAAMC,QAAQ,GAAGlH,qBAAC,CAAC,IAAD,CAAlB;EACA,UAAImH,IAAI,GAAGD,QAAQ,CAACC,IAAT,CAAclC,UAAd,CAAX;;EAEA,UAAI,CAACkC,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAImB,MAAJ,CAAW,IAAX,CAAP;EACApB,QAAAA,QAAQ,CAACC,IAAT,CAAclC,UAAd,EAAwBkC,IAAxB;EACD;;EAEDA,MAAAA,IAAI,CAACoB,wBAAL,GAAgCc,kBAAhC;;EAEA,UAAInG,MAAM,KAAK,QAAf,EAAyB;EACvBiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ;EACD;EACF,KAdM,CAAP;EAeD;;;;0BA7EoB;EACnB,aAAO8B,SAAP;EACD;;;;;EA8EH;EACA;EACA;EACA;EACA;;;AAEAhF,uBAAC,CAACuB,QAAD,CAAD,CACGgG,EADH,CACM/B,sBADN,EAC4BqC,2BAD5B,EACyD,UAAA9H,KAAK,EAAI;EAC9D,MAAIuJ,MAAM,GAAGvJ,KAAK,CAACE,MAAnB;EACA,MAAMsJ,aAAa,GAAGD,MAAtB;;EAEA,MAAI,CAACtJ,qBAAC,CAACsJ,MAAD,CAAD,CAAU1C,QAAV,CAAmBe,iBAAnB,CAAL,EAA4C;EAC1C2B,IAAAA,MAAM,GAAGtJ,qBAAC,CAACsJ,MAAD,CAAD,CAAU9C,OAAV,CAAkB2B,eAAlB,EAAmC,CAAnC,CAAT;EACD;;EAED,MAAI,CAACmB,MAAD,IAAWA,MAAM,CAACJ,YAAP,CAAoB,UAApB,CAAX,IAA8CI,MAAM,CAACR,SAAP,CAAiBC,QAAjB,CAA0B,UAA1B,CAAlD,EAAyF;EACvFhJ,IAAAA,KAAK,CAACuH,cAAN,GADuF;EAExF,GAFD,MAEO;EACL,QAAMkC,QAAQ,GAAGF,MAAM,CAACvH,aAAP,CAAqBkG,cAArB,CAAjB;;EAEA,QAAIuB,QAAQ,KAAKA,QAAQ,CAACN,YAAT,CAAsB,UAAtB,KAAqCM,QAAQ,CAACV,SAAT,CAAmBC,QAAnB,CAA4B,UAA5B,CAA1C,CAAZ,EAAgG;EAC9FhJ,MAAAA,KAAK,CAACuH,cAAN,GAD8F;;EAE9F;EACD;;EAED,QAAIiC,aAAa,CAACE,OAAd,KAA0B,OAA1B,IAAqCH,MAAM,CAACG,OAAP,KAAmB,OAA5D,EAAqE;EACnEnB,MAAAA,MAAM,CAACtB,gBAAP,CAAwBxH,IAAxB,CAA6BQ,qBAAC,CAACsJ,MAAD,CAA9B,EAAwC,QAAxC,EAAkDC,aAAa,CAACE,OAAd,KAA0B,OAA5E;EACD;EACF;EACF,CAvBH,EAwBGlC,EAxBH,CAwBMa,yBAxBN,EAwBiCP,2BAxBjC,EAwB8D,UAAA9H,KAAK,EAAI;EACnE,MAAMuJ,MAAM,GAAGtJ,qBAAC,CAACD,KAAK,CAACE,MAAP,CAAD,CAAgBuG,OAAhB,CAAwB2B,eAAxB,EAAyC,CAAzC,CAAf;EACAnI,EAAAA,qBAAC,CAACsJ,MAAD,CAAD,CAAUF,WAAV,CAAsBxB,gBAAtB,EAAwC,eAAehE,IAAf,CAAoB7D,KAAK,CAAC6I,IAA1B,CAAxC;EACD,CA3BH;AA6BA5I,uBAAC,CAAC0J,MAAD,CAAD,CAAUnC,EAAV,CAAac,mBAAb,EAAkC,YAAM;EACtC;EAEA;EACA,MAAIsB,OAAO,GAAG,GAAGC,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B7B,6BAA1B,CAAd,CAAd;;EACA,OAAK,IAAI8B,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGJ,OAAO,CAACK,MAA9B,EAAsCF,CAAC,GAAGC,GAA1C,EAA+CD,CAAC,EAAhD,EAAoD;EAClD,QAAMR,MAAM,GAAGK,OAAO,CAACG,CAAD,CAAtB;EACA,QAAMnB,KAAK,GAAGW,MAAM,CAACvH,aAAP,CAAqBkG,cAArB,CAAd;;EACA,QAAIU,KAAK,CAACE,OAAN,IAAiBF,KAAK,CAACO,YAAN,CAAmB,SAAnB,CAArB,EAAoD;EAClDI,MAAAA,MAAM,CAACR,SAAP,CAAiBmB,GAAjB,CAAqBvC,iBAArB;EACD,KAFD,MAEO;EACL4B,MAAAA,MAAM,CAACR,SAAP,CAAiB/B,MAAjB,CAAwBW,iBAAxB;EACD;EACF,GAbqC;;;EAgBtCiC,EAAAA,OAAO,GAAG,GAAGC,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B9B,oBAA1B,CAAd,CAAV;;EACA,OAAK,IAAI+B,EAAC,GAAG,CAAR,EAAWC,IAAG,GAAGJ,OAAO,CAACK,MAA9B,EAAsCF,EAAC,GAAGC,IAA1C,EAA+CD,EAAC,EAAhD,EAAoD;EAClD,QAAMR,OAAM,GAAGK,OAAO,CAACG,EAAD,CAAtB;;EACA,QAAIR,OAAM,CAAC1H,YAAP,CAAoB,cAApB,MAAwC,MAA5C,EAAoD;EAClD0H,MAAAA,OAAM,CAACR,SAAP,CAAiBmB,GAAjB,CAAqBvC,iBAArB;EACD,KAFD,MAEO;EACL4B,MAAAA,OAAM,CAACR,SAAP,CAAiB/B,MAAjB,CAAwBW,iBAAxB;EACD;EACF;EACF,CAzBD;EA2BA;EACA;EACA;EACA;EACA;;AAEA1H,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAauD,MAAM,CAACtB,gBAApB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyBc,MAAzB;;AACAtI,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAOkD,MAAM,CAACtB,gBAAd;EACD,CAHD;;ECjMA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,UAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,aAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAME,cAAY,GAAG,WAArB;EACA,IAAMC,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EACA,IAAMmF,kBAAkB,GAAG,EAA3B;;EACA,IAAMC,mBAAmB,GAAG,EAA5B;;EACA,IAAMC,sBAAsB,GAAG,GAA/B;;EACA,IAAMC,eAAe,GAAG,EAAxB;EAEA,IAAMC,OAAO,GAAG;EACdC,EAAAA,QAAQ,EAAE,IADI;EAEdC,EAAAA,QAAQ,EAAE,IAFI;EAGdC,EAAAA,KAAK,EAAE,KAHO;EAIdC,EAAAA,KAAK,EAAE,OAJO;EAKdC,EAAAA,IAAI,EAAE,IALQ;EAMdC,EAAAA,KAAK,EAAE;EANO,CAAhB;EASA,IAAMC,WAAW,GAAG;EAClBN,EAAAA,QAAQ,EAAE,kBADQ;EAElBC,EAAAA,QAAQ,EAAE,SAFQ;EAGlBC,EAAAA,KAAK,EAAE,kBAHW;EAIlBC,EAAAA,KAAK,EAAE,kBAJW;EAKlBC,EAAAA,IAAI,EAAE,SALY;EAMlBC,EAAAA,KAAK,EAAE;EANW,CAApB;EASA,IAAME,cAAc,GAAG,MAAvB;EACA,IAAMC,cAAc,GAAG,MAAvB;EACA,IAAMC,cAAc,GAAG,MAAvB;EACA,IAAMC,eAAe,GAAG,OAAxB;EAEA,IAAMC,WAAW,aAAWhG,WAA5B;EACA,IAAMiG,UAAU,YAAUjG,WAA1B;EACA,IAAMkG,aAAa,eAAalG,WAAhC;EACA,IAAMmG,gBAAgB,kBAAgBnG,WAAtC;EACA,IAAMoG,gBAAgB,kBAAgBpG,WAAtC;EACA,IAAMqG,gBAAgB,kBAAgBrG,WAAtC;EACA,IAAMsG,eAAe,iBAAetG,WAApC;EACA,IAAMuG,cAAc,gBAAcvG,WAAlC;EACA,IAAMwG,iBAAiB,mBAAiBxG,WAAxC;EACA,IAAMyG,eAAe,iBAAezG,WAApC;EACA,IAAM0G,gBAAgB,iBAAe1G,WAArC;EACA,IAAMmD,qBAAmB,YAAUnD,WAAV,GAAsBC,cAA/C;EACA,IAAMK,sBAAoB,aAAWN,WAAX,GAAuBC,cAAjD;EAEA,IAAM0G,mBAAmB,GAAG,UAA5B;EACA,IAAMnE,mBAAiB,GAAG,QAA1B;EACA,IAAMoE,gBAAgB,GAAG,OAAzB;EACA,IAAMC,gBAAgB,GAAG,qBAAzB;EACA,IAAMC,eAAe,GAAG,oBAAxB;EACA,IAAMC,eAAe,GAAG,oBAAxB;EACA,IAAMC,eAAe,GAAG,oBAAxB;EACA,IAAMC,wBAAwB,GAAG,eAAjC;EAEA,IAAMjE,iBAAe,GAAG,SAAxB;EACA,IAAMkE,oBAAoB,GAAG,uBAA7B;EACA,IAAMC,aAAa,GAAG,gBAAtB;EACA,IAAMC,iBAAiB,GAAG,oBAA1B;EACA,IAAMC,kBAAkB,GAAG,0CAA3B;EACA,IAAMC,mBAAmB,GAAG,sBAA5B;EACA,IAAMC,mBAAmB,GAAG,+BAA5B;EACA,IAAMC,kBAAkB,GAAG,wBAA3B;EAEA,IAAMC,WAAW,GAAG;EAClBC,EAAAA,KAAK,EAAE,OADW;EAElBC,EAAAA,GAAG,EAAE;EAFa,CAApB;EAKA;EACA;EACA;EACA;EACA;;MACMC;EACJ,oBAAYpL,OAAZ,EAAqBwB,MAArB,EAA6B;EAC3B,SAAK6J,MAAL,GAAc,IAAd;EACA,SAAKC,SAAL,GAAiB,IAAjB;EACA,SAAKC,cAAL,GAAsB,IAAtB;EACA,SAAKC,SAAL,GAAiB,KAAjB;EACA,SAAKC,UAAL,GAAkB,KAAlB;EACA,SAAKC,YAAL,GAAoB,IAApB;EACA,SAAKC,WAAL,GAAmB,CAAnB;EACA,SAAKC,WAAL,GAAmB,CAAnB;EAEA,SAAKC,OAAL,GAAe,KAAKC,UAAL,CAAgBtK,MAAhB,CAAf;EACA,SAAK2C,QAAL,GAAgBnE,OAAhB;EACA,SAAK+L,kBAAL,GAA0B,KAAK5H,QAAL,CAAc9D,aAAd,CAA4ByK,mBAA5B,CAA1B;EACA,SAAKkB,eAAL,GAAuB,kBAAkBnM,QAAQ,CAACyC,eAA3B,IAA8C2J,SAAS,CAACC,cAAV,GAA2B,CAAhG;EACA,SAAKC,aAAL,GAAqBhL,OAAO,CAAC6G,MAAM,CAACoE,YAAP,IAAuBpE,MAAM,CAACqE,cAA/B,CAA5B;;EAEA,SAAKC,kBAAL;EACD;;;;;EAYD;WAEAC,OAAA,gBAAO;EACL,QAAI,CAAC,KAAKd,UAAV,EAAsB;EACpB,WAAKe,MAAL,CAAYpD,cAAZ;EACD;EACF;;WAEDqD,kBAAA,2BAAkB;EAChB,QAAMjH,QAAQ,GAAGlH,qBAAC,CAAC,KAAK6F,QAAN,CAAlB,CADgB;EAGhB;;EACA,QAAI,CAACtE,QAAQ,CAAC6M,MAAV,IACDlH,QAAQ,CAAChH,EAAT,CAAY,UAAZ,KAA2BgH,QAAQ,CAAC/E,GAAT,CAAa,YAAb,MAA+B,QAD7D,EACwE;EACtE,WAAK8L,IAAL;EACD;EACF;;WAEDI,OAAA,gBAAO;EACL,QAAI,CAAC,KAAKlB,UAAV,EAAsB;EACpB,WAAKe,MAAL,CAAYnD,cAAZ;EACD;EACF;;WAEDL,QAAA,eAAM3K,KAAN,EAAa;EACX,QAAI,CAACA,KAAL,EAAY;EACV,WAAKmN,SAAL,GAAiB,IAAjB;EACD;;EAED,QAAI,KAAKrH,QAAL,CAAc9D,aAAd,CAA4BwK,kBAA5B,CAAJ,EAAqD;EACnD3L,MAAAA,IAAI,CAACE,oBAAL,CAA0B,KAAK+E,QAA/B;EACA,WAAKyI,KAAL,CAAW,IAAX;EACD;;EAEDC,IAAAA,aAAa,CAAC,KAAKvB,SAAN,CAAb;EACA,SAAKA,SAAL,GAAiB,IAAjB;EACD;;WAEDsB,QAAA,eAAMvO,KAAN,EAAa;EACX,QAAI,CAACA,KAAL,EAAY;EACV,WAAKmN,SAAL,GAAiB,KAAjB;EACD;;EAED,QAAI,KAAKF,SAAT,EAAoB;EAClBuB,MAAAA,aAAa,CAAC,KAAKvB,SAAN,CAAb;EACA,WAAKA,SAAL,GAAiB,IAAjB;EACD;;EAED,QAAI,KAAKO,OAAL,CAAahD,QAAb,IAAyB,CAAC,KAAK2C,SAAnC,EAA8C;EAC5C,WAAKsB,eAAL;;EAEA,WAAKxB,SAAL,GAAiByB,WAAW,CAC1B,CAAClN,QAAQ,CAACmN,eAAT,GAA2B,KAAKP,eAAhC,GAAkD,KAAKF,IAAxD,EAA8DU,IAA9D,CAAmE,IAAnE,CAD0B,EAE1B,KAAKpB,OAAL,CAAahD,QAFa,CAA5B;EAID;EACF;;WAEDqE,KAAA,YAAGC,KAAH,EAAU;EAAA;;EACR,SAAK5B,cAAL,GAAsB,KAAKpH,QAAL,CAAc9D,aAAd,CAA4BqK,oBAA5B,CAAtB;;EAEA,QAAM0C,WAAW,GAAG,KAAKC,aAAL,CAAmB,KAAK9B,cAAxB,CAApB;;EAEA,QAAI4B,KAAK,GAAG,KAAK9B,MAAL,CAAY/C,MAAZ,GAAqB,CAA7B,IAAkC6E,KAAK,GAAG,CAA9C,EAAiD;EAC/C;EACD;;EAED,QAAI,KAAK1B,UAAT,EAAqB;EACnBnN,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlF,GAAjB,CAAqBwK,UAArB,EAAiC;EAAA,eAAM,KAAI,CAACyD,EAAL,CAAQC,KAAR,CAAN;EAAA,OAAjC;EACA;EACD;;EAED,QAAIC,WAAW,KAAKD,KAApB,EAA2B;EACzB,WAAKnE,KAAL;EACA,WAAK4D,KAAL;EACA;EACD;;EAED,QAAMU,SAAS,GAAGH,KAAK,GAAGC,WAAR,GAChBhE,cADgB,GAEhBC,cAFF;;EAIA,SAAKmD,MAAL,CAAYc,SAAZ,EAAuB,KAAKjC,MAAL,CAAY8B,KAAZ,CAAvB;EACD;;WAEDxI,UAAA,mBAAU;EACRrG,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBoJ,GAAjB,CAAqB/J,WAArB;EACAlF,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EAEA,SAAK8H,MAAL,GAAc,IAAd;EACA,SAAKQ,OAAL,GAAe,IAAf;EACA,SAAK1H,QAAL,GAAgB,IAAhB;EACA,SAAKmH,SAAL,GAAiB,IAAjB;EACA,SAAKE,SAAL,GAAiB,IAAjB;EACA,SAAKC,UAAL,GAAkB,IAAlB;EACA,SAAKF,cAAL,GAAsB,IAAtB;EACA,SAAKQ,kBAAL,GAA0B,IAA1B;EACD;;;WAIDD,aAAA,oBAAWtK,MAAX,EAAmB;EACjBA,IAAAA,MAAM,gBACDoH,OADC,EAEDpH,MAFC,CAAN;EAIAtC,IAAAA,IAAI,CAACoC,eAAL,CAAqB+B,MAArB,EAA2B7B,MAA3B,EAAmC2H,WAAnC;EACA,WAAO3H,MAAP;EACD;;WAEDgM,eAAA,wBAAe;EACb,QAAMC,SAAS,GAAG9N,IAAI,CAAC+N,GAAL,CAAS,KAAK9B,WAAd,CAAlB;;EAEA,QAAI6B,SAAS,IAAI9E,eAAjB,EAAkC;EAChC;EACD;;EAED,QAAM2E,SAAS,GAAGG,SAAS,GAAG,KAAK7B,WAAnC;EAEA,SAAKA,WAAL,GAAmB,CAAnB,CATa;;EAYb,QAAI0B,SAAS,GAAG,CAAhB,EAAmB;EACjB,WAAKX,IAAL;EACD,KAdY;;;EAiBb,QAAIW,SAAS,GAAG,CAAhB,EAAmB;EACjB,WAAKf,IAAL;EACD;EACF;;WAEDD,qBAAA,8BAAqB;EAAA;;EACnB,QAAI,KAAKT,OAAL,CAAa/C,QAAjB,EAA2B;EACzBxK,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoB6D,aAApB,EAAmC,UAAArL,KAAK;EAAA,eAAI,MAAI,CAACsP,QAAL,CAActP,KAAd,CAAJ;EAAA,OAAxC;EACD;;EAED,QAAI,KAAKwN,OAAL,CAAa7C,KAAb,KAAuB,OAA3B,EAAoC;EAClC1K,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACG0B,EADH,CACM8D,gBADN,EACwB,UAAAtL,KAAK;EAAA,eAAI,MAAI,CAAC2K,KAAL,CAAW3K,KAAX,CAAJ;EAAA,OAD7B,EAEGwH,EAFH,CAEM+D,gBAFN,EAEwB,UAAAvL,KAAK;EAAA,eAAI,MAAI,CAACuO,KAAL,CAAWvO,KAAX,CAAJ;EAAA,OAF7B;EAGD;;EAED,QAAI,KAAKwN,OAAL,CAAa3C,KAAjB,EAAwB;EACtB,WAAK0E,uBAAL;EACD;EACF;;WAEDA,0BAAA,mCAA0B;EAAA;;EACxB,QAAI,CAAC,KAAK5B,eAAV,EAA2B;EACzB;EACD;;EAED,QAAM6B,KAAK,GAAG,SAARA,KAAQ,CAAAxP,KAAK,EAAI;EACrB,UAAI,MAAI,CAAC8N,aAAL,IAAsBlB,WAAW,CAAC5M,KAAK,CAACyP,aAAN,CAAoBC,WAApB,CAAgC3L,WAAhC,EAAD,CAArC,EAAsF;EACpF,QAAA,MAAI,CAACuJ,WAAL,GAAmBtN,KAAK,CAACyP,aAAN,CAAoBE,OAAvC;EACD,OAFD,MAEO,IAAI,CAAC,MAAI,CAAC7B,aAAV,EAAyB;EAC9B,QAAA,MAAI,CAACR,WAAL,GAAmBtN,KAAK,CAACyP,aAAN,CAAoBG,OAApB,CAA4B,CAA5B,EAA+BD,OAAlD;EACD;EACF,KAND;;EAQA,QAAME,IAAI,GAAG,SAAPA,IAAO,CAAA7P,KAAK,EAAI;EACpB;EACA,UAAIA,KAAK,CAACyP,aAAN,CAAoBG,OAApB,IAA+B5P,KAAK,CAACyP,aAAN,CAAoBG,OAApB,CAA4B3F,MAA5B,GAAqC,CAAxE,EAA2E;EACzE,QAAA,MAAI,CAACsD,WAAL,GAAmB,CAAnB;EACD,OAFD,MAEO;EACL,QAAA,MAAI,CAACA,WAAL,GAAmBvN,KAAK,CAACyP,aAAN,CAAoBG,OAApB,CAA4B,CAA5B,EAA+BD,OAA/B,GAAyC,MAAI,CAACrC,WAAjE;EACD;EACF,KAPD;;EASA,QAAMwC,GAAG,GAAG,SAANA,GAAM,CAAA9P,KAAK,EAAI;EACnB,UAAI,MAAI,CAAC8N,aAAL,IAAsBlB,WAAW,CAAC5M,KAAK,CAACyP,aAAN,CAAoBC,WAApB,CAAgC3L,WAAhC,EAAD,CAArC,EAAsF;EACpF,QAAA,MAAI,CAACwJ,WAAL,GAAmBvN,KAAK,CAACyP,aAAN,CAAoBE,OAApB,GAA8B,MAAI,CAACrC,WAAtD;EACD;;EAED,MAAA,MAAI,CAAC6B,YAAL;;EACA,UAAI,MAAI,CAAC3B,OAAL,CAAa7C,KAAb,KAAuB,OAA3B,EAAoC;EAClC;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,QAAA,MAAI,CAACA,KAAL;;EACA,YAAI,MAAI,CAAC0C,YAAT,EAAuB;EACrB0C,UAAAA,YAAY,CAAC,MAAI,CAAC1C,YAAN,CAAZ;EACD;;EAED,QAAA,MAAI,CAACA,YAAL,GAAoBvM,UAAU,CAAC,UAAAd,KAAK;EAAA,iBAAI,MAAI,CAACuO,KAAL,CAAWvO,KAAX,CAAJ;EAAA,SAAN,EAA6BqK,sBAAsB,GAAG,MAAI,CAACmD,OAAL,CAAahD,QAAnE,CAA9B;EACD;EACF,KAtBD;;EAwBAvK,IAAAA,qBAAC,CAAC,KAAK6F,QAAL,CAAcgE,gBAAd,CAA+ByC,iBAA/B,CAAD,CAAD,CACG/E,EADH,CACMqE,gBADN,EACwB,UAAAmE,CAAC;EAAA,aAAIA,CAAC,CAACzI,cAAF,EAAJ;EAAA,KADzB;;EAGA,QAAI,KAAKuG,aAAT,EAAwB;EACtB7N,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoBmE,iBAApB,EAAuC,UAAA3L,KAAK;EAAA,eAAIwP,KAAK,CAACxP,KAAD,CAAT;EAAA,OAA5C;EACAC,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoBoE,eAApB,EAAqC,UAAA5L,KAAK;EAAA,eAAI8P,GAAG,CAAC9P,KAAD,CAAP;EAAA,OAA1C;;EAEA,WAAK8F,QAAL,CAAciD,SAAd,CAAwBmB,GAAxB,CAA4BkC,wBAA5B;EACD,KALD,MAKO;EACLnM,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoBgE,gBAApB,EAAsC,UAAAxL,KAAK;EAAA,eAAIwP,KAAK,CAACxP,KAAD,CAAT;EAAA,OAA3C;EACAC,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoBiE,eAApB,EAAqC,UAAAzL,KAAK;EAAA,eAAI6P,IAAI,CAAC7P,KAAD,CAAR;EAAA,OAA1C;EACAC,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoBkE,cAApB,EAAoC,UAAA1L,KAAK;EAAA,eAAI8P,GAAG,CAAC9P,KAAD,CAAP;EAAA,OAAzC;EACD;EACF;;WAEDsP,WAAA,kBAAStP,KAAT,EAAgB;EACd,QAAI,kBAAkB6D,IAAlB,CAAuB7D,KAAK,CAACE,MAAN,CAAawJ,OAApC,CAAJ,EAAkD;EAChD;EACD;;EAED,YAAQ1J,KAAK,CAACiQ,KAAd;EACE,WAAK9F,kBAAL;EACEnK,QAAAA,KAAK,CAACuH,cAAN;EACA,aAAK+G,IAAL;EACA;;EACF,WAAKlE,mBAAL;EACEpK,QAAAA,KAAK,CAACuH,cAAN;EACA,aAAK2G,IAAL;EACA;EARJ;EAWD;;WAEDc,gBAAA,uBAAcrN,OAAd,EAAuB;EACrB,SAAKqL,MAAL,GAAcrL,OAAO,IAAIA,OAAO,CAAC2C,UAAnB,GACZ,GAAGuF,KAAH,CAASpK,IAAT,CAAckC,OAAO,CAAC2C,UAAR,CAAmBwF,gBAAnB,CAAoCwC,aAApC,CAAd,CADY,GAEZ,EAFF;EAGA,WAAO,KAAKU,MAAL,CAAYkD,OAAZ,CAAoBvO,OAApB,CAAP;EACD;;WAEDwO,sBAAA,6BAAoBlB,SAApB,EAA+BhG,aAA/B,EAA8C;EAC5C,QAAMmH,eAAe,GAAGnB,SAAS,KAAKlE,cAAtC;EACA,QAAMsF,eAAe,GAAGpB,SAAS,KAAKjE,cAAtC;;EACA,QAAM+D,WAAW,GAAG,KAAKC,aAAL,CAAmB/F,aAAnB,CAApB;;EACA,QAAMqH,aAAa,GAAG,KAAKtD,MAAL,CAAY/C,MAAZ,GAAqB,CAA3C;EACA,QAAMsG,aAAa,GAAGF,eAAe,IAAItB,WAAW,KAAK,CAAnC,IACEqB,eAAe,IAAIrB,WAAW,KAAKuB,aAD3D;;EAGA,QAAIC,aAAa,IAAI,CAAC,KAAK/C,OAAL,CAAa5C,IAAnC,EAAyC;EACvC,aAAO3B,aAAP;EACD;;EAED,QAAMuH,KAAK,GAAGvB,SAAS,KAAKjE,cAAd,GAA+B,CAAC,CAAhC,GAAoC,CAAlD;EACA,QAAMyF,SAAS,GAAG,CAAC1B,WAAW,GAAGyB,KAAf,IAAwB,KAAKxD,MAAL,CAAY/C,MAAtD;EAEA,WAAOwG,SAAS,KAAK,CAAC,CAAf,GACL,KAAKzD,MAAL,CAAY,KAAKA,MAAL,CAAY/C,MAAZ,GAAqB,CAAjC,CADK,GACiC,KAAK+C,MAAL,CAAYyD,SAAZ,CADxC;EAED;;WAEDC,qBAAA,4BAAmBC,aAAnB,EAAkCC,kBAAlC,EAAsD;EACpD,QAAMC,WAAW,GAAG,KAAK7B,aAAL,CAAmB2B,aAAnB,CAApB;;EACA,QAAMG,SAAS,GAAG,KAAK9B,aAAL,CAAmB,KAAKlJ,QAAL,CAAc9D,aAAd,CAA4BqK,oBAA5B,CAAnB,CAAlB;;EACA,QAAM0E,UAAU,GAAG9Q,qBAAC,CAAC0G,KAAF,CAAQwE,WAAR,EAAqB;EACtCwF,MAAAA,aAAa,EAAbA,aADsC;EAEtC1B,MAAAA,SAAS,EAAE2B,kBAF2B;EAGtCI,MAAAA,IAAI,EAAEF,SAHgC;EAItCjC,MAAAA,EAAE,EAAEgC;EAJkC,KAArB,CAAnB;EAOA5Q,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBmO,UAAzB;EAEA,WAAOA,UAAP;EACD;;WAEDE,6BAAA,oCAA2BtP,OAA3B,EAAoC;EAClC,QAAI,KAAK+L,kBAAT,EAA6B;EAC3B,UAAMwD,UAAU,GAAG,GAAGrH,KAAH,CAASpK,IAAT,CAAc,KAAKiO,kBAAL,CAAwB5D,gBAAxB,CAAyC3B,iBAAzC,CAAd,CAAnB;EACAlI,MAAAA,qBAAC,CAACiR,UAAD,CAAD,CAActK,WAAd,CAA0Be,mBAA1B;;EAEA,UAAMwJ,aAAa,GAAG,KAAKzD,kBAAL,CAAwB0D,QAAxB,CACpB,KAAKpC,aAAL,CAAmBrN,OAAnB,CADoB,CAAtB;;EAIA,UAAIwP,aAAJ,EAAmB;EACjBlR,QAAAA,qBAAC,CAACkR,aAAD,CAAD,CAAiBE,QAAjB,CAA0B1J,mBAA1B;EACD;EACF;EACF;;WAED8G,kBAAA,2BAAkB;EAChB,QAAM9M,OAAO,GAAG,KAAKuL,cAAL,IAAuB,KAAKpH,QAAL,CAAc9D,aAAd,CAA4BqK,oBAA5B,CAAvC;;EAEA,QAAI,CAAC1K,OAAL,EAAc;EACZ;EACD;;EAED,QAAM2P,eAAe,GAAGC,QAAQ,CAAC5P,OAAO,CAACE,YAAR,CAAqB,eAArB,CAAD,EAAwC,EAAxC,CAAhC;;EAEA,QAAIyP,eAAJ,EAAqB;EACnB,WAAK9D,OAAL,CAAagE,eAAb,GAA+B,KAAKhE,OAAL,CAAagE,eAAb,IAAgC,KAAKhE,OAAL,CAAahD,QAA5E;EACA,WAAKgD,OAAL,CAAahD,QAAb,GAAwB8G,eAAxB;EACD,KAHD,MAGO;EACL,WAAK9D,OAAL,CAAahD,QAAb,GAAwB,KAAKgD,OAAL,CAAagE,eAAb,IAAgC,KAAKhE,OAAL,CAAahD,QAArE;EACD;EACF;;WAED2D,SAAA,gBAAOc,SAAP,EAAkBtN,OAAlB,EAA2B;EAAA;;EACzB,QAAMsH,aAAa,GAAG,KAAKnD,QAAL,CAAc9D,aAAd,CAA4BqK,oBAA5B,CAAtB;;EACA,QAAMoF,kBAAkB,GAAG,KAAKzC,aAAL,CAAmB/F,aAAnB,CAA3B;;EACA,QAAMyI,WAAW,GAAG/P,OAAO,IAAIsH,aAAa,IAC1C,KAAKkH,mBAAL,CAAyBlB,SAAzB,EAAoChG,aAApC,CADF;;EAEA,QAAM0I,gBAAgB,GAAG,KAAK3C,aAAL,CAAmB0C,WAAnB,CAAzB;;EACA,QAAME,SAAS,GAAG9O,OAAO,CAAC,KAAKmK,SAAN,CAAzB;EAEA,QAAI4E,oBAAJ;EACA,QAAIC,cAAJ;EACA,QAAIlB,kBAAJ;;EAEA,QAAI3B,SAAS,KAAKlE,cAAlB,EAAkC;EAChC8G,MAAAA,oBAAoB,GAAG5F,eAAvB;EACA6F,MAAAA,cAAc,GAAG5F,eAAjB;EACA0E,MAAAA,kBAAkB,GAAG3F,cAArB;EACD,KAJD,MAIO;EACL4G,MAAAA,oBAAoB,GAAG7F,gBAAvB;EACA8F,MAAAA,cAAc,GAAG3F,eAAjB;EACAyE,MAAAA,kBAAkB,GAAG1F,eAArB;EACD;;EAED,QAAIwG,WAAW,IAAIzR,qBAAC,CAACyR,WAAD,CAAD,CAAe7K,QAAf,CAAwBc,mBAAxB,CAAnB,EAA+D;EAC7D,WAAKyF,UAAL,GAAkB,KAAlB;EACA;EACD;;EAED,QAAM2D,UAAU,GAAG,KAAKL,kBAAL,CAAwBgB,WAAxB,EAAqCd,kBAArC,CAAnB;;EACA,QAAIG,UAAU,CAAC3K,kBAAX,EAAJ,EAAqC;EACnC;EACD;;EAED,QAAI,CAAC6C,aAAD,IAAkB,CAACyI,WAAvB,EAAoC;EAClC;EACA;EACD;;EAED,SAAKtE,UAAL,GAAkB,IAAlB;;EAEA,QAAIwE,SAAJ,EAAe;EACb,WAAKjH,KAAL;EACD;;EAED,SAAKsG,0BAAL,CAAgCS,WAAhC;;EACA,SAAKxE,cAAL,GAAsBwE,WAAtB;EAEA,QAAMK,SAAS,GAAG9R,qBAAC,CAAC0G,KAAF,CAAQyE,UAAR,EAAoB;EACpCuF,MAAAA,aAAa,EAAEe,WADqB;EAEpCzC,MAAAA,SAAS,EAAE2B,kBAFyB;EAGpCI,MAAAA,IAAI,EAAES,kBAH8B;EAIpC5C,MAAAA,EAAE,EAAE8C;EAJgC,KAApB,CAAlB;;EAOA,QAAI1R,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BkF,gBAA1B,CAAJ,EAAiD;EAC/C9L,MAAAA,qBAAC,CAACyR,WAAD,CAAD,CAAeL,QAAf,CAAwBS,cAAxB;EAEAjR,MAAAA,IAAI,CAAC6B,MAAL,CAAYgP,WAAZ;EAEAzR,MAAAA,qBAAC,CAACgJ,aAAD,CAAD,CAAiBoI,QAAjB,CAA0BQ,oBAA1B;EACA5R,MAAAA,qBAAC,CAACyR,WAAD,CAAD,CAAeL,QAAf,CAAwBQ,oBAAxB;EAEA,UAAM1P,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC+G,aAAtC,CAA3B;EAEAhJ,MAAAA,qBAAC,CAACgJ,aAAD,CAAD,CACGrI,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4B,YAAM;EAC9Bc,QAAAA,qBAAC,CAACyR,WAAD,CAAD,CACG9K,WADH,CACkBiL,oBADlB,SAC0CC,cAD1C,EAEGT,QAFH,CAEY1J,mBAFZ;EAIA1H,QAAAA,qBAAC,CAACgJ,aAAD,CAAD,CAAiBrC,WAAjB,CAAgCe,mBAAhC,SAAqDmK,cAArD,SAAuED,oBAAvE;EAEA,QAAA,MAAI,CAACzE,UAAL,GAAkB,KAAlB;EAEAtM,QAAAA,UAAU,CAAC;EAAA,iBAAMb,qBAAC,CAAC,MAAI,CAAC6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBmP,SAAzB,CAAN;EAAA,SAAD,EAA4C,CAA5C,CAAV;EACD,OAXH,EAYG7Q,oBAZH,CAYwBiB,kBAZxB;EAaD,KAvBD,MAuBO;EACLlC,MAAAA,qBAAC,CAACgJ,aAAD,CAAD,CAAiBrC,WAAjB,CAA6Be,mBAA7B;EACA1H,MAAAA,qBAAC,CAACyR,WAAD,CAAD,CAAeL,QAAf,CAAwB1J,mBAAxB;EAEA,WAAKyF,UAAL,GAAkB,KAAlB;EACAnN,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBmP,SAAzB;EACD;;EAED,QAAIH,SAAJ,EAAe;EACb,WAAKrD,KAAL;EACD;EACF;;;aAIMtH,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAIE,IAAI,GAAGnH,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,CAAX;;EACA,UAAIsI,OAAO,gBACNjD,OADM,EAENtK,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,EAFM,CAAX;;EAKA,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9BqK,QAAAA,OAAO,gBACFA,OADE,EAEFrK,MAFE,CAAP;EAID;;EAED,UAAM6O,MAAM,GAAG,OAAO7O,MAAP,KAAkB,QAAlB,GAA6BA,MAA7B,GAAsCqK,OAAO,CAAC9C,KAA7D;;EAEA,UAAI,CAACtD,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAI2F,QAAJ,CAAa,IAAb,EAAmBS,OAAnB,CAAP;EACAvN,QAAAA,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,EAAuBkC,IAAvB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9BiE,QAAAA,IAAI,CAACyH,EAAL,CAAQ1L,MAAR;EACD,OAFD,MAEO,IAAI,OAAO6O,MAAP,KAAkB,QAAtB,EAAgC;EACrC,YAAI,OAAO5K,IAAI,CAAC4K,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIxN,SAAJ,wBAAkCwN,MAAlC,QAAN;EACD;;EAED5K,QAAAA,IAAI,CAAC4K,MAAD,CAAJ;EACD,OANM,MAMA,IAAIxE,OAAO,CAAChD,QAAR,IAAoBgD,OAAO,CAACyE,IAAhC,EAAsC;EAC3C7K,QAAAA,IAAI,CAACuD,KAAL;EACAvD,QAAAA,IAAI,CAACmH,KAAL;EACD;EACF,KAjCM,CAAP;EAkCD;;aAEM2D,uBAAP,8BAA4BlS,KAA5B,EAAmC;EACjC,QAAM4B,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4B,IAA5B,CAAjB;;EAEA,QAAI,CAACE,QAAL,EAAe;EACb;EACD;;EAED,QAAM1B,MAAM,GAAGD,qBAAC,CAAC2B,QAAD,CAAD,CAAY,CAAZ,CAAf;;EAEA,QAAI,CAAC1B,MAAD,IAAW,CAACD,qBAAC,CAACC,MAAD,CAAD,CAAU2G,QAAV,CAAmBiF,mBAAnB,CAAhB,EAAyD;EACvD;EACD;;EAED,QAAM3I,MAAM,gBACPlD,qBAAC,CAACC,MAAD,CAAD,CAAUkH,IAAV,EADO,EAEPnH,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,EAFO,CAAZ;;EAIA,QAAM+K,UAAU,GAAG,KAAKtQ,YAAL,CAAkB,eAAlB,CAAnB;;EAEA,QAAIsQ,UAAJ,EAAgB;EACdhP,MAAAA,MAAM,CAACqH,QAAP,GAAkB,KAAlB;EACD;;EAEDuC,IAAAA,QAAQ,CAAC9F,gBAAT,CAA0BxH,IAA1B,CAA+BQ,qBAAC,CAACC,MAAD,CAAhC,EAA0CiD,MAA1C;;EAEA,QAAIgP,UAAJ,EAAgB;EACdlS,MAAAA,qBAAC,CAACC,MAAD,CAAD,CAAUkH,IAAV,CAAelC,UAAf,EAAyB2J,EAAzB,CAA4BsD,UAA5B;EACD;;EAEDnS,IAAAA,KAAK,CAACuH,cAAN;EACD;;;;0BAldoB;EACnB,aAAOtC,SAAP;EACD;;;0BAEoB;EACnB,aAAOsF,OAAP;EACD;;;;;EA+cH;EACA;EACA;EACA;EACA;;;AAEAtK,uBAAC,CAACuB,QAAD,CAAD,CAAYgG,EAAZ,CAAe/B,sBAAf,EAAqCiH,mBAArC,EAA0DK,QAAQ,CAACmF,oBAAnE;AAEAjS,uBAAC,CAAC0J,MAAD,CAAD,CAAUnC,EAAV,CAAac,qBAAb,EAAkC,YAAM;EACtC,MAAM8J,SAAS,GAAG,GAAGvI,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B6C,kBAA1B,CAAd,CAAlB;;EACA,OAAK,IAAI5C,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGoI,SAAS,CAACnI,MAAhC,EAAwCF,CAAC,GAAGC,GAA5C,EAAiDD,CAAC,EAAlD,EAAsD;EACpD,QAAMsI,SAAS,GAAGpS,qBAAC,CAACmS,SAAS,CAACrI,CAAD,CAAV,CAAnB;;EACAgD,IAAAA,QAAQ,CAAC9F,gBAAT,CAA0BxH,IAA1B,CAA+B4S,SAA/B,EAA0CA,SAAS,CAACjL,IAAV,EAA1C;EACD;EACF,CAND;EAQA;EACA;EACA;EACA;EACA;;AAEAnH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAa+H,QAAQ,CAAC9F,gBAAtB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyBsF,QAAzB;;AACA9M,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAO0H,QAAQ,CAAC9F,gBAAhB;EACD,CAHD;;ECrlBA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,UAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,aAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAME,cAAY,GAAG,WAArB;EACA,IAAMC,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EAEA,IAAMuF,SAAO,GAAG;EACd9B,EAAAA,MAAM,EAAE,IADM;EAEdjC,EAAAA,MAAM,EAAE;EAFM,CAAhB;EAKA,IAAMsE,aAAW,GAAG;EAClBrC,EAAAA,MAAM,EAAE,SADU;EAElBjC,EAAAA,MAAM,EAAE;EAFU,CAApB;EAKA,IAAM8L,UAAU,YAAUnN,WAA1B;EACA,IAAMoN,WAAW,aAAWpN,WAA5B;EACA,IAAMqN,UAAU,YAAUrN,WAA1B;EACA,IAAMsN,YAAY,cAAYtN,WAA9B;EACA,IAAMM,sBAAoB,aAAWN,WAAX,GAAuBC,cAAjD;EAEA,IAAMQ,iBAAe,GAAG,MAAxB;EACA,IAAM8M,mBAAmB,GAAG,UAA5B;EACA,IAAMC,qBAAqB,GAAG,YAA9B;EACA,IAAMC,oBAAoB,GAAG,WAA7B;EAEA,IAAMC,eAAe,GAAG,OAAxB;EACA,IAAMC,gBAAgB,GAAG,QAAzB;EAEA,IAAMC,gBAAgB,GAAG,oBAAzB;EACA,IAAM/K,sBAAoB,GAAG,0BAA7B;EAEA;EACA;EACA;EACA;EACA;;MAEMgL;EACJ,oBAAYrR,OAAZ,EAAqBwB,MAArB,EAA6B;EAC3B,SAAK8P,gBAAL,GAAwB,KAAxB;EACA,SAAKnN,QAAL,GAAgBnE,OAAhB;EACA,SAAK6L,OAAL,GAAe,KAAKC,UAAL,CAAgBtK,MAAhB,CAAf;EACA,SAAK+P,aAAL,GAAqB,GAAGrJ,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CACjC,wCAAmCnI,OAAO,CAACwR,EAA3C,4DAC0CxR,OAAO,CAACwR,EADlD,SADiC,CAAd,CAArB;EAKA,QAAMC,UAAU,GAAG,GAAGvJ,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B9B,sBAA1B,CAAd,CAAnB;;EACA,SAAK,IAAI+B,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGoJ,UAAU,CAACnJ,MAAjC,EAAyCF,CAAC,GAAGC,GAA7C,EAAkDD,CAAC,EAAnD,EAAuD;EACrD,UAAMsJ,IAAI,GAAGD,UAAU,CAACrJ,CAAD,CAAvB;EACA,UAAMnI,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4B2R,IAA5B,CAAjB;EACA,UAAMC,aAAa,GAAG,GAAGzJ,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0BlI,QAA1B,CAAd,EACnB2R,MADmB,CACZ,UAAAC,SAAS;EAAA,eAAIA,SAAS,KAAK7R,OAAlB;EAAA,OADG,CAAtB;;EAGA,UAAIC,QAAQ,KAAK,IAAb,IAAqB0R,aAAa,CAACrJ,MAAd,GAAuB,CAAhD,EAAmD;EACjD,aAAKwJ,SAAL,GAAiB7R,QAAjB;;EACA,aAAKsR,aAAL,CAAmBQ,IAAnB,CAAwBL,IAAxB;EACD;EACF;;EAED,SAAKM,OAAL,GAAe,KAAKnG,OAAL,CAAahH,MAAb,GAAsB,KAAKoN,UAAL,EAAtB,GAA0C,IAAzD;;EAEA,QAAI,CAAC,KAAKpG,OAAL,CAAahH,MAAlB,EAA0B;EACxB,WAAKqN,yBAAL,CAA+B,KAAK/N,QAApC,EAA8C,KAAKoN,aAAnD;EACD;;EAED,QAAI,KAAK1F,OAAL,CAAa/E,MAAjB,EAAyB;EACvB,WAAKA,MAAL;EACD;EACF;;;;;EAYD;WAEAA,SAAA,kBAAS;EACP,QAAIxI,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BjB,iBAA1B,CAAJ,EAAgD;EAC9C,WAAKkO,IAAL;EACD,KAFD,MAEO;EACL,WAAKC,IAAL;EACD;EACF;;WAEDA,OAAA,gBAAO;EAAA;;EACL,QAAI,KAAKd,gBAAL,IACFhT,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BjB,iBAA1B,CADF,EAC8C;EAC5C;EACD;;EAED,QAAIoO,OAAJ;EACA,QAAIC,WAAJ;;EAEA,QAAI,KAAKN,OAAT,EAAkB;EAChBK,MAAAA,OAAO,GAAG,GAAGnK,KAAH,CAASpK,IAAT,CAAc,KAAKkU,OAAL,CAAa7J,gBAAb,CAA8BiJ,gBAA9B,CAAd,EACPQ,MADO,CACA,UAAAF,IAAI,EAAI;EACd,YAAI,OAAO,KAAI,CAAC7F,OAAL,CAAahH,MAApB,KAA+B,QAAnC,EAA6C;EAC3C,iBAAO6M,IAAI,CAACxR,YAAL,CAAkB,aAAlB,MAAqC,KAAI,CAAC2L,OAAL,CAAahH,MAAzD;EACD;;EAED,eAAO6M,IAAI,CAACtK,SAAL,CAAeC,QAAf,CAAwB0J,mBAAxB,CAAP;EACD,OAPO,CAAV;;EASA,UAAIsB,OAAO,CAAC/J,MAAR,KAAmB,CAAvB,EAA0B;EACxB+J,QAAAA,OAAO,GAAG,IAAV;EACD;EACF;;EAED,QAAIA,OAAJ,EAAa;EACXC,MAAAA,WAAW,GAAGhU,qBAAC,CAAC+T,OAAD,CAAD,CAAWE,GAAX,CAAe,KAAKT,SAApB,EAA+BrM,IAA/B,CAAoClC,UAApC,CAAd;;EACA,UAAI+O,WAAW,IAAIA,WAAW,CAAChB,gBAA/B,EAAiD;EAC/C;EACD;EACF;;EAED,QAAMkB,UAAU,GAAGlU,qBAAC,CAAC0G,KAAF,CAAQ2L,UAAR,CAAnB;EACArS,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBuR,UAAzB;;EACA,QAAIA,UAAU,CAAC/N,kBAAX,EAAJ,EAAqC;EACnC;EACD;;EAED,QAAI4N,OAAJ,EAAa;EACXhB,MAAAA,QAAQ,CAAC/L,gBAAT,CAA0BxH,IAA1B,CAA+BQ,qBAAC,CAAC+T,OAAD,CAAD,CAAWE,GAAX,CAAe,KAAKT,SAApB,CAA/B,EAA+D,MAA/D;;EACA,UAAI,CAACQ,WAAL,EAAkB;EAChBhU,QAAAA,qBAAC,CAAC+T,OAAD,CAAD,CAAW5M,IAAX,CAAgBlC,UAAhB,EAA0B,IAA1B;EACD;EACF;;EAED,QAAMkP,SAAS,GAAG,KAAKC,aAAL,EAAlB;;EAEApU,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACGc,WADH,CACe8L,mBADf,EAEGrB,QAFH,CAEYsB,qBAFZ;EAIA,SAAK7M,QAAL,CAAcwO,KAAd,CAAoBF,SAApB,IAAiC,CAAjC;;EAEA,QAAI,KAAKlB,aAAL,CAAmBjJ,MAAvB,EAA+B;EAC7BhK,MAAAA,qBAAC,CAAC,KAAKiT,aAAN,CAAD,CACGtM,WADH,CACegM,oBADf,EAEG2B,IAFH,CAEQ,eAFR,EAEyB,IAFzB;EAGD;;EAED,SAAKC,gBAAL,CAAsB,IAAtB;;EAEA,QAAMC,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrBxU,MAAAA,qBAAC,CAAC,KAAI,CAAC6F,QAAN,CAAD,CACGc,WADH,CACe+L,qBADf,EAEGtB,QAFH,CAEeqB,mBAFf,SAEsC9M,iBAFtC;EAIA,MAAA,KAAI,CAACE,QAAL,CAAcwO,KAAd,CAAoBF,SAApB,IAAiC,EAAjC;;EAEA,MAAA,KAAI,CAACI,gBAAL,CAAsB,KAAtB;;EAEAvU,MAAAA,qBAAC,CAAC,KAAI,CAAC6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyB2P,WAAzB;EACD,KAVD;;EAYA,QAAMmC,oBAAoB,GAAGN,SAAS,CAAC,CAAD,CAAT,CAAarQ,WAAb,KAA6BqQ,SAAS,CAACvK,KAAV,CAAgB,CAAhB,CAA1D;EACA,QAAM8K,UAAU,cAAYD,oBAA5B;EACA,QAAMvS,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC,KAAK4D,QAA3C,CAA3B;EAEA7F,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACGlF,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4BsV,QAD5B,EAEGvT,oBAFH,CAEwBiB,kBAFxB;EAIA,SAAK2D,QAAL,CAAcwO,KAAd,CAAoBF,SAApB,IAAoC,KAAKtO,QAAL,CAAc6O,UAAd,CAApC;EACD;;WAEDb,OAAA,gBAAO;EAAA;;EACL,QAAI,KAAKb,gBAAL,IACF,CAAChT,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BjB,iBAA1B,CADH,EAC+C;EAC7C;EACD;;EAED,QAAMuO,UAAU,GAAGlU,qBAAC,CAAC0G,KAAF,CAAQ6L,UAAR,CAAnB;EACAvS,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBuR,UAAzB;;EACA,QAAIA,UAAU,CAAC/N,kBAAX,EAAJ,EAAqC;EACnC;EACD;;EAED,QAAMgO,SAAS,GAAG,KAAKC,aAAL,EAAlB;;EAEA,SAAKvO,QAAL,CAAcwO,KAAd,CAAoBF,SAApB,IAAoC,KAAKtO,QAAL,CAAc8O,qBAAd,GAAsCR,SAAtC,CAApC;EAEAvT,IAAAA,IAAI,CAAC6B,MAAL,CAAY,KAAKoD,QAAjB;EAEA7F,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACGuL,QADH,CACYsB,qBADZ,EAEG/L,WAFH,CAEkB8L,mBAFlB,SAEyC9M,iBAFzC;EAIA,QAAMiP,kBAAkB,GAAG,KAAK3B,aAAL,CAAmBjJ,MAA9C;;EACA,QAAI4K,kBAAkB,GAAG,CAAzB,EAA4B;EAC1B,WAAK,IAAI9K,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG8K,kBAApB,EAAwC9K,CAAC,EAAzC,EAA6C;EAC3C,YAAMnH,OAAO,GAAG,KAAKsQ,aAAL,CAAmBnJ,CAAnB,CAAhB;EACA,YAAMnI,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4BkB,OAA5B,CAAjB;;EAEA,YAAIhB,QAAQ,KAAK,IAAjB,EAAuB;EACrB,cAAMkT,KAAK,GAAG7U,qBAAC,CAAC,GAAG4J,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0BlI,QAA1B,CAAd,CAAD,CAAf;;EACA,cAAI,CAACkT,KAAK,CAACjO,QAAN,CAAejB,iBAAf,CAAL,EAAsC;EACpC3F,YAAAA,qBAAC,CAAC2C,OAAD,CAAD,CAAWyO,QAAX,CAAoBuB,oBAApB,EACG2B,IADH,CACQ,eADR,EACyB,KADzB;EAED;EACF;EACF;EACF;;EAED,SAAKC,gBAAL,CAAsB,IAAtB;;EAEA,QAAMC,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,MAAA,MAAI,CAACD,gBAAL,CAAsB,KAAtB;;EACAvU,MAAAA,qBAAC,CAAC,MAAI,CAAC6F,QAAN,CAAD,CACGc,WADH,CACe+L,qBADf,EAEGtB,QAFH,CAEYqB,mBAFZ,EAGG9P,OAHH,CAGW6P,YAHX;EAID,KAND;;EAQA,SAAK3M,QAAL,CAAcwO,KAAd,CAAoBF,SAApB,IAAiC,EAAjC;EACA,QAAMjS,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC,KAAK4D,QAA3C,CAA3B;EAEA7F,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACGlF,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4BsV,QAD5B,EAEGvT,oBAFH,CAEwBiB,kBAFxB;EAGD;;WAEDqS,mBAAA,0BAAiBO,eAAjB,EAAkC;EAChC,SAAK9B,gBAAL,GAAwB8B,eAAxB;EACD;;WAEDzO,UAAA,mBAAU;EACRrG,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EAEA,SAAKsI,OAAL,GAAe,IAAf;EACA,SAAKmG,OAAL,GAAe,IAAf;EACA,SAAK7N,QAAL,GAAgB,IAAhB;EACA,SAAKoN,aAAL,GAAqB,IAArB;EACA,SAAKD,gBAAL,GAAwB,IAAxB;EACD;;;WAIDxF,aAAA,oBAAWtK,MAAX,EAAmB;EACjBA,IAAAA,MAAM,gBACDoH,SADC,EAEDpH,MAFC,CAAN;EAIAA,IAAAA,MAAM,CAACsF,MAAP,GAAgB3F,OAAO,CAACK,MAAM,CAACsF,MAAR,CAAvB,CALiB;;EAMjB5H,IAAAA,IAAI,CAACoC,eAAL,CAAqB+B,MAArB,EAA2B7B,MAA3B,EAAmC2H,aAAnC;EACA,WAAO3H,MAAP;EACD;;WAEDkR,gBAAA,yBAAgB;EACd,QAAMW,QAAQ,GAAG/U,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BgM,eAA1B,CAAjB;EACA,WAAOmC,QAAQ,GAAGnC,eAAH,GAAqBC,gBAApC;EACD;;WAEDc,aAAA,sBAAa;EAAA;;EACX,QAAIpN,MAAJ;;EAEA,QAAI3F,IAAI,CAACkC,SAAL,CAAe,KAAKyK,OAAL,CAAahH,MAA5B,CAAJ,EAAyC;EACvCA,MAAAA,MAAM,GAAG,KAAKgH,OAAL,CAAahH,MAAtB,CADuC;;EAIvC,UAAI,OAAO,KAAKgH,OAAL,CAAahH,MAAb,CAAoB9B,MAA3B,KAAsC,WAA1C,EAAuD;EACrD8B,QAAAA,MAAM,GAAG,KAAKgH,OAAL,CAAahH,MAAb,CAAoB,CAApB,CAAT;EACD;EACF,KAPD,MAOO;EACLA,MAAAA,MAAM,GAAGhF,QAAQ,CAACQ,aAAT,CAAuB,KAAKwL,OAAL,CAAahH,MAApC,CAAT;EACD;;EAED,QAAM5E,QAAQ,iDAA4C,KAAK4L,OAAL,CAAahH,MAAzD,QAAd;EACA,QAAM4K,QAAQ,GAAG,GAAGvH,KAAH,CAASpK,IAAT,CAAc+G,MAAM,CAACsD,gBAAP,CAAwBlI,QAAxB,CAAd,CAAjB;EAEA3B,IAAAA,qBAAC,CAACmR,QAAD,CAAD,CAAYlK,IAAZ,CAAiB,UAAC6C,CAAD,EAAIpI,OAAJ,EAAgB;EAC/B,MAAA,MAAI,CAACkS,yBAAL,CACEb,QAAQ,CAACiC,qBAAT,CAA+BtT,OAA/B,CADF,EAEE,CAACA,OAAD,CAFF;EAID,KALD;EAOA,WAAO6E,MAAP;EACD;;WAEDqN,4BAAA,mCAA0BlS,OAA1B,EAAmCuT,YAAnC,EAAiD;EAC/C,QAAMC,MAAM,GAAGlV,qBAAC,CAAC0B,OAAD,CAAD,CAAWkF,QAAX,CAAoBjB,iBAApB,CAAf;;EAEA,QAAIsP,YAAY,CAACjL,MAAjB,EAAyB;EACvBhK,MAAAA,qBAAC,CAACiV,YAAD,CAAD,CACG7L,WADH,CACeuJ,oBADf,EACqC,CAACuC,MADtC,EAEGZ,IAFH,CAEQ,eAFR,EAEyBY,MAFzB;EAGD;EACF;;;aAIMF,wBAAP,+BAA6BtT,OAA7B,EAAsC;EACpC,QAAMC,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4BC,OAA5B,CAAjB;EACA,WAAOC,QAAQ,GAAGJ,QAAQ,CAACQ,aAAT,CAAuBJ,QAAvB,CAAH,GAAsC,IAArD;EACD;;aAEMqF,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAMC,QAAQ,GAAGlH,qBAAC,CAAC,IAAD,CAAlB;EACA,UAAImH,IAAI,GAAGD,QAAQ,CAACC,IAAT,CAAclC,UAAd,CAAX;;EACA,UAAMsI,OAAO,gBACRjD,SADQ,EAERpD,QAAQ,CAACC,IAAT,EAFQ,EAGP,OAAOjE,MAAP,KAAkB,QAAlB,IAA8BA,MAA9B,GAAuCA,MAAvC,GAAgD,EAHzC,CAAb;;EAMA,UAAI,CAACiE,IAAD,IAASoG,OAAO,CAAC/E,MAAjB,IAA2B,OAAOtF,MAAP,KAAkB,QAA7C,IAAyD,YAAYU,IAAZ,CAAiBV,MAAjB,CAA7D,EAAuF;EACrFqK,QAAAA,OAAO,CAAC/E,MAAR,GAAiB,KAAjB;EACD;;EAED,UAAI,CAACrB,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAI4L,QAAJ,CAAa,IAAb,EAAmBxF,OAAnB,CAAP;EACArG,QAAAA,QAAQ,CAACC,IAAT,CAAclC,UAAd,EAAwBkC,IAAxB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ;EACD;EACF,KAzBM,CAAP;EA0BD;;;;0BAnQoB;EACnB,aAAO8B,SAAP;EACD;;;0BAEoB;EACnB,aAAOsF,SAAP;EACD;;;;;EAgQH;EACA;EACA;EACA;EACA;;;AAEAtK,uBAAC,CAACuB,QAAD,CAAD,CAAYgG,EAAZ,CAAe/B,sBAAf,EAAqCuC,sBAArC,EAA2D,UAAUhI,KAAV,EAAiB;EAC1E;EACA,MAAIA,KAAK,CAACoV,aAAN,CAAoB1L,OAApB,KAAgC,GAApC,EAAyC;EACvC1J,IAAAA,KAAK,CAACuH,cAAN;EACD;;EAED,MAAM8N,QAAQ,GAAGpV,qBAAC,CAAC,IAAD,CAAlB;EACA,MAAM2B,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4B,IAA5B,CAAjB;EACA,MAAM4T,SAAS,GAAG,GAAGzL,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0BlI,QAA1B,CAAd,CAAlB;EAEA3B,EAAAA,qBAAC,CAACqV,SAAD,CAAD,CAAapO,IAAb,CAAkB,YAAY;EAC5B,QAAMqO,OAAO,GAAGtV,qBAAC,CAAC,IAAD,CAAjB;EACA,QAAMmH,IAAI,GAAGmO,OAAO,CAACnO,IAAR,CAAalC,UAAb,CAAb;EACA,QAAM/B,MAAM,GAAGiE,IAAI,GAAG,QAAH,GAAciO,QAAQ,CAACjO,IAAT,EAAjC;;EACA4L,IAAAA,QAAQ,CAAC/L,gBAAT,CAA0BxH,IAA1B,CAA+B8V,OAA/B,EAAwCpS,MAAxC;EACD,GALD;EAMD,CAhBD;EAkBA;EACA;EACA;EACA;EACA;;AAEAlD,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAagO,QAAQ,CAAC/L,gBAAtB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyBuL,QAAzB;;AACA/S,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAO2N,QAAQ,CAAC/L,gBAAhB;EACD,CAHD;;ECvXA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,UAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,aAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAME,cAAY,GAAG,WAArB;EACA,IAAMC,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EACA,IAAMwQ,cAAc,GAAG,EAAvB;;EACA,IAAMC,aAAa,GAAG,EAAtB;;EACA,IAAMC,WAAW,GAAG,CAApB;;EACA,IAAMC,gBAAgB,GAAG,EAAzB;;EACA,IAAMC,kBAAkB,GAAG,EAA3B;;EACA,IAAMC,wBAAwB,GAAG,CAAjC;;EACA,IAAMC,cAAc,GAAG,IAAIlS,MAAJ,CAAc+R,gBAAd,SAAkCC,kBAAlC,SAAwDJ,cAAxD,CAAvB;EAEA,IAAMhD,YAAU,YAAUrN,WAA1B;EACA,IAAMsN,cAAY,cAAYtN,WAA9B;EACA,IAAMmN,YAAU,YAAUnN,WAA1B;EACA,IAAMoN,aAAW,aAAWpN,WAA5B;EACA,IAAM4Q,WAAW,aAAW5Q,WAA5B;EACA,IAAMM,sBAAoB,aAAWN,WAAX,GAAuBC,cAAjD;EACA,IAAM4Q,sBAAsB,eAAa7Q,WAAb,GAAyBC,cAArD;EACA,IAAM6Q,oBAAoB,aAAW9Q,WAAX,GAAuBC,cAAjD;EAEA,IAAM8Q,mBAAmB,GAAG,UAA5B;EACA,IAAMtQ,iBAAe,GAAG,MAAxB;EACA,IAAMuQ,iBAAiB,GAAG,QAA1B;EACA,IAAMC,oBAAoB,GAAG,WAA7B;EACA,IAAMC,mBAAmB,GAAG,UAA5B;EACA,IAAMC,oBAAoB,GAAG,qBAA7B;EACA,IAAMC,0BAA0B,GAAG,iBAAnC;EAEA,IAAMvO,sBAAoB,GAAG,0BAA7B;EACA,IAAMwO,mBAAmB,GAAG,gBAA5B;EACA,IAAMC,aAAa,GAAG,gBAAtB;EACA,IAAMC,mBAAmB,GAAG,aAA5B;EACA,IAAMC,sBAAsB,GAAG,6DAA/B;EAEA,IAAMC,aAAa,GAAG,WAAtB;EACA,IAAMC,gBAAgB,GAAG,SAAzB;EACA,IAAMC,gBAAgB,GAAG,cAAzB;EACA,IAAMC,mBAAmB,GAAG,YAA5B;EACA,IAAMC,eAAe,GAAG,aAAxB;EACA,IAAMC,cAAc,GAAG,YAAvB;EAEA,IAAM1M,SAAO,GAAG;EACd2M,EAAAA,MAAM,EAAE,CADM;EAEdC,EAAAA,IAAI,EAAE,IAFQ;EAGdC,EAAAA,QAAQ,EAAE,cAHI;EAIdC,EAAAA,SAAS,EAAE,QAJG;EAKdC,EAAAA,OAAO,EAAE,SALK;EAMdC,EAAAA,YAAY,EAAE;EANA,CAAhB;EASA,IAAMzM,aAAW,GAAG;EAClBoM,EAAAA,MAAM,EAAE,0BADU;EAElBC,EAAAA,IAAI,EAAE,SAFY;EAGlBC,EAAAA,QAAQ,EAAE,kBAHQ;EAIlBC,EAAAA,SAAS,EAAE,kBAJO;EAKlBC,EAAAA,OAAO,EAAE,QALS;EAMlBC,EAAAA,YAAY,EAAE;EANI,CAApB;EASA;EACA;EACA;EACA;EACA;;MAEMC;EACJ,oBAAY7V,OAAZ,EAAqBwB,MAArB,EAA6B;EAC3B,SAAK2C,QAAL,GAAgBnE,OAAhB;EACA,SAAK8V,OAAL,GAAe,IAAf;EACA,SAAKjK,OAAL,GAAe,KAAKC,UAAL,CAAgBtK,MAAhB,CAAf;EACA,SAAKuU,KAAL,GAAa,KAAKC,eAAL,EAAb;EACA,SAAKC,SAAL,GAAiB,KAAKC,aAAL,EAAjB;;EAEA,SAAK5J,kBAAL;EACD;;;;;EAgBD;WAEAxF,SAAA,kBAAS;EACP,QAAI,KAAK3C,QAAL,CAAcgS,QAAd,IAA0B7X,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BqP,mBAA1B,CAA9B,EAA8E;EAC5E;EACD;;EAED,QAAM6B,QAAQ,GAAG9X,qBAAC,CAAC,KAAKyX,KAAN,CAAD,CAAc7Q,QAAd,CAAuBjB,iBAAvB,CAAjB;;EAEA4R,IAAAA,QAAQ,CAACQ,WAAT;;EAEA,QAAID,QAAJ,EAAc;EACZ;EACD;;EAED,SAAKhE,IAAL,CAAU,IAAV;EACD;;WAEDA,OAAA,cAAKkE,SAAL,EAAwB;EAAA,QAAnBA,SAAmB;EAAnBA,MAAAA,SAAmB,GAAP,KAAO;EAAA;;EACtB,QAAI,KAAKnS,QAAL,CAAcgS,QAAd,IAA0B7X,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BqP,mBAA1B,CAA1B,IAA4EjW,qBAAC,CAAC,KAAKyX,KAAN,CAAD,CAAc7Q,QAAd,CAAuBjB,iBAAvB,CAAhF,EAAyH;EACvH;EACD;;EAED,QAAM+K,aAAa,GAAG;EACpBA,MAAAA,aAAa,EAAE,KAAK7K;EADA,KAAtB;EAGA,QAAMoS,SAAS,GAAGjY,qBAAC,CAAC0G,KAAF,CAAQ2L,YAAR,EAAoB3B,aAApB,CAAlB;;EACA,QAAMnK,MAAM,GAAGgR,QAAQ,CAACW,qBAAT,CAA+B,KAAKrS,QAApC,CAAf;;EAEA7F,IAAAA,qBAAC,CAACuG,MAAD,CAAD,CAAU5D,OAAV,CAAkBsV,SAAlB;;EAEA,QAAIA,SAAS,CAAC9R,kBAAV,EAAJ,EAAoC;EAClC;EACD,KAfqB;;;EAkBtB,QAAI,CAAC,KAAKwR,SAAN,IAAmBK,SAAvB,EAAkC;EAChC;EACN;EACA;EACA;EACM,UAAI,OAAOG,0BAAP,KAAkB,WAAtB,EAAmC;EACjC,cAAM,IAAI5T,SAAJ,CAAc,+DAAd,CAAN;EACD;;EAED,UAAI6T,gBAAgB,GAAG,KAAKvS,QAA5B;;EAEA,UAAI,KAAK0H,OAAL,CAAa6J,SAAb,KAA2B,QAA/B,EAAyC;EACvCgB,QAAAA,gBAAgB,GAAG7R,MAAnB;EACD,OAFD,MAEO,IAAI3F,IAAI,CAACkC,SAAL,CAAe,KAAKyK,OAAL,CAAa6J,SAA5B,CAAJ,EAA4C;EACjDgB,QAAAA,gBAAgB,GAAG,KAAK7K,OAAL,CAAa6J,SAAhC,CADiD;;EAIjD,YAAI,OAAO,KAAK7J,OAAL,CAAa6J,SAAb,CAAuB3S,MAA9B,KAAyC,WAA7C,EAA0D;EACxD2T,UAAAA,gBAAgB,GAAG,KAAK7K,OAAL,CAAa6J,SAAb,CAAuB,CAAvB,CAAnB;EACD;EACF,OApB+B;EAuBhC;EACA;;;EACA,UAAI,KAAK7J,OAAL,CAAa4J,QAAb,KAA0B,cAA9B,EAA8C;EAC5CnX,QAAAA,qBAAC,CAACuG,MAAD,CAAD,CAAU6K,QAAV,CAAmBkF,0BAAnB;EACD;;EAED,WAAKkB,OAAL,GAAe,IAAIW,0BAAJ,CAAWC,gBAAX,EAA6B,KAAKX,KAAlC,EAAyC,KAAKY,gBAAL,EAAzC,CAAf;EACD,KAhDqB;EAmDtB;EACA;EACA;;;EACA,QAAI,kBAAkB9W,QAAQ,CAACyC,eAA3B,IACAhE,qBAAC,CAACuG,MAAD,CAAD,CAAUC,OAAV,CAAkBiQ,mBAAlB,EAAuCzM,MAAvC,KAAkD,CADtD,EACyD;EACvDhK,MAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBnH,QAAjB,GAA4B5J,EAA5B,CAA+B,WAA/B,EAA4C,IAA5C,EAAkDvH,qBAAC,CAACuY,IAApD;EACD;;EAED,SAAK1S,QAAL,CAAcoD,KAAd;;EACA,SAAKpD,QAAL,CAAcsD,YAAd,CAA2B,eAA3B,EAA4C,IAA5C;;EAEAnJ,IAAAA,qBAAC,CAAC,KAAKyX,KAAN,CAAD,CAAcrO,WAAd,CAA0BzD,iBAA1B;EACA3F,IAAAA,qBAAC,CAACuG,MAAD,CAAD,CACG6C,WADH,CACezD,iBADf,EAEGhD,OAFH,CAEW3C,qBAAC,CAAC0G,KAAF,CAAQ4L,aAAR,EAAqB5B,aAArB,CAFX;EAGD;;WAEDmD,OAAA,gBAAO;EACL,QAAI,KAAKhO,QAAL,CAAcgS,QAAd,IAA0B7X,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BqP,mBAA1B,CAA1B,IAA4E,CAACjW,qBAAC,CAAC,KAAKyX,KAAN,CAAD,CAAc7Q,QAAd,CAAuBjB,iBAAvB,CAAjF,EAA0H;EACxH;EACD;;EAED,QAAM+K,aAAa,GAAG;EACpBA,MAAAA,aAAa,EAAE,KAAK7K;EADA,KAAtB;EAGA,QAAM2S,SAAS,GAAGxY,qBAAC,CAAC0G,KAAF,CAAQ6L,YAAR,EAAoB7B,aAApB,CAAlB;;EACA,QAAMnK,MAAM,GAAGgR,QAAQ,CAACW,qBAAT,CAA+B,KAAKrS,QAApC,CAAf;;EAEA7F,IAAAA,qBAAC,CAACuG,MAAD,CAAD,CAAU5D,OAAV,CAAkB6V,SAAlB;;EAEA,QAAIA,SAAS,CAACrS,kBAAV,EAAJ,EAAoC;EAClC;EACD;;EAED,QAAI,KAAKqR,OAAT,EAAkB;EAChB,WAAKA,OAAL,CAAaiB,OAAb;EACD;;EAEDzY,IAAAA,qBAAC,CAAC,KAAKyX,KAAN,CAAD,CAAcrO,WAAd,CAA0BzD,iBAA1B;EACA3F,IAAAA,qBAAC,CAACuG,MAAD,CAAD,CACG6C,WADH,CACezD,iBADf,EAEGhD,OAFH,CAEW3C,qBAAC,CAAC0G,KAAF,CAAQ8L,cAAR,EAAsB9B,aAAtB,CAFX;EAGD;;WAEDrK,UAAA,mBAAU;EACRrG,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EACAjF,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBoJ,GAAjB,CAAqB/J,WAArB;EACA,SAAKW,QAAL,GAAgB,IAAhB;EACA,SAAK4R,KAAL,GAAa,IAAb;;EACA,QAAI,KAAKD,OAAL,KAAiB,IAArB,EAA2B;EACzB,WAAKA,OAAL,CAAaiB,OAAb;;EACA,WAAKjB,OAAL,GAAe,IAAf;EACD;EACF;;WAEDkB,SAAA,kBAAS;EACP,SAAKf,SAAL,GAAiB,KAAKC,aAAL,EAAjB;;EACA,QAAI,KAAKJ,OAAL,KAAiB,IAArB,EAA2B;EACzB,WAAKA,OAAL,CAAamB,cAAb;EACD;EACF;;;WAID3K,qBAAA,8BAAqB;EAAA;;EACnBhO,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoBuO,WAApB,EAAiC,UAAA/V,KAAK,EAAI;EACxCA,MAAAA,KAAK,CAACuH,cAAN;EACAvH,MAAAA,KAAK,CAAC6Y,eAAN;;EACA,MAAA,KAAI,CAACpQ,MAAL;EACD,KAJD;EAKD;;WAEDgF,aAAA,oBAAWtK,MAAX,EAAmB;EACjBA,IAAAA,MAAM,gBACD,KAAK2V,WAAL,CAAiBvO,OADhB,EAEDtK,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBsB,IAAjB,EAFC,EAGDjE,MAHC,CAAN;EAMAtC,IAAAA,IAAI,CAACoC,eAAL,CACE+B,MADF,EAEE7B,MAFF,EAGE,KAAK2V,WAAL,CAAiBhO,WAHnB;EAMA,WAAO3H,MAAP;EACD;;WAEDwU,kBAAA,2BAAkB;EAChB,QAAI,CAAC,KAAKD,KAAV,EAAiB;EACf,UAAMlR,MAAM,GAAGgR,QAAQ,CAACW,qBAAT,CAA+B,KAAKrS,QAApC,CAAf;;EAEA,UAAIU,MAAJ,EAAY;EACV,aAAKkR,KAAL,GAAalR,MAAM,CAACxE,aAAP,CAAqByU,aAArB,CAAb;EACD;EACF;;EAED,WAAO,KAAKiB,KAAZ;EACD;;WAEDqB,gBAAA,yBAAgB;EACd,QAAMC,eAAe,GAAG/Y,qBAAC,CAAC,KAAK6F,QAAL,CAAcxB,UAAf,CAAzB;EACA,QAAI2U,SAAS,GAAGnC,gBAAhB,CAFc;;EAKd,QAAIkC,eAAe,CAACnS,QAAhB,CAAyBsP,iBAAzB,CAAJ,EAAiD;EAC/C8C,MAAAA,SAAS,GAAGhZ,qBAAC,CAAC,KAAKyX,KAAN,CAAD,CAAc7Q,QAAd,CAAuByP,oBAAvB,IACVO,gBADU,GAEVD,aAFF;EAGD,KAJD,MAIO,IAAIoC,eAAe,CAACnS,QAAhB,CAAyBuP,oBAAzB,CAAJ,EAAoD;EACzD6C,MAAAA,SAAS,GAAGjC,eAAZ;EACD,KAFM,MAEA,IAAIgC,eAAe,CAACnS,QAAhB,CAAyBwP,mBAAzB,CAAJ,EAAmD;EACxD4C,MAAAA,SAAS,GAAGhC,cAAZ;EACD,KAFM,MAEA,IAAIhX,qBAAC,CAAC,KAAKyX,KAAN,CAAD,CAAc7Q,QAAd,CAAuByP,oBAAvB,CAAJ,EAAkD;EACvD2C,MAAAA,SAAS,GAAGlC,mBAAZ;EACD;;EAED,WAAOkC,SAAP;EACD;;WAEDpB,gBAAA,yBAAgB;EACd,WAAO5X,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBW,OAAjB,CAAyB,SAAzB,EAAoCwD,MAApC,GAA6C,CAApD;EACD;;WAEDiP,aAAA,sBAAa;EAAA;;EACX,QAAMhC,MAAM,GAAG,EAAf;;EAEA,QAAI,OAAO,KAAK1J,OAAL,CAAa0J,MAApB,KAA+B,UAAnC,EAA+C;EAC7CA,MAAAA,MAAM,CAACjW,EAAP,GAAY,UAAAmG,IAAI,EAAI;EAClBA,QAAAA,IAAI,CAAC+R,OAAL,gBACK/R,IAAI,CAAC+R,OADV,EAEM,MAAI,CAAC3L,OAAL,CAAa0J,MAAb,CAAoB9P,IAAI,CAAC+R,OAAzB,EAAkC,MAAI,CAACrT,QAAvC,KAAoD,EAF1D;EAKA,eAAOsB,IAAP;EACD,OAPD;EAQD,KATD,MASO;EACL8P,MAAAA,MAAM,CAACA,MAAP,GAAgB,KAAK1J,OAAL,CAAa0J,MAA7B;EACD;;EAED,WAAOA,MAAP;EACD;;WAEDoB,mBAAA,4BAAmB;EACjB,QAAMf,YAAY,GAAG;EACnB0B,MAAAA,SAAS,EAAE,KAAKF,aAAL,EADQ;EAEnBK,MAAAA,SAAS,EAAE;EACTlC,QAAAA,MAAM,EAAE,KAAKgC,UAAL,EADC;EAET/B,QAAAA,IAAI,EAAE;EACJkC,UAAAA,OAAO,EAAE,KAAK7L,OAAL,CAAa2J;EADlB,SAFG;EAKTmC,QAAAA,eAAe,EAAE;EACfC,UAAAA,iBAAiB,EAAE,KAAK/L,OAAL,CAAa4J;EADjB;EALR;EAFQ,KAArB,CADiB;;EAejB,QAAI,KAAK5J,OAAL,CAAa8J,OAAb,KAAyB,QAA7B,EAAuC;EACrCC,MAAAA,YAAY,CAAC6B,SAAb,CAAuBI,UAAvB,GAAoC;EAClCH,QAAAA,OAAO,EAAE;EADyB,OAApC;EAGD;;EAED,wBACK9B,YADL,EAEK,KAAK/J,OAAL,CAAa+J,YAFlB;EAID;;;aAIMtQ,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAIE,IAAI,GAAGnH,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,CAAX;;EACA,UAAMsI,OAAO,GAAG,OAAOrK,MAAP,KAAkB,QAAlB,GAA6BA,MAA7B,GAAsC,IAAtD;;EAEA,UAAI,CAACiE,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAIoQ,QAAJ,CAAa,IAAb,EAAmBhK,OAAnB,CAAP;EACAvN,QAAAA,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,EAAuBkC,IAAvB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ;EACD;EACF,KAhBM,CAAP;EAiBD;;aAEM6U,cAAP,qBAAmBhY,KAAnB,EAA0B;EACxB,QAAIA,KAAK,KAAKA,KAAK,CAACiQ,KAAN,KAAgB4F,wBAAhB,IACZ7V,KAAK,CAAC6I,IAAN,KAAe,OAAf,IAA0B7I,KAAK,CAACiQ,KAAN,KAAgByF,WADnC,CAAT,EAC0D;EACxD;EACD;;EAED,QAAM+D,OAAO,GAAG,GAAG5P,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B9B,sBAA1B,CAAd,CAAhB;;EAEA,SAAK,IAAI+B,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGyP,OAAO,CAACxP,MAA9B,EAAsCF,CAAC,GAAGC,GAA1C,EAA+CD,CAAC,EAAhD,EAAoD;EAClD,UAAMvD,MAAM,GAAGgR,QAAQ,CAACW,qBAAT,CAA+BsB,OAAO,CAAC1P,CAAD,CAAtC,CAAf;;EACA,UAAM2P,OAAO,GAAGzZ,qBAAC,CAACwZ,OAAO,CAAC1P,CAAD,CAAR,CAAD,CAAc3C,IAAd,CAAmBlC,UAAnB,CAAhB;EACA,UAAMyL,aAAa,GAAG;EACpBA,QAAAA,aAAa,EAAE8I,OAAO,CAAC1P,CAAD;EADF,OAAtB;;EAIA,UAAI/J,KAAK,IAAIA,KAAK,CAAC6I,IAAN,KAAe,OAA5B,EAAqC;EACnC8H,QAAAA,aAAa,CAACgJ,UAAd,GAA2B3Z,KAA3B;EACD;;EAED,UAAI,CAAC0Z,OAAL,EAAc;EACZ;EACD;;EAED,UAAME,YAAY,GAAGF,OAAO,CAAChC,KAA7B;;EACA,UAAI,CAACzX,qBAAC,CAACuG,MAAD,CAAD,CAAUK,QAAV,CAAmBjB,iBAAnB,CAAL,EAA0C;EACxC;EACD;;EAED,UAAI5F,KAAK,KAAKA,KAAK,CAAC6I,IAAN,KAAe,OAAf,IACV,kBAAkBhF,IAAlB,CAAuB7D,KAAK,CAACE,MAAN,CAAawJ,OAApC,CADU,IACsC1J,KAAK,CAAC6I,IAAN,KAAe,OAAf,IAA0B7I,KAAK,CAACiQ,KAAN,KAAgByF,WADrF,CAAL,IAEAzV,qBAAC,CAAC+I,QAAF,CAAWxC,MAAX,EAAmBxG,KAAK,CAACE,MAAzB,CAFJ,EAEsC;EACpC;EACD;;EAED,UAAMuY,SAAS,GAAGxY,qBAAC,CAAC0G,KAAF,CAAQ6L,YAAR,EAAoB7B,aAApB,CAAlB;EACA1Q,MAAAA,qBAAC,CAACuG,MAAD,CAAD,CAAU5D,OAAV,CAAkB6V,SAAlB;;EACA,UAAIA,SAAS,CAACrS,kBAAV,EAAJ,EAAoC;EAClC;EACD,OA9BiD;EAiClD;;;EACA,UAAI,kBAAkB5E,QAAQ,CAACyC,eAA/B,EAAgD;EAC9ChE,QAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBnH,QAAjB,GAA4BlC,GAA5B,CAAgC,WAAhC,EAA6C,IAA7C,EAAmDjP,qBAAC,CAACuY,IAArD;EACD;;EAEDiB,MAAAA,OAAO,CAAC1P,CAAD,CAAP,CAAWX,YAAX,CAAwB,eAAxB,EAAyC,OAAzC;;EAEA,UAAIsQ,OAAO,CAACjC,OAAZ,EAAqB;EACnBiC,QAAAA,OAAO,CAACjC,OAAR,CAAgBiB,OAAhB;EACD;;EAEDzY,MAAAA,qBAAC,CAAC2Z,YAAD,CAAD,CAAgBhT,WAAhB,CAA4BhB,iBAA5B;EACA3F,MAAAA,qBAAC,CAACuG,MAAD,CAAD,CACGI,WADH,CACehB,iBADf,EAEGhD,OAFH,CAEW3C,qBAAC,CAAC0G,KAAF,CAAQ8L,cAAR,EAAsB9B,aAAtB,CAFX;EAGD;EACF;;aAEMwH,wBAAP,+BAA6BxW,OAA7B,EAAsC;EACpC,QAAI6E,MAAJ;EACA,QAAM5E,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4BC,OAA5B,CAAjB;;EAEA,QAAIC,QAAJ,EAAc;EACZ4E,MAAAA,MAAM,GAAGhF,QAAQ,CAACQ,aAAT,CAAuBJ,QAAvB,CAAT;EACD;;EAED,WAAO4E,MAAM,IAAI7E,OAAO,CAAC2C,UAAzB;EACD;;;aAGMuV,yBAAP,gCAA8B7Z,KAA9B,EAAqC;EACnC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAI,kBAAkB6D,IAAlB,CAAuB7D,KAAK,CAACE,MAAN,CAAawJ,OAApC,IACF1J,KAAK,CAACiQ,KAAN,KAAgBwF,aAAhB,IAAiCzV,KAAK,CAACiQ,KAAN,KAAgBuF,cAAhB,KAChCxV,KAAK,CAACiQ,KAAN,KAAgB2F,kBAAhB,IAAsC5V,KAAK,CAACiQ,KAAN,KAAgB0F,gBAAtD,IACC1V,qBAAC,CAACD,KAAK,CAACE,MAAP,CAAD,CAAgBuG,OAAhB,CAAwBgQ,aAAxB,EAAuCxM,MAFR,CAD/B,GAGiD,CAAC6L,cAAc,CAACjS,IAAf,CAAoB7D,KAAK,CAACiQ,KAA1B,CAHtD,EAGwF;EACtF;EACD;;EAED,QAAI,KAAK6H,QAAL,IAAiB7X,qBAAC,CAAC,IAAD,CAAD,CAAQ4G,QAAR,CAAiBqP,mBAAjB,CAArB,EAA4D;EAC1D;EACD;;EAED,QAAM1P,MAAM,GAAGgR,QAAQ,CAACW,qBAAT,CAA+B,IAA/B,CAAf;;EACA,QAAMJ,QAAQ,GAAG9X,qBAAC,CAACuG,MAAD,CAAD,CAAUK,QAAV,CAAmBjB,iBAAnB,CAAjB;;EAEA,QAAI,CAACmS,QAAD,IAAa/X,KAAK,CAACiQ,KAAN,KAAgBuF,cAAjC,EAAiD;EAC/C;EACD;;EAEDxV,IAAAA,KAAK,CAACuH,cAAN;EACAvH,IAAAA,KAAK,CAAC6Y,eAAN;;EAEA,QAAI,CAACd,QAAD,IAAc/X,KAAK,CAACiQ,KAAN,KAAgBuF,cAAhB,IAAkCxV,KAAK,CAACiQ,KAAN,KAAgBwF,aAApE,EAAoF;EAClF,UAAIzV,KAAK,CAACiQ,KAAN,KAAgBuF,cAApB,EAAoC;EAClCvV,QAAAA,qBAAC,CAACuG,MAAM,CAACxE,aAAP,CAAqBgG,sBAArB,CAAD,CAAD,CAA8CpF,OAA9C,CAAsD,OAAtD;EACD;;EAED3C,MAAAA,qBAAC,CAAC,IAAD,CAAD,CAAQ2C,OAAR,CAAgB,OAAhB;EACA;EACD;;EAED,QAAMkX,KAAK,GAAG,GAAGjQ,KAAH,CAASpK,IAAT,CAAc+G,MAAM,CAACsD,gBAAP,CAAwB6M,sBAAxB,CAAd,EACXpD,MADW,CACJ,UAAAwG,IAAI;EAAA,aAAI9Z,qBAAC,CAAC8Z,IAAD,CAAD,CAAQ5Z,EAAR,CAAW,UAAX,CAAJ;EAAA,KADA,CAAd;;EAGA,QAAI2Z,KAAK,CAAC7P,MAAN,KAAiB,CAArB,EAAwB;EACtB;EACD;;EAED,QAAI6E,KAAK,GAAGgL,KAAK,CAAC5J,OAAN,CAAclQ,KAAK,CAACE,MAApB,CAAZ;;EAEA,QAAIF,KAAK,CAACiQ,KAAN,KAAgB0F,gBAAhB,IAAoC7G,KAAK,GAAG,CAAhD,EAAmD;EAAE;EACnDA,MAAAA,KAAK;EACN;;EAED,QAAI9O,KAAK,CAACiQ,KAAN,KAAgB2F,kBAAhB,IAAsC9G,KAAK,GAAGgL,KAAK,CAAC7P,MAAN,GAAe,CAAjE,EAAoE;EAAE;EACpE6E,MAAAA,KAAK;EACN;;EAED,QAAIA,KAAK,GAAG,CAAZ,EAAe;EACbA,MAAAA,KAAK,GAAG,CAAR;EACD;;EAEDgL,IAAAA,KAAK,CAAChL,KAAD,CAAL,CAAa5F,KAAb;EACD;;;;0BApZoB;EACnB,aAAOjE,SAAP;EACD;;;0BAEoB;EACnB,aAAOsF,SAAP;EACD;;;0BAEwB;EACvB,aAAOO,aAAP;EACD;;;;;EA6YH;EACA;EACA;EACA;EACA;;;AAEA7K,uBAAC,CAACuB,QAAD,CAAD,CACGgG,EADH,CACMwO,sBADN,EAC8BhO,sBAD9B,EACoDwP,QAAQ,CAACqC,sBAD7D,EAEGrS,EAFH,CAEMwO,sBAFN,EAE8BS,aAF9B,EAE6Ce,QAAQ,CAACqC,sBAFtD,EAGGrS,EAHH,CAGS/B,sBAHT,SAGiCwQ,oBAHjC,EAGyDuB,QAAQ,CAACQ,WAHlE,EAIGxQ,EAJH,CAIM/B,sBAJN,EAI4BuC,sBAJ5B,EAIkD,UAAUhI,KAAV,EAAiB;EAC/DA,EAAAA,KAAK,CAACuH,cAAN;EACAvH,EAAAA,KAAK,CAAC6Y,eAAN;;EACArB,EAAAA,QAAQ,CAACvQ,gBAAT,CAA0BxH,IAA1B,CAA+BQ,qBAAC,CAAC,IAAD,CAAhC,EAAwC,QAAxC;EACD,CARH,EASGuH,EATH,CASM/B,sBATN,EAS4B+Q,mBAT5B,EASiD,UAAAxG,CAAC,EAAI;EAClDA,EAAAA,CAAC,CAAC6I,eAAF;EACD,CAXH;EAaA;EACA;EACA;EACA;EACA;;AAEA5Y,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAawS,QAAQ,CAACvQ,gBAAtB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyB+P,QAAzB;;AACAvX,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAOmS,QAAQ,CAACvQ,gBAAhB;EACD,CAHD;;EC1gBA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,OAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,UAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAME,cAAY,GAAG,WAArB;EACA,IAAMC,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EACA,IAAMwQ,gBAAc,GAAG,EAAvB;;EAEA,IAAMjL,SAAO,GAAG;EACdyP,EAAAA,QAAQ,EAAE,IADI;EAEdvP,EAAAA,QAAQ,EAAE,IAFI;EAGdvB,EAAAA,KAAK,EAAE,IAHO;EAId6K,EAAAA,IAAI,EAAE;EAJQ,CAAhB;EAOA,IAAMjJ,aAAW,GAAG;EAClBkP,EAAAA,QAAQ,EAAE,kBADQ;EAElBvP,EAAAA,QAAQ,EAAE,SAFQ;EAGlBvB,EAAAA,KAAK,EAAE,SAHW;EAIlB6K,EAAAA,IAAI,EAAE;EAJY,CAApB;EAOA,IAAMvB,YAAU,YAAUrN,WAA1B;EACA,IAAM8U,oBAAoB,qBAAmB9U,WAA7C;EACA,IAAMsN,cAAY,cAAYtN,WAA9B;EACA,IAAMmN,YAAU,YAAUnN,WAA1B;EACA,IAAMoN,aAAW,aAAWpN,WAA5B;EACA,IAAM+U,aAAa,eAAa/U,WAAhC;EACA,IAAMgV,YAAY,cAAYhV,WAA9B;EACA,IAAMiV,mBAAmB,qBAAmBjV,WAA5C;EACA,IAAMkV,qBAAqB,uBAAqBlV,WAAhD;EACA,IAAMmV,qBAAqB,uBAAqBnV,WAAhD;EACA,IAAMoV,uBAAuB,yBAAuBpV,WAApD;EACA,IAAMM,sBAAoB,aAAWN,WAAX,GAAuBC,cAAjD;EAEA,IAAMoV,qBAAqB,GAAG,yBAA9B;EACA,IAAMC,6BAA6B,GAAG,yBAAtC;EACA,IAAMC,mBAAmB,GAAG,gBAA5B;EACA,IAAMC,eAAe,GAAG,YAAxB;EACA,IAAMhV,iBAAe,GAAG,MAAxB;EACA,IAAMC,iBAAe,GAAG,MAAxB;EACA,IAAMgV,iBAAiB,GAAG,cAA1B;EAEA,IAAMC,eAAe,GAAG,eAAxB;EACA,IAAMC,mBAAmB,GAAG,aAA5B;EACA,IAAM9S,sBAAoB,GAAG,uBAA7B;EACA,IAAM+S,qBAAqB,GAAG,wBAA9B;EACA,IAAMC,sBAAsB,GAAG,mDAA/B;EACA,IAAMC,uBAAuB,GAAG,aAAhC;EAEA;EACA;EACA;EACA;EACA;;MAEMC;EACJ,iBAAYvZ,OAAZ,EAAqBwB,MAArB,EAA6B;EAC3B,SAAKqK,OAAL,GAAe,KAAKC,UAAL,CAAgBtK,MAAhB,CAAf;EACA,SAAK2C,QAAL,GAAgBnE,OAAhB;EACA,SAAKwZ,OAAL,GAAexZ,OAAO,CAACK,aAAR,CAAsB6Y,eAAtB,CAAf;EACA,SAAKO,SAAL,GAAiB,IAAjB;EACA,SAAKC,QAAL,GAAgB,KAAhB;EACA,SAAKC,kBAAL,GAA0B,KAA1B;EACA,SAAKC,oBAAL,GAA4B,KAA5B;EACA,SAAKtI,gBAAL,GAAwB,KAAxB;EACA,SAAKuI,eAAL,GAAuB,CAAvB;EACD;;;;;EAYD;WAEA/S,SAAA,gBAAOkI,aAAP,EAAsB;EACpB,WAAO,KAAK0K,QAAL,GAAgB,KAAKvH,IAAL,EAAhB,GAA8B,KAAKC,IAAL,CAAUpD,aAAV,CAArC;EACD;;WAEDoD,OAAA,cAAKpD,aAAL,EAAoB;EAAA;;EAClB,QAAI,KAAK0K,QAAL,IAAiB,KAAKpI,gBAA1B,EAA4C;EAC1C;EACD;;EAED,QAAIhT,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BlB,iBAA1B,CAAJ,EAAgD;EAC9C,WAAKsN,gBAAL,GAAwB,IAAxB;EACD;;EAED,QAAMiF,SAAS,GAAGjY,qBAAC,CAAC0G,KAAF,CAAQ2L,YAAR,EAAoB;EACpC3B,MAAAA,aAAa,EAAbA;EADoC,KAApB,CAAlB;EAIA1Q,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBsV,SAAzB;;EAEA,QAAI,KAAKmD,QAAL,IAAiBnD,SAAS,CAAC9R,kBAAV,EAArB,EAAqD;EACnD;EACD;;EAED,SAAKiV,QAAL,GAAgB,IAAhB;;EAEA,SAAKI,eAAL;;EACA,SAAKC,aAAL;;EAEA,SAAKC,aAAL;;EAEA,SAAKC,eAAL;;EACA,SAAKC,eAAL;;EAEA5b,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CACE4S,mBADF,EAEEW,qBAFF,EAGE,UAAA/a,KAAK;EAAA,aAAI,KAAI,CAAC8T,IAAL,CAAU9T,KAAV,CAAJ;EAAA,KAHP;EAMAC,IAAAA,qBAAC,CAAC,KAAKkb,OAAN,CAAD,CAAgB3T,EAAhB,CAAmB+S,uBAAnB,EAA4C,YAAM;EAChDta,MAAAA,qBAAC,CAAC,KAAI,CAAC6F,QAAN,CAAD,CAAiBlF,GAAjB,CAAqB0Z,qBAArB,EAA4C,UAAAta,KAAK,EAAI;EACnD,YAAIC,qBAAC,CAACD,KAAK,CAACE,MAAP,CAAD,CAAgBC,EAAhB,CAAmB,KAAI,CAAC2F,QAAxB,CAAJ,EAAuC;EACrC,UAAA,KAAI,CAACyV,oBAAL,GAA4B,IAA5B;EACD;EACF,OAJD;EAKD,KAND;;EAQA,SAAKO,aAAL,CAAmB;EAAA,aAAM,KAAI,CAACC,YAAL,CAAkBpL,aAAlB,CAAN;EAAA,KAAnB;EACD;;WAEDmD,OAAA,cAAK9T,KAAL,EAAY;EAAA;;EACV,QAAIA,KAAJ,EAAW;EACTA,MAAAA,KAAK,CAACuH,cAAN;EACD;;EAED,QAAI,CAAC,KAAK8T,QAAN,IAAkB,KAAKpI,gBAA3B,EAA6C;EAC3C;EACD;;EAED,QAAMwF,SAAS,GAAGxY,qBAAC,CAAC0G,KAAF,CAAQ6L,YAAR,CAAlB;EAEAvS,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyB6V,SAAzB;;EAEA,QAAI,CAAC,KAAK4C,QAAN,IAAkB5C,SAAS,CAACrS,kBAAV,EAAtB,EAAsD;EACpD;EACD;;EAED,SAAKiV,QAAL,GAAgB,KAAhB;EACA,QAAMW,UAAU,GAAG/b,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BlB,iBAA1B,CAAnB;;EAEA,QAAIqW,UAAJ,EAAgB;EACd,WAAK/I,gBAAL,GAAwB,IAAxB;EACD;;EAED,SAAK2I,eAAL;;EACA,SAAKC,eAAL;;EAEA5b,IAAAA,qBAAC,CAACuB,QAAD,CAAD,CAAY0N,GAAZ,CAAgBgL,aAAhB;EAEAja,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBc,WAAjB,CAA6BhB,iBAA7B;EAEA3F,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBoJ,GAAjB,CAAqBkL,mBAArB;EACAna,IAAAA,qBAAC,CAAC,KAAKkb,OAAN,CAAD,CAAgBjM,GAAhB,CAAoBqL,uBAApB;;EAEA,QAAIyB,UAAJ,EAAgB;EACd,UAAM7Z,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC,KAAK4D,QAA3C,CAA3B;EAEA7F,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACGlF,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4B,UAAAa,KAAK;EAAA,eAAI,MAAI,CAACic,UAAL,CAAgBjc,KAAhB,CAAJ;EAAA,OADjC,EAEGkB,oBAFH,CAEwBiB,kBAFxB;EAGD,KAND,MAMO;EACL,WAAK8Z,UAAL;EACD;EACF;;WAED3V,UAAA,mBAAU;EACR,KAACqD,MAAD,EAAS,KAAK7D,QAAd,EAAwB,KAAKqV,OAA7B,EACGe,OADH,CACW,UAAAC,WAAW;EAAA,aAAIlc,qBAAC,CAACkc,WAAD,CAAD,CAAejN,GAAf,CAAmB/J,WAAnB,CAAJ;EAAA,KADtB;EAGA;EACJ;EACA;EACA;EACA;;EACIlF,IAAAA,qBAAC,CAACuB,QAAD,CAAD,CAAY0N,GAAZ,CAAgBgL,aAAhB;EAEAja,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EAEA,SAAKsI,OAAL,GAAe,IAAf;EACA,SAAK1H,QAAL,GAAgB,IAAhB;EACA,SAAKqV,OAAL,GAAe,IAAf;EACA,SAAKC,SAAL,GAAiB,IAAjB;EACA,SAAKC,QAAL,GAAgB,IAAhB;EACA,SAAKC,kBAAL,GAA0B,IAA1B;EACA,SAAKC,oBAAL,GAA4B,IAA5B;EACA,SAAKtI,gBAAL,GAAwB,IAAxB;EACA,SAAKuI,eAAL,GAAuB,IAAvB;EACD;;WAEDY,eAAA,wBAAe;EACb,SAAKT,aAAL;EACD;;;WAIDlO,aAAA,oBAAWtK,MAAX,EAAmB;EACjBA,IAAAA,MAAM,gBACDoH,SADC,EAEDpH,MAFC,CAAN;EAIAtC,IAAAA,IAAI,CAACoC,eAAL,CAAqB+B,MAArB,EAA2B7B,MAA3B,EAAmC2H,aAAnC;EACA,WAAO3H,MAAP;EACD;;WAEDkZ,6BAAA,sCAA6B;EAAA;;EAC3B,QAAMC,kBAAkB,GAAGrc,qBAAC,CAAC0G,KAAF,CAAQsT,oBAAR,CAA3B;EAEAha,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyB0Z,kBAAzB;;EACA,QAAIA,kBAAkB,CAAClW,kBAAnB,EAAJ,EAA6C;EAC3C;EACD;;EAED,QAAMmW,kBAAkB,GAAG,KAAKzW,QAAL,CAAc0W,YAAd,GAA6Bhb,QAAQ,CAACyC,eAAT,CAAyBwY,YAAjF;;EAEA,QAAI,CAACF,kBAAL,EAAyB;EACvB,WAAKzW,QAAL,CAAcwO,KAAd,CAAoBoI,SAApB,GAAgC,QAAhC;EACD;;EAED,SAAK5W,QAAL,CAAciD,SAAd,CAAwBmB,GAAxB,CAA4B0Q,iBAA5B;;EAEA,QAAM+B,uBAAuB,GAAG9b,IAAI,CAACqB,gCAAL,CAAsC,KAAKiZ,OAA3C,CAAhC;EACAlb,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBoJ,GAAjB,CAAqBrO,IAAI,CAAC1B,cAA1B;EAEAc,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlF,GAAjB,CAAqBC,IAAI,CAAC1B,cAA1B,EAA0C,YAAM;EAC9C,MAAA,MAAI,CAAC2G,QAAL,CAAciD,SAAd,CAAwB/B,MAAxB,CAA+B4T,iBAA/B;;EACA,UAAI,CAAC2B,kBAAL,EAAyB;EACvBtc,QAAAA,qBAAC,CAAC,MAAI,CAAC6F,QAAN,CAAD,CAAiBlF,GAAjB,CAAqBC,IAAI,CAAC1B,cAA1B,EAA0C,YAAM;EAC9C,UAAA,MAAI,CAAC2G,QAAL,CAAcwO,KAAd,CAAoBoI,SAApB,GAAgC,EAAhC;EACD,SAFD,EAGGxb,oBAHH,CAGwB,MAAI,CAAC4E,QAH7B,EAGuC6W,uBAHvC;EAID;EACF,KARD,EASGzb,oBATH,CASwByb,uBATxB;;EAUA,SAAK7W,QAAL,CAAcoD,KAAd;EACD;;WAED6S,eAAA,sBAAapL,aAAb,EAA4B;EAAA;;EAC1B,QAAMqL,UAAU,GAAG/b,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BlB,iBAA1B,CAAnB;EACA,QAAMiX,SAAS,GAAG,KAAKzB,OAAL,GAAe,KAAKA,OAAL,CAAanZ,aAAb,CAA2B8Y,mBAA3B,CAAf,GAAiE,IAAnF;;EAEA,QAAI,CAAC,KAAKhV,QAAL,CAAcxB,UAAf,IACA,KAAKwB,QAAL,CAAcxB,UAAd,CAAyBtB,QAAzB,KAAsC6Z,IAAI,CAACC,YAD/C,EAC6D;EAC3D;EACAtb,MAAAA,QAAQ,CAAC+W,IAAT,CAAcwE,WAAd,CAA0B,KAAKjX,QAA/B;EACD;;EAED,SAAKA,QAAL,CAAcwO,KAAd,CAAoBgD,OAApB,GAA8B,OAA9B;;EACA,SAAKxR,QAAL,CAAckX,eAAd,CAA8B,aAA9B;;EACA,SAAKlX,QAAL,CAAcsD,YAAd,CAA2B,YAA3B,EAAyC,IAAzC;;EACA,SAAKtD,QAAL,CAAcsD,YAAd,CAA2B,MAA3B,EAAmC,QAAnC;;EAEA,QAAInJ,qBAAC,CAAC,KAAKkb,OAAN,CAAD,CAAgBtU,QAAhB,CAAyB2T,qBAAzB,KAAmDoC,SAAvD,EAAkE;EAChEA,MAAAA,SAAS,CAACK,SAAV,GAAsB,CAAtB;EACD,KAFD,MAEO;EACL,WAAKnX,QAAL,CAAcmX,SAAd,GAA0B,CAA1B;EACD;;EAED,QAAIjB,UAAJ,EAAgB;EACdnb,MAAAA,IAAI,CAAC6B,MAAL,CAAY,KAAKoD,QAAjB;EACD;;EAED7F,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBuL,QAAjB,CAA0BzL,iBAA1B;;EAEA,QAAI,KAAK4H,OAAL,CAAatE,KAAjB,EAAwB;EACtB,WAAKgU,aAAL;EACD;;EAED,QAAMC,UAAU,GAAGld,qBAAC,CAAC0G,KAAF,CAAQ4L,aAAR,EAAqB;EACtC5B,MAAAA,aAAa,EAAbA;EADsC,KAArB,CAAnB;;EAIA,QAAMyM,kBAAkB,GAAG,SAArBA,kBAAqB,GAAM;EAC/B,UAAI,MAAI,CAAC5P,OAAL,CAAatE,KAAjB,EAAwB;EACtB,QAAA,MAAI,CAACpD,QAAL,CAAcoD,KAAd;EACD;;EAED,MAAA,MAAI,CAAC+J,gBAAL,GAAwB,KAAxB;EACAhT,MAAAA,qBAAC,CAAC,MAAI,CAAC6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBua,UAAzB;EACD,KAPD;;EASA,QAAInB,UAAJ,EAAgB;EACd,UAAM7Z,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC,KAAKiZ,OAA3C,CAA3B;EAEAlb,MAAAA,qBAAC,CAAC,KAAKkb,OAAN,CAAD,CACGva,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4Bie,kBAD5B,EAEGlc,oBAFH,CAEwBiB,kBAFxB;EAGD,KAND,MAMO;EACLib,MAAAA,kBAAkB;EACnB;EACF;;WAEDF,gBAAA,yBAAgB;EAAA;;EACdjd,IAAAA,qBAAC,CAACuB,QAAD,CAAD,CACG0N,GADH,CACOgL,aADP;EAAA,KAEG1S,EAFH,CAEM0S,aAFN,EAEqB,UAAAla,KAAK,EAAI;EAC1B,UAAIwB,QAAQ,KAAKxB,KAAK,CAACE,MAAnB,IACA,MAAI,CAAC4F,QAAL,KAAkB9F,KAAK,CAACE,MADxB,IAEAD,qBAAC,CAAC,MAAI,CAAC6F,QAAN,CAAD,CAAiBuX,GAAjB,CAAqBrd,KAAK,CAACE,MAA3B,EAAmC+J,MAAnC,KAA8C,CAFlD,EAEqD;EACnD,QAAA,MAAI,CAACnE,QAAL,CAAcoD,KAAd;EACD;EACF,KARH;EASD;;WAED0S,kBAAA,2BAAkB;EAAA;;EAChB,QAAI,KAAKP,QAAT,EAAmB;EACjBpb,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoB6S,qBAApB,EAA2C,UAAAra,KAAK,EAAI;EAClD,YAAI,MAAI,CAACwN,OAAL,CAAa/C,QAAb,IAAyBzK,KAAK,CAACiQ,KAAN,KAAgBuF,gBAA7C,EAA6D;EAC3DxV,UAAAA,KAAK,CAACuH,cAAN;;EACA,UAAA,MAAI,CAACuM,IAAL;EACD,SAHD,MAGO,IAAI,CAAC,MAAI,CAACtG,OAAL,CAAa/C,QAAd,IAA0BzK,KAAK,CAACiQ,KAAN,KAAgBuF,gBAA9C,EAA8D;EACnE,UAAA,MAAI,CAAC6G,0BAAL;EACD;EACF,OAPD;EAQD,KATD,MASO,IAAI,CAAC,KAAKhB,QAAV,EAAoB;EACzBpb,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBoJ,GAAjB,CAAqBmL,qBAArB;EACD;EACF;;WAEDwB,kBAAA,2BAAkB;EAAA;;EAChB,QAAI,KAAKR,QAAT,EAAmB;EACjBpb,MAAAA,qBAAC,CAAC0J,MAAD,CAAD,CAAUnC,EAAV,CAAa2S,YAAb,EAA2B,UAAAna,KAAK;EAAA,eAAI,MAAI,CAACoc,YAAL,CAAkBpc,KAAlB,CAAJ;EAAA,OAAhC;EACD,KAFD,MAEO;EACLC,MAAAA,qBAAC,CAAC0J,MAAD,CAAD,CAAUuF,GAAV,CAAciL,YAAd;EACD;EACF;;WAED8B,aAAA,sBAAa;EAAA;;EACX,SAAKnW,QAAL,CAAcwO,KAAd,CAAoBgD,OAApB,GAA8B,MAA9B;;EACA,SAAKxR,QAAL,CAAcsD,YAAd,CAA2B,aAA3B,EAA0C,IAA1C;;EACA,SAAKtD,QAAL,CAAckX,eAAd,CAA8B,YAA9B;;EACA,SAAKlX,QAAL,CAAckX,eAAd,CAA8B,MAA9B;;EACA,SAAK/J,gBAAL,GAAwB,KAAxB;;EACA,SAAK6I,aAAL,CAAmB,YAAM;EACvB7b,MAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiB3R,WAAjB,CAA6B+T,eAA7B;;EACA,MAAA,MAAI,CAAC2C,iBAAL;;EACA,MAAA,MAAI,CAACC,eAAL;;EACAtd,MAAAA,qBAAC,CAAC,MAAI,CAAC6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyB6P,cAAzB;EACD,KALD;EAMD;;WAED+K,kBAAA,2BAAkB;EAChB,QAAI,KAAKpC,SAAT,EAAoB;EAClBnb,MAAAA,qBAAC,CAAC,KAAKmb,SAAN,CAAD,CAAkBpU,MAAlB;EACA,WAAKoU,SAAL,GAAiB,IAAjB;EACD;EACF;;WAEDU,gBAAA,uBAAc2B,QAAd,EAAwB;EAAA;;EACtB,QAAMC,OAAO,GAAGzd,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BlB,iBAA1B,IACdA,iBADc,GACI,EADpB;;EAGA,QAAI,KAAK0V,QAAL,IAAiB,KAAK7N,OAAL,CAAawM,QAAlC,EAA4C;EAC1C,WAAKoB,SAAL,GAAiB5Z,QAAQ,CAACmc,aAAT,CAAuB,KAAvB,CAAjB;EACA,WAAKvC,SAAL,CAAewC,SAAf,GAA2BlD,mBAA3B;;EAEA,UAAIgD,OAAJ,EAAa;EACX,aAAKtC,SAAL,CAAerS,SAAf,CAAyBmB,GAAzB,CAA6BwT,OAA7B;EACD;;EAEDzd,MAAAA,qBAAC,CAAC,KAAKmb,SAAN,CAAD,CAAkByC,QAAlB,CAA2Brc,QAAQ,CAAC+W,IAApC;EAEAtY,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoB4S,mBAApB,EAAyC,UAAApa,KAAK,EAAI;EAChD,YAAI,MAAI,CAACub,oBAAT,EAA+B;EAC7B,UAAA,MAAI,CAACA,oBAAL,GAA4B,KAA5B;EACA;EACD;;EAED,YAAIvb,KAAK,CAACE,MAAN,KAAiBF,KAAK,CAACoV,aAA3B,EAA0C;EACxC;EACD;;EAED,YAAI,MAAI,CAAC5H,OAAL,CAAawM,QAAb,KAA0B,QAA9B,EAAwC;EACtC,UAAA,MAAI,CAACqC,0BAAL;EACD,SAFD,MAEO;EACL,UAAA,MAAI,CAACvI,IAAL;EACD;EACF,OAfD;;EAiBA,UAAI4J,OAAJ,EAAa;EACX7c,QAAAA,IAAI,CAAC6B,MAAL,CAAY,KAAK0Y,SAAjB;EACD;;EAEDnb,MAAAA,qBAAC,CAAC,KAAKmb,SAAN,CAAD,CAAkB/J,QAAlB,CAA2BzL,iBAA3B;;EAEA,UAAI,CAAC6X,QAAL,EAAe;EACb;EACD;;EAED,UAAI,CAACC,OAAL,EAAc;EACZD,QAAAA,QAAQ;EACR;EACD;;EAED,UAAMK,0BAA0B,GAAGjd,IAAI,CAACqB,gCAAL,CAAsC,KAAKkZ,SAA3C,CAAnC;EAEAnb,MAAAA,qBAAC,CAAC,KAAKmb,SAAN,CAAD,CACGxa,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4Bse,QAD5B,EAEGvc,oBAFH,CAEwB4c,0BAFxB;EAGD,KA/CD,MA+CO,IAAI,CAAC,KAAKzC,QAAN,IAAkB,KAAKD,SAA3B,EAAsC;EAC3Cnb,MAAAA,qBAAC,CAAC,KAAKmb,SAAN,CAAD,CAAkBxU,WAAlB,CAA8BhB,iBAA9B;;EAEA,UAAMmY,cAAc,GAAG,SAAjBA,cAAiB,GAAM;EAC3B,QAAA,MAAI,CAACP,eAAL;;EACA,YAAIC,QAAJ,EAAc;EACZA,UAAAA,QAAQ;EACT;EACF,OALD;;EAOA,UAAIxd,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BlB,iBAA1B,CAAJ,EAAgD;EAC9C,YAAMmY,2BAA0B,GAAGjd,IAAI,CAACqB,gCAAL,CAAsC,KAAKkZ,SAA3C,CAAnC;;EAEAnb,QAAAA,qBAAC,CAAC,KAAKmb,SAAN,CAAD,CACGxa,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4B4e,cAD5B,EAEG7c,oBAFH,CAEwB4c,2BAFxB;EAGD,OAND,MAMO;EACLC,QAAAA,cAAc;EACf;EACF,KAnBM,MAmBA,IAAIN,QAAJ,EAAc;EACnBA,MAAAA,QAAQ;EACT;EACF;EAGD;EACA;EACA;;;WAEA9B,gBAAA,yBAAgB;EACd,QAAMY,kBAAkB,GAAG,KAAKzW,QAAL,CAAc0W,YAAd,GAA6Bhb,QAAQ,CAACyC,eAAT,CAAyBwY,YAAjF;;EAEA,QAAI,CAAC,KAAKnB,kBAAN,IAA4BiB,kBAAhC,EAAoD;EAClD,WAAKzW,QAAL,CAAcwO,KAAd,CAAoB0J,WAApB,GAAqC,KAAKxC,eAA1C;EACD;;EAED,QAAI,KAAKF,kBAAL,IAA2B,CAACiB,kBAAhC,EAAoD;EAClD,WAAKzW,QAAL,CAAcwO,KAAd,CAAoB2J,YAApB,GAAsC,KAAKzC,eAA3C;EACD;EACF;;WAED8B,oBAAA,6BAAoB;EAClB,SAAKxX,QAAL,CAAcwO,KAAd,CAAoB0J,WAApB,GAAkC,EAAlC;EACA,SAAKlY,QAAL,CAAcwO,KAAd,CAAoB2J,YAApB,GAAmC,EAAnC;EACD;;WAEDxC,kBAAA,2BAAkB;EAChB,QAAMyC,IAAI,GAAG1c,QAAQ,CAAC+W,IAAT,CAAc3D,qBAAd,EAAb;EACA,SAAK0G,kBAAL,GAA0Bha,IAAI,CAAC6c,KAAL,CAAWD,IAAI,CAACE,IAAL,GAAYF,IAAI,CAACG,KAA5B,IAAqC1U,MAAM,CAAC2U,UAAtE;EACA,SAAK9C,eAAL,GAAuB,KAAK+C,kBAAL,EAAvB;EACD;;WAED7C,gBAAA,yBAAgB;EAAA;;EACd,QAAI,KAAKJ,kBAAT,EAA6B;EAC3B;EACA;EACA,UAAMkD,YAAY,GAAG,GAAG3U,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0BkR,sBAA1B,CAAd,CAArB;EACA,UAAMyD,aAAa,GAAG,GAAG5U,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0BmR,uBAA1B,CAAd,CAAtB,CAJ2B;;EAO3Bhb,MAAAA,qBAAC,CAACue,YAAD,CAAD,CAAgBtX,IAAhB,CAAqB,UAAC4H,KAAD,EAAQnN,OAAR,EAAoB;EACvC,YAAM+c,aAAa,GAAG/c,OAAO,CAAC2S,KAAR,CAAc2J,YAApC;EACA,YAAMU,iBAAiB,GAAG1e,qBAAC,CAAC0B,OAAD,CAAD,CAAWS,GAAX,CAAe,eAAf,CAA1B;EACAnC,QAAAA,qBAAC,CAAC0B,OAAD,CAAD,CACGyF,IADH,CACQ,eADR,EACyBsX,aADzB,EAEGtc,GAFH,CAEO,eAFP,EAE2BG,UAAU,CAACoc,iBAAD,CAAV,GAAgC,OAAI,CAACnD,eAFhE;EAGD,OAND,EAP2B;;EAgB3Bvb,MAAAA,qBAAC,CAACwe,aAAD,CAAD,CAAiBvX,IAAjB,CAAsB,UAAC4H,KAAD,EAAQnN,OAAR,EAAoB;EACxC,YAAMid,YAAY,GAAGjd,OAAO,CAAC2S,KAAR,CAAcuK,WAAnC;EACA,YAAMC,gBAAgB,GAAG7e,qBAAC,CAAC0B,OAAD,CAAD,CAAWS,GAAX,CAAe,cAAf,CAAzB;EACAnC,QAAAA,qBAAC,CAAC0B,OAAD,CAAD,CACGyF,IADH,CACQ,cADR,EACwBwX,YADxB,EAEGxc,GAFH,CAEO,cAFP,EAE0BG,UAAU,CAACuc,gBAAD,CAAV,GAA+B,OAAI,CAACtD,eAF9D;EAGD,OAND,EAhB2B;;EAyB3B,UAAMkD,aAAa,GAAGld,QAAQ,CAAC+W,IAAT,CAAcjE,KAAd,CAAoB2J,YAA1C;EACA,UAAMU,iBAAiB,GAAG1e,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBnW,GAAjB,CAAqB,eAArB,CAA1B;EACAnC,MAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CACGnR,IADH,CACQ,eADR,EACyBsX,aADzB,EAEGtc,GAFH,CAEO,eAFP,EAE2BG,UAAU,CAACoc,iBAAD,CAAV,GAAgC,KAAKnD,eAFhE;EAGD;;EAEDvb,IAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBlH,QAAjB,CAA0BsJ,eAA1B;EACD;;WAED4C,kBAAA,2BAAkB;EAChB;EACA,QAAMiB,YAAY,GAAG,GAAG3U,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0BkR,sBAA1B,CAAd,CAArB;EACA/a,IAAAA,qBAAC,CAACue,YAAD,CAAD,CAAgBtX,IAAhB,CAAqB,UAAC4H,KAAD,EAAQnN,OAAR,EAAoB;EACvC,UAAMod,OAAO,GAAG9e,qBAAC,CAAC0B,OAAD,CAAD,CAAWyF,IAAX,CAAgB,eAAhB,CAAhB;EACAnH,MAAAA,qBAAC,CAAC0B,OAAD,CAAD,CAAW4E,UAAX,CAAsB,eAAtB;EACA5E,MAAAA,OAAO,CAAC2S,KAAR,CAAc2J,YAAd,GAA6Bc,OAAO,GAAGA,OAAH,GAAa,EAAjD;EACD,KAJD,EAHgB;;EAUhB,QAAMC,QAAQ,GAAG,GAAGnV,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,MAA6BmR,uBAA7B,CAAd,CAAjB;EACAhb,IAAAA,qBAAC,CAAC+e,QAAD,CAAD,CAAY9X,IAAZ,CAAiB,UAAC4H,KAAD,EAAQnN,OAAR,EAAoB;EACnC,UAAMsd,MAAM,GAAGhf,qBAAC,CAAC0B,OAAD,CAAD,CAAWyF,IAAX,CAAgB,cAAhB,CAAf;;EACA,UAAI,OAAO6X,MAAP,KAAkB,WAAtB,EAAmC;EACjChf,QAAAA,qBAAC,CAAC0B,OAAD,CAAD,CAAWS,GAAX,CAAe,cAAf,EAA+B6c,MAA/B,EAAuC1Y,UAAvC,CAAkD,cAAlD;EACD;EACF,KALD,EAXgB;;EAmBhB,QAAMwY,OAAO,GAAG9e,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBnR,IAAjB,CAAsB,eAAtB,CAAhB;EACAnH,IAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBhS,UAAjB,CAA4B,eAA5B;EACA/E,IAAAA,QAAQ,CAAC+W,IAAT,CAAcjE,KAAd,CAAoB2J,YAApB,GAAmCc,OAAO,GAAGA,OAAH,GAAa,EAAvD;EACD;;WAEDR,qBAAA,8BAAqB;EAAE;EACrB,QAAMW,SAAS,GAAG1d,QAAQ,CAACmc,aAAT,CAAuB,KAAvB,CAAlB;EACAuB,IAAAA,SAAS,CAACtB,SAAV,GAAsBnD,6BAAtB;EACAjZ,IAAAA,QAAQ,CAAC+W,IAAT,CAAcwE,WAAd,CAA0BmC,SAA1B;EACA,QAAMC,cAAc,GAAGD,SAAS,CAACtK,qBAAV,GAAkCwK,KAAlC,GAA0CF,SAAS,CAACG,WAA3E;EACA7d,IAAAA,QAAQ,CAAC+W,IAAT,CAAc+G,WAAd,CAA0BJ,SAA1B;EACA,WAAOC,cAAP;EACD;;;UAIMlY,mBAAP,0BAAwB9D,MAAxB,EAAgCwN,aAAhC,EAA+C;EAC7C,WAAO,KAAKzJ,IAAL,CAAU,YAAY;EAC3B,UAAIE,IAAI,GAAGnH,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,CAAX;;EACA,UAAMsI,OAAO,gBACRjD,SADQ,EAERtK,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,EAFQ,EAGP,OAAOjE,MAAP,KAAkB,QAAlB,IAA8BA,MAA9B,GAAuCA,MAAvC,GAAgD,EAHzC,CAAb;;EAMA,UAAI,CAACiE,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAI8T,KAAJ,CAAU,IAAV,EAAgB1N,OAAhB,CAAP;EACAvN,QAAAA,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,EAAuBkC,IAAvB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ,CAAawN,aAAb;EACD,OAND,MAMO,IAAInD,OAAO,CAACuG,IAAZ,EAAkB;EACvB3M,QAAAA,IAAI,CAAC2M,IAAL,CAAUpD,aAAV;EACD;EACF,KAtBM,CAAP;EAuBD;;;;0BAreoB;EACnB,aAAO1L,SAAP;EACD;;;0BAEoB;EACnB,aAAOsF,SAAP;EACD;;;;;EAkeH;EACA;EACA;EACA;EACA;;;AAEAtK,uBAAC,CAACuB,QAAD,CAAD,CAAYgG,EAAZ,CAAe/B,sBAAf,EAAqCuC,sBAArC,EAA2D,UAAUhI,KAAV,EAAiB;EAAA;;EAC1E,MAAIE,MAAJ;EACA,MAAM0B,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4B,IAA5B,CAAjB;;EAEA,MAAIE,QAAJ,EAAc;EACZ1B,IAAAA,MAAM,GAAGsB,QAAQ,CAACQ,aAAT,CAAuBJ,QAAvB,CAAT;EACD;;EAED,MAAMuB,MAAM,GAAGlD,qBAAC,CAACC,MAAD,CAAD,CAAUkH,IAAV,CAAelC,UAAf,IACb,QADa,gBAERjF,qBAAC,CAACC,MAAD,CAAD,CAAUkH,IAAV,EAFQ,EAGRnH,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,EAHQ,CAAf;;EAMA,MAAI,KAAKsC,OAAL,KAAiB,GAAjB,IAAwB,KAAKA,OAAL,KAAiB,MAA7C,EAAqD;EACnD1J,IAAAA,KAAK,CAACuH,cAAN;EACD;;EAED,MAAMgO,OAAO,GAAGtV,qBAAC,CAACC,MAAD,CAAD,CAAUU,GAAV,CAAc0R,YAAd,EAA0B,UAAA4F,SAAS,EAAI;EACrD,QAAIA,SAAS,CAAC9R,kBAAV,EAAJ,EAAoC;EAClC;EACA;EACD;;EAEDmP,IAAAA,OAAO,CAAC3U,GAAR,CAAY6R,cAAZ,EAA0B,YAAM;EAC9B,UAAIxS,qBAAC,CAAC,OAAD,CAAD,CAAQE,EAAR,CAAW,UAAX,CAAJ,EAA4B;EAC1B,QAAA,OAAI,CAAC+I,KAAL;EACD;EACF,KAJD;EAKD,GAXe,CAAhB;;EAaAgS,EAAAA,KAAK,CAACjU,gBAAN,CAAuBxH,IAAvB,CAA4BQ,qBAAC,CAACC,MAAD,CAA7B,EAAuCiD,MAAvC,EAA+C,IAA/C;EACD,CAhCD;EAkCA;EACA;EACA;EACA;EACA;;AAEAlD,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAakW,KAAK,CAACjU,gBAAnB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyByT,KAAzB;;AACAjb,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAO6V,KAAK,CAACjU,gBAAb;EACD,CAHD;;EC/mBA;EACA;EACA;EACA;EACA;EACA;EAEA,IAAMsY,QAAQ,GAAG,CACf,YADe,EAEf,MAFe,EAGf,MAHe,EAIf,UAJe,EAKf,UALe,EAMf,QANe,EAOf,KAPe,EAQf,YARe,CAAjB;EAWA,IAAMC,sBAAsB,GAAG,gBAA/B;EAEO,IAAMC,gBAAgB,GAAG;EAC9B;EACA,OAAK,CAAC,OAAD,EAAU,KAAV,EAAiB,IAAjB,EAAuB,MAAvB,EAA+B,MAA/B,EAAuCD,sBAAvC,CAFyB;EAG9BE,EAAAA,CAAC,EAAE,CAAC,QAAD,EAAW,MAAX,EAAmB,OAAnB,EAA4B,KAA5B,CAH2B;EAI9BC,EAAAA,IAAI,EAAE,EAJwB;EAK9BC,EAAAA,CAAC,EAAE,EAL2B;EAM9BC,EAAAA,EAAE,EAAE,EAN0B;EAO9BC,EAAAA,GAAG,EAAE,EAPyB;EAQ9BC,EAAAA,IAAI,EAAE,EARwB;EAS9BC,EAAAA,GAAG,EAAE,EATyB;EAU9BC,EAAAA,EAAE,EAAE,EAV0B;EAW9BC,EAAAA,EAAE,EAAE,EAX0B;EAY9BC,EAAAA,EAAE,EAAE,EAZ0B;EAa9BC,EAAAA,EAAE,EAAE,EAb0B;EAc9BC,EAAAA,EAAE,EAAE,EAd0B;EAe9BC,EAAAA,EAAE,EAAE,EAf0B;EAgB9BC,EAAAA,EAAE,EAAE,EAhB0B;EAiB9BC,EAAAA,EAAE,EAAE,EAjB0B;EAkB9BzW,EAAAA,CAAC,EAAE,EAlB2B;EAmB9B0W,EAAAA,GAAG,EAAE,CAAC,KAAD,EAAQ,QAAR,EAAkB,KAAlB,EAAyB,OAAzB,EAAkC,OAAlC,EAA2C,QAA3C,CAnByB;EAoB9BC,EAAAA,EAAE,EAAE,EApB0B;EAqB9BC,EAAAA,EAAE,EAAE,EArB0B;EAsB9BC,EAAAA,CAAC,EAAE,EAtB2B;EAuB9BC,EAAAA,GAAG,EAAE,EAvByB;EAwB9BC,EAAAA,CAAC,EAAE,EAxB2B;EAyB9BC,EAAAA,KAAK,EAAE,EAzBuB;EA0B9BC,EAAAA,IAAI,EAAE,EA1BwB;EA2B9BC,EAAAA,GAAG,EAAE,EA3ByB;EA4B9BC,EAAAA,GAAG,EAAE,EA5ByB;EA6B9BC,EAAAA,MAAM,EAAE,EA7BsB;EA8B9BC,EAAAA,CAAC,EAAE,EA9B2B;EA+B9BC,EAAAA,EAAE,EAAE;EA/B0B,CAAzB;EAkCP;EACA;EACA;EACA;EACA;;EACA,IAAMC,gBAAgB,GAAG,6DAAzB;EAEA;EACA;EACA;EACA;EACA;;EACA,IAAMC,gBAAgB,GAAG,oIAAzB;;EAEA,SAASC,gBAAT,CAA0BjN,IAA1B,EAAgCkN,oBAAhC,EAAsD;EACpD,MAAMC,QAAQ,GAAGnN,IAAI,CAACoN,QAAL,CAAchiB,WAAd,EAAjB;;EAEA,MAAI8hB,oBAAoB,CAACvR,OAArB,CAA6BwR,QAA7B,MAA2C,CAAC,CAAhD,EAAmD;EACjD,QAAInC,QAAQ,CAACrP,OAAT,CAAiBwR,QAAjB,MAA+B,CAAC,CAApC,EAAuC;EACrC,aAAO5e,OAAO,CAACyR,IAAI,CAACqN,SAAL,CAAeliB,KAAf,CAAqB4hB,gBAArB,KAA0C/M,IAAI,CAACqN,SAAL,CAAeliB,KAAf,CAAqB6hB,gBAArB,CAA3C,CAAd;EACD;;EAED,WAAO,IAAP;EACD;;EAED,MAAMM,MAAM,GAAGJ,oBAAoB,CAAClO,MAArB,CAA4B,UAAAuO,SAAS;EAAA,WAAIA,SAAS,YAAYle,MAAzB;EAAA,GAArC,CAAf,CAXoD;;EAcpD,OAAK,IAAImG,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAG6X,MAAM,CAAC5X,MAA7B,EAAqCF,CAAC,GAAGC,GAAzC,EAA8CD,CAAC,EAA/C,EAAmD;EACjD,QAAI2X,QAAQ,CAAChiB,KAAT,CAAemiB,MAAM,CAAC9X,CAAD,CAArB,CAAJ,EAA+B;EAC7B,aAAO,IAAP;EACD;EACF;;EAED,SAAO,KAAP;EACD;;EAEM,SAASgY,YAAT,CAAsBC,UAAtB,EAAkCC,SAAlC,EAA6CC,UAA7C,EAAyD;EAC9D,MAAIF,UAAU,CAAC/X,MAAX,KAAsB,CAA1B,EAA6B;EAC3B,WAAO+X,UAAP;EACD;;EAED,MAAIE,UAAU,IAAI,OAAOA,UAAP,KAAsB,UAAxC,EAAoD;EAClD,WAAOA,UAAU,CAACF,UAAD,CAAjB;EACD;;EAED,MAAMG,SAAS,GAAG,IAAIxY,MAAM,CAACyY,SAAX,EAAlB;EACA,MAAMC,eAAe,GAAGF,SAAS,CAACG,eAAV,CAA0BN,UAA1B,EAAsC,WAAtC,CAAxB;EACA,MAAMO,aAAa,GAAGjf,MAAM,CAACkf,IAAP,CAAYP,SAAZ,CAAtB;EACA,MAAMjD,QAAQ,GAAG,GAAGnV,KAAH,CAASpK,IAAT,CAAc4iB,eAAe,CAAC9J,IAAhB,CAAqBzO,gBAArB,CAAsC,GAAtC,CAAd,CAAjB;;EAZ8D,6BAcrDC,CAdqD,EAc9CC,GAd8C;EAe5D,QAAMyY,EAAE,GAAGzD,QAAQ,CAACjV,CAAD,CAAnB;EACA,QAAM2Y,MAAM,GAAGD,EAAE,CAACd,QAAH,CAAYhiB,WAAZ,EAAf;;EAEA,QAAI4iB,aAAa,CAACrS,OAAd,CAAsBuS,EAAE,CAACd,QAAH,CAAYhiB,WAAZ,EAAtB,MAAqD,CAAC,CAA1D,EAA6D;EAC3D8iB,MAAAA,EAAE,CAACne,UAAH,CAAcgb,WAAd,CAA0BmD,EAA1B;EAEA;EACD;;EAED,QAAME,aAAa,GAAG,GAAG9Y,KAAH,CAASpK,IAAT,CAAcgjB,EAAE,CAACG,UAAjB,CAAtB;EACA,QAAMC,qBAAqB,GAAG,GAAGC,MAAH,CAAUb,SAAS,CAAC,GAAD,CAAT,IAAkB,EAA5B,EAAgCA,SAAS,CAACS,MAAD,CAAT,IAAqB,EAArD,CAA9B;EAEAC,IAAAA,aAAa,CAACzG,OAAd,CAAsB,UAAA3H,IAAI,EAAI;EAC5B,UAAI,CAACiN,gBAAgB,CAACjN,IAAD,EAAOsO,qBAAP,CAArB,EAAoD;EAClDJ,QAAAA,EAAE,CAACzF,eAAH,CAAmBzI,IAAI,CAACoN,QAAxB;EACD;EACF,KAJD;EA3B4D;;EAc9D,OAAK,IAAI5X,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGgV,QAAQ,CAAC/U,MAA/B,EAAuCF,CAAC,GAAGC,GAA3C,EAAgDD,CAAC,EAAjD,EAAqD;EAAA,qBAA5CA,CAA4C;;EAAA,6BAOjD;EAWH;;EAED,SAAOsY,eAAe,CAAC9J,IAAhB,CAAqBwK,SAA5B;EACD;;EC/GD;EACA;EACA;EACA;EACA;;EAEA,IAAM/d,MAAI,GAAG,SAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,YAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAMG,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EACA,IAAMge,YAAY,GAAG,YAArB;EACA,IAAMC,kBAAkB,GAAG,IAAIrf,MAAJ,aAAqBof,YAArB,WAAyC,GAAzC,CAA3B;EACA,IAAME,qBAAqB,GAAG,CAAC,UAAD,EAAa,WAAb,EAA0B,YAA1B,CAA9B;EAEA,IAAMpY,aAAW,GAAG;EAClBqY,EAAAA,SAAS,EAAE,SADO;EAElBC,EAAAA,QAAQ,EAAE,QAFQ;EAGlBC,EAAAA,KAAK,EAAE,2BAHW;EAIlBzgB,EAAAA,OAAO,EAAE,QAJS;EAKlB0gB,EAAAA,KAAK,EAAE,iBALW;EAMlBC,EAAAA,IAAI,EAAE,SANY;EAOlB3hB,EAAAA,QAAQ,EAAE,kBAPQ;EAQlBqX,EAAAA,SAAS,EAAE,mBARO;EASlB/B,EAAAA,MAAM,EAAE,0BATU;EAUlBsM,EAAAA,SAAS,EAAE,0BAVO;EAWlBC,EAAAA,iBAAiB,EAAE,gBAXD;EAYlBrM,EAAAA,QAAQ,EAAE,kBAZQ;EAalBsM,EAAAA,WAAW,EAAE,mBAbK;EAclBC,EAAAA,QAAQ,EAAE,SAdQ;EAelBzB,EAAAA,UAAU,EAAE,iBAfM;EAgBlBD,EAAAA,SAAS,EAAE,QAhBO;EAiBlB1K,EAAAA,YAAY,EAAE;EAjBI,CAApB;EAoBA,IAAMqM,aAAa,GAAG;EACpBC,EAAAA,IAAI,EAAE,MADc;EAEpBC,EAAAA,GAAG,EAAE,KAFe;EAGpBC,EAAAA,KAAK,EAAE,OAHa;EAIpBC,EAAAA,MAAM,EAAE,QAJY;EAKpBC,EAAAA,IAAI,EAAE;EALc,CAAtB;EAQA,IAAM1Z,SAAO,GAAG;EACd4Y,EAAAA,SAAS,EAAE,IADG;EAEdC,EAAAA,QAAQ,EAAE,yCACQ,2BADR,GAEQ,yCAJJ;EAKdxgB,EAAAA,OAAO,EAAE,aALK;EAMdygB,EAAAA,KAAK,EAAE,EANO;EAOdC,EAAAA,KAAK,EAAE,CAPO;EAQdC,EAAAA,IAAI,EAAE,KARQ;EASd3hB,EAAAA,QAAQ,EAAE,KATI;EAUdqX,EAAAA,SAAS,EAAE,KAVG;EAWd/B,EAAAA,MAAM,EAAE,CAXM;EAYdsM,EAAAA,SAAS,EAAE,KAZG;EAadC,EAAAA,iBAAiB,EAAE,MAbL;EAcdrM,EAAAA,QAAQ,EAAE,cAdI;EAedsM,EAAAA,WAAW,EAAE,EAfC;EAgBdC,EAAAA,QAAQ,EAAE,IAhBI;EAiBdzB,EAAAA,UAAU,EAAE,IAjBE;EAkBdD,EAAAA,SAAS,EAAExC,gBAlBG;EAmBdlI,EAAAA,YAAY,EAAE;EAnBA,CAAhB;EAsBA,IAAM2M,gBAAgB,GAAG,MAAzB;EACA,IAAMC,eAAe,GAAG,KAAxB;EAEA,IAAMxd,KAAK,GAAG;EACZyd,EAAAA,IAAI,WAASjf,WADD;EAEZkf,EAAAA,MAAM,aAAWlf,WAFL;EAGZmf,EAAAA,IAAI,WAASnf,WAHD;EAIZof,EAAAA,KAAK,YAAUpf,WAJH;EAKZqf,EAAAA,QAAQ,eAAarf,WALT;EAMZsf,EAAAA,KAAK,YAAUtf,WANH;EAOZuf,EAAAA,OAAO,cAAYvf,WAPP;EAQZwf,EAAAA,QAAQ,eAAaxf,WART;EASZyf,EAAAA,UAAU,iBAAezf,WATb;EAUZ0f,EAAAA,UAAU,iBAAe1f;EAVb,CAAd;EAaA,IAAMQ,iBAAe,GAAG,MAAxB;EACA,IAAMC,iBAAe,GAAG,MAAxB;EAEA,IAAMkf,sBAAsB,GAAG,gBAA/B;EACA,IAAMC,cAAc,GAAG,QAAvB;EAEA,IAAMC,aAAa,GAAG,OAAtB;EACA,IAAMC,aAAa,GAAG,OAAtB;EACA,IAAMC,aAAa,GAAG,OAAtB;EACA,IAAMC,cAAc,GAAG,QAAvB;EAEA;EACA;EACA;EACA;EACA;;MAEMC;EACJ,mBAAYzjB,OAAZ,EAAqBwB,MAArB,EAA6B;EAC3B,QAAI,OAAOiV,0BAAP,KAAkB,WAAtB,EAAmC;EACjC,YAAM,IAAI5T,SAAJ,CAAc,8DAAd,CAAN;EACD,KAH0B;;;EAM3B,SAAK6gB,UAAL,GAAkB,IAAlB;EACA,SAAKC,QAAL,GAAgB,CAAhB;EACA,SAAKC,WAAL,GAAmB,EAAnB;EACA,SAAKC,cAAL,GAAsB,EAAtB;EACA,SAAK/N,OAAL,GAAe,IAAf,CAV2B;;EAa3B,SAAK9V,OAAL,GAAeA,OAAf;EACA,SAAKwB,MAAL,GAAc,KAAKsK,UAAL,CAAgBtK,MAAhB,CAAd;EACA,SAAKsiB,GAAL,GAAW,IAAX;;EAEA,SAAKC,aAAL;EACD;;;;;EAgCD;WAEAC,SAAA,kBAAS;EACP,SAAKN,UAAL,GAAkB,IAAlB;EACD;;WAEDO,UAAA,mBAAU;EACR,SAAKP,UAAL,GAAkB,KAAlB;EACD;;WAEDQ,gBAAA,yBAAgB;EACd,SAAKR,UAAL,GAAkB,CAAC,KAAKA,UAAxB;EACD;;WAED5c,SAAA,gBAAOzI,KAAP,EAAc;EACZ,QAAI,CAAC,KAAKqlB,UAAV,EAAsB;EACpB;EACD;;EAED,QAAIrlB,KAAJ,EAAW;EACT,UAAM8lB,OAAO,GAAG,KAAKhN,WAAL,CAAiB5T,QAAjC;EACA,UAAIwU,OAAO,GAAGzZ,qBAAC,CAACD,KAAK,CAACoV,aAAP,CAAD,CAAuBhO,IAAvB,CAA4B0e,OAA5B,CAAd;;EAEA,UAAI,CAACpM,OAAL,EAAc;EACZA,QAAAA,OAAO,GAAG,IAAI,KAAKZ,WAAT,CACR9Y,KAAK,CAACoV,aADE,EAER,KAAK2Q,kBAAL,EAFQ,CAAV;EAIA9lB,QAAAA,qBAAC,CAACD,KAAK,CAACoV,aAAP,CAAD,CAAuBhO,IAAvB,CAA4B0e,OAA5B,EAAqCpM,OAArC;EACD;;EAEDA,MAAAA,OAAO,CAAC8L,cAAR,CAAuBQ,KAAvB,GAA+B,CAACtM,OAAO,CAAC8L,cAAR,CAAuBQ,KAAvD;;EAEA,UAAItM,OAAO,CAACuM,oBAAR,EAAJ,EAAoC;EAClCvM,QAAAA,OAAO,CAACwM,MAAR,CAAe,IAAf,EAAqBxM,OAArB;EACD,OAFD,MAEO;EACLA,QAAAA,OAAO,CAACyM,MAAR,CAAe,IAAf,EAAqBzM,OAArB;EACD;EACF,KAnBD,MAmBO;EACL,UAAIzZ,qBAAC,CAAC,KAAKmmB,aAAL,EAAD,CAAD,CAAwBvf,QAAxB,CAAiCjB,iBAAjC,CAAJ,EAAuD;EACrD,aAAKugB,MAAL,CAAY,IAAZ,EAAkB,IAAlB;;EACA;EACD;;EAED,WAAKD,MAAL,CAAY,IAAZ,EAAkB,IAAlB;EACD;EACF;;WAED5f,UAAA,mBAAU;EACRyJ,IAAAA,YAAY,CAAC,KAAKuV,QAAN,CAAZ;EAEArlB,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAK5E,OAAlB,EAA2B,KAAKmX,WAAL,CAAiB5T,QAA5C;EAEAjF,IAAAA,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgBuN,GAAhB,CAAoB,KAAK4J,WAAL,CAAiB3T,SAArC;EACAlF,IAAAA,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgB8E,OAAhB,CAAwB,QAAxB,EAAkCyI,GAAlC,CAAsC,eAAtC,EAAuD,KAAKmX,iBAA5D;;EAEA,QAAI,KAAKZ,GAAT,EAAc;EACZxlB,MAAAA,qBAAC,CAAC,KAAKwlB,GAAN,CAAD,CAAYze,MAAZ;EACD;;EAED,SAAKqe,UAAL,GAAkB,IAAlB;EACA,SAAKC,QAAL,GAAgB,IAAhB;EACA,SAAKC,WAAL,GAAmB,IAAnB;EACA,SAAKC,cAAL,GAAsB,IAAtB;;EACA,QAAI,KAAK/N,OAAT,EAAkB;EAChB,WAAKA,OAAL,CAAaiB,OAAb;EACD;;EAED,SAAKjB,OAAL,GAAe,IAAf;EACA,SAAK9V,OAAL,GAAe,IAAf;EACA,SAAKwB,MAAL,GAAc,IAAd;EACA,SAAKsiB,GAAL,GAAW,IAAX;EACD;;WAED1R,OAAA,gBAAO;EAAA;;EACL,QAAI9T,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgBS,GAAhB,CAAoB,SAApB,MAAmC,MAAvC,EAA+C;EAC7C,YAAM,IAAI0B,KAAJ,CAAU,qCAAV,CAAN;EACD;;EAED,QAAMoU,SAAS,GAAGjY,qBAAC,CAAC0G,KAAF,CAAQ,KAAKmS,WAAL,CAAiBnS,KAAjB,CAAuB2d,IAA/B,CAAlB;;EACA,QAAI,KAAKgC,aAAL,MAAwB,KAAKjB,UAAjC,EAA6C;EAC3CplB,MAAAA,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgBiB,OAAhB,CAAwBsV,SAAxB;EAEA,UAAMqO,UAAU,GAAG1lB,IAAI,CAACmD,cAAL,CAAoB,KAAKrC,OAAzB,CAAnB;EACA,UAAM6kB,UAAU,GAAGvmB,qBAAC,CAAC+I,QAAF,CACjBud,UAAU,KAAK,IAAf,GAAsBA,UAAtB,GAAmC,KAAK5kB,OAAL,CAAa8kB,aAAb,CAA2BxiB,eAD7C,EAEjB,KAAKtC,OAFY,CAAnB;;EAKA,UAAIuW,SAAS,CAAC9R,kBAAV,MAAkC,CAACogB,UAAvC,EAAmD;EACjD;EACD;;EAED,UAAMf,GAAG,GAAG,KAAKW,aAAL,EAAZ;EACA,UAAMM,KAAK,GAAG7lB,IAAI,CAACO,MAAL,CAAY,KAAK0X,WAAL,CAAiB9T,IAA7B,CAAd;EAEAygB,MAAAA,GAAG,CAACrc,YAAJ,CAAiB,IAAjB,EAAuBsd,KAAvB;EACA,WAAK/kB,OAAL,CAAayH,YAAb,CAA0B,kBAA1B,EAA8Csd,KAA9C;EAEA,WAAKC,UAAL;;EAEA,UAAI,KAAKxjB,MAAL,CAAYggB,SAAhB,EAA2B;EACzBljB,QAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAOpU,QAAP,CAAgB1L,iBAAhB;EACD;;EAED,UAAMsT,SAAS,GAAG,OAAO,KAAK9V,MAAL,CAAY8V,SAAnB,KAAiC,UAAjC,GAChB,KAAK9V,MAAL,CAAY8V,SAAZ,CAAsBxZ,IAAtB,CAA2B,IAA3B,EAAiCgmB,GAAjC,EAAsC,KAAK9jB,OAA3C,CADgB,GAEhB,KAAKwB,MAAL,CAAY8V,SAFd;;EAIA,UAAM2N,UAAU,GAAG,KAAKC,cAAL,CAAoB5N,SAApB,CAAnB;;EACA,WAAK6N,kBAAL,CAAwBF,UAAxB;;EAEA,UAAMpD,SAAS,GAAG,KAAKuD,aAAL,EAAlB;;EACA9mB,MAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAOre,IAAP,CAAY,KAAK0R,WAAL,CAAiB5T,QAA7B,EAAuC,IAAvC;;EAEA,UAAI,CAACjF,qBAAC,CAAC+I,QAAF,CAAW,KAAKrH,OAAL,CAAa8kB,aAAb,CAA2BxiB,eAAtC,EAAuD,KAAKwhB,GAA5D,CAAL,EAAuE;EACrExlB,QAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAO5H,QAAP,CAAgB2F,SAAhB;EACD;;EAEDvjB,MAAAA,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgBiB,OAAhB,CAAwB,KAAKkW,WAAL,CAAiBnS,KAAjB,CAAuB6d,QAA/C;EAEA,WAAK/M,OAAL,GAAe,IAAIW,0BAAJ,CAAW,KAAKzW,OAAhB,EAAyB8jB,GAAzB,EAA8B,KAAKnN,gBAAL,CAAsBsO,UAAtB,CAA9B,CAAf;EAEA3mB,MAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAOpU,QAAP,CAAgBzL,iBAAhB;EACA3F,MAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAOpU,QAAP,CAAgB,KAAKlO,MAAL,CAAYugB,WAA5B,EA5C2C;EA+C3C;EACA;EACA;;EACA,UAAI,kBAAkBliB,QAAQ,CAACyC,eAA/B,EAAgD;EAC9ChE,QAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBnH,QAAjB,GAA4B5J,EAA5B,CAA+B,WAA/B,EAA4C,IAA5C,EAAkDvH,qBAAC,CAACuY,IAApD;EACD;;EAED,UAAM/D,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,YAAI,KAAI,CAACtR,MAAL,CAAYggB,SAAhB,EAA2B;EACzB,UAAA,KAAI,CAAC6D,cAAL;EACD;;EAED,YAAMC,cAAc,GAAG,KAAI,CAAC1B,WAA5B;EACA,QAAA,KAAI,CAACA,WAAL,GAAmB,IAAnB;EAEAtlB,QAAAA,qBAAC,CAAC,KAAI,CAAC0B,OAAN,CAAD,CAAgBiB,OAAhB,CAAwB,KAAI,CAACkW,WAAL,CAAiBnS,KAAjB,CAAuB4d,KAA/C;;EAEA,YAAI0C,cAAc,KAAK9C,eAAvB,EAAwC;EACtC,UAAA,KAAI,CAACgC,MAAL,CAAY,IAAZ,EAAkB,KAAlB;EACD;EACF,OAbD;;EAeA,UAAIlmB,qBAAC,CAAC,KAAKwlB,GAAN,CAAD,CAAY5e,QAAZ,CAAqBlB,iBAArB,CAAJ,EAA2C;EACzC,YAAMxD,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC,KAAKujB,GAA3C,CAA3B;EAEAxlB,QAAAA,qBAAC,CAAC,KAAKwlB,GAAN,CAAD,CACG7kB,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4BsV,QAD5B,EAEGvT,oBAFH,CAEwBiB,kBAFxB;EAGD,OAND,MAMO;EACLsS,QAAAA,QAAQ;EACT;EACF;EACF;;WAEDX,OAAA,cAAK2J,QAAL,EAAe;EAAA;;EACb,QAAMgI,GAAG,GAAG,KAAKW,aAAL,EAAZ;EACA,QAAM3N,SAAS,GAAGxY,qBAAC,CAAC0G,KAAF,CAAQ,KAAKmS,WAAL,CAAiBnS,KAAjB,CAAuByd,IAA/B,CAAlB;;EACA,QAAM3P,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,UAAI,MAAI,CAAC8Q,WAAL,KAAqBrB,gBAArB,IAAyCuB,GAAG,CAACnhB,UAAjD,EAA6D;EAC3DmhB,QAAAA,GAAG,CAACnhB,UAAJ,CAAegb,WAAf,CAA2BmG,GAA3B;EACD;;EAED,MAAA,MAAI,CAACyB,cAAL;;EACA,MAAA,MAAI,CAACvlB,OAAL,CAAaqb,eAAb,CAA6B,kBAA7B;;EACA/c,MAAAA,qBAAC,CAAC,MAAI,CAAC0B,OAAN,CAAD,CAAgBiB,OAAhB,CAAwB,MAAI,CAACkW,WAAL,CAAiBnS,KAAjB,CAAuB0d,MAA/C;;EACA,UAAI,MAAI,CAAC5M,OAAL,KAAiB,IAArB,EAA2B;EACzB,QAAA,MAAI,CAACA,OAAL,CAAaiB,OAAb;EACD;;EAED,UAAI+E,QAAJ,EAAc;EACZA,QAAAA,QAAQ;EACT;EACF,KAfD;;EAiBAxd,IAAAA,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgBiB,OAAhB,CAAwB6V,SAAxB;;EAEA,QAAIA,SAAS,CAACrS,kBAAV,EAAJ,EAAoC;EAClC;EACD;;EAEDnG,IAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAO7e,WAAP,CAAmBhB,iBAAnB,EA1Ba;EA6Bb;;EACA,QAAI,kBAAkBpE,QAAQ,CAACyC,eAA/B,EAAgD;EAC9ChE,MAAAA,qBAAC,CAACuB,QAAQ,CAAC+W,IAAV,CAAD,CAAiBnH,QAAjB,GAA4BlC,GAA5B,CAAgC,WAAhC,EAA6C,IAA7C,EAAmDjP,qBAAC,CAACuY,IAArD;EACD;;EAED,SAAKgN,cAAL,CAAoBN,aAApB,IAAqC,KAArC;EACA,SAAKM,cAAL,CAAoBP,aAApB,IAAqC,KAArC;EACA,SAAKO,cAAL,CAAoBR,aAApB,IAAqC,KAArC;;EAEA,QAAI/kB,qBAAC,CAAC,KAAKwlB,GAAN,CAAD,CAAY5e,QAAZ,CAAqBlB,iBAArB,CAAJ,EAA2C;EACzC,UAAMxD,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsCujB,GAAtC,CAA3B;EAEAxlB,MAAAA,qBAAC,CAACwlB,GAAD,CAAD,CACG7kB,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4BsV,QAD5B,EAEGvT,oBAFH,CAEwBiB,kBAFxB;EAGD,KAND,MAMO;EACLsS,MAAAA,QAAQ;EACT;;EAED,SAAK8Q,WAAL,GAAmB,EAAnB;EACD;;WAED5M,SAAA,kBAAS;EACP,QAAI,KAAKlB,OAAL,KAAiB,IAArB,EAA2B;EACzB,WAAKA,OAAL,CAAamB,cAAb;EACD;EACF;;;WAID0N,gBAAA,yBAAgB;EACd,WAAOxjB,OAAO,CAAC,KAAKqkB,QAAL,EAAD,CAAd;EACD;;WAEDL,qBAAA,4BAAmBF,UAAnB,EAA+B;EAC7B3mB,IAAAA,qBAAC,CAAC,KAAKmmB,aAAL,EAAD,CAAD,CAAwB/U,QAAxB,CAAoC2R,YAApC,SAAoD4D,UAApD;EACD;;WAEDR,gBAAA,yBAAgB;EACd,SAAKX,GAAL,GAAW,KAAKA,GAAL,IAAYxlB,qBAAC,CAAC,KAAKkD,MAAL,CAAYigB,QAAb,CAAD,CAAwB,CAAxB,CAAvB;EACA,WAAO,KAAKqC,GAAZ;EACD;;WAEDkB,aAAA,sBAAa;EACX,QAAMlB,GAAG,GAAG,KAAKW,aAAL,EAAZ;EACA,SAAKgB,iBAAL,CAAuBnnB,qBAAC,CAACwlB,GAAG,CAAC3b,gBAAJ,CAAqBgb,sBAArB,CAAD,CAAxB,EAAwE,KAAKqC,QAAL,EAAxE;EACAlnB,IAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAO7e,WAAP,CAAsBjB,iBAAtB,SAAyCC,iBAAzC;EACD;;WAEDwhB,oBAAA,2BAAkBjgB,QAAlB,EAA4BkgB,OAA5B,EAAqC;EACnC,QAAI,OAAOA,OAAP,KAAmB,QAAnB,KAAgCA,OAAO,CAACrkB,QAAR,IAAoBqkB,OAAO,CAAC3iB,MAA5D,CAAJ,EAAyE;EACvE;EACA,UAAI,KAAKvB,MAAL,CAAYogB,IAAhB,EAAsB;EACpB,YAAI,CAACtjB,qBAAC,CAAConB,OAAD,CAAD,CAAW7gB,MAAX,GAAoBrG,EAApB,CAAuBgH,QAAvB,CAAL,EAAuC;EACrCA,UAAAA,QAAQ,CAACmgB,KAAT,GAAiBC,MAAjB,CAAwBF,OAAxB;EACD;EACF,OAJD,MAIO;EACLlgB,QAAAA,QAAQ,CAACqgB,IAAT,CAAcvnB,qBAAC,CAAConB,OAAD,CAAD,CAAWG,IAAX,EAAd;EACD;;EAED;EACD;;EAED,QAAI,KAAKrkB,MAAL,CAAYogB,IAAhB,EAAsB;EACpB,UAAI,KAAKpgB,MAAL,CAAYwgB,QAAhB,EAA0B;EACxB0D,QAAAA,OAAO,GAAGtF,YAAY,CAACsF,OAAD,EAAU,KAAKlkB,MAAL,CAAY8e,SAAtB,EAAiC,KAAK9e,MAAL,CAAY+e,UAA7C,CAAtB;EACD;;EAED/a,MAAAA,QAAQ,CAACoc,IAAT,CAAc8D,OAAd;EACD,KAND,MAMO;EACLlgB,MAAAA,QAAQ,CAACqgB,IAAT,CAAcH,OAAd;EACD;EACF;;WAEDF,WAAA,oBAAW;EACT,QAAI9D,KAAK,GAAG,KAAK1hB,OAAL,CAAaE,YAAb,CAA0B,qBAA1B,CAAZ;;EAEA,QAAI,CAACwhB,KAAL,EAAY;EACVA,MAAAA,KAAK,GAAG,OAAO,KAAKlgB,MAAL,CAAYkgB,KAAnB,KAA6B,UAA7B,GACN,KAAKlgB,MAAL,CAAYkgB,KAAZ,CAAkB5jB,IAAlB,CAAuB,KAAKkC,OAA5B,CADM,GAEN,KAAKwB,MAAL,CAAYkgB,KAFd;EAGD;;EAED,WAAOA,KAAP;EACD;;;WAID/K,mBAAA,0BAAiBsO,UAAjB,EAA6B;EAAA;;EAC3B,QAAMa,eAAe,GAAG;EACtBxO,MAAAA,SAAS,EAAE2N,UADW;EAEtBxN,MAAAA,SAAS,EAAE;EACTlC,QAAAA,MAAM,EAAE,KAAKgC,UAAL,EADC;EAET/B,QAAAA,IAAI,EAAE;EACJuQ,UAAAA,QAAQ,EAAE,KAAKvkB,MAAL,CAAYsgB;EADlB,SAFG;EAKTkE,QAAAA,KAAK,EAAE;EACLhmB,UAAAA,OAAO,EAAEojB;EADJ,SALE;EAQTzL,QAAAA,eAAe,EAAE;EACfC,UAAAA,iBAAiB,EAAE,KAAKpW,MAAL,CAAYiU;EADhB;EARR,OAFW;EActBwQ,MAAAA,QAAQ,EAAE,kBAAAxgB,IAAI,EAAI;EAChB,YAAIA,IAAI,CAACygB,iBAAL,KAA2BzgB,IAAI,CAAC6R,SAApC,EAA+C;EAC7C,UAAA,MAAI,CAAC6O,4BAAL,CAAkC1gB,IAAlC;EACD;EACF,OAlBqB;EAmBtB2gB,MAAAA,QAAQ,EAAE,kBAAA3gB,IAAI;EAAA,eAAI,MAAI,CAAC0gB,4BAAL,CAAkC1gB,IAAlC,CAAJ;EAAA;EAnBQ,KAAxB;EAsBA,wBACKqgB,eADL,EAEK,KAAKtkB,MAAL,CAAYoU,YAFjB;EAID;;WAED2B,aAAA,sBAAa;EAAA;;EACX,QAAMhC,MAAM,GAAG,EAAf;;EAEA,QAAI,OAAO,KAAK/T,MAAL,CAAY+T,MAAnB,KAA8B,UAAlC,EAA8C;EAC5CA,MAAAA,MAAM,CAACjW,EAAP,GAAY,UAAAmG,IAAI,EAAI;EAClBA,QAAAA,IAAI,CAAC+R,OAAL,gBACK/R,IAAI,CAAC+R,OADV,EAEM,MAAI,CAAChW,MAAL,CAAY+T,MAAZ,CAAmB9P,IAAI,CAAC+R,OAAxB,EAAiC,MAAI,CAACxX,OAAtC,KAAkD,EAFxD;EAKA,eAAOyF,IAAP;EACD,OAPD;EAQD,KATD,MASO;EACL8P,MAAAA,MAAM,CAACA,MAAP,GAAgB,KAAK/T,MAAL,CAAY+T,MAA5B;EACD;;EAED,WAAOA,MAAP;EACD;;WAED6P,gBAAA,yBAAgB;EACd,QAAI,KAAK5jB,MAAL,CAAYqgB,SAAZ,KAA0B,KAA9B,EAAqC;EACnC,aAAOhiB,QAAQ,CAAC+W,IAAhB;EACD;;EAED,QAAI1X,IAAI,CAACkC,SAAL,CAAe,KAAKI,MAAL,CAAYqgB,SAA3B,CAAJ,EAA2C;EACzC,aAAOvjB,qBAAC,CAAC,KAAKkD,MAAL,CAAYqgB,SAAb,CAAR;EACD;;EAED,WAAOvjB,qBAAC,CAACuB,QAAD,CAAD,CAAYwmB,IAAZ,CAAiB,KAAK7kB,MAAL,CAAYqgB,SAA7B,CAAP;EACD;;WAEDqD,iBAAA,wBAAe5N,SAAf,EAA0B;EACxB,WAAO2K,aAAa,CAAC3K,SAAS,CAAClV,WAAV,EAAD,CAApB;EACD;;WAED2hB,gBAAA,yBAAgB;EAAA;;EACd,QAAMuC,QAAQ,GAAG,KAAK9kB,MAAL,CAAYP,OAAZ,CAAoBH,KAApB,CAA0B,GAA1B,CAAjB;EAEAwlB,IAAAA,QAAQ,CAAC/L,OAAT,CAAiB,UAAAtZ,OAAO,EAAI;EAC1B,UAAIA,OAAO,KAAK,OAAhB,EAAyB;EACvB3C,QAAAA,qBAAC,CAAC,MAAI,CAAC0B,OAAN,CAAD,CAAgB6F,EAAhB,CACE,MAAI,CAACsR,WAAL,CAAiBnS,KAAjB,CAAuB8d,KADzB,EAEE,MAAI,CAACthB,MAAL,CAAYvB,QAFd,EAGE,UAAA5B,KAAK;EAAA,iBAAI,MAAI,CAACyI,MAAL,CAAYzI,KAAZ,CAAJ;EAAA,SAHP;EAKD,OAND,MAMO,IAAI4C,OAAO,KAAKuiB,cAAhB,EAAgC;EACrC,YAAM+C,OAAO,GAAGtlB,OAAO,KAAKoiB,aAAZ,GACd,MAAI,CAAClM,WAAL,CAAiBnS,KAAjB,CAAuBie,UADT,GAEd,MAAI,CAAC9L,WAAL,CAAiBnS,KAAjB,CAAuB+d,OAFzB;EAGA,YAAMyD,QAAQ,GAAGvlB,OAAO,KAAKoiB,aAAZ,GACf,MAAI,CAAClM,WAAL,CAAiBnS,KAAjB,CAAuBke,UADR,GAEf,MAAI,CAAC/L,WAAL,CAAiBnS,KAAjB,CAAuBge,QAFzB;EAIA1kB,QAAAA,qBAAC,CAAC,MAAI,CAAC0B,OAAN,CAAD,CACG6F,EADH,CACM0gB,OADN,EACe,MAAI,CAAC/kB,MAAL,CAAYvB,QAD3B,EACqC,UAAA5B,KAAK;EAAA,iBAAI,MAAI,CAACkmB,MAAL,CAAYlmB,KAAZ,CAAJ;EAAA,SAD1C,EAEGwH,EAFH,CAEM2gB,QAFN,EAEgB,MAAI,CAAChlB,MAAL,CAAYvB,QAF5B,EAEsC,UAAA5B,KAAK;EAAA,iBAAI,MAAI,CAACmmB,MAAL,CAAYnmB,KAAZ,CAAJ;EAAA,SAF3C;EAGD;EACF,KAnBD;;EAqBA,SAAKqmB,iBAAL,GAAyB,YAAM;EAC7B,UAAI,MAAI,CAAC1kB,OAAT,EAAkB;EAChB,QAAA,MAAI,CAACmS,IAAL;EACD;EACF,KAJD;;EAMA7T,IAAAA,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgB8E,OAAhB,CAAwB,QAAxB,EAAkCe,EAAlC,CAAqC,eAArC,EAAsD,KAAK6e,iBAA3D;;EAEA,QAAI,KAAKljB,MAAL,CAAYvB,QAAhB,EAA0B;EACxB,WAAKuB,MAAL,gBACK,KAAKA,MADV;EAEEP,QAAAA,OAAO,EAAE,QAFX;EAGEhB,QAAAA,QAAQ,EAAE;EAHZ;EAKD,KAND,MAMO;EACL,WAAKwmB,SAAL;EACD;EACF;;WAEDA,YAAA,qBAAY;EACV,QAAMC,SAAS,GAAG,OAAO,KAAK1mB,OAAL,CAAaE,YAAb,CAA0B,qBAA1B,CAAzB;;EAEA,QAAI,KAAKF,OAAL,CAAaE,YAAb,CAA0B,OAA1B,KAAsCwmB,SAAS,KAAK,QAAxD,EAAkE;EAChE,WAAK1mB,OAAL,CAAayH,YAAb,CACE,qBADF,EAEE,KAAKzH,OAAL,CAAaE,YAAb,CAA0B,OAA1B,KAAsC,EAFxC;EAKA,WAAKF,OAAL,CAAayH,YAAb,CAA0B,OAA1B,EAAmC,EAAnC;EACD;EACF;;WAED8c,SAAA,gBAAOlmB,KAAP,EAAc0Z,OAAd,EAAuB;EACrB,QAAMoM,OAAO,GAAG,KAAKhN,WAAL,CAAiB5T,QAAjC;EACAwU,IAAAA,OAAO,GAAGA,OAAO,IAAIzZ,qBAAC,CAACD,KAAK,CAACoV,aAAP,CAAD,CAAuBhO,IAAvB,CAA4B0e,OAA5B,CAArB;;EAEA,QAAI,CAACpM,OAAL,EAAc;EACZA,MAAAA,OAAO,GAAG,IAAI,KAAKZ,WAAT,CACR9Y,KAAK,CAACoV,aADE,EAER,KAAK2Q,kBAAL,EAFQ,CAAV;EAIA9lB,MAAAA,qBAAC,CAACD,KAAK,CAACoV,aAAP,CAAD,CAAuBhO,IAAvB,CAA4B0e,OAA5B,EAAqCpM,OAArC;EACD;;EAED,QAAI1Z,KAAJ,EAAW;EACT0Z,MAAAA,OAAO,CAAC8L,cAAR,CACExlB,KAAK,CAAC6I,IAAN,KAAe,SAAf,GAA2Boc,aAA3B,GAA2CD,aAD7C,IAEI,IAFJ;EAGD;;EAED,QAAI/kB,qBAAC,CAACyZ,OAAO,CAAC0M,aAAR,EAAD,CAAD,CAA2Bvf,QAA3B,CAAoCjB,iBAApC,KAAwD8T,OAAO,CAAC6L,WAAR,KAAwBrB,gBAApF,EAAsG;EACpGxK,MAAAA,OAAO,CAAC6L,WAAR,GAAsBrB,gBAAtB;EACA;EACD;;EAEDnU,IAAAA,YAAY,CAAC2J,OAAO,CAAC4L,QAAT,CAAZ;EAEA5L,IAAAA,OAAO,CAAC6L,WAAR,GAAsBrB,gBAAtB;;EAEA,QAAI,CAACxK,OAAO,CAACvW,MAAR,CAAemgB,KAAhB,IAAyB,CAAC5J,OAAO,CAACvW,MAAR,CAAemgB,KAAf,CAAqBvP,IAAnD,EAAyD;EACvD2F,MAAAA,OAAO,CAAC3F,IAAR;EACA;EACD;;EAED2F,IAAAA,OAAO,CAAC4L,QAAR,GAAmBxkB,UAAU,CAAC,YAAM;EAClC,UAAI4Y,OAAO,CAAC6L,WAAR,KAAwBrB,gBAA5B,EAA8C;EAC5CxK,QAAAA,OAAO,CAAC3F,IAAR;EACD;EACF,KAJ4B,EAI1B2F,OAAO,CAACvW,MAAR,CAAemgB,KAAf,CAAqBvP,IAJK,CAA7B;EAKD;;WAEDoS,SAAA,gBAAOnmB,KAAP,EAAc0Z,OAAd,EAAuB;EACrB,QAAMoM,OAAO,GAAG,KAAKhN,WAAL,CAAiB5T,QAAjC;EACAwU,IAAAA,OAAO,GAAGA,OAAO,IAAIzZ,qBAAC,CAACD,KAAK,CAACoV,aAAP,CAAD,CAAuBhO,IAAvB,CAA4B0e,OAA5B,CAArB;;EAEA,QAAI,CAACpM,OAAL,EAAc;EACZA,MAAAA,OAAO,GAAG,IAAI,KAAKZ,WAAT,CACR9Y,KAAK,CAACoV,aADE,EAER,KAAK2Q,kBAAL,EAFQ,CAAV;EAIA9lB,MAAAA,qBAAC,CAACD,KAAK,CAACoV,aAAP,CAAD,CAAuBhO,IAAvB,CAA4B0e,OAA5B,EAAqCpM,OAArC;EACD;;EAED,QAAI1Z,KAAJ,EAAW;EACT0Z,MAAAA,OAAO,CAAC8L,cAAR,CACExlB,KAAK,CAAC6I,IAAN,KAAe,UAAf,GAA4Boc,aAA5B,GAA4CD,aAD9C,IAEI,KAFJ;EAGD;;EAED,QAAItL,OAAO,CAACuM,oBAAR,EAAJ,EAAoC;EAClC;EACD;;EAEDlW,IAAAA,YAAY,CAAC2J,OAAO,CAAC4L,QAAT,CAAZ;EAEA5L,IAAAA,OAAO,CAAC6L,WAAR,GAAsBpB,eAAtB;;EAEA,QAAI,CAACzK,OAAO,CAACvW,MAAR,CAAemgB,KAAhB,IAAyB,CAAC5J,OAAO,CAACvW,MAAR,CAAemgB,KAAf,CAAqBxP,IAAnD,EAAyD;EACvD4F,MAAAA,OAAO,CAAC5F,IAAR;EACA;EACD;;EAED4F,IAAAA,OAAO,CAAC4L,QAAR,GAAmBxkB,UAAU,CAAC,YAAM;EAClC,UAAI4Y,OAAO,CAAC6L,WAAR,KAAwBpB,eAA5B,EAA6C;EAC3CzK,QAAAA,OAAO,CAAC5F,IAAR;EACD;EACF,KAJ4B,EAI1B4F,OAAO,CAACvW,MAAR,CAAemgB,KAAf,CAAqBxP,IAJK,CAA7B;EAKD;;WAEDmS,uBAAA,gCAAuB;EACrB,SAAK,IAAMrjB,OAAX,IAAsB,KAAK4iB,cAA3B,EAA2C;EACzC,UAAI,KAAKA,cAAL,CAAoB5iB,OAApB,CAAJ,EAAkC;EAChC,eAAO,IAAP;EACD;EACF;;EAED,WAAO,KAAP;EACD;;WAED6K,aAAA,oBAAWtK,MAAX,EAAmB;EACjB,QAAMmlB,cAAc,GAAGroB,qBAAC,CAAC,KAAK0B,OAAN,CAAD,CAAgByF,IAAhB,EAAvB;EAEA9D,IAAAA,MAAM,CAACkf,IAAP,CAAY8F,cAAZ,EACGpM,OADH,CACW,UAAAqM,QAAQ,EAAI;EACnB,UAAIrF,qBAAqB,CAAChT,OAAtB,CAA8BqY,QAA9B,MAA4C,CAAC,CAAjD,EAAoD;EAClD,eAAOD,cAAc,CAACC,QAAD,CAArB;EACD;EACF,KALH;EAOAplB,IAAAA,MAAM,gBACD,KAAK2V,WAAL,CAAiBvO,OADhB,EAED+d,cAFC,EAGA,OAAOnlB,MAAP,KAAkB,QAAlB,IAA8BA,MAA9B,GAAuCA,MAAvC,GAAgD,EAHhD,CAAN;;EAMA,QAAI,OAAOA,MAAM,CAACmgB,KAAd,KAAwB,QAA5B,EAAsC;EACpCngB,MAAAA,MAAM,CAACmgB,KAAP,GAAe;EACbvP,QAAAA,IAAI,EAAE5Q,MAAM,CAACmgB,KADA;EAEbxP,QAAAA,IAAI,EAAE3Q,MAAM,CAACmgB;EAFA,OAAf;EAID;;EAED,QAAI,OAAOngB,MAAM,CAACkgB,KAAd,KAAwB,QAA5B,EAAsC;EACpClgB,MAAAA,MAAM,CAACkgB,KAAP,GAAelgB,MAAM,CAACkgB,KAAP,CAAa7jB,QAAb,EAAf;EACD;;EAED,QAAI,OAAO2D,MAAM,CAACkkB,OAAd,KAA0B,QAA9B,EAAwC;EACtClkB,MAAAA,MAAM,CAACkkB,OAAP,GAAiBlkB,MAAM,CAACkkB,OAAP,CAAe7nB,QAAf,EAAjB;EACD;;EAEDqB,IAAAA,IAAI,CAACoC,eAAL,CACE+B,MADF,EAEE7B,MAFF,EAGE,KAAK2V,WAAL,CAAiBhO,WAHnB;;EAMA,QAAI3H,MAAM,CAACwgB,QAAX,EAAqB;EACnBxgB,MAAAA,MAAM,CAACigB,QAAP,GAAkBrB,YAAY,CAAC5e,MAAM,CAACigB,QAAR,EAAkBjgB,MAAM,CAAC8e,SAAzB,EAAoC9e,MAAM,CAAC+e,UAA3C,CAA9B;EACD;;EAED,WAAO/e,MAAP;EACD;;WAED4iB,qBAAA,8BAAqB;EACnB,QAAM5iB,MAAM,GAAG,EAAf;;EAEA,QAAI,KAAKA,MAAT,EAAiB;EACf,WAAK,IAAMqlB,GAAX,IAAkB,KAAKrlB,MAAvB,EAA+B;EAC7B,YAAI,KAAK2V,WAAL,CAAiBvO,OAAjB,CAAyBie,GAAzB,MAAkC,KAAKrlB,MAAL,CAAYqlB,GAAZ,CAAtC,EAAwD;EACtDrlB,UAAAA,MAAM,CAACqlB,GAAD,CAAN,GAAc,KAAKrlB,MAAL,CAAYqlB,GAAZ,CAAd;EACD;EACF;EACF;;EAED,WAAOrlB,MAAP;EACD;;WAED+jB,iBAAA,0BAAiB;EACf,QAAMuB,IAAI,GAAGxoB,qBAAC,CAAC,KAAKmmB,aAAL,EAAD,CAAd;EACA,QAAMsC,QAAQ,GAAGD,IAAI,CAAClU,IAAL,CAAU,OAAV,EAAmB7U,KAAnB,CAAyBujB,kBAAzB,CAAjB;;EACA,QAAIyF,QAAQ,KAAK,IAAb,IAAqBA,QAAQ,CAACze,MAAlC,EAA0C;EACxCwe,MAAAA,IAAI,CAAC7hB,WAAL,CAAiB8hB,QAAQ,CAACC,IAAT,CAAc,EAAd,CAAjB;EACD;EACF;;WAEDb,+BAAA,sCAA6Bc,UAA7B,EAAyC;EACvC,SAAKnD,GAAL,GAAWmD,UAAU,CAACC,QAAX,CAAoBC,MAA/B;;EACA,SAAK5B,cAAL;;EACA,SAAKJ,kBAAL,CAAwB,KAAKD,cAAL,CAAoB+B,UAAU,CAAC3P,SAA/B,CAAxB;EACD;;WAED+N,iBAAA,0BAAiB;EACf,QAAMvB,GAAG,GAAG,KAAKW,aAAL,EAAZ;EACA,QAAM2C,mBAAmB,GAAG,KAAK5lB,MAAL,CAAYggB,SAAxC;;EAEA,QAAIsC,GAAG,CAAC5jB,YAAJ,CAAiB,aAAjB,MAAoC,IAAxC,EAA8C;EAC5C;EACD;;EAED5B,IAAAA,qBAAC,CAACwlB,GAAD,CAAD,CAAO7e,WAAP,CAAmBjB,iBAAnB;EACA,SAAKxC,MAAL,CAAYggB,SAAZ,GAAwB,KAAxB;EACA,SAAKrP,IAAL;EACA,SAAKC,IAAL;EACA,SAAK5Q,MAAL,CAAYggB,SAAZ,GAAwB4F,mBAAxB;EACD;;;YAIM9hB,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAMC,QAAQ,GAAGlH,qBAAC,CAAC,IAAD,CAAlB;EACA,UAAImH,IAAI,GAAGD,QAAQ,CAACC,IAAT,CAAclC,UAAd,CAAX;;EACA,UAAMsI,OAAO,GAAG,OAAOrK,MAAP,KAAkB,QAAlB,IAA8BA,MAA9C;;EAEA,UAAI,CAACiE,IAAD,IAAS,eAAevD,IAAf,CAAoBV,MAApB,CAAb,EAA0C;EACxC;EACD;;EAED,UAAI,CAACiE,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAIge,OAAJ,CAAY,IAAZ,EAAkB5X,OAAlB,CAAP;EACArG,QAAAA,QAAQ,CAACC,IAAT,CAAclC,UAAd,EAAwBkC,IAAxB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ;EACD;EACF,KArBM,CAAP;EAsBD;;;;0BAjnBoB;EACnB,aAAO8B,SAAP;EACD;;;0BAEoB;EACnB,aAAOsF,SAAP;EACD;;;0BAEiB;EAChB,aAAOvF,MAAP;EACD;;;0BAEqB;EACpB,aAAOE,UAAP;EACD;;;0BAEkB;EACjB,aAAOyB,KAAP;EACD;;;0BAEsB;EACrB,aAAOxB,WAAP;EACD;;;0BAEwB;EACvB,aAAO2F,aAAP;EACD;;;;;EA0lBH;EACA;EACA;EACA;EACA;;;AAEA7K,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaogB,OAAO,CAACne,gBAArB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyB2d,OAAzB;;AACAnlB,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAO+f,OAAO,CAACne,gBAAf;EACD,CAHD;;EC1vBA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,SAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,YAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAMG,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EACA,IAAMge,cAAY,GAAG,YAArB;EACA,IAAMC,oBAAkB,GAAG,IAAIrf,MAAJ,aAAqBof,cAArB,WAAyC,GAAzC,CAA3B;;EAEA,IAAMzY,SAAO,gBACR6a,OAAO,CAAC7a,OADA;EAEX0O,EAAAA,SAAS,EAAE,OAFA;EAGXrW,EAAAA,OAAO,EAAE,OAHE;EAIXykB,EAAAA,OAAO,EAAE,EAJE;EAKXjE,EAAAA,QAAQ,EAAE,yCACE,2BADF,GAEE,kCAFF,GAGE;EARD,EAAb;;EAWA,IAAMtY,aAAW,gBACZsa,OAAO,CAACta,WADI;EAEfuc,EAAAA,OAAO,EAAE;EAFM,EAAjB;;EAKA,IAAM1hB,iBAAe,GAAG,MAAxB;EACA,IAAMC,iBAAe,GAAG,MAAxB;EAEA,IAAMojB,cAAc,GAAG,iBAAvB;EACA,IAAMC,gBAAgB,GAAG,eAAzB;EAEA,IAAMtiB,OAAK,GAAG;EACZyd,EAAAA,IAAI,WAASjf,WADD;EAEZkf,EAAAA,MAAM,aAAWlf,WAFL;EAGZmf,EAAAA,IAAI,WAASnf,WAHD;EAIZof,EAAAA,KAAK,YAAUpf,WAJH;EAKZqf,EAAAA,QAAQ,eAAarf,WALT;EAMZsf,EAAAA,KAAK,YAAUtf,WANH;EAOZuf,EAAAA,OAAO,cAAYvf,WAPP;EAQZwf,EAAAA,QAAQ,eAAaxf,WART;EASZyf,EAAAA,UAAU,iBAAezf,WATb;EAUZ0f,EAAAA,UAAU,iBAAe1f;EAVb,CAAd;EAaA;EACA;EACA;EACA;EACA;;MAEM+jB;;;;;;;;;EA+BJ;WAEA5C,gBAAA,yBAAgB;EACd,WAAO,KAAKa,QAAL,MAAmB,KAAKgC,WAAL,EAA1B;EACD;;WAEDrC,qBAAA,4BAAmBF,UAAnB,EAA+B;EAC7B3mB,IAAAA,qBAAC,CAAC,KAAKmmB,aAAL,EAAD,CAAD,CAAwB/U,QAAxB,CAAoC2R,cAApC,SAAoD4D,UAApD;EACD;;WAEDR,gBAAA,yBAAgB;EACd,SAAKX,GAAL,GAAW,KAAKA,GAAL,IAAYxlB,qBAAC,CAAC,KAAKkD,MAAL,CAAYigB,QAAb,CAAD,CAAwB,CAAxB,CAAvB;EACA,WAAO,KAAKqC,GAAZ;EACD;;WAEDkB,aAAA,sBAAa;EACX,QAAM8B,IAAI,GAAGxoB,qBAAC,CAAC,KAAKmmB,aAAL,EAAD,CAAd,CADW;;EAIX,SAAKgB,iBAAL,CAAuBqB,IAAI,CAACT,IAAL,CAAUgB,cAAV,CAAvB,EAAkD,KAAK7B,QAAL,EAAlD;;EACA,QAAIE,OAAO,GAAG,KAAK8B,WAAL,EAAd;;EACA,QAAI,OAAO9B,OAAP,KAAmB,UAAvB,EAAmC;EACjCA,MAAAA,OAAO,GAAGA,OAAO,CAAC5nB,IAAR,CAAa,KAAKkC,OAAlB,CAAV;EACD;;EAED,SAAKylB,iBAAL,CAAuBqB,IAAI,CAACT,IAAL,CAAUiB,gBAAV,CAAvB,EAAoD5B,OAApD;EAEAoB,IAAAA,IAAI,CAAC7hB,WAAL,CAAoBjB,iBAApB,SAAuCC,iBAAvC;EACD;;;WAIDujB,cAAA,uBAAc;EACZ,WAAO,KAAKxnB,OAAL,CAAaE,YAAb,CAA0B,cAA1B,KACL,KAAKsB,MAAL,CAAYkkB,OADd;EAED;;WAEDH,iBAAA,0BAAiB;EACf,QAAMuB,IAAI,GAAGxoB,qBAAC,CAAC,KAAKmmB,aAAL,EAAD,CAAd;EACA,QAAMsC,QAAQ,GAAGD,IAAI,CAAClU,IAAL,CAAU,OAAV,EAAmB7U,KAAnB,CAAyBujB,oBAAzB,CAAjB;;EACA,QAAIyF,QAAQ,KAAK,IAAb,IAAqBA,QAAQ,CAACze,MAAT,GAAkB,CAA3C,EAA8C;EAC5Cwe,MAAAA,IAAI,CAAC7hB,WAAL,CAAiB8hB,QAAQ,CAACC,IAAT,CAAc,EAAd,CAAjB;EACD;EACF;;;YAIM1hB,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAIE,IAAI,GAAGnH,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,CAAX;;EACA,UAAMsI,OAAO,GAAG,OAAOrK,MAAP,KAAkB,QAAlB,GAA6BA,MAA7B,GAAsC,IAAtD;;EAEA,UAAI,CAACiE,IAAD,IAAS,eAAevD,IAAf,CAAoBV,MAApB,CAAb,EAA0C;EACxC;EACD;;EAED,UAAI,CAACiE,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAI8hB,OAAJ,CAAY,IAAZ,EAAkB1b,OAAlB,CAAP;EACAvN,QAAAA,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,EAAuBkC,IAAvB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ;EACD;EACF,KApBM,CAAP;EAqBD;;;;EAnGD;0BAEqB;EACnB,aAAO8B,SAAP;EACD;;;0BAEoB;EACnB,aAAOsF,SAAP;EACD;;;0BAEiB;EAChB,aAAOvF,MAAP;EACD;;;0BAEqB;EACpB,aAAOE,UAAP;EACD;;;0BAEkB;EACjB,aAAOyB,OAAP;EACD;;;0BAEsB;EACrB,aAAOxB,WAAP;EACD;;;0BAEwB;EACvB,aAAO2F,aAAP;EACD;;;;IA7BmBsa;EAuGtB;EACA;EACA;EACA;EACA;;;AAEAnlB,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAakkB,OAAO,CAACjiB,gBAArB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyByhB,OAAzB;;AACAjpB,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAO6jB,OAAO,CAACjiB,gBAAf;EACD,CAHD;;ECtKA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,WAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,cAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAME,cAAY,GAAG,WAArB;EACA,IAAMC,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EAEA,IAAMuF,SAAO,GAAG;EACd2M,EAAAA,MAAM,EAAE,EADM;EAEdkS,EAAAA,MAAM,EAAE,MAFM;EAGdlpB,EAAAA,MAAM,EAAE;EAHM,CAAhB;EAMA,IAAM4K,aAAW,GAAG;EAClBoM,EAAAA,MAAM,EAAE,QADU;EAElBkS,EAAAA,MAAM,EAAE,QAFU;EAGlBlpB,EAAAA,MAAM,EAAE;EAHU,CAApB;EAMA,IAAMmpB,cAAc,gBAAclkB,WAAlC;EACA,IAAMmkB,YAAY,cAAYnkB,WAA9B;EACA,IAAMmD,qBAAmB,YAAUnD,WAAV,GAAsBC,cAA/C;EAEA,IAAMmkB,wBAAwB,GAAG,eAAjC;EACA,IAAM5hB,mBAAiB,GAAG,QAA1B;EAEA,IAAM6hB,iBAAiB,GAAG,qBAA1B;EACA,IAAMC,uBAAuB,GAAG,mBAAhC;EACA,IAAMC,kBAAkB,GAAG,WAA3B;EACA,IAAMC,kBAAkB,GAAG,WAA3B;EACA,IAAMC,mBAAmB,GAAG,kBAA5B;EACA,IAAMC,iBAAiB,GAAG,WAA1B;EACA,IAAMC,uBAAuB,GAAG,gBAAhC;EACA,IAAMC,wBAAwB,GAAG,kBAAjC;EAEA,IAAMC,aAAa,GAAG,QAAtB;EACA,IAAMC,eAAe,GAAG,UAAxB;EAEA;EACA;EACA;EACA;EACA;;MAEMC;EACJ,qBAAYvoB,OAAZ,EAAqBwB,MAArB,EAA6B;EAAA;;EAC3B,SAAK2C,QAAL,GAAgBnE,OAAhB;EACA,SAAKwoB,cAAL,GAAsBxoB,OAAO,CAAC+H,OAAR,KAAoB,MAApB,GAA6BC,MAA7B,GAAsChI,OAA5D;EACA,SAAK6L,OAAL,GAAe,KAAKC,UAAL,CAAgBtK,MAAhB,CAAf;EACA,SAAKsQ,SAAL,GAAoB,KAAKjG,OAAL,CAAatN,MAAhB,SAA0BwpB,kBAA1B,UACQ,KAAKlc,OAAL,CAAatN,MADrB,SAC+B0pB,mBAD/B,WAEQ,KAAKpc,OAAL,CAAatN,MAFrB,SAE+B4pB,uBAF/B,CAAjB;EAGA,SAAKM,QAAL,GAAgB,EAAhB;EACA,SAAKC,QAAL,GAAgB,EAAhB;EACA,SAAKC,aAAL,GAAqB,IAArB;EACA,SAAKC,aAAL,GAAqB,CAArB;EAEAtqB,IAAAA,qBAAC,CAAC,KAAKkqB,cAAN,CAAD,CAAuB3iB,EAAvB,CAA0B8hB,YAA1B,EAAwC,UAAAtpB,KAAK;EAAA,aAAI,KAAI,CAACwqB,QAAL,CAAcxqB,KAAd,CAAJ;EAAA,KAA7C;EAEA,SAAKyqB,OAAL;;EACA,SAAKD,QAAL;EACD;;;;;EAYD;WAEAC,UAAA,mBAAU;EAAA;;EACR,QAAMC,UAAU,GAAG,KAAKP,cAAL,KAAwB,KAAKA,cAAL,CAAoBxgB,MAA5C,GACjBqgB,aADiB,GACDC,eADlB;EAGA,QAAMU,YAAY,GAAG,KAAKnd,OAAL,CAAa4b,MAAb,KAAwB,MAAxB,GACnBsB,UADmB,GACN,KAAKld,OAAL,CAAa4b,MAD5B;EAGA,QAAMwB,UAAU,GAAGD,YAAY,KAAKV,eAAjB,GACjB,KAAKY,aAAL,EADiB,GACM,CADzB;EAGA,SAAKT,QAAL,GAAgB,EAAhB;EACA,SAAKC,QAAL,GAAgB,EAAhB;EAEA,SAAKE,aAAL,GAAqB,KAAKO,gBAAL,EAArB;EAEA,QAAMC,OAAO,GAAG,GAAGlhB,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B,KAAK2J,SAA/B,CAAd,CAAhB;EAEAsX,IAAAA,OAAO,CACJC,GADH,CACO,UAAArpB,OAAO,EAAI;EACd,UAAIzB,MAAJ;EACA,UAAM+qB,cAAc,GAAGpqB,IAAI,CAACa,sBAAL,CAA4BC,OAA5B,CAAvB;;EAEA,UAAIspB,cAAJ,EAAoB;EAClB/qB,QAAAA,MAAM,GAAGsB,QAAQ,CAACQ,aAAT,CAAuBipB,cAAvB,CAAT;EACD;;EAED,UAAI/qB,MAAJ,EAAY;EACV,YAAMgrB,SAAS,GAAGhrB,MAAM,CAAC0U,qBAAP,EAAlB;;EACA,YAAIsW,SAAS,CAAC9L,KAAV,IAAmB8L,SAAS,CAACC,MAAjC,EAAyC;EACvC;EACA,iBAAO,CACLlrB,qBAAC,CAACC,MAAD,CAAD,CAAUyqB,YAAV,IAA0BS,GAA1B,GAAgCR,UAD3B,EAELK,cAFK,CAAP;EAID;EACF;;EAED,aAAO,IAAP;EACD,KArBH,EAsBG1X,MAtBH,CAsBU,UAAAwG,IAAI;EAAA,aAAIA,IAAJ;EAAA,KAtBd,EAuBGsR,IAvBH,CAuBQ,UAAC3L,CAAD,EAAIE,CAAJ;EAAA,aAAUF,CAAC,CAAC,CAAD,CAAD,GAAOE,CAAC,CAAC,CAAD,CAAlB;EAAA,KAvBR,EAwBG1D,OAxBH,CAwBW,UAAAnC,IAAI,EAAI;EACf,MAAA,MAAI,CAACqQ,QAAL,CAAc1W,IAAd,CAAmBqG,IAAI,CAAC,CAAD,CAAvB;;EACA,MAAA,MAAI,CAACsQ,QAAL,CAAc3W,IAAd,CAAmBqG,IAAI,CAAC,CAAD,CAAvB;EACD,KA3BH;EA4BD;;WAEDzT,UAAA,mBAAU;EACRrG,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EACAjF,IAAAA,qBAAC,CAAC,KAAKkqB,cAAN,CAAD,CAAuBjb,GAAvB,CAA2B/J,WAA3B;EAEA,SAAKW,QAAL,GAAgB,IAAhB;EACA,SAAKqkB,cAAL,GAAsB,IAAtB;EACA,SAAK3c,OAAL,GAAe,IAAf;EACA,SAAKiG,SAAL,GAAiB,IAAjB;EACA,SAAK2W,QAAL,GAAgB,IAAhB;EACA,SAAKC,QAAL,GAAgB,IAAhB;EACA,SAAKC,aAAL,GAAqB,IAArB;EACA,SAAKC,aAAL,GAAqB,IAArB;EACD;;;WAID9c,aAAA,oBAAWtK,MAAX,EAAmB;EACjBA,IAAAA,MAAM,gBACDoH,SADC,EAEA,OAAOpH,MAAP,KAAkB,QAAlB,IAA8BA,MAA9B,GAAuCA,MAAvC,GAAgD,EAFhD,CAAN;;EAKA,QAAI,OAAOA,MAAM,CAACjD,MAAd,KAAyB,QAAzB,IAAqCW,IAAI,CAACkC,SAAL,CAAeI,MAAM,CAACjD,MAAtB,CAAzC,EAAwE;EACtE,UAAIiT,EAAE,GAAGlT,qBAAC,CAACkD,MAAM,CAACjD,MAAR,CAAD,CAAiBqU,IAAjB,CAAsB,IAAtB,CAAT;;EACA,UAAI,CAACpB,EAAL,EAAS;EACPA,QAAAA,EAAE,GAAGtS,IAAI,CAACO,MAAL,CAAY4D,MAAZ,CAAL;EACA/E,QAAAA,qBAAC,CAACkD,MAAM,CAACjD,MAAR,CAAD,CAAiBqU,IAAjB,CAAsB,IAAtB,EAA4BpB,EAA5B;EACD;;EAEDhQ,MAAAA,MAAM,CAACjD,MAAP,SAAoBiT,EAApB;EACD;;EAEDtS,IAAAA,IAAI,CAACoC,eAAL,CAAqB+B,MAArB,EAA2B7B,MAA3B,EAAmC2H,aAAnC;EAEA,WAAO3H,MAAP;EACD;;WAED0nB,gBAAA,yBAAgB;EACd,WAAO,KAAKV,cAAL,KAAwBxgB,MAAxB,GACL,KAAKwgB,cAAL,CAAoBmB,WADf,GAC6B,KAAKnB,cAAL,CAAoBlN,SADxD;EAED;;WAED6N,mBAAA,4BAAmB;EACjB,WAAO,KAAKX,cAAL,CAAoB3N,YAApB,IAAoClb,IAAI,CAACiqB,GAAL,CACzC/pB,QAAQ,CAAC+W,IAAT,CAAciE,YAD2B,EAEzChb,QAAQ,CAACyC,eAAT,CAAyBuY,YAFgB,CAA3C;EAID;;WAEDgP,mBAAA,4BAAmB;EACjB,WAAO,KAAKrB,cAAL,KAAwBxgB,MAAxB,GACLA,MAAM,CAAC8hB,WADF,GACgB,KAAKtB,cAAL,CAAoBvV,qBAApB,GAA4CuW,MADnE;EAED;;WAEDX,WAAA,oBAAW;EACT,QAAMvN,SAAS,GAAG,KAAK4N,aAAL,KAAuB,KAAKrd,OAAL,CAAa0J,MAAtD;;EACA,QAAMsF,YAAY,GAAG,KAAKsO,gBAAL,EAArB;;EACA,QAAMY,SAAS,GAAG,KAAKle,OAAL,CAAa0J,MAAb,GAAsBsF,YAAtB,GAAqC,KAAKgP,gBAAL,EAAvD;;EAEA,QAAI,KAAKjB,aAAL,KAAuB/N,YAA3B,EAAyC;EACvC,WAAKiO,OAAL;EACD;;EAED,QAAIxN,SAAS,IAAIyO,SAAjB,EAA4B;EAC1B,UAAMxrB,MAAM,GAAG,KAAKmqB,QAAL,CAAc,KAAKA,QAAL,CAAcpgB,MAAd,GAAuB,CAArC,CAAf;;EAEA,UAAI,KAAKqgB,aAAL,KAAuBpqB,MAA3B,EAAmC;EACjC,aAAKyrB,SAAL,CAAezrB,MAAf;EACD;;EAED;EACD;;EAED,QAAI,KAAKoqB,aAAL,IAAsBrN,SAAS,GAAG,KAAKmN,QAAL,CAAc,CAAd,CAAlC,IAAsD,KAAKA,QAAL,CAAc,CAAd,IAAmB,CAA7E,EAAgF;EAC9E,WAAKE,aAAL,GAAqB,IAArB;;EACA,WAAKsB,MAAL;;EACA;EACD;;EAED,SAAK,IAAI7hB,CAAC,GAAG,KAAKqgB,QAAL,CAAcngB,MAA3B,EAAmCF,CAAC,EAApC,GAAyC;EACvC,UAAM8hB,cAAc,GAAG,KAAKvB,aAAL,KAAuB,KAAKD,QAAL,CAActgB,CAAd,CAAvB,IACnBkT,SAAS,IAAI,KAAKmN,QAAL,CAAcrgB,CAAd,CADM,KAElB,OAAO,KAAKqgB,QAAL,CAAcrgB,CAAC,GAAG,CAAlB,CAAP,KAAgC,WAAhC,IACGkT,SAAS,GAAG,KAAKmN,QAAL,CAAcrgB,CAAC,GAAG,CAAlB,CAHG,CAAvB;;EAKA,UAAI8hB,cAAJ,EAAoB;EAClB,aAAKF,SAAL,CAAe,KAAKtB,QAAL,CAActgB,CAAd,CAAf;EACD;EACF;EACF;;WAED4hB,YAAA,mBAAUzrB,MAAV,EAAkB;EAChB,SAAKoqB,aAAL,GAAqBpqB,MAArB;;EAEA,SAAK0rB,MAAL;;EAEA,QAAME,OAAO,GAAG,KAAKrY,SAAL,CACbhR,KADa,CACP,GADO,EAEbuoB,GAFa,CAET,UAAAppB,QAAQ;EAAA,aAAOA,QAAP,uBAAgC1B,MAAhC,YAA4C0B,QAA5C,gBAA8D1B,MAA9D;EAAA,KAFC,CAAhB;;EAIA,QAAM6rB,KAAK,GAAG9rB,qBAAC,CAAC,GAAG4J,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0BgiB,OAAO,CAACnD,IAAR,CAAa,GAAb,CAA1B,CAAd,CAAD,CAAf;;EAEA,QAAIoD,KAAK,CAACllB,QAAN,CAAe0iB,wBAAf,CAAJ,EAA8C;EAC5CwC,MAAAA,KAAK,CAACtlB,OAAN,CAAcojB,iBAAd,EACG7B,IADH,CACQ+B,wBADR,EAEG1Y,QAFH,CAEY1J,mBAFZ;EAGAokB,MAAAA,KAAK,CAAC1a,QAAN,CAAe1J,mBAAf;EACD,KALD,MAKO;EACL;EACAokB,MAAAA,KAAK,CAAC1a,QAAN,CAAe1J,mBAAf,EAFK;EAIL;;EACAokB,MAAAA,KAAK,CAACC,OAAN,CAAcvC,uBAAd,EACGnb,IADH,CACWob,kBADX,UACkCE,mBADlC,EAEGvY,QAFH,CAEY1J,mBAFZ,EALK;;EASLokB,MAAAA,KAAK,CAACC,OAAN,CAAcvC,uBAAd,EACGnb,IADH,CACQqb,kBADR,EAEGvY,QAFH,CAEYsY,kBAFZ,EAGGrY,QAHH,CAGY1J,mBAHZ;EAID;;EAED1H,IAAAA,qBAAC,CAAC,KAAKkqB,cAAN,CAAD,CAAuBvnB,OAAvB,CAA+BymB,cAA/B,EAA+C;EAC7C1Y,MAAAA,aAAa,EAAEzQ;EAD8B,KAA/C;EAGD;;WAED0rB,SAAA,kBAAS;EACP,OAAG/hB,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B,KAAK2J,SAA/B,CAAd,EACGF,MADH,CACU,UAAA0Y,IAAI;EAAA,aAAIA,IAAI,CAACljB,SAAL,CAAeC,QAAf,CAAwBrB,mBAAxB,CAAJ;EAAA,KADd,EAEGuU,OAFH,CAEW,UAAA+P,IAAI;EAAA,aAAIA,IAAI,CAACljB,SAAL,CAAe/B,MAAf,CAAsBW,mBAAtB,CAAJ;EAAA,KAFf;EAGD;;;cAIMV,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAIE,IAAI,GAAGnH,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,CAAX;;EACA,UAAMsI,OAAO,GAAG,OAAOrK,MAAP,KAAkB,QAAlB,IAA8BA,MAA9C;;EAEA,UAAI,CAACiE,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAI8iB,SAAJ,CAAc,IAAd,EAAoB1c,OAApB,CAAP;EACAvN,QAAAA,qBAAC,CAAC,IAAD,CAAD,CAAQmH,IAAR,CAAalC,UAAb,EAAuBkC,IAAvB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ;EACD;EACF,KAhBM,CAAP;EAiBD;;;;0BAlNoB;EACnB,aAAO8B,SAAP;EACD;;;0BAEoB;EACnB,aAAOsF,SAAP;EACD;;;;;EA+MH;EACA;EACA;EACA;EACA;;;AAEAtK,uBAAC,CAAC0J,MAAD,CAAD,CAAUnC,EAAV,CAAac,qBAAb,EAAkC,YAAM;EACtC,MAAM4jB,UAAU,GAAG,GAAGriB,KAAH,CAASpK,IAAT,CAAc+B,QAAQ,CAACsI,gBAAT,CAA0B0f,iBAA1B,CAAd,CAAnB;EACA,MAAM2C,gBAAgB,GAAGD,UAAU,CAACjiB,MAApC;;EAEA,OAAK,IAAIF,CAAC,GAAGoiB,gBAAb,EAA+BpiB,CAAC,EAAhC,GAAqC;EACnC,QAAMqiB,IAAI,GAAGnsB,qBAAC,CAACisB,UAAU,CAACniB,CAAD,CAAX,CAAd;;EACAmgB,IAAAA,SAAS,CAACjjB,gBAAV,CAA2BxH,IAA3B,CAAgC2sB,IAAhC,EAAsCA,IAAI,CAAChlB,IAAL,EAAtC;EACD;EACF,CARD;EAUA;EACA;EACA;EACA;EACA;;AAEAnH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaklB,SAAS,CAACjjB,gBAAvB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyByiB,SAAzB;;AACAjqB,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAO6kB,SAAS,CAACjjB,gBAAjB;EACD,CAHD;;ECpTA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,KAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,QAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAME,cAAY,GAAG,WAArB;EACA,IAAMC,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EAEA,IAAMwN,YAAU,YAAUrN,WAA1B;EACA,IAAMsN,cAAY,cAAYtN,WAA9B;EACA,IAAMmN,YAAU,YAAUnN,WAA1B;EACA,IAAMoN,aAAW,aAAWpN,WAA5B;EACA,IAAMM,sBAAoB,aAAWN,WAAX,GAAuBC,cAAjD;EAEA,IAAMinB,wBAAwB,GAAG,eAAjC;EACA,IAAM1kB,mBAAiB,GAAG,QAA1B;EACA,IAAMuO,qBAAmB,GAAG,UAA5B;EACA,IAAMvQ,iBAAe,GAAG,MAAxB;EACA,IAAMC,iBAAe,GAAG,MAAxB;EAEA,IAAMikB,mBAAiB,GAAG,WAA1B;EACA,IAAMJ,yBAAuB,GAAG,mBAAhC;EACA,IAAMthB,iBAAe,GAAG,SAAxB;EACA,IAAMmkB,kBAAkB,GAAG,gBAA3B;EACA,IAAMtkB,sBAAoB,GAAG,iEAA7B;EACA,IAAM+hB,0BAAwB,GAAG,kBAAjC;EACA,IAAMwC,8BAA8B,GAAG,0BAAvC;EAEA;EACA;EACA;EACA;EACA;;MAEMC;EACJ,eAAY7qB,OAAZ,EAAqB;EACnB,SAAKmE,QAAL,GAAgBnE,OAAhB;EACD;;;;;EAQD;WAEAoS,OAAA,gBAAO;EAAA;;EACL,QAAI,KAAKjO,QAAL,CAAcxB,UAAd,IACA,KAAKwB,QAAL,CAAcxB,UAAd,CAAyBtB,QAAzB,KAAsC6Z,IAAI,CAACC,YAD3C,IAEA7c,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0Bc,mBAA1B,CAFA,IAGA1H,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBe,QAAjB,CAA0BqP,qBAA1B,CAHJ,EAGoD;EAClD;EACD;;EAED,QAAIhW,MAAJ;EACA,QAAIusB,QAAJ;EACA,QAAMC,WAAW,GAAGzsB,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBW,OAAjB,CAAyBgjB,yBAAzB,EAAkD,CAAlD,CAApB;EACA,QAAM7nB,QAAQ,GAAGf,IAAI,CAACa,sBAAL,CAA4B,KAAKoE,QAAjC,CAAjB;;EAEA,QAAI4mB,WAAJ,EAAiB;EACf,UAAMC,YAAY,GAAGD,WAAW,CAAC/K,QAAZ,KAAyB,IAAzB,IAAiC+K,WAAW,CAAC/K,QAAZ,KAAyB,IAA1D,GAAiE2K,kBAAjE,GAAsFnkB,iBAA3G;EACAskB,MAAAA,QAAQ,GAAGxsB,qBAAC,CAAC2sB,SAAF,CAAY3sB,qBAAC,CAACysB,WAAD,CAAD,CAAe1E,IAAf,CAAoB2E,YAApB,CAAZ,CAAX;EACAF,MAAAA,QAAQ,GAAGA,QAAQ,CAACA,QAAQ,CAACxiB,MAAT,GAAkB,CAAnB,CAAnB;EACD;;EAED,QAAMwO,SAAS,GAAGxY,qBAAC,CAAC0G,KAAF,CAAQ6L,YAAR,EAAoB;EACpC7B,MAAAA,aAAa,EAAE,KAAK7K;EADgB,KAApB,CAAlB;EAIA,QAAMoS,SAAS,GAAGjY,qBAAC,CAAC0G,KAAF,CAAQ2L,YAAR,EAAoB;EACpC3B,MAAAA,aAAa,EAAE8b;EADqB,KAApB,CAAlB;;EAIA,QAAIA,QAAJ,EAAc;EACZxsB,MAAAA,qBAAC,CAACwsB,QAAD,CAAD,CAAY7pB,OAAZ,CAAoB6V,SAApB;EACD;;EAEDxY,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBsV,SAAzB;;EAEA,QAAIA,SAAS,CAAC9R,kBAAV,MACAqS,SAAS,CAACrS,kBAAV,EADJ,EACoC;EAClC;EACD;;EAED,QAAIxE,QAAJ,EAAc;EACZ1B,MAAAA,MAAM,GAAGsB,QAAQ,CAACQ,aAAT,CAAuBJ,QAAvB,CAAT;EACD;;EAED,SAAK+pB,SAAL,CACE,KAAK7lB,QADP,EAEE4mB,WAFF;;EAKA,QAAMjY,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,UAAMoY,WAAW,GAAG5sB,qBAAC,CAAC0G,KAAF,CAAQ8L,cAAR,EAAsB;EACxC9B,QAAAA,aAAa,EAAE,KAAI,CAAC7K;EADoB,OAAtB,CAApB;EAIA,UAAMqX,UAAU,GAAGld,qBAAC,CAAC0G,KAAF,CAAQ4L,aAAR,EAAqB;EACtC5B,QAAAA,aAAa,EAAE8b;EADuB,OAArB,CAAnB;EAIAxsB,MAAAA,qBAAC,CAACwsB,QAAD,CAAD,CAAY7pB,OAAZ,CAAoBiqB,WAApB;EACA5sB,MAAAA,qBAAC,CAAC,KAAI,CAAC6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBua,UAAzB;EACD,KAXD;;EAaA,QAAIjd,MAAJ,EAAY;EACV,WAAKyrB,SAAL,CAAezrB,MAAf,EAAuBA,MAAM,CAACoE,UAA9B,EAA0CmQ,QAA1C;EACD,KAFD,MAEO;EACLA,MAAAA,QAAQ;EACT;EACF;;WAEDnO,UAAA,mBAAU;EACRrG,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EACA,SAAKY,QAAL,GAAgB,IAAhB;EACD;;;WAID6lB,YAAA,mBAAUhqB,OAAV,EAAmB6hB,SAAnB,EAA8B/F,QAA9B,EAAwC;EAAA;;EACtC,QAAMqP,cAAc,GAAGtJ,SAAS,KAAKA,SAAS,CAAC7B,QAAV,KAAuB,IAAvB,IAA+B6B,SAAS,CAAC7B,QAAV,KAAuB,IAA3D,CAAT,GACrB1hB,qBAAC,CAACujB,SAAD,CAAD,CAAawE,IAAb,CAAkBsE,kBAAlB,CADqB,GAErBrsB,qBAAC,CAACujB,SAAD,CAAD,CAAapS,QAAb,CAAsBjJ,iBAAtB,CAFF;EAIA,QAAM4kB,MAAM,GAAGD,cAAc,CAAC,CAAD,CAA7B;EACA,QAAM/X,eAAe,GAAG0I,QAAQ,IAAKsP,MAAM,IAAI9sB,qBAAC,CAAC8sB,MAAD,CAAD,CAAUlmB,QAAV,CAAmBlB,iBAAnB,CAA/C;;EACA,QAAM8O,QAAQ,GAAG,SAAXA,QAAW;EAAA,aAAM,MAAI,CAACuY,mBAAL,CACrBrrB,OADqB,EAErBorB,MAFqB,EAGrBtP,QAHqB,CAAN;EAAA,KAAjB;;EAMA,QAAIsP,MAAM,IAAIhY,eAAd,EAA+B;EAC7B,UAAM5S,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC6qB,MAAtC,CAA3B;EAEA9sB,MAAAA,qBAAC,CAAC8sB,MAAD,CAAD,CACGnmB,WADH,CACehB,iBADf,EAEGhF,GAFH,CAEOC,IAAI,CAAC1B,cAFZ,EAE4BsV,QAF5B,EAGGvT,oBAHH,CAGwBiB,kBAHxB;EAID,KAPD,MAOO;EACLsS,MAAAA,QAAQ;EACT;EACF;;WAEDuY,sBAAA,6BAAoBrrB,OAApB,EAA6BorB,MAA7B,EAAqCtP,QAArC,EAA+C;EAC7C,QAAIsP,MAAJ,EAAY;EACV9sB,MAAAA,qBAAC,CAAC8sB,MAAD,CAAD,CAAUnmB,WAAV,CAAsBe,mBAAtB;EAEA,UAAMslB,aAAa,GAAGhtB,qBAAC,CAAC8sB,MAAM,CAACzoB,UAAR,CAAD,CAAqB0jB,IAArB,CACpBuE,8BADoB,EAEpB,CAFoB,CAAtB;;EAIA,UAAIU,aAAJ,EAAmB;EACjBhtB,QAAAA,qBAAC,CAACgtB,aAAD,CAAD,CAAiBrmB,WAAjB,CAA6Be,mBAA7B;EACD;;EAED,UAAIolB,MAAM,CAAClrB,YAAP,CAAoB,MAApB,MAAgC,KAApC,EAA2C;EACzCkrB,QAAAA,MAAM,CAAC3jB,YAAP,CAAoB,eAApB,EAAqC,KAArC;EACD;EACF;;EAEDnJ,IAAAA,qBAAC,CAAC0B,OAAD,CAAD,CAAW0P,QAAX,CAAoB1J,mBAApB;;EACA,QAAIhG,OAAO,CAACE,YAAR,CAAqB,MAArB,MAAiC,KAArC,EAA4C;EAC1CF,MAAAA,OAAO,CAACyH,YAAR,CAAqB,eAArB,EAAsC,IAAtC;EACD;;EAEDvI,IAAAA,IAAI,CAAC6B,MAAL,CAAYf,OAAZ;;EAEA,QAAIA,OAAO,CAACoH,SAAR,CAAkBC,QAAlB,CAA2BrD,iBAA3B,CAAJ,EAAiD;EAC/ChE,MAAAA,OAAO,CAACoH,SAAR,CAAkBmB,GAAlB,CAAsBtE,iBAAtB;EACD;;EAED,QAAIjE,OAAO,CAAC2C,UAAR,IAAsBrE,qBAAC,CAAC0B,OAAO,CAAC2C,UAAT,CAAD,CAAsBuC,QAAtB,CAA+BwlB,wBAA/B,CAA1B,EAAoF;EAClF,UAAMa,eAAe,GAAGjtB,qBAAC,CAAC0B,OAAD,CAAD,CAAW8E,OAAX,CAAmBojB,mBAAnB,EAAsC,CAAtC,CAAxB;;EAEA,UAAIqD,eAAJ,EAAqB;EACnB,YAAMC,kBAAkB,GAAG,GAAGtjB,KAAH,CAASpK,IAAT,CAAcytB,eAAe,CAACpjB,gBAAhB,CAAiCigB,0BAAjC,CAAd,CAA3B;EAEA9pB,QAAAA,qBAAC,CAACktB,kBAAD,CAAD,CAAsB9b,QAAtB,CAA+B1J,mBAA/B;EACD;;EAEDhG,MAAAA,OAAO,CAACyH,YAAR,CAAqB,eAArB,EAAsC,IAAtC;EACD;;EAED,QAAIqU,QAAJ,EAAc;EACZA,MAAAA,QAAQ;EACT;EACF;;;QAIMxW,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAMkmB,KAAK,GAAGntB,qBAAC,CAAC,IAAD,CAAf;EACA,UAAImH,IAAI,GAAGgmB,KAAK,CAAChmB,IAAN,CAAWlC,UAAX,CAAX;;EAEA,UAAI,CAACkC,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAIolB,GAAJ,CAAQ,IAAR,CAAP;EACAY,QAAAA,KAAK,CAAChmB,IAAN,CAAWlC,UAAX,EAAqBkC,IAArB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ;EACD;EACF,KAhBM,CAAP;EAiBD;;;;0BA1KoB;EACnB,aAAO8B,SAAP;EACD;;;;;EA2KH;EACA;EACA;EACA;EACA;;;AAEAhF,uBAAC,CAACuB,QAAD,CAAD,CACGgG,EADH,CACM/B,sBADN,EAC4BuC,sBAD5B,EACkD,UAAUhI,KAAV,EAAiB;EAC/DA,EAAAA,KAAK,CAACuH,cAAN;;EACAilB,EAAAA,GAAG,CAACvlB,gBAAJ,CAAqBxH,IAArB,CAA0BQ,qBAAC,CAAC,IAAD,CAA3B,EAAmC,MAAnC;EACD,CAJH;EAMA;EACA;EACA;EACA;EACA;;AAEAA,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAawnB,GAAG,CAACvlB,gBAAjB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyB+kB,GAAzB;;AACAvsB,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAOmnB,GAAG,CAACvlB,gBAAX;EACD,CAHD;;EC/OA;EACA;EACA;EACA;EACA;;EAEA,IAAMjC,MAAI,GAAG,OAAb;EACA,IAAMC,SAAO,GAAG,OAAhB;EACA,IAAMC,UAAQ,GAAG,UAAjB;EACA,IAAMC,WAAS,SAAOD,UAAtB;EACA,IAAMG,oBAAkB,GAAGpF,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,CAA3B;EAEA,IAAMoV,qBAAmB,qBAAmBjV,WAA5C;EACA,IAAMqN,YAAU,YAAUrN,WAA1B;EACA,IAAMsN,cAAY,cAAYtN,WAA9B;EACA,IAAMmN,YAAU,YAAUnN,WAA1B;EACA,IAAMoN,aAAW,aAAWpN,WAA5B;EAEA,IAAMQ,iBAAe,GAAG,MAAxB;EACA,IAAM0nB,eAAe,GAAG,MAAxB;EACA,IAAMznB,iBAAe,GAAG,MAAxB;EACA,IAAM0nB,kBAAkB,GAAG,SAA3B;EAEA,IAAMxiB,aAAW,GAAG;EAClBqY,EAAAA,SAAS,EAAE,SADO;EAElBoK,EAAAA,QAAQ,EAAE,SAFQ;EAGlBjK,EAAAA,KAAK,EAAE;EAHW,CAApB;EAMA,IAAM/Y,SAAO,GAAG;EACd4Y,EAAAA,SAAS,EAAE,IADG;EAEdoK,EAAAA,QAAQ,EAAE,IAFI;EAGdjK,EAAAA,KAAK,EAAE;EAHO,CAAhB;EAMA,IAAMvI,uBAAqB,GAAG,wBAA9B;EAEA;EACA;EACA;EACA;EACA;;MAEMyS;EACJ,iBAAY7rB,OAAZ,EAAqBwB,MAArB,EAA6B;EAC3B,SAAK2C,QAAL,GAAgBnE,OAAhB;EACA,SAAK6L,OAAL,GAAe,KAAKC,UAAL,CAAgBtK,MAAhB,CAAf;EACA,SAAKmiB,QAAL,GAAgB,IAAhB;;EACA,SAAKI,aAAL;EACD;;;;;EAgBD;WAEA3R,OAAA,gBAAO;EAAA;;EACL,QAAMmE,SAAS,GAAGjY,qBAAC,CAAC0G,KAAF,CAAQ2L,YAAR,CAAlB;EAEArS,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyBsV,SAAzB;;EACA,QAAIA,SAAS,CAAC9R,kBAAV,EAAJ,EAAoC;EAClC;EACD;;EAED,SAAKqnB,aAAL;;EAEA,QAAI,KAAKjgB,OAAL,CAAa2V,SAAjB,EAA4B;EAC1B,WAAKrd,QAAL,CAAciD,SAAd,CAAwBmB,GAAxB,CAA4BvE,iBAA5B;EACD;;EAED,QAAM8O,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,MAAA,KAAI,CAAC3O,QAAL,CAAciD,SAAd,CAAwB/B,MAAxB,CAA+BsmB,kBAA/B;;EACA,MAAA,KAAI,CAACxnB,QAAL,CAAciD,SAAd,CAAwBmB,GAAxB,CAA4BtE,iBAA5B;;EAEA3F,MAAAA,qBAAC,CAAC,KAAI,CAAC6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyB2P,aAAzB;;EAEA,UAAI,KAAI,CAAC/E,OAAL,CAAa+f,QAAjB,EAA2B;EACzB,QAAA,KAAI,CAACjI,QAAL,GAAgBxkB,UAAU,CAAC,YAAM;EAC/B,UAAA,KAAI,CAACgT,IAAL;EACD,SAFyB,EAEvB,KAAI,CAACtG,OAAL,CAAa8V,KAFU,CAA1B;EAGD;EACF,KAXD;;EAaA,SAAKxd,QAAL,CAAciD,SAAd,CAAwB/B,MAAxB,CAA+BqmB,eAA/B;;EACAxsB,IAAAA,IAAI,CAAC6B,MAAL,CAAY,KAAKoD,QAAjB;;EACA,SAAKA,QAAL,CAAciD,SAAd,CAAwBmB,GAAxB,CAA4BojB,kBAA5B;;EACA,QAAI,KAAK9f,OAAL,CAAa2V,SAAjB,EAA4B;EAC1B,UAAMhhB,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC,KAAK4D,QAA3C,CAA3B;EAEA7F,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACGlF,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4BsV,QAD5B,EAEGvT,oBAFH,CAEwBiB,kBAFxB;EAGD,KAND,MAMO;EACLsS,MAAAA,QAAQ;EACT;EACF;;WAEDX,OAAA,gBAAO;EACL,QAAI,CAAC,KAAKhO,QAAL,CAAciD,SAAd,CAAwBC,QAAxB,CAAiCpD,iBAAjC,CAAL,EAAwD;EACtD;EACD;;EAED,QAAM6S,SAAS,GAAGxY,qBAAC,CAAC0G,KAAF,CAAQ6L,YAAR,CAAlB;EAEAvS,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyB6V,SAAzB;;EACA,QAAIA,SAAS,CAACrS,kBAAV,EAAJ,EAAoC;EAClC;EACD;;EAED,SAAKsnB,MAAL;EACD;;WAEDpnB,UAAA,mBAAU;EACR,SAAKmnB,aAAL;;EAEA,QAAI,KAAK3nB,QAAL,CAAciD,SAAd,CAAwBC,QAAxB,CAAiCpD,iBAAjC,CAAJ,EAAuD;EACrD,WAAKE,QAAL,CAAciD,SAAd,CAAwB/B,MAAxB,CAA+BpB,iBAA/B;EACD;;EAED3F,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBoJ,GAAjB,CAAqBkL,qBAArB;EAEAna,IAAAA,qBAAC,CAACsG,UAAF,CAAa,KAAKT,QAAlB,EAA4BZ,UAA5B;EACA,SAAKY,QAAL,GAAgB,IAAhB;EACA,SAAK0H,OAAL,GAAe,IAAf;EACD;;;WAIDC,aAAA,oBAAWtK,MAAX,EAAmB;EACjBA,IAAAA,MAAM,gBACDoH,SADC,EAEDtK,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiBsB,IAAjB,EAFC,EAGA,OAAOjE,MAAP,KAAkB,QAAlB,IAA8BA,MAA9B,GAAuCA,MAAvC,GAAgD,EAHhD,CAAN;EAMAtC,IAAAA,IAAI,CAACoC,eAAL,CACE+B,MADF,EAEE7B,MAFF,EAGE,KAAK2V,WAAL,CAAiBhO,WAHnB;EAMA,WAAO3H,MAAP;EACD;;WAEDuiB,gBAAA,yBAAgB;EAAA;;EACdzlB,IAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CAAiB0B,EAAjB,CAAoB4S,qBAApB,EAAyCW,uBAAzC,EAAgE;EAAA,aAAM,MAAI,CAACjH,IAAL,EAAN;EAAA,KAAhE;EACD;;WAED4Z,SAAA,kBAAS;EAAA;;EACP,QAAMjZ,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,MAAA,MAAI,CAAC3O,QAAL,CAAciD,SAAd,CAAwBmB,GAAxB,CAA4BmjB,eAA5B;;EACAptB,MAAAA,qBAAC,CAAC,MAAI,CAAC6F,QAAN,CAAD,CAAiBlD,OAAjB,CAAyB6P,cAAzB;EACD,KAHD;;EAKA,SAAK3M,QAAL,CAAciD,SAAd,CAAwB/B,MAAxB,CAA+BpB,iBAA/B;;EACA,QAAI,KAAK4H,OAAL,CAAa2V,SAAjB,EAA4B;EAC1B,UAAMhhB,kBAAkB,GAAGtB,IAAI,CAACqB,gCAAL,CAAsC,KAAK4D,QAA3C,CAA3B;EAEA7F,MAAAA,qBAAC,CAAC,KAAK6F,QAAN,CAAD,CACGlF,GADH,CACOC,IAAI,CAAC1B,cADZ,EAC4BsV,QAD5B,EAEGvT,oBAFH,CAEwBiB,kBAFxB;EAGD,KAND,MAMO;EACLsS,MAAAA,QAAQ;EACT;EACF;;WAEDgZ,gBAAA,yBAAgB;EACd1d,IAAAA,YAAY,CAAC,KAAKuV,QAAN,CAAZ;EACA,SAAKA,QAAL,GAAgB,IAAhB;EACD;;;UAIMre,mBAAP,0BAAwB9D,MAAxB,EAAgC;EAC9B,WAAO,KAAK+D,IAAL,CAAU,YAAY;EAC3B,UAAMC,QAAQ,GAAGlH,qBAAC,CAAC,IAAD,CAAlB;EACA,UAAImH,IAAI,GAAGD,QAAQ,CAACC,IAAT,CAAclC,UAAd,CAAX;;EACA,UAAMsI,OAAO,GAAG,OAAOrK,MAAP,KAAkB,QAAlB,IAA8BA,MAA9C;;EAEA,UAAI,CAACiE,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAIomB,KAAJ,CAAU,IAAV,EAAgBhgB,OAAhB,CAAP;EACArG,QAAAA,QAAQ,CAACC,IAAT,CAAclC,UAAd,EAAwBkC,IAAxB;EACD;;EAED,UAAI,OAAOjE,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOiE,IAAI,CAACjE,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIqB,SAAJ,wBAAkCrB,MAAlC,QAAN;EACD;;EAEDiE,QAAAA,IAAI,CAACjE,MAAD,CAAJ,CAAa,IAAb;EACD;EACF,KAjBM,CAAP;EAkBD;;;;0BAtJoB;EACnB,aAAO8B,SAAP;EACD;;;0BAEwB;EACvB,aAAO6F,aAAP;EACD;;;0BAEoB;EACnB,aAAOP,SAAP;EACD;;;;;EA+IH;EACA;EACA;EACA;EACA;;;AAEAtK,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAawoB,KAAK,CAACvmB,gBAAnB;AACAhH,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAWyC,WAAX,GAAyB+lB,KAAzB;;AACAvtB,uBAAC,CAACgB,EAAF,CAAK+D,MAAL,EAAW0C,UAAX,GAAwB,YAAM;EAC5BzH,EAAAA,qBAAC,CAACgB,EAAF,CAAK+D,MAAL,IAAaK,oBAAb;EACA,SAAOmoB,KAAK,CAACvmB,gBAAb;EACD,CAHD;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.min.js b/vendor/twbs/bootstrap/dist/js/bootstrap.min.js index cd995a6bd..44d24b32f 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.min.js +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.min.js @@ -1,7 +1,7 @@ /*! - * Bootstrap v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=i(e),a=i(n);function s(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function l(t,e,n){return e&&s(t.prototype,e),n&&s(t,n),t}function r(){return(r=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function u(t){var e=this,n=!1;return o.default(this).one(d.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||d.triggerTransitionEnd(e)}),t),this}var d={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=o.default(t).css("transition-duration"),n=o.default(t).css("transition-delay"),i=parseFloat(e),a=parseFloat(n);return i||a?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){o.default(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],a=e[i],s=a&&d.isElement(a)?"element":null===(l=a)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(s))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?d.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof o.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=o.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};d.jQueryDetection(),o.default.fn.emulateTransitionEnd=u,o.default.event.special[d.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(o.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var f="alert",c=o.default.fn[f],h=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.default.removeData(this._element,"bs.alert"),this._element=null},e._getRootElement=function(t){var e=d.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=o.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=o.default.Event("close.bs.alert");return o.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(o.default(t).removeClass("show"),o.default(t).hasClass("fade")){var n=d.getTransitionDurationFromElement(t);o.default(t).one(d.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){o.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.alert");i||(i=new t(this),n.data("bs.alert",i)),"close"===e&&i[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}}]),t}();o.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),o.default.fn[f]=h._jQueryInterface,o.default.fn[f].Constructor=h,o.default.fn[f].noConflict=function(){return o.default.fn[f]=c,h._jQueryInterface};var g=o.default.fn.button,m=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=o.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var i=this._element.querySelector('input:not([type="hidden"])');if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains("active"))t=!1;else{var a=n.querySelector(".active");a&&o.default(a).removeClass("active")}t&&("checkbox"!==i.type&&"radio"!==i.type||(i.checked=!this._element.classList.contains("active")),this.shouldAvoidTriggerChange||o.default(i).trigger("change")),i.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&o.default(this._element).toggleClass("active"))},e.dispose=function(){o.default.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this),a=i.data("bs.button");a||(a=new t(this),i.data("bs.button",a)),a.shouldAvoidTriggerChange=n,"toggle"===e&&a[e]()}))},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}}]),t}();o.default(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target,n=e;if(o.default(e).hasClass("btn")||(e=o.default(e).closest(".btn")[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var i=e.querySelector('input:not([type="hidden"])');if(i&&(i.hasAttribute("disabled")||i.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||m._jQueryInterface.call(o.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=o.default(t.target).closest(".btn")[0];o.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),o.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var a=0,s=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;a<s;a++){var l=t[a];"true"===l.getAttribute("aria-pressed")?l.classList.add("active"):l.classList.remove("active")}})),o.default.fn.button=m._jQueryInterface,o.default.fn.button.Constructor=m,o.default.fn.button.noConflict=function(){return o.default.fn.button=g,m._jQueryInterface};var p="carousel",_=".bs.carousel",v=o.default.fn[p],b={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},E={TOUCH:"touch",PEN:"pen"},w=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide("next")},e.nextWhenVisible=function(){var t=o.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide("prev")},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(d.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(".active.carousel-item");var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)o.default(this._element).one("slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},e.dispose=function(){o.default(this._element).off(_),o.default.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=r({},b,t),d.typeCheckConfig(p,t,y),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&o.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&o.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&E[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&E[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};o.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(o.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(o.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),o.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),a=this._items.length-1;if((i&&0===o||n&&o===a)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(this._element.querySelector(".active.carousel-item")),a=o.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n});return o.default(this._element).trigger(a),a},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));o.default(e).removeClass("active");var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&o.default(n).addClass("active")}},e._slide=function(t,e){var n,i,a,s=this,l=this._element.querySelector(".active.carousel-item"),r=this._getItemIndex(l),u=e||l&&this._getItemByDirection(t,l),f=this._getItemIndex(u),c=Boolean(this._interval);if("next"===t?(n="carousel-item-left",i="carousel-item-next",a="left"):(n="carousel-item-right",i="carousel-item-prev",a="right"),u&&o.default(u).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(u,a).isDefaultPrevented()&&l&&u){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(u);var h=o.default.Event("slid.bs.carousel",{relatedTarget:u,direction:a,from:r,to:f});if(o.default(this._element).hasClass("slide")){o.default(u).addClass(i),d.reflow(u),o.default(l).addClass(n),o.default(u).addClass(n);var g=parseInt(u.getAttribute("data-interval"),10);g?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=g):this._config.interval=this._config.defaultInterval||this._config.interval;var m=d.getTransitionDurationFromElement(l);o.default(l).one(d.TRANSITION_END,(function(){o.default(u).removeClass(n+" "+i).addClass("active"),o.default(l).removeClass("active "+i+" "+n),s._isSliding=!1,setTimeout((function(){return o.default(s._element).trigger(h)}),0)})).emulateTransitionEnd(m)}else o.default(l).removeClass("active"),o.default(u).addClass("active"),this._isSliding=!1,o.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.carousel"),i=r({},b,o.default(this).data());"object"==typeof e&&(i=r({},i,e));var a="string"==typeof e?e:i.slide;if(n||(n=new t(this,i),o.default(this).data("bs.carousel",n)),"number"==typeof e)n.to(e);else if("string"==typeof a){if("undefined"==typeof n[a])throw new TypeError('No method named "'+a+'"');n[a]()}else i.interval&&i.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=d.getSelectorFromElement(this);if(n){var i=o.default(n)[0];if(i&&o.default(i).hasClass("carousel")){var a=r({},o.default(i).data(),o.default(this).data()),s=this.getAttribute("data-slide-to");s&&(a.interval=!1),t._jQueryInterface.call(o.default(i),a),s&&o.default(i).data("bs.carousel").to(s),e.preventDefault()}}},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return b}}]),t}();o.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",w._dataApiClickHandler),o.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e<n;e++){var i=o.default(t[e]);w._jQueryInterface.call(i,i.data())}})),o.default.fn[p]=w._jQueryInterface,o.default.fn[p].Constructor=w,o.default.fn[p].noConflict=function(){return o.default.fn[p]=v,w._jQueryInterface};var T="collapse",C=o.default.fn[T],S={toggle:!0,parent:""},N={toggle:"boolean",parent:"(string|element)"},D=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var a=n[i],s=d.getSelectorFromElement(a),l=[].slice.call(document.querySelectorAll(s)).filter((function(e){return e===t}));null!==s&&l.length>0&&(this._selector=s,this._triggerArray.push(a))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){o.default(this._element).hasClass("show")?this.hide():this.show()},e.show=function(){var e,n,i=this;if(!this._isTransitioning&&!o.default(this._element).hasClass("show")&&(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof i._config.parent?t.getAttribute("data-parent")===i._config.parent:t.classList.contains("collapse")}))).length&&(e=null),!(e&&(n=o.default(e).not(this._selector).data("bs.collapse"))&&n._isTransitioning))){var a=o.default.Event("show.bs.collapse");if(o.default(this._element).trigger(a),!a.isDefaultPrevented()){e&&(t._jQueryInterface.call(o.default(e).not(this._selector),"hide"),n||o.default(e).data("bs.collapse",null));var s=this._getDimension();o.default(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[s]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(s[0].toUpperCase()+s.slice(1)),r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){o.default(i._element).removeClass("collapsing").addClass("collapse show"),i._element.style[s]="",i.setTransitioning(!1),o.default(i._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(r),this._element.style[s]=this._element[l]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&o.default(this._element).hasClass("show")){var e=o.default.Event("hide.bs.collapse");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",d.reflow(this._element),o.default(this._element).addClass("collapsing").removeClass("collapse show");var i=this._triggerArray.length;if(i>0)for(var a=0;a<i;a++){var s=this._triggerArray[a],l=d.getSelectorFromElement(s);if(null!==l)o.default([].slice.call(document.querySelectorAll(l))).hasClass("show")||o.default(s).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[n]="";var r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){t.setTransitioning(!1),o.default(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(r)}}},e.setTransitioning=function(t){this._isTransitioning=t},e.dispose=function(){o.default.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},e._getConfig=function(t){return(t=r({},S,t)).toggle=Boolean(t.toggle),d.typeCheckConfig(T,t,N),t},e._getDimension=function(){return o.default(this._element).hasClass("width")?"width":"height"},e._getParent=function(){var e,n=this;d.isElement(this._config.parent)?(e=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(e=this._config.parent[0])):e=document.querySelector(this._config.parent);var i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',a=[].slice.call(e.querySelectorAll(i));return o.default(a).each((function(e,i){n._addAriaAndCollapsedClass(t._getTargetFromElement(i),[i])})),e},e._addAriaAndCollapsedClass=function(t,e){var n=o.default(t).hasClass("show");e.length&&o.default(e).toggleClass("collapsed",!n).attr("aria-expanded",n)},t._getTargetFromElement=function(t){var e=d.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.collapse"),a=r({},S,n.data(),"object"==typeof e&&e?e:{});if(!i&&a.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(a.toggle=!1),i||(i=new t(this,a),n.data("bs.collapse",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return S}}]),t}();o.default(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var e=o.default(this),n=d.getSelectorFromElement(this),i=[].slice.call(document.querySelectorAll(n));o.default(i).each((function(){var t=o.default(this),n=t.data("bs.collapse")?"toggle":e.data();D._jQueryInterface.call(t,n)}))})),o.default.fn[T]=D._jQueryInterface,o.default.fn[T].Constructor=D,o.default.fn[T].noConflict=function(){return o.default.fn[T]=C,D._jQueryInterface};var k="dropdown",A=o.default.fn[k],I=new RegExp("38|40|27"),j={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},O={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},x=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!o.default(this._element).hasClass("disabled")){var e=o.default(this._menu).hasClass("show");t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||o.default(this._element).hasClass("disabled")||o.default(this._menu).hasClass("show"))){var n={relatedTarget:this._element},i=o.default.Event("show.bs.dropdown",n),s=t._getParentFromElement(this._element);if(o.default(s).trigger(i),!i.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var l=this._element;"parent"===this._config.reference?l=s:d.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&o.default(s).addClass("position-static"),this._popper=new a.default(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===o.default(s).closest(".navbar-nav").length&&o.default(document.body).children().on("mouseover",null,o.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),o.default(this._menu).toggleClass("show"),o.default(s).toggleClass("show").trigger(o.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!o.default(this._element).hasClass("disabled")&&o.default(this._menu).hasClass("show")){var e={relatedTarget:this._element},n=o.default.Event("hide.bs.dropdown",e),i=t._getParentFromElement(this._element);o.default(i).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),o.default(this._menu).toggleClass("show"),o.default(i).toggleClass("show").trigger(o.default.Event("hidden.bs.dropdown",e)))}},e.dispose=function(){o.default.removeData(this._element,"bs.dropdown"),o.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;o.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=r({},this.constructor.Default,o.default(this._element).data(),t),d.typeCheckConfig(k,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},e._getPlacement=function(){var t=o.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=o.default(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":o.default(this._menu).hasClass("dropdown-menu-right")&&(e="bottom-end"),e},e._detectNavbar=function(){return o.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),r({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.dropdown");if(n||(n=new t(this,"object"==typeof e?e:null),o.default(this).data("bs.dropdown",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),i=0,a=n.length;i<a;i++){var s=t._getParentFromElement(n[i]),l=o.default(n[i]).data("bs.dropdown"),r={relatedTarget:n[i]};if(e&&"click"===e.type&&(r.clickEvent=e),l){var u=l._menu;if(o.default(s).hasClass("show")&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&o.default.contains(s,e.target))){var d=o.default.Event("hide.bs.dropdown",r);o.default(s).trigger(d),d.isDefaultPrevented()||("ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),n[i].setAttribute("aria-expanded","false"),l._popper&&l._popper.destroy(),o.default(u).removeClass("show"),o.default(s).removeClass("show").trigger(o.default.Event("hidden.bs.dropdown",r)))}}}},t._getParentFromElement=function(t){var e,n=d.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||o.default(e.target).closest(".dropdown-menu").length):!I.test(e.which))&&!this.disabled&&!o.default(this).hasClass("disabled")){var n=t._getParentFromElement(this),i=o.default(n).hasClass("show");if(i||27!==e.which){if(e.preventDefault(),e.stopPropagation(),!i||27===e.which||32===e.which)return 27===e.which&&o.default(n.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void o.default(this).trigger("click");var a=[].slice.call(n.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return o.default(t).is(":visible")}));if(0!==a.length){var s=a.indexOf(e.target);38===e.which&&s>0&&s--,40===e.which&&s<a.length-1&&s++,s<0&&(s=0),a[s].focus()}}}},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return j}},{key:"DefaultType",get:function(){return O}}]),t}();o.default(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',x._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",x._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",x._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),x._jQueryInterface.call(o.default(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),o.default.fn[k]=x._jQueryInterface,o.default.fn[k].Constructor=x,o.default.fn[k].noConflict=function(){return o.default.fn[k]=A,x._jQueryInterface};var P=o.default.fn.modal,R={backdrop:!0,keyboard:!0,focus:!0,show:!0},L={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},q=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var e=t.prototype;return e.toggle=function(t){return this._isShown?this.hide():this.show(t)},e.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){o.default(this._element).hasClass("fade")&&(this._isTransitioning=!0);var n=o.default.Event("show.bs.modal",{relatedTarget:t});o.default(this._element).trigger(n),this._isShown||n.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),o.default(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return e.hide(t)})),o.default(this._dialog).on("mousedown.dismiss.bs.modal",(function(){o.default(e._element).one("mouseup.dismiss.bs.modal",(function(t){o.default(t.target).is(e._element)&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},e.hide=function(t){var e=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var n=o.default.Event("hide.bs.modal");if(o.default(this._element).trigger(n),this._isShown&&!n.isDefaultPrevented()){this._isShown=!1;var i=o.default(this._element).hasClass("fade");if(i&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),o.default(document).off("focusin.bs.modal"),o.default(this._element).removeClass("show"),o.default(this._element).off("click.dismiss.bs.modal"),o.default(this._dialog).off("mousedown.dismiss.bs.modal"),i){var a=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(t){return e._hideModal(t)})).emulateTransitionEnd(a)}else this._hideModal()}}},e.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return o.default(t).off(".bs.modal")})),o.default(document).off("focusin.bs.modal"),o.default.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},e.handleUpdate=function(){this._adjustDialog()},e._getConfig=function(t){return t=r({},R,t),d.typeCheckConfig("modal",t,L),t},e._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var e=o.default.Event("hidePrevented.bs.modal");if(o.default(this._element).trigger(e),e.isDefaultPrevented())return;var n=this._element.scrollHeight>document.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var i=d.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(d.TRANSITION_END),o.default(this._element).one(d.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),n||o.default(t._element).one(d.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,i)})).emulateTransitionEnd(i),this._element.focus()}else this.hide()},e._showElement=function(t){var e=this,n=o.default(this._element).hasClass("fade"),i=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass("modal-dialog-scrollable")&&i?i.scrollTop=0:this._element.scrollTop=0,n&&d.reflow(this._element),o.default(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var a=o.default.Event("shown.bs.modal",{relatedTarget:t}),s=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,o.default(e._element).trigger(a)};if(n){var l=d.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(d.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._enforceFocus=function(){var t=this;o.default(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(e){document!==e.target&&t._element!==e.target&&0===o.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?o.default(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||o.default(this._element).off("keydown.dismiss.bs.modal")},e._setResizeEvent=function(){var t=this;this._isShown?o.default(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):o.default(window).off("resize.bs.modal")},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){o.default(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),o.default(t._element).trigger("hidden.bs.modal")}))},e._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=o.default(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on("click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&e._triggerBackdropTransition()})),n&&d.reflow(this._backdrop),o.default(this._backdrop).addClass("show"),!t)return;if(!n)return void t();var i=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,t).emulateTransitionEnd(i)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass("show");var a=function(){e._removeBackdrop(),t&&t()};if(o.default(this._element).hasClass("fade")){var s=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},e._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var e=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),n=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(e,n){var i=n.style.paddingRight,a=o.default(n).css("padding-right");o.default(n).data("padding-right",i).css("padding-right",parseFloat(a)+t._scrollbarWidth+"px")})),o.default(n).each((function(e,n){var i=n.style.marginRight,a=o.default(n).css("margin-right");o.default(n).data("margin-right",i).css("margin-right",parseFloat(a)-t._scrollbarWidth+"px")}));var i=document.body.style.paddingRight,a=o.default(document.body).css("padding-right");o.default(document.body).data("padding-right",i).css("padding-right",parseFloat(a)+this._scrollbarWidth+"px")}o.default(document.body).addClass("modal-open")},e._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));o.default(t).each((function(t,e){var n=o.default(e).data("padding-right");o.default(e).removeData("padding-right"),e.style.paddingRight=n||""}));var e=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(t,e){var n=o.default(e).data("margin-right");"undefined"!=typeof n&&o.default(e).css("margin-right",n).removeData("margin-right")}));var n=o.default(document.body).data("padding-right");o.default(document.body).removeData("padding-right"),document.body.style.paddingRight=n||""},e._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this).data("bs.modal"),a=r({},R,o.default(this).data(),"object"==typeof e&&e?e:{});if(i||(i=new t(this,a),o.default(this).data("bs.modal",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](n)}else a.show&&i.show(n)}))},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return R}}]),t}();o.default(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e,n=this,i=d.getSelectorFromElement(this);i&&(e=document.querySelector(i));var a=o.default(e).data("bs.modal")?"toggle":r({},o.default(e).data(),o.default(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var s=o.default(e).one("show.bs.modal",(function(t){t.isDefaultPrevented()||s.one("hidden.bs.modal",(function(){o.default(n).is(":visible")&&n.focus()}))}));q._jQueryInterface.call(o.default(e),a,this)})),o.default.fn.modal=q._jQueryInterface,o.default.fn.modal.Constructor=q,o.default.fn.modal.noConflict=function(){return o.default.fn.modal=P,q._jQueryInterface};var F=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Q={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},B=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,H=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function U(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),a=[].slice.call(i.body.querySelectorAll("*")),s=function(t,n){var i=a[t],s=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var l=[].slice.call(i.attributes),r=[].concat(e["*"]||[],e[s]||[]);l.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===F.indexOf(n)||Boolean(t.nodeValue.match(B)||t.nodeValue.match(H));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,a=i.length;o<a;o++)if(n.match(i[o]))return!0;return!1})(t,r)||i.removeAttribute(t.nodeName)}))},l=0,r=a.length;l<r;l++)s(l);return i.body.innerHTML}var M="tooltip",W=o.default.fn[M],V=new RegExp("(^|\\s)bs-tooltip\\S+","g"),z=["sanitize","whiteList","sanitizeFn"],K={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},X={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Y={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Q,popperConfig:null},$={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},J=function(){function t(t,e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=o.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(e);var n=d.findShadowRoot(this.element),i=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var s=this.getTipElement(),l=d.getUID(this.constructor.NAME);s.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&o.default(s).addClass("fade");var r="function"==typeof this.config.placement?this.config.placement.call(this,s,this.element):this.config.placement,u=this._getAttachment(r);this.addAttachmentClass(u);var f=this._getContainer();o.default(s).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(s).appendTo(f),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new a.default(this.element,s,this._getPopperConfig(u)),o.default(s).addClass("show"),"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,o.default(t.element).trigger(t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(o.default(this.tip).hasClass("fade")){var h=d.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(d.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},e.hide=function(t){var e=this,n=this.getTipElement(),i=o.default.Event(this.constructor.Event.HIDE),a=function(){"show"!==e._hoverState&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),o.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(o.default(this.element).trigger(i),!i.isDefaultPrevented()){if(o.default(n).removeClass("show"),"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,o.default(this.tip).hasClass("fade")){var s=d.getTransitionDurationFromElement(n);o.default(n).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(o.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),o.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=U(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?o.default(e).parent().is(t)||t.empty().append(e):t.text(o.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return r({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:d.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},e._getAttachment=function(t){return X[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)o.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;o.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),o.default(e.getTipElement()).hasClass("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=o.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==z.indexOf(t)&&delete e[t]})),"number"==typeof(t=r({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d.typeCheckConfig(M,t,this.constructor.DefaultType),t.sanitize&&(t.template=U(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(V);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(o.default(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.tooltip"),a="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new t(this,a),n.data("bs.tooltip",i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return Y}},{key:"NAME",get:function(){return M}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return $}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return K}}]),t}();o.default.fn[M]=J._jQueryInterface,o.default.fn[M].Constructor=J,o.default.fn[M].noConflict=function(){return o.default.fn[M]=W,J._jQueryInterface};var G="popover",Z=o.default.fn[G],tt=new RegExp("(^|\\s)bs-popover\\S+","g"),et=r({},J.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),nt=r({},J.DefaultType,{content:"(string|element|function)"}),it={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},ot=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n;var a=i.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},a.setContent=function(){var t=o.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(tt);null!==e&&e.length>0&&t.removeClass(e.join(""))},i._jQueryInterface=function(t){return this.each((function(){var e=o.default(this).data("bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new i(this,n),o.default(this).data("bs.popover",e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},l(i,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return et}},{key:"NAME",get:function(){return G}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return it}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return nt}}]),i}(J);o.default.fn[G]=ot._jQueryInterface,o.default.fn[G].Constructor=ot,o.default.fn[G].noConflict=function(){return o.default.fn[G]=Z,ot._jQueryInterface};var at="scrollspy",st=o.default.fn[at],lt={offset:10,method:"auto",target:""},rt={offset:"number",method:"string",target:"(string|element)"},ut=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,a=d.getSelectorFromElement(t);if(a&&(e=document.querySelector(a)),e){var s=e.getBoundingClientRect();if(s.width||s.height)return[o.default(e)[n]().top+i,a]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){o.default.removeData(this._element,"bs.scrollspy"),o.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=r({},lt,"object"==typeof t&&t?t:{})).target&&d.isElement(t.target)){var e=o.default(t.target).attr("id");e||(e=d.getUID(at),o.default(t.target).attr("id",e)),t.target="#"+e}return d.typeCheckConfig(at,t,rt),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},e._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=o.default([].slice.call(document.querySelectorAll(e.join(","))));n.hasClass("dropdown-item")?(n.closest(".dropdown").find(".dropdown-toggle").addClass("active"),n.addClass("active")):(n.addClass("active"),n.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),n.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),o.default(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},e._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.scrollspy");if(n||(n=new t(this,"object"==typeof e&&e),o.default(this).data("bs.scrollspy",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"Default",get:function(){return lt}}]),t}();o.default(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),e=t.length;e--;){var n=o.default(t[e]);ut._jQueryInterface.call(n,n.data())}})),o.default.fn[at]=ut._jQueryInterface,o.default.fn[at].Constructor=ut,o.default.fn[at].noConflict=function(){return o.default.fn[at]=st,ut._jQueryInterface};var dt=o.default.fn.tab,ft=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&o.default(this._element).hasClass("active")||o.default(this._element).hasClass("disabled"))){var e,n,i=o.default(this._element).closest(".nav, .list-group")[0],a=d.getSelectorFromElement(this._element);if(i){var s="UL"===i.nodeName||"OL"===i.nodeName?"> li > .active":".active";n=(n=o.default.makeArray(o.default(i).find(s)))[n.length-1]}var l=o.default.Event("hide.bs.tab",{relatedTarget:this._element}),r=o.default.Event("show.bs.tab",{relatedTarget:n});if(n&&o.default(n).trigger(l),o.default(this._element).trigger(r),!r.isDefaultPrevented()&&!l.isDefaultPrevented()){a&&(e=document.querySelector(a)),this._activate(this._element,i);var u=function(){var e=o.default.Event("hidden.bs.tab",{relatedTarget:t._element}),i=o.default.Event("shown.bs.tab",{relatedTarget:n});o.default(n).trigger(e),o.default(t._element).trigger(i)};e?this._activate(e,e.parentNode,u):u()}}},e.dispose=function(){o.default.removeData(this._element,"bs.tab"),this._element=null},e._activate=function(t,e,n){var i=this,a=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?o.default(e).children(".active"):o.default(e).find("> li > .active"))[0],s=n&&a&&o.default(a).hasClass("fade"),l=function(){return i._transitionComplete(t,a,n)};if(a&&s){var r=d.getTransitionDurationFromElement(a);o.default(a).removeClass("show").one(d.TRANSITION_END,l).emulateTransitionEnd(r)}else l()},e._transitionComplete=function(t,e,n){if(e){o.default(e).removeClass("active");var i=o.default(e.parentNode).find("> .dropdown-menu .active")[0];i&&o.default(i).removeClass("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}if(o.default(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),d.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&o.default(t.parentNode).hasClass("dropdown-menu")){var a=o.default(t).closest(".dropdown")[0];if(a){var s=[].slice.call(a.querySelectorAll(".dropdown-toggle"));o.default(s).addClass("active")}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.tab");if(i||(i=new t(this),n.data("bs.tab",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}}]),t}();o.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),ft._jQueryInterface.call(o.default(this),"show")})),o.default.fn.tab=ft._jQueryInterface,o.default.fn.tab.Constructor=ft,o.default.fn.tab.noConflict=function(){return o.default.fn.tab=dt,ft._jQueryInterface};var ct=o.default.fn.toast,ht={animation:"boolean",autohide:"boolean",delay:"number"},gt={animation:!0,autohide:!0,delay:500},mt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=o.default.Event("show.bs.toast");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),o.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),d.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var i=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,n).emulateTransitionEnd(i)}else n()}},e.hide=function(){if(this._element.classList.contains("show")){var t=o.default.Event("hide.bs.toast");o.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),o.default(this._element).off("click.dismiss.bs.toast"),o.default.removeData(this._element,"bs.toast"),this._element=null,this._config=null},e._getConfig=function(t){return t=r({},gt,o.default(this._element).data(),"object"==typeof t&&t?t:{}),d.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;o.default(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add("hide"),o.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.toast");if(i||(i=new t(this,"object"==typeof e&&e),n.data("bs.toast",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](this)}}))},l(t,null,[{key:"VERSION",get:function(){return"4.5.3"}},{key:"DefaultType",get:function(){return ht}},{key:"Default",get:function(){return gt}}]),t}();o.default.fn.toast=mt._jQueryInterface,o.default.fn.toast.Constructor=mt,o.default.fn.toast.noConflict=function(){return o.default.fn.toast=ct,mt._jQueryInterface},t.Alert=h,t.Button=m,t.Carousel=w,t.Collapse=D,t.Dropdown=x,t.Modal=q,t.Popover=ot,t.Scrollspy=ut,t.Tab=ft,t.Toast=mt,t.Tooltip=J,t.Util=d,Object.defineProperty(t,"__esModule",{value:!0})})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=i(e),a=i(n);function s(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function l(t,e,n){return e&&s(t.prototype,e),n&&s(t,n),t}function r(){return(r=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function u(t){var e=this,n=!1;return o.default(this).one(d.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||d.triggerTransitionEnd(e)}),t),this}var d={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=o.default(t).css("transition-duration"),n=o.default(t).css("transition-delay"),i=parseFloat(e),a=parseFloat(n);return i||a?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){o.default(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],a=e[i],s=a&&d.isElement(a)?"element":null===(l=a)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(s))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?d.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof o.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=o.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};d.jQueryDetection(),o.default.fn.emulateTransitionEnd=u,o.default.event.special[d.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(o.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var f="alert",c=o.default.fn[f],h=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.default.removeData(this._element,"bs.alert"),this._element=null},e._getRootElement=function(t){var e=d.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=o.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=o.default.Event("close.bs.alert");return o.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(o.default(t).removeClass("show"),o.default(t).hasClass("fade")){var n=d.getTransitionDurationFromElement(t);o.default(t).one(d.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){o.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.alert");i||(i=new t(this),n.data("bs.alert",i)),"close"===e&&i[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();o.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),o.default.fn[f]=h._jQueryInterface,o.default.fn[f].Constructor=h,o.default.fn[f].noConflict=function(){return o.default.fn[f]=c,h._jQueryInterface};var g=o.default.fn.button,m=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=o.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var i=this._element.querySelector('input:not([type="hidden"])');if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains("active"))t=!1;else{var a=n.querySelector(".active");a&&o.default(a).removeClass("active")}t&&("checkbox"!==i.type&&"radio"!==i.type||(i.checked=!this._element.classList.contains("active")),this.shouldAvoidTriggerChange||o.default(i).trigger("change")),i.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&o.default(this._element).toggleClass("active"))},e.dispose=function(){o.default.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this),a=i.data("bs.button");a||(a=new t(this),i.data("bs.button",a)),a.shouldAvoidTriggerChange=n,"toggle"===e&&a[e]()}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();o.default(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target,n=e;if(o.default(e).hasClass("btn")||(e=o.default(e).closest(".btn")[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var i=e.querySelector('input:not([type="hidden"])');if(i&&(i.hasAttribute("disabled")||i.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||m._jQueryInterface.call(o.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=o.default(t.target).closest(".btn")[0];o.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),o.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var a=0,s=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;a<s;a++){var l=t[a];"true"===l.getAttribute("aria-pressed")?l.classList.add("active"):l.classList.remove("active")}})),o.default.fn.button=m._jQueryInterface,o.default.fn.button.Constructor=m,o.default.fn.button.noConflict=function(){return o.default.fn.button=g,m._jQueryInterface};var p="carousel",_=".bs.carousel",v=o.default.fn[p],b={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},E={TOUCH:"touch",PEN:"pen"},w=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide("next")},e.nextWhenVisible=function(){var t=o.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide("prev")},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(d.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(".active.carousel-item");var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)o.default(this._element).one("slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},e.dispose=function(){o.default(this._element).off(_),o.default.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=r({},b,t),d.typeCheckConfig(p,t,y),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&o.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&o.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&E[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&E[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};o.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(o.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(o.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),o.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),a=this._items.length-1;if((i&&0===o||n&&o===a)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(this._element.querySelector(".active.carousel-item")),a=o.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n});return o.default(this._element).trigger(a),a},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));o.default(e).removeClass("active");var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&o.default(n).addClass("active")}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(".active.carousel-item");if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,i,a,s=this,l=this._element.querySelector(".active.carousel-item"),r=this._getItemIndex(l),u=e||l&&this._getItemByDirection(t,l),f=this._getItemIndex(u),c=Boolean(this._interval);if("next"===t?(n="carousel-item-left",i="carousel-item-next",a="left"):(n="carousel-item-right",i="carousel-item-prev",a="right"),u&&o.default(u).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(u,a).isDefaultPrevented()&&l&&u){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(u),this._activeElement=u;var h=o.default.Event("slid.bs.carousel",{relatedTarget:u,direction:a,from:r,to:f});if(o.default(this._element).hasClass("slide")){o.default(u).addClass(i),d.reflow(u),o.default(l).addClass(n),o.default(u).addClass(n);var g=d.getTransitionDurationFromElement(l);o.default(l).one(d.TRANSITION_END,(function(){o.default(u).removeClass(n+" "+i).addClass("active"),o.default(l).removeClass("active "+i+" "+n),s._isSliding=!1,setTimeout((function(){return o.default(s._element).trigger(h)}),0)})).emulateTransitionEnd(g)}else o.default(l).removeClass("active"),o.default(u).addClass("active"),this._isSliding=!1,o.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.carousel"),i=r({},b,o.default(this).data());"object"==typeof e&&(i=r({},i,e));var a="string"==typeof e?e:i.slide;if(n||(n=new t(this,i),o.default(this).data("bs.carousel",n)),"number"==typeof e)n.to(e);else if("string"==typeof a){if("undefined"==typeof n[a])throw new TypeError('No method named "'+a+'"');n[a]()}else i.interval&&i.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=d.getSelectorFromElement(this);if(n){var i=o.default(n)[0];if(i&&o.default(i).hasClass("carousel")){var a=r({},o.default(i).data(),o.default(this).data()),s=this.getAttribute("data-slide-to");s&&(a.interval=!1),t._jQueryInterface.call(o.default(i),a),s&&o.default(i).data("bs.carousel").to(s),e.preventDefault()}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return b}}]),t}();o.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",w._dataApiClickHandler),o.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e<n;e++){var i=o.default(t[e]);w._jQueryInterface.call(i,i.data())}})),o.default.fn[p]=w._jQueryInterface,o.default.fn[p].Constructor=w,o.default.fn[p].noConflict=function(){return o.default.fn[p]=v,w._jQueryInterface};var T="collapse",C=o.default.fn[T],S={toggle:!0,parent:""},N={toggle:"boolean",parent:"(string|element)"},D=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var a=n[i],s=d.getSelectorFromElement(a),l=[].slice.call(document.querySelectorAll(s)).filter((function(e){return e===t}));null!==s&&l.length>0&&(this._selector=s,this._triggerArray.push(a))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){o.default(this._element).hasClass("show")?this.hide():this.show()},e.show=function(){var e,n,i=this;if(!this._isTransitioning&&!o.default(this._element).hasClass("show")&&(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof i._config.parent?t.getAttribute("data-parent")===i._config.parent:t.classList.contains("collapse")}))).length&&(e=null),!(e&&(n=o.default(e).not(this._selector).data("bs.collapse"))&&n._isTransitioning))){var a=o.default.Event("show.bs.collapse");if(o.default(this._element).trigger(a),!a.isDefaultPrevented()){e&&(t._jQueryInterface.call(o.default(e).not(this._selector),"hide"),n||o.default(e).data("bs.collapse",null));var s=this._getDimension();o.default(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[s]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(s[0].toUpperCase()+s.slice(1)),r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){o.default(i._element).removeClass("collapsing").addClass("collapse show"),i._element.style[s]="",i.setTransitioning(!1),o.default(i._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(r),this._element.style[s]=this._element[l]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&o.default(this._element).hasClass("show")){var e=o.default.Event("hide.bs.collapse");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",d.reflow(this._element),o.default(this._element).addClass("collapsing").removeClass("collapse show");var i=this._triggerArray.length;if(i>0)for(var a=0;a<i;a++){var s=this._triggerArray[a],l=d.getSelectorFromElement(s);if(null!==l)o.default([].slice.call(document.querySelectorAll(l))).hasClass("show")||o.default(s).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[n]="";var r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){t.setTransitioning(!1),o.default(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(r)}}},e.setTransitioning=function(t){this._isTransitioning=t},e.dispose=function(){o.default.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},e._getConfig=function(t){return(t=r({},S,t)).toggle=Boolean(t.toggle),d.typeCheckConfig(T,t,N),t},e._getDimension=function(){return o.default(this._element).hasClass("width")?"width":"height"},e._getParent=function(){var e,n=this;d.isElement(this._config.parent)?(e=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(e=this._config.parent[0])):e=document.querySelector(this._config.parent);var i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',a=[].slice.call(e.querySelectorAll(i));return o.default(a).each((function(e,i){n._addAriaAndCollapsedClass(t._getTargetFromElement(i),[i])})),e},e._addAriaAndCollapsedClass=function(t,e){var n=o.default(t).hasClass("show");e.length&&o.default(e).toggleClass("collapsed",!n).attr("aria-expanded",n)},t._getTargetFromElement=function(t){var e=d.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.collapse"),a=r({},S,n.data(),"object"==typeof e&&e?e:{});if(!i&&a.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(a.toggle=!1),i||(i=new t(this,a),n.data("bs.collapse",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return S}}]),t}();o.default(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var e=o.default(this),n=d.getSelectorFromElement(this),i=[].slice.call(document.querySelectorAll(n));o.default(i).each((function(){var t=o.default(this),n=t.data("bs.collapse")?"toggle":e.data();D._jQueryInterface.call(t,n)}))})),o.default.fn[T]=D._jQueryInterface,o.default.fn[T].Constructor=D,o.default.fn[T].noConflict=function(){return o.default.fn[T]=C,D._jQueryInterface};var k="dropdown",A=o.default.fn[k],I=new RegExp("38|40|27"),j={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},O={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},x=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!o.default(this._element).hasClass("disabled")){var e=o.default(this._menu).hasClass("show");t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||o.default(this._element).hasClass("disabled")||o.default(this._menu).hasClass("show"))){var n={relatedTarget:this._element},i=o.default.Event("show.bs.dropdown",n),s=t._getParentFromElement(this._element);if(o.default(s).trigger(i),!i.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");var l=this._element;"parent"===this._config.reference?l=s:d.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&o.default(s).addClass("position-static"),this._popper=new a.default(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===o.default(s).closest(".navbar-nav").length&&o.default(document.body).children().on("mouseover",null,o.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),o.default(this._menu).toggleClass("show"),o.default(s).toggleClass("show").trigger(o.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!o.default(this._element).hasClass("disabled")&&o.default(this._menu).hasClass("show")){var e={relatedTarget:this._element},n=o.default.Event("hide.bs.dropdown",e),i=t._getParentFromElement(this._element);o.default(i).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),o.default(this._menu).toggleClass("show"),o.default(i).toggleClass("show").trigger(o.default.Event("hidden.bs.dropdown",e)))}},e.dispose=function(){o.default.removeData(this._element,"bs.dropdown"),o.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;o.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=r({},this.constructor.Default,o.default(this._element).data(),t),d.typeCheckConfig(k,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},e._getPlacement=function(){var t=o.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=o.default(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":o.default(this._menu).hasClass("dropdown-menu-right")&&(e="bottom-end"),e},e._detectNavbar=function(){return o.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),r({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.dropdown");if(n||(n=new t(this,"object"==typeof e?e:null),o.default(this).data("bs.dropdown",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),i=0,a=n.length;i<a;i++){var s=t._getParentFromElement(n[i]),l=o.default(n[i]).data("bs.dropdown"),r={relatedTarget:n[i]};if(e&&"click"===e.type&&(r.clickEvent=e),l){var u=l._menu;if(o.default(s).hasClass("show")&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&o.default.contains(s,e.target))){var d=o.default.Event("hide.bs.dropdown",r);o.default(s).trigger(d),d.isDefaultPrevented()||("ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),n[i].setAttribute("aria-expanded","false"),l._popper&&l._popper.destroy(),o.default(u).removeClass("show"),o.default(s).removeClass("show").trigger(o.default.Event("hidden.bs.dropdown",r)))}}}},t._getParentFromElement=function(t){var e,n=d.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||o.default(e.target).closest(".dropdown-menu").length):!I.test(e.which))&&!this.disabled&&!o.default(this).hasClass("disabled")){var n=t._getParentFromElement(this),i=o.default(n).hasClass("show");if(i||27!==e.which){if(e.preventDefault(),e.stopPropagation(),!i||27===e.which||32===e.which)return 27===e.which&&o.default(n.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void o.default(this).trigger("click");var a=[].slice.call(n.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return o.default(t).is(":visible")}));if(0!==a.length){var s=a.indexOf(e.target);38===e.which&&s>0&&s--,40===e.which&&s<a.length-1&&s++,s<0&&(s=0),a[s].focus()}}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return j}},{key:"DefaultType",get:function(){return O}}]),t}();o.default(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',x._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",x._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",x._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),x._jQueryInterface.call(o.default(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),o.default.fn[k]=x._jQueryInterface,o.default.fn[k].Constructor=x,o.default.fn[k].noConflict=function(){return o.default.fn[k]=A,x._jQueryInterface};var P=o.default.fn.modal,R={backdrop:!0,keyboard:!0,focus:!0,show:!0},L={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},q=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var e=t.prototype;return e.toggle=function(t){return this._isShown?this.hide():this.show(t)},e.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){o.default(this._element).hasClass("fade")&&(this._isTransitioning=!0);var n=o.default.Event("show.bs.modal",{relatedTarget:t});o.default(this._element).trigger(n),this._isShown||n.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),o.default(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return e.hide(t)})),o.default(this._dialog).on("mousedown.dismiss.bs.modal",(function(){o.default(e._element).one("mouseup.dismiss.bs.modal",(function(t){o.default(t.target).is(e._element)&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},e.hide=function(t){var e=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var n=o.default.Event("hide.bs.modal");if(o.default(this._element).trigger(n),this._isShown&&!n.isDefaultPrevented()){this._isShown=!1;var i=o.default(this._element).hasClass("fade");if(i&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),o.default(document).off("focusin.bs.modal"),o.default(this._element).removeClass("show"),o.default(this._element).off("click.dismiss.bs.modal"),o.default(this._dialog).off("mousedown.dismiss.bs.modal"),i){var a=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(t){return e._hideModal(t)})).emulateTransitionEnd(a)}else this._hideModal()}}},e.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return o.default(t).off(".bs.modal")})),o.default(document).off("focusin.bs.modal"),o.default.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},e.handleUpdate=function(){this._adjustDialog()},e._getConfig=function(t){return t=r({},R,t),d.typeCheckConfig("modal",t,L),t},e._triggerBackdropTransition=function(){var t=this,e=o.default.Event("hidePrevented.bs.modal");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._element.scrollHeight>document.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var i=d.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(d.TRANSITION_END),o.default(this._element).one(d.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),n||o.default(t._element).one(d.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,i)})).emulateTransitionEnd(i),this._element.focus()}},e._showElement=function(t){var e=this,n=o.default(this._element).hasClass("fade"),i=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass("modal-dialog-scrollable")&&i?i.scrollTop=0:this._element.scrollTop=0,n&&d.reflow(this._element),o.default(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var a=o.default.Event("shown.bs.modal",{relatedTarget:t}),s=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,o.default(e._element).trigger(a)};if(n){var l=d.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(d.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._enforceFocus=function(){var t=this;o.default(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(e){document!==e.target&&t._element!==e.target&&0===o.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?o.default(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||o.default(this._element).off("keydown.dismiss.bs.modal")},e._setResizeEvent=function(){var t=this;this._isShown?o.default(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):o.default(window).off("resize.bs.modal")},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){o.default(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),o.default(t._element).trigger("hidden.bs.modal")}))},e._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=o.default(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on("click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&d.reflow(this._backdrop),o.default(this._backdrop).addClass("show"),!t)return;if(!n)return void t();var i=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,t).emulateTransitionEnd(i)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass("show");var a=function(){e._removeBackdrop(),t&&t()};if(o.default(this._element).hasClass("fade")){var s=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},e._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var e=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),n=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(e,n){var i=n.style.paddingRight,a=o.default(n).css("padding-right");o.default(n).data("padding-right",i).css("padding-right",parseFloat(a)+t._scrollbarWidth+"px")})),o.default(n).each((function(e,n){var i=n.style.marginRight,a=o.default(n).css("margin-right");o.default(n).data("margin-right",i).css("margin-right",parseFloat(a)-t._scrollbarWidth+"px")}));var i=document.body.style.paddingRight,a=o.default(document.body).css("padding-right");o.default(document.body).data("padding-right",i).css("padding-right",parseFloat(a)+this._scrollbarWidth+"px")}o.default(document.body).addClass("modal-open")},e._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));o.default(t).each((function(t,e){var n=o.default(e).data("padding-right");o.default(e).removeData("padding-right"),e.style.paddingRight=n||""}));var e=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(t,e){var n=o.default(e).data("margin-right");"undefined"!=typeof n&&o.default(e).css("margin-right",n).removeData("margin-right")}));var n=o.default(document.body).data("padding-right");o.default(document.body).removeData("padding-right"),document.body.style.paddingRight=n||""},e._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this).data("bs.modal"),a=r({},R,o.default(this).data(),"object"==typeof e&&e?e:{});if(i||(i=new t(this,a),o.default(this).data("bs.modal",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](n)}else a.show&&i.show(n)}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return R}}]),t}();o.default(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e,n=this,i=d.getSelectorFromElement(this);i&&(e=document.querySelector(i));var a=o.default(e).data("bs.modal")?"toggle":r({},o.default(e).data(),o.default(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var s=o.default(e).one("show.bs.modal",(function(t){t.isDefaultPrevented()||s.one("hidden.bs.modal",(function(){o.default(n).is(":visible")&&n.focus()}))}));q._jQueryInterface.call(o.default(e),a,this)})),o.default.fn.modal=q._jQueryInterface,o.default.fn.modal.Constructor=q,o.default.fn.modal.noConflict=function(){return o.default.fn.modal=P,q._jQueryInterface};var F=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Q={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},B=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,H=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function U(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),a=[].slice.call(i.body.querySelectorAll("*")),s=function(t,n){var i=a[t],s=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var l=[].slice.call(i.attributes),r=[].concat(e["*"]||[],e[s]||[]);l.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===F.indexOf(n)||Boolean(t.nodeValue.match(B)||t.nodeValue.match(H));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,a=i.length;o<a;o++)if(n.match(i[o]))return!0;return!1})(t,r)||i.removeAttribute(t.nodeName)}))},l=0,r=a.length;l<r;l++)s(l);return i.body.innerHTML}var M="tooltip",W=o.default.fn[M],V=new RegExp("(^|\\s)bs-tooltip\\S+","g"),z=["sanitize","whiteList","sanitizeFn"],K={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},X={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Y={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:Q,popperConfig:null},$={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},J=function(){function t(t,e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=o.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(e);var n=d.findShadowRoot(this.element),i=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var s=this.getTipElement(),l=d.getUID(this.constructor.NAME);s.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&o.default(s).addClass("fade");var r="function"==typeof this.config.placement?this.config.placement.call(this,s,this.element):this.config.placement,u=this._getAttachment(r);this.addAttachmentClass(u);var f=this._getContainer();o.default(s).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(s).appendTo(f),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new a.default(this.element,s,this._getPopperConfig(u)),o.default(s).addClass("show"),o.default(s).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,o.default(t.element).trigger(t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(o.default(this.tip).hasClass("fade")){var h=d.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(d.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},e.hide=function(t){var e=this,n=this.getTipElement(),i=o.default.Event(this.constructor.Event.HIDE),a=function(){"show"!==e._hoverState&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),o.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(o.default(this.element).trigger(i),!i.isDefaultPrevented()){if(o.default(n).removeClass("show"),"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,o.default(this.tip).hasClass("fade")){var s=d.getTransitionDurationFromElement(n);o.default(n).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(o.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),o.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=U(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?o.default(e).parent().is(t)||t.empty().append(e):t.text(o.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return r({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:d.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},e._getAttachment=function(t){return X[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)o.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;o.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),o.default(e.getTipElement()).hasClass("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=o.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==z.indexOf(t)&&delete e[t]})),"number"==typeof(t=r({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d.typeCheckConfig(M,t,this.constructor.DefaultType),t.sanitize&&(t.template=U(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(V);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(o.default(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.tooltip"),a="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new t(this,a),n.data("bs.tooltip",i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return Y}},{key:"NAME",get:function(){return M}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return $}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return K}}]),t}();o.default.fn[M]=J._jQueryInterface,o.default.fn[M].Constructor=J,o.default.fn[M].noConflict=function(){return o.default.fn[M]=W,J._jQueryInterface};var G="popover",Z=o.default.fn[G],tt=new RegExp("(^|\\s)bs-popover\\S+","g"),et=r({},J.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),nt=r({},J.DefaultType,{content:"(string|element|function)"}),it={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},ot=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n;var a=i.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},a.setContent=function(){var t=o.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(tt);null!==e&&e.length>0&&t.removeClass(e.join(""))},i._jQueryInterface=function(t){return this.each((function(){var e=o.default(this).data("bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new i(this,n),o.default(this).data("bs.popover",e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},l(i,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return et}},{key:"NAME",get:function(){return G}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return it}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return nt}}]),i}(J);o.default.fn[G]=ot._jQueryInterface,o.default.fn[G].Constructor=ot,o.default.fn[G].noConflict=function(){return o.default.fn[G]=Z,ot._jQueryInterface};var at="scrollspy",st=o.default.fn[at],lt={offset:10,method:"auto",target:""},rt={offset:"number",method:"string",target:"(string|element)"},ut=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,a=d.getSelectorFromElement(t);if(a&&(e=document.querySelector(a)),e){var s=e.getBoundingClientRect();if(s.width||s.height)return[o.default(e)[n]().top+i,a]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){o.default.removeData(this._element,"bs.scrollspy"),o.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=r({},lt,"object"==typeof t&&t?t:{})).target&&d.isElement(t.target)){var e=o.default(t.target).attr("id");e||(e=d.getUID(at),o.default(t.target).attr("id",e)),t.target="#"+e}return d.typeCheckConfig(at,t,rt),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},e._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=o.default([].slice.call(document.querySelectorAll(e.join(","))));n.hasClass("dropdown-item")?(n.closest(".dropdown").find(".dropdown-toggle").addClass("active"),n.addClass("active")):(n.addClass("active"),n.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),n.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),o.default(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},e._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.scrollspy");if(n||(n=new t(this,"object"==typeof e&&e),o.default(this).data("bs.scrollspy",n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return lt}}]),t}();o.default(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),e=t.length;e--;){var n=o.default(t[e]);ut._jQueryInterface.call(n,n.data())}})),o.default.fn[at]=ut._jQueryInterface,o.default.fn[at].Constructor=ut,o.default.fn[at].noConflict=function(){return o.default.fn[at]=st,ut._jQueryInterface};var dt=o.default.fn.tab,ft=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&o.default(this._element).hasClass("active")||o.default(this._element).hasClass("disabled"))){var e,n,i=o.default(this._element).closest(".nav, .list-group")[0],a=d.getSelectorFromElement(this._element);if(i){var s="UL"===i.nodeName||"OL"===i.nodeName?"> li > .active":".active";n=(n=o.default.makeArray(o.default(i).find(s)))[n.length-1]}var l=o.default.Event("hide.bs.tab",{relatedTarget:this._element}),r=o.default.Event("show.bs.tab",{relatedTarget:n});if(n&&o.default(n).trigger(l),o.default(this._element).trigger(r),!r.isDefaultPrevented()&&!l.isDefaultPrevented()){a&&(e=document.querySelector(a)),this._activate(this._element,i);var u=function(){var e=o.default.Event("hidden.bs.tab",{relatedTarget:t._element}),i=o.default.Event("shown.bs.tab",{relatedTarget:n});o.default(n).trigger(e),o.default(t._element).trigger(i)};e?this._activate(e,e.parentNode,u):u()}}},e.dispose=function(){o.default.removeData(this._element,"bs.tab"),this._element=null},e._activate=function(t,e,n){var i=this,a=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?o.default(e).children(".active"):o.default(e).find("> li > .active"))[0],s=n&&a&&o.default(a).hasClass("fade"),l=function(){return i._transitionComplete(t,a,n)};if(a&&s){var r=d.getTransitionDurationFromElement(a);o.default(a).removeClass("show").one(d.TRANSITION_END,l).emulateTransitionEnd(r)}else l()},e._transitionComplete=function(t,e,n){if(e){o.default(e).removeClass("active");var i=o.default(e.parentNode).find("> .dropdown-menu .active")[0];i&&o.default(i).removeClass("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}if(o.default(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),d.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&o.default(t.parentNode).hasClass("dropdown-menu")){var a=o.default(t).closest(".dropdown")[0];if(a){var s=[].slice.call(a.querySelectorAll(".dropdown-toggle"));o.default(s).addClass("active")}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.tab");if(i||(i=new t(this),n.data("bs.tab",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();o.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),ft._jQueryInterface.call(o.default(this),"show")})),o.default.fn.tab=ft._jQueryInterface,o.default.fn.tab.Constructor=ft,o.default.fn.tab.noConflict=function(){return o.default.fn.tab=dt,ft._jQueryInterface};var ct=o.default.fn.toast,ht={animation:"boolean",autohide:"boolean",delay:"number"},gt={animation:!0,autohide:!0,delay:500},mt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=o.default.Event("show.bs.toast");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),o.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),d.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var i=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,n).emulateTransitionEnd(i)}else n()}},e.hide=function(){if(this._element.classList.contains("show")){var t=o.default.Event("hide.bs.toast");o.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),o.default(this._element).off("click.dismiss.bs.toast"),o.default.removeData(this._element,"bs.toast"),this._element=null,this._config=null},e._getConfig=function(t){return t=r({},gt,o.default(this._element).data(),"object"==typeof t&&t?t:{}),d.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;o.default(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add("hide"),o.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.toast");if(i||(i=new t(this,"object"==typeof e&&e),n.data("bs.toast",i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](this)}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"DefaultType",get:function(){return ht}},{key:"Default",get:function(){return gt}}]),t}();o.default.fn.toast=mt._jQueryInterface,o.default.fn.toast.Constructor=mt,o.default.fn.toast.noConflict=function(){return o.default.fn.toast=ct,mt._jQueryInterface},t.Alert=h,t.Button=m,t.Carousel=w,t.Collapse=D,t.Dropdown=x,t.Modal=q,t.Popover=ot,t.Scrollspy=ut,t.Tab=ft,t.Toast=mt,t.Tooltip=J,t.Util=d,Object.defineProperty(t,"__esModule",{value:!0})})); //# sourceMappingURL=bootstrap.min.js.map \ No newline at end of file diff --git a/vendor/twbs/bootstrap/dist/js/bootstrap.min.js.map b/vendor/twbs/bootstrap/dist/js/bootstrap.min.js.map index 69c273671..16db08112 100644 --- a/vendor/twbs/bootstrap/dist/js/bootstrap.min.js.map +++ b/vendor/twbs/bootstrap/dist/js/bootstrap.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"names":["transitionEndEmulator","duration","_this","this","called","$","one","Util","TRANSITION_END","setTimeout","triggerTransitionEnd","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","obj","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","call","expectedTypes","value","valueType","toString","match","toLowerCase","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","fn","jquery","emulateTransitionEnd","event","special","bindType","delegateType","handle","target","is","handleObj","handler","apply","arguments","NAME","JQUERY_NO_CONFLICT","Alert","_element","close","rootElement","_getRootElement","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","EVENT_KEY","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_extends","_handleSwipe","absDeltax","abs","_this2","_keydown","_addTouchEventListeners","_this3","start","originalEvent","pointerType","clientX","touches","end","clearTimeout","e","move","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","directionalClassName","orderClassName","_this4","activeElementIndex","nextElement","nextElementIndex","isCycling","slidEvent","nextElementInterval","parseInt","defaultInterval","CLASS_NAME_ACTIVE","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","scrollSize","CLASS_NAME_COLLAPSE","getBoundingClientRect","triggerArrayLength","isTransitioning","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","REGEXP_KEYDOWN","ARROW_UP_KEYCODE","offset","flip","boundary","reference","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","Popper","referenceElement","_getPopperConfig","body","noop","hideEvent","destroy","update","scheduleUpdate","stopPropagation","constructor","_getPlacement","$parentDropdown","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","EVENT_CLICK_DATA_API","backdrop","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","forEach","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","clientHeight","overflowY","modalTransitionDuration","modalBody","Node","ELEMENT_NODE","appendChild","removeAttribute","scrollTop","_enforceFocus","shownEvent","transitionComplete","_this5","has","_this6","_this7","_this8","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","_this9","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","round","left","right","innerWidth","_getScrollbarWidth","_this10","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","_this11","uriAttrs","DefaultWhitelist","*","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","createdDocument","DOMParser","parseFromString","whitelistKeys","keys","_loop","el","elName","nodeName","attributeList","attributes","whitelistedAttributes","concat","allowedAttributeList","attrName","nodeValue","regExp","attrRegex","allowedAttribute","innerHTML","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","html","container","fallbackPlacement","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","DATA_KEY","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","ownerDocument","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","complete","_fixTransition","prevHoverState","_cleanTipClass","getTitle","CLASS_PREFIX","setElementContent","CLASS_NAME_FADE","content","text","empty","append","behavior","arrow","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","find","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","Popover","_getContent","method","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","map","targetSelector","targetBCR","height","top","sort","pageYOffset","max","_getOffsetHeight","innerHeight","maxScroll","_activate","_clear","queries","$link","parents","SELECTOR_NAV_LINKS","node","scrollSpys","$spy","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","autohide","Toast","_clearTimeout","_close"],"mappings":"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","sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = nextElementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper.js (https://popper.js.org/)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n if (this._config.backdrop === 'static') {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n } else {\n this.hide()\n }\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper.js (https://popper.js.org/)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"]} \ No newline at end of file +{"version":3,"sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js"],"names":["transitionEndEmulator","duration","_this","this","called","$","one","Util","TRANSITION_END","setTimeout","triggerTransitionEnd","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","obj","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","call","expectedTypes","value","valueType","toString","match","toLowerCase","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","fn","jquery","emulateTransitionEnd","event","special","bindType","delegateType","handle","target","is","handleObj","handler","apply","arguments","NAME","JQUERY_NO_CONFLICT","Alert","_element","close","rootElement","_getRootElement","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","Event","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","Button","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","focus","hasAttribute","setAttribute","toggleClass","avoidTriggerChange","button","initialButton","inputBtn","tagName","window","buttons","slice","querySelectorAll","i","len","length","add","EVENT_KEY","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","_updateInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","direction","off","_extends","_handleSwipe","absDeltax","abs","_this2","_keydown","_addTouchEventListeners","_this3","start","originalEvent","pointerType","clientX","touches","end","clearTimeout","e","move","which","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","elementInterval","parseInt","defaultInterval","directionalClassName","orderClassName","_this4","activeElementIndex","nextElement","nextElementIndex","isCycling","slidEvent","CLASS_NAME_ACTIVE","action","ride","_dataApiClickHandler","slideIndex","carousels","$carousel","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","scrollSize","CLASS_NAME_COLLAPSE","getBoundingClientRect","triggerArrayLength","isTransitioning","_getTargetFromElement","triggerArray","isOpen","currentTarget","$trigger","selectors","$target","REGEXP_KEYDOWN","ARROW_UP_KEYCODE","offset","flip","boundary","reference","display","popperConfig","Dropdown","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","isActive","_clearMenus","usePopper","showEvent","_getParentFromElement","Popper","referenceElement","_getPopperConfig","body","noop","hideEvent","destroy","update","scheduleUpdate","stopPropagation","constructor","_getPlacement","$parentDropdown","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","toggles","context","clickEvent","dropdownMenu","_dataApiKeydownHandler","items","item","EVENT_CLICK_DATA_API","backdrop","Modal","_dialog","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","_showBackdrop","_showElement","transition","_hideModal","forEach","htmlElement","handleUpdate","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","clientHeight","overflowY","modalTransitionDuration","modalBody","Node","ELEMENT_NODE","appendChild","removeAttribute","scrollTop","_enforceFocus","shownEvent","transitionComplete","_this5","has","_this6","_this7","_this8","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","_this9","animate","createElement","className","appendTo","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","round","left","right","innerWidth","_getScrollbarWidth","_this10","fixedContent","stickyContent","actualPadding","calculatedPadding","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","_this11","uriAttrs","DefaultWhitelist","*","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","createdDocument","DOMParser","parseFromString","whitelistKeys","keys","_loop","el","elName","nodeName","attributeList","attributes","whitelistedAttributes","concat","allowedAttributeList","attrName","nodeValue","regExp","attrRegex","allowedAttribute","innerHTML","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","animation","template","title","delay","html","container","fallbackPlacement","customClass","sanitize","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","Tooltip","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","DATA_KEY","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","_hideModalHandler","isWithContent","shadowRoot","isInTheDom","ownerDocument","tipId","setContent","attachment","_getAttachment","addAttachmentClass","_getContainer","complete","_fixTransition","prevHoverState","_cleanTipClass","getTitle","CLASS_PREFIX","setElementContent","CLASS_NAME_FADE","content","text","empty","append","behavior","arrow","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","find","eventIn","eventOut","_fixTitle","titleType","dataAttributes","dataAttr","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","Popover","_getContent","method","ScrollSpy","_scrollElement","_offsets","_targets","_activeTarget","_scrollHeight","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","map","targetSelector","targetBCR","height","top","sort","pageYOffset","max","_getOffsetHeight","innerHeight","maxScroll","_activate","_clear","queries","$link","parents","SELECTOR_NAV_LINKS","node","scrollSpys","$spy","Tab","previous","listElement","itemSelector","makeArray","hiddenEvent","active","_transitionComplete","dropdownChild","dropdownElement","dropdownToggleList","$this","autohide","Toast","_clearTimeout","_close"],"mappings":"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","sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._updateInterval()\n\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n if (!element) {\n return\n }\n\n const elementInterval = parseInt(element.getAttribute('data-interval'), 10)\n\n if (elementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = elementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n this._activeElement = nextElement\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Totally disable Popper for Dropdowns in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n customClass: '(string|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n customClass: '',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n $(tip).addClass(this.config.customClass)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/alert.js b/vendor/twbs/bootstrap/js/dist/alert.js index 3c3b376cf..2f5d80f12 100644 --- a/vendor/twbs/bootstrap/js/dist/alert.js +++ b/vendor/twbs/bootstrap/js/dist/alert.js @@ -1,11 +1,11 @@ /*! - * Bootstrap alert.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap alert.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.jQuery, global.Util)); }(this, (function ($, Util) { 'use strict'; @@ -14,9 +14,22 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -24,7 +37,7 @@ */ var NAME = 'alert'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.alert'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; diff --git a/vendor/twbs/bootstrap/js/dist/alert.js.map b/vendor/twbs/bootstrap/js/dist/alert.js.map index bc2be9aad..54e7e2ddb 100644 --- a/vendor/twbs/bootstrap/js/dist/alert.js.map +++ b/vendor/twbs/bootstrap/js/dist/alert.js.map @@ -1 +1 @@ -{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","SELECTOR_DISMISS","EVENT_CLOSE","EVENT_CLOSED","EVENT_CLICK_DATA_API","CLASS_NAME_ALERT","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","element","_element","close","rootElement","_getRootElement","customEvent","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","selector","Util","getSelectorFromElement","parent","document","querySelector","closest","closeEvent","Event","trigger","removeClass","hasClass","_destroyElement","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","event","emulateTransitionEnd","detach","remove","_jQueryInterface","config","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'alert'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst SELECTOR_DISMISS = '[data-dismiss=\"alert\"]'\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_ALERT = 'alert'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(EVENT_CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(CLASS_NAME_SHOW)\n\n if (!$(element).hasClass(CLASS_NAME_FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, event => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(EVENT_CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(\n EVENT_CLICK_DATA_API,\n SELECTOR_DISMISS,\n Alert._handleDismiss(new Alert())\n)\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Alert._jQueryInterface\n$.fn[NAME].Constructor = Alert\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n}\n\nexport default Alert\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","SELECTOR_DISMISS","EVENT_CLOSE","EVENT_CLOSED","EVENT_CLICK_DATA_API","CLASS_NAME_ALERT","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","element","_element","close","rootElement","_getRootElement","customEvent","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","selector","Util","getSelectorFromElement","parent","document","querySelector","closest","closeEvent","Event","trigger","removeClass","hasClass","_destroyElement","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","event","emulateTransitionEnd","detach","remove","_jQueryInterface","config","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/button.js b/vendor/twbs/bootstrap/js/dist/button.js index 722c7c41b..b91fd0731 100644 --- a/vendor/twbs/bootstrap/js/dist/button.js +++ b/vendor/twbs/bootstrap/js/dist/button.js @@ -1,6 +1,6 @@ /*! - * Bootstrap button.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap button.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { @@ -13,9 +13,22 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -23,7 +36,7 @@ */ var NAME = 'button'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.button'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; diff --git a/vendor/twbs/bootstrap/js/dist/button.js.map b/vendor/twbs/bootstrap/js/dist/button.js.map index 5220b0052..71770938b 100644 --- a/vendor/twbs/bootstrap/js/dist/button.js.map +++ b/vendor/twbs/bootstrap/js/dist/button.js.map @@ -1 +1 @@ -{"version":3,"file":"button.js","sources":["../src/button.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","CLASS_NAME_ACTIVE","CLASS_NAME_BUTTON","CLASS_NAME_FOCUS","SELECTOR_DATA_TOGGLE_CARROT","SELECTOR_DATA_TOGGLES","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_TOGGLES_BUTTONS","SELECTOR_INPUT","SELECTOR_ACTIVE","SELECTOR_BUTTON","EVENT_CLICK_DATA_API","EVENT_FOCUS_BLUR_DATA_API","EVENT_LOAD_DATA_API","Button","element","_element","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","rootElement","closest","input","querySelector","type","checked","classList","contains","activeElement","removeClass","trigger","focus","hasAttribute","setAttribute","toggleClass","dispose","removeData","_jQueryInterface","config","avoidTriggerChange","each","$element","data","document","on","event","button","target","initialButton","hasClass","preventDefault","inputBtn","tagName","call","test","window","buttons","slice","querySelectorAll","i","len","length","add","remove","getAttribute","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"button.js","sources":["../src/button.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'button'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_BUTTON = 'btn'\nconst CLASS_NAME_FOCUS = 'focus'\n\nconst SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^=\"button\"]'\nconst SELECTOR_DATA_TOGGLES = '[data-toggle=\"buttons\"]'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"button\"]'\nconst SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle=\"buttons\"] .btn'\nconst SELECTOR_INPUT = 'input:not([type=\"hidden\"])'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_BUTTON = '.btn'\n\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button {\n constructor(element) {\n this._element = element\n this.shouldAvoidTriggerChange = false\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0]\n\n if (rootElement) {\n const input = this._element.querySelector(SELECTOR_INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input\n if (input.type === 'checkbox' || input.type === 'radio') {\n input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)\n }\n\n if (!this.shouldAvoidTriggerChange) {\n $(input).trigger('change')\n }\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config, avoidTriggerChange) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $element.data(DATA_KEY, data)\n }\n\n data.shouldAvoidTriggerChange = avoidTriggerChange\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n let button = event.target\n const initialButton = button\n\n if (!$(button).hasClass(CLASS_NAME_BUTTON)) {\n button = $(button).closest(SELECTOR_BUTTON)[0]\n }\n\n if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {\n event.preventDefault() // work around Firefox bug #1540995\n } else {\n const inputBtn = button.querySelector(SELECTOR_INPUT)\n\n if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {\n event.preventDefault() // work around Firefox bug #1540995\n return\n }\n\n if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {\n Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT')\n }\n }\n })\n .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {\n const button = $(event.target).closest(SELECTOR_BUTTON)[0]\n $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n // ensure correct active class is set to match the controls' actual values/states\n\n // find all checkboxes/readio buttons inside data-toggle groups\n let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n const input = button.querySelector(SELECTOR_INPUT)\n if (input.checked || input.hasAttribute('checked')) {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n\n // find all button toggles\n buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = buttons.length; i < len; i++) {\n const button = buttons[i]\n if (button.getAttribute('aria-pressed') === 'true') {\n button.classList.add(CLASS_NAME_ACTIVE)\n } else {\n button.classList.remove(CLASS_NAME_ACTIVE)\n }\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Button._jQueryInterface\n$.fn[NAME].Constructor = Button\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n}\n\nexport default Button\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","CLASS_NAME_ACTIVE","CLASS_NAME_BUTTON","CLASS_NAME_FOCUS","SELECTOR_DATA_TOGGLE_CARROT","SELECTOR_DATA_TOGGLES","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_TOGGLES_BUTTONS","SELECTOR_INPUT","SELECTOR_ACTIVE","SELECTOR_BUTTON","EVENT_CLICK_DATA_API","EVENT_FOCUS_BLUR_DATA_API","EVENT_LOAD_DATA_API","Button","element","_element","shouldAvoidTriggerChange","toggle","triggerChangeEvent","addAriaPressed","rootElement","closest","input","querySelector","type","checked","classList","contains","activeElement","removeClass","trigger","focus","hasAttribute","setAttribute","toggleClass","dispose","removeData","_jQueryInterface","config","avoidTriggerChange","each","$element","data","document","on","event","button","target","initialButton","hasClass","preventDefault","inputBtn","tagName","call","test","window","buttons","slice","querySelectorAll","i","len","length","add","remove","getAttribute","Constructor","noConflict"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASA;EACA;EACA;EACA;EACA;;EAEA,IAAMA,IAAI,GAAG,QAAb;EACA,IAAMC,OAAO,GAAG,OAAhB;EACA,IAAMC,QAAQ,GAAG,WAAjB;EACA,IAAMC,SAAS,SAAOD,QAAtB;EACA,IAAME,YAAY,GAAG,WAArB;EACA,IAAMC,kBAAkB,GAAGC,qBAAC,CAACC,EAAF,CAAKP,IAAL,CAA3B;EAEA,IAAMQ,iBAAiB,GAAG,QAA1B;EACA,IAAMC,iBAAiB,GAAG,KAA1B;EACA,IAAMC,gBAAgB,GAAG,OAAzB;EAEA,IAAMC,2BAA2B,GAAG,yBAApC;EACA,IAAMC,qBAAqB,GAAG,yBAA9B;EACA,IAAMC,oBAAoB,GAAG,wBAA7B;EACA,IAAMC,6BAA6B,GAAG,8BAAtC;EACA,IAAMC,cAAc,GAAG,4BAAvB;EACA,IAAMC,eAAe,GAAG,SAAxB;EACA,IAAMC,eAAe,GAAG,MAAxB;EAEA,IAAMC,oBAAoB,aAAWf,SAAX,GAAuBC,YAAjD;EACA,IAAMe,yBAAyB,GAAG,UAAQhB,SAAR,GAAoBC,YAApB,mBACDD,SADC,GACWC,YADX,CAAlC;EAEA,IAAMgB,mBAAmB,YAAUjB,SAAV,GAAsBC,YAA/C;EAEA;EACA;EACA;EACA;EACA;;MAEMiB;EACJ,kBAAYC,OAAZ,EAAqB;EACnB,SAAKC,QAAL,GAAgBD,OAAhB;EACA,SAAKE,wBAAL,GAAgC,KAAhC;EACD;;;;;EAQD;WAEAC,SAAA,kBAAS;EACP,QAAIC,kBAAkB,GAAG,IAAzB;EACA,QAAIC,cAAc,GAAG,IAArB;EACA,QAAMC,WAAW,GAAGtB,qBAAC,CAAC,KAAKiB,QAAN,CAAD,CAAiBM,OAAjB,CAAyBjB,qBAAzB,EAAgD,CAAhD,CAApB;;EAEA,QAAIgB,WAAJ,EAAiB;EACf,UAAME,KAAK,GAAG,KAAKP,QAAL,CAAcQ,aAAd,CAA4BhB,cAA5B,CAAd;;EAEA,UAAIe,KAAJ,EAAW;EACT,YAAIA,KAAK,CAACE,IAAN,KAAe,OAAnB,EAA4B;EAC1B,cAAIF,KAAK,CAACG,OAAN,IAAiB,KAAKV,QAAL,CAAcW,SAAd,CAAwBC,QAAxB,CAAiC3B,iBAAjC,CAArB,EAA0E;EACxEkB,YAAAA,kBAAkB,GAAG,KAArB;EACD,WAFD,MAEO;EACL,gBAAMU,aAAa,GAAGR,WAAW,CAACG,aAAZ,CAA0Bf,eAA1B,CAAtB;;EAEA,gBAAIoB,aAAJ,EAAmB;EACjB9B,cAAAA,qBAAC,CAAC8B,aAAD,CAAD,CAAiBC,WAAjB,CAA6B7B,iBAA7B;EACD;EACF;EACF;;EAED,YAAIkB,kBAAJ,EAAwB;EACtB;EACA,cAAII,KAAK,CAACE,IAAN,KAAe,UAAf,IAA6BF,KAAK,CAACE,IAAN,KAAe,OAAhD,EAAyD;EACvDF,YAAAA,KAAK,CAACG,OAAN,GAAgB,CAAC,KAAKV,QAAL,CAAcW,SAAd,CAAwBC,QAAxB,CAAiC3B,iBAAjC,CAAjB;EACD;;EAED,cAAI,CAAC,KAAKgB,wBAAV,EAAoC;EAClClB,YAAAA,qBAAC,CAACwB,KAAD,CAAD,CAASQ,OAAT,CAAiB,QAAjB;EACD;EACF;;EAEDR,QAAAA,KAAK,CAACS,KAAN;EACAZ,QAAAA,cAAc,GAAG,KAAjB;EACD;EACF;;EAED,QAAI,EAAE,KAAKJ,QAAL,CAAciB,YAAd,CAA2B,UAA3B,KAA0C,KAAKjB,QAAL,CAAcW,SAAd,CAAwBC,QAAxB,CAAiC,UAAjC,CAA5C,CAAJ,EAA+F;EAC7F,UAAIR,cAAJ,EAAoB;EAClB,aAAKJ,QAAL,CAAckB,YAAd,CAA2B,cAA3B,EAA2C,CAAC,KAAKlB,QAAL,CAAcW,SAAd,CAAwBC,QAAxB,CAAiC3B,iBAAjC,CAA5C;EACD;;EAED,UAAIkB,kBAAJ,EAAwB;EACtBpB,QAAAA,qBAAC,CAAC,KAAKiB,QAAN,CAAD,CAAiBmB,WAAjB,CAA6BlC,iBAA7B;EACD;EACF;EACF;;WAEDmC,UAAA,mBAAU;EACRrC,IAAAA,qBAAC,CAACsC,UAAF,CAAa,KAAKrB,QAAlB,EAA4BrB,QAA5B;EACA,SAAKqB,QAAL,GAAgB,IAAhB;EACD;;;WAIMsB,mBAAP,0BAAwBC,MAAxB,EAAgCC,kBAAhC,EAAoD;EAClD,WAAO,KAAKC,IAAL,CAAU,YAAY;EAC3B,UAAMC,QAAQ,GAAG3C,qBAAC,CAAC,IAAD,CAAlB;EACA,UAAI4C,IAAI,GAAGD,QAAQ,CAACC,IAAT,CAAchD,QAAd,CAAX;;EAEA,UAAI,CAACgD,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAI7B,MAAJ,CAAW,IAAX,CAAP;EACA4B,QAAAA,QAAQ,CAACC,IAAT,CAAchD,QAAd,EAAwBgD,IAAxB;EACD;;EAEDA,MAAAA,IAAI,CAAC1B,wBAAL,GAAgCuB,kBAAhC;;EAEA,UAAID,MAAM,KAAK,QAAf,EAAyB;EACvBI,QAAAA,IAAI,CAACJ,MAAD,CAAJ;EACD;EACF,KAdM,CAAP;EAeD;;;;0BA7EoB;EACnB,aAAO7C,OAAP;EACD;;;;;EA8EH;EACA;EACA;EACA;EACA;;;AAEAK,uBAAC,CAAC6C,QAAD,CAAD,CACGC,EADH,CACMlC,oBADN,EAC4BP,2BAD5B,EACyD,UAAA0C,KAAK,EAAI;EAC9D,MAAIC,MAAM,GAAGD,KAAK,CAACE,MAAnB;EACA,MAAMC,aAAa,GAAGF,MAAtB;;EAEA,MAAI,CAAChD,qBAAC,CAACgD,MAAD,CAAD,CAAUG,QAAV,CAAmBhD,iBAAnB,CAAL,EAA4C;EAC1C6C,IAAAA,MAAM,GAAGhD,qBAAC,CAACgD,MAAD,CAAD,CAAUzB,OAAV,CAAkBZ,eAAlB,EAAmC,CAAnC,CAAT;EACD;;EAED,MAAI,CAACqC,MAAD,IAAWA,MAAM,CAACd,YAAP,CAAoB,UAApB,CAAX,IAA8Cc,MAAM,CAACpB,SAAP,CAAiBC,QAAjB,CAA0B,UAA1B,CAAlD,EAAyF;EACvFkB,IAAAA,KAAK,CAACK,cAAN,GADuF;EAExF,GAFD,MAEO;EACL,QAAMC,QAAQ,GAAGL,MAAM,CAACvB,aAAP,CAAqBhB,cAArB,CAAjB;;EAEA,QAAI4C,QAAQ,KAAKA,QAAQ,CAACnB,YAAT,CAAsB,UAAtB,KAAqCmB,QAAQ,CAACzB,SAAT,CAAmBC,QAAnB,CAA4B,UAA5B,CAA1C,CAAZ,EAAgG;EAC9FkB,MAAAA,KAAK,CAACK,cAAN,GAD8F;;EAE9F;EACD;;EAED,QAAIF,aAAa,CAACI,OAAd,KAA0B,OAA1B,IAAqCN,MAAM,CAACM,OAAP,KAAmB,OAA5D,EAAqE;EACnEvC,MAAAA,MAAM,CAACwB,gBAAP,CAAwBgB,IAAxB,CAA6BvD,qBAAC,CAACgD,MAAD,CAA9B,EAAwC,QAAxC,EAAkDE,aAAa,CAACI,OAAd,KAA0B,OAA5E;EACD;EACF;EACF,CAvBH,EAwBGR,EAxBH,CAwBMjC,yBAxBN,EAwBiCR,2BAxBjC,EAwB8D,UAAA0C,KAAK,EAAI;EACnE,MAAMC,MAAM,GAAGhD,qBAAC,CAAC+C,KAAK,CAACE,MAAP,CAAD,CAAgB1B,OAAhB,CAAwBZ,eAAxB,EAAyC,CAAzC,CAAf;EACAX,EAAAA,qBAAC,CAACgD,MAAD,CAAD,CAAUZ,WAAV,CAAsBhC,gBAAtB,EAAwC,eAAeoD,IAAf,CAAoBT,KAAK,CAACrB,IAA1B,CAAxC;EACD,CA3BH;AA6BA1B,uBAAC,CAACyD,MAAD,CAAD,CAAUX,EAAV,CAAahC,mBAAb,EAAkC,YAAM;EACtC;EAEA;EACA,MAAI4C,OAAO,GAAG,GAAGC,KAAH,CAASJ,IAAT,CAAcV,QAAQ,CAACe,gBAAT,CAA0BpD,6BAA1B,CAAd,CAAd;;EACA,OAAK,IAAIqD,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGJ,OAAO,CAACK,MAA9B,EAAsCF,CAAC,GAAGC,GAA1C,EAA+CD,CAAC,EAAhD,EAAoD;EAClD,QAAMb,MAAM,GAAGU,OAAO,CAACG,CAAD,CAAtB;EACA,QAAMrC,KAAK,GAAGwB,MAAM,CAACvB,aAAP,CAAqBhB,cAArB,CAAd;;EACA,QAAIe,KAAK,CAACG,OAAN,IAAiBH,KAAK,CAACU,YAAN,CAAmB,SAAnB,CAArB,EAAoD;EAClDc,MAAAA,MAAM,CAACpB,SAAP,CAAiBoC,GAAjB,CAAqB9D,iBAArB;EACD,KAFD,MAEO;EACL8C,MAAAA,MAAM,CAACpB,SAAP,CAAiBqC,MAAjB,CAAwB/D,iBAAxB;EACD;EACF,GAbqC;;;EAgBtCwD,EAAAA,OAAO,GAAG,GAAGC,KAAH,CAASJ,IAAT,CAAcV,QAAQ,CAACe,gBAAT,CAA0BrD,oBAA1B,CAAd,CAAV;;EACA,OAAK,IAAIsD,EAAC,GAAG,CAAR,EAAWC,IAAG,GAAGJ,OAAO,CAACK,MAA9B,EAAsCF,EAAC,GAAGC,IAA1C,EAA+CD,EAAC,EAAhD,EAAoD;EAClD,QAAMb,OAAM,GAAGU,OAAO,CAACG,EAAD,CAAtB;;EACA,QAAIb,OAAM,CAACkB,YAAP,CAAoB,cAApB,MAAwC,MAA5C,EAAoD;EAClDlB,MAAAA,OAAM,CAACpB,SAAP,CAAiBoC,GAAjB,CAAqB9D,iBAArB;EACD,KAFD,MAEO;EACL8C,MAAAA,OAAM,CAACpB,SAAP,CAAiBqC,MAAjB,CAAwB/D,iBAAxB;EACD;EACF;EACF,CAzBD;EA2BA;EACA;EACA;EACA;EACA;;AAEAF,uBAAC,CAACC,EAAF,CAAKP,IAAL,IAAaqB,MAAM,CAACwB,gBAApB;AACAvC,uBAAC,CAACC,EAAF,CAAKP,IAAL,EAAWyE,WAAX,GAAyBpD,MAAzB;;AACAf,uBAAC,CAACC,EAAF,CAAKP,IAAL,EAAW0E,UAAX,GAAwB,YAAM;EAC5BpE,EAAAA,qBAAC,CAACC,EAAF,CAAKP,IAAL,IAAaK,kBAAb;EACA,SAAOgB,MAAM,CAACwB,gBAAd;EACD,CAHD;;;;;;;;"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/carousel.js b/vendor/twbs/bootstrap/js/dist/carousel.js index b9d1ec6d8..4520f5409 100644 --- a/vendor/twbs/bootstrap/js/dist/carousel.js +++ b/vendor/twbs/bootstrap/js/dist/carousel.js @@ -1,11 +1,11 @@ /*! - * Bootstrap carousel.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap carousel.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Carousel = factory(global.jQuery, global.Util)); }(this, (function ($, Util) { 'use strict'; @@ -14,11 +14,40 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + return _extends.apply(this, arguments); + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -26,7 +55,7 @@ */ var NAME = 'carousel'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.carousel'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -166,6 +195,8 @@ } if (this._config.interval && !this._isPaused) { + this._updateInterval(); + this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); } }; @@ -407,6 +438,23 @@ } }; + _proto._updateInterval = function _updateInterval() { + var element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM); + + if (!element) { + return; + } + + var elementInterval = parseInt(element.getAttribute('data-interval'), 10); + + if (elementInterval) { + this._config.defaultInterval = this._config.defaultInterval || this._config.interval; + this._config.interval = elementInterval; + } else { + this._config.interval = this._config.defaultInterval || this._config.interval; + } + }; + _proto._slide = function _slide(direction, element) { var _this4 = this; @@ -457,6 +505,7 @@ this._setActiveIndicatorElement(nextElement); + this._activeElement = nextElement; var slidEvent = $__default['default'].Event(EVENT_SLID, { relatedTarget: nextElement, direction: eventDirectionName, @@ -469,15 +518,6 @@ Util__default['default'].reflow(nextElement); $__default['default'](activeElement).addClass(directionalClassName); $__default['default'](nextElement).addClass(directionalClassName); - var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10); - - if (nextElementInterval) { - this._config.defaultInterval = this._config.defaultInterval || this._config.interval; - this._config.interval = nextElementInterval; - } else { - this._config.interval = this._config.defaultInterval || this._config.interval; - } - var transitionDuration = Util__default['default'].getTransitionDurationFromElement(activeElement); $__default['default'](activeElement).one(Util__default['default'].TRANSITION_END, function () { $__default['default'](nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE); diff --git a/vendor/twbs/bootstrap/js/dist/carousel.js.map b/vendor/twbs/bootstrap/js/dist/carousel.js.map index f3a092193..b4662008c 100644 --- a/vendor/twbs/bootstrap/js/dist/carousel.js.map +++ b/vendor/twbs/bootstrap/js/dist/carousel.js.map @@ -1 +1 @@ -{"version":3,"file":"carousel.js","sources":["../src/carousel.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)\n if (nextElementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = nextElementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","ARROW_LEFT_KEYCODE","ARROW_RIGHT_KEYCODE","TOUCHEVENT_COMPAT_WAIT","SWIPE_THRESHOLD","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","DIRECTION_NEXT","DIRECTION_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLIDE","EVENT_SLID","EVENT_KEYDOWN","EVENT_MOUSEENTER","EVENT_MOUSELEAVE","EVENT_TOUCHSTART","EVENT_TOUCHMOVE","EVENT_TOUCHEND","EVENT_POINTERDOWN","EVENT_POINTERUP","EVENT_DRAG_START","EVENT_LOAD_DATA_API","EVENT_CLICK_DATA_API","CLASS_NAME_CAROUSEL","CLASS_NAME_ACTIVE","CLASS_NAME_SLIDE","CLASS_NAME_RIGHT","CLASS_NAME_LEFT","CLASS_NAME_NEXT","CLASS_NAME_PREV","CLASS_NAME_POINTER_EVENT","SELECTOR_ACTIVE","SELECTOR_ACTIVE_ITEM","SELECTOR_ITEM","SELECTOR_ITEM_IMG","SELECTOR_NEXT_PREV","SELECTOR_INDICATORS","SELECTOR_DATA_SLIDE","SELECTOR_DATA_RIDE","PointerType","TOUCH","PEN","Carousel","element","config","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_element","_indicatorsElement","querySelector","_touchSupported","document","documentElement","navigator","maxTouchPoints","_pointerEvent","Boolean","window","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","$element","hidden","is","css","prev","event","Util","triggerTransitionEnd","cycle","clearInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","length","one","direction","dispose","off","removeData","typeCheckConfig","_handleSwipe","absDeltax","Math","abs","on","_keydown","_addTouchEventListeners","start","originalEvent","pointerType","toUpperCase","clientX","touches","move","end","clearTimeout","setTimeout","querySelectorAll","e","preventDefault","classList","add","test","target","tagName","which","parentNode","slice","call","indexOf","_getItemByDirection","activeElement","isNextDirection","isPrevDirection","lastItemIndex","isGoingToWrap","delta","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","Event","from","trigger","_setActiveIndicatorElement","indicators","removeClass","nextIndicator","children","addClass","activeElementIndex","nextElement","nextElementIndex","isCycling","directionalClassName","orderClassName","hasClass","isDefaultPrevented","slidEvent","reflow","nextElementInterval","parseInt","getAttribute","defaultInterval","transitionDuration","getTransitionDurationFromElement","TRANSITION_END","emulateTransitionEnd","_jQueryInterface","each","data","action","TypeError","ride","_dataApiClickHandler","selector","getSelectorFromElement","slideIndex","carousels","i","len","$carousel","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"carousel.js","sources":["../src/carousel.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'carousel'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\nconst ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n slide: false,\n pause: 'hover',\n wrap: true,\n touch: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)',\n keyboard: 'boolean',\n slide: '(boolean|string)',\n pause: '(string|boolean)',\n wrap: 'boolean',\n touch: 'boolean'\n}\n\nconst DIRECTION_NEXT = 'next'\nconst DIRECTION_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_RIGHT = 'carousel-item-right'\nconst CLASS_NAME_LEFT = 'carousel-item-left'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-ride=\"carousel\"]'\n\nconst PointerType = {\n TOUCH: 'touch',\n PEN: 'pen'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\nclass Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n this._isPaused = false\n this._isSliding = false\n this.touchTimeout = null\n this.touchStartX = 0\n this.touchDeltaX = 0\n\n this._config = this._getConfig(config)\n this._element = element\n this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)\n this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(DIRECTION_NEXT)\n }\n }\n\n nextWhenVisible() {\n const $element = $(this._element)\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($element.is(':visible') && $element.css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(DIRECTION_PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(SELECTOR_NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._updateInterval()\n\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(EVENT_SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex ?\n DIRECTION_NEXT :\n DIRECTION_PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _handleSwipe() {\n const absDeltax = Math.abs(this.touchDeltaX)\n\n if (absDeltax <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltax / this.touchDeltaX\n\n this.touchDeltaX = 0\n\n // swipe left\n if (direction > 0) {\n this.prev()\n }\n\n // swipe right\n if (direction < 0) {\n this.next()\n }\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(EVENT_MOUSEENTER, event => this.pause(event))\n .on(EVENT_MOUSELEAVE, event => this.cycle(event))\n }\n\n if (this._config.touch) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n if (!this._touchSupported) {\n return\n }\n\n const start = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchStartX = event.originalEvent.clientX\n } else if (!this._pointerEvent) {\n this.touchStartX = event.originalEvent.touches[0].clientX\n }\n }\n\n const move = event => {\n // ensure swiping with one touch and not pinching\n if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {\n this.touchDeltaX = 0\n } else {\n this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX\n }\n }\n\n const end = event => {\n if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {\n this.touchDeltaX = event.originalEvent.clientX - this.touchStartX\n }\n\n this._handleSwipe()\n if (this._config.pause === 'hover') {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n }\n\n $(this._element.querySelectorAll(SELECTOR_ITEM_IMG))\n .on(EVENT_DRAG_START, e => e.preventDefault())\n\n if (this._pointerEvent) {\n $(this._element).on(EVENT_POINTERDOWN, event => start(event))\n $(this._element).on(EVENT_POINTERUP, event => end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n $(this._element).on(EVENT_TOUCHSTART, event => start(event))\n $(this._element).on(EVENT_TOUCHMOVE, event => move(event))\n $(this._element).on(EVENT_TOUCHEND, event => end(event))\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode ?\n [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) :\n []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === DIRECTION_NEXT\n const isPrevDirection = direction === DIRECTION_PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === DIRECTION_PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1 ?\n this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))\n const slideEvent = $.Event(EVENT_SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))\n $(indicators).removeClass(CLASS_NAME_ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(CLASS_NAME_ACTIVE)\n }\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n\n if (!element) {\n return\n }\n\n const elementInterval = parseInt(element.getAttribute('data-interval'), 10)\n\n if (elementInterval) {\n this._config.defaultInterval = this._config.defaultInterval || this._config.interval\n this._config.interval = elementInterval\n } else {\n this._config.interval = this._config.defaultInterval || this._config.interval\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === DIRECTION_NEXT) {\n directionalClassName = CLASS_NAME_LEFT\n orderClassName = CLASS_NAME_NEXT\n eventDirectionName = DIRECTION_LEFT\n } else {\n directionalClassName = CLASS_NAME_RIGHT\n orderClassName = CLASS_NAME_PREV\n eventDirectionName = DIRECTION_RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n this._activeElement = nextElement\n\n const slidEvent = $.Event(EVENT_SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(CLASS_NAME_ACTIVE)\n\n $(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(CLASS_NAME_ACTIVE)\n $(nextElement).addClass(CLASS_NAME_ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n\n data[action]()\n } else if (_config.interval && _config.ride) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Carousel._jQueryInterface\n$.fn[NAME].Constructor = Carousel\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n}\n\nexport default Carousel\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","ARROW_LEFT_KEYCODE","ARROW_RIGHT_KEYCODE","TOUCHEVENT_COMPAT_WAIT","SWIPE_THRESHOLD","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","DIRECTION_NEXT","DIRECTION_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLIDE","EVENT_SLID","EVENT_KEYDOWN","EVENT_MOUSEENTER","EVENT_MOUSELEAVE","EVENT_TOUCHSTART","EVENT_TOUCHMOVE","EVENT_TOUCHEND","EVENT_POINTERDOWN","EVENT_POINTERUP","EVENT_DRAG_START","EVENT_LOAD_DATA_API","EVENT_CLICK_DATA_API","CLASS_NAME_CAROUSEL","CLASS_NAME_ACTIVE","CLASS_NAME_SLIDE","CLASS_NAME_RIGHT","CLASS_NAME_LEFT","CLASS_NAME_NEXT","CLASS_NAME_PREV","CLASS_NAME_POINTER_EVENT","SELECTOR_ACTIVE","SELECTOR_ACTIVE_ITEM","SELECTOR_ITEM","SELECTOR_ITEM_IMG","SELECTOR_NEXT_PREV","SELECTOR_INDICATORS","SELECTOR_DATA_SLIDE","SELECTOR_DATA_RIDE","PointerType","TOUCH","PEN","Carousel","element","config","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_element","_indicatorsElement","querySelector","_touchSupported","document","documentElement","navigator","maxTouchPoints","_pointerEvent","Boolean","window","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","$element","hidden","is","css","prev","event","Util","triggerTransitionEnd","cycle","clearInterval","_updateInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","length","one","direction","dispose","off","removeData","typeCheckConfig","_handleSwipe","absDeltax","Math","abs","on","_keydown","_addTouchEventListeners","start","originalEvent","pointerType","toUpperCase","clientX","touches","move","end","clearTimeout","setTimeout","querySelectorAll","e","preventDefault","classList","add","test","target","tagName","which","parentNode","slice","call","indexOf","_getItemByDirection","activeElement","isNextDirection","isPrevDirection","lastItemIndex","isGoingToWrap","delta","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","Event","from","trigger","_setActiveIndicatorElement","indicators","removeClass","nextIndicator","children","addClass","elementInterval","parseInt","getAttribute","defaultInterval","activeElementIndex","nextElement","nextElementIndex","isCycling","directionalClassName","orderClassName","hasClass","isDefaultPrevented","slidEvent","reflow","transitionDuration","getTransitionDurationFromElement","TRANSITION_END","emulateTransitionEnd","_jQueryInterface","each","data","action","TypeError","ride","_dataApiClickHandler","selector","getSelectorFromElement","slideIndex","carousels","i","len","$carousel","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/collapse.js b/vendor/twbs/bootstrap/js/dist/collapse.js index b5d663243..427e2711f 100644 --- a/vendor/twbs/bootstrap/js/dist/collapse.js +++ b/vendor/twbs/bootstrap/js/dist/collapse.js @@ -1,11 +1,11 @@ /*! - * Bootstrap collapse.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap collapse.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Collapse = factory(global.jQuery, global.Util)); }(this, (function ($, Util) { 'use strict'; @@ -14,11 +14,40 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + return _extends.apply(this, arguments); + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -26,7 +55,7 @@ */ var NAME = 'collapse'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.collapse'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; diff --git a/vendor/twbs/bootstrap/js/dist/collapse.js.map b/vendor/twbs/bootstrap/js/dist/collapse.js.map index d14e4647d..dd3bac4b9 100644 --- a/vendor/twbs/bootstrap/js/dist/collapse.js.map +++ b/vendor/twbs/bootstrap/js/dist/collapse.js.map @@ -1 +1 @@ -{"version":3,"file":"collapse.js","sources":["../src/collapse.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","Default","toggle","parent","DefaultType","EVENT_SHOW","EVENT_SHOWN","EVENT_HIDE","EVENT_HIDDEN","EVENT_CLICK_DATA_API","CLASS_NAME_SHOW","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","CLASS_NAME_COLLAPSED","DIMENSION_WIDTH","DIMENSION_HEIGHT","SELECTOR_ACTIVES","SELECTOR_DATA_TOGGLE","Collapse","element","config","_isTransitioning","_element","_config","_getConfig","_triggerArray","slice","call","document","querySelectorAll","id","toggleList","i","len","length","elem","selector","Util","getSelectorFromElement","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hasClass","hide","show","actives","activesData","getAttribute","classList","contains","not","data","startEvent","Event","trigger","isDefaultPrevented","_jQueryInterface","dimension","_getDimension","removeClass","addClass","style","attr","setTransitioning","complete","capitalizedDimension","toUpperCase","scrollSize","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","emulateTransitionEnd","getBoundingClientRect","reflow","triggerArrayLength","$elem","isTransitioning","dispose","removeData","Boolean","typeCheckConfig","hasWidth","isElement","jquery","querySelector","children","each","_getTargetFromElement","triggerArray","isOpen","toggleClass","$element","test","TypeError","on","event","currentTarget","tagName","preventDefault","$trigger","selectors","$target","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"collapse.js","sources":["../src/collapse.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'collapse'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n toggle: true,\n parent: ''\n}\n\nconst DefaultType = {\n toggle: 'boolean',\n parent: '(string|element)'\n}\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\n\nconst DIMENSION_WIDTH = 'width'\nconst DIMENSION_HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.show, .collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"collapse\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = [].slice.call(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n\n const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter(foundElem => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(CLASS_NAME_SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))\n .filter(elem => {\n if (typeof this._config.parent === 'string') {\n return elem.getAttribute('data-parent') === this._config.parent\n }\n\n return elem.classList.contains(CLASS_NAME_COLLAPSE)\n })\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(EVENT_SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSE)\n .addClass(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const startEvent = $.Event(EVENT_HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(CLASS_NAME_COLLAPSING)\n .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(CLASS_NAME_SHOW)) {\n $(trigger).addClass(CLASS_NAME_COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(CLASS_NAME_COLLAPSING)\n .addClass(CLASS_NAME_COLLAPSE)\n .trigger(EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)\n return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT\n }\n\n _getParent() {\n let parent\n\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector = `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n const children = [].slice.call(parent.querySelectorAll(selector))\n\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n const isOpen = $(element).hasClass(CLASS_NAME_SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$element.data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Collapse._jQueryInterface\n$.fn[NAME].Constructor = Collapse\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n}\n\nexport default Collapse\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","Default","toggle","parent","DefaultType","EVENT_SHOW","EVENT_SHOWN","EVENT_HIDE","EVENT_HIDDEN","EVENT_CLICK_DATA_API","CLASS_NAME_SHOW","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","CLASS_NAME_COLLAPSED","DIMENSION_WIDTH","DIMENSION_HEIGHT","SELECTOR_ACTIVES","SELECTOR_DATA_TOGGLE","Collapse","element","config","_isTransitioning","_element","_config","_getConfig","_triggerArray","slice","call","document","querySelectorAll","id","toggleList","i","len","length","elem","selector","Util","getSelectorFromElement","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hasClass","hide","show","actives","activesData","getAttribute","classList","contains","not","data","startEvent","Event","trigger","isDefaultPrevented","_jQueryInterface","dimension","_getDimension","removeClass","addClass","style","attr","setTransitioning","complete","capitalizedDimension","toUpperCase","scrollSize","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","emulateTransitionEnd","getBoundingClientRect","reflow","triggerArrayLength","$elem","isTransitioning","dispose","removeData","Boolean","typeCheckConfig","hasWidth","isElement","jquery","querySelector","children","each","_getTargetFromElement","triggerArray","isOpen","toggleClass","$element","test","TypeError","on","event","currentTarget","tagName","preventDefault","$trigger","selectors","$target","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/dropdown.js b/vendor/twbs/bootstrap/js/dist/dropdown.js index 9ba052ef6..772617ce8 100644 --- a/vendor/twbs/bootstrap/js/dist/dropdown.js +++ b/vendor/twbs/bootstrap/js/dist/dropdown.js @@ -1,11 +1,11 @@ /*! - * Bootstrap dropdown.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap dropdown.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dropdown = factory(global.jQuery, global.Popper, global.Util)); }(this, (function ($, Popper, Util) { 'use strict'; @@ -15,11 +15,40 @@ var Popper__default = /*#__PURE__*/_interopDefaultLegacy(Popper); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + return _extends.apply(this, arguments); + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -27,7 +56,7 @@ */ var NAME = 'dropdown'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.dropdown'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -144,7 +173,7 @@ if (showEvent.isDefaultPrevented()) { return; - } // Disable totally Popper.js for Dropdown in Navbar + } // Totally disable Popper for Dropdowns in Navbar if (!this._inNavbar && usePopper) { @@ -153,7 +182,7 @@ * Popper - https://popper.js.org */ if (typeof Popper__default['default'] === 'undefined') { - throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); + throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)'); } var referenceElement = this._element; @@ -321,7 +350,7 @@ boundariesElement: this._config.boundary } } - }; // Disable Popper.js if we have a static display + }; // Disable Popper if we have a static display if (this._config.display === 'static') { popperConfig.modifiers.applyStyle = { diff --git a/vendor/twbs/bootstrap/js/dist/dropdown.js.map b/vendor/twbs/bootstrap/js/dist/dropdown.js.map index a033a2d4a..70346d88f 100644 --- a/vendor/twbs/bootstrap/js/dist/dropdown.js.map +++ b/vendor/twbs/bootstrap/js/dist/dropdown.js.map @@ -1 +1 @@ -{"version":3,"file":"dropdown.js","sources":["../src/dropdown.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper.js (https://popper.js.org/)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","ESCAPE_KEYCODE","SPACE_KEYCODE","TAB_KEYCODE","ARROW_UP_KEYCODE","ARROW_DOWN_KEYCODE","RIGHT_MOUSE_BUTTON_WHICH","REGEXP_KEYDOWN","RegExp","EVENT_HIDE","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","EVENT_CLICK","EVENT_CLICK_DATA_API","EVENT_KEYDOWN_DATA_API","EVENT_KEYUP_DATA_API","CLASS_NAME_DISABLED","CLASS_NAME_SHOW","CLASS_NAME_DROPUP","CLASS_NAME_DROPRIGHT","CLASS_NAME_DROPLEFT","CLASS_NAME_MENURIGHT","CLASS_NAME_POSITION_STATIC","SELECTOR_DATA_TOGGLE","SELECTOR_FORM_CHILD","SELECTOR_MENU","SELECTOR_NAVBAR_NAV","SELECTOR_VISIBLE_ITEMS","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","Default","offset","flip","boundary","reference","display","popperConfig","DefaultType","Dropdown","element","config","_element","_popper","_config","_getConfig","_menu","_getMenuElement","_inNavbar","_detectNavbar","_addEventListeners","toggle","disabled","hasClass","isActive","_clearMenus","show","usePopper","relatedTarget","showEvent","Event","parent","_getParentFromElement","trigger","isDefaultPrevented","Popper","TypeError","referenceElement","Util","isElement","jquery","addClass","_getPopperConfig","document","documentElement","closest","length","body","children","on","noop","focus","setAttribute","toggleClass","hide","hideEvent","destroy","dispose","removeData","off","update","scheduleUpdate","event","preventDefault","stopPropagation","constructor","data","typeCheckConfig","querySelector","_getPlacement","$parentDropdown","parentNode","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","_jQueryInterface","each","which","type","toggles","slice","call","querySelectorAll","i","len","context","clickEvent","dropdownMenu","test","target","tagName","contains","removeClass","selector","getSelectorFromElement","_dataApiKeydownHandler","items","filter","item","is","index","indexOf","e","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"dropdown.js","sources":["../src/dropdown.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'dropdown'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\nconst SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\nconst TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\nconst ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\nconst ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\nconst RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPRIGHT = 'dropright'\nconst CLASS_NAME_DROPLEFT = 'dropleft'\nconst CLASS_NAME_MENURIGHT = 'dropdown-menu-right'\nconst CLASS_NAME_POSITION_STATIC = 'position-static'\n\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"dropdown\"]'\nconst SELECTOR_FORM_CHILD = '.dropdown form'\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = 'top-start'\nconst PLACEMENT_TOPEND = 'top-end'\nconst PLACEMENT_BOTTOM = 'bottom-start'\nconst PLACEMENT_BOTTOMEND = 'bottom-end'\nconst PLACEMENT_RIGHT = 'right-start'\nconst PLACEMENT_LEFT = 'left-start'\n\nconst Default = {\n offset: 0,\n flip: true,\n boundary: 'scrollParent',\n reference: 'toggle',\n display: 'dynamic',\n popperConfig: null\n}\n\nconst DefaultType = {\n offset: '(number|string|function)',\n flip: 'boolean',\n boundary: '(string|element)',\n reference: '(string|element)',\n display: 'string',\n popperConfig: '(null|object)'\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n this.show(true)\n }\n\n show(usePopper = false) {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(EVENT_SHOW, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Totally disable Popper for Dropdowns in Navbar\n if (!this._inNavbar && usePopper) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(CLASS_NAME_POSITION_STATIC)\n }\n\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_SHOWN, relatedTarget))\n }\n\n hide() {\n if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n const parent = Dropdown._getParentFromElement(this._element)\n\n $(parent).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n $(this._menu).toggleClass(CLASS_NAME_SHOW)\n $(parent)\n .toggleClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(EVENT_CLICK, event => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n\n if (parent) {\n this._menu = parent.querySelector(SELECTOR_MENU)\n }\n }\n\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = PLACEMENT_BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {\n placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ?\n PLACEMENT_TOPEND :\n PLACEMENT_TOP\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {\n placement = PLACEMENT_RIGHT\n } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {\n placement = PLACEMENT_LEFT\n } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {\n placement = PLACEMENT_BOTTOMEND\n }\n\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this._config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this._config.offset(data.offsets, this._element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this._config.offset\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: this._getOffset(),\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n\n return {\n ...popperConfig,\n ...this._config.popperConfig\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))\n\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(CLASS_NAME_SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(EVENT_HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n if (context._popper) {\n context._popper.destroy()\n }\n\n $(dropdownMenu).removeClass(CLASS_NAME_SHOW)\n $(parent)\n .removeClass(CLASS_NAME_SHOW)\n .trigger($.Event(EVENT_HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName) ?\n event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(CLASS_NAME_SHOW)\n\n if (!isActive && event.which === ESCAPE_KEYCODE) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (!isActive || (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))\n .filter(item => $(item).is(':visible'))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)\n .on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => {\n e.stopPropagation()\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Dropdown._jQueryInterface\n$.fn[NAME].Constructor = Dropdown\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n}\n\nexport default Dropdown\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","ESCAPE_KEYCODE","SPACE_KEYCODE","TAB_KEYCODE","ARROW_UP_KEYCODE","ARROW_DOWN_KEYCODE","RIGHT_MOUSE_BUTTON_WHICH","REGEXP_KEYDOWN","RegExp","EVENT_HIDE","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","EVENT_CLICK","EVENT_CLICK_DATA_API","EVENT_KEYDOWN_DATA_API","EVENT_KEYUP_DATA_API","CLASS_NAME_DISABLED","CLASS_NAME_SHOW","CLASS_NAME_DROPUP","CLASS_NAME_DROPRIGHT","CLASS_NAME_DROPLEFT","CLASS_NAME_MENURIGHT","CLASS_NAME_POSITION_STATIC","SELECTOR_DATA_TOGGLE","SELECTOR_FORM_CHILD","SELECTOR_MENU","SELECTOR_NAVBAR_NAV","SELECTOR_VISIBLE_ITEMS","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","Default","offset","flip","boundary","reference","display","popperConfig","DefaultType","Dropdown","element","config","_element","_popper","_config","_getConfig","_menu","_getMenuElement","_inNavbar","_detectNavbar","_addEventListeners","toggle","disabled","hasClass","isActive","_clearMenus","show","usePopper","relatedTarget","showEvent","Event","parent","_getParentFromElement","trigger","isDefaultPrevented","Popper","TypeError","referenceElement","Util","isElement","jquery","addClass","_getPopperConfig","document","documentElement","closest","length","body","children","on","noop","focus","setAttribute","toggleClass","hide","hideEvent","destroy","dispose","removeData","off","update","scheduleUpdate","event","preventDefault","stopPropagation","constructor","data","typeCheckConfig","querySelector","_getPlacement","$parentDropdown","parentNode","placement","_getOffset","offsets","modifiers","enabled","preventOverflow","boundariesElement","applyStyle","_jQueryInterface","each","which","type","toggles","slice","call","querySelectorAll","i","len","context","clickEvent","dropdownMenu","test","target","tagName","contains","removeClass","selector","getSelectorFromElement","_dataApiKeydownHandler","items","filter","item","is","index","indexOf","e","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/index.js b/vendor/twbs/bootstrap/js/dist/index.js index d209db97b..5f219ec1a 100644 --- a/vendor/twbs/bootstrap/js/dist/index.js +++ b/vendor/twbs/bootstrap/js/dist/index.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): index.js + * Bootstrap (v4.6.0): index.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ diff --git a/vendor/twbs/bootstrap/js/dist/modal.js b/vendor/twbs/bootstrap/js/dist/modal.js index 92a9c77b6..f3738fbd7 100644 --- a/vendor/twbs/bootstrap/js/dist/modal.js +++ b/vendor/twbs/bootstrap/js/dist/modal.js @@ -1,11 +1,11 @@ /*! - * Bootstrap modal.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap modal.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Modal = factory(global.jQuery, global.Util)); }(this, (function ($, Util) { 'use strict'; @@ -14,11 +14,40 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + return _extends.apply(this, arguments); + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -26,7 +55,7 @@ */ var NAME = 'modal'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.modal'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -226,38 +255,34 @@ _proto._triggerBackdropTransition = function _triggerBackdropTransition() { var _this3 = this; - if (this._config.backdrop === 'static') { - var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED); - $__default['default'](this._element).trigger(hideEventPrevented); + var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED); + $__default['default'](this._element).trigger(hideEventPrevented); - if (hideEventPrevented.isDefaultPrevented()) { - return; - } + if (hideEventPrevented.isDefaultPrevented()) { + return; + } - var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; - if (!isModalOverflowing) { - this._element.style.overflowY = 'hidden'; - } + if (!isModalOverflowing) { + this._element.style.overflowY = 'hidden'; + } - this._element.classList.add(CLASS_NAME_STATIC); + this._element.classList.add(CLASS_NAME_STATIC); - var modalTransitionDuration = Util__default['default'].getTransitionDurationFromElement(this._dialog); - $__default['default'](this._element).off(Util__default['default'].TRANSITION_END); - $__default['default'](this._element).one(Util__default['default'].TRANSITION_END, function () { - _this3._element.classList.remove(CLASS_NAME_STATIC); + var modalTransitionDuration = Util__default['default'].getTransitionDurationFromElement(this._dialog); + $__default['default'](this._element).off(Util__default['default'].TRANSITION_END); + $__default['default'](this._element).one(Util__default['default'].TRANSITION_END, function () { + _this3._element.classList.remove(CLASS_NAME_STATIC); - if (!isModalOverflowing) { - $__default['default'](_this3._element).one(Util__default['default'].TRANSITION_END, function () { - _this3._element.style.overflowY = ''; - }).emulateTransitionEnd(_this3._element, modalTransitionDuration); - } - }).emulateTransitionEnd(modalTransitionDuration); + if (!isModalOverflowing) { + $__default['default'](_this3._element).one(Util__default['default'].TRANSITION_END, function () { + _this3._element.style.overflowY = ''; + }).emulateTransitionEnd(_this3._element, modalTransitionDuration); + } + }).emulateTransitionEnd(modalTransitionDuration); - this._element.focus(); - } else { - this.hide(); - } + this._element.focus(); }; _proto._showElement = function _showElement(relatedTarget) { @@ -412,7 +437,11 @@ return; } - _this9._triggerBackdropTransition(); + if (_this9._config.backdrop === 'static') { + _this9._triggerBackdropTransition(); + } else { + _this9.hide(); + } }); if (animate) { diff --git a/vendor/twbs/bootstrap/js/dist/modal.js.map b/vendor/twbs/bootstrap/js/dist/modal.js.map index 5c13b2e88..db9bc20cf 100644 --- a/vendor/twbs/bootstrap/js/dist/modal.js.map +++ b/vendor/twbs/bootstrap/js/dist/modal.js.map @@ -1 +1 @@ -{"version":3,"file":"modal.js","sources":["../src/modal.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n if (this._config.backdrop === 'static') {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n } else {\n this.hide()\n }\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","ESCAPE_KEYCODE","Default","backdrop","keyboard","focus","show","DefaultType","EVENT_HIDE","EVENT_HIDE_PREVENTED","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","EVENT_FOCUSIN","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_KEYDOWN_DISMISS","EVENT_MOUSEUP_DISMISS","EVENT_MOUSEDOWN_DISMISS","EVENT_CLICK_DATA_API","CLASS_NAME_SCROLLABLE","CLASS_NAME_SCROLLBAR_MEASURER","CLASS_NAME_BACKDROP","CLASS_NAME_OPEN","CLASS_NAME_FADE","CLASS_NAME_SHOW","CLASS_NAME_STATIC","SELECTOR_DIALOG","SELECTOR_MODAL_BODY","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_DISMISS","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","Modal","element","config","_config","_getConfig","_element","_dialog","querySelector","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_isTransitioning","_scrollbarWidth","toggle","relatedTarget","hide","hasClass","showEvent","Event","trigger","isDefaultPrevented","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","on","event","one","target","is","_showBackdrop","_showElement","preventDefault","hideEvent","transition","document","off","removeClass","transitionDuration","Util","getTransitionDurationFromElement","TRANSITION_END","_hideModal","emulateTransitionEnd","dispose","window","forEach","htmlElement","removeData","handleUpdate","typeCheckConfig","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","documentElement","clientHeight","style","overflowY","classList","add","modalTransitionDuration","remove","modalBody","parentNode","nodeType","Node","ELEMENT_NODE","body","appendChild","display","removeAttribute","setAttribute","scrollTop","reflow","addClass","_enforceFocus","shownEvent","transitionComplete","has","length","which","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","animate","createElement","className","appendTo","currentTarget","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","getBoundingClientRect","Math","round","left","right","innerWidth","_getScrollbarWidth","fixedContent","slice","call","querySelectorAll","stickyContent","each","index","actualPadding","calculatedPadding","css","data","parseFloat","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","_jQueryInterface","TypeError","selector","getSelectorFromElement","tagName","$target","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"modal.js","sources":["../src/modal.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'modal'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n focus: true,\n show: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n focus: 'boolean',\n show: 'boolean'\n}\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'\nconst CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'\nconst CLASS_NAME_BACKDROP = 'modal-backdrop'\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"modal\"]'\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"modal\"]'\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(SELECTOR_DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._isTransitioning = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n EVENT_CLICK_DISMISS,\n SELECTOR_DATA_DISMISS,\n event => this.hide(event)\n )\n\n $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {\n $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(EVENT_FOCUSIN)\n\n $(this._element).removeClass(CLASS_NAME_SHOW)\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, event => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n [window, this._element, this._dialog]\n .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))\n\n /**\n * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`\n * Do not move `document` in `htmlElements` array\n * It will remove `EVENT_CLICK_DATA_API` event that should remain\n */\n $(document).off(EVENT_FOCUSIN)\n\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._isTransitioning = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _triggerBackdropTransition() {\n const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)\n\n $(this._element).trigger(hideEventPrevented)\n if (hideEventPrevented.isDefaultPrevented()) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n\n const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n $(this._element).off(Util.TRANSITION_END)\n\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n if (!isModalOverflowing) {\n $(this._element).one(Util.TRANSITION_END, () => {\n this._element.style.overflowY = ''\n })\n .emulateTransitionEnd(this._element, modalTransitionDuration)\n }\n })\n .emulateTransitionEnd(modalTransitionDuration)\n this._element.focus()\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(CLASS_NAME_FADE)\n const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n\n if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {\n modalBody.scrollTop = 0\n } else {\n this._element.scrollTop = 0\n }\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(CLASS_NAME_SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(EVENT_FOCUSIN) // Guard against infinite focus loop\n .on(EVENT_FOCUSIN, event => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown) {\n $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {\n if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {\n this._triggerBackdropTransition()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(EVENT_KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))\n } else {\n $(window).off(EVENT_RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(EVENT_HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?\n CLASS_NAME_FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = CLASS_NAME_BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(EVENT_CLICK_DISMISS, event => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n\n if (event.target !== event.currentTarget) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(CLASS_NAME_SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(CLASS_NAME_SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(CLASS_NAME_FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n\n $(document.body).addClass(CLASS_NAME_OPEN)\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY) ?\n 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(EVENT_SHOW, showEvent => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(EVENT_HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Modal._jQueryInterface\n$.fn[NAME].Constructor = Modal\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n}\n\nexport default Modal\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","ESCAPE_KEYCODE","Default","backdrop","keyboard","focus","show","DefaultType","EVENT_HIDE","EVENT_HIDE_PREVENTED","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","EVENT_FOCUSIN","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_KEYDOWN_DISMISS","EVENT_MOUSEUP_DISMISS","EVENT_MOUSEDOWN_DISMISS","EVENT_CLICK_DATA_API","CLASS_NAME_SCROLLABLE","CLASS_NAME_SCROLLBAR_MEASURER","CLASS_NAME_BACKDROP","CLASS_NAME_OPEN","CLASS_NAME_FADE","CLASS_NAME_SHOW","CLASS_NAME_STATIC","SELECTOR_DIALOG","SELECTOR_MODAL_BODY","SELECTOR_DATA_TOGGLE","SELECTOR_DATA_DISMISS","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","Modal","element","config","_config","_getConfig","_element","_dialog","querySelector","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_isTransitioning","_scrollbarWidth","toggle","relatedTarget","hide","hasClass","showEvent","Event","trigger","isDefaultPrevented","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","on","event","one","target","is","_showBackdrop","_showElement","preventDefault","hideEvent","transition","document","off","removeClass","transitionDuration","Util","getTransitionDurationFromElement","TRANSITION_END","_hideModal","emulateTransitionEnd","dispose","window","forEach","htmlElement","removeData","handleUpdate","typeCheckConfig","_triggerBackdropTransition","hideEventPrevented","isModalOverflowing","scrollHeight","documentElement","clientHeight","style","overflowY","classList","add","modalTransitionDuration","remove","modalBody","parentNode","nodeType","Node","ELEMENT_NODE","body","appendChild","display","removeAttribute","setAttribute","scrollTop","reflow","addClass","_enforceFocus","shownEvent","transitionComplete","has","length","which","_resetAdjustments","_resetScrollbar","_removeBackdrop","callback","animate","createElement","className","appendTo","currentTarget","backdropTransitionDuration","callbackRemove","paddingLeft","paddingRight","rect","getBoundingClientRect","Math","round","left","right","innerWidth","_getScrollbarWidth","fixedContent","slice","call","querySelectorAll","stickyContent","each","index","actualPadding","calculatedPadding","css","data","parseFloat","actualMargin","marginRight","calculatedMargin","padding","elements","margin","scrollDiv","scrollbarWidth","width","clientWidth","removeChild","_jQueryInterface","TypeError","selector","getSelectorFromElement","tagName","$target","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/popover.js b/vendor/twbs/bootstrap/js/dist/popover.js index 00f3b9120..04cc5df73 100644 --- a/vendor/twbs/bootstrap/js/dist/popover.js +++ b/vendor/twbs/bootstrap/js/dist/popover.js @@ -1,11 +1,11 @@ /*! - * Bootstrap popover.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap popover.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./tooltip.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './tooltip.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './tooltip'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Popover = factory(global.jQuery, global.Tooltip)); }(this, (function ($, Tooltip) { 'use strict'; @@ -14,13 +14,46 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Tooltip__default = /*#__PURE__*/_interopDefaultLegacy(Tooltip); - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + return _extends.apply(this, arguments); + } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; + } - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /** * ------------------------------------------------------------------------ * Constants @@ -28,7 +61,7 @@ */ var NAME = 'popover'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.popover'; var EVENT_KEY = "." + DATA_KEY; var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME]; diff --git a/vendor/twbs/bootstrap/js/dist/popover.js.map b/vendor/twbs/bootstrap/js/dist/popover.js.map index c0309af7a..b976d52ed 100644 --- a/vendor/twbs/bootstrap/js/dist/popover.js.map +++ b/vendor/twbs/bootstrap/js/dist/popover.js.map @@ -1 +1 @@ -{"version":3,"file":"popover.js","sources":["../src/popover.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","$","fn","CLASS_PREFIX","BSCLS_PREFIX_REGEX","RegExp","Default","Tooltip","placement","trigger","content","template","DefaultType","CLASS_NAME_FADE","CLASS_NAME_SHOW","SELECTOR_TITLE","SELECTOR_CONTENT","Event","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","Popover","isWithContent","getTitle","_getContent","addAttachmentClass","attachment","getTipElement","addClass","tip","config","setContent","$tip","setElementContent","find","call","element","removeClass","getAttribute","_cleanTipClass","tabClass","attr","match","length","join","_jQueryInterface","each","data","_config","test","TypeError","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"popover.js","sources":["../src/popover.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'popover'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.popover'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-popover'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\nconst Default = {\n ...Tooltip.Default,\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(string|element|function)'\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n\n this.setElementContent($tip.find(SELECTOR_CONTENT), content)\n\n $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Popover._jQueryInterface\n$.fn[NAME].Constructor = Popover\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n}\n\nexport default Popover\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","$","fn","CLASS_PREFIX","BSCLS_PREFIX_REGEX","RegExp","Default","Tooltip","placement","trigger","content","template","DefaultType","CLASS_NAME_FADE","CLASS_NAME_SHOW","SELECTOR_TITLE","SELECTOR_CONTENT","Event","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","Popover","isWithContent","getTitle","_getContent","addAttachmentClass","attachment","getTipElement","addClass","tip","config","setContent","$tip","setElementContent","find","call","element","removeClass","getAttribute","_cleanTipClass","tabClass","attr","match","length","join","_jQueryInterface","each","data","_config","test","TypeError","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/scrollspy.js b/vendor/twbs/bootstrap/js/dist/scrollspy.js index 366519656..9503a9589 100644 --- a/vendor/twbs/bootstrap/js/dist/scrollspy.js +++ b/vendor/twbs/bootstrap/js/dist/scrollspy.js @@ -1,11 +1,11 @@ /*! - * Bootstrap scrollspy.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap scrollspy.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ScrollSpy = factory(global.jQuery, global.Util)); }(this, (function ($, Util) { 'use strict'; @@ -14,11 +14,40 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + return _extends.apply(this, arguments); + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -26,7 +55,7 @@ */ var NAME = 'scrollspy'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.scrollspy'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; diff --git a/vendor/twbs/bootstrap/js/dist/scrollspy.js.map b/vendor/twbs/bootstrap/js/dist/scrollspy.js.map index 0281b63d5..5fe94b368 100644 --- a/vendor/twbs/bootstrap/js/dist/scrollspy.js.map +++ b/vendor/twbs/bootstrap/js/dist/scrollspy.js.map @@ -1 +1 @@ -{"version":3,"file":"scrollspy.js","sources":["../src/scrollspy.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","Default","offset","method","target","DefaultType","EVENT_ACTIVATE","EVENT_SCROLL","EVENT_LOAD_DATA_API","CLASS_NAME_DROPDOWN_ITEM","CLASS_NAME_ACTIVE","SELECTOR_DATA_SPY","SELECTOR_NAV_LIST_GROUP","SELECTOR_NAV_LINKS","SELECTOR_NAV_ITEMS","SELECTOR_LIST_ITEMS","SELECTOR_DROPDOWN","SELECTOR_DROPDOWN_ITEMS","SELECTOR_DROPDOWN_TOGGLE","METHOD_OFFSET","METHOD_POSITION","ScrollSpy","element","config","_element","_scrollElement","tagName","window","_config","_getConfig","_selector","_offsets","_targets","_activeTarget","_scrollHeight","on","event","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targets","slice","call","document","querySelectorAll","map","targetSelector","Util","getSelectorFromElement","querySelector","targetBCR","getBoundingClientRect","width","height","top","filter","item","sort","a","b","forEach","push","dispose","removeData","off","isElement","id","attr","getUID","typeCheckConfig","pageYOffset","scrollTop","scrollHeight","Math","max","body","documentElement","_getOffsetHeight","innerHeight","maxScroll","length","_activate","_clear","i","isActiveTarget","queries","split","selector","$link","join","hasClass","closest","find","addClass","parents","prev","children","trigger","relatedTarget","node","classList","contains","remove","_jQueryInterface","each","data","TypeError","scrollSpys","scrollSpysLength","$spy","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"scrollspy.js","sources":["../src/scrollspy.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'scrollspy'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst Default = {\n offset: 10,\n method: 'auto',\n target: ''\n}\n\nconst DefaultType = {\n offset: 'number',\n method: 'string',\n target: '(string|element)'\n}\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_SCROLL = `scroll${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-spy=\"scroll\"]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst METHOD_OFFSET = 'offset'\nconst METHOD_POSITION = 'position'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +\n `${this._config.target} ${SELECTOR_LIST_ITEMS},` +\n `${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(EVENT_SCROLL, event => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window ?\n METHOD_OFFSET : METHOD_POSITION\n\n const offsetMethod = this._config.method === 'auto' ?\n autoMethod : this._config.method\n\n const offsetBase = offsetMethod === METHOD_POSITION ?\n this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map(element => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n\n return null\n })\n .filter(item => item)\n .sort((a, b) => a[0] - b[0])\n .forEach(item => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.target !== 'string' && Util.isElement(config.target)) {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window ?\n this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window ?\n window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n const queries = this._selector\n .split(',')\n .map(selector => `${selector}[data-target=\"${target}\"],${selector}[href=\"${target}\"]`)\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {\n $link.closest(SELECTOR_DROPDOWN)\n .find(SELECTOR_DROPDOWN_TOGGLE)\n .addClass(CLASS_NAME_ACTIVE)\n $link.addClass(CLASS_NAME_ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(CLASS_NAME_ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)\n .addClass(CLASS_NAME_ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(SELECTOR_NAV_LIST_GROUP)\n .prev(SELECTOR_NAV_ITEMS)\n .children(SELECTOR_NAV_LINKS)\n .addClass(CLASS_NAME_ACTIVE)\n }\n\n $(this._scrollElement).trigger(EVENT_ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n [].slice.call(document.querySelectorAll(this._selector))\n .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))\n .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(window).on(EVENT_LOAD_DATA_API, () => {\n const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))\n const scrollSpysLength = scrollSpys.length\n\n for (let i = scrollSpysLength; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n})\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = ScrollSpy._jQueryInterface\n$.fn[NAME].Constructor = ScrollSpy\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n}\n\nexport default ScrollSpy\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","Default","offset","method","target","DefaultType","EVENT_ACTIVATE","EVENT_SCROLL","EVENT_LOAD_DATA_API","CLASS_NAME_DROPDOWN_ITEM","CLASS_NAME_ACTIVE","SELECTOR_DATA_SPY","SELECTOR_NAV_LIST_GROUP","SELECTOR_NAV_LINKS","SELECTOR_NAV_ITEMS","SELECTOR_LIST_ITEMS","SELECTOR_DROPDOWN","SELECTOR_DROPDOWN_ITEMS","SELECTOR_DROPDOWN_TOGGLE","METHOD_OFFSET","METHOD_POSITION","ScrollSpy","element","config","_element","_scrollElement","tagName","window","_config","_getConfig","_selector","_offsets","_targets","_activeTarget","_scrollHeight","on","event","_process","refresh","autoMethod","offsetMethod","offsetBase","_getScrollTop","_getScrollHeight","targets","slice","call","document","querySelectorAll","map","targetSelector","Util","getSelectorFromElement","querySelector","targetBCR","getBoundingClientRect","width","height","top","filter","item","sort","a","b","forEach","push","dispose","removeData","off","isElement","id","attr","getUID","typeCheckConfig","pageYOffset","scrollTop","scrollHeight","Math","max","body","documentElement","_getOffsetHeight","innerHeight","maxScroll","length","_activate","_clear","i","isActiveTarget","queries","split","selector","$link","join","hasClass","closest","find","addClass","parents","prev","children","trigger","relatedTarget","node","classList","contains","remove","_jQueryInterface","each","data","TypeError","scrollSpys","scrollSpysLength","$spy","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/tab.js b/vendor/twbs/bootstrap/js/dist/tab.js index 84d6169bd..757761d33 100644 --- a/vendor/twbs/bootstrap/js/dist/tab.js +++ b/vendor/twbs/bootstrap/js/dist/tab.js @@ -1,11 +1,11 @@ /*! - * Bootstrap tab.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap tab.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tab = factory(global.jQuery, global.Util)); }(this, (function ($, Util) { 'use strict'; @@ -14,9 +14,22 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -24,7 +37,7 @@ */ var NAME = 'tab'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.tab'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; diff --git a/vendor/twbs/bootstrap/js/dist/tab.js.map b/vendor/twbs/bootstrap/js/dist/tab.js.map index 2890e9765..58a93c71b 100644 --- a/vendor/twbs/bootstrap/js/dist/tab.js.map +++ b/vendor/twbs/bootstrap/js/dist/tab.js.map @@ -1 +1 @@ -{"version":3,"file":"tab.js","sources":["../src/tab.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","EVENT_HIDE","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","EVENT_CLICK_DATA_API","CLASS_NAME_DROPDOWN_MENU","CLASS_NAME_ACTIVE","CLASS_NAME_DISABLED","CLASS_NAME_FADE","CLASS_NAME_SHOW","SELECTOR_DROPDOWN","SELECTOR_NAV_LIST_GROUP","SELECTOR_ACTIVE","SELECTOR_ACTIVE_UL","SELECTOR_DATA_TOGGLE","SELECTOR_DROPDOWN_TOGGLE","SELECTOR_DROPDOWN_ACTIVE_CHILD","Tab","element","_element","show","parentNode","nodeType","Node","ELEMENT_NODE","hasClass","target","previous","listElement","closest","selector","Util","getSelectorFromElement","itemSelector","nodeName","makeArray","find","length","hideEvent","Event","relatedTarget","showEvent","trigger","isDefaultPrevented","document","querySelector","_activate","complete","hiddenEvent","shownEvent","dispose","removeData","container","callback","activeElements","children","active","isTransitioning","_transitionComplete","transitionDuration","getTransitionDurationFromElement","removeClass","one","TRANSITION_END","emulateTransitionEnd","dropdownChild","getAttribute","setAttribute","addClass","reflow","classList","contains","add","dropdownElement","dropdownToggleList","slice","call","querySelectorAll","_jQueryInterface","config","each","$this","data","TypeError","on","event","preventDefault","Constructor","noConflict"],"mappings":";;;;;;;;;;;;;;;;;;;EAUA;;;;;;EAMA,IAAMA,IAAI,GAAG,KAAb;EACA,IAAMC,OAAO,GAAG,OAAhB;EACA,IAAMC,QAAQ,GAAG,QAAjB;EACA,IAAMC,SAAS,SAAOD,QAAtB;EACA,IAAME,YAAY,GAAG,WAArB;EACA,IAAMC,kBAAkB,GAAGC,qBAAC,CAACC,EAAF,CAAKP,IAAL,CAA3B;EAEA,IAAMQ,UAAU,YAAUL,SAA1B;EACA,IAAMM,YAAY,cAAYN,SAA9B;EACA,IAAMO,UAAU,YAAUP,SAA1B;EACA,IAAMQ,WAAW,aAAWR,SAA5B;EACA,IAAMS,oBAAoB,aAAWT,SAAX,GAAuBC,YAAjD;EAEA,IAAMS,wBAAwB,GAAG,eAAjC;EACA,IAAMC,iBAAiB,GAAG,QAA1B;EACA,IAAMC,mBAAmB,GAAG,UAA5B;EACA,IAAMC,eAAe,GAAG,MAAxB;EACA,IAAMC,eAAe,GAAG,MAAxB;EAEA,IAAMC,iBAAiB,GAAG,WAA1B;EACA,IAAMC,uBAAuB,GAAG,mBAAhC;EACA,IAAMC,eAAe,GAAG,SAAxB;EACA,IAAMC,kBAAkB,GAAG,gBAA3B;EACA,IAAMC,oBAAoB,GAAG,iEAA7B;EACA,IAAMC,wBAAwB,GAAG,kBAAjC;EACA,IAAMC,8BAA8B,GAAG,0BAAvC;EAEA;;;;;;MAMMC;EACJ,eAAYC,OAAZ,EAAqB;EACnB,SAAKC,QAAL,GAAgBD,OAAhB;EACD;;;;;EAQD;WAEAE,OAAA,gBAAO;EAAA;;EACL,QAAI,KAAKD,QAAL,CAAcE,UAAd,IACA,KAAKF,QAAL,CAAcE,UAAd,CAAyBC,QAAzB,KAAsCC,IAAI,CAACC,YAD3C,IAEA1B,qBAAC,CAAC,KAAKqB,QAAN,CAAD,CAAiBM,QAAjB,CAA0BnB,iBAA1B,CAFA,IAGAR,qBAAC,CAAC,KAAKqB,QAAN,CAAD,CAAiBM,QAAjB,CAA0BlB,mBAA1B,CAHJ,EAGoD;EAClD;EACD;;EAED,QAAImB,MAAJ;EACA,QAAIC,QAAJ;EACA,QAAMC,WAAW,GAAG9B,qBAAC,CAAC,KAAKqB,QAAN,CAAD,CAAiBU,OAAjB,CAAyBlB,uBAAzB,EAAkD,CAAlD,CAApB;EACA,QAAMmB,QAAQ,GAAGC,wBAAI,CAACC,sBAAL,CAA4B,KAAKb,QAAjC,CAAjB;;EAEA,QAAIS,WAAJ,EAAiB;EACf,UAAMK,YAAY,GAAGL,WAAW,CAACM,QAAZ,KAAyB,IAAzB,IAAiCN,WAAW,CAACM,QAAZ,KAAyB,IAA1D,GAAiErB,kBAAjE,GAAsFD,eAA3G;EACAe,MAAAA,QAAQ,GAAG7B,qBAAC,CAACqC,SAAF,CAAYrC,qBAAC,CAAC8B,WAAD,CAAD,CAAeQ,IAAf,CAAoBH,YAApB,CAAZ,CAAX;EACAN,MAAAA,QAAQ,GAAGA,QAAQ,CAACA,QAAQ,CAACU,MAAT,GAAkB,CAAnB,CAAnB;EACD;;EAED,QAAMC,SAAS,GAAGxC,qBAAC,CAACyC,KAAF,CAAQvC,UAAR,EAAoB;EACpCwC,MAAAA,aAAa,EAAE,KAAKrB;EADgB,KAApB,CAAlB;EAIA,QAAMsB,SAAS,GAAG3C,qBAAC,CAACyC,KAAF,CAAQrC,UAAR,EAAoB;EACpCsC,MAAAA,aAAa,EAAEb;EADqB,KAApB,CAAlB;;EAIA,QAAIA,QAAJ,EAAc;EACZ7B,MAAAA,qBAAC,CAAC6B,QAAD,CAAD,CAAYe,OAAZ,CAAoBJ,SAApB;EACD;;EAEDxC,IAAAA,qBAAC,CAAC,KAAKqB,QAAN,CAAD,CAAiBuB,OAAjB,CAAyBD,SAAzB;;EAEA,QAAIA,SAAS,CAACE,kBAAV,MACAL,SAAS,CAACK,kBAAV,EADJ,EACoC;EAClC;EACD;;EAED,QAAIb,QAAJ,EAAc;EACZJ,MAAAA,MAAM,GAAGkB,QAAQ,CAACC,aAAT,CAAuBf,QAAvB,CAAT;EACD;;EAED,SAAKgB,SAAL,CACE,KAAK3B,QADP,EAEES,WAFF;;EAKA,QAAMmB,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,UAAMC,WAAW,GAAGlD,qBAAC,CAACyC,KAAF,CAAQtC,YAAR,EAAsB;EACxCuC,QAAAA,aAAa,EAAE,KAAI,CAACrB;EADoB,OAAtB,CAApB;EAIA,UAAM8B,UAAU,GAAGnD,qBAAC,CAACyC,KAAF,CAAQpC,WAAR,EAAqB;EACtCqC,QAAAA,aAAa,EAAEb;EADuB,OAArB,CAAnB;EAIA7B,MAAAA,qBAAC,CAAC6B,QAAD,CAAD,CAAYe,OAAZ,CAAoBM,WAApB;EACAlD,MAAAA,qBAAC,CAAC,KAAI,CAACqB,QAAN,CAAD,CAAiBuB,OAAjB,CAAyBO,UAAzB;EACD,KAXD;;EAaA,QAAIvB,MAAJ,EAAY;EACV,WAAKoB,SAAL,CAAepB,MAAf,EAAuBA,MAAM,CAACL,UAA9B,EAA0C0B,QAA1C;EACD,KAFD,MAEO;EACLA,MAAAA,QAAQ;EACT;EACF;;WAEDG,UAAA,mBAAU;EACRpD,IAAAA,qBAAC,CAACqD,UAAF,CAAa,KAAKhC,QAAlB,EAA4BzB,QAA5B;EACA,SAAKyB,QAAL,GAAgB,IAAhB;EACD;;;WAID2B,YAAA,mBAAU5B,OAAV,EAAmBkC,SAAnB,EAA8BC,QAA9B,EAAwC;EAAA;;EACtC,QAAMC,cAAc,GAAGF,SAAS,KAAKA,SAAS,CAAClB,QAAV,KAAuB,IAAvB,IAA+BkB,SAAS,CAAClB,QAAV,KAAuB,IAA3D,CAAT,GACrBpC,qBAAC,CAACsD,SAAD,CAAD,CAAahB,IAAb,CAAkBvB,kBAAlB,CADqB,GAErBf,qBAAC,CAACsD,SAAD,CAAD,CAAaG,QAAb,CAAsB3C,eAAtB,CAFF;EAIA,QAAM4C,MAAM,GAAGF,cAAc,CAAC,CAAD,CAA7B;EACA,QAAMG,eAAe,GAAGJ,QAAQ,IAAKG,MAAM,IAAI1D,qBAAC,CAAC0D,MAAD,CAAD,CAAU/B,QAAV,CAAmBjB,eAAnB,CAA/C;;EACA,QAAMuC,QAAQ,GAAG,SAAXA,QAAW;EAAA,aAAM,MAAI,CAACW,mBAAL,CACrBxC,OADqB,EAErBsC,MAFqB,EAGrBH,QAHqB,CAAN;EAAA,KAAjB;;EAMA,QAAIG,MAAM,IAAIC,eAAd,EAA+B;EAC7B,UAAME,kBAAkB,GAAG5B,wBAAI,CAAC6B,gCAAL,CAAsCJ,MAAtC,CAA3B;EAEA1D,MAAAA,qBAAC,CAAC0D,MAAD,CAAD,CACGK,WADH,CACepD,eADf,EAEGqD,GAFH,CAEO/B,wBAAI,CAACgC,cAFZ,EAE4BhB,QAF5B,EAGGiB,oBAHH,CAGwBL,kBAHxB;EAID,KAPD,MAOO;EACLZ,MAAAA,QAAQ;EACT;EACF;;WAEDW,sBAAA,6BAAoBxC,OAApB,EAA6BsC,MAA7B,EAAqCH,QAArC,EAA+C;EAC7C,QAAIG,MAAJ,EAAY;EACV1D,MAAAA,qBAAC,CAAC0D,MAAD,CAAD,CAAUK,WAAV,CAAsBvD,iBAAtB;EAEA,UAAM2D,aAAa,GAAGnE,qBAAC,CAAC0D,MAAM,CAACnC,UAAR,CAAD,CAAqBe,IAArB,CACpBpB,8BADoB,EAEpB,CAFoB,CAAtB;;EAIA,UAAIiD,aAAJ,EAAmB;EACjBnE,QAAAA,qBAAC,CAACmE,aAAD,CAAD,CAAiBJ,WAAjB,CAA6BvD,iBAA7B;EACD;;EAED,UAAIkD,MAAM,CAACU,YAAP,CAAoB,MAApB,MAAgC,KAApC,EAA2C;EACzCV,QAAAA,MAAM,CAACW,YAAP,CAAoB,eAApB,EAAqC,KAArC;EACD;EACF;;EAEDrE,IAAAA,qBAAC,CAACoB,OAAD,CAAD,CAAWkD,QAAX,CAAoB9D,iBAApB;;EACA,QAAIY,OAAO,CAACgD,YAAR,CAAqB,MAArB,MAAiC,KAArC,EAA4C;EAC1ChD,MAAAA,OAAO,CAACiD,YAAR,CAAqB,eAArB,EAAsC,IAAtC;EACD;;EAEDpC,IAAAA,wBAAI,CAACsC,MAAL,CAAYnD,OAAZ;;EAEA,QAAIA,OAAO,CAACoD,SAAR,CAAkBC,QAAlB,CAA2B/D,eAA3B,CAAJ,EAAiD;EAC/CU,MAAAA,OAAO,CAACoD,SAAR,CAAkBE,GAAlB,CAAsB/D,eAAtB;EACD;;EAED,QAAIS,OAAO,CAACG,UAAR,IAAsBvB,qBAAC,CAACoB,OAAO,CAACG,UAAT,CAAD,CAAsBI,QAAtB,CAA+BpB,wBAA/B,CAA1B,EAAoF;EAClF,UAAMoE,eAAe,GAAG3E,qBAAC,CAACoB,OAAD,CAAD,CAAWW,OAAX,CAAmBnB,iBAAnB,EAAsC,CAAtC,CAAxB;;EAEA,UAAI+D,eAAJ,EAAqB;EACnB,YAAMC,kBAAkB,GAAG,GAAGC,KAAH,CAASC,IAAT,CAAcH,eAAe,CAACI,gBAAhB,CAAiC9D,wBAAjC,CAAd,CAA3B;EAEAjB,QAAAA,qBAAC,CAAC4E,kBAAD,CAAD,CAAsBN,QAAtB,CAA+B9D,iBAA/B;EACD;;EAEDY,MAAAA,OAAO,CAACiD,YAAR,CAAqB,eAArB,EAAsC,IAAtC;EACD;;EAED,QAAId,QAAJ,EAAc;EACZA,MAAAA,QAAQ;EACT;EACF;;;QAIMyB,mBAAP,0BAAwBC,MAAxB,EAAgC;EAC9B,WAAO,KAAKC,IAAL,CAAU,YAAY;EAC3B,UAAMC,KAAK,GAAGnF,qBAAC,CAAC,IAAD,CAAf;EACA,UAAIoF,IAAI,GAAGD,KAAK,CAACC,IAAN,CAAWxF,QAAX,CAAX;;EAEA,UAAI,CAACwF,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAIjE,GAAJ,CAAQ,IAAR,CAAP;EACAgE,QAAAA,KAAK,CAACC,IAAN,CAAWxF,QAAX,EAAqBwF,IAArB;EACD;;EAED,UAAI,OAAOH,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAOG,IAAI,CAACH,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAII,SAAJ,wBAAkCJ,MAAlC,QAAN;EACD;;EAEDG,QAAAA,IAAI,CAACH,MAAD,CAAJ;EACD;EACF,KAhBM,CAAP;EAiBD;;;;0BA1KoB;EACnB,aAAOtF,OAAP;EACD;;;;;EA2KH;;;;;;;AAMAK,uBAAC,CAAC8C,QAAD,CAAD,CACGwC,EADH,CACMhF,oBADN,EAC4BU,oBAD5B,EACkD,UAAUuE,KAAV,EAAiB;EAC/DA,EAAAA,KAAK,CAACC,cAAN;;EACArE,EAAAA,GAAG,CAAC6D,gBAAJ,CAAqBF,IAArB,CAA0B9E,qBAAC,CAAC,IAAD,CAA3B,EAAmC,MAAnC;EACD,CAJH;EAMA;;;;;;AAMAA,uBAAC,CAACC,EAAF,CAAKP,IAAL,IAAayB,GAAG,CAAC6D,gBAAjB;AACAhF,uBAAC,CAACC,EAAF,CAAKP,IAAL,EAAW+F,WAAX,GAAyBtE,GAAzB;;AACAnB,uBAAC,CAACC,EAAF,CAAKP,IAAL,EAAWgG,UAAX,GAAwB,YAAM;EAC5B1F,EAAAA,qBAAC,CAACC,EAAF,CAAKP,IAAL,IAAaK,kBAAb;EACA,SAAOoB,GAAG,CAAC6D,gBAAX;EACD,CAHD;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"tab.js","sources":["../src/tab.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tab'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_DISABLED = 'disabled'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ACTIVE_UL = '> li > .active'\nconst SELECTOR_DATA_TOGGLE = '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(CLASS_NAME_ACTIVE) ||\n $(this._element).hasClass(CLASS_NAME_DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(EVENT_HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(EVENT_SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(EVENT_HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(EVENT_SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?\n $(container).find(SELECTOR_ACTIVE_UL) :\n $(container).children(SELECTOR_ACTIVE)\n\n const active = activeElements[0]\n const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n const transitionDuration = Util.getTransitionDurationFromElement(active)\n\n $(active)\n .removeClass(CLASS_NAME_SHOW)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(CLASS_NAME_ACTIVE)\n\n const dropdownChild = $(active.parentNode).find(\n SELECTOR_DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(CLASS_NAME_ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n\n if (element.classList.contains(CLASS_NAME_FADE)) {\n element.classList.add(CLASS_NAME_SHOW)\n }\n\n if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]\n\n if (dropdownElement) {\n const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))\n\n $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n$(document)\n .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tab._jQueryInterface\n$.fn[NAME].Constructor = Tab\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n}\n\nexport default Tab\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","DATA_API_KEY","JQUERY_NO_CONFLICT","$","fn","EVENT_HIDE","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","EVENT_CLICK_DATA_API","CLASS_NAME_DROPDOWN_MENU","CLASS_NAME_ACTIVE","CLASS_NAME_DISABLED","CLASS_NAME_FADE","CLASS_NAME_SHOW","SELECTOR_DROPDOWN","SELECTOR_NAV_LIST_GROUP","SELECTOR_ACTIVE","SELECTOR_ACTIVE_UL","SELECTOR_DATA_TOGGLE","SELECTOR_DROPDOWN_TOGGLE","SELECTOR_DROPDOWN_ACTIVE_CHILD","Tab","element","_element","show","parentNode","nodeType","Node","ELEMENT_NODE","hasClass","target","previous","listElement","closest","selector","Util","getSelectorFromElement","itemSelector","nodeName","makeArray","find","length","hideEvent","Event","relatedTarget","showEvent","trigger","isDefaultPrevented","document","querySelector","_activate","complete","hiddenEvent","shownEvent","dispose","removeData","container","callback","activeElements","children","active","isTransitioning","_transitionComplete","transitionDuration","getTransitionDurationFromElement","removeClass","one","TRANSITION_END","emulateTransitionEnd","dropdownChild","getAttribute","setAttribute","addClass","reflow","classList","contains","add","dropdownElement","dropdownToggleList","slice","call","querySelectorAll","_jQueryInterface","config","each","$this","data","TypeError","on","event","preventDefault","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/toast.js b/vendor/twbs/bootstrap/js/dist/toast.js index f74f29d46..62694e44b 100644 --- a/vendor/twbs/bootstrap/js/dist/toast.js +++ b/vendor/twbs/bootstrap/js/dist/toast.js @@ -1,11 +1,11 @@ /*! - * Bootstrap toast.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap toast.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Toast = factory(global.jQuery, global.Util)); }(this, (function ($, Util) { 'use strict'; @@ -14,11 +14,40 @@ var $__default = /*#__PURE__*/_interopDefaultLegacy($); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + return _extends.apply(this, arguments); + } - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -26,7 +55,7 @@ */ var NAME = 'toast'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.toast'; var EVENT_KEY = "." + DATA_KEY; var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME]; diff --git a/vendor/twbs/bootstrap/js/dist/toast.js.map b/vendor/twbs/bootstrap/js/dist/toast.js.map index 71675b7c3..eafaad649 100644 --- a/vendor/twbs/bootstrap/js/dist/toast.js.map +++ b/vendor/twbs/bootstrap/js/dist/toast.js.map @@ -1 +1 @@ -{"version":3,"file":"toast.js","sources":["../src/toast.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","$","fn","EVENT_CLICK_DISMISS","EVENT_HIDE","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","CLASS_NAME_FADE","CLASS_NAME_HIDE","CLASS_NAME_SHOW","CLASS_NAME_SHOWING","DefaultType","animation","autohide","delay","Default","SELECTOR_DATA_DISMISS","Toast","element","config","_element","_config","_getConfig","_timeout","_setListeners","show","showEvent","Event","trigger","isDefaultPrevented","_clearTimeout","classList","add","complete","remove","setTimeout","hide","Util","reflow","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","emulateTransitionEnd","contains","hideEvent","_close","dispose","off","removeData","data","typeCheckConfig","constructor","on","clearTimeout","_jQueryInterface","each","$element","TypeError","Constructor","noConflict"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAUA;;;;;;EAMA,IAAMA,IAAI,GAAG,OAAb;EACA,IAAMC,OAAO,GAAG,OAAhB;EACA,IAAMC,QAAQ,GAAG,UAAjB;EACA,IAAMC,SAAS,SAAOD,QAAtB;EACA,IAAME,kBAAkB,GAAGC,qBAAC,CAACC,EAAF,CAAKN,IAAL,CAA3B;EAEA,IAAMO,mBAAmB,qBAAmBJ,SAA5C;EACA,IAAMK,UAAU,YAAUL,SAA1B;EACA,IAAMM,YAAY,cAAYN,SAA9B;EACA,IAAMO,UAAU,YAAUP,SAA1B;EACA,IAAMQ,WAAW,aAAWR,SAA5B;EAEA,IAAMS,eAAe,GAAG,MAAxB;EACA,IAAMC,eAAe,GAAG,MAAxB;EACA,IAAMC,eAAe,GAAG,MAAxB;EACA,IAAMC,kBAAkB,GAAG,SAA3B;EAEA,IAAMC,WAAW,GAAG;EAClBC,EAAAA,SAAS,EAAE,SADO;EAElBC,EAAAA,QAAQ,EAAE,SAFQ;EAGlBC,EAAAA,KAAK,EAAE;EAHW,CAApB;EAMA,IAAMC,OAAO,GAAG;EACdH,EAAAA,SAAS,EAAE,IADG;EAEdC,EAAAA,QAAQ,EAAE,IAFI;EAGdC,EAAAA,KAAK,EAAE;EAHO,CAAhB;EAMA,IAAME,qBAAqB,GAAG,wBAA9B;EAEA;;;;;;MAMMC;EACJ,iBAAYC,OAAZ,EAAqBC,MAArB,EAA6B;EAC3B,SAAKC,QAAL,GAAgBF,OAAhB;EACA,SAAKG,OAAL,GAAe,KAAKC,UAAL,CAAgBH,MAAhB,CAAf;EACA,SAAKI,QAAL,GAAgB,IAAhB;;EACA,SAAKC,aAAL;EACD;;;;;EAgBD;WAEAC,OAAA,gBAAO;EAAA;;EACL,QAAMC,SAAS,GAAG1B,qBAAC,CAAC2B,KAAF,CAAQtB,UAAR,CAAlB;EAEAL,IAAAA,qBAAC,CAAC,KAAKoB,QAAN,CAAD,CAAiBQ,OAAjB,CAAyBF,SAAzB;;EACA,QAAIA,SAAS,CAACG,kBAAV,EAAJ,EAAoC;EAClC;EACD;;EAED,SAAKC,aAAL;;EAEA,QAAI,KAAKT,OAAL,CAAaT,SAAjB,EAA4B;EAC1B,WAAKQ,QAAL,CAAcW,SAAd,CAAwBC,GAAxB,CAA4BzB,eAA5B;EACD;;EAED,QAAM0B,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,MAAA,KAAI,CAACb,QAAL,CAAcW,SAAd,CAAwBG,MAAxB,CAA+BxB,kBAA/B;;EACA,MAAA,KAAI,CAACU,QAAL,CAAcW,SAAd,CAAwBC,GAAxB,CAA4BvB,eAA5B;;EAEAT,MAAAA,qBAAC,CAAC,KAAI,CAACoB,QAAN,CAAD,CAAiBQ,OAAjB,CAAyBtB,WAAzB;;EAEA,UAAI,KAAI,CAACe,OAAL,CAAaR,QAAjB,EAA2B;EACzB,QAAA,KAAI,CAACU,QAAL,GAAgBY,UAAU,CAAC,YAAM;EAC/B,UAAA,KAAI,CAACC,IAAL;EACD,SAFyB,EAEvB,KAAI,CAACf,OAAL,CAAaP,KAFU,CAA1B;EAGD;EACF,KAXD;;EAaA,SAAKM,QAAL,CAAcW,SAAd,CAAwBG,MAAxB,CAA+B1B,eAA/B;;EACA6B,IAAAA,wBAAI,CAACC,MAAL,CAAY,KAAKlB,QAAjB;;EACA,SAAKA,QAAL,CAAcW,SAAd,CAAwBC,GAAxB,CAA4BtB,kBAA5B;;EACA,QAAI,KAAKW,OAAL,CAAaT,SAAjB,EAA4B;EAC1B,UAAM2B,kBAAkB,GAAGF,wBAAI,CAACG,gCAAL,CAAsC,KAAKpB,QAA3C,CAA3B;EAEApB,MAAAA,qBAAC,CAAC,KAAKoB,QAAN,CAAD,CACGqB,GADH,CACOJ,wBAAI,CAACK,cADZ,EAC4BT,QAD5B,EAEGU,oBAFH,CAEwBJ,kBAFxB;EAGD,KAND,MAMO;EACLN,MAAAA,QAAQ;EACT;EACF;;WAEDG,OAAA,gBAAO;EACL,QAAI,CAAC,KAAKhB,QAAL,CAAcW,SAAd,CAAwBa,QAAxB,CAAiCnC,eAAjC,CAAL,EAAwD;EACtD;EACD;;EAED,QAAMoC,SAAS,GAAG7C,qBAAC,CAAC2B,KAAF,CAAQxB,UAAR,CAAlB;EAEAH,IAAAA,qBAAC,CAAC,KAAKoB,QAAN,CAAD,CAAiBQ,OAAjB,CAAyBiB,SAAzB;;EACA,QAAIA,SAAS,CAAChB,kBAAV,EAAJ,EAAoC;EAClC;EACD;;EAED,SAAKiB,MAAL;EACD;;WAEDC,UAAA,mBAAU;EACR,SAAKjB,aAAL;;EAEA,QAAI,KAAKV,QAAL,CAAcW,SAAd,CAAwBa,QAAxB,CAAiCnC,eAAjC,CAAJ,EAAuD;EACrD,WAAKW,QAAL,CAAcW,SAAd,CAAwBG,MAAxB,CAA+BzB,eAA/B;EACD;;EAEDT,IAAAA,qBAAC,CAAC,KAAKoB,QAAN,CAAD,CAAiB4B,GAAjB,CAAqB9C,mBAArB;EAEAF,IAAAA,qBAAC,CAACiD,UAAF,CAAa,KAAK7B,QAAlB,EAA4BvB,QAA5B;EACA,SAAKuB,QAAL,GAAgB,IAAhB;EACA,SAAKC,OAAL,GAAe,IAAf;EACD;;;WAIDC,aAAA,oBAAWH,MAAX,EAAmB;EACjBA,IAAAA,MAAM,gBACDJ,OADC,EAEDf,qBAAC,CAAC,KAAKoB,QAAN,CAAD,CAAiB8B,IAAjB,EAFC,EAGA,OAAO/B,MAAP,KAAkB,QAAlB,IAA8BA,MAA9B,GAAuCA,MAAvC,GAAgD,EAHhD,CAAN;EAMAkB,IAAAA,wBAAI,CAACc,eAAL,CACExD,IADF,EAEEwB,MAFF,EAGE,KAAKiC,WAAL,CAAiBzC,WAHnB;EAMA,WAAOQ,MAAP;EACD;;WAEDK,gBAAA,yBAAgB;EAAA;;EACdxB,IAAAA,qBAAC,CAAC,KAAKoB,QAAN,CAAD,CAAiBiC,EAAjB,CAAoBnD,mBAApB,EAAyCc,qBAAzC,EAAgE;EAAA,aAAM,MAAI,CAACoB,IAAL,EAAN;EAAA,KAAhE;EACD;;WAEDU,SAAA,kBAAS;EAAA;;EACP,QAAMb,QAAQ,GAAG,SAAXA,QAAW,GAAM;EACrB,MAAA,MAAI,CAACb,QAAL,CAAcW,SAAd,CAAwBC,GAAxB,CAA4BxB,eAA5B;;EACAR,MAAAA,qBAAC,CAAC,MAAI,CAACoB,QAAN,CAAD,CAAiBQ,OAAjB,CAAyBxB,YAAzB;EACD,KAHD;;EAKA,SAAKgB,QAAL,CAAcW,SAAd,CAAwBG,MAAxB,CAA+BzB,eAA/B;;EACA,QAAI,KAAKY,OAAL,CAAaT,SAAjB,EAA4B;EAC1B,UAAM2B,kBAAkB,GAAGF,wBAAI,CAACG,gCAAL,CAAsC,KAAKpB,QAA3C,CAA3B;EAEApB,MAAAA,qBAAC,CAAC,KAAKoB,QAAN,CAAD,CACGqB,GADH,CACOJ,wBAAI,CAACK,cADZ,EAC4BT,QAD5B,EAEGU,oBAFH,CAEwBJ,kBAFxB;EAGD,KAND,MAMO;EACLN,MAAAA,QAAQ;EACT;EACF;;WAEDH,gBAAA,yBAAgB;EACdwB,IAAAA,YAAY,CAAC,KAAK/B,QAAN,CAAZ;EACA,SAAKA,QAAL,GAAgB,IAAhB;EACD;;;UAIMgC,mBAAP,0BAAwBpC,MAAxB,EAAgC;EAC9B,WAAO,KAAKqC,IAAL,CAAU,YAAY;EAC3B,UAAMC,QAAQ,GAAGzD,qBAAC,CAAC,IAAD,CAAlB;EACA,UAAIkD,IAAI,GAAGO,QAAQ,CAACP,IAAT,CAAcrD,QAAd,CAAX;;EACA,UAAMwB,OAAO,GAAG,OAAOF,MAAP,KAAkB,QAAlB,IAA8BA,MAA9C;;EAEA,UAAI,CAAC+B,IAAL,EAAW;EACTA,QAAAA,IAAI,GAAG,IAAIjC,KAAJ,CAAU,IAAV,EAAgBI,OAAhB,CAAP;EACAoC,QAAAA,QAAQ,CAACP,IAAT,CAAcrD,QAAd,EAAwBqD,IAAxB;EACD;;EAED,UAAI,OAAO/B,MAAP,KAAkB,QAAtB,EAAgC;EAC9B,YAAI,OAAO+B,IAAI,CAAC/B,MAAD,CAAX,KAAwB,WAA5B,EAAyC;EACvC,gBAAM,IAAIuC,SAAJ,wBAAkCvC,MAAlC,QAAN;EACD;;EAED+B,QAAAA,IAAI,CAAC/B,MAAD,CAAJ,CAAa,IAAb;EACD;EACF,KAjBM,CAAP;EAkBD;;;;0BAtJoB;EACnB,aAAOvB,OAAP;EACD;;;0BAEwB;EACvB,aAAOe,WAAP;EACD;;;0BAEoB;EACnB,aAAOI,OAAP;EACD;;;;;EA+IH;;;;;;;AAMAf,uBAAC,CAACC,EAAF,CAAKN,IAAL,IAAasB,KAAK,CAACsC,gBAAnB;AACAvD,uBAAC,CAACC,EAAF,CAAKN,IAAL,EAAWgE,WAAX,GAAyB1C,KAAzB;;AACAjB,uBAAC,CAACC,EAAF,CAAKN,IAAL,EAAWiE,UAAX,GAAwB,YAAM;EAC5B5D,EAAAA,qBAAC,CAACC,EAAF,CAAKN,IAAL,IAAaI,kBAAb;EACA,SAAOkB,KAAK,CAACsC,gBAAb;EACD,CAHD;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"toast.js","sources":["../src/toast.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\n\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n}\n\nconst Default = {\n animation: true,\n autohide: true,\n delay: 500\n}\n\nconst SELECTOR_DATA_DISMISS = '[data-dismiss=\"toast\"]'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast {\n constructor(element, config) {\n this._element = element\n this._config = this._getConfig(config)\n this._timeout = null\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n show() {\n const showEvent = $.Event(EVENT_SHOW)\n\n $(this._element).trigger(showEvent)\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n this._clearTimeout()\n\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE)\n }\n\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING)\n this._element.classList.add(CLASS_NAME_SHOW)\n\n $(this._element).trigger(EVENT_SHOWN)\n\n if (this._config.autohide) {\n this._timeout = setTimeout(() => {\n this.hide()\n }, this._config.delay)\n }\n }\n\n this._element.classList.remove(CLASS_NAME_HIDE)\n Util.reflow(this._element)\n this._element.classList.add(CLASS_NAME_SHOWING)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n hide() {\n if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n return\n }\n\n const hideEvent = $.Event(EVENT_HIDE)\n\n $(this._element).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._close()\n }\n\n dispose() {\n this._clearTimeout()\n\n if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n this._element.classList.remove(CLASS_NAME_SHOW)\n }\n\n $(this._element).off(EVENT_CLICK_DISMISS)\n\n $.removeData(this._element, DATA_KEY)\n this._element = null\n this._config = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...$(this._element).data(),\n ...(typeof config === 'object' && config ? config : {})\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _setListeners() {\n $(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())\n }\n\n _close() {\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE)\n $(this._element).trigger(EVENT_HIDDEN)\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n if (this._config.animation) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n\n _clearTimeout() {\n clearTimeout(this._timeout)\n this._timeout = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new Toast(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Toast._jQueryInterface\n$.fn[NAME].Constructor = Toast\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Toast._jQueryInterface\n}\n\nexport default Toast\n"],"names":["NAME","VERSION","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","$","fn","EVENT_CLICK_DISMISS","EVENT_HIDE","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","CLASS_NAME_FADE","CLASS_NAME_HIDE","CLASS_NAME_SHOW","CLASS_NAME_SHOWING","DefaultType","animation","autohide","delay","Default","SELECTOR_DATA_DISMISS","Toast","element","config","_element","_config","_getConfig","_timeout","_setListeners","show","showEvent","Event","trigger","isDefaultPrevented","_clearTimeout","classList","add","complete","remove","setTimeout","hide","Util","reflow","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","emulateTransitionEnd","contains","hideEvent","_close","dispose","off","removeData","data","typeCheckConfig","constructor","on","clearTimeout","_jQueryInterface","each","$element","TypeError","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/tooltip.js b/vendor/twbs/bootstrap/js/dist/tooltip.js index 663337862..ae6ec8ed7 100644 --- a/vendor/twbs/bootstrap/js/dist/tooltip.js +++ b/vendor/twbs/bootstrap/js/dist/tooltip.js @@ -1,11 +1,11 @@ /*! - * Bootstrap tooltip.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap tooltip.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : - typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : + typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tooltip = factory(global.jQuery, global.Popper, global.Util)); }(this, (function ($, Popper, Util) { 'use strict'; @@ -15,9 +15,43 @@ var Popper__default = /*#__PURE__*/_interopDefaultLegacy(Popper); var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util); + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); + } + /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): tools/sanitizer.js + * Bootstrap (v4.6.0): tools/sanitizer.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -136,11 +170,6 @@ return createdDocument.body.innerHTML; } - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - - function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * ------------------------------------------------------------------------ * Constants @@ -148,7 +177,7 @@ */ var NAME = 'tooltip'; - var VERSION = '4.5.3'; + var VERSION = '4.6.0'; var DATA_KEY = 'bs.tooltip'; var EVENT_KEY = "." + DATA_KEY; var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME]; @@ -168,6 +197,7 @@ container: '(string|element|boolean)', fallbackPlacement: '(string|array)', boundary: '(string|element)', + customClass: '(string|function)', sanitize: 'boolean', sanitizeFn: '(null|function)', whiteList: 'object', @@ -193,6 +223,7 @@ container: false, fallbackPlacement: 'flip', boundary: 'scrollParent', + customClass: '', sanitize: true, sanitizeFn: null, whiteList: DefaultWhitelist, @@ -229,7 +260,7 @@ var Tooltip = /*#__PURE__*/function () { function Tooltip(element, config) { if (typeof Popper__default['default'] === 'undefined') { - throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); + throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); } // private @@ -363,7 +394,8 @@ $__default['default'](this.element).trigger(this.constructor.Event.INSERTED); this._popper = new Popper__default['default'](this.element, tip, this._getPopperConfig(attachment)); - $__default['default'](tip).addClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we add extra + $__default['default'](tip).addClass(CLASS_NAME_SHOW); + $__default['default'](tip).addClass(this.config.customClass); // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html diff --git a/vendor/twbs/bootstrap/js/dist/tooltip.js.map b/vendor/twbs/bootstrap/js/dist/tooltip.js.map index b48d5030b..065d3e743 100644 --- a/vendor/twbs/bootstrap/js/dist/tooltip.js.map +++ b/vendor/twbs/bootstrap/js/dist/tooltip.js.map @@ -1 +1 @@ -{"version":3,"file":"tooltip.js","sources":["../src/tools/sanitizer.js","../src/tooltip.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.5.3'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper.js (https://popper.js.org/)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n"],"names":["uriAttrs","ARIA_ATTRIBUTE_PATTERN","DefaultWhitelist","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","i","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","attr","allowedAttributeList","attrName","nodeName","toLowerCase","indexOf","Boolean","nodeValue","match","regExp","filter","attrRegex","RegExp","len","length","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","domParser","window","DOMParser","createdDocument","parseFromString","whitelistKeys","Object","keys","elements","slice","call","body","querySelectorAll","el","elName","parentNode","removeChild","attributeList","attributes","whitelistedAttributes","concat","forEach","removeAttribute","innerHTML","NAME","VERSION","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","$","fn","CLASS_PREFIX","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","DefaultType","animation","template","title","trigger","delay","html","selector","placement","offset","container","fallbackPlacement","boundary","sanitize","popperConfig","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","Default","HOVER_STATE_SHOW","HOVER_STATE_OUT","Event","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","CLASS_NAME_FADE","CLASS_NAME_SHOW","SELECTOR_TOOLTIP_INNER","SELECTOR_ARROW","TRIGGER_HOVER","TRIGGER_FOCUS","TRIGGER_CLICK","TRIGGER_MANUAL","Tooltip","element","config","Popper","TypeError","_isEnabled","_timeout","_hoverState","_activeTrigger","_popper","_getConfig","tip","_setListeners","enable","disable","toggleEnabled","toggle","event","dataKey","constructor","context","currentTarget","data","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","hasClass","dispose","clearTimeout","removeData","off","closest","_hideModalHandler","remove","destroy","show","css","Error","showEvent","isWithContent","shadowRoot","Util","findShadowRoot","isInTheDom","contains","ownerDocument","documentElement","isDefaultPrevented","tipId","getUID","setAttribute","setContent","addClass","attachment","_getAttachment","addAttachmentClass","_getContainer","appendTo","_getPopperConfig","document","children","on","noop","complete","_fixTransition","prevHoverState","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","emulateTransitionEnd","hide","callback","hideEvent","_cleanTipClass","removeClass","update","scheduleUpdate","getTitle","setElementContent","$element","content","nodeType","jquery","parent","is","empty","append","text","getAttribute","defaultBsConfig","modifiers","_getOffset","flip","behavior","arrow","preventOverflow","boundariesElement","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","offsets","isElement","find","toUpperCase","triggers","split","eventIn","eventOut","_fixTitle","titleType","type","setTimeout","dataAttributes","dataAttr","toString","typeCheckConfig","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","_jQueryInterface","each","_config","test","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"tooltip.js","sources":["../src/tools/sanitizer.js","../src/tooltip.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tools/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttrs = [\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n]\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultWhitelist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nfunction allowedAttribute(attr, allowedAttributeList) {\n const attrName = attr.nodeName.toLowerCase()\n\n if (allowedAttributeList.indexOf(attrName) !== -1) {\n if (uriAttrs.indexOf(attrName) !== -1) {\n return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))\n }\n\n return true\n }\n\n const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)\n\n // Check if a regular expression validates the attribute.\n for (let i = 0, len = regExp.length; i < len; i++) {\n if (attrName.match(regExp[i])) {\n return true\n }\n }\n\n return false\n}\n\nexport function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {\n if (unsafeHtml.length === 0) {\n return unsafeHtml\n }\n\n if (sanitizeFn && typeof sanitizeFn === 'function') {\n return sanitizeFn(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const whitelistKeys = Object.keys(whiteList)\n const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))\n\n for (let i = 0, len = elements.length; i < len; i++) {\n const el = elements[i]\n const elName = el.nodeName.toLowerCase()\n\n if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {\n el.parentNode.removeChild(el)\n\n continue\n }\n\n const attributeList = [].slice.call(el.attributes)\n const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])\n\n attributeList.forEach(attr => {\n if (!allowedAttribute(attr, whitelistedAttributes)) {\n el.removeAttribute(attr.nodeName)\n }\n })\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n DefaultWhitelist,\n sanitizeHtml\n} from './tools/sanitizer'\nimport $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'tooltip'\nconst VERSION = '4.6.0'\nconst DATA_KEY = 'bs.tooltip'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst JQUERY_NO_CONFLICT = $.fn[NAME]\nconst CLASS_PREFIX = 'bs-tooltip'\nconst BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\nconst DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']\n\nconst DefaultType = {\n animation: 'boolean',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string',\n delay: '(number|object)',\n html: 'boolean',\n selector: '(string|boolean)',\n placement: '(string|function)',\n offset: '(number|string|function)',\n container: '(string|element|boolean)',\n fallbackPlacement: '(string|array)',\n boundary: '(string|element)',\n customClass: '(string|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n whiteList: 'object',\n popperConfig: '(null|object)'\n}\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: 'right',\n BOTTOM: 'bottom',\n LEFT: 'left'\n}\n\nconst Default = {\n animation: true,\n template: '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n selector: false,\n placement: 'top',\n offset: 0,\n container: false,\n fallbackPlacement: 'flip',\n boundary: 'scrollParent',\n customClass: '',\n sanitize: true,\n sanitizeFn: null,\n whiteList: DefaultWhitelist,\n popperConfig: null\n}\n\nconst HOVER_STATE_SHOW = 'show'\nconst HOVER_STATE_OUT = 'out'\n\nconst Event = {\n HIDE: `hide${EVENT_KEY}`,\n HIDDEN: `hidden${EVENT_KEY}`,\n SHOW: `show${EVENT_KEY}`,\n SHOWN: `shown${EVENT_KEY}`,\n INSERTED: `inserted${EVENT_KEY}`,\n CLICK: `click${EVENT_KEY}`,\n FOCUSIN: `focusin${EVENT_KEY}`,\n FOCUSOUT: `focusout${EVENT_KEY}`,\n MOUSEENTER: `mouseenter${EVENT_KEY}`,\n MOUSELEAVE: `mouseleave${EVENT_KEY}`\n}\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_ARROW = '.arrow'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler)\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const shadowRoot = Util.findShadowRoot(this.element)\n const isInTheDom = $.contains(\n shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(CLASS_NAME_FADE)\n }\n\n const placement = typeof this.config.placement === 'function' ?\n this.config.placement.call(this, tip, this.element) :\n this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this._getContainer()\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))\n\n $(tip).addClass(CLASS_NAME_SHOW)\n $(tip).addClass(this.config.customClass)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HOVER_STATE_OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n\n if ($(this.tip).hasClass(CLASS_NAME_FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)\n }\n\n setElementContent($element, content) {\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (this.config.html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n\n return\n }\n\n if (this.config.html) {\n if (this.config.sanitize) {\n content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)\n }\n\n $element.html(content)\n } else {\n $element.text(content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function' ?\n this.config.title.call(this.element) :\n this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getPopperConfig(attachment) {\n const defaultBsConfig = {\n placement: attachment,\n modifiers: {\n offset: this._getOffset(),\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: SELECTOR_ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: data => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: data => this._handlePopperPlacementChange(data)\n }\n\n return {\n ...defaultBsConfig,\n ...this.config.popperConfig\n }\n }\n\n _getOffset() {\n const offset = {}\n\n if (typeof this.config.offset === 'function') {\n offset.fn = data => {\n data.offsets = {\n ...data.offsets,\n ...(this.config.offset(data.offsets, this.element) || {})\n }\n\n return data\n }\n } else {\n offset.offset = this.config.offset\n }\n\n return offset\n }\n\n _getContainer() {\n if (this.config.container === false) {\n return document.body\n }\n\n if (Util.isElement(this.config.container)) {\n return $(this.config.container)\n }\n\n return $(document).find(this.config.container)\n }\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach(trigger => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n event => this.toggle(event)\n )\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSEENTER :\n this.constructor.Event.FOCUSIN\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.Event.MOUSELEAVE :\n this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(eventIn, this.config.selector, event => this._enter(event))\n .on(eventOut, this.config.selector, event => this._leave(event))\n }\n })\n\n this._hideModalHandler = () => {\n if (this.element) {\n this.hide()\n }\n }\n\n $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler)\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n\n if (this.element.getAttribute('title') || titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {\n context._hoverState = HOVER_STATE_SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HOVER_STATE_OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HOVER_STATE_OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n const dataAttributes = $(this.element).data()\n\n Object.keys(dataAttributes)\n .forEach(dataAttr => {\n if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {\n delete dataAttributes[dataAttr]\n }\n })\n\n config = {\n ...this.constructor.Default,\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n if (config.sanitize) {\n config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn)\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n this.tip = popperData.instance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n\n $(tip).removeClass(CLASS_NAME_FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $element.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n$.fn[NAME] = Tooltip._jQueryInterface\n$.fn[NAME].Constructor = Tooltip\n$.fn[NAME].noConflict = () => {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n}\n\nexport default Tooltip\n"],"names":["uriAttrs","ARIA_ATTRIBUTE_PATTERN","DefaultWhitelist","a","area","b","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","i","img","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","attr","allowedAttributeList","attrName","nodeName","toLowerCase","indexOf","Boolean","nodeValue","match","regExp","filter","attrRegex","RegExp","len","length","sanitizeHtml","unsafeHtml","whiteList","sanitizeFn","domParser","window","DOMParser","createdDocument","parseFromString","whitelistKeys","Object","keys","elements","slice","call","body","querySelectorAll","el","elName","parentNode","removeChild","attributeList","attributes","whitelistedAttributes","concat","forEach","removeAttribute","innerHTML","NAME","VERSION","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","$","fn","CLASS_PREFIX","BSCLS_PREFIX_REGEX","DISALLOWED_ATTRIBUTES","DefaultType","animation","template","title","trigger","delay","html","selector","placement","offset","container","fallbackPlacement","boundary","customClass","sanitize","popperConfig","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","Default","HOVER_STATE_SHOW","HOVER_STATE_OUT","Event","HIDE","HIDDEN","SHOW","SHOWN","INSERTED","CLICK","FOCUSIN","FOCUSOUT","MOUSEENTER","MOUSELEAVE","CLASS_NAME_FADE","CLASS_NAME_SHOW","SELECTOR_TOOLTIP_INNER","SELECTOR_ARROW","TRIGGER_HOVER","TRIGGER_FOCUS","TRIGGER_CLICK","TRIGGER_MANUAL","Tooltip","element","config","Popper","TypeError","_isEnabled","_timeout","_hoverState","_activeTrigger","_popper","_getConfig","tip","_setListeners","enable","disable","toggleEnabled","toggle","event","dataKey","constructor","context","currentTarget","data","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","hasClass","dispose","clearTimeout","removeData","off","closest","_hideModalHandler","remove","destroy","show","css","Error","showEvent","isWithContent","shadowRoot","Util","findShadowRoot","isInTheDom","contains","ownerDocument","documentElement","isDefaultPrevented","tipId","getUID","setAttribute","setContent","addClass","attachment","_getAttachment","addAttachmentClass","_getContainer","appendTo","_getPopperConfig","document","children","on","noop","complete","_fixTransition","prevHoverState","transitionDuration","getTransitionDurationFromElement","one","TRANSITION_END","emulateTransitionEnd","hide","callback","hideEvent","_cleanTipClass","removeClass","update","scheduleUpdate","getTitle","setElementContent","$element","content","nodeType","jquery","parent","is","empty","append","text","getAttribute","defaultBsConfig","modifiers","_getOffset","flip","behavior","arrow","preventOverflow","boundariesElement","onCreate","originalPlacement","_handlePopperPlacementChange","onUpdate","offsets","isElement","find","toUpperCase","triggers","split","eventIn","eventOut","_fixTitle","titleType","type","setTimeout","dataAttributes","dataAttr","toString","typeCheckConfig","key","$tip","tabClass","join","popperData","instance","popper","initConfigAnimation","_jQueryInterface","each","_config","test","Constructor","noConflict"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/dist/util.js b/vendor/twbs/bootstrap/js/dist/util.js index e3b5c1180..55b6d244b 100644 --- a/vendor/twbs/bootstrap/js/dist/util.js +++ b/vendor/twbs/bootstrap/js/dist/util.js @@ -1,6 +1,6 @@ /*! - * Bootstrap util.js v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap util.js v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ (function (global, factory) { @@ -15,7 +15,7 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): util.js + * Bootstrap (v4.6.0): util.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ diff --git a/vendor/twbs/bootstrap/js/dist/util.js.map b/vendor/twbs/bootstrap/js/dist/util.js.map index 246cf3d2e..1740a2f3b 100644 --- a/vendor/twbs/bootstrap/js/dist/util.js.map +++ b/vendor/twbs/bootstrap/js/dist/util.js.map @@ -1 +1 @@ -{"version":3,"file":"util.js","sources":["../src/util.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.5.3): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n"],"names":["TRANSITION_END","MAX_UID","MILLISECONDS_MULTIPLIER","toType","obj","toString","call","match","toLowerCase","getSpecialTransitionEndEvent","bindType","delegateType","handle","event","$","target","is","handleObj","handler","apply","arguments","undefined","transitionEndEmulator","duration","called","one","Util","setTimeout","triggerTransitionEnd","setTransitionEndSupport","fn","emulateTransitionEnd","special","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","expectedTypes","value","valueType","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","jquery","minMajor","ltMajor","minMinor","minPatch","maxMajor"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"util.js","sources":["../src/util.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport $ from 'jquery'\n\n/**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\nconst TRANSITION_END = 'transitionend'\nconst MAX_UID = 1000000\nconst MILLISECONDS_MULTIPLIER = 1000\n\n// Shoutout AngusCroll (https://goo.gl/pxwQGp)\nfunction toType(obj) {\n if (obj === null || typeof obj === 'undefined') {\n return `${obj}`\n }\n\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\nfunction getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n\n return undefined\n }\n }\n}\n\nfunction transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n}\n\nfunction setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n}\n\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\nconst Util = {\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n\n if (!selector || selector === '#') {\n const hrefAttr = element.getAttribute('href')\n selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (_) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n let transitionDelay = $(element).css('transition-delay')\n\n const floatTransitionDuration = parseFloat(transitionDuration)\n const floatTransitionDelay = parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value) ?\n 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n },\n\n findShadowRoot(element) {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return Util.findShadowRoot(element.parentNode)\n },\n\n jQueryDetection() {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n }\n}\n\nUtil.jQueryDetection()\nsetTransitionEndSupport()\n\nexport default Util\n"],"names":["TRANSITION_END","MAX_UID","MILLISECONDS_MULTIPLIER","toType","obj","toString","call","match","toLowerCase","getSpecialTransitionEndEvent","bindType","delegateType","handle","event","$","target","is","handleObj","handler","apply","arguments","undefined","transitionEndEmulator","duration","called","one","Util","setTimeout","triggerTransitionEnd","setTransitionEndSupport","fn","emulateTransitionEnd","special","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","_","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","expectedTypes","value","valueType","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","parentNode","jQueryDetection","TypeError","version","jquery","minMajor","ltMajor","minMinor","minPatch","maxMajor"],"mappings":"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"} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/js/src/alert.js b/vendor/twbs/bootstrap/js/src/alert.js index 421da7435..afd7736c7 100644 --- a/vendor/twbs/bootstrap/js/src/alert.js +++ b/vendor/twbs/bootstrap/js/src/alert.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): alert.js + * Bootstrap (v4.6.0): alert.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Util from './util' */ const NAME = 'alert' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.alert' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' diff --git a/vendor/twbs/bootstrap/js/src/button.js b/vendor/twbs/bootstrap/js/src/button.js index ec40af333..316387e8e 100644 --- a/vendor/twbs/bootstrap/js/src/button.js +++ b/vendor/twbs/bootstrap/js/src/button.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): button.js + * Bootstrap (v4.6.0): button.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -14,7 +14,7 @@ import $ from 'jquery' */ const NAME = 'button' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.button' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' diff --git a/vendor/twbs/bootstrap/js/src/carousel.js b/vendor/twbs/bootstrap/js/src/carousel.js index 5f738fd92..b63d406bd 100644 --- a/vendor/twbs/bootstrap/js/src/carousel.js +++ b/vendor/twbs/bootstrap/js/src/carousel.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): carousel.js + * Bootstrap (v4.6.0): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Util from './util' */ const NAME = 'carousel' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.carousel' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -169,6 +169,8 @@ class Carousel { } if (this._config.interval && !this._isPaused) { + this._updateInterval() + this._interval = setInterval( (document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval @@ -401,6 +403,23 @@ class Carousel { } } + _updateInterval() { + const element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM) + + if (!element) { + return + } + + const elementInterval = parseInt(element.getAttribute('data-interval'), 10) + + if (elementInterval) { + this._config.defaultInterval = this._config.defaultInterval || this._config.interval + this._config.interval = elementInterval + } else { + this._config.interval = this._config.defaultInterval || this._config.interval + } + } + _slide(direction, element) { const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM) const activeElementIndex = this._getItemIndex(activeElement) @@ -445,6 +464,7 @@ class Carousel { } this._setActiveIndicatorElement(nextElement) + this._activeElement = nextElement const slidEvent = $.Event(EVENT_SLID, { relatedTarget: nextElement, @@ -461,14 +481,6 @@ class Carousel { $(activeElement).addClass(directionalClassName) $(nextElement).addClass(directionalClassName) - const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10) - if (nextElementInterval) { - this._config.defaultInterval = this._config.defaultInterval || this._config.interval - this._config.interval = nextElementInterval - } else { - this._config.interval = this._config.defaultInterval || this._config.interval - } - const transitionDuration = Util.getTransitionDurationFromElement(activeElement) $(activeElement) diff --git a/vendor/twbs/bootstrap/js/src/collapse.js b/vendor/twbs/bootstrap/js/src/collapse.js index 0ec037704..af3163be9 100644 --- a/vendor/twbs/bootstrap/js/src/collapse.js +++ b/vendor/twbs/bootstrap/js/src/collapse.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): collapse.js + * Bootstrap (v4.6.0): collapse.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Util from './util' */ const NAME = 'collapse' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.collapse' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' diff --git a/vendor/twbs/bootstrap/js/src/dropdown.js b/vendor/twbs/bootstrap/js/src/dropdown.js index c2779f05f..76dda8f57 100644 --- a/vendor/twbs/bootstrap/js/src/dropdown.js +++ b/vendor/twbs/bootstrap/js/src/dropdown.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): dropdown.js + * Bootstrap (v4.6.0): dropdown.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -16,7 +16,7 @@ import Util from './util' */ const NAME = 'dropdown' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.dropdown' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -143,14 +143,14 @@ class Dropdown { return } - // Disable totally Popper.js for Dropdown in Navbar + // Totally disable Popper for Dropdowns in Navbar if (!this._inNavbar && usePopper) { /** * Check for Popper dependency * Popper - https://popper.js.org */ if (typeof Popper === 'undefined') { - throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)') + throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)') } let referenceElement = this._element @@ -334,7 +334,7 @@ class Dropdown { } } - // Disable Popper.js if we have a static display + // Disable Popper if we have a static display if (this._config.display === 'static') { popperConfig.modifiers.applyStyle = { enabled: false diff --git a/vendor/twbs/bootstrap/js/src/index.js b/vendor/twbs/bootstrap/js/src/index.js deleted file mode 100644 index f407cffa5..000000000 --- a/vendor/twbs/bootstrap/js/src/index.js +++ /dev/null @@ -1,34 +0,0 @@ -import Alert from './alert' -import Button from './button' -import Carousel from './carousel' -import Collapse from './collapse' -import Dropdown from './dropdown' -import Modal from './modal' -import Popover from './popover' -import Scrollspy from './scrollspy' -import Tab from './tab' -import Toast from './toast' -import Tooltip from './tooltip' -import Util from './util' - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): index.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -export { - Util, - Alert, - Button, - Carousel, - Collapse, - Dropdown, - Modal, - Popover, - Scrollspy, - Tab, - Toast, - Tooltip -} diff --git a/vendor/twbs/bootstrap/js/src/modal.js b/vendor/twbs/bootstrap/js/src/modal.js index 975a20be6..2e3017024 100644 --- a/vendor/twbs/bootstrap/js/src/modal.js +++ b/vendor/twbs/bootstrap/js/src/modal.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): modal.js + * Bootstrap (v4.6.0): modal.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Util from './util' */ const NAME = 'modal' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.modal' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' @@ -230,39 +230,35 @@ class Modal { } _triggerBackdropTransition() { - if (this._config.backdrop === 'static') { - const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED) + const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED) - $(this._element).trigger(hideEventPrevented) - if (hideEventPrevented.isDefaultPrevented()) { - return - } + $(this._element).trigger(hideEventPrevented) + if (hideEventPrevented.isDefaultPrevented()) { + return + } - const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight + const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight - if (!isModalOverflowing) { - this._element.style.overflowY = 'hidden' - } + if (!isModalOverflowing) { + this._element.style.overflowY = 'hidden' + } - this._element.classList.add(CLASS_NAME_STATIC) + this._element.classList.add(CLASS_NAME_STATIC) - const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog) - $(this._element).off(Util.TRANSITION_END) + const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog) + $(this._element).off(Util.TRANSITION_END) - $(this._element).one(Util.TRANSITION_END, () => { - this._element.classList.remove(CLASS_NAME_STATIC) - if (!isModalOverflowing) { - $(this._element).one(Util.TRANSITION_END, () => { - this._element.style.overflowY = '' - }) - .emulateTransitionEnd(this._element, modalTransitionDuration) - } - }) - .emulateTransitionEnd(modalTransitionDuration) - this._element.focus() - } else { - this.hide() - } + $(this._element).one(Util.TRANSITION_END, () => { + this._element.classList.remove(CLASS_NAME_STATIC) + if (!isModalOverflowing) { + $(this._element).one(Util.TRANSITION_END, () => { + this._element.style.overflowY = '' + }) + .emulateTransitionEnd(this._element, modalTransitionDuration) + } + }) + .emulateTransitionEnd(modalTransitionDuration) + this._element.focus() } _showElement(relatedTarget) { @@ -400,7 +396,11 @@ class Modal { return } - this._triggerBackdropTransition() + if (this._config.backdrop === 'static') { + this._triggerBackdropTransition() + } else { + this.hide() + } }) if (animate) { diff --git a/vendor/twbs/bootstrap/js/src/popover.js b/vendor/twbs/bootstrap/js/src/popover.js index ee7a4ca9a..4e2c260b9 100644 --- a/vendor/twbs/bootstrap/js/src/popover.js +++ b/vendor/twbs/bootstrap/js/src/popover.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): popover.js + * Bootstrap (v4.6.0): popover.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Tooltip from './tooltip' */ const NAME = 'popover' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.popover' const EVENT_KEY = `.${DATA_KEY}` const JQUERY_NO_CONFLICT = $.fn[NAME] diff --git a/vendor/twbs/bootstrap/js/src/scrollspy.js b/vendor/twbs/bootstrap/js/src/scrollspy.js index 7daa51e86..351df0649 100644 --- a/vendor/twbs/bootstrap/js/src/scrollspy.js +++ b/vendor/twbs/bootstrap/js/src/scrollspy.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): scrollspy.js + * Bootstrap (v4.6.0): scrollspy.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Util from './util' */ const NAME = 'scrollspy' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.scrollspy' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' diff --git a/vendor/twbs/bootstrap/js/src/tab.js b/vendor/twbs/bootstrap/js/src/tab.js index 512016483..e9a6f555f 100644 --- a/vendor/twbs/bootstrap/js/src/tab.js +++ b/vendor/twbs/bootstrap/js/src/tab.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): tab.js + * Bootstrap (v4.6.0): tab.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Util from './util' */ const NAME = 'tab' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.tab' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' diff --git a/vendor/twbs/bootstrap/js/src/toast.js b/vendor/twbs/bootstrap/js/src/toast.js index 953879ebd..0c2186908 100644 --- a/vendor/twbs/bootstrap/js/src/toast.js +++ b/vendor/twbs/bootstrap/js/src/toast.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): toast.js + * Bootstrap (v4.6.0): toast.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ import Util from './util' */ const NAME = 'toast' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.toast' const EVENT_KEY = `.${DATA_KEY}` const JQUERY_NO_CONFLICT = $.fn[NAME] diff --git a/vendor/twbs/bootstrap/js/src/tools/sanitizer.js b/vendor/twbs/bootstrap/js/src/tools/sanitizer.js index 57768e45f..45fd6106c 100644 --- a/vendor/twbs/bootstrap/js/src/tools/sanitizer.js +++ b/vendor/twbs/bootstrap/js/src/tools/sanitizer.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): tools/sanitizer.js + * Bootstrap (v4.6.0): tools/sanitizer.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ diff --git a/vendor/twbs/bootstrap/js/src/tooltip.js b/vendor/twbs/bootstrap/js/src/tooltip.js index 4b58f3156..fd6ceea67 100644 --- a/vendor/twbs/bootstrap/js/src/tooltip.js +++ b/vendor/twbs/bootstrap/js/src/tooltip.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): tooltip.js + * Bootstrap (v4.6.0): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ import Util from './util' */ const NAME = 'tooltip' -const VERSION = '4.5.3' +const VERSION = '4.6.0' const DATA_KEY = 'bs.tooltip' const EVENT_KEY = `.${DATA_KEY}` const JQUERY_NO_CONFLICT = $.fn[NAME] @@ -41,6 +41,7 @@ const DefaultType = { container: '(string|element|boolean)', fallbackPlacement: '(string|array)', boundary: '(string|element)', + customClass: '(string|function)', sanitize: 'boolean', sanitizeFn: '(null|function)', whiteList: 'object', @@ -70,6 +71,7 @@ const Default = { container: false, fallbackPlacement: 'flip', boundary: 'scrollParent', + customClass: '', sanitize: true, sanitizeFn: null, whiteList: DefaultWhitelist, @@ -112,7 +114,7 @@ const TRIGGER_MANUAL = 'manual' class Tooltip { constructor(element, config) { if (typeof Popper === 'undefined') { - throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)') + throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)') } // private @@ -284,6 +286,7 @@ class Tooltip { this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)) $(tip).addClass(CLASS_NAME_SHOW) + $(tip).addClass(this.config.customClass) // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; diff --git a/vendor/twbs/bootstrap/js/src/util.js b/vendor/twbs/bootstrap/js/src/util.js index 6ce6ca50b..cd9d5e3b8 100644 --- a/vendor/twbs/bootstrap/js/src/util.js +++ b/vendor/twbs/bootstrap/js/src/util.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.5.3): util.js + * Bootstrap (v4.6.0): util.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ diff --git a/vendor/twbs/bootstrap/nuget/bootstrap.nuspec b/vendor/twbs/bootstrap/nuget/bootstrap.nuspec index 9d8d190d3..8e7a0a322 100644 --- a/vendor/twbs/bootstrap/nuget/bootstrap.nuspec +++ b/vendor/twbs/bootstrap/nuget/bootstrap.nuspec @@ -14,7 +14,7 @@ <projectUrl>https://getbootstrap.com/</projectUrl> <icon>bootstrap.png</icon> <license type="file">LICENSE.txt</license> - <copyright>Copyright 2017-2020</copyright> + <copyright>Copyright 2017-2021</copyright> <requireLicenseAcceptance>false</requireLicenseAcceptance> <dependencies> <dependency id="jQuery" version="[3.0.0,4)" /> diff --git a/vendor/twbs/bootstrap/nuget/bootstrap.sass.nuspec b/vendor/twbs/bootstrap/nuget/bootstrap.sass.nuspec index 72b1e3aaf..015726a67 100644 --- a/vendor/twbs/bootstrap/nuget/bootstrap.sass.nuspec +++ b/vendor/twbs/bootstrap/nuget/bootstrap.sass.nuspec @@ -14,7 +14,7 @@ <projectUrl>https://getbootstrap.com/</projectUrl> <icon>bootstrap.png</icon> <license type="file">LICENSE.txt</license> - <copyright>Copyright 2017-2020</copyright> + <copyright>Copyright 2017-2021</copyright> <requireLicenseAcceptance>false</requireLicenseAcceptance> <dependencies> <dependency id="jQuery" version="[3.0.0,4)" /> diff --git a/vendor/twbs/bootstrap/package-lock.json b/vendor/twbs/bootstrap/package-lock.json index a162c170a..c2d6942f5 100644 --- a/vendor/twbs/bootstrap/package-lock.json +++ b/vendor/twbs/bootstrap/package-lock.json @@ -1,16 +1,17 @@ { "name": "bootstrap", - "version": "4.5.3", + "version": "4.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/cli": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.11.6.tgz", - "integrity": "sha512-+w7BZCvkewSmaRM6H4L2QM3RL90teqEIHDIFXAmrW33+0jhlymnDAEdqVeCZATvxhQuio1ifoGVlJJbIiH9Ffg==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.12.10.tgz", + "integrity": "sha512-+y4ZnePpvWs1fc/LhZRTHkTesbXkyBYuOB+5CyodZqrEuETXi3zOVfpAQIdgC3lXbHLTDG9dQosxR9BhvLKDLQ==", "dev": true, "requires": { - "chokidar": "^2.1.8", + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents", + "chokidar": "^3.4.0", "commander": "^4.0.1", "convert-source-map": "^1.1.0", "fs-readdir-recursive": "^1.1.0", @@ -22,53 +23,47 @@ } }, "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/compat-data": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", - "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", + "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "dev": true }, "@babel/core": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz", - "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", + "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.6", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.5", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.5", - "@babel/types": "^7.11.5", + "@babel/generator": "^7.12.10", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.2", "lodash": "^4.17.19", - "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -83,23 +78,23 @@ } }, "@babel/generator": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz", - "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.11.5", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -113,41 +108,38 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", - "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", + "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", "dev": true, "requires": { - "@babel/compat-data": "^7.10.4", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", + "@babel/compat-data": "^7.12.5", + "@babel/helper-validator-option": "^7.12.1", + "browserslist": "^4.14.5", "semver": "^5.5.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", - "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", + "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.5", + "@babel/helper-member-expression-to-functions": "^7.12.1", "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", "@babel/helper-split-export-declaration": "^7.10.4" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", - "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", + "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-regex": "^7.10.4", - "regexpu-core": "^4.7.0" + "regexpu-core": "^4.7.1" } }, "@babel/helper-define-map": { @@ -162,32 +154,32 @@ } }, "@babel/helper-explode-assignable-expression": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz", - "integrity": "sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", + "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } }, "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, "@babel/helper-hoist-variables": { @@ -200,45 +192,47 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.5" } }, "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, "@babel/helper-plugin-utils": { @@ -247,77 +241,72 @@ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true }, - "@babel/helper-regex": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", - "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, "@babel/helper-remap-async-to-generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz", - "integrity": "sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", + "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-wrap-function": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", - "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.1" } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", + "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", - "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "version": "7.12.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", + "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", @@ -327,14 +316,14 @@ } }, "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "dev": true, "requires": { "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/highlight": { @@ -349,36 +338,36 @@ } }, "@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", - "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", + "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", - "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", + "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", - "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", + "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -386,9 +375,9 @@ } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", - "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", + "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -396,9 +385,9 @@ } }, "@babel/plugin-proposal-json-strings": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", - "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", + "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -406,9 +395,9 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", - "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", + "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -416,9 +405,9 @@ } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", - "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", + "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -426,9 +415,9 @@ } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", - "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", + "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -436,20 +425,20 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", - "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.4" + "@babel/plugin-transform-parameters": "^7.12.1" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", - "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", + "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -457,33 +446,33 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", - "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", + "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", - "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", + "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", - "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", + "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, @@ -497,9 +486,9 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", - "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -587,56 +576,56 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", - "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", - "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", + "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", - "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", + "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-module-imports": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4" + "@babel/helper-remap-async-to-generator": "^7.12.1" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", - "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", + "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", - "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", + "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-classes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", - "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", + "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", @@ -644,52 +633,52 @@ "@babel/helper-function-name": "^7.10.4", "@babel/helper-optimise-call-expression": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", "@babel/helper-split-export-declaration": "^7.10.4", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", - "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", + "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-destructuring": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", - "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", + "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", - "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", + "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", - "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", + "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", - "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", + "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", @@ -697,18 +686,18 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", - "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", + "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", - "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", + "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", @@ -716,225 +705,224 @@ } }, "@babel/plugin-transform-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", - "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", + "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", - "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", + "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", - "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", + "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", + "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-simple-access": "^7.12.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", - "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", + "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-validator-identifier": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", + "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", - "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", + "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.1" } }, "@babel/plugin-transform-new-target": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", - "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", + "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-object-super": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", - "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", + "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4" + "@babel/helper-replace-supers": "^7.12.1" } }, "@babel/plugin-transform-parameters": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", - "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", + "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-property-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", - "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", + "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-regenerator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", - "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", + "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", - "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", + "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", - "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", + "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", - "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", + "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", - "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", + "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-regex": "^7.10.4" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-template-literals": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", - "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", + "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", - "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", + "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", - "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", + "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", - "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", + "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/preset-env": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.5.tgz", - "integrity": "sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", + "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", "dev": true, "requires": { - "@babel/compat-data": "^7.11.0", - "@babel/helper-compilation-targets": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", + "@babel/compat-data": "^7.12.7", + "@babel/helper-compilation-targets": "^7.12.5", + "@babel/helper-module-imports": "^7.12.5", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-proposal-async-generator-functions": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-dynamic-import": "^7.10.4", - "@babel/plugin-proposal-export-namespace-from": "^7.10.4", - "@babel/plugin-proposal-json-strings": "^7.10.4", - "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", - "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@babel/plugin-proposal-private-methods": "^7.10.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", + "@babel/helper-validator-option": "^7.12.11", + "@babel/plugin-proposal-async-generator-functions": "^7.12.1", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-export-namespace-from": "^7.12.1", + "@babel/plugin-proposal-json-strings": "^7.12.1", + "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-numeric-separator": "^7.12.7", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.4", + "@babel/plugin-syntax-class-properties": "^7.12.1", "@babel/plugin-syntax-dynamic-import": "^7.8.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.0", @@ -944,45 +932,42 @@ "@babel/plugin-syntax-object-rest-spread": "^7.8.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.10.4", - "@babel/plugin-transform-classes": "^7.10.4", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-dotall-regex": "^7.10.4", - "@babel/plugin-transform-duplicate-keys": "^7.10.4", - "@babel/plugin-transform-exponentiation-operator": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-function-name": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-member-expression-literals": "^7.10.4", - "@babel/plugin-transform-modules-amd": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-modules-systemjs": "^7.10.4", - "@babel/plugin-transform-modules-umd": "^7.10.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", - "@babel/plugin-transform-new-target": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.4", - "@babel/plugin-transform-property-literals": "^7.10.4", - "@babel/plugin-transform-regenerator": "^7.10.4", - "@babel/plugin-transform-reserved-words": "^7.10.4", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-sticky-regex": "^7.10.4", - "@babel/plugin-transform-template-literals": "^7.10.4", - "@babel/plugin-transform-typeof-symbol": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.4", - "@babel/plugin-transform-unicode-regex": "^7.10.4", + "@babel/plugin-syntax-top-level-await": "^7.12.1", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-async-to-generator": "^7.12.1", + "@babel/plugin-transform-block-scoped-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.11", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-computed-properties": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-dotall-regex": "^7.12.1", + "@babel/plugin-transform-duplicate-keys": "^7.12.1", + "@babel/plugin-transform-exponentiation-operator": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-function-name": "^7.12.1", + "@babel/plugin-transform-literals": "^7.12.1", + "@babel/plugin-transform-member-expression-literals": "^7.12.1", + "@babel/plugin-transform-modules-amd": "^7.12.1", + "@babel/plugin-transform-modules-commonjs": "^7.12.1", + "@babel/plugin-transform-modules-systemjs": "^7.12.1", + "@babel/plugin-transform-modules-umd": "^7.12.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", + "@babel/plugin-transform-new-target": "^7.12.1", + "@babel/plugin-transform-object-super": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-property-literals": "^7.12.1", + "@babel/plugin-transform-regenerator": "^7.12.1", + "@babel/plugin-transform-reserved-words": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-sticky-regex": "^7.12.7", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/plugin-transform-typeof-symbol": "^7.12.10", + "@babel/plugin-transform-unicode-escapes": "^7.12.1", + "@babel/plugin-transform-unicode-regex": "^7.12.1", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.5", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", + "@babel/types": "^7.12.11", + "core-js-compat": "^3.8.0", "semver": "^5.5.0" } }, @@ -1000,46 +985,46 @@ } }, "@babel/runtime": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", - "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/traverse": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", - "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.5", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.5", - "@babel/types": "^7.11.5", + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -1054,20 +1039,20 @@ } }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, "@eslint/eslintrc": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", - "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", + "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -1083,9 +1068,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -1127,36 +1112,56 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, + "@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz", + "integrity": "sha512-+nb9vWloHNNMFHjGofEam3wopE3m1yuambrrd/fnPc+lFOMB9ROTqQlche9ByFWNkdNqfSgR/kkQtQ8DzEWt2w==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.4", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.4", "fastq": "^1.6.0" } }, "@rollup/plugin-babel": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.1.tgz", - "integrity": "sha512-Jd7oqFR2dzZJ3NWANDyBjwTtX/lYbZpVcmkHrfQcpvawHs9E4c0nYk5U2mfZ6I/DZcIvy506KZJi54XK/jxH7A==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.2.tgz", + "integrity": "sha512-MjmH7GvFT4TW8xFdIeFS3wqIX646y5tACdxkTO+khbHvS3ZcVJL6vkAHLw2wqPmkhwCfWHoNsp15VYNwW6JEJA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.10.4", @@ -1164,9 +1169,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-15.1.0.tgz", - "integrity": "sha512-xCQqz4z/o0h2syQ7d9LskIMvBSH4PX5PjYdpSSvgS+pQik3WahkQVNWg3D8XJeYjZoVWnIUQYDghuEMRGrmQYQ==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.0.0.tgz", + "integrity": "sha512-/omBIJG1nHQc+bgkYDuLpb/V08QyutP9amOrJRUSlYJZP+b/68gM//D8sxJe3Yry2QnYIr3QjR3x4AlxJEN3GA==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -1179,17 +1184,17 @@ }, "dependencies": { "estree-walker": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.1.tgz", - "integrity": "sha512-tF0hv+Yi2Ot1cwj9eYHtxC0jB9bmjacjQs6ZBTj82H8JwUywFuc+7E83NWfNMwHXZc11mjfFcVXPe9gEP4B8dg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true } } }, "@rollup/plugin-node-resolve": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz", - "integrity": "sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.0.1.tgz", + "integrity": "sha512-ltlsj/4Bhwwhb+Nb5xCz/6vieuEj2/BAkkqVIKmZwC7pIdl8srmgmglE4S0jFlZa32K4qvdQ6NHdmpRKD/LwoQ==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -1197,7 +1202,7 @@ "builtin-modules": "^3.1.0", "deepmerge": "^4.2.2", "is-module": "^1.0.0", - "resolve": "^1.17.0" + "resolve": "^1.19.0" } }, "@rollup/pluginutils": { @@ -1212,9 +1217,9 @@ } }, "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", "dev": true }, "@sinonjs/commons": { @@ -1263,13 +1268,13 @@ } }, "@stylelint/postcss-markdown": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.1.tgz", - "integrity": "sha512-iDxMBWk9nB2BPi1VFQ+Dc5+XpvODBHw2n3tYpaBZuEAFQlbtF9If0Qh5LTTwSi/XwdbJ2jt+0dis3i8omyggpw==", + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz", + "integrity": "sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==", "dev": true, "requires": { - "remark": "^12.0.0", - "unist-util-find-all-after": "^3.0.1" + "remark": "^13.0.0", + "unist-util-find-all-after": "^3.0.2" } }, "@szmarczak/http-timer": { @@ -1293,16 +1298,25 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/mdast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", + "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, "@types/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", "dev": true }, "@types/node": { - "version": "14.11.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz", - "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==", + "version": "14.14.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", + "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", "dev": true }, "@types/normalize-package-data": { @@ -1415,6 +1429,46 @@ "dev": true, "requires": { "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, "ansi-colors": { @@ -1467,6 +1521,29 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, + "arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true + }, + "archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", + "dev": true, + "requires": { + "file-type": "^4.2.0" + }, + "dependencies": { + "file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", + "dev": true + } + } + }, "are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", @@ -1520,35 +1597,16 @@ "dev": true }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", + "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.1", + "get-intrinsic": "^1.0.1", "is-string": "^1.0.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "array-union": { @@ -1565,34 +1623,14 @@ "optional": true }, "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "es-abstract": "^1.18.0-next.1" } }, "arraybuffer.slice": { @@ -1630,9 +1668,9 @@ "optional": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async-each": { @@ -1648,12 +1686,6 @@ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", "dev": true }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1674,17 +1706,16 @@ "optional": true }, "autoprefixer": { - "version": "9.8.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", - "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.1.tgz", + "integrity": "sha512-dwP0UjyYvROUvtU+boBx8ff5pPWami1NGTrJs9YUsS/oZVbRAcdNHOOuXSA1fc46tgKqe072cVaKD69rvCc3QQ==", "dev": true, "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", + "browserslist": "^4.16.1", + "caniuse-lite": "^1.0.30001173", "colorette": "^1.2.1", + "fraction.js": "^4.0.13", "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.32", "postcss-value-parser": "^4.1.0" } }, @@ -1695,9 +1726,9 @@ "dev": true }, "aws4": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", - "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "axios": { @@ -1837,6 +1868,12 @@ "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, "base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -1852,82 +1889,178 @@ "tweetnacl": "^0.14.3" } }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, "big-integer": { "version": "1.6.48", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", "dev": true }, - "binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", - "dev": true, - "requires": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "optional": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "bin-check": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", + "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", "dev": true, "requires": { - "inherits": "~2.0.0" + "execa": "^0.7.0", + "executable": "^4.1.0" } }, - "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "bin-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz", + "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==", "dev": true, "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", + "execa": "^1.0.0", + "find-versions": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "bin-version-check": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz", + "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==", + "dev": true, + "requires": { + "bin-version": "^3.0.0", + "semver": "^5.6.0", + "semver-truncate": "^1.1.2" + } + }, + "bin-wrapper": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz", + "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==", + "dev": true, + "requires": { + "bin-check": "^4.1.0", + "bin-version-check": "^4.0.0", + "download": "^7.1.0", + "import-lazy": "^3.1.0", + "os-filter-obj": "^2.0.0", + "pify": "^4.0.1" + } + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dev": true, + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", "qs": "6.7.0", "raw-body": "2.4.0", "type-is": "~1.6.17" @@ -1989,35 +2122,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2071,15 +2181,16 @@ } }, "browserslist": { - "version": "4.14.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.5.tgz", - "integrity": "sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA==", + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", + "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001135", - "electron-to-chromium": "^1.3.571", - "escalade": "^3.1.0", - "node-releases": "^1.1.61" + "caniuse-lite": "^1.0.30001173", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.634", + "escalade": "^3.1.1", + "node-releases": "^1.1.69" } }, "browserstack": { @@ -2101,6 +2212,44 @@ "unzipper": "^0.9.3" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -2120,9 +2269,9 @@ "dev": true }, "builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, "bundlewatch": { @@ -2225,69 +2374,38 @@ } }, "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", "dev": true, "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" }, "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", "dev": true } } }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "requires": { - "caller-callsite": "^2.0.0" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" } }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2312,9 +2430,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001148", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001148.tgz", - "integrity": "sha512-E66qcd0KMKZHNJQt9hiLZGE3J4zuTqE1OnU53miEVtylFbwOEmeA5OsRu90noZful+XGSQOni1aT2tiqu/9yYw==", + "version": "1.0.30001176", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001176.tgz", + "integrity": "sha512-VWdkYmqdkDLRe0lvfJlZQ43rnjKqIGKHWhWWRbkqMsJIUaYDNf/K/sdZZcVO6YKQklubokdkJY+ujArsuJ5cag==", "dev": true }, "caseless": { @@ -2323,11 +2441,17 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "ccount": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", - "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==", - "dev": true + "caw": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", + "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", + "dev": true, + "requires": { + "get-proxy": "^2.0.0", + "isurl": "^1.0.0-alpha5", + "tunnel-agent": "^0.6.0", + "url-to-options": "^1.0.1" + } }, "chainsaw": { "version": "0.1.0", @@ -2355,12 +2479,6 @@ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", "dev": true }, - "character-entities-html4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", - "dev": true - }, "character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", @@ -2374,90 +2492,183 @@ "dev": true }, "cheerio": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", - "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "version": "1.0.0-rc.5", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.5.tgz", + "integrity": "sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==", "dev": true, "requires": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.1", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash": "^4.15.0", - "parse5": "^3.0.1" + "cheerio-select-tmp": "^0.1.0", + "dom-serializer": "~1.2.0", + "domhandler": "^4.0.0", + "entities": "~2.1.0", + "htmlparser2": "^6.0.0", + "parse5": "^6.0.0", + "parse5-htmlparser2-tree-adapter": "^6.0.0" } }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "cheerio-select-tmp": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz", + "integrity": "sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==", "dev": true, - "optional": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "css-select": "^3.1.2", + "css-what": "^4.0.0", + "domelementtype": "^2.1.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.4" } }, - "ci-env": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.16.0.tgz", - "integrity": "sha512-ucF9caQEX5wQlY449KZBIJPx91+kRg9tJ3tWSc4+KzrvC5KNiPm/3g1noP8VhdI3046+Vw3jLmKAD0fjCRJTmw==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "optional": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "chokidar": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz", + "integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, - "optional": true, "requires": { - "is-descriptor": "^0.1.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } - } - } - }, - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "ci-env": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.16.0.tgz", + "integrity": "sha512-ucF9caQEX5wQlY449KZBIJPx91+kRg9tJ3tWSc4+KzrvC5KNiPm/3g1noP8VhdI3046+Vw3jLmKAD0fjCRJTmw==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "optional": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } @@ -2496,21 +2707,6 @@ "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-spinners": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz", - "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==", - "dev": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -2520,39 +2716,8 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } } }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, "clone-regexp": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", @@ -2577,12 +2742,6 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, - "collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "dev": true - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -2666,6 +2825,16 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -2698,9 +2867,9 @@ } }, "confusing-browser-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", - "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", "dev": true }, "connect": { @@ -2727,6 +2896,15 @@ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -2743,9 +2921,9 @@ } }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", "dev": true }, "copy-descriptor": { @@ -2756,12 +2934,12 @@ "optional": true }, "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.2.tgz", + "integrity": "sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ==", "dev": true, "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.16.0", "semver": "7.0.0" }, "dependencies": { @@ -2801,9 +2979,9 @@ } }, "cross-env": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", - "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, "requires": { "cross-spawn": "^7.0.1" @@ -2827,21 +3005,22 @@ "dev": true }, "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", + "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", "dev": true, "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" + "boolbase": "^1.0.0", + "css-what": "^4.0.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.3", + "nth-check": "^2.0.0" } }, "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", + "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", "dev": true }, "cssesc": { @@ -2917,8 +3096,48 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", "dev": true, - "optional": true + "requires": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } }, "decompress-response": { "version": "3.3.0", @@ -2929,6 +3148,101 @@ "mimic-response": "^1.0.0" } }, + "decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "requires": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true + } + } + }, + "decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "requires": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "dependencies": { + "file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true + } + } + }, + "decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "requires": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true + } + } + }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "dev": true, + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "dev": true + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -2947,15 +3261,6 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -3097,38 +3402,40 @@ } }, "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz", + "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==", "dev": true, "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "entities": "^2.0.0" } }, "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", "dev": true }, "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", + "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "^2.1.0" } }, "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz", + "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0" } }, "dot-prop": { @@ -3140,8 +3447,45 @@ "is-obj": "^2.0.0" } }, - "duplexer": { - "version": "0.1.2", + "download": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", + "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", + "dev": true, + "requires": { + "archive-type": "^4.0.0", + "caw": "^2.0.1", + "content-disposition": "^0.5.2", + "decompress": "^4.2.0", + "ext-name": "^5.0.0", + "file-type": "^8.1.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^8.3.1", + "make-dir": "^1.2.0", + "p-event": "^2.1.0", + "pify": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "duplexer": { + "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true @@ -3178,15 +3522,15 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.578", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.578.tgz", - "integrity": "sha512-z4gU6dA1CbBJsAErW5swTGAaU2TBzc2mPAonJb00zqW1rOraDo2zfBMDRvaz9cVic+0JEZiYbHWPw/fTaZlG2Q==", + "version": "1.3.637", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.637.tgz", + "integrity": "sha512-924WXYMYquYybc+7pNApGlhY2RWg3MY3he4BrZ5BUmM2n1MGBsrS+PZxrlo6UAsWuNl4NE66fqFdwsWkBUGgkA==", "dev": true }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "encodeurl": { @@ -3205,17 +3549,17 @@ } }, "engine.io": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", - "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", + "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "0.3.1", + "cookie": "~0.4.1", "debug": "~4.1.0", "engine.io-parser": "~2.2.0", - "ws": "^7.1.2" + "ws": "~7.4.2" }, "dependencies": { "debug": { @@ -3228,17 +3572,17 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } }, "engine.io-client": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.4.tgz", - "integrity": "sha512-iU4CRr38Fecj8HoZEnFtm2EiKGbYZcPn3cHxqNGl/tmdWRf60KhK+9vE0JeSjgnlS/0oynEfLgKbT9ALpim0sQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz", + "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==", "dev": true, "requires": { "component-emitter": "~1.3.0", @@ -3249,7 +3593,7 @@ "indexof": "0.0.1", "parseqs": "0.0.6", "parseuri": "0.0.6", - "ws": "~6.1.0", + "ws": "~7.4.2", "xmlhttprequest-ssl": "~1.5.4", "yeast": "0.1.2" }, @@ -3262,27 +3606,6 @@ "requires": { "ms": "2.0.0" } - }, - "parseqs": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", - "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==", - "dev": true - }, - "parseuri": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", - "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==", - "dev": true - }, - "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } } } }, @@ -3315,9 +3638,15 @@ "dev": true }, "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + }, + "env-paths": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", "dev": true }, "error-ex": { @@ -3360,12 +3689,6 @@ "is-symbol": "^1.0.2" } }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=", - "dev": true - }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -3406,13 +3729,13 @@ "dev": true }, "eslint": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.11.0.tgz", - "integrity": "sha512-G9+qtYVCHaDi1ZuWzBsOWo2wSwd70TXnU6UHA3cTYHp7gCTXZcpggWFoUVAMRarg68qtPoNfFbzPh+VdOgmwmw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz", + "integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.1.3", + "@eslint/eslintrc": "^0.2.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3422,10 +3745,10 @@ "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", + "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", @@ -3445,7 +3768,7 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", + "table": "^6.0.4", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, @@ -3485,9 +3808,9 @@ "dev": true }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -3524,10 +3847,13 @@ "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "supports-color": { "version": "7.2.0", @@ -3551,12 +3877,12 @@ } }, "eslint-config-xo": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.32.1.tgz", - "integrity": "sha512-achnYLilUTtljR1CGRikVj9HRAf5GplJeGgeyQMvph7mKo+AqTkNuig4EO/IrNOChcjoazgw9YT4cW/3+69i3Q==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.34.0.tgz", + "integrity": "sha512-lbpHNfVmSrEQsHsyQ44wY8VA5mEI4Jri5Dk1BJUH0jiCw6nTkj16VQeHiuWzIBJ/uf+mF2FzSqLVf3tD1cHhYA==", "dev": true, "requires": { - "confusing-browser-globals": "1.0.9" + "confusing-browser-globals": "1.0.10" } }, "eslint-import-resolver-node": { @@ -3683,9 +4009,9 @@ } }, "eslint-plugin-unicorn": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-22.0.0.tgz", - "integrity": "sha512-jXPOauNiVFYLr+AeU3l21Ao+iDl/G08vUWui21RCI2L1TJIIoJvAMjMR6I+QPKr8FgIumzuR6gzDKCtEx2IkzA==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-25.0.1.tgz", + "integrity": "sha512-MEyEWoyou/qhJH6rEER9YHACtCsQT+eewc6Fdxbi2eiTvsGrBR8JZMA6qaeof3oMQeRxOpaERoBKzU7R5c4A/w==", "dev": true, "requires": { "ci-info": "^2.0.0", @@ -3700,7 +4026,7 @@ "regexp-tree": "^0.1.21", "reserved-words": "^0.1.2", "safe-regex": "^2.1.1", - "semver": "^7.3.2" + "semver": "^7.3.4" }, "dependencies": { "safe-regex": { @@ -3713,10 +4039,13 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -3731,23 +4060,15 @@ } }, "eslint-template-visitor": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.1.tgz", - "integrity": "sha512-q3SxoBXz0XjPGkUpwGVAwIwIPIxzCAJX1uwfVc8tW3v7u/zS7WXNH3I2Mu2MDz2NgSITAyKLRaQFPHu/iyKxDQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.2.tgz", + "integrity": "sha512-SkcLjzKw3JjKTWHacRDeLBa2gxb600zbCKTkXj/V97QnZ9yxkknoPL8vc8PFueqbFXP7mYNTQzjCjcMpTRdRaA==", "dev": true, "requires": { "babel-eslint": "^10.1.0", - "eslint-visitor-keys": "^1.3.0", + "eslint-visitor-keys": "^2.0.0", "esquery": "^1.3.1", "multimap": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } } }, "eslint-utils": { @@ -3774,13 +4095,13 @@ "dev": true }, "espree": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", - "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", - "acorn-jsx": "^5.2.0", + "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" }, "dependencies": { @@ -3868,6 +4189,74 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, "execall": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", @@ -3877,6 +4266,23 @@ "clone-regexp": "^2.1.0" } }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -3915,6 +4321,25 @@ } } }, + "ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "requires": { + "mime-db": "^1.28.0" + } + }, + "ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "requires": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4114,29 +4539,63 @@ "dev": true }, "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", + "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", "dev": true, "requires": { "reusify": "^1.0.4" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "file-type": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", + "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==", + "dev": true + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "dev": true + }, + "filenamify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", + "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", "dev": true, - "optional": true + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } }, "fill-range": { "version": "4.0.0", @@ -4179,18 +4638,17 @@ } }, "find-unused-sass-variables": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-unused-sass-variables/-/find-unused-sass-variables-2.0.0.tgz", - "integrity": "sha512-P9QHY8AUkREpnAwCgzUysQJ5Z+Uf9NR3wpaeVN1886nNPXGxy4tgapdVzieYX9ISMi5akJGEKr0hrpzFcFMLQA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/find-unused-sass-variables/-/find-unused-sass-variables-3.1.0.tgz", + "integrity": "sha512-ttKh7u4KgbanzrR6Ax2d9fOb/TLDdbvWD3uM4Hx0sO9ofx4whzKIHrg2nCuRrzdiTcFNsWdnf5nOHIGVatOTUQ==", "dev": true, "requires": { - "chalk": "^4.0.0", + "chalk": "^4.1.0", "commander": "^5.1.0", "escape-string-regexp": "^4.0.0", "glob": "^7.1.6", - "ora": "^4.0.4", - "postcss": "^7.0.27", - "postcss-scss": "^2.0.0" + "postcss": "^8.2.2", + "postcss-scss": "^3.0.4" }, "dependencies": { "ansi-styles": { @@ -4266,21 +4724,29 @@ "path-exists": "^4.0.0" } }, + "find-versions": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", + "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "dev": true, + "requires": { + "semver-regex": "^2.0.0" + } + }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", + "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", "dev": true }, "follow-redirects": { @@ -4327,6 +4793,12 @@ "mime-types": "^2.1.12" } }, + "fraction.js": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz", + "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==", + "dev": true + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -4343,6 +4815,22 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -4354,6 +4842,15 @@ "universalify": "^0.1.0" } }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -4367,15 +4864,11 @@ "dev": true }, "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", + "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } + "optional": true }, "fstream": { "version": "1.0.12", @@ -4387,6 +4880,17 @@ "inherits": "~2.0.0", "mkdirp": ">=0.5 0", "rimraf": "2" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "function-bind": { @@ -4455,9 +4959,9 @@ } }, "gaxios": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz", - "integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", "dev": true, "requires": { "abort-controller": "^3.0.0", @@ -4468,18 +4972,18 @@ }, "dependencies": { "agent-base": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", - "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { "debug": "4" } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -4495,6 +4999,12 @@ "debug": "4" } }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4513,9 +5023,9 @@ } }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -4524,12 +5034,32 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", + "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-proxy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", + "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", + "dev": true, + "requires": { + "npm-conf": "^1.1.0" + } + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -4537,13 +5067,10 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true }, "get-value": { "version": "2.0.6", @@ -4599,12 +5126,20 @@ } }, "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", "dev": true, "requires": { - "ini": "^1.3.5" + "ini": "1.3.7" + }, + "dependencies": { + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + } } }, "global-modules": { @@ -4645,15 +5180,15 @@ "dev": true }, "globalyzer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.4.tgz", - "integrity": "sha512-LeguVWaxgHN0MNbWC6YljNMzHkrCny9fzjmEUdnF1kQ7wATFD1RHFRqA1qxaX2tgxGENlcxjOflopBwj3YZiXA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", "dev": true }, "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", + "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -4711,22 +5246,36 @@ } }, "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", "dev": true, "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } } }, "graceful-fs": { @@ -4828,12 +5377,27 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true + }, "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -4900,36 +5464,21 @@ "dev": true }, "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.0.tgz", + "integrity": "sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw==", "dev": true, "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.4.4", + "entities": "^2.0.0" } }, "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", "dev": true }, "http-errors": { @@ -4986,22 +5535,34 @@ }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } }, + "hugo-bin": { + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/hugo-bin/-/hugo-bin-0.68.0.tgz", + "integrity": "sha512-QdmnjN45BGCp4mlKMFUIZFzuZJ/ClW0dVUbeUkgRgxfRlf444Sg5aPKXtLkQgpbP/jCVlxoyVt5sRmhntwtI8Q==", + "dev": true, + "requires": { + "bin-wrapper": "^4.1.0", + "pkg-conf": "^3.1.0", + "rimraf": "^3.0.2", + "signale": "^1.4.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -5011,6 +5572,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -5024,18 +5591,18 @@ "dev": true }, "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz", + "integrity": "sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==", "dev": true, "requires": { - "import-from": "^2.1.0" + "import-from": "^3.0.0" } }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -5051,32 +5618,24 @@ } }, "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", "dev": true, "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } + "resolve-from": "^5.0.0" } }, "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", + "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", "dev": true }, "import-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.0.0.tgz", - "integrity": "sha512-iczM/v9drffdNnABOKwj0f9G3cFDon99VcG1mxeBsdqnbd+vnQ5c2uAiCHNQITqFTOPaEvwg3VjoWCur0uHLEw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz", + "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==", "dev": true }, "imurmurhash": { @@ -5085,12 +5644,6 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "in-publish": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", - "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", - "dev": true - }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -5126,9 +5679,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "interpret": { @@ -5137,13 +5690,14 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", "dev": true, "requires": { - "loose-envify": "^1.0.0" + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" } }, "ip": { @@ -5180,12 +5734,6 @@ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "dev": true }, - "is-alphanumeric": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", - "dev": true - }, "is-alphanumerical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", @@ -5234,6 +5782,15 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -5289,12 +5846,6 @@ } } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, "is-docker": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", @@ -5321,9 +5872,9 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { @@ -5351,22 +5902,22 @@ "is-path-inside": "^3.0.1" } }, - "is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true - }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, + "is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", + "dev": true + }, "is-negative-zero": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", - "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "dev": true }, "is-npm": { @@ -5403,6 +5954,12 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, + "is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true + }, "is-path-inside": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", @@ -5449,10 +6006,16 @@ "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", "dev": true }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true + }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-string": { @@ -5482,12 +6045,6 @@ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, - "is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -5495,12 +6052,6 @@ "dev": true, "optional": true }, - "is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -5630,9 +6181,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -5650,6 +6201,15 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5668,6 +6228,16 @@ "istanbul-lib-report": "^3.0.0" } }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, "jquery": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", @@ -5693,9 +6263,9 @@ "dev": true }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -5766,9 +6336,9 @@ } }, "jsonexport": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.0.1.tgz", - "integrity": "sha512-lxDoAZxmWDt1wa4S75CUYe/ZASdmOYyhV7iYbF4npTWxrDv19ofZpJMGbt20W5Orx0hYuid65zGHpt6rRW0Z3A==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.2.0.tgz", + "integrity": "sha512-GbO9ugb0YTZatPd/hqCGR0FSwbr82H6OzG04yzdrG7XOe4QZ0jhQ+kOsB29zqkzoYJLmLxbbrFiuwbQu891XnQ==", "dev": true }, "jsonfile": { @@ -5835,22 +6405,6 @@ "yargs": "^15.3.1" }, "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -5860,22 +6414,6 @@ "fill-range": "^7.0.1" } }, - "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5885,55 +6423,12 @@ "to-regex-range": "^5.0.1" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6016,12 +6511,13 @@ } }, "karma-firefox-launcher": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.3.0.tgz", - "integrity": "sha512-Fi7xPhwrRgr+94BnHX0F5dCl1miIW4RHnzjIGxF8GaIEp7rNqX7LSi7ok63VXs3PS/5MQaQMhGxw+bvD+pibBQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.0.tgz", + "integrity": "sha512-dkiyqN2R6fCWt78rciOXJLFDWcQ7QEQi++HgebPJlw1y0ycDjGNDHuSrhdh48QG02fzZKK20WHFWVyBZ6CPngg==", "dev": true, "requires": { - "is-wsl": "^2.1.0" + "is-wsl": "^2.2.0", + "which": "^2.0.1" } }, "karma-qunit": { @@ -6037,9 +6533,9 @@ "dev": true }, "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", "dev": true, "requires": { "json-buffer": "3.0.0" @@ -6052,9 +6548,9 @@ "dev": true }, "known-css-properties": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.19.0.tgz", - "integrity": "sha512-eYboRV94Vco725nKMlpkn3nV2+96p9c3gKXRsYqAJSswSENvBhN7n5L+uDhY58xQa0UukWsDMTGELzmD8Q+wTA==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.20.0.tgz", + "integrity": "sha512-URvsjaA9ypfreqJ2/ylDr5MUERhJZ+DhguoWRr2xgS5C7aGCalXo+ewL+GixgKBfhT2vuL02nbIgNGqVWgTOYw==", "dev": true }, "latest-version": { @@ -6066,21 +6562,6 @@ "package-json": "^6.3.0" } }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "requires": { - "leven": "^3.1.0" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6098,17 +6579,19 @@ "dev": true }, "linkinator": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.1.3.tgz", - "integrity": "sha512-MBjaTkMiBuoUq0+e8CtWhlSo6AR+TojNQ7USNCoIiaClI/71o6mF3wrPEizSCwMTjFviHbm/M7JD1M8/0vIFnw==", + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.11.2.tgz", + "integrity": "sha512-TmTtsxSiea6gL/vjd0rD1X7FZzRHLzWeaO+1QMiQh+OTKXCd+LW38ChTQjcxt1XNZ3BH9aAsoG+vxRhNkAY1Wg==", "dev": true, "requires": { "chalk": "^4.0.0", "cheerio": "^1.0.0-rc.2", "finalhandler": "^1.1.2", - "gaxios": "^3.0.0", + "gaxios": "^4.0.0", + "glob": "^7.1.6", "jsonexport": "^3.0.0", - "meow": "^7.0.0", + "marked": "^1.2.5", + "meow": "^8.0.0", "p-queue": "^6.2.1", "serve-static": "^1.14.1", "server-destroy": "^1.0.1", @@ -6223,9 +6706,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -6251,9 +6734,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -6273,18 +6756,42 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.forown": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz", + "integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68=", + "dev": true + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, + "lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, "lodash.zip": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", @@ -6292,12 +6799,63 @@ "dev": true }, "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "requires": { - "chalk": "^2.4.2" + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "log4js": { @@ -6314,14 +6872,20 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" } }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -6342,15 +6906,6 @@ "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -6368,13 +6923,12 @@ "dev": true }, "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "yallist": "^4.0.0" } }, "magic-string": { @@ -6419,41 +6973,56 @@ "object-visit": "^1.0.0" } }, - "markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "marked": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz", + "integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==", "dev": true }, - "markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "dev": true, - "requires": { - "repeat-string": "^1.0.0" - } - }, "mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true }, - "mdast-util-compact": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-2.0.1.tgz", - "integrity": "sha512-7GlnT24gEwDrdAwEHrU4Vv5lLWrEer4KOkAiKT9nYstsTad7Oc1TwqT2zIMKRdZF7cTuaf+GA1E4Kv7jJh8mPA==", + "mdast-util-from-markdown": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.4.tgz", + "integrity": "sha512-jj891B5pV2r63n2kBTFh8cRI2uR9LQHsXG1zSDqfhXkIlDzrTcIlbB5+5aaYEkl8vOPIOPLf8VT7Ere1wWTMdw==", "dev": true, "requires": { - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" } }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true + "mdast-util-to-markdown": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.2.tgz", + "integrity": "sha512-iRczns6WMvu0hUw02LXsPDJshBIwtUPbvHBWo19IQeU0YqmzlA8Pd30U8V7uiI0VPkxzS7A/NXBXH6u+HS87Zg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + } + }, + "mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true }, "memorystream": { "version": "0.3.1", @@ -6462,9 +7031,9 @@ "dev": true }, "meow": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", - "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -6472,18 +7041,54 @@ "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", - "normalize-package-data": "^2.5.0", + "normalize-package-data": "^3.0.0", "read-pkg-up": "^7.0.1", "redent": "^3.0.0", "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "dependencies": { + "hosted-git-info": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", + "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "normalize-package-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.0.tgz", + "integrity": "sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==", + "dev": true, + "requires": { + "hosted-git-info": "^3.0.6", + "resolve": "^1.17.0", + "semver": "^7.3.2", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true } } @@ -6494,6 +7099,33 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "micromark": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.2.tgz", + "integrity": "sha512-IXuP76p2uj8uMg4FQc1cRE7lPCLsfAXuEfdjtdO55VRiFO1asrCSQ5g43NmPqFtRwzEnEhafRVzn2jg0UiKArQ==", + "dev": true, + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -6517,32 +7149,26 @@ } }, "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.7.tgz", + "integrity": "sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA==", "dev": true }, "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", "dev": true }, "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", "dev": true, "requires": { - "mime-db": "1.44.0" + "mime-db": "1.45.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -6581,6 +7207,25 @@ "kind-of": "^6.0.3" } }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -6625,16 +7270,16 @@ "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", "dev": true }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", "dev": true }, "nanomatch": { @@ -6706,66 +7351,57 @@ "dev": true }, "node-gyp": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "dev": true, "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" }, "dependencies": { "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "dev": true, "requires": { - "isexe": "^2.0.0" + "lru-cache": "^6.0.0" } } } }, "node-releases": { - "version": "1.1.61", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.61.tgz", - "integrity": "sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g==", + "version": "1.1.69", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.69.tgz", + "integrity": "sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==", "dev": true }, "node-sass": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", - "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz", + "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==", "dev": true, "requires": { "async-foreach": "^0.1.3", "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", + "cross-spawn": "^7.0.3", "gaze": "^1.0.0", "get-stdin": "^4.0.1", "glob": "^7.0.3", - "in-publish": "^2.0.0", "lodash": "^4.17.15", "meow": "^3.7.0", "mkdirp": "^0.5.1", "nan": "^2.13.2", - "node-gyp": "^3.8.0", + "node-gyp": "^7.1.0", "npmlog": "^4.0.0", "request": "^2.88.0", "sass-graph": "2.2.5", @@ -6814,16 +7450,6 @@ "supports-color": "^2.0.0" } }, - "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -6984,28 +7610,19 @@ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, "node-watch": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.4.tgz", - "integrity": "sha512-cI6CHzivIFESe8djiK3Wh90CtWQBxLwMem8x8S+2GSvCvFgoMuOKVlfJtQ/2v3Afg3wOnHl/+tXotEs8z5vOrg==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.1.tgz", + "integrity": "sha512-UWblPYuZYrkCQCW5PxAwYSxaELNBLUckrTBBk8xr1/bUgyOkYYTsUcV4e3ytcazFEOyiRyiUrsG37pu6I0I05g==", "dev": true }, "nodemon": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", - "integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", "dev": true, "requires": { "chokidar": "^3.2.2", @@ -7016,8 +7633,8 @@ "semver": "^5.7.1", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^4.0.0" + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" }, "dependencies": { "ansi-styles": { @@ -7029,31 +7646,6 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -7075,22 +7667,6 @@ } } }, - "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7107,53 +7683,25 @@ "dev": true }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "is-binary-path": { + "import-lazy": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true }, "is-npm": { "version": "4.0.0", @@ -7161,36 +7709,12 @@ "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "dev": true }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "update-notifier": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", @@ -7215,9 +7739,9 @@ } }, "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "dev": true, "requires": { "abbrev": "1" @@ -7254,10 +7778,44 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "dependencies": { + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + } + } + }, + "npm-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "dev": true, + "requires": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } }, "npm-run-all": { "version": "4.1.5", @@ -7369,6 +7927,23 @@ } } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + } + } + }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", @@ -7382,12 +7957,12 @@ } }, "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", "dev": true, "requires": { - "boolbase": "~1.0.0" + "boolbase": "^1.0.0" } }, "num2fraction": { @@ -7414,12 +7989,6 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -7455,15 +8024,15 @@ } }, "object-hash": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", - "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", + "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==", "dev": true }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, "object-keys": { @@ -7483,13 +8052,13 @@ } }, "object.assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", - "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.0", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" } @@ -7505,36 +8074,15 @@ } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", + "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "on-finished": { @@ -7555,15 +8103,6 @@ "wrappy": "1" } }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -7578,107 +8117,42 @@ "word-wrap": "^1.2.3" } }, - "ora": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz", - "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==", + "os-filter-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", + "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", "dev": true, "requires": { - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.2.0", - "is-interactive": "^1.0.0", - "log-symbols": "^3.0.0", - "mute-stream": "0.0.8", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "arch": "^2.1.0" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", "dev": true }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "p-timeout": "^2.0.1" } }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -7705,12 +8179,23 @@ "requires": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" + }, + "dependencies": { + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + } } }, "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", "dev": true, "requires": { "p-finally": "^1.0.0" @@ -7734,6 +8219,90 @@ "semver": "^6.2.0" }, "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -7778,31 +8347,31 @@ } }, "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, "requires": { - "@types/node": "*" + "parse5": "^6.0.1" } }, "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==", + "dev": true }, "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==", + "dev": true }, "parseurl": { "version": "1.3.3", @@ -7882,6 +8451,12 @@ } } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -7921,6 +8496,81 @@ "pinkie": "^2.0.0" } }, + "pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", @@ -8001,14 +8651,14 @@ "optional": true }, "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", + "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "colorette": "^1.2.1", + "nanoid": "^3.1.20", + "source-map": "^0.6.1" }, "dependencies": { "source-map": { @@ -8016,22 +8666,13 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, "postcss-cli": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-7.1.2.tgz", - "integrity": "sha512-3mlEmN1v2NVuosMWZM2tP8bgZn7rO5PYxRRrXtdSyL5KipcgBDjJ9ct8/LKxImMCJJi3x5nYhCGFJOkGyEqXBQ==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-8.3.1.tgz", + "integrity": "sha512-leHXsQRq89S3JC9zw/tKyiVV2jAhnfQe0J8VI4eQQbUjwIe0XxVqLrR+7UsahF1s9wi4GlqP6SJ8ydf44cgF2Q==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -8040,12 +8681,12 @@ "fs-extra": "^9.0.0", "get-stdin": "^8.0.0", "globby": "^11.0.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "postcss-reporter": "^6.0.0", + "postcss-load-config": "^3.0.0", + "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", - "yargs": "^15.0.2" + "slash": "^3.0.0", + "yargs": "^16.0.0" }, "dependencies": { "ansi-styles": { @@ -8057,31 +8698,6 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -8092,20 +8708,15 @@ "supports-color": "^7.1.0" } }, - "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, "color-convert": { @@ -8123,15 +8734,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "fs-extra": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", @@ -8144,67 +8746,41 @@ "universalify": "^1.0.0" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, "get-stdin": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, "supports-color": { "version": "7.2.0", @@ -8215,20 +8791,49 @@ "has-flag": "^4.0.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "universalify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } }, @@ -8239,63 +8844,154 @@ "dev": true, "requires": { "htmlparser2": "^3.10.0" + }, + "dependencies": { + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", + "dev": true + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, - "postcss-less": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", - "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } - }, - "postcss-load-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", - "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", "dev": true, "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" + "postcss": "^7.0.14" }, "dependencies": { - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "has-flag": "^3.0.0" } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + } + } + }, + "postcss-load-config": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.0.0.tgz", + "integrity": "sha512-lErrN8imuEF1cSiHBV8MiR7HeuzlDpCGNtaMyYHlOBuJHHOGw6S4xOMZp8BbXPr7AGQp14L6PZDlIOpfFJ6f7w==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "import-cwd": "^3.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" } }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true } } @@ -8307,26 +9003,17 @@ "dev": true }, "postcss-reporter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", - "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.2.tgz", + "integrity": "sha512-JyQ96NTQQsso42y6L1H1RqHfWH1C3Jr0pt91mVv5IdYddZAE9DUZxuferNgk6q0o6vBVOrfVJb10X1FgDzjmDw==", "dev": true, "requires": { - "chalk": "^2.4.1", - "lodash": "^4.17.11", - "log-symbols": "^2.2.0", - "postcss": "^7.0.7" - }, - "dependencies": { - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - } + "colorette": "^1.2.1", + "lodash.difference": "^4.5.0", + "lodash.forown": "^4.4.0", + "lodash.get": "^4.4.2", + "lodash.groupby": "^4.6.0", + "lodash.sortby": "^4.7.0" } }, "postcss-resolve-nested-selector": { @@ -8342,6 +9029,34 @@ "dev": true, "requires": { "postcss": "^7.0.26" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "postcss-sass": { @@ -8352,15 +9067,43 @@ "requires": { "gonzales-pe": "^4.3.0", "postcss": "^7.0.21" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "postcss-scss": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", - "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-3.0.4.tgz", + "integrity": "sha512-BAkBZ35aXhCeBRmliHylYqTN1PvNJyh9aBPQHUmk9SdDdbk7n3GExm7cQivDckOgJpB+agyig9TwRAmf6WnvfA==", "dev": true, "requires": { - "postcss": "^7.0.6" + "postcss": "^8.1.6" } }, "postcss-selector-parser": { @@ -8383,6 +9126,34 @@ "requires": { "lodash": "^4.17.14", "postcss": "^7.0.17" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "postcss-syntax": { @@ -8427,6 +9198,12 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -8462,9 +9239,9 @@ "dev": true }, "pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dev": true, "requires": { "escape-goat": "^2.0.0" @@ -8488,6 +9265,17 @@ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -8495,21 +9283,21 @@ "dev": true }, "qunit": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.11.3.tgz", - "integrity": "sha512-38gyZblz6kjV4G+6cn18Vvsh3ESnCXH9YXtfMJQGpKXWzLzUj8W/8iUewP+TsLwv95GQUXtMf2nl8h1iKsybFA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.14.0.tgz", + "integrity": "sha512-CYfenbgdpmhl2Ql2rDrrj0felY4h8k6lYhtWwGBCLL4qQC33YOj0psV8MWo85L1i0SIOmEDRXkFopWnGCLmf7g==", "dev": true, "requires": { - "commander": "6.0.0", + "commander": "6.2.0", "js-reporters": "1.2.3", - "node-watch": "0.6.4", - "tiny-glob": "0.2.6" + "node-watch": "0.7.1", + "tiny-glob": "0.2.8" }, "dependencies": { "commander": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.0.0.tgz", - "integrity": "sha512-s7EA+hDtTYNhuXkTlhqew4txMZVdszBmKWSPEMxGr8ru8JXR7bLUFIAtPhcSuFdJQ0ILMxnJi8GkQL0yvDy/YA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", "dev": true } } @@ -8647,9 +9435,9 @@ } }, "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true }, "regenerate-unicode-properties": { @@ -8714,9 +9502,9 @@ } }, "registry-auth-token": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", - "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { "rc": "^1.2.8" @@ -8738,9 +9526,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.6.tgz", + "integrity": "sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -8755,60 +9543,32 @@ } }, "remark": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-12.0.1.tgz", - "integrity": "sha512-gS7HDonkdIaHmmP/+shCPejCEEW+liMp/t/QwmF0Xt47Rpuhl32lLtDV1uKWvGoq+kxr5jSgg5oAIpGuyULjUw==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", "dev": true, "requires": { - "remark-parse": "^8.0.0", - "remark-stringify": "^8.0.0", - "unified": "^9.0.0" + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" } }, "remark-parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", - "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", "dev": true, "requires": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" + "mdast-util-from-markdown": "^0.8.0" } }, "remark-stringify": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-8.1.1.tgz", - "integrity": "sha512-q4EyPZT3PcA3Eq7vPpT6bIdokXzFGp9i85igjmhRyXWmPs0Y6/d2FYwUNotKAWyLch7g0ASZJn/KHHcHZQ163A==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", "dev": true, "requires": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^2.0.0", - "mdast-util-compact": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^3.0.0", - "unherit": "^1.0.4", - "xtend": "^4.0.1" + "mdast-util-to-markdown": "^0.6.0" } }, "remove-trailing-separator": { @@ -8840,12 +9600,6 @@ "is-finite": "^1.0.0" } }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -8888,6 +9642,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -8907,11 +9667,12 @@ "dev": true }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, @@ -8937,16 +9698,6 @@ "lowercase-keys": "^1.0.0" } }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -8967,18 +9718,18 @@ "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, "rollup": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.29.0.tgz", - "integrity": "sha512-gtU0sjxMpsVlpuAf4QXienPmUAhd6Kc7owQ4f5lypoxBW18fw2UNYZ4NssLGsri6WhUZkE/Ts3EMRebN+gNLiQ==", + "version": "2.36.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.36.1.tgz", + "integrity": "sha512-eAfqho8dyzuVvrGqpR0ITgEdq0zG2QJeWYh+HeuTbpcaXk8vNFc48B7bJa1xYosTCKx0CuW+447oQOW8HgBIZQ==", "dev": true, "requires": { "fsevents": "~2.1.2" @@ -8994,9 +9745,9 @@ } }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", "dev": true }, "safe-buffer": { @@ -9050,6 +9801,12 @@ "wrap-ansi": "^5.1.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -9059,6 +9816,12 @@ "locate-path": "^3.0.0" } }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -9084,6 +9847,17 @@ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -9155,6 +9929,23 @@ } } }, + "seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "requires": { + "commander": "^2.8.1" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -9178,6 +9969,21 @@ } } }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "dev": true + }, + "semver-truncate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", + "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -9306,23 +10112,112 @@ "rechoir": "^0.6.2" } }, - "shx": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.2.tgz", - "integrity": "sha512-aS0mWtW3T2sHAenrSrip2XGv39O9dXIFUqxAEWHEOS1ePtGIBavdPJY1kE2IHl14V/4iCbUiNDPGdyYTtmhSoA==", + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", "dev": true, "requires": { - "es6-object-assign": "^1.0.3", - "minimist": "^1.2.0", - "shelljs": "^0.8.1" + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + } + } } }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, "sinon": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz", @@ -9345,14 +10240,40 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } } }, "snapdragon": { @@ -9473,16 +10394,16 @@ } }, "socket.io": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", - "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz", + "integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==", "dev": true, "requires": { "debug": "~4.1.0", - "engine.io": "~3.4.0", + "engine.io": "~3.5.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.3.0", + "socket.io-client": "2.4.0", "socket.io-parser": "~3.4.0" }, "dependencies": { @@ -9496,9 +10417,9 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } @@ -9510,46 +10431,31 @@ "dev": true }, "socket.io-client": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", - "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", + "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", "dev": true, "requires": { "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "engine.io-client": "~3.4.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", "has-binary2": "~1.0.2", - "has-cors": "1.1.0", "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", + "parseqs": "0.0.6", + "parseuri": "0.0.6", "socket.io-parser": "~3.3.0", "to-array": "0.1.4" }, "dependencies": { - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "isarray": { @@ -9558,44 +10464,15 @@ "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", "dev": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "socket.io-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.1.tgz", - "integrity": "sha512-1QLvVAe8dTz+mKmZ07Swxt+LAo4Y1ff50rlyoEx00TQmDFVQYPfcqGvIDJLGaBdhdNCecXtyKpD+EgKGcmmbuQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", "dev": true, "requires": { "component-emitter": "~1.3.0", "debug": "~3.1.0", "isarray": "2.0.1" - }, - "dependencies": { - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } } } } @@ -9633,13 +10510,31 @@ "dev": true }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", + "dev": true, + "requires": { + "sort-keys": "^1.0.0" + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -9718,9 +10613,9 @@ } }, "spdx-license-ids": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", - "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, "specificity": { @@ -9762,12 +10657,6 @@ "tweetnacl": "~0.14.0" } }, - "state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true - }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -9824,9 +10713,9 @@ "dev": true }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -9840,125 +10729,52 @@ } } }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "string.prototype.padend": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz", - "integrity": "sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.1.tgz", + "integrity": "sha512-eCzTASPnoCr5Ht+Vn1YXgm8SB015hHKgEIMu9Nr9bQmLhRBxKRfmzSj/IQsxDFc8JInJDDFA0qXwK+xxI7wDkg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "es-abstract": "^1.18.0-next.1" } }, "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string_decoder": { @@ -9970,19 +10786,6 @@ "safe-buffer": "~5.1.0" } }, - "stringify-entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.0.1.tgz", - "integrity": "sha512-Lsk3ISA2++eJYqBMPKcr/8eby1I6L0gP0NlxF8Zja6c05yr/yCYyb2c9PwXjd08Ib3If1vn1rbs1H5ZtVuOfvQ==", - "dev": true, - "requires": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.2", - "is-hexadecimal": "^1.0.0" - } - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -9998,6 +10801,21 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "requires": { + "is-natural-number": "^4.0.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -10013,6 +10831,15 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, "style-search": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", @@ -10020,22 +10847,22 @@ "dev": true }, "stylelint": { - "version": "13.7.2", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.7.2.tgz", - "integrity": "sha512-mmieorkfmO+ZA6CNDu1ic9qpt4tFvH2QUB7vqXgrMVHe5ENU69q7YDq0YUg/UHLuCsZOWhUAvcMcLzLDIERzSg==", + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.8.0.tgz", + "integrity": "sha512-iHH3dv3UI23SLDrH4zMQDjLT9/dDIz/IpoFeuNxZmEx86KtfpjDOscxLTFioQyv+2vQjPlRZnK0UoJtfxLICXQ==", "dev": true, "requires": { "@stylelint/postcss-css-in-js": "^0.37.2", - "@stylelint/postcss-markdown": "^0.36.1", + "@stylelint/postcss-markdown": "^0.36.2", "autoprefixer": "^9.8.6", "balanced-match": "^1.0.0", "chalk": "^4.1.0", "cosmiconfig": "^7.0.0", - "debug": "^4.1.1", + "debug": "^4.2.0", "execall": "^2.0.0", "fast-glob": "^3.2.4", "fastest-levenshtein": "^1.0.12", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "get-stdin": "^8.0.0", "global-modules": "^2.0.0", "globby": "^11.0.1", @@ -10044,14 +10871,14 @@ "ignore": "^5.1.8", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", - "known-css-properties": "^0.19.0", + "known-css-properties": "^0.20.0", "lodash": "^4.17.20", "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", - "meow": "^7.1.1", + "meow": "^8.0.0", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", - "postcss": "^7.0.32", + "postcss": "^7.0.35", "postcss-html": "^0.36.0", "postcss-less": "^3.1.4", "postcss-media-query-parser": "^0.2.3", @@ -10059,7 +10886,7 @@ "postcss-safe-parser": "^4.0.2", "postcss-sass": "^0.4.4", "postcss-scss": "^2.1.1", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^6.0.4", "postcss-syntax": "^0.36.2", "postcss-value-parser": "^4.1.0", "resolve-from": "^5.0.0", @@ -10070,26 +10897,26 @@ "style-search": "^0.1.0", "sugarss": "^2.0.0", "svg-tags": "^1.0.0", - "table": "^6.0.1", - "v8-compile-cache": "^2.1.1", + "table": "^6.0.3", + "v8-compile-cache": "^2.2.0", "write-file-atomic": "^3.0.3" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "autoprefixer": { + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", "dev": true, "requires": { - "color-convert": "^2.0.1" + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" } }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -10107,6 +10934,32 @@ "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "color-convert": { @@ -10138,20 +10991,14 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" } }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -10167,12 +11014,6 @@ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", @@ -10185,27 +11026,12 @@ "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, - "requires": { - "chalk": "^4.0.0" - } - }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -10225,56 +11051,72 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + } } }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "postcss": "^7.0.6" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, - "table": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.3.tgz", - "integrity": "sha512-8321ZMcf1B9HvVX/btKv8mMZahCjn2aYrDlpqHaBFCfnox64edeH9kEid0vTLTRR8gWR2A20aDgeuTTea4sVtw==", + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "ajv": "^6.12.4", - "lodash": "^4.17.20", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" + "has-flag": "^3.0.0" } }, "to-regex-range": { @@ -10333,6 +11175,34 @@ "lodash": "^4.17.15", "postcss": "^7.0.31", "postcss-sorting": "^5.0.1" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "stylelint-scss": { @@ -10355,6 +11225,34 @@ "dev": true, "requires": { "postcss": "^7.0.2" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "supports-color": { @@ -10373,38 +11271,84 @@ "dev": true }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^7.0.2", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ajv": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", + "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } } }, "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "dev": true, "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" } }, "term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "dev": true }, "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.1.0.tgz", + "integrity": "sha512-pwC1Jbzahz1ZPU87NQ8B3g5pKbhyJSiHih4gLH6WZiPU8mmS1IlGbB0A2Nuvkj/LCNsgIKctg6GkYwWCeTvXZQ==", "dev": true, "requires": { "commander": "^2.20.0", @@ -10443,14 +11387,26 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, "tiny-glob": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.6.tgz", - "integrity": "sha512-A7ewMqPu1B5PWwC3m7KVgAu96Ch5LA0w4SnEN/LbDREj/gAD0nPWboRbn8YoP9ISZXqeNAlMvKSKoEuhcfK3Pw==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.8.tgz", + "integrity": "sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==", "dev": true, "requires": { - "globalyzer": "^0.1.0", - "globrex": "^0.1.1" + "globalyzer": "0.1.0", + "globrex": "^0.1.2" } }, "tmp": { @@ -10460,17 +11416,6 @@ "dev": true, "requires": { "rimraf": "^3.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "to-array": { @@ -10479,6 +11424,12 @@ "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", "dev": true }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -10579,23 +11530,20 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", "dev": true }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true - }, "trim-newlines": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", "dev": true }, - "trim-trailing-lines": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", - "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==", - "dev": true + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } }, "trough": { "version": "1.0.5", @@ -10696,6 +11644,16 @@ "integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==", "dev": true }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, "undefsafe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", @@ -10705,16 +11663,6 @@ "debug": "^2.2.0" } }, - "unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "requires": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - } - }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -10758,9 +11706,9 @@ }, "dependencies": { "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true }, "is-plain-obj": { @@ -10800,29 +11748,20 @@ } }, "unist-util-find-all-after": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.1.tgz", - "integrity": "sha512-0GICgc++sRJesLwEYDjFVJPJttBpVQaTNgc6Jw0Jhzvfs+jtKePEMu+uD+PqkRUrAvGQqwhpDwLGWo1PK8PDEw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz", + "integrity": "sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==", "dev": true, "requires": { "unist-util-is": "^4.0.0" } }, "unist-util-is": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", "dev": true }, - "unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", - "dev": true, - "requires": { - "unist-util-visit": "^2.0.0" - } - }, "unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", @@ -10832,27 +11771,6 @@ "@types/unist": "^2.0.2" } }, - "unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - } - }, - "unist-util-visit-parents": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.0.tgz", - "integrity": "sha512-0g4wbluTF93npyPrp/ymd3tCDTMnP0yo2akFD2FIBAYXq/Sga3lwaU1D8OYKbtpioaI6CkDcQ6fsMnmtzt7htw==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - } - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -10934,9 +11852,9 @@ "optional": true }, "update-notifier": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.0.0.tgz", - "integrity": "sha512-8tqsiVrMv7aZsKNSjqA6DdBLKJpZG1hRpkj1RbOJu1PgyP69OX+EInAnP1EK/ShX5YdPFgwWdk19oquZ0HTM8g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.0.1.tgz", + "integrity": "sha512-BuVpRdlwxeIOvmc32AGYvO1KVdPlsmqSh8KDDBxS6kDE5VR7R8OMP1d8MdhaVBvxl4H3551k9akXr0Y1iIB2Wg==", "dev": true, "requires": { "boxen": "^4.2.0", @@ -10945,11 +11863,11 @@ "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", + "is-installed-globally": "^0.3.2", "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", "semver": "^7.3.2", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" @@ -10995,12 +11913,21 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11013,9 +11940,9 @@ } }, "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -11037,6 +11964,12 @@ "prepend-http": "^2.0.0" } }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -11063,9 +11996,9 @@ "dev": true }, "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, "validate-npm-package-license": { @@ -11090,32 +12023,25 @@ } }, "vfile": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.0.tgz", - "integrity": "sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "dev": true, "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" }, "dependencies": { "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true } } }, - "vfile-location": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.1.0.tgz", - "integrity": "sha512-FCZ4AN9xMcjFIG1oGmZKo61PjwJHRVA+0/tPUP2ul4uIwjGGndIxavEMRpWn5p4xwm/ZsdXp9YNygf1ZyE4x8g==", - "dev": true - }, "vfile-message": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", @@ -11138,15 +12064,6 @@ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", "dev": true }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -11177,6 +12094,12 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -11205,31 +12128,6 @@ "dev": true, "requires": { "string-width": "^4.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } } }, "word-wrap": { @@ -11272,29 +12170,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } } } }, @@ -11304,15 +12179,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -11326,9 +12192,9 @@ } }, "ws": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", - "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", "dev": true }, "xdg-basedir": { @@ -11350,15 +12216,15 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yaml": { @@ -11384,31 +12250,6 @@ "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } } }, "yargs-parser": { @@ -11421,11 +12262,27 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", "dev": true + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true } } } diff --git a/vendor/twbs/bootstrap/package.js b/vendor/twbs/bootstrap/package.js index aca0bede0..c55620aab 100644 --- a/vendor/twbs/bootstrap/package.js +++ b/vendor/twbs/bootstrap/package.js @@ -1,17 +1,19 @@ // package metadata file for Meteor.js +/* eslint-env meteor */ + Package.describe({ name: 'twbs:bootstrap', // https://atmospherejs.com/twbs/bootstrap summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.', - version: '4.5.3', + version: '4.6.0', git: 'https://github.com/twbs/bootstrap.git' -}); +}) -Package.onUse(function (api) { - api.versionsFrom('METEOR@1.0'); - api.use('jquery', 'client'); +Package.onUse(api => { + api.versionsFrom('METEOR@1.0') + api.use('jquery', 'client') api.addFiles([ 'dist/css/bootstrap.css', 'dist/js/bootstrap.js' - ], 'client'); -}); + ], 'client') +}) diff --git a/vendor/twbs/bootstrap/package.json b/vendor/twbs/bootstrap/package.json index 7343246fc..4da8cdd70 100644 --- a/vendor/twbs/bootstrap/package.json +++ b/vendor/twbs/bootstrap/package.json @@ -1,8 +1,10 @@ { "name": "bootstrap", "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", - "version": "4.5.3", - "version_short": "4.5", + "version": "4.6.0", + "config": { + "version_short": "4.6" + }, "keywords": [ "css", "sass", @@ -20,73 +22,56 @@ "scripts": { "start": "npm-run-all --parallel watch docs-serve", "bundlewatch": "bundlewatch --config .bundlewatch.config.json", - "css": "npm-run-all css-compile css-prefix css-minify css-copy", - "css-copy": "cross-env-shell shx mkdir -p site/docs/$npm_package_version_short/dist/ && cross-env-shell shx cp -r dist/css/ site/docs/$npm_package_version_short/dist/", - "css-main": "npm-run-all css-lint css-compile-main css-prefix-main css-minify-main css-copy", - "css-docs": "npm-run-all css-compile-docs css-prefix-docs css-minify-docs", - "css-compile": "npm-run-all --parallel css-compile-*", - "css-compile-main": "node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 scss/ -o dist/css/ && npm run css-copy", - "css-compile-docs": "cross-env-shell node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 site/docs/$npm_package_version_short/assets/scss/docs.scss site/docs/$npm_package_version_short/assets/css/docs.min.css", + "css": "npm-run-all css-compile css-prefix css-minify", + "css-compile": "node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 scss/ -o dist/css/", "css-lint": "npm-run-all --continue-on-error --parallel css-lint-*", - "css-lint-main": "stylelint \"scss/**/*.scss\" --cache --cache-location .cache/.stylelintcache --rd", - "css-lint-docs": "stylelint \"site/docs/**/assets/scss/*.scss\" \"site/docs/**/*.css\" --cache --cache-location .cache/.stylelintcache", - "css-lint-vars": "fusv scss/ site/docs/", - "css-minify": "npm-run-all --parallel css-minify-*", - "css-minify-main": "cleancss --level 1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap.min.css dist/css/bootstrap.css && cleancss --level 1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-grid.min.css dist/css/bootstrap-grid.css && cleancss --level 1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-reboot.min.css dist/css/bootstrap-reboot.css", - "css-minify-docs": "cross-env-shell cleancss --level 1 --format breakWith=lf --source-map --source-map-inline-sources --output site/docs/$npm_package_version_short/assets/css/docs.min.css site/docs/$npm_package_version_short/assets/css/docs.min.css", + "css-lint-stylelint": "stylelint \"**/*.{css,scss}\" --cache --cache-location .cache/.stylelintcache --rd", + "css-lint-vars": "fusv scss/ site/assets/scss/", + "css-minify": "cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap.min.css dist/css/bootstrap.css && cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-grid.min.css dist/css/bootstrap-grid.css && cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources --output dist/css/bootstrap-reboot.min.css dist/css/bootstrap-reboot.css", "css-prefix": "npm-run-all --parallel css-prefix-*", "css-prefix-main": "postcss --config build/postcss.config.js --replace \"dist/css/*.css\" \"!dist/css/*.min.css\"", - "css-prefix-docs": "postcss --config build/postcss.config.js --replace \"site/docs/**/*.css\"", - "js": "npm-run-all js-compile js-minify js-copy", - "js-copy": "cross-env-shell shx mkdir -p site/docs/$npm_package_version_short/dist/ && cross-env-shell shx cp -r dist/js/ site/docs/$npm_package_version_short/dist/", - "js-main": "npm-run-all js-lint js-compile js-minify-main", - "js-docs": "npm-run-all js-lint-docs js-minify-docs", - "js-compile": "npm-run-all --parallel js-compile-* --sequential js-copy", + "css-prefix-examples": "postcss --config build/postcss.config.js --replace \"site/content/**/*.css\"", + "js": "npm-run-all js-compile js-minify", + "js-compile": "npm-run-all --parallel js-compile-*", "js-compile-standalone": "rollup --environment BUNDLE:false --config build/rollup.config.js --sourcemap", "js-compile-bundle": "rollup --environment BUNDLE:true --config build/rollup.config.js --sourcemap", "js-compile-plugins": "node build/build-plugins.js", "js-compile-plugins-coverage": "cross-env NODE_ENV=test node build/build-plugins.js", - "js-lint": "npm-run-all --continue-on-error --parallel js-lint-*", - "js-lint-main": "eslint --report-unused-disable-directives --cache --cache-location .cache/.eslintcache js/src js/tests build/", - "js-lint-docs": "eslint --report-unused-disable-directives --cache --cache-location .cache/.eslintcache site/", - "js-minify": "npm-run-all --parallel js-minify-main js-minify-docs", - "js-minify-main": "npm-run-all js-minify-standalone js-minify-bundle", + "js-lint": "eslint --cache --cache-location .cache/.eslintcache --report-unused-disable-directives .", + "js-minify": "npm-run-all --parallel js-minify-*", "js-minify-standalone": "terser --compress typeofs=false --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js", "js-minify-bundle": "terser --compress typeofs=false --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js", - "js-minify-docs": "cross-env-shell terser --mangle --comments \\\"/^!/\\\" --output site/docs/$npm_package_version_short/assets/js/docs.min.js site/docs/$npm_package_version_short/assets/js/vendor/anchor.min.js site/docs/$npm_package_version_short/assets/js/vendor/clipboard.min.js site/docs/$npm_package_version_short/assets/js/vendor/bs-custom-file-input.min.js \"site/docs/$npm_package_version_short/assets/js/src/*.js\"", - "js-test": "npm-run-all js-test-karma* js-test-integration", + "js-test": "npm-run-all --parallel js-test-karma* --serial js-test-integration", "js-test-karma": "karma start js/tests/karma.conf.js", "js-test-karma-old": "cross-env USE_OLD_JQUERY=true npm run js-test-karma", "js-test-karma-bundle": "cross-env BUNDLE=true npm run js-test-karma", "js-test-karma-bundle-old": "cross-env BUNDLE=true USE_OLD_JQUERY=true npm run js-test-karma", "js-test-integration": "rollup --config js/tests/integration/rollup.bundle.js", - "js-test-cloud": "cross-env BROWSER=true npm run js-test-karma", + "js-test-cloud": "cross-env BROWSERSTACK=true npm run js-test-karma", "lint": "npm-run-all --parallel js-lint css-lint lockfile-lint", - "docs": "npm-run-all css-docs js-docs docs-build docs-lint", - "docs-build": "bundle exec jekyll build", + "docs": "npm-run-all docs-build docs-lint", + "docs-build": "hugo --cleanDestinationDir", "docs-compile": "npm run docs-build", - "docs-production": "cross-env JEKYLL_ENV=production npm run docs-build", - "docs-netlify": "cross-env JEKYLL_ENV=netlify npm run docs-build", "docs-linkinator": "linkinator _gh_pages --recurse --silent --skip \"^(?!http://localhost)\"", "docs-vnu": "node build/vnu-jar.js", "docs-lint": "npm-run-all --parallel docs-vnu docs-linkinator", - "docs-serve": "bundle exec jekyll serve", - "docs-serve-only": "npm run docs-serve -- --skip-initial-build --no-watch", + "docs-serve": "hugo server --port 9001 --disableFastRender", + "docs-serve-only": "npx sirv-cli _gh_pages --port 9001", "lockfile-lint": "lockfile-lint --allowed-hosts npm --allowed-schemes https: --empty-hostname false --type npm --path package-lock.json", - "update-deps": "ncu -u -x \"jquery,karma-browserstack-launcher,sinon\" && npm update && bundle update && cross-env-shell echo Manually update \\\"site/docs/$npm_package_version_short/assets/js/vendor/\\\"", - "release": "npm-run-all dist release-sri docs-production release-zip*", + "update-deps": "ncu -u -x \"jquery,karma-browserstack-launcher,sinon,terser\" && npm update && echo Manually update site/assets/js/vendor", + "release": "npm-run-all dist release-sri docs-build release-zip*", "release-sri": "node build/generate-sri.js", "release-version": "node build/change-version.js", - "release-zip": "cross-env-shell \"shx rm -rf bootstrap-$npm_package_version-dist && shx cp -r dist/ bootstrap-$npm_package_version-dist && zip -r9 bootstrap-$npm_package_version-dist.zip bootstrap-$npm_package_version-dist && shx rm -rf bootstrap-$npm_package_version-dist\"", + "release-zip": "cross-env-shell \"rm -rf bootstrap-$npm_package_version-dist && cp -r dist/ bootstrap-$npm_package_version-dist && zip -r9 bootstrap-$npm_package_version-dist.zip bootstrap-$npm_package_version-dist && rm -rf bootstrap-$npm_package_version-dist\"", "release-zip-examples": "node build/zip-examples.js", "dist": "npm-run-all --parallel css js", "test": "npm-run-all lint dist js-test docs-build docs-lint", - "netlify": "npm-run-all dist release-sri docs-netlify", + "netlify": "cross-env-shell HUGO_BASEURL=$DEPLOY_PRIME_URL npm-run-all dist release-sri docs-build", "watch": "npm-run-all --parallel watch-*", - "watch-css-main": "nodemon --watch scss/ --ext scss --exec \"npm run css-main\"", - "watch-css-docs": "nodemon --watch \"site/docs/**/assets/scss/\" --ext scss --exec \"npm run css-docs\"", - "watch-js-main": "nodemon --watch js/src/ --ext js --exec \"npm run js-compile\"", - "watch-js-docs": "nodemon --watch \"site/docs/**/assets/js/src/\" --ext js --exec \"npm run js-docs\"" + "watch-css-main": "nodemon --watch scss/ --ext scss --exec \"npm-run-all css-lint css-compile css-prefix\"", + "watch-css-docs": "nodemon --watch site/assets/scss/ --ext scss --exec \"npm run css-lint\"", + "watch-js-main": "nodemon --watch js/src/ --ext js --exec \"npm-run-all js-lint js-compile\"", + "watch-js-docs": "nodemon --watch site/assets/js/ --ext js --exec \"npm run js-lint\"" }, "style": "dist/css/bootstrap.css", "sass": "scss/bootstrap.scss", @@ -109,24 +94,25 @@ "popper.js": "^1.16.1" }, "devDependencies": { - "@babel/cli": "^7.11.6", - "@babel/core": "^7.11.6", - "@babel/preset-env": "^7.11.5", - "@rollup/plugin-babel": "^5.2.1", - "@rollup/plugin-commonjs": "^15.1.0", - "@rollup/plugin-node-resolve": "^9.0.0", - "autoprefixer": "^9.8.6", + "@babel/cli": "^7.12.10", + "@babel/core": "^7.12.10", + "@babel/preset-env": "^7.12.11", + "@rollup/plugin-babel": "^5.2.2", + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.1", + "autoprefixer": "^10.2.1", "babel-plugin-istanbul": "^6.0.0", "bundlewatch": "^0.3.1", "clean-css-cli": "^4.3.0", - "cross-env": "^7.0.2", - "eslint": "^7.11.0", - "eslint-config-xo": "^0.32.1", + "cross-env": "^7.0.3", + "eslint": "^7.17.0", + "eslint-config-xo": "^0.34.0", "eslint-plugin-import": "^2.22.1", - "eslint-plugin-unicorn": "^22.0.0", - "find-unused-sass-variables": "^2.0.0", + "eslint-plugin-unicorn": "^25.0.1", + "find-unused-sass-variables": "^3.1.0", "glob": "^7.1.6", "hammer-simulator": "0.0.1", + "hugo-bin": "^0.68.0", "ip": "^1.1.5", "jquery": "^3.5.1", "karma": "^5.2.3", @@ -134,24 +120,24 @@ "karma-chrome-launcher": "^3.1.0", "karma-coverage-istanbul-reporter": "^3.0.3", "karma-detect-browsers": "^2.3.3", - "karma-firefox-launcher": "^1.3.0", + "karma-firefox-launcher": "^2.1.0", "karma-qunit": "^4.1.1", "karma-sinon": "^1.0.5", - "linkinator": "^2.1.3", + "linkinator": "^2.11.2", "lockfile-lint": "^4.3.7", - "node-sass": "^4.14.1", - "nodemon": "^2.0.4", + "node-sass": "^5.0.0", + "nodemon": "^2.0.7", "npm-run-all": "^4.1.5", "popper.js": "^1.16.1", - "postcss-cli": "^7.1.2", - "qunit": "^2.11.3", - "rollup": "^2.29.0", + "postcss": "^8.2.4", + "postcss-cli": "^8.3.1", + "qunit": "^2.14.0", + "rollup": "^2.36.1", "shelljs": "^0.8.4", - "shx": "^0.3.2", "sinon": "^7.5.0", - "stylelint": "^13.7.2", + "stylelint": "^13.8.0", "stylelint-config-twbs-bootstrap": "^2.1.0", - "terser": "^4.8.0", + "terser": "5.1.0", "vnu-jar": "20.6.30" }, "files": [ @@ -159,6 +145,9 @@ "js/{src,dist}/**/*.{js,map}", "scss/**/*.scss" ], + "hugo-bin": { + "buildTags": "extended" + }, "jspm": { "registry": "npm", "main": "js/bootstrap", diff --git a/vendor/twbs/bootstrap/scss/_breadcrumb.scss b/vendor/twbs/bootstrap/scss/_breadcrumb.scss index a0cf7e29b..9c204c7d5 100644 --- a/vendor/twbs/bootstrap/scss/_breadcrumb.scss +++ b/vendor/twbs/bootstrap/scss/_breadcrumb.scss @@ -10,14 +10,12 @@ } .breadcrumb-item { - display: flex; - // The separator between breadcrumbs (by default, a forward-slash: "/") + .breadcrumb-item { padding-left: $breadcrumb-item-padding; &::before { - display: inline-block; // Suppress underlining of the separator in modern browsers + float: left; // Suppress inline spacings and underlining of the separator padding-right: $breadcrumb-item-padding; color: $breadcrumb-divider-color; content: escape-svg($breadcrumb-divider); diff --git a/vendor/twbs/bootstrap/scss/_carousel.scss b/vendor/twbs/bootstrap/scss/_carousel.scss index fb5e9f856..db30bed8b 100644 --- a/vendor/twbs/bootstrap/scss/_carousel.scss +++ b/vendor/twbs/bootstrap/scss/_carousel.scss @@ -127,7 +127,7 @@ display: inline-block; width: $carousel-control-icon-width; height: $carousel-control-icon-width; - background: no-repeat 50% / 100% 100%; + background: 50% / 100% 100% no-repeat; } .carousel-control-prev-icon { background-image: escape-svg($carousel-control-prev-icon-bg); diff --git a/vendor/twbs/bootstrap/scss/_custom-forms.scss b/vendor/twbs/bootstrap/scss/_custom-forms.scss index 0057b330f..06725ff36 100644 --- a/vendor/twbs/bootstrap/scss/_custom-forms.scss +++ b/vendor/twbs/bootstrap/scss/_custom-forms.scss @@ -104,7 +104,7 @@ width: $custom-control-indicator-size; height: $custom-control-indicator-size; content: ""; - background: no-repeat 50% / #{$custom-control-indicator-bg-size}; + background: 50% / #{$custom-control-indicator-bg-size} no-repeat; } } @@ -315,6 +315,7 @@ width: 100%; height: $custom-file-height; margin: 0; + overflow: hidden; opacity: 0; &:focus ~ .custom-file-label { @@ -347,6 +348,7 @@ z-index: 1; height: $custom-file-height; padding: $custom-file-padding-y $custom-file-padding-x; + overflow: hidden; font-family: $custom-file-font-family; font-weight: $custom-file-font-weight; line-height: $custom-file-line-height; @@ -388,7 +390,7 @@ appearance: none; &:focus { - outline: none; + outline: 0; // Pseudo-elements must be split across multiple rulesets to have an effect. // No box-shadow() mixin for focus accessibility. diff --git a/vendor/twbs/bootstrap/scss/_dropdown.scss b/vendor/twbs/bootstrap/scss/_dropdown.scss index a8aaa585c..f39de1185 100644 --- a/vendor/twbs/bootstrap/scss/_dropdown.scss +++ b/vendor/twbs/bootstrap/scss/_dropdown.scss @@ -100,7 +100,7 @@ } } -// When enabled Popper.js, reset basic dropdown position +// When Popper is enabled, reset the basic dropdown position // stylelint-disable-next-line no-duplicate-selectors .dropdown-menu { &[x-placement^="top"], diff --git a/vendor/twbs/bootstrap/scss/_input-group.scss b/vendor/twbs/bootstrap/scss/_input-group.scss index cad8ea367..d72ebeaba 100644 --- a/vendor/twbs/bootstrap/scss/_input-group.scss +++ b/vendor/twbs/bootstrap/scss/_input-group.scss @@ -42,7 +42,6 @@ > .form-control, > .custom-select { - &:not(:last-child) { @include border-right-radius(0); } &:not(:first-child) { @include border-left-radius(0); } } @@ -53,9 +52,24 @@ align-items: center; &:not(:last-child) .custom-file-label, - &:not(:last-child) .custom-file-label::after { @include border-right-radius(0); } &:not(:first-child) .custom-file-label { @include border-left-radius(0); } } + + &:not(.has-validation) { + > .form-control:not(:last-child), + > .custom-select:not(:last-child), + > .custom-file:not(:last-child) .custom-file-label::after { + @include border-right-radius(0); + } + } + + &.has-validation { + > .form-control:nth-last-child(n + 3), + > .custom-select:nth-last-child(n + 3), + > .custom-file:nth-last-child(n + 3) .custom-file-label::after { + @include border-right-radius(0); + } + } } @@ -175,8 +189,10 @@ .input-group > .input-group-prepend > .btn, .input-group > .input-group-prepend > .input-group-text, -.input-group > .input-group-append:not(:last-child) > .btn, -.input-group > .input-group-append:not(:last-child) > .input-group-text, +.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn, +.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text, +.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn, +.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text, .input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { @include border-right-radius(0); diff --git a/vendor/twbs/bootstrap/scss/_nav.scss b/vendor/twbs/bootstrap/scss/_nav.scss index d866c9841..fad684e57 100644 --- a/vendor/twbs/bootstrap/scss/_nav.scss +++ b/vendor/twbs/bootstrap/scss/_nav.scss @@ -35,11 +35,8 @@ .nav-tabs { border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color; - .nav-item { - margin-bottom: -$nav-tabs-border-width; - } - .nav-link { + margin-bottom: -$nav-tabs-border-width; border: $nav-tabs-border-width solid transparent; @include border-top-radius($nav-tabs-border-radius); diff --git a/vendor/twbs/bootstrap/scss/_navbar.scss b/vendor/twbs/bootstrap/scss/_navbar.scss index 5f10a62f1..cf5b66790 100644 --- a/vendor/twbs/bootstrap/scss/_navbar.scss +++ b/vendor/twbs/bootstrap/scss/_navbar.scss @@ -136,8 +136,12 @@ height: 1.5em; vertical-align: middle; content: ""; - background: no-repeat center center; - background-size: 100% 100%; + background: 50% / 100% 100% no-repeat; +} + +.navbar-nav-scroll { + max-height: $navbar-nav-scroll-max-height; + overflow-y: auto; } // Generate series of `.navbar-expand-*` responsive classes for configuring @@ -199,6 +203,10 @@ } } + .navbar-nav-scroll { + overflow: visible; + } + .navbar-collapse { display: flex !important; // stylelint-disable-line declaration-no-important diff --git a/vendor/twbs/bootstrap/scss/_pagination.scss b/vendor/twbs/bootstrap/scss/_pagination.scss index d7d553cca..9313cc547 100644 --- a/vendor/twbs/bootstrap/scss/_pagination.scss +++ b/vendor/twbs/bootstrap/scss/_pagination.scss @@ -66,9 +66,9 @@ // .pagination-lg { - @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg); + @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $pagination-border-radius-lg); } .pagination-sm { - @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm); + @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $pagination-border-radius-sm); } diff --git a/vendor/twbs/bootstrap/scss/_progress.scss b/vendor/twbs/bootstrap/scss/_progress.scss index 1a037045a..e206474a8 100644 --- a/vendor/twbs/bootstrap/scss/_progress.scss +++ b/vendor/twbs/bootstrap/scss/_progress.scss @@ -36,7 +36,7 @@ @if $enable-transitions { .progress-bar-animated { - animation: progress-bar-stripes $progress-bar-animation-timing; + animation: $progress-bar-animation-timing progress-bar-stripes; @if $enable-prefers-reduced-motion-media-query { @media (prefers-reduced-motion: reduce) { diff --git a/vendor/twbs/bootstrap/scss/_reboot.scss b/vendor/twbs/bootstrap/scss/_reboot.scss index 6f73466d3..cd93bfe24 100644 --- a/vendor/twbs/bootstrap/scss/_reboot.scss +++ b/vendor/twbs/bootstrap/scss/_reboot.scss @@ -1,4 +1,4 @@ -// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix +// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix // Reboot // @@ -307,13 +307,13 @@ button { border-radius: 0; } -// Work around a Firefox/IE bug where the transparent `button` background -// results in a loss of the default `button` focus styles. -// -// Credit: https://github.com/suitcss/base/ -button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; +// Explicitly remove focus outline in Chromium when it shouldn't be +// visible (e.g. as result of mouse click or touch tap). It already +// should be doing this automatically, but seems to currently be +// confused and applies its very visible two-tone outline anyway. + +button:focus:not(:focus-visible) { + outline: 0; } input, diff --git a/vendor/twbs/bootstrap/scss/_root.scss b/vendor/twbs/bootstrap/scss/_root.scss index 8110030c6..ad550df3b 100644 --- a/vendor/twbs/bootstrap/scss/_root.scss +++ b/vendor/twbs/bootstrap/scss/_root.scss @@ -1,4 +1,3 @@ -// Do not forget to update getting-started/theming.md! :root { // Custom variable values only support SassScript inside `#{}`. @each $color, $value in $colors { diff --git a/vendor/twbs/bootstrap/scss/_spinners.scss b/vendor/twbs/bootstrap/scss/_spinners.scss index 146c82067..7d8fba7a1 100644 --- a/vendor/twbs/bootstrap/scss/_spinners.scss +++ b/vendor/twbs/bootstrap/scss/_spinners.scss @@ -15,7 +15,7 @@ border-right-color: transparent; // stylelint-disable-next-line property-disallowed-list border-radius: 50%; - animation: spinner-border .75s linear infinite; + animation: .75s linear infinite spinner-border; } .spinner-border-sm { @@ -47,10 +47,19 @@ // stylelint-disable-next-line property-disallowed-list border-radius: 50%; opacity: 0; - animation: spinner-grow .75s linear infinite; + animation: .75s linear infinite spinner-grow; } .spinner-grow-sm { width: $spinner-width-sm; height: $spinner-height-sm; } + +@if $enable-prefers-reduced-motion-media-query { + @media (prefers-reduced-motion: reduce) { + .spinner-border, + .spinner-grow { + animation-duration: 1.5s; + } + } +} diff --git a/vendor/twbs/bootstrap/scss/_type.scss b/vendor/twbs/bootstrap/scss/_type.scss index 43dde7d0f..3112a734b 100644 --- a/vendor/twbs/bootstrap/scss/_type.scss +++ b/vendor/twbs/bootstrap/scss/_type.scss @@ -1,4 +1,4 @@ -// stylelint-disable declaration-no-important, selector-list-comma-newline-after +// stylelint-disable selector-list-comma-newline-after // // Headings diff --git a/vendor/twbs/bootstrap/scss/_variables.scss b/vendor/twbs/bootstrap/scss/_variables.scss index d7171e5a4..0a260b96f 100644 --- a/vendor/twbs/bootstrap/scss/_variables.scss +++ b/vendor/twbs/bootstrap/scss/_variables.scss @@ -274,7 +274,7 @@ $embed-responsive-aspect-ratios: join( // Font, line-height, and color for body text, headings, and more. // stylelint-disable value-keyword-case -$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default; +$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default; $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; $font-family-base: $font-family-sans-serif !default; // stylelint-enable value-keyword-case @@ -583,7 +583,7 @@ $custom-select-disabled-bg: $gray-200 !default; $custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions $custom-select-indicator-color: $gray-800 !default; $custom-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>") !default; -$custom-select-background: escape-svg($custom-select-indicator) no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon) +$custom-select-background: escape-svg($custom-select-indicator) right $custom-select-padding-x center / $custom-select-bg-size no-repeat !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon) $custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default; $custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default; @@ -731,6 +731,8 @@ $navbar-toggler-padding-x: .75rem !default; $navbar-toggler-font-size: $font-size-lg !default; $navbar-toggler-border-radius: $btn-border-radius !default; +$navbar-nav-scroll-max-height: 75vh !default; + $navbar-dark-color: rgba($white, .5) !default; $navbar-dark-hover-color: rgba($white, .75) !default; $navbar-dark-active-color: $white !default; @@ -772,12 +774,12 @@ $dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default; $dropdown-link-color: $gray-900 !default; $dropdown-link-hover-color: darken($gray-900, 5%) !default; -$dropdown-link-hover-bg: $gray-100 !default; +$dropdown-link-hover-bg: $gray-200 !default; $dropdown-link-active-color: $component-active-color !default; $dropdown-link-active-bg: $component-active-bg !default; -$dropdown-link-disabled-color: $gray-600 !default; +$dropdown-link-disabled-color: $gray-500 !default; $dropdown-item-padding-y: .25rem !default; $dropdown-item-padding-x: 1.5rem !default; @@ -816,6 +818,8 @@ $pagination-disabled-color: $gray-600 !default; $pagination-disabled-bg: $white !default; $pagination-disabled-border-color: $gray-300 !default; +$pagination-border-radius-sm: $border-radius-sm !default; +$pagination-border-radius-lg: $border-radius-lg !default; // Jumbotron diff --git a/vendor/twbs/bootstrap/scss/bootstrap-grid.scss b/vendor/twbs/bootstrap/scss/bootstrap-grid.scss index a5cf3b789..6a6648377 100644 --- a/vendor/twbs/bootstrap/scss/bootstrap-grid.scss +++ b/vendor/twbs/bootstrap/scss/bootstrap-grid.scss @@ -1,7 +1,7 @@ /*! - * Bootstrap Grid v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap Grid v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -19,6 +19,7 @@ html { @import "functions"; @import "variables"; +@import "mixins/deprecate"; @import "mixins/breakpoints"; @import "mixins/grid-framework"; @import "mixins/grid"; diff --git a/vendor/twbs/bootstrap/scss/bootstrap-reboot.scss b/vendor/twbs/bootstrap/scss/bootstrap-reboot.scss index de63f528b..2b6cfc2f8 100644 --- a/vendor/twbs/bootstrap/scss/bootstrap-reboot.scss +++ b/vendor/twbs/bootstrap/scss/bootstrap-reboot.scss @@ -1,7 +1,7 @@ /*! - * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap Reboot v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) */ diff --git a/vendor/twbs/bootstrap/scss/bootstrap.scss b/vendor/twbs/bootstrap/scss/bootstrap.scss index 0a206557b..e86c49da5 100644 --- a/vendor/twbs/bootstrap/scss/bootstrap.scss +++ b/vendor/twbs/bootstrap/scss/bootstrap.scss @@ -1,7 +1,7 @@ /*! - * Bootstrap v4.5.3 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. + * Bootstrap v4.6.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ diff --git a/vendor/twbs/bootstrap/scss/mixins/_forms.scss b/vendor/twbs/bootstrap/scss/mixins/_forms.scss index 39b52f3ca..a32163049 100644 --- a/vendor/twbs/bootstrap/scss/mixins/_forms.scss +++ b/vendor/twbs/bootstrap/scss/mixins/_forms.scss @@ -64,6 +64,13 @@ color: color-yiq($color); background-color: rgba($color, $form-feedback-tooltip-opacity); @include border-radius($form-feedback-tooltip-border-radius); + + // See https://github.com/twbs/bootstrap/pull/31557 + // Align tooltip to form elements + .form-row > .col > &, + .form-row > [class*="col-"] > & { + left: $form-grid-gutter-width / 2; + } } @include form-validation-state-selector($state) { @@ -108,7 +115,7 @@ @if $enable-validation-icons { padding-right: $custom-select-feedback-icon-padding-right; - background: $custom-select-background, escape-svg($icon) $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size; + background: $custom-select-background, $custom-select-bg escape-svg($icon) $custom-select-feedback-icon-position / $custom-select-feedback-icon-size no-repeat; } &:focus { diff --git a/vendor/twbs/bootstrap/scss/mixins/_image.scss b/vendor/twbs/bootstrap/scss/mixins/_image.scss index c971e038b..3aaa0d704 100644 --- a/vendor/twbs/bootstrap/scss/mixins/_image.scss +++ b/vendor/twbs/bootstrap/scss/mixins/_image.scss @@ -26,7 +26,7 @@ // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio, // but doesn't convert dppx=>dpi. // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard. - // Compatibility info: https://caniuse.com/#feat=css-media-resolution + // Compatibility info: https://caniuse.com/css-media-resolution @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx only screen and (min-resolution: 2dppx) { // Standardized background-image: url($file-2x); diff --git a/vendor/twbs/bootstrap/site/.eslintrc.json b/vendor/twbs/bootstrap/site/.eslintrc.json index e911d46b2..11fae1928 100644 --- a/vendor/twbs/bootstrap/site/.eslintrc.json +++ b/vendor/twbs/bootstrap/site/.eslintrc.json @@ -35,10 +35,10 @@ "unicorn/no-for-loop": "off", "unicorn/no-null": "off", "unicorn/prefer-array-find": "off", - "unicorn/prefer-dataset": "off", + "unicorn/prefer-dom-node-dataset": "off", "unicorn/prefer-includes": "off", "unicorn/prefer-number-properties": "off", - "unicorn/prefer-node-append": "off", + "unicorn/prefer-dom-node-append": "off", "unicorn/prefer-query-selector": "off", "unicorn/prevent-abbreviations": "off" } diff --git a/vendor/twbs/bootstrap/site/_data/breakpoints.yml b/vendor/twbs/bootstrap/site/_data/breakpoints.yml deleted file mode 100644 index 3c8cfe293..000000000 --- a/vendor/twbs/bootstrap/site/_data/breakpoints.yml +++ /dev/null @@ -1,29 +0,0 @@ -- breakpoint: xs - abbr: "" - name: Extra small - min-width: 0px - container: "" - -- breakpoint: sm - abbr: -sm - name: Small - min-width: 576px - container: 540px - -- breakpoint: md - abbr: -md - name: Medium - min-width: 768px - container: 720px - -- breakpoint: lg - abbr: -lg - name: Large - min-width: 992px - container: 960px - -- breakpoint: xl - abbr: -xl - name: Extra large - min-width: 1200px - container: 1140px diff --git a/vendor/twbs/bootstrap/site/_data/browser-bugs.yml b/vendor/twbs/bootstrap/site/_data/browser-bugs.yml deleted file mode 100644 index 7138c75b4..000000000 --- a/vendor/twbs/bootstrap/site/_data/browser-bugs.yml +++ /dev/null @@ -1,411 +0,0 @@ -- - browser: > - Edge - summary: > - Visual artifacts in scrollable modal dialogs - upstream_bug: > - Edge#9011176 - origin: > - Bootstrap#20755 - -- - browser: > - Edge - summary: > - Native browser tooltip for `title` shows on first keyboard focus (in addition to custom tooltip component) - upstream_bug: > - Edge#6793560 - origin: > - Bootstrap#18692 - -- - browser: > - Edge - summary: > - Hovered element still remains in `:hover` state after scrolling away. - upstream_bug: > - Edge#5381673 - origin: > - Bootstrap#14211 - -- - browser: > - Edge - summary: > - CSS `border-radius` sometimes causes lines of bleed-through of the `background-color` of the parent element. - upstream_bug: > - Edge#3342037 - origin: > - Bootstrap#16671 - -- - browser: > - Edge - summary: > - `background` of `<tr>` is only applied to first child cell instead of all cells in the row - upstream_bug: > - Edge#5865620 - origin: > - Bootstrap#18504 - -- - browser: > - Edge - summary: > - Background color from lower layer bleeds through transparent border in some cases - upstream_bug: > - Edge#6274505 - origin: > - Bootstrap#18228 - -- - browser: > - Edge - summary: > - Hovering over descendant SVG element fires `mouseleave` event at ancestor - upstream_bug: > - Edge#7787318 - origin: > - Bootstrap#19670 - -- - browser: > - Edge - summary: > - Active `position: fixed;` `<button>` flickers when scrolling - upstream_bug: > - Edge#8770398 - origin: > - Bootstrap#20507 - -- - browser: > - Firefox - summary: > - `.table-bordered` with an empty `<tbody>` is missing borders. - upstream_bug: > - Mozilla#1023761 - origin: > - Bootstrap#13453 - -- - browser: > - Firefox - summary: > - If the disabled state of a form control is changed via JavaScript, the normal state doesn't return after refreshing the page. - upstream_bug: > - Mozilla#654072 - origin: > - Bootstrap#793 - -- - browser: > - Firefox - summary: > - `focus` events should not be fired at the `document` object - upstream_bug: > - Mozilla#1228802 - origin: > - Bootstrap#18365 - -- - browser: > - Firefox - summary: > - Wide floated table doesn't wrap onto new line - upstream_bug: > - Mozilla#1277782 - origin: > - Bootstrap#19839 - -- - browser: > - Firefox - summary: > - Mouse sometimes not within element for purposes of `mouseenter`/`mouseleave` when it's within SVG elements - upstream_bug: > - Mozilla#577785 - origin: > - Bootstrap#19670 - -- - browser: > - Firefox - summary: > - Layout with floated columns breaks when printing - upstream_bug: > - Mozilla#1315994 - origin: > - Bootstrap#21092 - -- - browser: > - Firefox (Windows) - summary: > - Right border of `<select>` menu is sometimes missing when screen is set to uncommon resolution - upstream_bug: > - Mozilla#545685 - origin: > - Bootstrap#15990 - -- - browser: > - Firefox (macOS & Linux) - summary: > - Badge widget causes bottom border of Tabs widget to unexpectedly not overlap - upstream_bug: > - Mozilla#1259972 - origin: > - Bootstrap#19626 - -- - browser: > - Chrome (macOS) - summary: > - Clicking above `<input type="number">` increment button flashes the decrement button. - upstream_bug: > - Chromium#419108 - origin: > - Offshoot of Bootstrap#8350 & Chromium#337668 - -- - browser: > - Chrome - summary: > - CSS infinite linear animation with alpha transparency leaks memory. - upstream_bug: > - Chromium#429375 - origin: > - Bootstrap#14409 - -- - browser: > - Chrome - summary: > - `table-cell` borders not overlapping despite `margin-right: -1px` - upstream_bug: > - Chromium#749848 - origin: > - Bootstrap#17438, Bootstrap#14237 - -- - browser: > - Chrome - summary: > - Don't make `:hover` sticky on touch-friendly webpages - upstream_bug: > - Chromium#370155 - origin: > - Bootstrap#12832 - -- - browser: > - Chrome - summary: > - `position: absolute` element that's wider than its column is incorrectly clipped to column boundary - upstream_bug: > - Chromium#269061 - origin: > - Bootstrap#20161 - -- - browser: > - Chrome - summary: > - Significant performance hit for dynamic SVGs with text depending on the number of fonts in `font-family`. - upstream_bug: > - Chromium#781344 - origin: > - Bootstrap#24673 - -- - browser: > - Safari - summary: > - `rem` units in media queries should be calculated using `font-size: initial`, not the root element's `font-size` - upstream_bug: > - WebKit#156684 - origin: > - Bootstrap#17403 - -- - browser: > - Safari - summary: > - Link to container with id and tabindex results in container being ignored by VoiceOver (affects skip links) - upstream_bug: > - WebKit#163658 - origin: > - Bootstrap#20732 - -- - browser: > - Safari - summary: > - CSS `min-width` and `max-width` media features should not round fractional pixel - upstream_bug: > - WebKit#178261 - origin: > - Bootstrap#25166 - -- - browser: > - Safari (macOS) - summary: > - `px`, `em`, and `rem` should all behave the same in media queries when page zoom is applied - upstream_bug: > - WebKit#156687 - origin: > - Bootstrap#17403 - -- - browser: > - Safari (macOS) - summary: > - Weird button behavior with some `<input type="number">` elements. - upstream_bug: > - WebKit#137269, Safari#18834768 - origin: > - Bootstrap#8350, - Normalize#283, - Chromium#337668 - -- - browser: > - Safari (macOS) - summary: > - Small font size when printing webpage with fixed-width `.container`. - upstream_bug: > - WebKit#138192, Safari#19435018 - origin: > - Bootstrap#14868 - -- - browser: > - Safari (iOS) - summary: > - `transform: translate3d(0,0,0);` rendering bug. - upstream_bug: > - WebKit#138162, Safari#18804973 - origin: > - Bootstrap#14603 - -- - browser: > - Safari (iOS) - summary: > - Text input's cursor doesn't move while scrolling the page. - upstream_bug: > - WebKit#138201, Safari#18819624 - origin: > - Bootstrap#14708 - -- - browser: > - Safari (iOS) - summary: > - Can't move cursor to start of text after entering long string of text into `<input type="text">` - upstream_bug: > - WebKit#148061, Safari#22299624 - origin: > - Bootstrap#16988 - -- - browser: > - Safari (iOS) - summary: > - `display: block` causes text of temporal `<input>`s to become vertically misaligned - upstream_bug: > - WebKit#139848, Safari#19434878 - origin: > - Bootstrap#11266, Bootstrap#13098 - -- - browser: > - Safari (iOS) - summary: > - Tapping on `<body>` doesn't fire `click` events - upstream_bug: > - WebKit#151933 - origin: > - Bootstrap#16028 - -- - browser: > - Safari (iOS) - summary: > - `position:fixed` is incorrectly positioned when tab bar is visible on iPhone 6S+ Safari - upstream_bug: > - WebKit#153056 - origin: > - Bootstrap#18859 - -- - browser: > - Safari (iOS) - summary: > - Tapping into an `<input>` within a `position:fixed` element scrolls to the top of the page - upstream_bug: > - WebKit#153224, Safari#24235301 - origin: > - Bootstrap#17497 - -- - browser: > - Safari (iOS) - summary: > - `<body>` with `overflow:hidden` CSS is scrollable on iOS - upstream_bug: > - WebKit#153852 - origin: > - Bootstrap#14839 - -- - browser: > - Safari (iOS) - summary: > - Scroll gesture in text field in `position:fixed` element sometimes scrolls `<body>` instead of scrollable ancestor - upstream_bug: > - WebKit#153856 - origin: > - Bootstrap#14839 - -- - browser: > - Safari (iOS) - summary: > - Modal with `-webkit-overflow-scrolling: touch` doesn't become scrollable after added text makes it taller - upstream_bug: > - WebKit#158342 - origin: > - Bootstrap#17695 - -- - browser: > - Safari (iOS) - summary: > - Don't make `:hover` sticky on touch-friendly webpages - upstream_bug: > - WebKit#158517 - origin: > - Bootstrap#12832 - -- - browser: > - Safari (iOS) - summary: > - Element which is `position:fixed` disappears after opening a `<select>` menu - upstream_bug: > - WebKit#162362 - origin: > - Bootstrap#20759 - -- - browser: > - Safari (iPad Pro) - summary: > - Rendering of descendants of `position: fixed` element gets clipped on iPad Pro in Landscape orientation - upstream_bug: > - WebKit#152637, Safari#24030853 - origin: > - Bootstrap#18738 diff --git a/vendor/twbs/bootstrap/site/_data/browser-features.yml b/vendor/twbs/bootstrap/site/_data/browser-features.yml deleted file mode 100644 index 8f75cb3af..000000000 --- a/vendor/twbs/bootstrap/site/_data/browser-features.yml +++ /dev/null @@ -1,139 +0,0 @@ -- - browser: > - Edge - summary: > - Focusable elements should fire focus event / receive :focus styling when they receive Narrator/accessibility focus - upstream_bug: > - A11yUserVoice#16717318 - origin: > - Bootstrap#20732 - -- - browser: > - Edge - summary: > - Implement the [`:dir()` pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:dir) from Selectors Level 4 - upstream_bug: > - UserVoice#12299532 - origin: > - Bootstrap#19984 - -- - browser: > - Edge - summary: > - Implement the HTML5 [`<dialog>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) - upstream_bug: > - UserVoice#6508895 - origin: > - Bootstrap#20175 - -- - browser: > - Edge - summary: > - Fire a [`transitioncancel` event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/transitioncancel_event) when a CSS transition is canceled - upstream_bug: > - UserVoice#15939898 - origin: > - Bootstrap#20618 - -- - browser: > - Edge - summary: > - Implement the [`of <selector-list>` clause](https://caniuse.com/#feat=css-nth-child-of) of the `:nth-child()` pseudo-class - upstream_bug: > - UserVoice#15944476 - origin: > - Bootstrap#20143 - -- - browser: > - Firefox - summary: > - Implement the [`of <selector-list>` clause](https://caniuse.com/#feat=css-nth-child-of) of the `:nth-child()` pseudo-class - upstream_bug: > - Mozilla#854148 - origin: > - Bootstrap#20143 - -- - browser: > - Firefox - summary: > - Implement the HTML5 [`<dialog>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) - upstream_bug: > - Mozilla#840640 - origin: > - Bootstrap#20175 - -- - browser: > - Firefox - summary: > - When virtual focus is on a button or link, fire actual focus on the element, too - upstream_bug: > - Mozilla#1000082 - origin: > - Bootstrap#20732 - -- - browser: > - Chrome - summary: > - Fire a [`transitioncancel` event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/transitioncancel_event) when a CSS transition is canceled - upstream_bug: > - Chromium#642487 - origin: > - Chromium#437860 - -- - browser: > - Chrome - summary: > - Implement the [`of <selector-list>` clause](https://caniuse.com/#feat=css-nth-child-of) of the `:nth-child()` pseudo-class - upstream_bug: > - Chromium#304163 - origin: > - Bootstrap#20143 - -- - browser: > - Chrome - summary: > - Implement the [`:dir()` pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:dir) from Selectors Level 4 - upstream_bug: > - Chromium#576815 - origin: > - Bootstrap#19984 - -- - browser: > - Safari - summary: > - Fire a [`transitioncancel` event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/transitioncancel_event) when a CSS transition is canceled - upstream_bug: > - WebKit#161535 - origin: > - Bootstrap#20618 - -- - browser: > - Safari - summary: > - Implement the [`:dir()` pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:dir) from Selectors Level 4 - upstream_bug: > - WebKit#64861 - origin: > - Bootstrap#19984 - -- - browser: > - Safari - summary: > - Implement the HTML5 [`<dialog>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) - upstream_bug: > - WebKit#84635 - origin: > - Bootstrap#20175 diff --git a/vendor/twbs/bootstrap/site/_data/colors.yml b/vendor/twbs/bootstrap/site/_data/colors.yml deleted file mode 100644 index 202270cdc..000000000 --- a/vendor/twbs/bootstrap/site/_data/colors.yml +++ /dev/null @@ -1,26 +0,0 @@ -- name: blue - hex: "#007bff" -- name: indigo - hex: "#6610f2" -- name: purple - hex: "#6f42c1" -- name: pink - hex: "#e83e8c" -- name: red - hex: "#dc3545" -- name: orange - hex: "#fd7e14" -- name: yellow - hex: "#ffc107" -- name: green - hex: "#28a745" -- name: teal - hex: "#20c997" -- name: cyan - hex: "#17a2b8" -- name: white - hex: "#fff" -- name: gray - hex: "#868e96" -- name: gray-dark - hex: "#343a40" diff --git a/vendor/twbs/bootstrap/site/_data/core-team.yml b/vendor/twbs/bootstrap/site/_data/core-team.yml deleted file mode 100644 index f59b4285c..000000000 --- a/vendor/twbs/bootstrap/site/_data/core-team.yml +++ /dev/null @@ -1,32 +0,0 @@ -- name: Mark Otto - user: mdo - -- name: Jacob Thornton - user: fat - -- name: Chris Rebert - user: cvrebert - -- name: XhmikosR - user: xhmikosr - -- name: Patrick H. Lauke - user: patrickhlauke - -- name: Gleb Mazovetskiy - user: glebm - -- name: Johann-S - user: johann-s - -- name: Andres Galante - user: andresgalante - -- name: Martijn Cuppens - user: martijncuppens - -- name: Shohei Yoshida - user: ysds - -- name: Gaël Poupard - user: ffoodd diff --git a/vendor/twbs/bootstrap/site/_data/docs-versions.yml b/vendor/twbs/bootstrap/site/_data/docs-versions.yml deleted file mode 100644 index c211a01c7..000000000 --- a/vendor/twbs/bootstrap/site/_data/docs-versions.yml +++ /dev/null @@ -1,46 +0,0 @@ -- group: v1.x - baseurl: https://getbootstrap.com - description: Every minor and patch release from v1 is listed below. - versions: - - v: 1.0.0 - - v: 1.1.0 - - v: 1.1.1 - - v: 1.2.0 - - v: 1.3.0 - - v: 1.4.0 - -- group: v2.x - baseurl: https://getbootstrap.com - description: Every minor and patch release from v2 is listed below. - versions: - - v: 2.0.0 - - v: 2.0.1 - - v: 2.0.2 - - v: 2.0.3 - - v: 2.0.4 - - v: 2.1.0 - - v: 2.1.1 - - v: 2.2.0 - - v: 2.2.1 - - v: 2.2.2 - - v: 2.3.0 - - v: 2.3.1 - - v: 2.3.2 - -- group: v3.x - baseurl: https://getbootstrap.com/docs - description: Our previous major release and its minor versions. Last update was v3.4.1. - versions: - - v: 3.3 - - v: 3.4 - -- group: v4.x - baseurl: https://getbootstrap.com/docs - description: Current major release and its minor versions. Last update was v4.5.3. - versions: - - v: 4.0 - - v: 4.1 - - v: 4.2 - - v: 4.3 - - v: 4.4 - - v: 4.5 diff --git a/vendor/twbs/bootstrap/site/_data/examples.yml b/vendor/twbs/bootstrap/site/_data/examples.yml deleted file mode 100644 index 673fde40b..000000000 --- a/vendor/twbs/bootstrap/site/_data/examples.yml +++ /dev/null @@ -1,55 +0,0 @@ -- category: Custom components - description: "Brand new components and templates to help folks quickly get started with Bootstrap and demonstrate best practices for adding onto the framework." - examples: - - name: Album - description: "Simple one-page template for photo galleries, portfolios, and more." - - name: Pricing - description: "Example pricing page built with Cards and featuring a custom header and footer." - - name: Checkout - description: "Custom checkout form showing our form components and their validation features." - - name: Product - description: "Lean product-focused marketing page with extensive grid and image work." - - name: Cover - description: "A one-page template for building simple and beautiful home pages." - - name: Carousel - description: "Customize the navbar and carousel, then add some new components." - - name: Blog - description: "Magazine like blog template with header, navigation, featured content." - - name: Dashboard - description: "Basic admin dashboard shell with fixed sidebar and navbar." - - name: Sign-in - description: "Custom form layout and design for a simple sign in form." - - name: Sticky footer - description: "Attach a footer to the bottom of the viewport when page content is short." - - name: Sticky footer navbar - description: "Attach a footer to the bottom of the viewport with a fixed top navbar." - -- category: Framework - description: "Examples that focus on implementing uses of built-in components provided by Bootstrap." - examples: - - name: "Starter template" - description: "Nothing but the basics: compiled CSS and JavaScript." - - name: Grid - description: "Multiple examples of grid layouts with all four tiers, nesting, and more." - - name: Jumbotron - description: "Build around the jumbotron with a navbar and some basic grid columns." - -- category: Navbars - description: "Taking the default navbar component and showing how it can be moved, placed, and extended." - examples: - - name: Navbars - description: "Demonstration of all responsive and container options for the navbar." - - name: Navbar static - description: "Single navbar example of a static top navbar along with some additional content." - - name: Navbar fixed - description: "Single navbar example with a fixed top navbar along with some additional content." - - name: Navbar bottom - description: "Single navbar example with a bottom navbar along with some additional content." - -- category: Experiments - description: "Examples that focus on future-friendly features or techniques." - examples: - - name: Floating labels - description: "Beautifully simple forms with floating labels over your inputs." - - name: Offcanvas - description: "Turn your expandable navbar into a sliding offcanvas menu." diff --git a/vendor/twbs/bootstrap/site/_data/grays.yml b/vendor/twbs/bootstrap/site/_data/grays.yml deleted file mode 100644 index d6e50f9e1..000000000 --- a/vendor/twbs/bootstrap/site/_data/grays.yml +++ /dev/null @@ -1,18 +0,0 @@ -- name: 100 - hex: "#f8f9fa" -- name: 200 - hex: "#e9ecef" -- name: 300 - hex: "#dee2e6" -- name: 400 - hex: "#ced4da" -- name: 500 - hex: "#adb5bd" -- name: 600 - hex: "#868e96" -- name: 700 - hex: "#495057" -- name: 800 - hex: "#343a40" -- name: 900 - hex: "#212529" diff --git a/vendor/twbs/bootstrap/site/_data/nav.yml b/vendor/twbs/bootstrap/site/_data/nav.yml deleted file mode 100644 index fb53efacd..000000000 --- a/vendor/twbs/bootstrap/site/_data/nav.yml +++ /dev/null @@ -1,92 +0,0 @@ -- title: Getting started - pages: - - title: Introduction - - title: Download - - title: Contents - - title: Browsers & devices - - title: JavaScript - - title: Theming - - title: Build tools - # - title: Best practices # TODO: Write this content - - title: Webpack - - title: Accessibility - -- title: Layout - pages: - - title: Overview - - title: Grid - - title: Utilities for layout - -- title: Content - pages: - - title: Reboot - - title: Typography - - title: Code - - title: Images - - title: Tables - - title: Figures - -- title: Components - pages: - - title: Alerts - - title: Badge - - title: Breadcrumb - - title: Buttons - - title: Button group - - title: Card - - title: Carousel - - title: Collapse - - title: Dropdowns - - title: Forms - - title: Input group - - title: Jumbotron - - title: List group - - title: Media object - - title: Modal - - title: Navs - - title: Navbar - - title: Pagination - - title: Popovers - - title: Progress - - title: Scrollspy - - title: Spinners - - title: Toasts - - title: Tooltips - -- title: Utilities - pages: - - title: Borders - - title: Clearfix - - title: Close icon - - title: Colors - - title: Display - - title: Embed - - title: Flex - - title: Float - - title: Image replacement - - title: Interactions - - title: Overflow - - title: Position - - title: Screen readers - - title: Shadows - - title: Sizing - - title: Spacing - - title: Stretched link - - title: Text - - title: Vertical align - - title: Visibility - -- title: Extend - pages: - - title: Approach - - title: Icons - -- title: Migration - -- title: About - pages: - - title: Overview - - title: Team - - title: Brand - - title: License - - title: Translations diff --git a/vendor/twbs/bootstrap/site/_data/theme-colors.yml b/vendor/twbs/bootstrap/site/_data/theme-colors.yml deleted file mode 100644 index bef5002ac..000000000 --- a/vendor/twbs/bootstrap/site/_data/theme-colors.yml +++ /dev/null @@ -1,16 +0,0 @@ -- name: primary - hex: "#007bff" -- name: secondary - hex: "#868e96" -- name: success - hex: "#28a745" -- name: danger - hex: "#dc3545" -- name: warning - hex: "#ffc107" -- name: info - hex: "#17a2b8" -- name: light - hex: "#f8f9fa" -- name: dark - hex: "#343a40" diff --git a/vendor/twbs/bootstrap/site/_data/translations.yml b/vendor/twbs/bootstrap/site/_data/translations.yml deleted file mode 100644 index 3fc270cec..000000000 --- a/vendor/twbs/bootstrap/site/_data/translations.yml +++ /dev/null @@ -1,29 +0,0 @@ -- name: 中文(繁體) - code: zh-tw - description: Bootstrap 4 繁體中文手冊 - url: https://bootstrap.hexschool.com/ - -- name: Chinese - code: zh - description: Bootstrap 4 · 全球最流行的 HTML、CSS 和 JS 工具库。 - url: https://code.z01.com/v4/ - -- name: Chinese Simplified - code: zh-CN - description: Bootstrap · 全球最受欢迎的 HTML、CSS 和 JS 库。 - url: https://bootstrap-zh-cn.github.io/ - -- name: Brazilian Portuguese - code: pt-BR - description: Bootstrap 4 Português do Brasil - url: https://getbootstrap.com.br/v4/ - -- name: Japanese - code: ja - description: Bootstrap 4 日本語リファレンス - url: https://getbootstrap.jp/ - -- name: Korean - code: ko - description: Bootstrap 4 한국어 문서 - url: https://getbootstrap.kr/ diff --git a/vendor/twbs/bootstrap/site/_includes/ads.html b/vendor/twbs/bootstrap/site/_includes/ads.html deleted file mode 100644 index bbb967141..000000000 --- a/vendor/twbs/bootstrap/site/_includes/ads.html +++ /dev/null @@ -1 +0,0 @@ -<script async src="https://cdn.carbonads.com/carbon.js?serve=CKYIKKJL&placement=getbootstrapcom" id="_carbonads_js"></script> diff --git a/vendor/twbs/bootstrap/site/_includes/analytics.html b/vendor/twbs/bootstrap/site/_includes/analytics.html deleted file mode 100644 index ded6e7244..000000000 --- a/vendor/twbs/bootstrap/site/_includes/analytics.html +++ /dev/null @@ -1,7 +0,0 @@ -<script> - window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date; - ga('create', 'UA-146052-10', 'getbootstrap.com'); - ga('set', 'anonymizeIp', true); - ga('send', 'pageview'); -</script> -<script async src="https://www.google-analytics.com/analytics.js"></script> diff --git a/vendor/twbs/bootstrap/site/_includes/bugify.html b/vendor/twbs/bootstrap/site/_includes/bugify.html deleted file mode 100644 index 7f3340421..000000000 --- a/vendor/twbs/bootstrap/site/_includes/bugify.html +++ /dev/null @@ -1,42 +0,0 @@ -{%- comment -%} - Usage: include bugify.html content=text, - where content is a string that contains a bug reference name and id. - e.g. Bootstrap#19984 -{%- endcomment -%} - -{%- assign words = include.content | split: " " -%} - -{%- for word in words -%} - {% if word contains "#" %} - {% if word contains "," %}{% assign separator = true %}{% else %}{% assign separator = false %}{% endif %} - {%- assign data = word | split: "#" -%} - {%- assign bug_cat = data[0] | strip_newlines -%} - {%- assign bug_id = data[1] | strip_newlines | remove: "," -%} - - {%- case bug_cat -%} - {%- when "Bootstrap" -%} - <a href="https://github.com/twbs/bootstrap/issues/{{ bug_id }}">#{{ bug_id }}</a> - {%- when "Edge" -%} - <a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/{{ bug_id }}/">Edge issue #{{ bug_id }}</a> - {%- when "A11yUserVoice" -%} - <a href="https://microsoftaccessibility.uservoice.com/forums/307429-microsoft-accessibility-feedback/suggestions/{{ bug_id }}">Microsoft A11y UserVoice idea #{{ bug_id }}</a> - {%- when "UserVoice" -%} - <a href="https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/{{ bug_id }}">Edge UserVoice idea #{{ bug_id }}</a> - {%- when "Mozilla" -%} - <a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bug_id }}">Mozilla bug #{{ bug_id }}</a> - {%- when "Chromium" -%} - <a href="https://bugs.chromium.org/p/chromium/issues/detail?id={{ bug_id }}">Chromium issue #{{ bug_id }}</a> - {%- when "WebKit" -%} - <a href="https://bugs.webkit.org/show_bug.cgi?id={{ bug_id }}">WebKit bug #{{ bug_id }}</a> - {%- when "Safari" -%} - <a href="https://openradar.appspot.com/{{ bug_id }}">Apple Safari Radar #{{ bug_id }}</a> - {%- when "Normalize" -%} - <a href="https://github.com/necolas/normalize.css/issues/{{ bug_id }}">Normalize #{{ bug_id }}</a> - {%- else -%} - <strong>parse error</strong> - {%- endcase -%}{% if separator %}, {% endif %} - - {% else %} - {{ word }} - {%- endif -%} -{%- endfor -%} diff --git a/vendor/twbs/bootstrap/site/_includes/callout-danger-async-methods.md b/vendor/twbs/bootstrap/site/_includes/callout-danger-async-methods.md deleted file mode 100644 index 2ca34afe0..000000000 --- a/vendor/twbs/bootstrap/site/_includes/callout-danger-async-methods.md +++ /dev/null @@ -1,8 +0,0 @@ -{% capture callout %} -#### Asynchronous methods and transitions - -All API methods are **asynchronous** and start a **transition**. They return to the caller as soon as the transition is started but **before it ends**. In addition, a method call on a **transitioning component will be ignored**. - -[See our JavaScript documentation for more information]({{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/javascript/#asynchronous-functions-and-transitions). -{% endcapture %} -{% include callout.html content=callout type="danger" %} diff --git a/vendor/twbs/bootstrap/site/_includes/callout-info-mediaqueries-breakpoints.md b/vendor/twbs/bootstrap/site/_includes/callout-info-mediaqueries-breakpoints.md deleted file mode 100644 index d3988ce1a..000000000 --- a/vendor/twbs/bootstrap/site/_includes/callout-info-mediaqueries-breakpoints.md +++ /dev/null @@ -1,4 +0,0 @@ -{% capture callout %} -Note that since browsers do not currently support [range context queries](https://www.w3.org/TR/mediaqueries-4/#range-context), we work around the limitations of [`min-` and `max-` prefixes](https://www.w3.org/TR/mediaqueries-4/#mq-min-max) and viewports with fractional widths (which can occur under certain conditions on high-dpi devices, for instance) by using values with higher precision for these comparisons. -{% endcapture %} -{% include callout.html content=callout type="info" %} diff --git a/vendor/twbs/bootstrap/site/_includes/callout-info-prefersreducedmotion.md b/vendor/twbs/bootstrap/site/_includes/callout-info-prefersreducedmotion.md deleted file mode 100644 index 9c3090376..000000000 --- a/vendor/twbs/bootstrap/site/_includes/callout-info-prefersreducedmotion.md +++ /dev/null @@ -1,4 +0,0 @@ -{% capture callout %} -The animation effect of this component is dependent on the `prefers-reduced-motion` media query. See the [reduced motion section of our accessibility documentation]({{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/accessibility/#reduced-motion). -{% endcapture %} -{% include callout.html content=callout type="info" %} diff --git a/vendor/twbs/bootstrap/site/_includes/callout-warning-color-assistive-technologies.md b/vendor/twbs/bootstrap/site/_includes/callout-warning-color-assistive-technologies.md deleted file mode 100644 index 98214eb58..000000000 --- a/vendor/twbs/bootstrap/site/_includes/callout-warning-color-assistive-technologies.md +++ /dev/null @@ -1,6 +0,0 @@ -{% capture callout %} -##### Conveying meaning to assistive technologies - -Using color to add meaning only provides a visual indication, which will not be conveyed to users of assistive technologies – such as screen readers. Ensure that information denoted by the color is either obvious from the content itself (e.g. the visible text), or is included through alternative means, such as additional text hidden with the `.sr-only` class. -{% endcapture %} -{% include callout.html content=callout type="warning" %} diff --git a/vendor/twbs/bootstrap/site/_includes/callout.html b/vendor/twbs/bootstrap/site/_includes/callout.html deleted file mode 100644 index 434d10e1e..000000000 --- a/vendor/twbs/bootstrap/site/_includes/callout.html +++ /dev/null @@ -1,9 +0,0 @@ -{%- comment -%} - Usage: include callout.html content=callout type="type", - where content is a capture with the content - and type is one of: info (default), danger, warning -{%- endcomment -%} -{%- assign css_class = include.type | default: "info" -%} -<div class="bd-callout bd-callout-{{ css_class }}"> - {{- include.content | markdownify -}} -</div> diff --git a/vendor/twbs/bootstrap/site/_includes/docs-navbar.html b/vendor/twbs/bootstrap/site/_includes/docs-navbar.html deleted file mode 100644 index aa77be0f0..000000000 --- a/vendor/twbs/bootstrap/site/_includes/docs-navbar.html +++ /dev/null @@ -1,70 +0,0 @@ -<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bd-navbar"> - <a class="navbar-brand mr-0 mr-md-2" href="{{ site.baseurl }}/" aria-label="Bootstrap"> - {%- include icons/bootstrap.svg width="36" height="36" class="d-block" -%} - </a> - - <div class="navbar-nav-scroll"> - <ul class="navbar-nav bd-navbar-nav flex-row"> - <li class="nav-item"> - <a class="nav-link {% if page.layout == "home" %}active{% endif %}" href="{{ site.baseurl }}/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Bootstrap');">Home</a> - </li> - <li class="nav-item"> - <a class="nav-link {% if page.layout == "docs" %}active{% endif %}" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/introduction/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Docs');">Documentation</a> - </li> - <li class="nav-item"> - <a class="nav-link {% if page.title == "Examples" %}active{% endif %}" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/examples/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Examples');">Examples</a> - </li> - <li class="nav-item"> - <a class="nav-link" href="{{ site.icons }}/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Icons');" target="_blank" rel="noopener">Icons</a> - </li> - <li class="nav-item"> - <a class="nav-link" href="{{ site.themes }}/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Themes');" target="_blank" rel="noopener">Themes</a> - </li> - <li class="nav-item"> - <a class="nav-link" href="{{ site.expo }}/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Expo');" target="_blank" rel="noopener">Expo</a> - </li> - <li class="nav-item"> - <a class="nav-link" href="{{ site.blog }}/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Blog');" target="_blank" rel="noopener">Blog</a> - </li> - </ul> - </div> - - <ul class="navbar-nav ml-md-auto"> - <li class="nav-item dropdown"> - <a class="nav-item nav-link dropdown-toggle mr-md-2" href="#" id="bd-versions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - v{{ site.docs_version }} - </a> - <div class="dropdown-menu dropdown-menu-md-right" aria-labelledby="bd-versions"> - <a class="dropdown-item active" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/">Latest (4.5.x)</a> - <div class="dropdown-divider"></div> - <a class="dropdown-item" href="https://getbootstrap.com/docs/3.4/">v3.4.1</a> - <a class="dropdown-item" href="https://getbootstrap.com/2.3.2/">v2.3.2</a> - <div class="dropdown-divider"></div> - <a class="dropdown-item" href="{{ site.baseurl }}/docs/versions/">All versions</a> - </div> - </li> - - <li class="nav-item"> - <a class="nav-link pl-2 pr-1 mx-1 py-3 my-n2" href="{{ site.github_org }}" target="_blank" rel="noopener" aria-label="GitHub"> - {%- include icons/github.svg class="navbar-nav-svg" -%} - </a> - </li> - <li class="nav-item"> - <a class="nav-link px-1 mx-1 py-3 my-n2" href="https://twitter.com/{{ site.twitter }}" target="_blank" rel="noopener" aria-label="Twitter"> - {%- include icons/twitter.svg class="navbar-nav-svg" -%} - </a> - </li> - <li class="nav-item"> - <a class="nav-link px-1 mx-1 py-3 my-n2" href="{{ site.slack }}/" target="_blank" rel="noopener" aria-label="Slack"> - {%- include icons/slack.svg class="navbar-nav-svg" -%} - </a> - </li> - <li class="nav-item"> - <a class="nav-link px-1 mx-1 py-3 my-n2" href="{{ site.opencollective }}/" target="_blank" rel="noopener" aria-label="Open Collective"> - {%- include icons/opencollective.svg class="navbar-nav-svg" -%} - </a> - </li> - </ul> - - <a class="btn btn-bd-download d-none d-lg-inline-block mb-3 mb-md-0 ml-md-3" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/download/">Download</a> -</header> diff --git a/vendor/twbs/bootstrap/site/_includes/docs-sidebar.html b/vendor/twbs/bootstrap/site/_includes/docs-sidebar.html deleted file mode 100644 index 1fb4ff016..000000000 --- a/vendor/twbs/bootstrap/site/_includes/docs-sidebar.html +++ /dev/null @@ -1,43 +0,0 @@ -<form role="search" class="bd-search d-flex align-items-center"> - <input type="search" class="form-control" id="search-input" placeholder="Search..." aria-label="Search for..." autocomplete="off" data-docs-version="{{ site.docs_version }}"> - <button class="btn bd-search-docs-toggle d-md-none p-0 ml-3" type="button" data-toggle="collapse" data-target="#bd-docs-nav" aria-controls="bd-docs-nav" aria-expanded="false" aria-label="Toggle docs navigation"> - {%- include icons/menu.svg width="30" height="30" -%} - </button> -</form> - -<nav class="collapse bd-links" id="bd-docs-nav" aria-label="Main navigation"> - {%- assign page_slug = page.url | split: '/' | last -%} - {%- for group in site.data.nav -%} - {%- assign link = group.pages | first -%} - {%- assign link_slug = link.title | slugify -%} - {%- assign group_slug = group.title | slugify -%} - {%- assign active = nil -%} - - {%- if page.group == group_slug -%} - {%- assign active = 'active' -%} - {%- endif -%} - - <div class="bd-toc-item{% unless active == nil %} {{ active }}{% endunless %}"> - <a class="bd-toc-link" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/{{ group_slug }}/{{ link_slug }}{% if link_slug %}/{% endif %}"> - {{ group.title }} - </a> - - <ul class="nav bd-sidenav"> - {%- for doc in group.pages -%} - {%- assign doc_slug = doc.title | slugify -%} - {%- assign active = nil -%} - - {%- if page.group == group_slug and page_slug == doc_slug -%} - {%- assign active = 'active bd-sidenav-active' -%} - {%- endif -%} - - <li{% unless active == nil %} class="{{ active }}"{% endunless %}> - <a href="{{ site.baseurl }}/docs/{{ site.docs_version }}/{{ group_slug }}/{{ doc_slug }}/"> - {{ doc.title }} - </a> - </li> - {%- endfor -%} - </ul> - </div> - {%- endfor -%} -</nav> diff --git a/vendor/twbs/bootstrap/site/_includes/example.html b/vendor/twbs/bootstrap/site/_includes/example.html deleted file mode 100644 index dcd148b02..000000000 --- a/vendor/twbs/bootstrap/site/_includes/example.html +++ /dev/null @@ -1,51 +0,0 @@ -{%- comment -%} - Usage: include example.html content=markup [args], - where content is a capture with the HTML content - - args can be one of the following: - id - null (default) - class - "bd-example" (default) - optional: hide_preview - disabled (default) - optional: hide_markup - disabled (default) -{%- endcomment -%} - -{%- assign id = include.id -%} -{%- assign class = include.class -%} - -{%- if include.hide_preview == null -%} -<div{% if id %} id="{{ id }}"{% endif %} class="bd-example{% if class %} {{ class }}{% endif %}"> - {{- include.content -}} -</div> -{%- endif -%} - -{%- if include.hide_markup == null -%} - {%- highlight html -%} - {%- if include.content contains '<svg class="bd-placeholder-img' -%} - {%- assign modified_content = include.content - | replace: '<svg class="bd-placeholder-img', '✂️<svg class="bd-placeholder-img' - | replace: '</svg>', '</svg>✂️' - | split: '✂️' -%} - - {%- if include.content contains 'bd-placeholder-img ' -%} - {%- assign image_class = include.content - | replace_first: 'bd-placeholder-img', 'bd-placeholder-img ✂️' - | replace: '" width="', '✂️" width="' - | split: '✂️' -%} - {%- assign image_class = image_class[1] | replace: 'bd-placeholder-img-lg', '' | strip -%} - {%- endif -%} - - {%- for content_chunk in modified_content -%} - {%- if content_chunk contains '<svg class="bd-placeholder-img' -%} - {%- capture img_placeholder -%} - <img src="..." {% if image_class %}class="{{ image_class }}" {% endif %}alt="..."> - {%- endcapture -%} - {{- img_placeholder -}} - {%- else -%} - {{- content_chunk -}} - {%- endif -%} - {%- endfor -%} - {%- else -%} - {{- include.content -}} - {%- endif -%} - {%- endhighlight -%} -{%- endif -%} diff --git a/vendor/twbs/bootstrap/site/_includes/favicons.html b/vendor/twbs/bootstrap/site/_includes/favicons.html deleted file mode 100644 index 051259d99..000000000 --- a/vendor/twbs/bootstrap/site/_includes/favicons.html +++ /dev/null @@ -1,9 +0,0 @@ -<!-- Favicons --> -<link rel="apple-touch-icon" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/apple-touch-icon.png" sizes="180x180"> -<link rel="icon" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/favicon-32x32.png" sizes="32x32" type="image/png"> -<link rel="icon" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/favicon-16x16.png" sizes="16x16" type="image/png"> -<link rel="manifest" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/manifest.json"> -<link rel="mask-icon" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/safari-pinned-tab.svg" color="#563d7c"> -<link rel="icon" href="{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/favicon.ico"> -<meta name="msapplication-config" content="{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/browserconfig.xml"> -<meta name="theme-color" content="#563d7c"> diff --git a/vendor/twbs/bootstrap/site/_includes/footer.html b/vendor/twbs/bootstrap/site/_includes/footer.html deleted file mode 100644 index cb15d7739..000000000 --- a/vendor/twbs/bootstrap/site/_includes/footer.html +++ /dev/null @@ -1,12 +0,0 @@ -<footer class="bd-footer text-muted"> - <div class="container-fluid p-3 p-md-5"> - <ul class="bd-footer-links"> - <li><a href="{{ site.github_org }}">GitHub</a></li> - <li><a href="https://twitter.com/{{ site.twitter }}">Twitter</a></li> - <li><a href="{{ site.baseurl }}/docs/{{ site.docs_version }}/examples/">Examples</a></li> - <li><a href="{{ site.baseurl }}/docs/{{ site.docs_version }}/about/overview/">About</a></li> - </ul> - <p>Designed and built with all the love in the world by the <a href="{{ site.baseurl }}/docs/{{ site.docs_version }}/about/team/">Bootstrap team</a> with the help of <a href="{{ site.repo }}/graphs/contributors">our contributors</a>.</p> - <p>Currently v{{ site.current_version }}. Code licensed <a href="{{ site.repo }}/blob/main/LICENSE" target="_blank" rel="license noopener">MIT</a>, docs <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank" rel="license noopener">CC BY 3.0</a>.</p> - </div> -</footer> diff --git a/vendor/twbs/bootstrap/site/_includes/header.html b/vendor/twbs/bootstrap/site/_includes/header.html deleted file mode 100644 index 985918bd6..000000000 --- a/vendor/twbs/bootstrap/site/_includes/header.html +++ /dev/null @@ -1,23 +0,0 @@ -<meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> -<meta name="description" content="{{ page.description | default: site.description | smartify }}"> -<meta name="author" content="{{ site.authors }}"> -<meta name="generator" content="Jekyll v{{ jekyll.version }}"> - -<meta name="docsearch:language" content="en"> -<meta name="docsearch:version" content="{{ site.docs_version }}"> - -<title> - {%- if page.title -%} - {{ page.title | smartify }} · {{ site.title | smartify }} v{{ site.docs_version }} - {%- else -%} - {{ site.title | smartify }} · {{ site.description | smartify }} - {%- endif -%} - - - - -{% include stylesheet.html %} -{% include favicons.html %} -{% include social.html %} -{% include analytics.html %} diff --git a/vendor/twbs/bootstrap/site/_includes/icons/bootstrap-stack.svg b/vendor/twbs/bootstrap/site/_includes/icons/bootstrap-stack.svg deleted file mode 100644 index 2e3abbfc4..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/bootstrap-stack.svg +++ /dev/null @@ -1 +0,0 @@ -Bootstrap \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg b/vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg deleted file mode 100644 index ec6da152f..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg +++ /dev/null @@ -1 +0,0 @@ -Bootstrap \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/circle-square.svg b/vendor/twbs/bootstrap/site/_includes/icons/circle-square.svg deleted file mode 100644 index 432a5ab98..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/circle-square.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/vendor/twbs/bootstrap/site/_includes/icons/cloud-fill.svg b/vendor/twbs/bootstrap/site/_includes/icons/cloud-fill.svg deleted file mode 100644 index 0116a0dcc..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/cloud-fill.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/vendor/twbs/bootstrap/site/_includes/icons/code.svg b/vendor/twbs/bootstrap/site/_includes/icons/code.svg deleted file mode 100644 index 29756662a..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/code.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/vendor/twbs/bootstrap/site/_includes/icons/droplet-fill.svg b/vendor/twbs/bootstrap/site/_includes/icons/droplet-fill.svg deleted file mode 100644 index 41b7b58f2..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/droplet-fill.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/vendor/twbs/bootstrap/site/_includes/icons/github.svg b/vendor/twbs/bootstrap/site/_includes/icons/github.svg deleted file mode 100644 index 0243df5a2..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/github.svg +++ /dev/null @@ -1 +0,0 @@ -GitHub \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/menu.svg b/vendor/twbs/bootstrap/site/_includes/icons/menu.svg deleted file mode 100644 index f6c47035a..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/menu.svg +++ /dev/null @@ -1 +0,0 @@ -Menu \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/opencollective.svg b/vendor/twbs/bootstrap/site/_includes/icons/opencollective.svg deleted file mode 100644 index 090d41dff..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/opencollective.svg +++ /dev/null @@ -1 +0,0 @@ -Open Collective \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/placeholder.svg b/vendor/twbs/bootstrap/site/_includes/icons/placeholder.svg deleted file mode 100644 index 36883e82d..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/placeholder.svg +++ /dev/null @@ -1,35 +0,0 @@ -{%- comment -%} - Usage: include icons/placeholder.svg args - - args can be one of the following: - title: Used in the SVG `title` tag - text: The text to show in the image - default: 'width x height' - class: default: 'bd-placeholder-img' - color: The text color (foreground) - default: '#dee2e6' - background: The background color - default: '#868e96' - width: default: 100% - height: default: 180px -{%- endcomment -%} - -{%- assign title = include.title | default: 'Placeholder' -%} -{%- assign class = include.class | default: '' -%} -{%- assign color = include.color | default: site.data.grays[2].hex -%} -{%- assign background = include.background | default: site.data.grays[5].hex -%} -{%- assign width = include.width | default: '100%' -%} -{%- assign height = include.height | default: '180' -%} - -{%- if include.text -%} - {%- assign text = include.text -%} -{%- else -%} - {%- assign text = width | append: 'x' | append: height -%} -{%- endif -%} - -{%- capture svg -%} - - {% if title != ' ' %}{{ title }}{% endif %} - - {% if text != ' ' %}{{ text }}{% endif %} - -{%- endcapture -%} - -{{- svg | replace: ' ', '' | strip_newlines -}} diff --git a/vendor/twbs/bootstrap/site/_includes/icons/slack.svg b/vendor/twbs/bootstrap/site/_includes/icons/slack.svg deleted file mode 100644 index d6ae455d8..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/slack.svg +++ /dev/null @@ -1 +0,0 @@ -Slack \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/twitter.svg b/vendor/twbs/bootstrap/site/_includes/icons/twitter.svg deleted file mode 100644 index 7b838be58..000000000 --- a/vendor/twbs/bootstrap/site/_includes/icons/twitter.svg +++ /dev/null @@ -1 +0,0 @@ -Twitter \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/scripts.html b/vendor/twbs/bootstrap/site/_includes/scripts.html deleted file mode 100644 index 2f90f1e5d..000000000 --- a/vendor/twbs/bootstrap/site/_includes/scripts.html +++ /dev/null @@ -1,23 +0,0 @@ - - - -{%- if jekyll.environment == "production" or jekyll.environment == "netlify" -%} - -{%- else -%} - -{%- endif -%} - -{%- if page.layout == "docs" -%} - -{%- endif -%} - -{%- if jekyll.environment == "production" or jekyll.environment == "netlify" -%} - -{%- else -%} - - - - - - -{%- endif -%} diff --git a/vendor/twbs/bootstrap/site/_includes/skippy.html b/vendor/twbs/bootstrap/site/_includes/skippy.html deleted file mode 100644 index 4fb12b8bd..000000000 --- a/vendor/twbs/bootstrap/site/_includes/skippy.html +++ /dev/null @@ -1,8 +0,0 @@ -
      -
      - Skip to main content - {%- if page.layout == "docs" -%} - Skip to docs navigation - {%- endif -%} -
      -
      diff --git a/vendor/twbs/bootstrap/site/_includes/social.html b/vendor/twbs/bootstrap/site/_includes/social.html deleted file mode 100644 index cf5be1270..000000000 --- a/vendor/twbs/bootstrap/site/_includes/social.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/_includes/stylesheet.html b/vendor/twbs/bootstrap/site/_includes/stylesheet.html deleted file mode 100644 index 2f7599e13..000000000 --- a/vendor/twbs/bootstrap/site/_includes/stylesheet.html +++ /dev/null @@ -1,16 +0,0 @@ - -{%- if jekyll.environment == "production" or jekyll.environment == "netlify" %} - -{% else %} - -{% endif -%} - -{%- if page.layout == "docs" or page.layout != "examples" -%} - -{% if page.layout == "docs" %} - -{% endif %} -{% if page.layout != "examples" %} - -{% endif %} -{%- endif -%} diff --git a/vendor/twbs/bootstrap/site/_layouts/default.html b/vendor/twbs/bootstrap/site/_layouts/default.html deleted file mode 100644 index 59f5c122b..000000000 --- a/vendor/twbs/bootstrap/site/_layouts/default.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - {% include header.html %} - - - {% include skippy.html %} - - {% include docs-navbar.html %} - - {% if page.layout == "simple" %} - {{ content }} - {% else %} -
      - {{ content }} -
      - {% endif %} - - {% include footer.html %} - {% include scripts.html %} - - diff --git a/vendor/twbs/bootstrap/site/_layouts/docs.html b/vendor/twbs/bootstrap/site/_layouts/docs.html deleted file mode 100644 index 10c9fcb0c..000000000 --- a/vendor/twbs/bootstrap/site/_layouts/docs.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - {% include header.html %} - - - {% include skippy.html %} - - {% include docs-navbar.html %} - -
      -
      -
      - {% include docs-sidebar.html %} -
      - - {% if page.toc %} - - {% endif %} - -
      -
      - View on GitHub -

      {{ page.title | smartify }}

      -
      -

      {{ page.description | smartify }}

      - {% include ads.html %} - {{ content }} -
      -
      -
      - - {% include scripts.html %} - - diff --git a/vendor/twbs/bootstrap/site/_layouts/examples.html b/vendor/twbs/bootstrap/site/_layouts/examples.html deleted file mode 100644 index 4ca4c5681..000000000 --- a/vendor/twbs/bootstrap/site/_layouts/examples.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - {{ page.title | smartify }} · {{ site.title | smartify }} - - - - {% include stylesheet.html %} - {% include favicons.html %} - - - - {%- for css in page.extra_css %} - - - {%- endfor %} - - - {{ content }} - - {%- if page.include_js != false -%} - - - - {%- if jekyll.environment == "production" or jekyll.environment == "netlify" -%} - - {%- else -%} - - {%- endif -%} - - {%- for js in page.extra_js %} - - {%- endfor %} - {%- endif -%} - - diff --git a/vendor/twbs/bootstrap/site/_layouts/simple.html b/vendor/twbs/bootstrap/site/_layouts/simple.html deleted file mode 100644 index 833061b70..000000000 --- a/vendor/twbs/bootstrap/site/_layouts/simple.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -layout: default ---- - -
      -
      -

      {{ page.title | smartify }}

      -

      {{ page.description | smartify }}

      - {%- if page.title == "Examples" -%} - - {%- endif -%} -
      - {% include ads.html %} -
      - -
      - {{ content }} -
      diff --git a/vendor/twbs/bootstrap/site/docs/4.5/about/brand.md b/vendor/twbs/bootstrap/site/docs/4.5/about/brand.md deleted file mode 100644 index 5e670091b..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/about/brand.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: docs -title: Brand guidelines -description: Documentation and examples for Bootstrap's logo and brand usage guidelines. -group: about -toc: true ---- - -Have a need for Bootstrap's brand resources? Great! We have only a few guidelines we follow, and in turn ask you to follow as well. These guidelines were inspired by MailChimp's [Brand Assets](https://mailchimp.com/about/brand-assets/). - -## Mark and logo - -Use either the Bootstrap mark (a capital **B**) or the standard logo (just **Bootstrap**). It should always appear in San Francisco Display Semibold. **Do not use the Twitter bird** in association with Bootstrap. - -
      -
      - Bootstrap -
      -
      - Bootstrap -
      -
      -
      -
      - Bootstrap -
      -
      - Bootstrap -
      -
      - -## Download mark - -Download the Bootstrap mark in one of three styles, each available as an SVG file. Right click, Save as. - -
      -
      - Bootstrap -
      -
      - Bootstrap -
      -
      - Bootstrap -
      -
      - -## Name - -The project and framework should always be referred to as **Bootstrap**. No Twitter before it, no capital _s_, and no abbreviations except for one, a capital **B**. - -
      -
      - Bootstrap - Right -
      -
      - BootStrap - Wrong -
      -
      - Twitter Bootstrap - Wrong -
      -
      - -## Colors - -Our docs and branding use a handful of primary colors to differentiate what *is* Bootstrap from what *is in* Bootstrap. In other words, if it's purple, it's representative of Bootstrap. - -
      -
      -
      -
      -
      -
      -
      -
      diff --git a/vendor/twbs/bootstrap/site/docs/4.5/about/license.md b/vendor/twbs/bootstrap/site/docs/4.5/about/license.md deleted file mode 100644 index 39720029d..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/about/license.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: docs -title: License FAQs -description: Commonly asked questions about Bootstrap's open source license. -group: about ---- - -Bootstrap is released under the MIT license and is copyright {{ site.time | date: "%Y" }} Twitter. Boiled down to smaller chunks, it can be described with the following conditions. - -#### It requires you to: - -* Keep the license and copyright notice included in Bootstrap's CSS and JavaScript files when you use them in your works - -#### It permits you to: - -- Freely download and use Bootstrap, in whole or in part, for personal, private, company internal, or commercial purposes -- Use Bootstrap in packages or distributions that you create -- Modify the source code -- Grant a sublicense to modify and distribute Bootstrap to third parties not included in the license - -#### It forbids you to: - -- Hold the authors and license owners liable for damages as Bootstrap is provided without warranty -- Hold the creators or copyright holders of Bootstrap liable -- Redistribute any piece of Bootstrap without proper attribution -- Use any marks owned by Twitter in any way that might state or imply that Twitter endorses your distribution -- Use any marks owned by Twitter in any way that might state or imply that you created the Twitter software in question - -#### It does not require you to: - -- Include the source of Bootstrap itself, or of any modifications you may have made to it, in any redistribution you may assemble that includes it -- Submit changes that you make to Bootstrap back to the Bootstrap project (though such feedback is encouraged) - -The full Bootstrap license is located [in the project repository]({{ site.repo }}/blob/v{{ site.current_version }}/LICENSE) for more information. diff --git a/vendor/twbs/bootstrap/site/docs/4.5/about/overview.md b/vendor/twbs/bootstrap/site/docs/4.5/about/overview.md deleted file mode 100644 index 71572a47e..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/about/overview.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: docs -title: About -description: Learn more about the team maintaining Bootstrap, how and why the project started, and how to get involved. -group: about -redirect_from: - - "/about/" - - "/docs/4.5/about/" ---- - -## Team - -Bootstrap is maintained by a [small team of developers](https://github.com/orgs/twbs/people) on GitHub. We're actively looking to grow this team and would love to hear from you if you're excited about CSS at scale, writing and maintaining vanilla JavaScript plugins, and improving build tooling processes for frontend code. - -## History - -Originally created by a designer and a developer at Twitter, Bootstrap has become one of the most popular front-end frameworks and open source projects in the world. - -Bootstrap was created at Twitter in mid-2010 by [@mdo](https://twitter.com/mdo) and [@fat](https://twitter.com/fat). Prior to being an open-sourced framework, Bootstrap was known as _Twitter Blueprint_. A few months into development, Twitter held its [first Hack Week](https://blog.twitter.com/engineering/en_us/a/2010/hack-week.html) and the project exploded as developers of all skill levels jumped in without any external guidance. It served as the style guide for internal tools development at the company for over a year before its public release, and continues to do so today. - -Originally [released](https://blog.twitter.com/developer/en_us/a/2011/bootstrap-twitter.html) on , we've since had over [twenty releases]({{ site.repo }}/releases), including two major rewrites with v2 and v3. With Bootstrap 2, we added responsive functionality to the entire framework as an optional stylesheet. Building on that with Bootstrap 3, we rewrote the library once more to make it responsive by default with a mobile first approach. - -With Bootstrap 4, we once again rewrote the project to account for two key architectural changes: a migration to Sass and the move to CSS's flexbox. Our intention is to help in a small way to move the web development community forward by pushing for newer CSS properties, fewer dependencies, and new technologies across more modern browsers. - -## Get involved - -Get involved with Bootstrap development by [opening an issue]({{ site.repo }}/issues/new) or submitting a pull request. Read our [contributing guidelines]({{ site.repo }}/blob/v{{ site.current_version }}/.github/CONTRIBUTING.md) for information on how we develop. diff --git a/vendor/twbs/bootstrap/site/docs/4.5/about/team.md b/vendor/twbs/bootstrap/site/docs/4.5/about/team.md deleted file mode 100644 index 231e315c5..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/about/team.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -layout: docs -title: Team -description: An overview of the founding team and core contributors to Bootstrap. -group: about ---- - -Bootstrap is maintained by the founding team and a small group of invaluable core contributors, with the massive support and involvement of our community. - -
      - {% for member in site.data.core-team %} - - @{{ member.user }} - - {{ member.name }} @{{ member.user }} - - - {% endfor %} -
      - -Get involved with Bootstrap development by [opening an issue]({{ site.repo }}/issues/new) or submitting a pull request. Read our [contributing guidelines]({{ site.repo }}/blob/v{{ site.current_version }}/.github/CONTRIBUTING.md) for information on how we develop. diff --git a/vendor/twbs/bootstrap/site/docs/4.5/about/translations.md b/vendor/twbs/bootstrap/site/docs/4.5/about/translations.md deleted file mode 100644 index 576259d35..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/about/translations.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: docs -title: Translations -description: Links to community-translated Bootstrap documentation sites. -group: about ---- - -Community members have translated Bootstrap's documentation into various languages. None are officially supported and they may not always be up to date. - - - -**We don't help organize or host translations, we just link to them.** - -Finished a new or better translation? Open a pull request to add it to our list. diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-outline.svg b/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-outline.svg deleted file mode 100644 index ed1825e3e..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-outline.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-punchout.svg b/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-punchout.svg deleted file mode 100644 index be0696e1a..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-punchout.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social-logo.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social-logo.png deleted file mode 100644 index fdd35e5d4..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social-logo.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social.png deleted file mode 100644 index 468ab5b59..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-social.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-solid.svg b/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-solid.svg deleted file mode 100644 index 2f536b687..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/brand/bootstrap-solid.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css b/vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css deleted file mode 100644 index 7beb35828..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * Bootstrap Docs (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. - * Licensed under the Creative Commons Attribution 3.0 Unported License. - * For details, see https://creativecommons.org/licenses/by/3.0/. - */.bd-navbar{min-height:4rem;background-color:#7952b3;box-shadow:0 .5rem 1rem rgba(0,0,0,.05),inset 0 -1px 0 rgba(0,0,0,.1)}@media (max-width:991.98px){.bd-navbar{padding-right:.5rem;padding-left:.5rem}.bd-navbar .navbar-nav-scroll{max-width:100%;height:2.5rem;margin-top:.25rem;overflow:hidden}.bd-navbar .navbar-nav-scroll .navbar-nav{padding-bottom:2rem;overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch}}@media (min-width:768px){@supports ((position:-webkit-sticky) or (position:sticky)){.bd-navbar{position:-webkit-sticky;position:sticky;top:0;z-index:1071}}}.bd-navbar .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem;color:rgba(255,255,255,.85)}.bd-navbar .navbar-nav .nav-link.active,.bd-navbar .navbar-nav .nav-link:hover{color:#fff;background-color:transparent}.bd-navbar .navbar-nav .nav-link.active{font-weight:600}.bd-navbar .navbar-nav-svg{display:inline-block;width:1rem;height:1rem;vertical-align:text-top}.bd-navbar .dropdown-menu{font-size:.875rem}.bd-navbar .dropdown-item.active{font-weight:600;color:#212529;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") no-repeat .4rem .6rem/.75rem .75rem}.bd-masthead{position:relative;padding:3rem 15px;background:linear-gradient(to right bottom,#f7f5fb 50%,#fff 50%)}.bd-masthead h1{font-size:4rem;line-height:1}@media (max-width:1200px){.bd-masthead h1{font-size:calc(1.525rem + 3.3vw)}}.bd-masthead .lead{font-size:1.5rem;font-weight:400;color:#495057}@media (max-width:1200px){.bd-masthead .lead{font-size:calc(1.275rem + .3vw)}}.bd-masthead .btn{padding:.8rem 2rem;font-weight:600;font-size:1.25rem}.bd-masthead .carbonad{margin-top:0!important;margin-bottom:-3rem!important}@media (min-width:576px){.bd-masthead{padding-top:5rem;padding-bottom:5rem}.bd-masthead .carbonad{margin-bottom:0!important}}@media (min-width:768px){.bd-masthead .carbonad{margin-top:3rem!important}}.masthead-followup .bd-clipboard{display:none}.masthead-followup h2{font-size:2.5rem}@media (max-width:1200px){.masthead-followup h2{font-size:calc(1.375rem + 1.5vw)}}.masthead-followup .highlight{border-radius:.5rem}.masthead-followup .highlight pre::-webkit-scrollbar{display:none}.masthead-followup .highlight pre code{display:inline-block;white-space:pre}.masthead-followup .highlight pre code::before{display:none}.masthead-followup-icon{padding:.75rem;background-image:linear-gradient(to bottom right,rgba(255,255,255,.2),rgba(255,255,255,.01));border-radius:.75rem;box-shadow:0 .125rem .25rem rgba(0,0,0,.1)}.masthead-followup-svg{-webkit-filter:drop-shadow(0 1px 0 rgba(0, 0, 0, .125));filter:drop-shadow(0 1px 0 rgba(0, 0, 0, .125))}#carbonads{position:static;display:block;max-width:400px;padding:15px 15px 15px 160px;margin:2rem 0;overflow:hidden;font-size:.8125rem;line-height:1.4;text-align:left;background-color:rgba(0,0,0,.05)}#carbonads a{color:#333;text-decoration:none}@media (min-width:576px){#carbonads{max-width:330px;border-radius:4px}}.carbon-img{float:left;margin-left:-145px}.carbon-poweredby{display:block;margin-top:.75rem;color:#777!important}.bd-content{-ms-flex-order:1;order:1}.bd-content>h2[id],.bd-content>h3[id],.bd-content>h4[id]{pointer-events:none}.bd-content>h2[id]::before,.bd-content>h3[id]::before,.bd-content>h4[id]::before{display:block;height:6rem;margin-top:-6rem;content:""}.bd-content>table{width:100%;max-width:100%;margin-bottom:1rem}@media (max-width:991.98px){.bd-content>table{display:block;overflow-x:auto}.bd-content>table.table-bordered{border:0}}.bd-content>table>tbody>tr>td,.bd-content>table>tbody>tr>th,.bd-content>table>tfoot>tr>td,.bd-content>table>tfoot>tr>th,.bd-content>table>thead>tr>td,.bd-content>table>thead>tr>th{padding:.75rem;vertical-align:top;border:1px solid #dee2e6}.bd-content>table>tbody>tr>td>p:last-child,.bd-content>table>tbody>tr>th>p:last-child,.bd-content>table>tfoot>tr>td>p:last-child,.bd-content>table>tfoot>tr>th>p:last-child,.bd-content>table>thead>tr>td>p:last-child,.bd-content>table>thead>tr>th>p:last-child{margin-bottom:0}.bd-content>table td:first-child>code{white-space:nowrap}.bd-content-title{display:block;pointer-events:auto}.bd-content>h2{font-size:2rem}@media (max-width:1200px){.bd-content>h2{font-size:calc(1.325rem + .9vw)}}.bd-content>h3{font-size:1.75rem}@media (max-width:1200px){.bd-content>h3{font-size:calc(1.3rem + .6vw)}}.bd-content>h4{font-size:1.5rem}@media (max-width:1200px){.bd-content>h4{font-size:calc(1.275rem + .3vw)}}.bd-content>h2:not(:first-child){margin-top:3rem}.bd-content>h3{margin-top:1.5rem}.bd-content>ol li,.bd-content>ul li{margin-bottom:.25rem}@media (min-width:992px){.bd-content>ol,.bd-content>p,.bd-content>ul{max-width:80%}}.bd-title{margin-top:1rem;margin-bottom:.5rem;font-size:3rem}@media (max-width:1200px){.bd-title{font-size:calc(1.425rem + 2.1vw)}}.bd-lead{font-size:1.5rem;font-weight:300}@media (max-width:1200px){.bd-lead{font-size:calc(1.275rem + .3vw)}}@media (min-width:992px){.bd-lead{max-width:80%}}.bd-text-purple{color:#563d7c}.bd-text-purple-bright{color:#7952b3}.bd-bg-purple-bright{background-color:#7952b3}.skippy{background-color:#563d7c}.skippy a{color:#fff}.skippy:focus-within a{position:static!important;width:auto!important;height:auto!important;padding:.5rem!important;margin:.25rem!important;overflow:visible!important;clip:auto!important;white-space:normal!important}.bd-toc{-ms-flex-order:2;order:2;padding-top:1.5rem;padding-bottom:1.5rem;font-size:.875rem}@supports ((position:-webkit-sticky) or (position:sticky)){.bd-toc{position:-webkit-sticky;position:sticky;top:4rem;height:calc(100vh - 4rem);overflow-y:auto}}.section-nav{padding-left:0;border-left:1px solid #eee}.section-nav ul{padding-left:1rem}.toc-entry{display:block}.toc-entry a{display:block;padding:.125rem 1.5rem;color:#77757a}.toc-entry a:hover{color:#007bff;text-decoration:none}.bd-sidebar{-ms-flex-order:0;order:0;border-bottom:1px solid rgba(0,0,0,.1)}@media (min-width:768px){.bd-sidebar{border-right:1px solid rgba(0,0,0,.1)}@supports ((position:-webkit-sticky) or (position:sticky)){.bd-sidebar{position:-webkit-sticky;position:sticky;top:4rem;z-index:1000;height:calc(100vh - 4rem)}}}@media (min-width:1200px){.bd-sidebar{-ms-flex:0 1 320px;flex:0 1 320px}}.bd-links{padding-top:1rem;padding-bottom:1rem;margin-right:-15px;margin-left:-15px}@media (min-width:768px){@supports ((position:-webkit-sticky) or (position:sticky)){.bd-links{max-height:calc(100vh - 9rem);overflow-y:auto}}}@media (min-width:768px){.bd-links{display:block!important}}.bd-search{position:relative;padding:1rem 15px;margin-right:-15px;margin-left:-15px;border-bottom:1px solid rgba(0,0,0,.05)}.bd-search .form-control:focus{border-color:#7952b3;box-shadow:0 0 0 3px rgba(121,82,179,.25)}.bd-search-docs-toggle{color:#212529}.bd-sidenav{display:none}.bd-toc-link{display:block;padding:.25rem 1.5rem;font-weight:600;color:rgba(0,0,0,.65)}.bd-toc-link:hover{color:rgba(0,0,0,.85);text-decoration:none}.bd-toc-item.active{margin-bottom:1rem}.bd-toc-item.active:not(:first-child){margin-top:1rem}.bd-toc-item.active>.bd-toc-link{color:rgba(0,0,0,.85)}.bd-toc-item.active>.bd-toc-link:hover{background-color:transparent}.bd-toc-item.active>.bd-sidenav{display:block}.bd-sidebar .nav>li>a{display:block;padding:.25rem 1.5rem;font-size:90%;color:rgba(0,0,0,.65)}.bd-sidebar .nav>li>a:hover{color:rgba(0,0,0,.85);text-decoration:none;background-color:transparent}.bd-sidebar .nav>.active:hover>a,.bd-sidebar .nav>.active>a{font-weight:600;color:rgba(0,0,0,.85);background-color:transparent}.bd-footer{font-size:.875rem;text-align:center;background-color:#f7f7f7}.bd-footer a{font-weight:600;color:#495057}.bd-footer a:focus,.bd-footer a:hover{color:#007bff}.bd-footer p{margin-bottom:0}@media (min-width:576px){.bd-footer{text-align:left}}.bd-footer-links{padding-left:0;margin-bottom:1rem}.bd-footer-links li{display:inline-block}.bd-footer-links li+li{margin-left:1rem}.bd-example-row .row>.col,.bd-example-row .row>[class^=col-]{padding-top:.75rem;padding-bottom:.75rem;background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.2)}.bd-example-row .row+.row{margin-top:1rem}.bd-example-row .flex-items-bottom,.bd-example-row .flex-items-middle,.bd-example-row .flex-items-top{min-height:6rem;background-color:rgba(255,0,0,.1)}.bd-example-row-flex-cols .row{min-height:10rem;background-color:rgba(255,0,0,.1)}.bd-highlight{background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.15)}.bd-example-responsive-containers [class^=container]{padding-top:.75rem;padding-bottom:.75rem;background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.2)}.example-container{width:800px;width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.example-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.example-content-main{position:relative;width:100%;padding-right:15px;padding-left:15px}@media (min-width:576px){.example-content-main{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}}@media (min-width:992px){.example-content-main{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}}.example-content-secondary{position:relative;width:100%;padding-right:15px;padding-left:15px}@media (min-width:576px){.example-content-secondary{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}}@media (min-width:992px){.example-content-secondary{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}}.bd-example{position:relative;padding:1rem;margin:1rem -15px 0;border:solid #f8f9fa;border-width:.2rem 0 0}.bd-example::after{display:block;clear:both;content:""}@media (min-width:576px){.bd-example{padding:1.5rem;margin-right:0;margin-left:0;border-width:.2rem}}.bd-example+.clipboard+.highlight,.bd-example+.highlight{margin-top:0}.bd-example+p{margin-top:2rem}.bd-example .custom-file-input:lang(es)~.custom-file-label::after{content:"Elegir"}.bd-example>.form-control+.form-control{margin-top:.5rem}.bd-example>.alert+.alert,.bd-example>.nav+.nav,.bd-example>.navbar+.navbar,.bd-example>.progress+.btn,.bd-example>.progress+.progress{margin-top:1rem}.bd-example>.dropdown-menu:first-child{position:static;display:block}.bd-example>.form-group:last-child{margin-bottom:0}.bd-example>.close{float:none}.bd-example-type .table td{padding:1rem 0;border-color:#eee}.bd-example-type .table tr:first-child td{border-top:0}.bd-example-type h1,.bd-example-type h2,.bd-example-type h3,.bd-example-type h4,.bd-example-type h5,.bd-example-type h6{margin-top:0;margin-bottom:0}.bd-example-bg-classes p{padding:1rem}.bd-example>img+img,.bd-example>svg+svg{margin-left:.5rem}.bd-example>.btn,.bd-example>.btn-group{margin-top:.25rem;margin-bottom:.25rem}.bd-example>.btn-toolbar+.btn-toolbar{margin-top:.5rem}.bd-example-control-sizing input[type=text]+input[type=text],.bd-example-control-sizing select{margin-top:.5rem}.bd-example-form .input-group{margin-bottom:.5rem}.bd-example>textarea.form-control{resize:vertical}.bd-example>.list-group{max-width:400px}.bd-example>[class*=list-group-horizontal]{max-width:100%}.bd-example .fixed-top,.bd-example .sticky-top{position:static;margin:-1rem -1rem 1rem}.bd-example .fixed-bottom{position:static;margin:1rem -1rem -1rem}@media (min-width:576px){.bd-example .fixed-top,.bd-example .sticky-top{margin:-1.5rem -1.5rem 1rem}.bd-example .fixed-bottom{margin:1rem -1.5rem -1.5rem}}.bd-example .pagination{margin-top:.5rem;margin-bottom:.5rem}.modal{z-index:1072}.modal .popover,.modal .tooltip{z-index:1073}.modal-backdrop{z-index:1071}.bd-example-modal{background-color:#fafafa}.bd-example-modal .modal{position:relative;top:auto;right:auto;bottom:auto;left:auto;z-index:1;display:block}.bd-example-modal .modal-dialog{left:auto;margin-right:auto;margin-left:auto}.bd-example-tabs .nav-tabs{margin-bottom:1rem}.bd-example-popover-static{padding-bottom:1.5rem;background-color:#f9f9f9}.bd-example-popover-static .popover{position:relative;display:block;float:left;width:260px;margin:1.25rem}.tooltip-demo a{white-space:nowrap}.bd-example-tooltip-static .tooltip{position:relative;display:inline-block;margin:10px 20px;opacity:1}.scrollspy-example{position:relative;height:200px;margin-top:.5rem;overflow:auto}.scrollspy-example-2{position:relative;height:350px;overflow:auto}.bd-example-border-utils [class^=border]{display:inline-block;width:5rem;height:5rem;margin:.25rem;background-color:#f5f5f5}.bd-example-border-utils-0 [class^=border]{border:1px solid #dee2e6}.bd-example-forms-input-group-workaround .fix-rounded-right{border-top-right-radius:.2rem!important;border-bottom-right-radius:.2rem!important}.highlight{padding:1rem;margin-top:1rem;margin-bottom:1rem;background-color:#f8f9fa;-ms-overflow-style:-ms-autohiding-scrollbar}@media (min-width:576px){.highlight{padding:1.5rem}}.bd-content .highlight{margin-right:-15px;margin-left:-15px}@media (min-width:576px){.bd-content .highlight{margin-right:0;margin-left:0}}.highlight pre{padding:0;margin-top:.65rem;margin-bottom:.65rem;background-color:transparent;border:0}.highlight pre code{font-size:inherit;color:#212529}.btn-bd-primary{font-weight:600;color:#fff;background-color:#7952b3;border-color:#7952b3}.btn-bd-primary:active,.btn-bd-primary:hover{color:#fff;background-color:#614092;border-color:#614092}.btn-bd-primary:focus{box-shadow:0 0 0 3px rgba(121,82,179,.25)}.btn-bd-download{font-weight:600;color:#ffe484;border-color:#ffe484}.btn-bd-download:active,.btn-bd-download:hover{color:#2a2730;background-color:#ffe484;border-color:#ffe484}.btn-bd-download:focus{box-shadow:0 0 0 3px rgba(255,228,132,.25)}.btn-bd-light{color:#6c757d;border-color:#dee2e6}.btn-bd-light:active,.btn-bd-light:hover,.show>.btn-bd-light{color:#7952b3;background-color:#fff;border-color:#7952b3}.btn-bd-light:focus{box-shadow:0 0 0 3px rgba(121,82,179,.25)}.bd-callout{padding:1.25rem;margin-top:1.25rem;margin-bottom:1.25rem;border:1px solid #eee;border-left-width:.25rem;border-radius:.25rem}.bd-callout h4{margin-top:0;margin-bottom:.25rem}.bd-callout p:last-child{margin-bottom:0}.bd-callout code{border-radius:.25rem}.bd-callout+.bd-callout{margin-top:-.25rem}.bd-callout-info{border-left-color:#5bc0de}.bd-callout-info h4{color:#5bc0de}.bd-callout-warning{border-left-color:#f0ad4e}.bd-callout-warning h4{color:#f0ad4e}.bd-callout-danger{border-left-color:#d9534f}.bd-callout-danger h4{color:#d9534f}.bd-browser-bugs td p{margin-bottom:0}.bd-browser-bugs th:first-child{width:18%}.bd-brand-logos{display:table;width:100%;margin-bottom:1rem;overflow:hidden;color:#563d7c;background-color:#f9f9f9;border-radius:.25rem}.bd-brand-logos .inverse{color:#fff;background-color:#563d7c}.bd-brand-item{padding:4rem 0;text-align:center}.bd-brand-item+.bd-brand-item{border-top:1px solid #fff}.bd-brand-item h1,.bd-brand-item h3{margin-top:0;margin-bottom:0}@media (min-width:768px){.bd-brand-item{display:table-cell;width:1%}.bd-brand-item+.bd-brand-item{border-top:0;border-left:1px solid #fff}.bd-brand-item h1{font-size:4rem}}@media (min-width:768px) and (max-width:1200px){.bd-brand-item h1{font-size:calc(1.525rem + 3.3vw)}}.color-swatches{margin:0 -5px;overflow:hidden}.color-swatches .bd-purple{background-color:#563d7c}.color-swatches .bd-purple-light{background-color:#cbbde2}.color-swatches .bd-purple-lighter{background-color:#e5e1ea}.color-swatches .bd-gray{background-color:#f9f9f9}.color-swatch{float:left;width:4rem;height:4rem;margin-right:.25rem;margin-left:.25rem;border-radius:.25rem}@media (min-width:768px){.color-swatch{width:6rem;height:6rem}}.swatch-blue{color:#fff;background-color:#007bff}.swatch-indigo{color:#fff;background-color:#6610f2}.swatch-purple{color:#fff;background-color:#6f42c1}.swatch-pink{color:#fff;background-color:#e83e8c}.swatch-red{color:#fff;background-color:#dc3545}.swatch-orange{color:#212529;background-color:#fd7e14}.swatch-yellow{color:#212529;background-color:#ffc107}.swatch-green{color:#fff;background-color:#28a745}.swatch-teal{color:#fff;background-color:#20c997}.swatch-cyan{color:#fff;background-color:#17a2b8}.swatch-white{color:#212529;background-color:#fff}.swatch-gray{color:#fff;background-color:#6c757d}.swatch-gray-dark{color:#fff;background-color:#343a40}.swatch-100{color:#212529;background-color:#f8f9fa}.swatch-200{color:#212529;background-color:#e9ecef}.swatch-300{color:#212529;background-color:#dee2e6}.swatch-400{color:#212529;background-color:#ced4da}.swatch-500{color:#212529;background-color:#adb5bd}.swatch-600{color:#fff;background-color:#6c757d}.swatch-700{color:#fff;background-color:#495057}.swatch-800{color:#fff;background-color:#343a40}.swatch-900{color:#fff;background-color:#212529}.bd-clipboard{position:relative;display:none;float:right}.bd-clipboard+.highlight{margin-top:0}@media (min-width:768px){.bd-clipboard{display:block}}.btn-clipboard{position:absolute;top:.65rem;right:.65rem;z-index:10;display:block;padding:.25rem .5rem;font-size:65%;color:#007bff;background-color:#fff;border:1px solid;border-radius:.25rem}.btn-clipboard:hover{color:#fff;background-color:#007bff}.bd-placeholder-img{font-size:1.125rem;text-anchor:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bd-placeholder-img-lg{font-size:3.5rem}@media (max-width:1200px){.bd-placeholder-img-lg{font-size:calc(1.475rem + 2.7vw)}}.hll{background-color:#ffc}.c{color:#727272}.k{color:#069}.o{color:#555}.cm{color:#727272}.cp{color:#008085}.c1{color:#727272}.cs{color:#727272}.gd{background-color:#fcc;border:1px solid #c00}.ge{font-style:italic}.gr{color:red}.gh{color:#030}.gi{background-color:#cfc;border:1px solid #0c0}.go{color:#aaa}.gp{color:#009}.gu{color:#030}.gt{color:#9c6}.kc{color:#069}.kd{color:#069}.kn{color:#069}.kp{color:#069}.kr{color:#069}.kt{color:#078}.m{color:#c24f19}.s{color:#d73038}.na{color:#006ee0}.nb{color:#366}.nc{color:#168174}.no{color:#360}.nd{color:#6b62de}.ni{color:#727272}.ne{color:#c00}.nf{color:#b715f4}.nl{color:#6b62de}.nn{color:#007ca5}.nt{color:#2f6f9f}.nv{color:#033}.ow{color:#000}.w{color:#bbb}.mf{color:#c24f19}.mh{color:#c24f19}.mi{color:#c24f19}.mo{color:#c24f19}.sb{color:#c30}.sc{color:#c30}.sd{font-style:italic;color:#c30}.s2{color:#c30}.se{color:#c30}.sh{color:#c30}.si{color:#a00}.sx{color:#c30}.sr{color:#337e7e}.s1{color:#c30}.ss{color:#fc3}.bp{color:#366}.vc{color:#033}.vg{color:#033}.vi{color:#033}.il{color:#c24f19}.css .nt+.nt,.css .o,.css .o+.nt{color:#727272}.language-bash::before,.language-sh::before{color:#009;content:"$ ";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.language-powershell::before{color:#009;content:"PM> ";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.anchorjs-link{font-weight:400;color:rgba(0,123,255,.5);transition:color .15s ease-in-out,opacity .15s ease-in-out}@media (prefers-reduced-motion:reduce){.anchorjs-link{transition:none}}.anchorjs-link:hover{color:#007bff;text-decoration:none}.algolia-autocomplete{display:block!important;-ms-flex:1;flex:1}.algolia-autocomplete .ds-dropdown-menu{width:100%;min-width:0!important;max-width:none!important;padding:.75rem 0!important;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.175)}@media (min-width:768px){.algolia-autocomplete .ds-dropdown-menu{width:175%}}.algolia-autocomplete .ds-dropdown-menu::before{display:none!important}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{padding:0!important;overflow:visible!important;background-color:transparent!important;border:0!important}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0!important}.algolia-autocomplete .algolia-docsearch-suggestion{padding:0!important;overflow:visible!important}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{padding:.125rem 1rem!important;margin-top:0!important;font-size:.875rem!important;font-weight:600!important;color:#7952b3!important;border-bottom:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{float:none!important;padding-top:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:none!important;width:auto!important;padding:0!important;text-align:left!important}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:block!important;font-size:.875rem;color:#495057}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline::after{padding:0 .25rem;content:"/"}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;float:none!important;width:100%!important;padding:.25rem 1rem!important}.algolia-autocomplete .algolia-docsearch-suggestion--content::before{display:none!important}.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header{padding-top:.75rem!important;margin-top:.75rem!important;border-top:1px solid rgba(0,0,0,.1)}.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column{display:none!important}.algolia-autocomplete .algolia-docsearch-suggestion--title{display:block;margin-bottom:0!important;font-size:.875rem!important;font-weight:400!important}.algolia-autocomplete .algolia-docsearch-suggestion--text{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%;padding:.2rem 0;font-size:.8125rem!important;font-weight:400;line-height:1.25!important;color:#6c757d}.algolia-autocomplete .algolia-docsearch-footer{float:none!important;width:auto!important;height:auto!important;padding:.75rem 1rem 0;font-size:.75rem!important;line-height:1!important;color:#767676!important;border-top:1px solid rgba(0,0,0,.1)}.algolia-autocomplete .algolia-docsearch-footer--logo{display:inline!important;overflow:visible!important;color:inherit!important;text-indent:0!important;background:0 0!important}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#5f2dab;background-color:rgba(154,132,187,.12)}.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{box-shadow:inset 0 -2px 0 0 rgba(95,45,171,.5)!important}.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content{background-color:rgba(208,189,236,.15)!important} -/*# sourceMappingURL=docs.min.css.map */ \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css.map b/vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css.map deleted file mode 100644 index e47827331..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/css/docs.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["../scss/docs.scss","../scss/_nav.scss","../../../../../scss/mixins/_breakpoints.scss","../../../../../scss/vendor/_rfs.scss","../scss/_masthead.scss","../../../../../scss/mixins/_border-radius.scss","../scss/_ads.scss","../scss/_content.scss","site/docs/4.5/assets/css/docs.min.css","../scss/_skippy.scss","../scss/_sidebar.scss","../scss/_footer.scss","../scss/_component-examples.scss","../../../../../scss/mixins/_grid.scss","../../../../../scss/mixins/_clearfix.scss","../scss/_buttons.scss","../scss/_callouts.scss","../scss/_browser-bugs.scss","../scss/_brand.scss","../scss/_colors.scss","../scss/_clipboard-js.scss","../scss/_placeholder-img.scss","../scss/_syntax.scss","../scss/_anchor.scss","../../../../../scss/mixins/_transition.scss","../scss/_algolia.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap Docs (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under the Creative Commons Attribution 3.0 Unported License.\n * For details, see https://creativecommons.org/licenses/by/3.0/.\n */\n\n// Dev notes\n//\n// Background information on nomenclature and architecture decisions here.\n//\n// - Bootstrap functions, variables, and mixins are included for easy reuse.\n// Doing so gives us access to the same core utilities provided by Bootstrap.\n// For example, consistent media queries through those mixins.\n//\n// - Bootstrap's **docs variables** are prefixed with `$bd-`.\n// These custom colors avoid collision with the components Bootstrap provides.\n//\n// - Classes are prefixed with `.bd-`.\n// These classes indicate custom-built or modified components for the design\n// and layout of the Bootstrap docs. They are not included in our builds.\n//\n// Happy Bootstrapping!\n\n// Load Bootstrap variables and mixins\n@import \"../../../../../scss/functions\";\n@import \"../../../../../scss/variables\";\n@import \"../../../../../scss/mixins\";\n\n// Load docs components\n@import \"variables\";\n@import \"nav\";\n@import \"masthead\";\n@import \"ads\";\n@import \"content\";\n@import \"skippy\";\n@import \"sidebar\";\n@import \"footer\";\n@import \"component-examples\";\n@import \"buttons\";\n@import \"callouts\";\n@import \"browser-bugs\";\n@import \"brand\";\n@import \"colors\";\n@import \"clipboard-js\";\n@import \"placeholder-img\";\n\n// Load docs dependencies\n@import \"syntax\";\n@import \"anchor\";\n@import \"algolia\";\n","//\n// Main navbar\n//\n\n.bd-navbar {\n min-height: 4rem;\n background-color: $bd-purple-bright;\n box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05), inset 0 -1px 0 rgba(0, 0, 0, .1);\n\n @include media-breakpoint-down(md) {\n padding-right: .5rem;\n padding-left: .5rem;\n\n .navbar-nav-scroll {\n max-width: 100%;\n height: 2.5rem;\n margin-top: .25rem;\n overflow: hidden;\n\n .navbar-nav {\n padding-bottom: 2rem;\n overflow-x: auto;\n white-space: nowrap;\n -webkit-overflow-scrolling: touch;\n }\n }\n }\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: 1071; // over everything in bootstrap\n }\n }\n\n .navbar-nav {\n .nav-link {\n padding-right: .5rem;\n padding-left: .5rem;\n color: rgba($white, .85);\n\n &.active,\n &:hover {\n color: $white;\n background-color: transparent;\n }\n\n &.active {\n font-weight: 600;\n }\n }\n }\n\n .navbar-nav-svg {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n vertical-align: text-top;\n }\n\n .dropdown-menu {\n @include font-size(.875rem);\n }\n\n .dropdown-item.active {\n font-weight: 600;\n color: $gray-900;\n background: escape-svg($dropdown-active-icon) no-repeat .4rem .6rem/.75rem .75rem;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","// stylelint-disable declaration-no-important\n\n.bd-masthead {\n position: relative;\n padding: 3rem ($grid-gutter-width / 2);\n background: linear-gradient(to right bottom, lighten($bd-purple-light, 16%) 50%, #fff 50%);\n\n h1 {\n @include font-size(4rem);\n line-height: 1;\n }\n\n .lead {\n @include font-size(1.5rem);\n font-weight: 400;\n color: $gray-700;\n }\n\n .btn {\n padding: .8rem 2rem;\n font-weight: 600;\n @include font-size(1.25rem);\n }\n\n .carbonad {\n margin-top: 0 !important;\n margin-bottom: -3rem !important;\n }\n\n @include media-breakpoint-up(sm) {\n padding-top: 5rem;\n padding-bottom: 5rem;\n\n .carbonad {\n margin-bottom: 0 !important;\n }\n }\n\n @include media-breakpoint-up(md) {\n .carbonad {\n margin-top: 3rem !important;\n }\n }\n}\n\n.masthead-followup {\n .bd-clipboard { display: none; }\n\n h2 {\n @include font-size(2.5rem);\n }\n\n .highlight {\n @include border-radius(.5rem);\n\n pre::-webkit-scrollbar {\n display: none;\n }\n\n pre code {\n display: inline-block;\n white-space: pre;\n\n &::before {\n display: none;\n }\n }\n }\n}\n\n.masthead-followup-icon {\n padding: .75rem;\n background-image: linear-gradient(to bottom right, rgba(255, 255, 255, .2), rgba(255, 255, 255, .01));\n @include border-radius(.75rem);\n box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .1);\n}\n\n.masthead-followup-svg {\n filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .125));\n}\n","// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n $return: ();\n @each $value in $radius {\n @if type-of($value) == number {\n $return: append($return, max($value, 0));\n } @else {\n $return: append($return, $value);\n }\n }\n @return $return;\n}\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: valid-radius($radius);\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: valid-radius($radius);\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: valid-radius($radius);\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: valid-radius($radius);\n }\n}\n","// stylelint-disable declaration-no-important, selector-max-id\n\n//\n// Carbon ads\n//\n\n#carbonads {\n position: static;\n display: block;\n max-width: 400px;\n padding: 15px 15px 15px 160px;\n margin: 2rem 0;\n overflow: hidden;\n @include font-size(.8125rem);\n line-height: 1.4;\n text-align: left;\n background-color: rgba(0, 0, 0, .05);\n\n a {\n color: #333;\n text-decoration: none;\n }\n\n @include media-breakpoint-up(sm) {\n max-width: 330px;\n @include border-radius(4px);\n }\n}\n\n.carbon-img {\n float: left;\n margin-left: -145px;\n}\n\n.carbon-poweredby {\n display: block;\n margin-top: .75rem;\n color: #777 !important;\n}\n","// stylelint-disable no-duplicate-selectors, selector-max-combinators, selector-max-compound-selectors, selector-max-type, selector-no-qualifying-type\n\n//\n// Automatically style Markdown-based tables like a Bootstrap `.table`.\n//\n\n.bd-content {\n order: 1;\n\n // Hack the sticky header\n > h2[id],\n > h3[id],\n > h4[id] {\n pointer-events: none;\n\n &::before {\n display: block;\n height: 6rem;\n margin-top: -6rem;\n content: \"\";\n }\n }\n\n > table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n\n @include media-breakpoint-down(md) {\n display: block;\n overflow-x: auto;\n\n &.table-bordered {\n border: 0;\n }\n }\n\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: $table-cell-padding;\n vertical-align: top;\n border: 1px solid $table-border-color;\n\n > p:last-child {\n margin-bottom: 0;\n }\n }\n }\n }\n\n // Prevent breaking of code (e.g., Grunt tasks list)\n td:first-child > code {\n white-space: nowrap;\n }\n }\n}\n\n.bd-content-title {\n display: block;\n pointer-events: auto;\n}\n\n//\n// Docs sections\n//\n\n.bd-content {\n > h2 {\n @include font-size($h2-font-size);\n }\n\n > h3 {\n @include font-size($h3-font-size);\n }\n\n > h4 {\n @include font-size($h4-font-size);\n }\n\n > h2:not(:first-child) {\n margin-top: 3rem;\n }\n\n > h3 {\n margin-top: 1.5rem;\n }\n\n > ul li,\n > ol li {\n margin-bottom: .25rem;\n }\n\n @include media-breakpoint-up(lg) {\n > ul,\n > ol,\n > p {\n max-width: 80%;\n }\n }\n}\n\n.bd-title {\n margin-top: 1rem;\n margin-bottom: .5rem;\n @include font-size(3rem);\n}\n\n.bd-lead {\n @include font-size(1.5rem);\n font-weight: 300;\n\n @include media-breakpoint-up(lg) {\n max-width: 80%;\n }\n}\n\n.bd-text-purple { color: $bd-purple; }\n.bd-text-purple-bright { color: $bd-purple-bright; }\n\n.bd-bg-purple-bright {\n background-color: $bd-purple-bright;\n}\n","/*!\n * Bootstrap Docs (https://getbootstrap.com/)\n * Copyright 2011-2020 The Bootstrap Authors\n * Copyright 2011-2020 Twitter, Inc.\n * Licensed under the Creative Commons Attribution 3.0 Unported License.\n * For details, see https://creativecommons.org/licenses/by/3.0/.\n */\n.bd-navbar {\n min-height: 4rem;\n background-color: #7952b3;\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.05), inset 0 -1px 0 rgba(0, 0, 0, 0.1);\n}\n\n@media (max-width: 991.98px) {\n .bd-navbar {\n padding-right: .5rem;\n padding-left: .5rem;\n }\n .bd-navbar .navbar-nav-scroll {\n max-width: 100%;\n height: 2.5rem;\n margin-top: .25rem;\n overflow: hidden;\n }\n .bd-navbar .navbar-nav-scroll .navbar-nav {\n padding-bottom: 2rem;\n overflow-x: auto;\n white-space: nowrap;\n -webkit-overflow-scrolling: touch;\n }\n}\n\n@media (min-width: 768px) {\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-navbar {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1071;\n }\n }\n}\n\n.bd-navbar .navbar-nav .nav-link {\n padding-right: .5rem;\n padding-left: .5rem;\n color: rgba(255, 255, 255, 0.85);\n}\n\n.bd-navbar .navbar-nav .nav-link.active, .bd-navbar .navbar-nav .nav-link:hover {\n color: #fff;\n background-color: transparent;\n}\n\n.bd-navbar .navbar-nav .nav-link.active {\n font-weight: 600;\n}\n\n.bd-navbar .navbar-nav-svg {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n vertical-align: text-top;\n}\n\n.bd-navbar .dropdown-menu {\n font-size: 0.875rem;\n}\n\n.bd-navbar .dropdown-item.active {\n font-weight: 600;\n color: #212529;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") no-repeat 0.4rem 0.6rem/0.75rem 0.75rem;\n}\n\n.bd-masthead {\n position: relative;\n padding: 3rem 15px;\n background: linear-gradient(to right bottom, #f7f5fb 50%, #fff 50%);\n}\n\n.bd-masthead h1 {\n font-size: 4rem;\n line-height: 1;\n}\n\n@media (max-width: 1200px) {\n .bd-masthead h1 {\n font-size: calc(1.525rem + 3.3vw) ;\n }\n}\n\n.bd-masthead .lead {\n font-size: 1.5rem;\n font-weight: 400;\n color: #495057;\n}\n\n@media (max-width: 1200px) {\n .bd-masthead .lead {\n font-size: calc(1.275rem + 0.3vw) ;\n }\n}\n\n.bd-masthead .btn {\n padding: .8rem 2rem;\n font-weight: 600;\n font-size: 1.25rem;\n}\n\n.bd-masthead .carbonad {\n margin-top: 0 !important;\n margin-bottom: -3rem !important;\n}\n\n@media (min-width: 576px) {\n .bd-masthead {\n padding-top: 5rem;\n padding-bottom: 5rem;\n }\n .bd-masthead .carbonad {\n margin-bottom: 0 !important;\n }\n}\n\n@media (min-width: 768px) {\n .bd-masthead .carbonad {\n margin-top: 3rem !important;\n }\n}\n\n.masthead-followup .bd-clipboard {\n display: none;\n}\n\n.masthead-followup h2 {\n font-size: 2.5rem;\n}\n\n@media (max-width: 1200px) {\n .masthead-followup h2 {\n font-size: calc(1.375rem + 1.5vw) ;\n }\n}\n\n.masthead-followup .highlight {\n border-radius: 0.5rem;\n}\n\n.masthead-followup .highlight pre::-webkit-scrollbar {\n display: none;\n}\n\n.masthead-followup .highlight pre code {\n display: inline-block;\n white-space: pre;\n}\n\n.masthead-followup .highlight pre code::before {\n display: none;\n}\n\n.masthead-followup-icon {\n padding: .75rem;\n background-image: linear-gradient(to bottom right, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.01));\n border-radius: 0.75rem;\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.1);\n}\n\n.masthead-followup-svg {\n -webkit-filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.125));\n filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.125));\n}\n\n#carbonads {\n position: static;\n display: block;\n max-width: 400px;\n padding: 15px 15px 15px 160px;\n margin: 2rem 0;\n overflow: hidden;\n font-size: 0.8125rem;\n line-height: 1.4;\n text-align: left;\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n#carbonads a {\n color: #333;\n text-decoration: none;\n}\n\n@media (min-width: 576px) {\n #carbonads {\n max-width: 330px;\n border-radius: 4px;\n }\n}\n\n.carbon-img {\n float: left;\n margin-left: -145px;\n}\n\n.carbon-poweredby {\n display: block;\n margin-top: .75rem;\n color: #777 !important;\n}\n\n.bd-content {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.bd-content > h2[id],\n.bd-content > h3[id],\n.bd-content > h4[id] {\n pointer-events: none;\n}\n\n.bd-content > h2[id]::before,\n.bd-content > h3[id]::before,\n.bd-content > h4[id]::before {\n display: block;\n height: 6rem;\n margin-top: -6rem;\n content: \"\";\n}\n\n.bd-content > table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n}\n\n@media (max-width: 991.98px) {\n .bd-content > table {\n display: block;\n overflow-x: auto;\n }\n .bd-content > table.table-bordered {\n border: 0;\n }\n}\n\n.bd-content > table > thead > tr > th,\n.bd-content > table > thead > tr > td,\n.bd-content > table > tbody > tr > th,\n.bd-content > table > tbody > tr > td,\n.bd-content > table > tfoot > tr > th,\n.bd-content > table > tfoot > tr > td {\n padding: 0.75rem;\n vertical-align: top;\n border: 1px solid #dee2e6;\n}\n\n.bd-content > table > thead > tr > th > p:last-child,\n.bd-content > table > thead > tr > td > p:last-child,\n.bd-content > table > tbody > tr > th > p:last-child,\n.bd-content > table > tbody > tr > td > p:last-child,\n.bd-content > table > tfoot > tr > th > p:last-child,\n.bd-content > table > tfoot > tr > td > p:last-child {\n margin-bottom: 0;\n}\n\n.bd-content > table td:first-child > code {\n white-space: nowrap;\n}\n\n.bd-content-title {\n display: block;\n pointer-events: auto;\n}\n\n.bd-content > h2 {\n font-size: 2rem;\n}\n\n@media (max-width: 1200px) {\n .bd-content > h2 {\n font-size: calc(1.325rem + 0.9vw) ;\n }\n}\n\n.bd-content > h3 {\n font-size: 1.75rem;\n}\n\n@media (max-width: 1200px) {\n .bd-content > h3 {\n font-size: calc(1.3rem + 0.6vw) ;\n }\n}\n\n.bd-content > h4 {\n font-size: 1.5rem;\n}\n\n@media (max-width: 1200px) {\n .bd-content > h4 {\n font-size: calc(1.275rem + 0.3vw) ;\n }\n}\n\n.bd-content > h2:not(:first-child) {\n margin-top: 3rem;\n}\n\n.bd-content > h3 {\n margin-top: 1.5rem;\n}\n\n.bd-content > ul li,\n.bd-content > ol li {\n margin-bottom: .25rem;\n}\n\n@media (min-width: 992px) {\n .bd-content > ul,\n .bd-content > ol,\n .bd-content > p {\n max-width: 80%;\n }\n}\n\n.bd-title {\n margin-top: 1rem;\n margin-bottom: .5rem;\n font-size: 3rem;\n}\n\n@media (max-width: 1200px) {\n .bd-title {\n font-size: calc(1.425rem + 2.1vw) ;\n }\n}\n\n.bd-lead {\n font-size: 1.5rem;\n font-weight: 300;\n}\n\n@media (max-width: 1200px) {\n .bd-lead {\n font-size: calc(1.275rem + 0.3vw) ;\n }\n}\n\n@media (min-width: 992px) {\n .bd-lead {\n max-width: 80%;\n }\n}\n\n.bd-text-purple {\n color: #563d7c;\n}\n\n.bd-text-purple-bright {\n color: #7952b3;\n}\n\n.bd-bg-purple-bright {\n background-color: #7952b3;\n}\n\n.skippy {\n background-color: #563d7c;\n}\n\n.skippy a {\n color: #fff;\n}\n\n.skippy:focus-within a {\n position: static !important;\n width: auto !important;\n height: auto !important;\n padding: 0.5rem !important;\n margin: 0.25rem !important;\n overflow: visible !important;\n clip: auto !important;\n white-space: normal !important;\n}\n\n.bd-toc {\n -ms-flex-order: 2;\n order: 2;\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n font-size: 0.875rem;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-toc {\n position: -webkit-sticky;\n position: sticky;\n top: 4rem;\n height: calc(100vh - 4rem);\n overflow-y: auto;\n }\n}\n\n.section-nav {\n padding-left: 0;\n border-left: 1px solid #eee;\n}\n\n.section-nav ul {\n padding-left: 1rem;\n}\n\n.toc-entry {\n display: block;\n}\n\n.toc-entry a {\n display: block;\n padding: .125rem 1.5rem;\n color: #77757a;\n}\n\n.toc-entry a:hover {\n color: #007bff;\n text-decoration: none;\n}\n\n.bd-sidebar {\n -ms-flex-order: 0;\n order: 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n@media (min-width: 768px) {\n .bd-sidebar {\n border-right: 1px solid rgba(0, 0, 0, 0.1);\n }\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-sidebar {\n position: -webkit-sticky;\n position: sticky;\n top: 4rem;\n z-index: 1000;\n height: calc(100vh - 4rem);\n }\n }\n}\n\n@media (min-width: 1200px) {\n .bd-sidebar {\n -ms-flex: 0 1 320px;\n flex: 0 1 320px;\n }\n}\n\n.bd-links {\n padding-top: 1rem;\n padding-bottom: 1rem;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n@media (min-width: 768px) {\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-links {\n max-height: calc(100vh - 9rem);\n overflow-y: auto;\n }\n }\n}\n\n@media (min-width: 768px) {\n .bd-links {\n display: block !important;\n }\n}\n\n.bd-search {\n position: relative;\n padding: 1rem 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\n.bd-search .form-control:focus {\n border-color: #7952b3;\n box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);\n}\n\n.bd-search-docs-toggle {\n color: #212529;\n}\n\n.bd-sidenav {\n display: none;\n}\n\n.bd-toc-link {\n display: block;\n padding: .25rem 1.5rem;\n font-weight: 600;\n color: rgba(0, 0, 0, 0.65);\n}\n\n.bd-toc-link:hover {\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n}\n\n.bd-toc-item.active {\n margin-bottom: 1rem;\n}\n\n.bd-toc-item.active:not(:first-child) {\n margin-top: 1rem;\n}\n\n.bd-toc-item.active > .bd-toc-link {\n color: rgba(0, 0, 0, 0.85);\n}\n\n.bd-toc-item.active > .bd-toc-link:hover {\n background-color: transparent;\n}\n\n.bd-toc-item.active > .bd-sidenav {\n display: block;\n}\n\n.bd-sidebar .nav > li > a {\n display: block;\n padding: .25rem 1.5rem;\n font-size: 90%;\n color: rgba(0, 0, 0, 0.65);\n}\n\n.bd-sidebar .nav > li > a:hover {\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n background-color: transparent;\n}\n\n.bd-sidebar .nav > .active > a,\n.bd-sidebar .nav > .active:hover > a {\n font-weight: 600;\n color: rgba(0, 0, 0, 0.85);\n background-color: transparent;\n}\n\n.bd-footer {\n font-size: 0.875rem;\n text-align: center;\n background-color: #f7f7f7;\n}\n\n.bd-footer a {\n font-weight: 600;\n color: #495057;\n}\n\n.bd-footer a:hover, .bd-footer a:focus {\n color: #007bff;\n}\n\n.bd-footer p {\n margin-bottom: 0;\n}\n\n@media (min-width: 576px) {\n .bd-footer {\n text-align: left;\n }\n}\n\n.bd-footer-links {\n padding-left: 0;\n margin-bottom: 1rem;\n}\n\n.bd-footer-links li {\n display: inline-block;\n}\n\n.bd-footer-links li + li {\n margin-left: 1rem;\n}\n\n.bd-example-row .row > .col,\n.bd-example-row .row > [class^=\"col-\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, 0.15);\n border: 1px solid rgba(86, 61, 124, 0.2);\n}\n\n.bd-example-row .row + .row {\n margin-top: 1rem;\n}\n\n.bd-example-row .flex-items-top,\n.bd-example-row .flex-items-middle,\n.bd-example-row .flex-items-bottom {\n min-height: 6rem;\n background-color: rgba(255, 0, 0, 0.1);\n}\n\n.bd-example-row-flex-cols .row {\n min-height: 10rem;\n background-color: rgba(255, 0, 0, 0.1);\n}\n\n.bd-highlight {\n background-color: rgba(86, 61, 124, 0.15);\n border: 1px solid rgba(86, 61, 124, 0.15);\n}\n\n.bd-example-responsive-containers [class^=\"container\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, 0.15);\n border: 1px solid rgba(86, 61, 124, 0.2);\n}\n\n.example-container {\n width: 800px;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.example-row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.example-content-main {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n@media (min-width: 576px) {\n .example-content-main {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n}\n\n@media (min-width: 992px) {\n .example-content-main {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n}\n\n.example-content-secondary {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n@media (min-width: 576px) {\n .example-content-secondary {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n}\n\n@media (min-width: 992px) {\n .example-content-secondary {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n}\n\n.bd-example {\n position: relative;\n padding: 1rem;\n margin: 1rem -15px 0;\n border: solid #f8f9fa;\n border-width: .2rem 0 0;\n}\n\n.bd-example::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n@media (min-width: 576px) {\n .bd-example {\n padding: 1.5rem;\n margin-right: 0;\n margin-left: 0;\n border-width: .2rem;\n }\n}\n\n.bd-example + .highlight,\n.bd-example + .clipboard + .highlight {\n margin-top: 0;\n}\n\n.bd-example + p {\n margin-top: 2rem;\n}\n\n.bd-example .custom-file-input:lang(es) ~ .custom-file-label::after {\n content: \"Elegir\";\n}\n\n.bd-example > .form-control + .form-control {\n margin-top: .5rem;\n}\n\n.bd-example > .nav + .nav,\n.bd-example > .alert + .alert,\n.bd-example > .navbar + .navbar,\n.bd-example > .progress + .progress,\n.bd-example > .progress + .btn {\n margin-top: 1rem;\n}\n\n.bd-example > .dropdown-menu:first-child {\n position: static;\n display: block;\n}\n\n.bd-example > .form-group:last-child {\n margin-bottom: 0;\n}\n\n.bd-example > .close {\n float: none;\n}\n\n.bd-example-type .table td {\n padding: 1rem 0;\n border-color: #eee;\n}\n\n.bd-example-type .table tr:first-child td {\n border-top: 0;\n}\n\n.bd-example-type h1,\n.bd-example-type h2,\n.bd-example-type h3,\n.bd-example-type h4,\n.bd-example-type h5,\n.bd-example-type h6 {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.bd-example-bg-classes p {\n padding: 1rem;\n}\n\n.bd-example > svg + svg,\n.bd-example > img + img {\n margin-left: .5rem;\n}\n\n.bd-example > .btn,\n.bd-example > .btn-group {\n margin-top: .25rem;\n margin-bottom: .25rem;\n}\n\n.bd-example > .btn-toolbar + .btn-toolbar {\n margin-top: .5rem;\n}\n\n.bd-example-control-sizing select,\n.bd-example-control-sizing input[type=\"text\"] + input[type=\"text\"] {\n margin-top: .5rem;\n}\n\n.bd-example-form .input-group {\n margin-bottom: .5rem;\n}\n\n.bd-example > textarea.form-control {\n resize: vertical;\n}\n\n.bd-example > .list-group {\n max-width: 400px;\n}\n\n.bd-example > [class*=\"list-group-horizontal\"] {\n max-width: 100%;\n}\n\n.bd-example .fixed-top,\n.bd-example .sticky-top {\n position: static;\n margin: -1rem -1rem 1rem;\n}\n\n.bd-example .fixed-bottom {\n position: static;\n margin: 1rem -1rem -1rem;\n}\n\n@media (min-width: 576px) {\n .bd-example .fixed-top,\n .bd-example .sticky-top {\n margin: -1.5rem -1.5rem 1rem;\n }\n .bd-example .fixed-bottom {\n margin: 1rem -1.5rem -1.5rem;\n }\n}\n\n.bd-example .pagination {\n margin-top: .5rem;\n margin-bottom: .5rem;\n}\n\n.modal {\n z-index: 1072;\n}\n\n.modal .tooltip,\n.modal .popover {\n z-index: 1073;\n}\n\n.modal-backdrop {\n z-index: 1071;\n}\n\n.bd-example-modal {\n background-color: #fafafa;\n}\n\n.bd-example-modal .modal {\n position: relative;\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n z-index: 1;\n display: block;\n}\n\n.bd-example-modal .modal-dialog {\n left: auto;\n margin-right: auto;\n margin-left: auto;\n}\n\n.bd-example-tabs .nav-tabs {\n margin-bottom: 1rem;\n}\n\n.bd-example-popover-static {\n padding-bottom: 1.5rem;\n background-color: #f9f9f9;\n}\n\n.bd-example-popover-static .popover {\n position: relative;\n display: block;\n float: left;\n width: 260px;\n margin: 1.25rem;\n}\n\n.tooltip-demo a {\n white-space: nowrap;\n}\n\n.bd-example-tooltip-static .tooltip {\n position: relative;\n display: inline-block;\n margin: 10px 20px;\n opacity: 1;\n}\n\n.scrollspy-example {\n position: relative;\n height: 200px;\n margin-top: .5rem;\n overflow: auto;\n}\n\n.scrollspy-example-2 {\n position: relative;\n height: 350px;\n overflow: auto;\n}\n\n.bd-example-border-utils [class^=\"border\"] {\n display: inline-block;\n width: 5rem;\n height: 5rem;\n margin: .25rem;\n background-color: #f5f5f5;\n}\n\n.bd-example-border-utils-0 [class^=\"border\"] {\n border: 1px solid #dee2e6;\n}\n\n.bd-example-forms-input-group-workaround .fix-rounded-right {\n border-top-right-radius: 0.2rem !important;\n border-bottom-right-radius: 0.2rem !important;\n}\n\n.highlight {\n padding: 1rem;\n margin-top: 1rem;\n margin-bottom: 1rem;\n background-color: #f8f9fa;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n@media (min-width: 576px) {\n .highlight {\n padding: 1.5rem;\n }\n}\n\n.bd-content .highlight {\n margin-right: -15px;\n margin-left: -15px;\n}\n\n@media (min-width: 576px) {\n .bd-content .highlight {\n margin-right: 0;\n margin-left: 0;\n }\n}\n\n.highlight pre {\n padding: 0;\n margin-top: .65rem;\n margin-bottom: .65rem;\n background-color: transparent;\n border: 0;\n}\n\n.highlight pre code {\n font-size: inherit;\n color: #212529;\n}\n\n.btn-bd-primary {\n font-weight: 600;\n color: #fff;\n background-color: #7952b3;\n border-color: #7952b3;\n}\n\n.btn-bd-primary:hover, .btn-bd-primary:active {\n color: #fff;\n background-color: #614092;\n border-color: #614092;\n}\n\n.btn-bd-primary:focus {\n box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);\n}\n\n.btn-bd-download {\n font-weight: 600;\n color: #ffe484;\n border-color: #ffe484;\n}\n\n.btn-bd-download:hover, .btn-bd-download:active {\n color: #2a2730;\n background-color: #ffe484;\n border-color: #ffe484;\n}\n\n.btn-bd-download:focus {\n box-shadow: 0 0 0 3px rgba(255, 228, 132, 0.25);\n}\n\n.btn-bd-light {\n color: #6c757d;\n border-color: #dee2e6;\n}\n\n.show > .btn-bd-light, .btn-bd-light:hover, .btn-bd-light:active {\n color: #7952b3;\n background-color: #fff;\n border-color: #7952b3;\n}\n\n.btn-bd-light:focus {\n box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);\n}\n\n.bd-callout {\n padding: 1.25rem;\n margin-top: 1.25rem;\n margin-bottom: 1.25rem;\n border: 1px solid #eee;\n border-left-width: .25rem;\n border-radius: 0.25rem;\n}\n\n.bd-callout h4 {\n margin-top: 0;\n margin-bottom: .25rem;\n}\n\n.bd-callout p:last-child {\n margin-bottom: 0;\n}\n\n.bd-callout code {\n border-radius: 0.25rem;\n}\n\n.bd-callout + .bd-callout {\n margin-top: -.25rem;\n}\n\n.bd-callout-info {\n border-left-color: #5bc0de;\n}\n\n.bd-callout-info h4 {\n color: #5bc0de;\n}\n\n.bd-callout-warning {\n border-left-color: #f0ad4e;\n}\n\n.bd-callout-warning h4 {\n color: #f0ad4e;\n}\n\n.bd-callout-danger {\n border-left-color: #d9534f;\n}\n\n.bd-callout-danger h4 {\n color: #d9534f;\n}\n\n.bd-browser-bugs td p {\n margin-bottom: 0;\n}\n\n.bd-browser-bugs th:first-child {\n width: 18%;\n}\n\n.bd-brand-logos {\n display: table;\n width: 100%;\n margin-bottom: 1rem;\n overflow: hidden;\n color: #563d7c;\n background-color: #f9f9f9;\n border-radius: 0.25rem;\n}\n\n.bd-brand-logos .inverse {\n color: #fff;\n background-color: #563d7c;\n}\n\n.bd-brand-item {\n padding: 4rem 0;\n text-align: center;\n}\n\n.bd-brand-item + .bd-brand-item {\n border-top: 1px solid #fff;\n}\n\n.bd-brand-item h1,\n.bd-brand-item h3 {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n@media (min-width: 768px) {\n .bd-brand-item {\n display: table-cell;\n width: 1%;\n }\n .bd-brand-item + .bd-brand-item {\n border-top: 0;\n border-left: 1px solid #fff;\n }\n .bd-brand-item h1 {\n font-size: 4rem;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1200px) {\n .bd-brand-item h1 {\n font-size: calc(1.525rem + 3.3vw) ;\n }\n}\n\n.color-swatches {\n margin: 0 -5px;\n overflow: hidden;\n}\n\n.color-swatches .bd-purple {\n background-color: #563d7c;\n}\n\n.color-swatches .bd-purple-light {\n background-color: #cbbde2;\n}\n\n.color-swatches .bd-purple-lighter {\n background-color: #e5e1ea;\n}\n\n.color-swatches .bd-gray {\n background-color: #f9f9f9;\n}\n\n.color-swatch {\n float: left;\n width: 4rem;\n height: 4rem;\n margin-right: .25rem;\n margin-left: .25rem;\n border-radius: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .color-swatch {\n width: 6rem;\n height: 6rem;\n }\n}\n\n.swatch-blue {\n color: #fff;\n background-color: #007bff;\n}\n\n.swatch-indigo {\n color: #fff;\n background-color: #6610f2;\n}\n\n.swatch-purple {\n color: #fff;\n background-color: #6f42c1;\n}\n\n.swatch-pink {\n color: #fff;\n background-color: #e83e8c;\n}\n\n.swatch-red {\n color: #fff;\n background-color: #dc3545;\n}\n\n.swatch-orange {\n color: #212529;\n background-color: #fd7e14;\n}\n\n.swatch-yellow {\n color: #212529;\n background-color: #ffc107;\n}\n\n.swatch-green {\n color: #fff;\n background-color: #28a745;\n}\n\n.swatch-teal {\n color: #fff;\n background-color: #20c997;\n}\n\n.swatch-cyan {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.swatch-white {\n color: #212529;\n background-color: #fff;\n}\n\n.swatch-gray {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-gray-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-100 {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.swatch-200 {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.swatch-300 {\n color: #212529;\n background-color: #dee2e6;\n}\n\n.swatch-400 {\n color: #212529;\n background-color: #ced4da;\n}\n\n.swatch-500 {\n color: #212529;\n background-color: #adb5bd;\n}\n\n.swatch-600 {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-700 {\n color: #fff;\n background-color: #495057;\n}\n\n.swatch-800 {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-900 {\n color: #fff;\n background-color: #212529;\n}\n\n.bd-clipboard {\n position: relative;\n display: none;\n float: right;\n}\n\n.bd-clipboard + .highlight {\n margin-top: 0;\n}\n\n@media (min-width: 768px) {\n .bd-clipboard {\n display: block;\n }\n}\n\n.btn-clipboard {\n position: absolute;\n top: .65rem;\n right: .65rem;\n z-index: 10;\n display: block;\n padding: .25rem .5rem;\n font-size: 65%;\n color: #007bff;\n background-color: #fff;\n border: 1px solid;\n border-radius: 0.25rem;\n}\n\n.btn-clipboard:hover {\n color: #fff;\n background-color: #007bff;\n}\n\n.bd-placeholder-img {\n font-size: 1.125rem;\n text-anchor: middle;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.bd-placeholder-img-lg {\n font-size: 3.5rem;\n}\n\n@media (max-width: 1200px) {\n .bd-placeholder-img-lg {\n font-size: calc(1.475rem + 2.7vw) ;\n }\n}\n\n.hll {\n background-color: #ffc;\n}\n\n.c {\n color: #727272;\n}\n\n.k {\n color: #069;\n}\n\n.o {\n color: #555;\n}\n\n.cm {\n color: #727272;\n}\n\n.cp {\n color: #008085;\n}\n\n.c1 {\n color: #727272;\n}\n\n.cs {\n color: #727272;\n}\n\n.gd {\n background-color: #fcc;\n border: 1px solid #c00;\n}\n\n.ge {\n font-style: italic;\n}\n\n.gr {\n color: #f00;\n}\n\n.gh {\n color: #030;\n}\n\n.gi {\n background-color: #cfc;\n border: 1px solid #0c0;\n}\n\n.go {\n color: #aaa;\n}\n\n.gp {\n color: #009;\n}\n\n.gu {\n color: #030;\n}\n\n.gt {\n color: #9c6;\n}\n\n.kc {\n color: #069;\n}\n\n.kd {\n color: #069;\n}\n\n.kn {\n color: #069;\n}\n\n.kp {\n color: #069;\n}\n\n.kr {\n color: #069;\n}\n\n.kt {\n color: #078;\n}\n\n.m {\n color: #c24f19;\n}\n\n.s {\n color: #d73038;\n}\n\n.na {\n color: #006ee0;\n}\n\n.nb {\n color: #366;\n}\n\n.nc {\n color: #168174;\n}\n\n.no {\n color: #360;\n}\n\n.nd {\n color: #6b62de;\n}\n\n.ni {\n color: #727272;\n}\n\n.ne {\n color: #c00;\n}\n\n.nf {\n color: #b715f4;\n}\n\n.nl {\n color: #6b62de;\n}\n\n.nn {\n color: #007ca5;\n}\n\n.nt {\n color: #2f6f9f;\n}\n\n.nv {\n color: #033;\n}\n\n.ow {\n color: #000;\n}\n\n.w {\n color: #bbb;\n}\n\n.mf {\n color: #c24f19;\n}\n\n.mh {\n color: #c24f19;\n}\n\n.mi {\n color: #c24f19;\n}\n\n.mo {\n color: #c24f19;\n}\n\n.sb {\n color: #c30;\n}\n\n.sc {\n color: #c30;\n}\n\n.sd {\n font-style: italic;\n color: #c30;\n}\n\n.s2 {\n color: #c30;\n}\n\n.se {\n color: #c30;\n}\n\n.sh {\n color: #c30;\n}\n\n.si {\n color: #a00;\n}\n\n.sx {\n color: #c30;\n}\n\n.sr {\n color: #337e7e;\n}\n\n.s1 {\n color: #c30;\n}\n\n.ss {\n color: #fc3;\n}\n\n.bp {\n color: #366;\n}\n\n.vc {\n color: #033;\n}\n\n.vg {\n color: #033;\n}\n\n.vi {\n color: #033;\n}\n\n.il {\n color: #c24f19;\n}\n\n.css .o,\n.css .o + .nt,\n.css .nt + .nt {\n color: #727272;\n}\n\n.language-bash::before,\n.language-sh::before {\n color: #009;\n content: \"$ \";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.language-powershell::before {\n color: #009;\n content: \"PM> \";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.anchorjs-link {\n font-weight: 400;\n color: rgba(0, 123, 255, 0.5);\n transition: color 0.15s ease-in-out, opacity 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .anchorjs-link {\n transition: none;\n }\n}\n\n.anchorjs-link:hover {\n color: #007bff;\n text-decoration: none;\n}\n\n.algolia-autocomplete {\n display: block !important;\n -ms-flex: 1;\n flex: 1;\n}\n\n.algolia-autocomplete .ds-dropdown-menu {\n width: 100%;\n min-width: 0 !important;\n max-width: none !important;\n padding: .75rem 0 !important;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.175);\n}\n\n@media (min-width: 768px) {\n .algolia-autocomplete .ds-dropdown-menu {\n width: 175%;\n }\n}\n\n.algolia-autocomplete .ds-dropdown-menu::before {\n display: none !important;\n}\n\n.algolia-autocomplete .ds-dropdown-menu [class^=\"ds-dataset-\"] {\n padding: 0 !important;\n overflow: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n}\n\n.algolia-autocomplete .ds-dropdown-menu .ds-suggestions {\n margin-top: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion {\n padding: 0 !important;\n overflow: visible !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--category-header {\n padding: .125rem 1rem !important;\n margin-top: 0 !important;\n font-size: 0.875rem !important;\n font-weight: 600 !important;\n color: #7952b3 !important;\n border-bottom: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--wrapper {\n float: none !important;\n padding-top: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n text-align: left !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline {\n display: block !important;\n font-size: 0.875rem;\n color: #495057;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline::after {\n padding: 0 .25rem;\n content: \"/\";\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--content {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n float: none !important;\n width: 100% !important;\n padding: .25rem 1rem !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--content::before {\n display: none !important;\n}\n\n.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header {\n padding-top: .75rem !important;\n margin-top: .75rem !important;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column {\n display: none !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--title {\n display: block;\n margin-bottom: 0 !important;\n font-size: 0.875rem !important;\n font-weight: 400 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--text {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n padding: .2rem 0;\n font-size: 0.8125rem !important;\n font-weight: 400;\n line-height: 1.25 !important;\n color: #6c757d;\n}\n\n.algolia-autocomplete .algolia-docsearch-footer {\n float: none !important;\n width: auto !important;\n height: auto !important;\n padding: .75rem 1rem 0;\n font-size: 0.75rem !important;\n line-height: 1 !important;\n color: #767676 !important;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.algolia-autocomplete .algolia-docsearch-footer--logo {\n display: inline !important;\n overflow: visible !important;\n color: inherit !important;\n text-indent: 0 !important;\n background: none !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--highlight {\n color: #5f2dab;\n background-color: rgba(154, 132, 187, 0.12);\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight {\n box-shadow: inset 0 -2px 0 0 rgba(95, 45, 171, 0.5) !important;\n}\n\n.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content {\n background-color: rgba(208, 189, 236, 0.15) !important;\n}\n/*# sourceMappingURL=docs.min.css.map */","// stylelint-disable declaration-no-important\n\n.skippy {\n background-color: $bd-purple;\n\n a {\n color: $white;\n }\n\n &:focus-within a {\n position: static !important;\n width: auto !important;\n height: auto !important;\n padding: $spacer / 2 !important;\n margin: $spacer / 4 !important;\n overflow: visible !important;\n clip: auto !important;\n white-space: normal !important;\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Right side table of contents\n//\n\n.bd-toc {\n @supports (position: sticky) {\n position: sticky;\n top: 4rem;\n height: subtract(100vh, 4rem);\n overflow-y: auto;\n }\n order: 2;\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n @include font-size(.875rem);\n}\n\n.section-nav {\n padding-left: 0;\n border-left: 1px solid #eee;\n\n ul {\n padding-left: 1rem;\n }\n}\n\n.toc-entry {\n display: block;\n\n a {\n display: block;\n padding: .125rem 1.5rem;\n color: #77757a;\n\n &:hover {\n color: $blue;\n text-decoration: none;\n }\n }\n}\n\n//\n// Left side navigation\n//\n\n.bd-sidebar {\n order: 0;\n // background-color: #f5f2f9;\n border-bottom: 1px solid rgba(0, 0, 0, .1);\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n position: sticky;\n top: 4rem;\n z-index: 1000;\n height: subtract(100vh, 4rem);\n }\n border-right: 1px solid rgba(0, 0, 0, .1);\n }\n\n @include media-breakpoint-up(xl) {\n flex: 0 1 320px;\n }\n}\n\n.bd-links {\n padding-top: 1rem;\n padding-bottom: 1rem;\n margin-right: -15px;\n margin-left: -15px;\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n max-height: subtract(100vh, 9rem);\n overflow-y: auto;\n }\n }\n\n // Override collapse behaviors\n @include media-breakpoint-up(md) {\n display: block !important;\n }\n}\n\n.bd-search {\n position: relative; // To contain the Algolia search\n padding: 1rem 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-bottom: 1px solid rgba(0, 0, 0, .05);\n\n .form-control:focus {\n border-color: $bd-purple-bright;\n box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);\n }\n}\n\n.bd-search-docs-toggle {\n color: $gray-900;\n}\n\n.bd-sidenav {\n display: none;\n}\n\n.bd-toc-link {\n display: block;\n padding: .25rem 1.5rem;\n font-weight: 600;\n color: rgba(0, 0, 0, .65);\n\n &:hover {\n color: rgba(0, 0, 0, .85);\n text-decoration: none;\n }\n}\n\n.bd-toc-item {\n &.active {\n margin-bottom: 1rem;\n\n &:not(:first-child) {\n margin-top: 1rem;\n }\n\n > .bd-toc-link {\n color: rgba(0, 0, 0, .85);\n\n &:hover {\n background-color: transparent;\n }\n }\n\n > .bd-sidenav {\n display: block;\n }\n }\n}\n\n// All levels of nav\n.bd-sidebar .nav > li > a {\n display: block;\n padding: .25rem 1.5rem;\n @include font-size(90%);\n color: rgba(0, 0, 0, .65);\n}\n\n.bd-sidebar .nav > li > a:hover {\n color: rgba(0, 0, 0, .85);\n text-decoration: none;\n background-color: transparent;\n}\n\n.bd-sidebar .nav > .active > a,\n.bd-sidebar .nav > .active:hover > a {\n font-weight: 600;\n color: rgba(0, 0, 0, .85);\n background-color: transparent;\n}\n","//\n// Footer\n//\n\n.bd-footer {\n @include font-size(.875rem);\n text-align: center;\n background-color: #f7f7f7;\n\n a {\n font-weight: 600;\n color: $gray-700;\n\n &:hover,\n &:focus {\n color: $link-color;\n }\n }\n\n p {\n margin-bottom: 0;\n }\n\n @include media-breakpoint-up(sm) {\n text-align: left;\n }\n}\n\n.bd-footer-links {\n padding-left: 0;\n margin-bottom: 1rem;\n\n li {\n display: inline-block;\n\n + li {\n margin-left: 1rem;\n }\n }\n}\n","// stylelint-disable no-duplicate-selectors, selector-no-qualifying-type\n\n//\n// Grid examples\n//\n\n.bd-example-row {\n .row {\n > .col,\n > [class^=\"col-\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, .15);\n border: 1px solid rgba(86, 61, 124, .2);\n }\n }\n\n .row + .row {\n margin-top: 1rem;\n }\n\n .flex-items-top,\n .flex-items-middle,\n .flex-items-bottom {\n min-height: 6rem;\n background-color: rgba(255, 0, 0, .1);\n }\n}\n\n.bd-example-row-flex-cols .row {\n min-height: 10rem;\n background-color: rgba(255, 0, 0, .1);\n}\n\n.bd-highlight {\n background-color: rgba($bd-purple, .15);\n border: 1px solid rgba($bd-purple, .15);\n}\n\n.bd-example-responsive-containers {\n [class^=\"container\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, .15);\n border: 1px solid rgba(86, 61, 124, .2);\n }\n}\n\n// Grid mixins\n.example-container {\n width: 800px;\n @include make-container();\n}\n\n.example-row {\n @include make-row();\n}\n\n.example-content-main {\n @include make-col-ready();\n\n @include media-breakpoint-up(sm) {\n @include make-col(6);\n }\n\n @include media-breakpoint-up(lg) {\n @include make-col(8);\n }\n}\n\n.example-content-secondary {\n @include make-col-ready();\n\n @include media-breakpoint-up(sm) {\n @include make-col(6);\n }\n\n @include media-breakpoint-up(lg) {\n @include make-col(4);\n }\n}\n\n\n//\n// Docs examples\n//\n\n.bd-example {\n position: relative;\n padding: 1rem;\n margin: 1rem (-$grid-gutter-width / 2) 0;\n border: solid $gray-100;\n border-width: .2rem 0 0;\n @include clearfix();\n\n @include media-breakpoint-up(sm) {\n padding: 1.5rem;\n margin-right: 0;\n margin-left: 0;\n border-width: .2rem;\n }\n\n + .highlight,\n + .clipboard + .highlight {\n margin-top: 0;\n }\n\n + p {\n margin-top: 2rem;\n }\n\n .custom-file-input:lang(es) ~ .custom-file-label::after {\n content: \"Elegir\";\n }\n\n > .form-control {\n + .form-control {\n margin-top: .5rem;\n }\n }\n\n > .nav + .nav,\n > .alert + .alert,\n > .navbar + .navbar,\n > .progress + .progress,\n > .progress + .btn {\n margin-top: 1rem;\n }\n\n > .dropdown-menu:first-child {\n position: static;\n display: block;\n }\n\n > .form-group:last-child {\n margin-bottom: 0;\n }\n\n > .close {\n float: none;\n }\n}\n\n// Typography\n.bd-example-type {\n .table {\n td {\n padding: 1rem 0;\n border-color: #eee;\n }\n tr:first-child td {\n border-top: 0;\n }\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 0;\n margin-bottom: 0;\n }\n}\n\n// Contextual background colors\n.bd-example-bg-classes p {\n padding: 1rem;\n}\n\n// Images\n.bd-example {\n > svg + svg,\n > img + img {\n margin-left: .5rem;\n }\n}\n\n// Buttons\n.bd-example {\n > .btn,\n > .btn-group {\n margin-top: .25rem;\n margin-bottom: .25rem;\n }\n > .btn-toolbar + .btn-toolbar {\n margin-top: .5rem;\n }\n}\n\n// Forms\n.bd-example-control-sizing select,\n.bd-example-control-sizing input[type=\"text\"] + input[type=\"text\"] {\n margin-top: .5rem;\n}\n.bd-example-form .input-group {\n margin-bottom: .5rem;\n}\n.bd-example > textarea.form-control {\n resize: vertical;\n}\n\n// List groups\n.bd-example > .list-group {\n max-width: 400px;\n}\n.bd-example > [class*=\"list-group-horizontal\"] {\n max-width: 100%;\n}\n\n// Navbars\n.bd-example {\n .fixed-top,\n .sticky-top {\n position: static;\n margin: -1rem -1rem 1rem;\n }\n .fixed-bottom {\n position: static;\n margin: 1rem -1rem -1rem;\n }\n\n @include media-breakpoint-up(sm) {\n .fixed-top,\n .sticky-top {\n margin: -1.5rem -1.5rem 1rem;\n }\n .fixed-bottom {\n margin: 1rem -1.5rem -1.5rem;\n }\n }\n}\n\n// Pagination\n.bd-example .pagination {\n margin-top: .5rem;\n margin-bottom: .5rem;\n}\n\n// Example modals\n.modal {\n z-index: 1072;\n\n .tooltip,\n .popover {\n z-index: 1073;\n }\n}\n\n.modal-backdrop {\n z-index: 1071;\n}\n\n.bd-example-modal {\n background-color: #fafafa;\n\n .modal {\n position: relative;\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n z-index: 1;\n display: block;\n }\n\n .modal-dialog {\n left: auto;\n margin-right: auto;\n margin-left: auto;\n }\n}\n\n// Example tabbable tabs\n.bd-example-tabs .nav-tabs {\n margin-bottom: 1rem;\n}\n\n// Popovers\n.bd-example-popover-static {\n padding-bottom: 1.5rem;\n background-color: #f9f9f9;\n\n .popover {\n position: relative;\n display: block;\n float: left;\n width: 260px;\n margin: 1.25rem;\n }\n}\n\n// Tooltips\n.tooltip-demo a {\n white-space: nowrap;\n}\n\n.bd-example-tooltip-static .tooltip {\n position: relative;\n display: inline-block;\n margin: 10px 20px;\n opacity: 1;\n}\n\n// Scrollspy demo on fixed height div\n.scrollspy-example {\n position: relative;\n height: 200px;\n margin-top: .5rem;\n overflow: auto;\n}\n\n.scrollspy-example-2 {\n position: relative;\n height: 350px;\n overflow: auto;\n}\n\n.bd-example-border-utils {\n [class^=\"border\"] {\n display: inline-block;\n width: 5rem;\n height: 5rem;\n margin: .25rem;\n background-color: #f5f5f5;\n }\n}\n\n.bd-example-border-utils-0 {\n [class^=\"border\"] {\n border: 1px solid $border-color;\n }\n}\n\n.bd-example-forms-input-group-workaround .fix-rounded-right {\n @include border-right-radius(.2rem !important);\n}\n\n//\n// Code snippets\n//\n\n.highlight {\n padding: 1rem;\n margin-top: 1rem;\n margin-bottom: 1rem;\n background-color: $gray-100;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n\n @include media-breakpoint-up(sm) {\n padding: 1.5rem;\n }\n}\n\n.bd-content .highlight {\n margin-right: (-$grid-gutter-width / 2);\n margin-left: (-$grid-gutter-width / 2);\n\n @include media-breakpoint-up(sm) {\n margin-right: 0;\n margin-left: 0;\n }\n}\n\n.highlight {\n pre {\n padding: 0;\n margin-top: .65rem;\n margin-bottom: .65rem;\n background-color: transparent;\n border: 0;\n }\n pre code {\n @include font-size(inherit);\n color: $gray-900; // Effectively the base text color\n }\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n @include deprecate(\"The `make-container-max-widths` mixin\", \"v4.5.2\", \"v5\");\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 100% / $count;\n max-width: 100% / $count;\n }\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","// Buttons\n//\n// Custom buttons for the docs.\n\n.btn-bd-primary {\n font-weight: 600;\n color: $white;\n background-color: $bd-purple-bright;\n border-color: $bd-purple-bright;\n\n &:hover,\n &:active {\n color: $white;\n background-color: darken($bd-purple-bright, 10%);\n border-color: darken($bd-purple-bright, 10%);\n }\n\n &:focus {\n box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);\n }\n}\n\n.btn-bd-download {\n font-weight: 600;\n color: $bd-download;\n border-color: $bd-download;\n\n &:hover,\n &:active {\n color: $bd-dark;\n background-color: $bd-download;\n border-color: $bd-download;\n }\n\n &:focus {\n box-shadow: 0 0 0 3px rgba($bd-download, .25);\n }\n}\n\n.btn-bd-light {\n color: $gray-600;\n border-color: $gray-300;\n\n .show > &,\n &:hover,\n &:active {\n color: $bd-purple-bright;\n background-color: $white;\n border-color: $bd-purple-bright;\n }\n\n &:focus {\n box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);\n }\n}\n","//\n// Callouts\n//\n\n.bd-callout {\n padding: 1.25rem;\n margin-top: 1.25rem;\n margin-bottom: 1.25rem;\n border: 1px solid #eee;\n border-left-width: .25rem;\n @include border-radius();\n\n h4 {\n margin-top: 0;\n margin-bottom: .25rem;\n }\n\n p:last-child {\n margin-bottom: 0;\n }\n\n code {\n @include border-radius();\n }\n\n + .bd-callout {\n margin-top: -.25rem;\n }\n}\n\n// Variations\n@mixin bs-callout-variant($color) {\n border-left-color: $color;\n\n h4 { color: $color; }\n}\n\n.bd-callout-info { @include bs-callout-variant($bd-info); }\n.bd-callout-warning { @include bs-callout-variant($bd-warning); }\n.bd-callout-danger { @include bs-callout-variant($bd-danger); }\n","// Wall of Browser Bugs\n//\n// Better display for the responsive table on the Wall of Browser Bugs.\n\n.bd-browser-bugs {\n td p {\n margin-bottom: 0;\n }\n th:first-child {\n width: 18%;\n }\n}\n","//\n// Brand guidelines\n//\n\n// Logo series wrapper\n.bd-brand-logos {\n display: table;\n width: 100%;\n margin-bottom: 1rem;\n overflow: hidden;\n color: $bd-purple;\n background-color: #f9f9f9;\n @include border-radius();\n\n .inverse {\n color: $white;\n background-color: $bd-purple;\n }\n}\n\n// Individual items\n.bd-brand-item {\n padding: 4rem 0;\n text-align: center;\n\n + .bd-brand-item {\n border-top: 1px solid $white;\n }\n\n // Heading content within\n h1,\n h3 {\n margin-top: 0;\n margin-bottom: 0;\n }\n\n @include media-breakpoint-up(md) {\n display: table-cell;\n width: 1%;\n\n + .bd-brand-item {\n border-top: 0;\n border-left: 1px solid $white;\n }\n\n h1 {\n @include font-size(4rem);\n }\n }\n}\n\n\n//\n// Color swatches\n//\n\n.color-swatches {\n margin: 0 -5px;\n overflow: hidden; // clearfix\n\n // Docs colors\n .bd-purple {\n background-color: $bd-purple;\n }\n .bd-purple-light {\n background-color: $bd-purple-light;\n }\n .bd-purple-lighter {\n background-color: #e5e1ea;\n }\n .bd-gray {\n background-color: #f9f9f9;\n }\n}\n\n.color-swatch {\n float: left;\n width: 4rem;\n height: 4rem;\n margin-right: .25rem;\n margin-left: .25rem;\n @include border-radius();\n\n @include media-breakpoint-up(md) {\n width: 6rem;\n height: 6rem;\n }\n}\n","//\n// Docs color palette classes\n//\n\n@each $color, $value in $colors {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n\n@each $color, $value in $grays {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n","// clipboard.js\n//\n// JS-based `Copy` buttons for code snippets.\n\n.bd-clipboard {\n position: relative;\n display: none;\n float: right;\n\n + .highlight {\n margin-top: 0;\n }\n\n @include media-breakpoint-up(md) {\n display: block;\n }\n}\n\n.btn-clipboard {\n position: absolute;\n top: .65rem;\n right: .65rem;\n z-index: 10;\n display: block;\n padding: .25rem .5rem;\n @include font-size(65%);\n color: $primary;\n background-color: $white;\n border: 1px solid;\n @include border-radius();\n\n &:hover {\n color: $white;\n background-color: $primary;\n }\n}\n","//\n// Placeholder svg used in the docs.\n//\n\n// Remember to update `site/_layouts/examples.html` too if this changes!\n\n.bd-placeholder-img {\n @include font-size(1.125rem);\n text-anchor: middle;\n user-select: none;\n}\n\n.bd-placeholder-img-lg {\n @include font-size(3.5rem);\n}\n","// stylelint-disable declaration-block-single-line-max-declarations, selector-class-pattern\n\n.hll { background-color: #ffc; }\n.c { color: #727272; }\n.k { color: #069; }\n.o { color: #555; }\n.cm { color: #727272; }\n.cp { color: #008085; }\n.c1 { color: #727272; }\n.cs { color: #727272; }\n.gd { background-color: #fcc; border: 1px solid #c00; }\n.ge { font-style: italic; }\n.gr { color: #f00; }\n.gh { color: #030; }\n.gi { background-color: #cfc; border: 1px solid #0c0; }\n.go { color: #aaa; }\n.gp { color: #009; }\n.gu { color: #030; }\n.gt { color: #9c6; }\n.kc { color: #069; }\n.kd { color: #069; }\n.kn { color: #069; }\n.kp { color: #069; }\n.kr { color: #069; }\n.kt { color: #078; }\n.m { color: #c24f19; }\n.s { color: #d73038; }\n.na { color: #006ee0; }\n.nb { color: #366; }\n.nc { color: #168174; }\n.no { color: #360; }\n.nd { color: #6b62de; }\n.ni { color: #727272; }\n.ne { color: #c00; }\n.nf { color: #b715f4; }\n.nl { color: #6b62de; }\n.nn { color: #007ca5; }\n.nt { color: #2f6f9f; }\n.nv { color: #033; }\n.ow { color: #000; }\n.w { color: #bbb; }\n.mf { color: #c24f19; }\n.mh { color: #c24f19; }\n.mi { color: #c24f19; }\n.mo { color: #c24f19; }\n.sb { color: #c30; }\n.sc { color: #c30; }\n.sd { font-style: italic; color: #c30; }\n.s2 { color: #c30; }\n.se { color: #c30; }\n.sh { color: #c30; }\n.si { color: #a00; }\n.sx { color: #c30; }\n.sr { color: #337e7e; }\n.s1 { color: #c30; }\n.ss { color: #fc3; }\n.bp { color: #366; }\n.vc { color: #033; }\n.vg { color: #033; }\n.vi { color: #033; }\n.il { color: #c24f19; }\n\n.css .o,\n.css .o + .nt,\n.css .nt + .nt { color: #727272; }\n\n.language-bash::before,\n.language-sh::before {\n color: #009;\n content: \"$ \";\n user-select: none;\n}\n\n.language-powershell::before {\n color: #009;\n content: \"PM> \";\n user-select: none;\n}\n",".anchorjs-link {\n font-weight: 400;\n color: rgba($link-color, .5);\n @include transition(color .15s ease-in-out, opacity .15s ease-in-out);\n\n &:hover {\n color: $link-color;\n text-decoration: none;\n }\n}\n","// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n @if length($transition) == 0 {\n $transition: $transition-base;\n }\n\n @if length($transition) > 1 {\n @each $value in $transition {\n @if $value == null or $value == none {\n @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n }\n }\n }\n\n @if $enable-transitions {\n @if nth($transition, 1) != null {\n transition: $transition;\n }\n\n @if $enable-prefers-reduced-motion-media-query and nth($transition, 1) != null and nth($transition, 1) != none {\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Docsearch overrides\n//\n// `!important` indicates overridden properties.\n.algolia-autocomplete {\n display: block !important;\n flex: 1;\n\n // Menu container\n .ds-dropdown-menu {\n width: 100%;\n min-width: 0 !important;\n max-width: none !important;\n padding: .75rem 0 !important;\n background-color: $white;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, .1);\n box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175);\n\n @include media-breakpoint-up(md) {\n width: 175%;\n }\n\n // Caret\n &::before {\n display: none !important;\n }\n\n [class^=\"ds-dataset-\"] {\n padding: 0 !important;\n overflow: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n }\n\n .ds-suggestions {\n margin-top: 0 !important;\n }\n }\n\n .algolia-docsearch-suggestion {\n padding: 0 !important;\n overflow: visible !important;\n }\n\n .algolia-docsearch-suggestion--category-header {\n padding: .125rem 1rem !important;\n margin-top: 0 !important;\n @include font-size(.875rem, true);\n font-weight: 600 !important;\n color: $bd-purple-bright !important;\n border-bottom: 0 !important;\n }\n\n .algolia-docsearch-suggestion--wrapper {\n float: none !important;\n padding-top: 0 !important;\n }\n\n // Section header\n .algolia-docsearch-suggestion--subcategory-column {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n text-align: left !important;\n }\n\n .algolia-docsearch-suggestion--subcategory-inline {\n display: block !important;\n @include font-size(.875rem);\n color: $gray-700;\n\n &::after {\n padding: 0 .25rem;\n content: \"/\";\n }\n }\n\n .algolia-docsearch-suggestion--content {\n display: flex;\n flex-wrap: wrap;\n float: none !important;\n width: 100% !important;\n padding: .25rem 1rem !important;\n\n // Vertical divider between column header and content\n &::before {\n display: none !important;\n }\n }\n\n .ds-suggestion {\n &:not(:first-child) {\n .algolia-docsearch-suggestion--category-header {\n padding-top: .75rem !important;\n margin-top: .75rem !important;\n border-top: 1px solid rgba(0, 0, 0, .1);\n }\n }\n\n .algolia-docsearch-suggestion--subcategory-column {\n display: none !important;\n }\n }\n\n .algolia-docsearch-suggestion--title {\n display: block;\n margin-bottom: 0 !important;\n @include font-size(.875rem, true);\n font-weight: 400 !important;\n }\n\n .algolia-docsearch-suggestion--text {\n flex: 0 0 100%;\n max-width: 100%;\n padding: .2rem 0;\n @include font-size(.8125rem, true);\n font-weight: 400;\n line-height: 1.25 !important;\n color: $gray-600;\n }\n\n .algolia-docsearch-footer {\n float: none !important;\n width: auto !important;\n height: auto !important;\n padding: .75rem 1rem 0;\n @include font-size(.75rem, true);\n line-height: 1 !important;\n color: #767676 !important;\n border-top: 1px solid rgba(0, 0, 0, .1);\n }\n\n .algolia-docsearch-footer--logo {\n display: inline !important;\n overflow: visible !important;\n color: inherit !important;\n text-indent: 0 !important;\n background: none !important;\n }\n\n .algolia-docsearch-suggestion--highlight {\n color: #5f2dab;\n background-color: rgba(154, 132, 187, .12);\n }\n\n .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight {\n box-shadow: inset 0 -2px 0 0 rgba(95, 45, 171, .5) !important;\n }\n\n .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content {\n background-color: rgba(208, 189, 236, .15) !important;\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons.png deleted file mode 100644 index 9c418d5f3..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons@2x.png deleted file mode 100644 index 8d08df766..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-icons@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage.png deleted file mode 100644 index 54eba9993..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage@2x.png deleted file mode 100644 index ad165eb19..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes-collage@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes.png deleted file mode 100644 index d43dba2a7..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes@2x.png deleted file mode 100644 index 13c32337d..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/bootstrap-themes@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album.png deleted file mode 100644 index 694b3b2d2..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album@2x.png deleted file mode 100644 index 162269c46..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/album@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog.png deleted file mode 100644 index 6d6c8356b..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog@2x.png deleted file mode 100644 index f5480314b..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/blog@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel.png deleted file mode 100644 index abca5b3db..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel@2x.png deleted file mode 100644 index 39df35930..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/carousel@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout.png deleted file mode 100644 index 7af2e2efa..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout@2x.png deleted file mode 100644 index 3e3c5af4b..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/checkout@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover.png deleted file mode 100644 index 5458ff11d..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover@2x.png deleted file mode 100644 index 9d20fb2ed..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/cover@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard.png deleted file mode 100644 index 1ef0c3925..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard@2x.png deleted file mode 100644 index 52b23dff6..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/dashboard@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels.png deleted file mode 100644 index c836eadbb..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels@2x.png deleted file mode 100644 index 5d284bfe0..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/floating-labels@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid.png deleted file mode 100644 index b3b5b3565..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid@2x.png deleted file mode 100644 index e95c36365..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/grid@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron.png deleted file mode 100644 index afca61a7c..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron@2x.png deleted file mode 100644 index 4d83dffa6..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/jumbotron@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom.png deleted file mode 100644 index e9f0abc95..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom@2x.png deleted file mode 100644 index a62faa182..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-bottom@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed.png deleted file mode 100644 index c839602a7..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed@2x.png deleted file mode 100644 index 1ce8ca576..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-fixed@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static.png deleted file mode 100644 index faebe3451..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static@2x.png deleted file mode 100644 index 758aa61e8..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbar-static@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars.png deleted file mode 100644 index 874f6d752..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars@2x.png deleted file mode 100644 index ce11b8d2c..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/navbars@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas.png deleted file mode 100644 index b5073eba4..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas@2x.png deleted file mode 100644 index e5287dde8..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/offcanvas@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing.png deleted file mode 100644 index 3638c9ef3..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing@2x.png deleted file mode 100644 index 9ddac54ea..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/pricing@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product.png deleted file mode 100644 index a8d3dcb8d..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product@2x.png deleted file mode 100644 index 1dfe45482..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/product@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in.png deleted file mode 100644 index 53aed9724..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in@2x.png deleted file mode 100644 index 8b3431de9..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sign-in@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template.png deleted file mode 100644 index 0cbcaa1eb..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template@2x.png deleted file mode 100644 index 436c452de..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/starter-template@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar.png deleted file mode 100644 index f64d66638..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar@2x.png deleted file mode 100644 index 9478901f6..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer-navbar@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer.png deleted file mode 100644 index 203ed62f5..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer@2x.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer@2x.png deleted file mode 100644 index 5a008a0ac..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/examples/sticky-footer@2x.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-192x192.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-192x192.png deleted file mode 100644 index 547386f37..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-512x512.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-512x512.png deleted file mode 100644 index eae76488d..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/android-chrome-512x512.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/apple-touch-icon.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/apple-touch-icon.png deleted file mode 100644 index 447cec2c4..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/apple-touch-icon.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/browserconfig.xml b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/browserconfig.xml deleted file mode 100644 index 0d17d11d4..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/browserconfig.xml +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - - - - #563d7c - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-16x16.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-16x16.png deleted file mode 100644 index 5f7d11880..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-16x16.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-32x32.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-32x32.png deleted file mode 100644 index d752fd5d7..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/favicon-32x32.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/manifest.json b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/manifest.json deleted file mode 100644 index a92accba6..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/manifest.json +++ /dev/null @@ -1,22 +0,0 @@ ---- ---- -{ - "name": "Bootstrap", - "short_name": "Bootstrap", - "icons": [ - { - "src": "{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "start_url": "/?utm_source=a2hs", - "theme_color": "#563d7c", - "background_color": "#563d7c", - "display": "standalone" -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-144x144.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-144x144.png deleted file mode 100644 index 262a3c2e1..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-144x144.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-150x150.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-150x150.png deleted file mode 100644 index bb87faf74..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-150x150.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x150.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x150.png deleted file mode 100644 index 2fc36a726..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x150.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x310.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x310.png deleted file mode 100644 index 7f00d0c66..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-310x310.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-70x70.png b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-70x70.png deleted file mode 100644 index 4da2de9e3..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/mstile-70x70.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/safari-pinned-tab.svg b/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/safari-pinned-tab.svg deleted file mode 100644 index ddeeb53c9..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/img/favicons/safari-pinned-tab.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/docs.min.js b/vendor/twbs/bootstrap/site/docs/4.5/assets/js/docs.min.js deleted file mode 100644 index 2d5d79d3f..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/docs.min.js +++ /dev/null @@ -1,22 +0,0 @@ -!function(t,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(t.AnchorJS=e(),t.anchors=new t.AnchorJS)}(this,(function(){"use strict";return function(t){function e(t){t.icon=t.hasOwnProperty("icon")?t.icon:"",t.visible=t.hasOwnProperty("visible")?t.visible:"hover",t.placement=t.hasOwnProperty("placement")?t.placement:"right",t.ariaLabel=t.hasOwnProperty("ariaLabel")?t.ariaLabel:"Anchor",t.class=t.hasOwnProperty("class")?t.class:"",t.base=t.hasOwnProperty("base")?t.base:"",t.truncate=t.hasOwnProperty("truncate")?Math.floor(t.truncate):64,t.titleText=t.hasOwnProperty("titleText")?t.titleText:""}function n(t){var e;if("string"==typeof t||t instanceof String)e=[].slice.call(document.querySelectorAll(t));else{if(!(Array.isArray(t)||t instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(t)}return e}this.options=t||{},this.elements=[],e(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(t){var o,i,r,A,a,l,s,c,u,f,h,d,p=[];if(e(this.options),"touch"===(h=this.options.visible)&&(h=this.isTouchDevice()?"always":"hover"),0===(o=n(t=t||"h2, h3, h4, h5, h6")).length)return this;for(!function(){if(null!==document.head.querySelector("style.anchorjs"))return;var t,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(t=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,t);e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}(),i=document.querySelectorAll("[id]"),r=[].map.call(i,(function(t){return t.id})),a=0;a\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(t){var e=t.firstChild&&-1<(" "+t.firstChild.className+" ").indexOf(" anchorjs-link "),n=t.lastChild&&-1<(" "+t.lastChild.className+" ").indexOf(" anchorjs-link ");return e||n||!1}}})); -/*! - * clipboard.js v2.0.6 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,(function(){return n={},t.m=e=[function(t,e){t.exports=function(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),i=document.createRange();i.selectNodeContents(t),o.removeAllRanges(),o.addRange(i),e=o.toString()}return e}},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function i(){o.off(t,i),e.apply(n,arguments)}return i._=e,this.on(t,i,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,i=n.length;o - * Licensed under MIT (https://github.com/Johann-S/bs-custom-file-input/blob/master/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).bsCustomFileInput=e()}(this,(function(){"use strict";var t={CUSTOMFILE:'.custom-file input[type="file"]',CUSTOMFILELABEL:".custom-file-label",FORM:"form",INPUT:"input"},e=function(t){if(0 h2, .bd-content > h3, .bd-content > h4, .bd-content > h5");t(".bd-content").children("h2, h3, h4, h5").wrapInner('');bsCustomFileInput.init()}))})(jQuery);(function(){"use strict";function t(){var t=/MSIE ([\d.]+)/.exec(window.navigator.userAgent);if(t===null){return null}var e=parseInt(t[1],10);var n=Math.floor(e);return n}function e(){var t=new Function("/*@cc_on return @_jscript_version; @*/")();if(typeof t==="undefined"){return 11}if(t<9){return 8}return t}var n=window.navigator.userAgent;if(n.indexOf("Opera")>-1||n.indexOf("Presto")>-1){return}var o=t();if(o===null){return}var i=e();if(o!==i){window.alert("WARNING: You appear to be using IE"+i+" in IE"+o+" emulation mode.\nIE emulation modes can behave significantly differently from ACTUAL older versions of IE.\nPLEASE DON'T FILE BOOTSTRAP BUGS based on testing in IE emulation modes!")}})();(function(){"use strict";if(!window.docsearch){return}var t=document.getElementById("search-input");var e=t.getAttribute("data-docs-version");function n(){var t=window.location;var e=t.origin;if(!e){var n=t.port?":"+t.port:"";e=t.protocol+"//"+t.hostname+n}return e}window.docsearch({apiKey:"5990ad008512000bba2cf951ccf0332f",indexName:"bootstrap",inputSelector:"#search-input",algoliaOptions:{facetFilters:["version:"+e]},transformData:function(t){return t.map((function(t){var e=n();var o="https://getbootstrap.com/";t.url=e.lastIndexOf(o,0)===0?t.url:t.url.replace(o,"/");if(t.anchor==="content"){t.url=t.url.replace(/#content$/,"");t.anchor=null}return t}))},debug:false})})(); \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/application.js b/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/application.js deleted file mode 100644 index a3032173b..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/application.js +++ /dev/null @@ -1,112 +0,0 @@ -// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT -// IT'S ALL JUST JUNK FOR OUR DOCS! -// ++++++++++++++++++++++++++++++++++++++++++ - -/*! - * JavaScript for Bootstrap's docs (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. - * Licensed under the Creative Commons Attribution 3.0 Unported License. - * For details, see https://creativecommons.org/licenses/by/3.0/. - */ - -/* global ClipboardJS: false, anchors: false, bsCustomFileInput: false */ - -(function ($) { - 'use strict' - - $(function () { - // Tooltip and popover demos - $('.tooltip-demo').tooltip({ - selector: '[data-toggle="tooltip"]', - container: 'body' - }) - - $('[data-toggle="popover"]').popover() - - $('.toast') - .toast({ - autohide: false - }) - .toast('show') - - // Demos within modals - $('.tooltip-test').tooltip() - $('.popover-test').popover() - - // Indeterminate checkbox example - $('.bd-example-indeterminate [type="checkbox"]').prop('indeterminate', true) - - // Disable empty links in docs examples - $('.bd-content [href="#"]').click(function (e) { - e.preventDefault() - }) - - // Modal relatedTarget demo - $('#exampleModal').on('show.bs.modal', function (event) { - var $button = $(event.relatedTarget) // Button that triggered the modal - var recipient = $button.data('whatever') // Extract info from data-* attributes - // If necessary, you could initiate an AJAX request here (and then do the updating in a callback). - // Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead. - var $modal = $(this) - $modal.find('.modal-title').text('New message to ' + recipient) - $modal.find('.modal-body input').val(recipient) - }) - - // Activate animated progress bar - $('.bd-toggle-animated-progress').on('click', function () { - $(this).siblings('.progress').find('.progress-bar-striped').toggleClass('progress-bar-animated') - }) - - // Insert copy to clipboard button before .highlight - $('figure.highlight, div.highlight').each(function () { - var btnHtml = '
      ' - $(this).before(btnHtml) - $('.btn-clipboard') - .tooltip() - .on('mouseleave', function () { - // Explicitly hide tooltip, since after clicking it remains - // focused (as it's a button), so tooltip would otherwise - // remain visible until focus is moved away - $(this).tooltip('hide') - }) - }) - - var clipboard = new ClipboardJS('.btn-clipboard', { - target: function (trigger) { - return trigger.parentNode.nextElementSibling - } - }) - - clipboard.on('success', function (e) { - $(e.trigger) - .attr('title', 'Copied!') - .tooltip('_fixTitle') - .tooltip('show') - .attr('title', 'Copy to clipboard') - .tooltip('_fixTitle') - - e.clearSelection() - }) - - clipboard.on('error', function (e) { - var modifierKey = /mac/i.test(navigator.userAgent) ? '\u2318' : 'Ctrl-' - var fallbackMsg = 'Press ' + modifierKey + 'C to copy' - - $(e.trigger) - .attr('title', fallbackMsg) - .tooltip('_fixTitle') - .tooltip('show') - .attr('title', 'Copy to clipboard') - .tooltip('_fixTitle') - }) - - anchors.options = { - icon: '#' - } - anchors.add('.bd-content > h2, .bd-content > h3, .bd-content > h4, .bd-content > h5') - $('.bd-content').children('h2, h3, h4, h5').wrapInner('') - - bsCustomFileInput.init() - }) -})(jQuery) diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js b/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js deleted file mode 100644 index d11ec1c5a..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js +++ /dev/null @@ -1,52 +0,0 @@ -// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT -// IT'S ALL JUST JUNK FOR OUR DOCS! -// ++++++++++++++++++++++++++++++++++++++++++ - -// Intended to prevent false-positive bug reports about Bootstrap not working properly in old versions of IE due to folks testing using IE's unreliable emulation modes. -(function () { - 'use strict' - - function emulatedIEMajorVersion() { - var groups = /MSIE ([\d.]+)/.exec(window.navigator.userAgent) - if (groups === null) { - return null - } - - var ieVersionNum = parseInt(groups[1], 10) - var ieMajorVersion = Math.floor(ieVersionNum) - return ieMajorVersion - } - - function actualNonEmulatedIEMajorVersion() { - // Detects the actual version of IE in use, even if it's in an older-IE emulation mode. - // IE JavaScript conditional compilation docs: https://msdn.microsoft.com/library/121hztk3%28v=vs.94%29.aspx - // @cc_on docs: https://msdn.microsoft.com/library/8ka90k2e%28v=vs.94%29.aspx - var jscriptVersion = new Function('/*@cc_on return @_jscript_version; @*/')() // eslint-disable-line no-new-func - if (typeof jscriptVersion === 'undefined') { - return 11 // IE11+ not in emulation mode - } - - if (jscriptVersion < 9) { - return 8 // IE8 (or lower; haven't tested on IE<8) - } - - return jscriptVersion // IE9 or IE10 in any mode, or IE11 in non-IE11 mode - } - - var ua = window.navigator.userAgent - if (ua.indexOf('Opera') > -1 || ua.indexOf('Presto') > -1) { - return // Opera, which might pretend to be IE - } - - var emulated = emulatedIEMajorVersion() - if (emulated === null) { - return // Not IE - } - - var nonEmulated = actualNonEmulatedIEMajorVersion() - - if (emulated !== nonEmulated) { - // eslint-disable-next-line no-alert - window.alert('WARNING: You appear to be using IE' + nonEmulated + ' in IE' + emulated + ' emulation mode.\nIE emulation modes can behave significantly differently from ACTUAL older versions of IE.\nPLEASE DON\'T FILE BOOTSTRAP BUGS based on testing in IE emulation modes!') - } -})() diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/search.js b/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/search.js deleted file mode 100644 index bb97c5cf8..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/src/search.js +++ /dev/null @@ -1,59 +0,0 @@ -// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT -// IT'S ALL JUST JUNK FOR OUR DOCS! -// ++++++++++++++++++++++++++++++++++++++++++ - -(function () { - 'use strict' - - if (!window.docsearch) { - return - } - - var inputElement = document.getElementById('search-input') - var siteDocsVersion = inputElement.getAttribute('data-docs-version') - - function getOrigin() { - var location = window.location - var origin = location.origin - - if (!origin) { - var port = location.port ? ':' + location.port : '' - - origin = location.protocol + '//' + location.hostname + port - } - - return origin - } - - window.docsearch({ - apiKey: '5990ad008512000bba2cf951ccf0332f', - indexName: 'bootstrap', - inputSelector: '#search-input', - algoliaOptions: { - facetFilters: ['version:' + siteDocsVersion] - }, - transformData: function (hits) { - return hits.map(function (hit) { - var currentUrl = getOrigin() - var liveUrl = 'https://getbootstrap.com/' - - hit.url = currentUrl.lastIndexOf(liveUrl, 0) === 0 ? - // On production, return the result as is - hit.url : - // On development or Netlify, replace `hit.url` with a trailing slash, - // so that the result link is relative to the server root - hit.url.replace(liveUrl, '/') - - // Prevent jumping to first header - if (hit.anchor === 'content') { - hit.url = hit.url.replace(/#content$/, '') - hit.anchor = null - } - - return hit - }) - }, - // Set debug to `true` if you want to inspect the dropdown - debug: false - }) -})() diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/anchor.min.js b/vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/anchor.min.js deleted file mode 100644 index efa6c9856..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/anchor.min.js +++ /dev/null @@ -1,9 +0,0 @@ -// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat -// -// AnchorJS - v4.2.1 - 2019-11-11 -// https://www.bryanbraun.com/anchorjs/ -// Copyright (c) 2019 Bryan Braun; Licensed MIT -// -// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat -!function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function f(A){A.icon=A.hasOwnProperty("icon")?A.icon:"",A.visible=A.hasOwnProperty("visible")?A.visible:"hover",A.placement=A.hasOwnProperty("placement")?A.placement:"right",A.ariaLabel=A.hasOwnProperty("ariaLabel")?A.ariaLabel:"Anchor",A.class=A.hasOwnProperty("class")?A.class:"",A.base=A.hasOwnProperty("base")?A.base:"",A.truncate=A.hasOwnProperty("truncate")?Math.floor(A.truncate):64,A.titleText=A.hasOwnProperty("titleText")?A.titleText:""}function p(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],f(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var e,t,i,n,o,s,a,r,c,h,l,u,d=[];if(f(this.options),"touch"===(l=this.options.visible)&&(l=this.isTouchDevice()?"always":"hover"),0===(e=p(A=A||"h2, h3, h4, h5, h6")).length)return this;for(!function(){if(null!==document.head.querySelector("style.anchorjs"))return;var A,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,A);e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}(),t=document.querySelectorAll("[id]"),i=[].map.call(t,function(A){return A.id}),o=0;o\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),t=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||t||!1}}}); -// @license-end \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/bs-custom-file-input.min.js b/vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/bs-custom-file-input.min.js deleted file mode 100644 index 0815f3768..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/js/vendor/bs-custom-file-input.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * bsCustomFileInput v1.3.4 (https://github.com/Johann-S/bs-custom-file-input) - * Copyright 2018 - 2020 Johann-S - * Licensed under MIT (https://github.com/Johann-S/bs-custom-file-input/blob/master/LICENSE) - */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).bsCustomFileInput=t()}(this,function(){"use strict";var s={CUSTOMFILE:'.custom-file input[type="file"]',CUSTOMFILELABEL:".custom-file-label",FORM:"form",INPUT:"input"},l=function(e){if(0+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(d.childNodes),d.childNodes),t[d.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!k[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&(U.test(t)||_.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&p.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=A)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+be(l[o]);c=l.join(",")}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){k(t,!0)}finally{s===A&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[A]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:d;return r!=T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),d!=T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.scope=ce(function(e){return a.appendChild(e).appendChild(T.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=A,!T.getElementsByName||!T.getElementsByName(A).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+A+"-]").length||v.push("~="),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+R+"*name"+R+"*="+R+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+A+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==d&&y(d,e)?-1:t==T||t.ownerDocument==d&&y(d,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==T?-1:t==T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]==d?-1:s[r]==d?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),p.matchesSelector&&E&&!k[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){k(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return b(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||L,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:j.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:w,!0)),k.test(r[1])&&E.isPlainObject(t))for(r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=w.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,L=E(w);var q=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i;le=w.createDocumentFragment().appendChild(w.createElement("div")),(ce=w.createElement("input")).setAttribute("type","radio"),ce.setAttribute("checked","checked"),ce.setAttribute("name","t"),le.appendChild(ce),m.checkClone=le.cloneNode(!0).cloneNode(!0).lastChild.checked,le.innerHTML="",m.noCloneChecked=!!le.cloneNode(!0).lastChild.defaultValue,le.innerHTML="",m.option=!!le.lastChild;var he={thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var ye=/<|&#?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p\s*$/g;function Le(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function je(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n
      ",2===ft.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=w.implementation.createHTMLDocument("")).createElement("base")).href=w.location.href,t.head.appendChild(r)):t=w),o=!n&&[],(i=k.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),b(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=Fe(m.pixelPosition,function(e,t){if(t)return t=We(e,n),Ie.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0 &, - &:hover, - &:active { - color: $bd-purple-bright; - background-color: $white; - border-color: $bd-purple-bright; - } - - &:focus { - box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25); - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_callouts.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_callouts.scss deleted file mode 100644 index 6b9735949..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_callouts.scss +++ /dev/null @@ -1,40 +0,0 @@ -// -// Callouts -// - -.bd-callout { - padding: 1.25rem; - margin-top: 1.25rem; - margin-bottom: 1.25rem; - border: 1px solid #eee; - border-left-width: .25rem; - @include border-radius(); - - h4 { - margin-top: 0; - margin-bottom: .25rem; - } - - p:last-child { - margin-bottom: 0; - } - - code { - @include border-radius(); - } - - + .bd-callout { - margin-top: -.25rem; - } -} - -// Variations -@mixin bs-callout-variant($color) { - border-left-color: $color; - - h4 { color: $color; } -} - -.bd-callout-info { @include bs-callout-variant($bd-info); } -.bd-callout-warning { @include bs-callout-variant($bd-warning); } -.bd-callout-danger { @include bs-callout-variant($bd-danger); } diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_clipboard-js.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_clipboard-js.scss deleted file mode 100644 index b8c6a9e8f..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_clipboard-js.scss +++ /dev/null @@ -1,36 +0,0 @@ -// clipboard.js -// -// JS-based `Copy` buttons for code snippets. - -.bd-clipboard { - position: relative; - display: none; - float: right; - - + .highlight { - margin-top: 0; - } - - @include media-breakpoint-up(md) { - display: block; - } -} - -.btn-clipboard { - position: absolute; - top: .65rem; - right: .65rem; - z-index: 10; - display: block; - padding: .25rem .5rem; - @include font-size(65%); - color: $primary; - background-color: $white; - border: 1px solid; - @include border-radius(); - - &:hover { - color: $white; - background-color: $primary; - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_colors.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_colors.scss deleted file mode 100644 index 10ad8efdb..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_colors.scss +++ /dev/null @@ -1,17 +0,0 @@ -// -// Docs color palette classes -// - -@each $color, $value in $colors { - .swatch-#{$color} { - color: color-yiq($value); - background-color: #{$value}; - } -} - -@each $color, $value in $grays { - .swatch-#{$color} { - color: color-yiq($value); - background-color: #{$value}; - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_component-examples.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_component-examples.scss deleted file mode 100644 index a29671897..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_component-examples.scss +++ /dev/null @@ -1,378 +0,0 @@ -// stylelint-disable no-duplicate-selectors, selector-no-qualifying-type - -// -// Grid examples -// - -.bd-example-row { - .row { - > .col, - > [class^="col-"] { - padding-top: .75rem; - padding-bottom: .75rem; - background-color: rgba(86, 61, 124, .15); - border: 1px solid rgba(86, 61, 124, .2); - } - } - - .row + .row { - margin-top: 1rem; - } - - .flex-items-top, - .flex-items-middle, - .flex-items-bottom { - min-height: 6rem; - background-color: rgba(255, 0, 0, .1); - } -} - -.bd-example-row-flex-cols .row { - min-height: 10rem; - background-color: rgba(255, 0, 0, .1); -} - -.bd-highlight { - background-color: rgba($bd-purple, .15); - border: 1px solid rgba($bd-purple, .15); -} - -.bd-example-responsive-containers { - [class^="container"] { - padding-top: .75rem; - padding-bottom: .75rem; - background-color: rgba(86, 61, 124, .15); - border: 1px solid rgba(86, 61, 124, .2); - } -} - -// Grid mixins -.example-container { - width: 800px; - @include make-container(); -} - -.example-row { - @include make-row(); -} - -.example-content-main { - @include make-col-ready(); - - @include media-breakpoint-up(sm) { - @include make-col(6); - } - - @include media-breakpoint-up(lg) { - @include make-col(8); - } -} - -.example-content-secondary { - @include make-col-ready(); - - @include media-breakpoint-up(sm) { - @include make-col(6); - } - - @include media-breakpoint-up(lg) { - @include make-col(4); - } -} - - -// -// Docs examples -// - -.bd-example { - position: relative; - padding: 1rem; - margin: 1rem (-$grid-gutter-width / 2) 0; - border: solid $gray-100; - border-width: .2rem 0 0; - @include clearfix(); - - @include media-breakpoint-up(sm) { - padding: 1.5rem; - margin-right: 0; - margin-left: 0; - border-width: .2rem; - } - - + .highlight, - + .clipboard + .highlight { - margin-top: 0; - } - - + p { - margin-top: 2rem; - } - - .custom-file-input:lang(es) ~ .custom-file-label::after { - content: "Elegir"; - } - - > .form-control { - + .form-control { - margin-top: .5rem; - } - } - - > .nav + .nav, - > .alert + .alert, - > .navbar + .navbar, - > .progress + .progress, - > .progress + .btn { - margin-top: 1rem; - } - - > .dropdown-menu:first-child { - position: static; - display: block; - } - - > .form-group:last-child { - margin-bottom: 0; - } - - > .close { - float: none; - } -} - -// Typography -.bd-example-type { - .table { - td { - padding: 1rem 0; - border-color: #eee; - } - tr:first-child td { - border-top: 0; - } - } - - h1, - h2, - h3, - h4, - h5, - h6 { - margin-top: 0; - margin-bottom: 0; - } -} - -// Contextual background colors -.bd-example-bg-classes p { - padding: 1rem; -} - -// Images -.bd-example { - > svg + svg, - > img + img { - margin-left: .5rem; - } -} - -// Buttons -.bd-example { - > .btn, - > .btn-group { - margin-top: .25rem; - margin-bottom: .25rem; - } - > .btn-toolbar + .btn-toolbar { - margin-top: .5rem; - } -} - -// Forms -.bd-example-control-sizing select, -.bd-example-control-sizing input[type="text"] + input[type="text"] { - margin-top: .5rem; -} -.bd-example-form .input-group { - margin-bottom: .5rem; -} -.bd-example > textarea.form-control { - resize: vertical; -} - -// List groups -.bd-example > .list-group { - max-width: 400px; -} -.bd-example > [class*="list-group-horizontal"] { - max-width: 100%; -} - -// Navbars -.bd-example { - .fixed-top, - .sticky-top { - position: static; - margin: -1rem -1rem 1rem; - } - .fixed-bottom { - position: static; - margin: 1rem -1rem -1rem; - } - - @include media-breakpoint-up(sm) { - .fixed-top, - .sticky-top { - margin: -1.5rem -1.5rem 1rem; - } - .fixed-bottom { - margin: 1rem -1.5rem -1.5rem; - } - } -} - -// Pagination -.bd-example .pagination { - margin-top: .5rem; - margin-bottom: .5rem; -} - -// Example modals -.modal { - z-index: 1072; - - .tooltip, - .popover { - z-index: 1073; - } -} - -.modal-backdrop { - z-index: 1071; -} - -.bd-example-modal { - background-color: #fafafa; - - .modal { - position: relative; - top: auto; - right: auto; - bottom: auto; - left: auto; - z-index: 1; - display: block; - } - - .modal-dialog { - left: auto; - margin-right: auto; - margin-left: auto; - } -} - -// Example tabbable tabs -.bd-example-tabs .nav-tabs { - margin-bottom: 1rem; -} - -// Popovers -.bd-example-popover-static { - padding-bottom: 1.5rem; - background-color: #f9f9f9; - - .popover { - position: relative; - display: block; - float: left; - width: 260px; - margin: 1.25rem; - } -} - -// Tooltips -.tooltip-demo a { - white-space: nowrap; -} - -.bd-example-tooltip-static .tooltip { - position: relative; - display: inline-block; - margin: 10px 20px; - opacity: 1; -} - -// Scrollspy demo on fixed height div -.scrollspy-example { - position: relative; - height: 200px; - margin-top: .5rem; - overflow: auto; -} - -.scrollspy-example-2 { - position: relative; - height: 350px; - overflow: auto; -} - -.bd-example-border-utils { - [class^="border"] { - display: inline-block; - width: 5rem; - height: 5rem; - margin: .25rem; - background-color: #f5f5f5; - } -} - -.bd-example-border-utils-0 { - [class^="border"] { - border: 1px solid $border-color; - } -} - -.bd-example-forms-input-group-workaround .fix-rounded-right { - @include border-right-radius(.2rem !important); -} - -// -// Code snippets -// - -.highlight { - padding: 1rem; - margin-top: 1rem; - margin-bottom: 1rem; - background-color: $gray-100; - -ms-overflow-style: -ms-autohiding-scrollbar; - - @include media-breakpoint-up(sm) { - padding: 1.5rem; - } -} - -.bd-content .highlight { - margin-right: (-$grid-gutter-width / 2); - margin-left: (-$grid-gutter-width / 2); - - @include media-breakpoint-up(sm) { - margin-right: 0; - margin-left: 0; - } -} - -.highlight { - pre { - padding: 0; - margin-top: .65rem; - margin-bottom: .65rem; - background-color: transparent; - border: 0; - } - pre code { - @include font-size(inherit); - color: $gray-900; // Effectively the base text color - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_content.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_content.scss deleted file mode 100644 index 030a1a256..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_content.scss +++ /dev/null @@ -1,127 +0,0 @@ -// stylelint-disable no-duplicate-selectors, selector-max-combinators, selector-max-compound-selectors, selector-max-type, selector-no-qualifying-type - -// -// Automatically style Markdown-based tables like a Bootstrap `.table`. -// - -.bd-content { - order: 1; - - // Hack the sticky header - > h2[id], - > h3[id], - > h4[id] { - pointer-events: none; - - &::before { - display: block; - height: 6rem; - margin-top: -6rem; - content: ""; - } - } - - > table { - width: 100%; - max-width: 100%; - margin-bottom: 1rem; - - @include media-breakpoint-down(md) { - display: block; - overflow-x: auto; - - &.table-bordered { - border: 0; - } - } - - // Cells - > thead, - > tbody, - > tfoot { - > tr { - > th, - > td { - padding: $table-cell-padding; - vertical-align: top; - border: 1px solid $table-border-color; - - > p:last-child { - margin-bottom: 0; - } - } - } - } - - // Prevent breaking of code (e.g., Grunt tasks list) - td:first-child > code { - white-space: nowrap; - } - } -} - -.bd-content-title { - display: block; - pointer-events: auto; -} - -// -// Docs sections -// - -.bd-content { - > h2 { - @include font-size($h2-font-size); - } - - > h3 { - @include font-size($h3-font-size); - } - - > h4 { - @include font-size($h4-font-size); - } - - > h2:not(:first-child) { - margin-top: 3rem; - } - - > h3 { - margin-top: 1.5rem; - } - - > ul li, - > ol li { - margin-bottom: .25rem; - } - - @include media-breakpoint-up(lg) { - > ul, - > ol, - > p { - max-width: 80%; - } - } -} - -.bd-title { - margin-top: 1rem; - margin-bottom: .5rem; - @include font-size(3rem); -} - -.bd-lead { - @include font-size(1.5rem); - font-weight: 300; - - @include media-breakpoint-up(lg) { - max-width: 80%; - } -} - -.bd-text-purple { color: $bd-purple; } -.bd-text-purple-bright { color: $bd-purple-bright; } - -.bd-bg-purple-bright { - background-color: $bd-purple-bright; -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_footer.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_footer.scss deleted file mode 100644 index 29d31df3a..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_footer.scss +++ /dev/null @@ -1,40 +0,0 @@ -// -// Footer -// - -.bd-footer { - @include font-size(.875rem); - text-align: center; - background-color: #f7f7f7; - - a { - font-weight: 600; - color: $gray-700; - - &:hover, - &:focus { - color: $link-color; - } - } - - p { - margin-bottom: 0; - } - - @include media-breakpoint-up(sm) { - text-align: left; - } -} - -.bd-footer-links { - padding-left: 0; - margin-bottom: 1rem; - - li { - display: inline-block; - - + li { - margin-left: 1rem; - } - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_masthead.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_masthead.scss deleted file mode 100644 index 62047fbbb..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_masthead.scss +++ /dev/null @@ -1,80 +0,0 @@ -// stylelint-disable declaration-no-important - -.bd-masthead { - position: relative; - padding: 3rem ($grid-gutter-width / 2); - background: linear-gradient(to right bottom, lighten($bd-purple-light, 16%) 50%, #fff 50%); - - h1 { - @include font-size(4rem); - line-height: 1; - } - - .lead { - @include font-size(1.5rem); - font-weight: 400; - color: $gray-700; - } - - .btn { - padding: .8rem 2rem; - font-weight: 600; - @include font-size(1.25rem); - } - - .carbonad { - margin-top: 0 !important; - margin-bottom: -3rem !important; - } - - @include media-breakpoint-up(sm) { - padding-top: 5rem; - padding-bottom: 5rem; - - .carbonad { - margin-bottom: 0 !important; - } - } - - @include media-breakpoint-up(md) { - .carbonad { - margin-top: 3rem !important; - } - } -} - -.masthead-followup { - .bd-clipboard { display: none; } - - h2 { - @include font-size(2.5rem); - } - - .highlight { - @include border-radius(.5rem); - - pre::-webkit-scrollbar { - display: none; - } - - pre code { - display: inline-block; - white-space: pre; - - &::before { - display: none; - } - } - } -} - -.masthead-followup-icon { - padding: .75rem; - background-image: linear-gradient(to bottom right, rgba(255, 255, 255, .2), rgba(255, 255, 255, .01)); - @include border-radius(.75rem); - box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .1); -} - -.masthead-followup-svg { - filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .125)); -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_nav.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_nav.scss deleted file mode 100644 index d8d24b723..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_nav.scss +++ /dev/null @@ -1,71 +0,0 @@ -// -// Main navbar -// - -.bd-navbar { - min-height: 4rem; - background-color: $bd-purple-bright; - box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05), inset 0 -1px 0 rgba(0, 0, 0, .1); - - @include media-breakpoint-down(md) { - padding-right: .5rem; - padding-left: .5rem; - - .navbar-nav-scroll { - max-width: 100%; - height: 2.5rem; - margin-top: .25rem; - overflow: hidden; - - .navbar-nav { - padding-bottom: 2rem; - overflow-x: auto; - white-space: nowrap; - -webkit-overflow-scrolling: touch; - } - } - } - - @include media-breakpoint-up(md) { - @supports (position: sticky) { - position: sticky; - top: 0; - z-index: 1071; // over everything in bootstrap - } - } - - .navbar-nav { - .nav-link { - padding-right: .5rem; - padding-left: .5rem; - color: rgba($white, .85); - - &.active, - &:hover { - color: $white; - background-color: transparent; - } - - &.active { - font-weight: 600; - } - } - } - - .navbar-nav-svg { - display: inline-block; - width: 1rem; - height: 1rem; - vertical-align: text-top; - } - - .dropdown-menu { - @include font-size(.875rem); - } - - .dropdown-item.active { - font-weight: 600; - color: $gray-900; - background: escape-svg($dropdown-active-icon) no-repeat .4rem .6rem/.75rem .75rem; - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_placeholder-img.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_placeholder-img.scss deleted file mode 100644 index 90a29544e..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_placeholder-img.scss +++ /dev/null @@ -1,15 +0,0 @@ -// -// Placeholder svg used in the docs. -// - -// Remember to update `site/_layouts/examples.html` too if this changes! - -.bd-placeholder-img { - @include font-size(1.125rem); - text-anchor: middle; - user-select: none; -} - -.bd-placeholder-img-lg { - @include font-size(3.5rem); -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_sidebar.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_sidebar.scss deleted file mode 100644 index 8f6f1284e..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_sidebar.scss +++ /dev/null @@ -1,161 +0,0 @@ -// stylelint-disable declaration-no-important - -// -// Right side table of contents -// - -.bd-toc { - @supports (position: sticky) { - position: sticky; - top: 4rem; - height: subtract(100vh, 4rem); - overflow-y: auto; - } - order: 2; - padding-top: 1.5rem; - padding-bottom: 1.5rem; - @include font-size(.875rem); -} - -.section-nav { - padding-left: 0; - border-left: 1px solid #eee; - - ul { - padding-left: 1rem; - } -} - -.toc-entry { - display: block; - - a { - display: block; - padding: .125rem 1.5rem; - color: #77757a; - - &:hover { - color: $blue; - text-decoration: none; - } - } -} - -// -// Left side navigation -// - -.bd-sidebar { - order: 0; - // background-color: #f5f2f9; - border-bottom: 1px solid rgba(0, 0, 0, .1); - - @include media-breakpoint-up(md) { - @supports (position: sticky) { - position: sticky; - top: 4rem; - z-index: 1000; - height: subtract(100vh, 4rem); - } - border-right: 1px solid rgba(0, 0, 0, .1); - } - - @include media-breakpoint-up(xl) { - flex: 0 1 320px; - } -} - -.bd-links { - padding-top: 1rem; - padding-bottom: 1rem; - margin-right: -15px; - margin-left: -15px; - - @include media-breakpoint-up(md) { - @supports (position: sticky) { - max-height: subtract(100vh, 9rem); - overflow-y: auto; - } - } - - // Override collapse behaviors - @include media-breakpoint-up(md) { - display: block !important; - } -} - -.bd-search { - position: relative; // To contain the Algolia search - padding: 1rem 15px; - margin-right: -15px; - margin-left: -15px; - border-bottom: 1px solid rgba(0, 0, 0, .05); - - .form-control:focus { - border-color: $bd-purple-bright; - box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25); - } -} - -.bd-search-docs-toggle { - color: $gray-900; -} - -.bd-sidenav { - display: none; -} - -.bd-toc-link { - display: block; - padding: .25rem 1.5rem; - font-weight: 600; - color: rgba(0, 0, 0, .65); - - &:hover { - color: rgba(0, 0, 0, .85); - text-decoration: none; - } -} - -.bd-toc-item { - &.active { - margin-bottom: 1rem; - - &:not(:first-child) { - margin-top: 1rem; - } - - > .bd-toc-link { - color: rgba(0, 0, 0, .85); - - &:hover { - background-color: transparent; - } - } - - > .bd-sidenav { - display: block; - } - } -} - -// All levels of nav -.bd-sidebar .nav > li > a { - display: block; - padding: .25rem 1.5rem; - @include font-size(90%); - color: rgba(0, 0, 0, .65); -} - -.bd-sidebar .nav > li > a:hover { - color: rgba(0, 0, 0, .85); - text-decoration: none; - background-color: transparent; -} - -.bd-sidebar .nav > .active > a, -.bd-sidebar .nav > .active:hover > a { - font-weight: 600; - color: rgba(0, 0, 0, .85); - background-color: transparent; -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_skippy.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_skippy.scss deleted file mode 100644 index 894db70db..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_skippy.scss +++ /dev/null @@ -1,20 +0,0 @@ -// stylelint-disable declaration-no-important - -.skippy { - background-color: $bd-purple; - - a { - color: $white; - } - - &:focus-within a { - position: static !important; - width: auto !important; - height: auto !important; - padding: $spacer / 2 !important; - margin: $spacer / 4 !important; - overflow: visible !important; - clip: auto !important; - white-space: normal !important; - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_syntax.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_syntax.scss deleted file mode 100644 index 363ff07e7..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_syntax.scss +++ /dev/null @@ -1,78 +0,0 @@ -// stylelint-disable declaration-block-single-line-max-declarations, selector-class-pattern - -.hll { background-color: #ffc; } -.c { color: #727272; } -.k { color: #069; } -.o { color: #555; } -.cm { color: #727272; } -.cp { color: #008085; } -.c1 { color: #727272; } -.cs { color: #727272; } -.gd { background-color: #fcc; border: 1px solid #c00; } -.ge { font-style: italic; } -.gr { color: #f00; } -.gh { color: #030; } -.gi { background-color: #cfc; border: 1px solid #0c0; } -.go { color: #aaa; } -.gp { color: #009; } -.gu { color: #030; } -.gt { color: #9c6; } -.kc { color: #069; } -.kd { color: #069; } -.kn { color: #069; } -.kp { color: #069; } -.kr { color: #069; } -.kt { color: #078; } -.m { color: #c24f19; } -.s { color: #d73038; } -.na { color: #006ee0; } -.nb { color: #366; } -.nc { color: #168174; } -.no { color: #360; } -.nd { color: #6b62de; } -.ni { color: #727272; } -.ne { color: #c00; } -.nf { color: #b715f4; } -.nl { color: #6b62de; } -.nn { color: #007ca5; } -.nt { color: #2f6f9f; } -.nv { color: #033; } -.ow { color: #000; } -.w { color: #bbb; } -.mf { color: #c24f19; } -.mh { color: #c24f19; } -.mi { color: #c24f19; } -.mo { color: #c24f19; } -.sb { color: #c30; } -.sc { color: #c30; } -.sd { font-style: italic; color: #c30; } -.s2 { color: #c30; } -.se { color: #c30; } -.sh { color: #c30; } -.si { color: #a00; } -.sx { color: #c30; } -.sr { color: #337e7e; } -.s1 { color: #c30; } -.ss { color: #fc3; } -.bp { color: #366; } -.vc { color: #033; } -.vg { color: #033; } -.vi { color: #033; } -.il { color: #c24f19; } - -.css .o, -.css .o + .nt, -.css .nt + .nt { color: #727272; } - -.language-bash::before, -.language-sh::before { - color: #009; - content: "$ "; - user-select: none; -} - -.language-powershell::before { - color: #009; - content: "PM> "; - user-select: none; -} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_variables.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_variables.scss deleted file mode 100644 index b5a5381af..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/_variables.scss +++ /dev/null @@ -1,15 +0,0 @@ -// Local docs variables -$bd-purple: #563d7c; -$bd-purple-bright: lighten(saturate($bd-purple, 5%), 15%); -$bd-purple-light: lighten(saturate($bd-purple, 5%), 45%); -$bd-dark: #2a2730; -$bd-download: #ffe484; -$bd-info: #5bc0de; -$bd-warning: #f0ad4e; -$bd-danger: #d9534f; -$dropdown-active-icon: url("data:image/svg+xml,"); - -// Enable responsive font sizes for font sizes defined in the docs -// The weird if test is made as a workaround to prevent a false fusv error. -// -$enable-responsive-font-sizes: if($enable-responsive-font-sizes, true, true); diff --git a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/docs.scss b/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/docs.scss deleted file mode 100644 index 8dd3f5b56..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/assets/scss/docs.scss +++ /dev/null @@ -1,52 +0,0 @@ -/*! - * Bootstrap Docs (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. - * Licensed under the Creative Commons Attribution 3.0 Unported License. - * For details, see https://creativecommons.org/licenses/by/3.0/. - */ - -// Dev notes -// -// Background information on nomenclature and architecture decisions here. -// -// - Bootstrap functions, variables, and mixins are included for easy reuse. -// Doing so gives us access to the same core utilities provided by Bootstrap. -// For example, consistent media queries through those mixins. -// -// - Bootstrap's **docs variables** are prefixed with `$bd-`. -// These custom colors avoid collision with the components Bootstrap provides. -// -// - Classes are prefixed with `.bd-`. -// These classes indicate custom-built or modified components for the design -// and layout of the Bootstrap docs. They are not included in our builds. -// -// Happy Bootstrapping! - -// Load Bootstrap variables and mixins -@import "../../../../../scss/functions"; -@import "../../../../../scss/variables"; -@import "../../../../../scss/mixins"; - -// Load docs components -@import "variables"; -@import "nav"; -@import "masthead"; -@import "ads"; -@import "content"; -@import "skippy"; -@import "sidebar"; -@import "footer"; -@import "component-examples"; -@import "buttons"; -@import "callouts"; -@import "browser-bugs"; -@import "brand"; -@import "colors"; -@import "clipboard-js"; -@import "placeholder-img"; - -// Load docs dependencies -@import "syntax"; -@import "anchor"; -@import "algolia"; diff --git a/vendor/twbs/bootstrap/site/docs/4.5/browser-bugs.md b/vendor/twbs/bootstrap/site/docs/4.5/browser-bugs.md deleted file mode 100644 index 15c99a67d..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/browser-bugs.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -layout: docs -title: Wall of browser bugs -group: browser-bugs -redirect_from: "/browser-bugs/" ---- - -{% capture callout %} -##### Outdated content - -This page is outdated and is no longer applicable to the latest versions of Bootstrap. It's here purely for historical purposes now and will be removed in our next major release. -{% endcapture %} -{% include callout.html content=callout type="danger" %} - -Bootstrap currently works around several outstanding browser bugs in major browsers to deliver the best cross-browser experience possible. Some bugs, like those listed below, cannot be solved by us. - -We publicly list browser bugs that are impacting us here, in the hopes of expediting the process of fixing them. For information on Bootstrap's browser compatibility, [see our browser compatibility docs]({{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/browsers-devices/#supported-browsers). - -See also: - -* [Chromium issue 536263: [meta] Issues affecting Bootstrap](https://bugs.chromium.org/p/chromium/issues/detail?id=536263) -* [Mozilla bug 1230801: Fix the issues that affect Bootstrap](https://bugzilla.mozilla.org/show_bug.cgi?id=1230801) -* [WebKit bug 159753: [meta] Issues affecting Bootstrap](https://bugs.webkit.org/show_bug.cgi?id=159753) -* [jQuery's browser bug workarounds](https://docs.google.com/document/d/1LPaPA30bLUB_publLIMF0RlhdnPx_ePXm7oW02iiT6o) - - - - - - - - - - - - {% for bug in site.data.browser-bugs %} - - - - - - - {% endfor %} - -
      Browser(s)Summary of bugUpstream bug(s)Bootstrap issue(s)
      {{ bug.browser }}{{ bug.summary | markdownify }}{% include bugify.html content=bug.upstream_bug %}{% include bugify.html content=bug.origin %}
      - -# Most wanted features - -There are several features specified in Web standards which would allow us to make Bootstrap more robust, elegant, or performant, but aren't yet implemented in certain browsers, thus preventing us from taking advantage of them. - -We publicly list these "most wanted" feature requests here, in the hopes of expediting the process of getting them implemented. - - - - - - - - - - - - {% for feat in site.data.browser-features %} - - - - - - - {% endfor %} - -
      Browser(s)Summary of featureUpstream issue(s)Bootstrap issue(s)
      {{ feat.browser }}{{ feat.summary | markdownify }}{% include bugify.html content=feat.upstream_bug %}{% include bugify.html content=feat.origin %}
      diff --git a/vendor/twbs/bootstrap/site/docs/4.5/components/alerts.md b/vendor/twbs/bootstrap/site/docs/4.5/components/alerts.md deleted file mode 100644 index 5df7faa29..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/components/alerts.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -layout: docs -title: Alerts -description: Provide contextual feedback messages for typical user actions with the handful of available and flexible alert messages. -group: components -redirect_from: - - "/components/" - - "/docs/4.5/components/" -toc: true ---- - -## Examples - -Alerts are available for any length of text, as well as an optional dismiss button. For proper styling, use one of the eight **required** contextual classes (e.g., `.alert-success`). For inline dismissal, use the [alerts jQuery plugin](#dismissing). - -{% capture example %} -{% for color in site.data.theme-colors %} -{% endfor %} -{% endcapture %} -{% include example.html content=example %} - -{% include callout-warning-color-assistive-technologies.md %} - -### Link color - -Use the `.alert-link` utility class to quickly provide matching colored links within any alert. - -{% capture example %} -{% for color in site.data.theme-colors %} -{% endfor %} -{% endcapture %} -{% include example.html content=example %} - -### Additional content - -Alerts can also contain additional HTML elements like headings, paragraphs and dividers. - -{% capture example %} - -{% endcapture %} -{% include example.html content=example %} - - -### Dismissing - -Using the alert JavaScript plugin, it's possible to dismiss any alert inline. Here's how: - -- Be sure you've loaded the alert plugin, or the compiled Bootstrap JavaScript. -- If you're building our JavaScript from source, it [requires `util.js`]({{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/javascript/#util). The compiled version includes this. -- Add a dismiss button and the `.alert-dismissible` class, which adds extra padding to the right of the alert and positions the `.close` button. -- On the dismiss button, add the `data-dismiss="alert"` attribute, which triggers the JavaScript functionality. Be sure to use the ` -
      -{% endcapture %} -{% include example.html content=example %} - -## JavaScript behavior - -### Triggers - -Enable dismissal of an alert via JavaScript: - -{% highlight js %} -$('.alert').alert() -{% endhighlight %} - -Or with `data` attributes on a button **within the alert**, as demonstrated above: - -{% highlight html %} - -{% endhighlight %} - -Note that closing an alert will remove it from the DOM. - -### Methods - -| Method | Description | -| --- | --- | -| `$().alert()` | Makes an alert listen for click events on descendant elements which have the `data-dismiss="alert"` attribute. (Not necessary when using the data-api's auto-initialization.) | -| `$().alert('close')` | Closes an alert by removing it from the DOM. If the `.fade` and `.show` classes are present on the element, the alert will fade out before it is removed. | -| `$().alert('dispose')` | Destroys an element's alert. | - -{% highlight js %}$('.alert').alert('close'){% endhighlight %} - -### Events - -Bootstrap's alert plugin exposes a few events for hooking into alert functionality. - -| Event | Description | -| --- | --- | -| `close.bs.alert` | This event fires immediately when the close instance method is called. | -| `closed.bs.alert` | This event is fired when the alert has been closed (will wait for CSS transitions to complete). | - -{% highlight js %} -$('#myAlert').on('closed.bs.alert', function () { - // do something... -}) -{% endhighlight %} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/components/badge.md b/vendor/twbs/bootstrap/site/docs/4.5/components/badge.md deleted file mode 100644 index 8c1760045..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/components/badge.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -layout: docs -title: Badges -description: Documentation and examples for badges, our small count and labeling component. -group: components -toc: true ---- - -## Example - -Badges scale to match the size of the immediate parent element by using relative font sizing and `em` units. - -{% capture example %} -

      Example heading New

      -

      Example heading New

      -

      Example heading New

      -

      Example heading New

      -
      Example heading New
      -
      Example heading New
      -{% endcapture %} -{% include example.html content=example %} - -Badges can be used as part of links or buttons to provide a counter. - -{% capture example %} - -{% endcapture %} -{% include example.html content=example %} - -Note that depending on how they are used, badges may be confusing for users of screen readers and similar assistive technologies. While the styling of badges provides a visual cue as to their purpose, these users will simply be presented with the content of the badge. Depending on the specific situation, these badges may seem like random additional words or numbers at the end of a sentence, link, or button. - -Unless the context is clear (as with the "Notifications" example, where it is understood that the "4" is the number of notifications), consider including additional context with a visually hidden piece of additional text. - -{% capture example %} - -{% endcapture %} -{% include example.html content=example %} - -## Contextual variations - -Add any of the below mentioned modifier classes to change the appearance of a badge. - -{% capture example %} -{% for color in site.data.theme-colors %} -{{ color.name | capitalize }}{% endfor %} -{% endcapture %} -{% include example.html content=example %} - -{% include callout-warning-color-assistive-technologies.md %} - -## Pill badges - -Use the `.badge-pill` modifier class to make badges more rounded (with a larger `border-radius` and additional horizontal `padding`). Useful if you miss the badges from v3. - -{% capture example %} -{% for color in site.data.theme-colors %} -{{ color.name | capitalize }}{% endfor %} -{% endcapture %} -{% include example.html content=example %} - -## Links - -Using the contextual `.badge-*` classes on an `` element quickly provide _actionable_ badges with hover and focus states. - -{% capture example %} -{% for color in site.data.theme-colors %} -{{ color.name | capitalize }}{% endfor %} -{% endcapture %} -{% include example.html content=example %} diff --git a/vendor/twbs/bootstrap/site/docs/4.5/components/breadcrumb.md b/vendor/twbs/bootstrap/site/docs/4.5/components/breadcrumb.md deleted file mode 100644 index f6ce8f1be..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.5/components/breadcrumb.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -layout: docs -title: Breadcrumb -description: Indicate the current page's location within a navigational hierarchy that automatically adds separators via CSS. -group: components ---- - -## Example - -{% capture example %} - - - - - -{% endcapture %} -{% include example.html content=example %} - -## Changing the separator - -Separators are automatically added in CSS through [`::before`](https://developer.mozilla.org/en-US/docs/Web/CSS/::before) and [`content`](https://developer.mozilla.org/en-US/docs/Web/CSS/content). They can be changed by changing `$breadcrumb-divider`. The [quote](https://sass-lang.com/documentation/modules/string#quote) function is needed to generate the quotes around a string, so if you want `>` as separator, you can use this: - -```scss -$breadcrumb-divider: quote(">"); -``` - -It's also possible to use a **base64 embedded SVG icon**: - -```scss -$breadcrumb-divider: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4IiBoZWlnaHQ9IjgiPjxwYXRoIGQ9Ik0yLjUgMEwxIDEuNSAzLjUgNCAxIDYuNSAyLjUgOGw0LTQtNC00eiIgZmlsbD0iY3VycmVudENvbG9yIi8+PC9zdmc+); -``` - -The separator can be removed by setting `$breadcrumb-divider` to `none`: - -```scss -$breadcrumb-divider: none; -``` - -## Accessibility - -Since breadcrumbs provide a navigation, it's a good idea to add a meaningful label such as `aria-label="breadcrumb"` to describe the type of navigation provided in the `
      - -{% endcapture %} -{% include example.html content=example %} - -For file inputs, swap the `.form-control` for `.form-control-file`. - -{% capture example %} -
      -
      - - -
      -
      -{% endcapture %} -{% include example.html content=example %} - -### Sizing - -Set heights using classes like `.form-control-lg` and `.form-control-sm`. - -{% capture example %} - - - -{% endcapture %} -{% include example.html content=example %} - -{% capture example %} - - - -{% endcapture %} -{% include example.html content=example %} - -### Readonly - -Add the `readonly` boolean attribute on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor. - -{% capture example %} - -{% endcapture %} -{% include example.html content=example %} - -### Readonly plain text - -If you want to have `` elements in your form styled as plain text, use the `.form-control-plaintext` class to remove the default form field styling and preserve the correct margin and padding. - -{% capture example %} -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      -{% endcapture %} -{% include example.html content=example %} - -{% capture example %} -
      -
      - - -
      -
      - - -
      - -
      -{% endcapture %} -{% include example.html content=example %} - -## Range Inputs - -Set horizontally scrollable range inputs using `.form-control-range`. - -{% capture example %} -
      -
      - - -
      -
      -{% endcapture %} -{% include example.html content=example %} - -## Checkboxes and radios - -Default checkboxes and radios are improved upon with the help of `.form-check`, **a single class for both input types that improves the layout and behavior of their HTML elements**. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many. - -Disabled checkboxes and radios are supported. The `disabled` attribute will apply a lighter color to help indicate the input's state. - -Checkboxes and radio buttons support HTML-based form validation and provide concise, accessible labels. As such, our ``s and `